From d29a449f941f5a423c5250873d594034a9bf674d Mon Sep 17 00:00:00 2001 From: codecalm Date: Wed, 7 Oct 2026 10:53:40 +0200 Subject: [PATCH] Add stepper sizes and tidy the docs examples - .stepper-sm / .stepper-lg on the root size scale - width: fit-content so flex columns do not stretch the box - docs examples use the Icon component --- core/scss/_variables.scss | 8 +++ core/scss/ui/forms/_form-stepper.scss | 24 ++++++++ docs/content/ui/forms/stepper.mdx | 88 ++++++++++++++++----------- preview/pages/stepper.astro | 13 ++++ shared/ui/Stepper.astro | 5 +- 5 files changed, 100 insertions(+), 38 deletions(-) diff --git a/core/scss/_variables.scss b/core/scss/_variables.scss index 89beeaf60..71f9bf0c1 100644 --- a/core/scss/_variables.scss +++ b/core/scss/_variables.scss @@ -1210,6 +1210,14 @@ $otp-separator-color: var(--secondary) !default; // Stepper // scss-docs-start stepper-variables $stepper-input-width: 3.5rem !default; +$stepper-input-widths: ( + 'sm': 3rem, + 'lg': 4rem, +) !default; +$stepper-icon-sizes: ( + 'sm': $input-btn-icon-size-sm, + 'lg': $input-btn-icon-size-lg, +) !default; $stepper-bg: $input-bg !default; $stepper-border-color: var(--border-color) !default; $stepper-border-radius: $input-border-radius !default; diff --git a/core/scss/ui/forms/_form-stepper.scss b/core/scss/ui/forms/_form-stepper.scss index 4442daad4..04ec68dbf 100644 --- a/core/scss/ui/forms/_form-stepper.scss +++ b/core/scss/ui/forms/_form-stepper.scss @@ -16,6 +16,8 @@ Stepper (number input with buttons) position: relative; display: inline-flex; align-items: stretch; + // Never stretched by a flex column parent: the box is as wide as its parts + width: fit-content; vertical-align: middle; background-color: var(--stepper-bg); border: $input-border-width solid var(--stepper-border-color); @@ -111,3 +113,25 @@ Stepper (number input with buttons) } } } + +// Sizes move the same tokens `.form-control-sm` / `.btn-sm` and their `-lg` +// twins read, so the field and the buttons keep one height. +@each $size in (sm, lg) { + .stepper-#{$size} { + --stepper-input-width: #{map.get($stepper-input-widths, $size)}; + --stepper-border-radius: var(--btn-input-#{$size}-border-radius); + + > .form-control { + --control-padding-y: var(--btn-input-#{$size}-padding-y); + --control-font-size: var(--btn-input-#{$size}-font-size); + --control-line-height: var(--btn-input-#{$size}-line-height); + } + + > .btn { + --btn-padding-y: var(--btn-input-#{$size}-padding-y); + --btn-font-size: var(--btn-input-#{$size}-font-size); + --btn-line-height: var(--btn-input-#{$size}-line-height); + --btn-icon-size: #{map.get($stepper-icon-sizes, $size)}; + } + } +} diff --git a/docs/content/ui/forms/stepper.mdx b/docs/content/ui/forms/stepper.mdx index 8d81db3aa..f6553b54a 100644 --- a/docs/content/ui/forms/stepper.mdx +++ b/docs/content/ui/forms/stepper.mdx @@ -11,10 +11,16 @@ classnames: component: - class: stepper desc: Wrapper; holds the two buttons and the input + size: + - class: stepper-sm + desc: Smaller field and buttons + - class: stepper-lg + desc: Larger field and buttons --- import Example from '@components/Example.astro' import CodeDocs from '@components/CodeDocs.astro' +import Icon from '@ui/Icon.astro' ## Overview @@ -25,16 +31,11 @@ Add `data-bs-toggle="stepper"` to a `.stepper` wrapper, mark the buttons with `d
@@ -43,21 +44,17 @@ Add `data-bs-toggle="stepper"` to a `.stepper` wrapper, mark the buttons with `d ### Bounds and step -The button at a bound goes disabled, so the user sees when the value cannot go further. Letters never get into the field: a typed one is dropped and a pasted text keeps only its digits, with a minus sign allowed only when `min` is negative and a decimal separator only for a fractional `step`. A typed value is clamped once the field is left. A fractional `step` sets the precision: with `step="0.25"` the value is always shown with two decimals. +The button at a bound goes disabled, so the user sees when the value cannot go further. Letters never get into the field: a typed one is dropped and a pasted text keeps only its digits, with a minus sign allowed only when `min` is negative and a decimal separator only for a fractional `step`. A typed value is clamped +once the field is left. A fractional `step` sets the precision: with `step="0.25"` the value is always shown with two decimals.
@@ -71,16 +68,11 @@ A `type="text"` input gets `role="spinbutton"`, the matching `aria-value*` attri
@@ -89,6 +81,40 @@ A `type="text"` input gets `role="spinbutton"`, the matching `aria-value*` attri With the focus in the field, ↑ and ↓ step the value, Home and End jump to `min` and `max`. Holding a button down keeps stepping after a short delay; set `data-bs-repeat="false"` to turn that off. +### Sizes + +Add `.stepper-sm` or `.stepper-lg` to the wrapper. The field and the buttons follow the same height as `.form-control-sm` and `.form-control-lg`. + + +
+ + + +
+
+ + + +
+
+ + + +
+
+ ### Wider input The input is `3.5rem` wide by default, enough for a quantity. Set `--tblr-stepper-input-width` on the wrapper for longer values. @@ -96,16 +122,11 @@ The input is `3.5rem` wide by default, enough for a quantity. Set `--tblr-steppe
@@ -117,16 +138,11 @@ Add `disabled` or `readonly` to the input; both buttons follow.
diff --git a/preview/pages/stepper.astro b/preview/pages/stepper.astro index 0d594faf1..403452148 100644 --- a/preview/pages/stepper.astro +++ b/preview/pages/stepper.astro @@ -53,6 +53,19 @@ const cart = [ +
+ + + Sizes + Add .stepper-sm or .stepper-lg; the field and the buttons follow the same height as .form-control-sm and -lg. +
+ + + +
+
+
+
diff --git a/shared/ui/Stepper.astro b/shared/ui/Stepper.astro index 01c1ae37a..7f1ca8a8f 100644 --- a/shared/ui/Stepper.astro +++ b/shared/ui/Stepper.astro @@ -11,6 +11,7 @@ interface Props { step?: number /** data-bs-repeat: keep stepping while a button is held (default: true) */ repeat?: boolean + size?: 'sm' | 'lg' value?: number | string /** `text` keeps the native spin buttons away; `number` keeps the browser's own validation */ type?: 'text' | 'number' @@ -27,9 +28,9 @@ interface Props { [key: string]: unknown } -const { min, max, step, repeat, value, type = 'text', ariaLabel, id, name, disabled, readonly, decrementLabel = 'Decrease', incrementLabel = 'Increase', class: className, ...rest } = Astro.props +const { min, max, step, repeat, size, value, type = 'text', ariaLabel, id, name, disabled, readonly, decrementLabel = 'Decrease', incrementLabel = 'Increase', class: className, ...rest } = Astro.props -const wrapperClass = ['stepper', className] +const wrapperClass = ['stepper', size && `stepper-${size}`, className] ---