@ahrowe/ui 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/common/alert/alert.types.mjs.map +1 -1
- package/dist/esm/common/badge/badge.types.mjs.map +1 -1
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/button/button.types.mjs +1 -1
- package/dist/esm/common/button/button.types.mjs.map +1 -1
- package/dist/esm/common/card/Card.mjs +1 -1
- package/dist/esm/common/card/Card.mjs.map +1 -1
- package/dist/esm/common/card/card.types.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.mjs +1 -1
- package/dist/esm/common/carousel/carousel.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.module.mjs +1 -1
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.mjs +1 -1
- package/dist/esm/common/chip/chip.mjs.map +1 -1
- package/dist/esm/common/chip/chip.types.mjs.map +1 -1
- package/dist/esm/common/dropZone/dropZone.types.mjs.map +1 -1
- package/dist/esm/common/floatingMenu/floatingMenu.types.mjs.map +1 -1
- package/dist/esm/common/hooks/useCoarsePointer.mjs +2 -0
- package/dist/esm/common/hooks/useCoarsePointer.mjs.map +1 -0
- package/dist/esm/common/hooks/useSwipeDismiss.mjs +1 -1
- package/dist/esm/common/hooks/useSwipeDismiss.mjs.map +1 -1
- package/dist/esm/common/iconPicker/iconPicker.mjs +1 -1
- package/dist/esm/common/iconPicker/iconPicker.mjs.map +1 -1
- package/dist/esm/common/input/input.types.mjs.map +1 -1
- package/dist/esm/common/interactableDiv/interactableDiv.mjs +1 -1
- package/dist/esm/common/interactableDiv/interactableDiv.mjs.map +1 -1
- package/dist/esm/common/numberInput/index.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.module.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.module.mjs.map +1 -1
- package/dist/esm/common/numberInput/useStepRepeat.mjs +2 -0
- package/dist/esm/common/numberInput/useStepRepeat.mjs.map +1 -0
- package/dist/esm/common/otpInput/otpInput.types.mjs.map +1 -1
- package/dist/esm/common/popover/popover.types.mjs.map +1 -1
- package/dist/esm/common/radioGroup/radioGroup.types.mjs.map +1 -1
- package/dist/esm/common/sectionHeader/sectionHeader.types.mjs.map +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/package/common/alert/alert.types.d.ts +1 -1
- package/dist/types/package/common/animatedLogo/animatedLogo.types.d.ts +11 -3
- package/dist/types/package/common/avatar/avatar.types.d.ts +1 -1
- package/dist/types/package/common/badge/badge.types.d.ts +1 -1
- package/dist/types/package/common/button/button.types.d.ts +10 -4
- package/dist/types/package/common/card/card.types.d.ts +1 -1
- package/dist/types/package/common/carousel/carousel.types.d.ts +3 -1
- package/dist/types/package/common/checkbox/checkbox.types.d.ts +1 -1
- package/dist/types/package/common/chip/chip.types.d.ts +2 -0
- package/dist/types/package/common/colorPicker/colorPicker.types.d.ts +1 -1
- package/dist/types/package/common/configProvider/configProvider.types.d.ts +1 -1
- package/dist/types/package/common/dropZone/dropZone.types.d.ts +1 -1
- package/dist/types/package/common/dropdown/dropdown.types.d.ts +1 -1
- package/dist/types/package/common/errorBoundary/errorBoundary.types.d.ts +1 -1
- package/dist/types/package/common/floatingMenu/floatingMenu.types.d.ts +1 -1
- package/dist/types/package/common/hooks/useCoarsePointer.d.ts +10 -0
- package/dist/types/package/common/iconPicker/iconPicker.types.d.ts +1 -1
- package/dist/types/package/common/input/input.types.d.ts +2 -2
- package/dist/types/package/common/inputDropdown/inputDropdown.types.d.ts +1 -1
- package/dist/types/package/common/interactableDiv/interactableDiv.d.ts +2 -2
- package/dist/types/package/common/kanbanBoard/kanbanBoard.types.d.ts +1 -1
- package/dist/types/package/common/numberInput/index.d.ts +1 -0
- package/dist/types/package/common/numberInput/numberInput.d.ts +3 -32
- package/dist/types/package/common/numberInput/numberInput.types.d.ts +61 -0
- package/dist/types/package/common/numberInput/useStepRepeat.d.ts +17 -0
- package/dist/types/package/common/optionPicker/optionPicker.types.d.ts +1 -1
- package/dist/types/package/common/otpInput/otpInput.types.d.ts +1 -1
- package/dist/types/package/common/popover/popover.types.d.ts +1 -1
- package/dist/types/package/common/radioGroup/radioGroup.types.d.ts +1 -1
- package/dist/types/package/common/rating/rating.types.d.ts +1 -1
- package/dist/types/package/common/searchInput/searchInput.types.d.ts +1 -1
- package/dist/types/package/common/sectionHeader/sectionHeader.types.d.ts +1 -1
- package/dist/types/package/common/slider/slider.types.d.ts +1 -1
- package/dist/types/package/common/switch/switch.types.d.ts +1 -1
- package/dist/types/package/common/tabHeader/tabHeader.types.d.ts +1 -1
- package/dist/types/package/common/timeInput/timeInput.types.d.ts +1 -1
- package/dist/types/package/common/types/baseProps.types.d.ts +20 -5
- package/dist/types/package/common/types/slots.types.d.ts +1 -1
- package/docs/Button.md +23 -2
- package/docs/Carousel.md +19 -0
- package/docs/Chip.md +1 -0
- package/docs/NumberInput.md +66 -2
- package/package.json +1 -1
package/docs/NumberInput.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**When to use:** Numeric input with formatting — prices, quantities, percentages, phone numbers with separators. Wraps `react-number-format` with the same floating-label style as `Input`.
|
|
4
4
|
|
|
5
|
-
**Keywords:** currency input, quantity field, numeric field
|
|
5
|
+
**Keywords:** currency input, quantity field, numeric field, spinner, stepper, up down arrows, increment, decrement, plus minus, range, bounds, disabled
|
|
6
6
|
|
|
7
7
|
**Import:** `import { NumberInput } from '@ahrowe/ui'`
|
|
8
8
|
|
|
@@ -32,7 +32,18 @@ const priceValidator = new FormValidator<number | undefined>(undefined, [Validat
|
|
|
32
32
|
<NumberInput label="Price" formValidator={priceValidator} prefix="€" decimalScale={2} />
|
|
33
33
|
|
|
34
34
|
// Percentage
|
|
35
|
-
<NumberInput label="Discount" suffix="%" decimalScale={1}
|
|
35
|
+
<NumberInput label="Discount" suffix="%" decimalScale={1} />
|
|
36
|
+
|
|
37
|
+
// Stepper buttons — hold to repeat, shift for ±10, clamped to min/max
|
|
38
|
+
<NumberInput
|
|
39
|
+
label="Guests"
|
|
40
|
+
value={guests}
|
|
41
|
+
onChange={setGuests}
|
|
42
|
+
decimalScale={0}
|
|
43
|
+
showArrows
|
|
44
|
+
min={0}
|
|
45
|
+
max={10}
|
|
46
|
+
/>
|
|
36
47
|
|
|
37
48
|
// Max decimals without padding — cap at 2 decimals, but keep what the user typed
|
|
38
49
|
// (12 stays "12", 12.1 stays "12.1"; 12.111 is truncated to "12.11")
|
|
@@ -58,5 +69,58 @@ const priceValidator = new FormValidator<number | undefined>(undefined, [Validat
|
|
|
58
69
|
| `isRequired` | `boolean` | Shows the required mark (`*`) next to the label. Also inferred automatically when `formValidator` has a `required` validator. Default: `false` |
|
|
59
70
|
| `placeholder` | `string` | |
|
|
60
71
|
| `error` | `string` | Manual error message |
|
|
72
|
+
| `showArrows` | `boolean` | Show stepper buttons. Default: `false` |
|
|
73
|
+
| `step` | `number` | Amount one step changes the value by. Default: `1` (hold shift for ×10) |
|
|
74
|
+
| `min` | `number` | Lower bound — see the note below |
|
|
75
|
+
| `max` | `number` | Upper bound — see the note below |
|
|
76
|
+
| `arrowsLayout` | `'auto' \| 'stacked' \| 'split'` | Stepper layout. Default: `'auto'` |
|
|
77
|
+
| `increaseLabel` | `string` | Accessible name for the increase button. Default: `'Increase'` |
|
|
78
|
+
| `decreaseLabel` | `string` | Accessible name for the decrease button. Default: `'Decrease'` |
|
|
79
|
+
|
|
80
|
+
**Steppers (`showArrows`):** two layouts, picked by `arrowsLayout`:
|
|
81
|
+
|
|
82
|
+
- `'stacked'` — chevrons inside the field's right edge, each roughly 27x17 at the default text
|
|
83
|
+
size. Compact and mouse-oriented: two targets stacked inside a 34px field cannot reach the 24px
|
|
84
|
+
minimum that WCAG 2.5.8 asks for, which is why `'auto'` prefers `'split'` on touch.
|
|
85
|
+
- `'split'` — full-height `−` / `+` buttons flanking the field, each a 44px touch target. The two
|
|
86
|
+
are far apart, so a mis-tap can't step the value the wrong way.
|
|
87
|
+
- `'auto'` (default) — `split` on a coarse (touch) pointer, `stacked` otherwise, detected with
|
|
88
|
+
`matchMedia('(pointer: coarse)')` and re-evaluated when the pointer type changes.
|
|
89
|
+
|
|
90
|
+
The split buttons are the shared `Button` component, so press feedback is the same ripple as everywhere else in the library.
|
|
91
|
+
|
|
92
|
+
Press and hold a button to repeat: one step immediately, then a repeat after 400ms that accelerates
|
|
93
|
+
after about a second. Hold shift for ×10. The field itself carries `role="spinbutton"` with
|
|
94
|
+
`aria-valuenow` / `aria-valuemin` / `aria-valuemax`, so ↑/↓ stepping is announced; the buttons stay
|
|
95
|
+
out of the tab order rather than adding two tab stops per field.
|
|
96
|
+
|
|
97
|
+
**`min` / `max` clamp, they do not block typing.** Both bounds constrain the steppers and the
|
|
98
|
+
↑/↓ keys, disable the corresponding button once reached, and pull a typed value back into range
|
|
99
|
+
when it stops being mid-edit: on blur, and on Enter (which submits a surrounding form without ever
|
|
100
|
+
blurring the field). An empty field is never clamped, so blurring an untouched field does not fill
|
|
101
|
+
in `min`.
|
|
102
|
+
|
|
103
|
+
Nothing is rejected as it is typed, deliberately. Editing inserts digits into an existing value, so
|
|
104
|
+
the intermediate state routinely leaves the range even when the destination is inside it — with
|
|
105
|
+
`max={10}`, putting the caret in front of `8` and typing `1` on the way to `18` would simply do
|
|
106
|
+
nothing, with no feedback. Blocking input suits *format* rules (digits only, a fixed length), where
|
|
107
|
+
every rejected keystroke is unambiguously wrong; a value range is not one of those.
|
|
108
|
+
|
|
109
|
+
The Enter clamp is exact for a `formValidator`-driven field, because `formValidator.set` is
|
|
110
|
+
imperative and lands before the submit handler runs. For a plain `value`/`onChange` field it is
|
|
111
|
+
best-effort: the consumer's own state update may not have flushed by the time their `onSubmit`
|
|
112
|
+
reads it. If an out-of-range value must be *impossible* to submit rather than merely corrected, add
|
|
113
|
+
a validator — `@ahrowe/form-validation` has no numeric range validator (`minLength`/`maxLength` are
|
|
114
|
+
string length), so write one:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
const inRange = (min: number, max: number): ValidatorFunction => (value) =>
|
|
118
|
+
typeof value === 'number' && (value < min || value > max)
|
|
119
|
+
? { id: 'range', message: `Must be between ${min} and ${max}` }
|
|
120
|
+
: null;
|
|
121
|
+
|
|
122
|
+
const qty = new FormValidator<number | undefined>(undefined, [inRange(10, 100)]);
|
|
123
|
+
<NumberInput label="Quantity" formValidator={qty} min={10} max={100} showArrows decimalScale={0} />
|
|
124
|
+
```
|
|
61
125
|
|
|
62
126
|
**Mobile keyboard layout:** shows the numeric on-screen keyboard automatically (`inputMode="numeric"` when `decimalScale={0}`, `"decimal"` otherwise, so a decimal separator key is available whenever fractional values are allowed). Pass `inputMode` directly to override.
|