@salt-ds/lab 1.0.0-alpha.60 → 1.0.0-alpha.61

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @salt-ds/lab
2
2
 
3
+ ## 1.0.0-alpha.61
4
+
5
+ ### Patch Changes
6
+
7
+ - 98d3aac: Improved screen reader support for read-only stepper inputs.
8
+ - Updated dependencies [90b85d4]
9
+ - Updated dependencies [90b85d4]
10
+ - Updated dependencies [fd86394]
11
+ - Updated dependencies [56a997c]
12
+ - Updated dependencies [9a75603]
13
+ - Updated dependencies [021e90d]
14
+ - Updated dependencies [7510f56]
15
+ - Updated dependencies [98d3aac]
16
+ - Updated dependencies [ea5fc00]
17
+ - Updated dependencies [ba0f436]
18
+ - @salt-ds/core@1.41.0
19
+ - @salt-ds/icons@1.13.2
20
+
3
21
  ## 1.0.0-alpha.60
4
22
 
5
23
  ### Patch Changes
package/css/salt-lab.css CHANGED
@@ -4599,4 +4599,4 @@
4599
4599
  margin: calc(var(--salt-size-unit) / 2) 0;
4600
4600
  }
4601
4601
 
4602
- /* src/e126ec89-3830-4f0c-887b-f2878057dae6.css */
4602
+ /* src/f215e743-86b0-4593-a239-e79356c02946.css */
@@ -188,11 +188,11 @@ const StepperInput = react.forwardRef(
188
188
  "input",
189
189
  {
190
190
  "aria-describedby": clsx.clsx(formFieldDescribedBy, inputDescribedBy),
191
- "aria-invalid": utils.isOutOfRange(value, min, max),
192
191
  "aria-labelledby": clsx.clsx(formFieldLabelledBy, inputLabelledBy),
193
- "aria-valuemax": utils.toFloat(utils.toFixedDecimalPlaces(max, decimalPlaces)),
194
- "aria-valuemin": utils.toFloat(utils.toFixedDecimalPlaces(min, decimalPlaces)),
195
- "aria-valuenow": value && !Number.isNaN(utils.toFloat(value)) ? utils.toFloat(utils.toFixedDecimalPlaces(utils.toFloat(value), decimalPlaces)) : void 0,
192
+ "aria-invalid": !isReadOnly ? utils.isOutOfRange(value, min, max) : void 0,
193
+ "aria-valuemax": !isReadOnly ? utils.toFloat(utils.toFixedDecimalPlaces(max, decimalPlaces)) : void 0,
194
+ "aria-valuemin": !isReadOnly ? utils.toFloat(utils.toFixedDecimalPlaces(min, decimalPlaces)) : void 0,
195
+ "aria-valuenow": value && !Number.isNaN(utils.toFloat(value)) && !isReadOnly ? utils.toFloat(utils.toFixedDecimalPlaces(utils.toFloat(value), decimalPlaces)) : void 0,
196
196
  className: clsx.clsx(
197
197
  withBaseName("input"),
198
198
  withBaseName(`inputTextAlign${core.capitalize(textAlign)}`),
@@ -205,9 +205,10 @@ const StepperInput = react.forwardRef(
205
205
  onKeyDown: handleInputKeyDown,
206
206
  placeholder,
207
207
  readOnly: isReadOnly,
208
+ "aria-readonly": isReadOnly ? "true" : void 0,
208
209
  ref: forkedInputRef,
209
210
  required: isRequired,
210
- role: "spinbutton",
211
+ role: isReadOnly ? "textbox" : "spinbutton",
211
212
  tabIndex: isDisabled ? -1 : 0,
212
213
  value,
213
214
  ...restInputProps
@@ -1 +1 @@
1
- {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import {\n Button,\n StatusAdornment,\n type ValidationStatus,\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useFormFieldProps,\n useIcon,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport {\n isAllowedNonNumeric,\n isOutOfRange,\n sanitizedInput,\n toFixedDecimalPlaces,\n toFloat,\n} from \"./internal/utils\";\n\nimport stepperInputCss from \"./StepperInput.css\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * A boolean. When `true`, the input will receive a full border.\n */\n bordered?: boolean;\n /**\n * The number of decimal places to display.\n */\n decimalPlaces?: number;\n /**\n * Sets the initial default value of the component.\n */\n defaultValue?: number | string;\n /**\n * If `true`, the stepper input will be disabled.\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * Use `''` to disable this feature. Defaults to '—'.\n * @default '—'\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * Whether to hide the stepper buttons. Defaults to `false`.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.\n */\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n /**\n * Optional ref for the input component\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * The maximum value that can be selected. Defaults to Number.MAX_SAFE_INTEGER.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected. Defaults to Number.MIN_SAFE_INTEGER.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback when stepper input value is changed.\n * @param event - the event triggers value change, could be undefined during increment / decrement button long press\n */\n onChange?: (\n event: SyntheticEvent | undefined,\n value: number | string,\n ) => void;\n /**\n * A string. Displayed in a dimmed color when the input value is empty.\n */\n placeholder?: string | undefined;\n /**\n * A boolean. If `true`, the component is not editable by the user.\n */\n readOnly?: boolean;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * The amount to increment or decrement the value by when using the stepper buttons or Up Arrow and Down Arrow keys. Default to 1.\n * @default 1\n */\n step?: number;\n /**\n * The amount to change the value when the value is incremented or decremented by holding Shift and pressing Up arrow or Down arrow keys.\n * Defaults to 10.\n * @default 10\n */\n stepBlock?: number;\n /**\n * Alignment of text within container. Defaults to \"left\".\n * @default \"left\"\n */\n textAlign?: \"left\" | \"center\" | \"right\";\n /**\n * Validation status.\n */\n validationStatus?: Extract<ValidationStatus, \"error\" | \"warning\" | \"success\">;\n /**\n * Styling variant. Defaults to \"primary\".\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * The value of the stepper input. The component will be controlled if this prop is provided.\n */\n value?: number | string | undefined;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(\n {\n bordered,\n className: classNameProp,\n decimalPlaces = 0,\n defaultValue: defaultValueProp,\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n hideButtons,\n inputProps: inputPropsProp = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange: onChangeProp,\n placeholder,\n readOnly: readOnlyProp,\n startAdornment,\n step = 1,\n stepBlock = 10,\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n value: valueProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const { IncreaseIcon, DecreaseIcon } = useIcon();\n\n const {\n a11yProps: {\n \"aria-describedby\": formFieldDescribedBy,\n \"aria-labelledby\": formFieldLabelledBy,\n } = {},\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n necessity: formFieldRequired,\n validationStatus: formFieldValidationStatus,\n } = useFormFieldProps();\n\n const isDisabled = disabled || formFieldDisabled;\n const isReadOnly = readOnlyProp || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onChange: inputOnChange,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputPropsProp;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default:\n typeof defaultValueProp === \"number\"\n ? toFixedDecimalPlaces(defaultValueProp, decimalPlaces)\n : defaultValueProp,\n name: \"StepperInput\",\n state: \"value\",\n });\n\n // Won't be needed when `:has` css can be used\n const [focused, setFocused] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const forkedInputRef = useForkRef(inputRef, inputRefProp);\n\n const {\n decrementButtonProps,\n decrementValue,\n incrementButtonProps,\n incrementValue,\n } = useStepperInput({\n inputRef,\n setValue,\n decimalPlaces,\n disabled,\n max,\n min,\n onChange: onChangeProp,\n readOnly: isReadOnly,\n step,\n stepBlock,\n value,\n });\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n\n inputOnFocus?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n\n if (value === undefined) return;\n\n const floatValue = toFloat(value);\n if (Number.isNaN(floatValue)) {\n // Keep original value if NaN\n setValue(value);\n onChangeProp?.(event, value);\n } else {\n const roundedValue = toFixedDecimalPlaces(floatValue, decimalPlaces);\n\n if (value !== \"\" && !isAllowedNonNumeric(value)) {\n setValue(roundedValue);\n }\n\n onChangeProp?.(event, roundedValue);\n }\n\n inputOnBlur?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const changedValue = event.target.value;\n\n setValue(sanitizedInput(changedValue));\n\n onChangeProp?.(event, sanitizedInput(changedValue));\n inputOnChange?.(event);\n };\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowUp\": {\n event.preventDefault();\n const block = event.shiftKey;\n incrementValue(event, block);\n break;\n }\n case \"ArrowDown\": {\n event.preventDefault();\n const block = event.shiftKey;\n decrementValue(event, block);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n setValue(min);\n onChangeProp?.(event, min);\n break;\n }\n case \"End\": {\n event.preventDefault();\n setValue(max);\n onChangeProp?.(event, max);\n break;\n }\n case \"PageUp\": {\n event.preventDefault();\n incrementValue(event, true);\n break;\n }\n case \"PageDown\": {\n event.preventDefault();\n decrementValue(event, true);\n break;\n }\n }\n\n inputOnKeyDown?.(event);\n };\n\n return (\n <div\n className={clsx(withBaseName(), classNameProp)}\n {...restProps}\n ref={ref}\n >\n <div\n className={clsx(\n withBaseName(\"inputContainer\"),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n )}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <input\n aria-describedby={clsx(formFieldDescribedBy, inputDescribedBy)}\n aria-invalid={isOutOfRange(value, min, max)}\n aria-labelledby={clsx(formFieldLabelledBy, inputLabelledBy)}\n aria-valuemax={toFloat(toFixedDecimalPlaces(max, decimalPlaces))}\n aria-valuemin={toFloat(toFixedDecimalPlaces(min, decimalPlaces))}\n aria-valuenow={\n value && !Number.isNaN(toFloat(value))\n ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces))\n : undefined\n }\n className={clsx(\n withBaseName(\"input\"),\n withBaseName(`inputTextAlign${capitalize(textAlign)}`),\n inputClassName,\n )}\n disabled={isDisabled}\n onBlur={handleInputBlur}\n onChange={handleInputChange}\n onFocus={!isDisabled ? handleInputFocus : undefined}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n ref={forkedInputRef}\n required={isRequired}\n role=\"spinbutton\"\n tabIndex={isDisabled ? -1 : 0}\n value={value}\n {...restInputProps}\n />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n\n {!hideButtons && !isReadOnly && (\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonIncrement\"),\n )}\n {...incrementButtonProps}\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonDecrement\"),\n )}\n {...decrementButtonProps}\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","StepperInput","useWindow","useComponentCssInjection","stepperInputCss","useIcon","useFormFieldProps","useControlled","toFixedDecimalPlaces","useState","useRef","useForkRef","useStepperInput","toFloat","isAllowedNonNumeric","sanitizedInput","jsxs","clsx","jsx","isOutOfRange","capitalize","StatusAdornment","Button"],"mappings":"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"}
1
+ {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import {\n Button,\n StatusAdornment,\n type ValidationStatus,\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useFormFieldProps,\n useIcon,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport {\n isAllowedNonNumeric,\n isOutOfRange,\n sanitizedInput,\n toFixedDecimalPlaces,\n toFloat,\n} from \"./internal/utils\";\n\nimport stepperInputCss from \"./StepperInput.css\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * A boolean. When `true`, the input will receive a full border.\n */\n bordered?: boolean;\n /**\n * The number of decimal places to display.\n */\n decimalPlaces?: number;\n /**\n * Sets the initial default value of the component.\n */\n defaultValue?: number | string;\n /**\n * If `true`, the stepper input will be disabled.\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * Use `''` to disable this feature. Defaults to '—'.\n * @default '—'\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * Whether to hide the stepper buttons. Defaults to `false`.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.\n */\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n /**\n * Optional ref for the input component\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * The maximum value that can be selected. Defaults to Number.MAX_SAFE_INTEGER.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected. Defaults to Number.MIN_SAFE_INTEGER.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback when stepper input value is changed.\n * @param event - the event triggers value change, could be undefined during increment / decrement button long press\n */\n onChange?: (\n event: SyntheticEvent | undefined,\n value: number | string,\n ) => void;\n /**\n * A string. Displayed in a dimmed color when the input value is empty.\n */\n placeholder?: string | undefined;\n /**\n * A boolean. If `true`, the component is not editable by the user.\n */\n readOnly?: boolean;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * The amount to increment or decrement the value by when using the stepper buttons or Up Arrow and Down Arrow keys. Default to 1.\n * @default 1\n */\n step?: number;\n /**\n * The amount to change the value when the value is incremented or decremented by holding Shift and pressing Up arrow or Down arrow keys.\n * Defaults to 10.\n * @default 10\n */\n stepBlock?: number;\n /**\n * Alignment of text within container. Defaults to \"left\".\n * @default \"left\"\n */\n textAlign?: \"left\" | \"center\" | \"right\";\n /**\n * Validation status.\n */\n validationStatus?: Extract<ValidationStatus, \"error\" | \"warning\" | \"success\">;\n /**\n * Styling variant. Defaults to \"primary\".\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * The value of the stepper input. The component will be controlled if this prop is provided.\n */\n value?: number | string | undefined;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(\n {\n bordered,\n className: classNameProp,\n decimalPlaces = 0,\n defaultValue: defaultValueProp,\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n hideButtons,\n inputProps: inputPropsProp = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange: onChangeProp,\n placeholder,\n readOnly: readOnlyProp,\n startAdornment,\n step = 1,\n stepBlock = 10,\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n value: valueProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const { IncreaseIcon, DecreaseIcon } = useIcon();\n\n const {\n a11yProps: {\n \"aria-describedby\": formFieldDescribedBy,\n \"aria-labelledby\": formFieldLabelledBy,\n } = {},\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n necessity: formFieldRequired,\n validationStatus: formFieldValidationStatus,\n } = useFormFieldProps();\n\n const isDisabled = disabled || formFieldDisabled;\n const isReadOnly = readOnlyProp || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onChange: inputOnChange,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputPropsProp;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default:\n typeof defaultValueProp === \"number\"\n ? toFixedDecimalPlaces(defaultValueProp, decimalPlaces)\n : defaultValueProp,\n name: \"StepperInput\",\n state: \"value\",\n });\n\n // Won't be needed when `:has` css can be used\n const [focused, setFocused] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const forkedInputRef = useForkRef(inputRef, inputRefProp);\n\n const {\n decrementButtonProps,\n decrementValue,\n incrementButtonProps,\n incrementValue,\n } = useStepperInput({\n inputRef,\n setValue,\n decimalPlaces,\n disabled,\n max,\n min,\n onChange: onChangeProp,\n readOnly: isReadOnly,\n step,\n stepBlock,\n value,\n });\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n\n inputOnFocus?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n\n if (value === undefined) return;\n\n const floatValue = toFloat(value);\n if (Number.isNaN(floatValue)) {\n // Keep original value if NaN\n setValue(value);\n onChangeProp?.(event, value);\n } else {\n const roundedValue = toFixedDecimalPlaces(floatValue, decimalPlaces);\n\n if (value !== \"\" && !isAllowedNonNumeric(value)) {\n setValue(roundedValue);\n }\n\n onChangeProp?.(event, roundedValue);\n }\n\n inputOnBlur?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const changedValue = event.target.value;\n\n setValue(sanitizedInput(changedValue));\n\n onChangeProp?.(event, sanitizedInput(changedValue));\n inputOnChange?.(event);\n };\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowUp\": {\n event.preventDefault();\n const block = event.shiftKey;\n incrementValue(event, block);\n break;\n }\n case \"ArrowDown\": {\n event.preventDefault();\n const block = event.shiftKey;\n decrementValue(event, block);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n setValue(min);\n onChangeProp?.(event, min);\n break;\n }\n case \"End\": {\n event.preventDefault();\n setValue(max);\n onChangeProp?.(event, max);\n break;\n }\n case \"PageUp\": {\n event.preventDefault();\n incrementValue(event, true);\n break;\n }\n case \"PageDown\": {\n event.preventDefault();\n decrementValue(event, true);\n break;\n }\n }\n\n inputOnKeyDown?.(event);\n };\n\n return (\n <div\n className={clsx(withBaseName(), classNameProp)}\n {...restProps}\n ref={ref}\n >\n <div\n className={clsx(\n withBaseName(\"inputContainer\"),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n )}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <input\n aria-describedby={clsx(formFieldDescribedBy, inputDescribedBy)}\n aria-labelledby={clsx(formFieldLabelledBy, inputLabelledBy)}\n aria-invalid={\n !isReadOnly ? isOutOfRange(value, min, max) : undefined\n }\n aria-valuemax={\n !isReadOnly\n ? toFloat(toFixedDecimalPlaces(max, decimalPlaces))\n : undefined\n }\n aria-valuemin={\n !isReadOnly\n ? toFloat(toFixedDecimalPlaces(min, decimalPlaces))\n : undefined\n }\n aria-valuenow={\n value && !Number.isNaN(toFloat(value)) && !isReadOnly\n ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces))\n : undefined\n }\n className={clsx(\n withBaseName(\"input\"),\n withBaseName(`inputTextAlign${capitalize(textAlign)}`),\n inputClassName,\n )}\n disabled={isDisabled}\n onBlur={handleInputBlur}\n onChange={handleInputChange}\n onFocus={!isDisabled ? handleInputFocus : undefined}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n aria-readonly={isReadOnly ? \"true\" : undefined}\n ref={forkedInputRef}\n required={isRequired}\n // Workaround to have readonly conveyed by screen readers (https://github.com/jpmorganchase/salt-ds/issues/4586)\n role={isReadOnly ? \"textbox\" : \"spinbutton\"}\n tabIndex={isDisabled ? -1 : 0}\n value={value}\n {...restInputProps}\n />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n\n {!hideButtons && !isReadOnly && (\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonIncrement\"),\n )}\n {...incrementButtonProps}\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonDecrement\"),\n )}\n {...decrementButtonProps}\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","StepperInput","useWindow","useComponentCssInjection","stepperInputCss","useIcon","useFormFieldProps","useControlled","toFixedDecimalPlaces","useState","useRef","useForkRef","useStepperInput","toFloat","isAllowedNonNumeric","sanitizedInput","jsxs","clsx","jsx","isOutOfRange","capitalize","StatusAdornment","Button"],"mappings":"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"}
@@ -186,11 +186,11 @@ const StepperInput = forwardRef(
186
186
  "input",
187
187
  {
188
188
  "aria-describedby": clsx(formFieldDescribedBy, inputDescribedBy),
189
- "aria-invalid": isOutOfRange(value, min, max),
190
189
  "aria-labelledby": clsx(formFieldLabelledBy, inputLabelledBy),
191
- "aria-valuemax": toFloat(toFixedDecimalPlaces(max, decimalPlaces)),
192
- "aria-valuemin": toFloat(toFixedDecimalPlaces(min, decimalPlaces)),
193
- "aria-valuenow": value && !Number.isNaN(toFloat(value)) ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces)) : void 0,
190
+ "aria-invalid": !isReadOnly ? isOutOfRange(value, min, max) : void 0,
191
+ "aria-valuemax": !isReadOnly ? toFloat(toFixedDecimalPlaces(max, decimalPlaces)) : void 0,
192
+ "aria-valuemin": !isReadOnly ? toFloat(toFixedDecimalPlaces(min, decimalPlaces)) : void 0,
193
+ "aria-valuenow": value && !Number.isNaN(toFloat(value)) && !isReadOnly ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces)) : void 0,
194
194
  className: clsx(
195
195
  withBaseName("input"),
196
196
  withBaseName(`inputTextAlign${capitalize(textAlign)}`),
@@ -203,9 +203,10 @@ const StepperInput = forwardRef(
203
203
  onKeyDown: handleInputKeyDown,
204
204
  placeholder,
205
205
  readOnly: isReadOnly,
206
+ "aria-readonly": isReadOnly ? "true" : void 0,
206
207
  ref: forkedInputRef,
207
208
  required: isRequired,
208
- role: "spinbutton",
209
+ role: isReadOnly ? "textbox" : "spinbutton",
209
210
  tabIndex: isDisabled ? -1 : 0,
210
211
  value,
211
212
  ...restInputProps
@@ -1 +1 @@
1
- {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import {\n Button,\n StatusAdornment,\n type ValidationStatus,\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useFormFieldProps,\n useIcon,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport {\n isAllowedNonNumeric,\n isOutOfRange,\n sanitizedInput,\n toFixedDecimalPlaces,\n toFloat,\n} from \"./internal/utils\";\n\nimport stepperInputCss from \"./StepperInput.css\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * A boolean. When `true`, the input will receive a full border.\n */\n bordered?: boolean;\n /**\n * The number of decimal places to display.\n */\n decimalPlaces?: number;\n /**\n * Sets the initial default value of the component.\n */\n defaultValue?: number | string;\n /**\n * If `true`, the stepper input will be disabled.\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * Use `''` to disable this feature. Defaults to '—'.\n * @default '—'\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * Whether to hide the stepper buttons. Defaults to `false`.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.\n */\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n /**\n * Optional ref for the input component\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * The maximum value that can be selected. Defaults to Number.MAX_SAFE_INTEGER.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected. Defaults to Number.MIN_SAFE_INTEGER.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback when stepper input value is changed.\n * @param event - the event triggers value change, could be undefined during increment / decrement button long press\n */\n onChange?: (\n event: SyntheticEvent | undefined,\n value: number | string,\n ) => void;\n /**\n * A string. Displayed in a dimmed color when the input value is empty.\n */\n placeholder?: string | undefined;\n /**\n * A boolean. If `true`, the component is not editable by the user.\n */\n readOnly?: boolean;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * The amount to increment or decrement the value by when using the stepper buttons or Up Arrow and Down Arrow keys. Default to 1.\n * @default 1\n */\n step?: number;\n /**\n * The amount to change the value when the value is incremented or decremented by holding Shift and pressing Up arrow or Down arrow keys.\n * Defaults to 10.\n * @default 10\n */\n stepBlock?: number;\n /**\n * Alignment of text within container. Defaults to \"left\".\n * @default \"left\"\n */\n textAlign?: \"left\" | \"center\" | \"right\";\n /**\n * Validation status.\n */\n validationStatus?: Extract<ValidationStatus, \"error\" | \"warning\" | \"success\">;\n /**\n * Styling variant. Defaults to \"primary\".\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * The value of the stepper input. The component will be controlled if this prop is provided.\n */\n value?: number | string | undefined;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(\n {\n bordered,\n className: classNameProp,\n decimalPlaces = 0,\n defaultValue: defaultValueProp,\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n hideButtons,\n inputProps: inputPropsProp = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange: onChangeProp,\n placeholder,\n readOnly: readOnlyProp,\n startAdornment,\n step = 1,\n stepBlock = 10,\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n value: valueProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const { IncreaseIcon, DecreaseIcon } = useIcon();\n\n const {\n a11yProps: {\n \"aria-describedby\": formFieldDescribedBy,\n \"aria-labelledby\": formFieldLabelledBy,\n } = {},\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n necessity: formFieldRequired,\n validationStatus: formFieldValidationStatus,\n } = useFormFieldProps();\n\n const isDisabled = disabled || formFieldDisabled;\n const isReadOnly = readOnlyProp || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onChange: inputOnChange,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputPropsProp;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default:\n typeof defaultValueProp === \"number\"\n ? toFixedDecimalPlaces(defaultValueProp, decimalPlaces)\n : defaultValueProp,\n name: \"StepperInput\",\n state: \"value\",\n });\n\n // Won't be needed when `:has` css can be used\n const [focused, setFocused] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const forkedInputRef = useForkRef(inputRef, inputRefProp);\n\n const {\n decrementButtonProps,\n decrementValue,\n incrementButtonProps,\n incrementValue,\n } = useStepperInput({\n inputRef,\n setValue,\n decimalPlaces,\n disabled,\n max,\n min,\n onChange: onChangeProp,\n readOnly: isReadOnly,\n step,\n stepBlock,\n value,\n });\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n\n inputOnFocus?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n\n if (value === undefined) return;\n\n const floatValue = toFloat(value);\n if (Number.isNaN(floatValue)) {\n // Keep original value if NaN\n setValue(value);\n onChangeProp?.(event, value);\n } else {\n const roundedValue = toFixedDecimalPlaces(floatValue, decimalPlaces);\n\n if (value !== \"\" && !isAllowedNonNumeric(value)) {\n setValue(roundedValue);\n }\n\n onChangeProp?.(event, roundedValue);\n }\n\n inputOnBlur?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const changedValue = event.target.value;\n\n setValue(sanitizedInput(changedValue));\n\n onChangeProp?.(event, sanitizedInput(changedValue));\n inputOnChange?.(event);\n };\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowUp\": {\n event.preventDefault();\n const block = event.shiftKey;\n incrementValue(event, block);\n break;\n }\n case \"ArrowDown\": {\n event.preventDefault();\n const block = event.shiftKey;\n decrementValue(event, block);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n setValue(min);\n onChangeProp?.(event, min);\n break;\n }\n case \"End\": {\n event.preventDefault();\n setValue(max);\n onChangeProp?.(event, max);\n break;\n }\n case \"PageUp\": {\n event.preventDefault();\n incrementValue(event, true);\n break;\n }\n case \"PageDown\": {\n event.preventDefault();\n decrementValue(event, true);\n break;\n }\n }\n\n inputOnKeyDown?.(event);\n };\n\n return (\n <div\n className={clsx(withBaseName(), classNameProp)}\n {...restProps}\n ref={ref}\n >\n <div\n className={clsx(\n withBaseName(\"inputContainer\"),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n )}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <input\n aria-describedby={clsx(formFieldDescribedBy, inputDescribedBy)}\n aria-invalid={isOutOfRange(value, min, max)}\n aria-labelledby={clsx(formFieldLabelledBy, inputLabelledBy)}\n aria-valuemax={toFloat(toFixedDecimalPlaces(max, decimalPlaces))}\n aria-valuemin={toFloat(toFixedDecimalPlaces(min, decimalPlaces))}\n aria-valuenow={\n value && !Number.isNaN(toFloat(value))\n ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces))\n : undefined\n }\n className={clsx(\n withBaseName(\"input\"),\n withBaseName(`inputTextAlign${capitalize(textAlign)}`),\n inputClassName,\n )}\n disabled={isDisabled}\n onBlur={handleInputBlur}\n onChange={handleInputChange}\n onFocus={!isDisabled ? handleInputFocus : undefined}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n ref={forkedInputRef}\n required={isRequired}\n role=\"spinbutton\"\n tabIndex={isDisabled ? -1 : 0}\n value={value}\n {...restInputProps}\n />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n\n {!hideButtons && !isReadOnly && (\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonIncrement\"),\n )}\n {...incrementButtonProps}\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonDecrement\"),\n )}\n {...decrementButtonProps}\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["StepperInput","stepperInputCss"],"mappings":"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"}
1
+ {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import {\n Button,\n StatusAdornment,\n type ValidationStatus,\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useFormFieldProps,\n useIcon,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport {\n isAllowedNonNumeric,\n isOutOfRange,\n sanitizedInput,\n toFixedDecimalPlaces,\n toFloat,\n} from \"./internal/utils\";\n\nimport stepperInputCss from \"./StepperInput.css\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * A boolean. When `true`, the input will receive a full border.\n */\n bordered?: boolean;\n /**\n * The number of decimal places to display.\n */\n decimalPlaces?: number;\n /**\n * Sets the initial default value of the component.\n */\n defaultValue?: number | string;\n /**\n * If `true`, the stepper input will be disabled.\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * Use `''` to disable this feature. Defaults to '—'.\n * @default '—'\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * Whether to hide the stepper buttons. Defaults to `false`.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.\n */\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n /**\n * Optional ref for the input component\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * The maximum value that can be selected. Defaults to Number.MAX_SAFE_INTEGER.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected. Defaults to Number.MIN_SAFE_INTEGER.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback when stepper input value is changed.\n * @param event - the event triggers value change, could be undefined during increment / decrement button long press\n */\n onChange?: (\n event: SyntheticEvent | undefined,\n value: number | string,\n ) => void;\n /**\n * A string. Displayed in a dimmed color when the input value is empty.\n */\n placeholder?: string | undefined;\n /**\n * A boolean. If `true`, the component is not editable by the user.\n */\n readOnly?: boolean;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * The amount to increment or decrement the value by when using the stepper buttons or Up Arrow and Down Arrow keys. Default to 1.\n * @default 1\n */\n step?: number;\n /**\n * The amount to change the value when the value is incremented or decremented by holding Shift and pressing Up arrow or Down arrow keys.\n * Defaults to 10.\n * @default 10\n */\n stepBlock?: number;\n /**\n * Alignment of text within container. Defaults to \"left\".\n * @default \"left\"\n */\n textAlign?: \"left\" | \"center\" | \"right\";\n /**\n * Validation status.\n */\n validationStatus?: Extract<ValidationStatus, \"error\" | \"warning\" | \"success\">;\n /**\n * Styling variant. Defaults to \"primary\".\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * The value of the stepper input. The component will be controlled if this prop is provided.\n */\n value?: number | string | undefined;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(\n {\n bordered,\n className: classNameProp,\n decimalPlaces = 0,\n defaultValue: defaultValueProp,\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n hideButtons,\n inputProps: inputPropsProp = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange: onChangeProp,\n placeholder,\n readOnly: readOnlyProp,\n startAdornment,\n step = 1,\n stepBlock = 10,\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n value: valueProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const { IncreaseIcon, DecreaseIcon } = useIcon();\n\n const {\n a11yProps: {\n \"aria-describedby\": formFieldDescribedBy,\n \"aria-labelledby\": formFieldLabelledBy,\n } = {},\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n necessity: formFieldRequired,\n validationStatus: formFieldValidationStatus,\n } = useFormFieldProps();\n\n const isDisabled = disabled || formFieldDisabled;\n const isReadOnly = readOnlyProp || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onChange: inputOnChange,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputPropsProp;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default:\n typeof defaultValueProp === \"number\"\n ? toFixedDecimalPlaces(defaultValueProp, decimalPlaces)\n : defaultValueProp,\n name: \"StepperInput\",\n state: \"value\",\n });\n\n // Won't be needed when `:has` css can be used\n const [focused, setFocused] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const forkedInputRef = useForkRef(inputRef, inputRefProp);\n\n const {\n decrementButtonProps,\n decrementValue,\n incrementButtonProps,\n incrementValue,\n } = useStepperInput({\n inputRef,\n setValue,\n decimalPlaces,\n disabled,\n max,\n min,\n onChange: onChangeProp,\n readOnly: isReadOnly,\n step,\n stepBlock,\n value,\n });\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n\n inputOnFocus?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n\n if (value === undefined) return;\n\n const floatValue = toFloat(value);\n if (Number.isNaN(floatValue)) {\n // Keep original value if NaN\n setValue(value);\n onChangeProp?.(event, value);\n } else {\n const roundedValue = toFixedDecimalPlaces(floatValue, decimalPlaces);\n\n if (value !== \"\" && !isAllowedNonNumeric(value)) {\n setValue(roundedValue);\n }\n\n onChangeProp?.(event, roundedValue);\n }\n\n inputOnBlur?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const changedValue = event.target.value;\n\n setValue(sanitizedInput(changedValue));\n\n onChangeProp?.(event, sanitizedInput(changedValue));\n inputOnChange?.(event);\n };\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowUp\": {\n event.preventDefault();\n const block = event.shiftKey;\n incrementValue(event, block);\n break;\n }\n case \"ArrowDown\": {\n event.preventDefault();\n const block = event.shiftKey;\n decrementValue(event, block);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n setValue(min);\n onChangeProp?.(event, min);\n break;\n }\n case \"End\": {\n event.preventDefault();\n setValue(max);\n onChangeProp?.(event, max);\n break;\n }\n case \"PageUp\": {\n event.preventDefault();\n incrementValue(event, true);\n break;\n }\n case \"PageDown\": {\n event.preventDefault();\n decrementValue(event, true);\n break;\n }\n }\n\n inputOnKeyDown?.(event);\n };\n\n return (\n <div\n className={clsx(withBaseName(), classNameProp)}\n {...restProps}\n ref={ref}\n >\n <div\n className={clsx(\n withBaseName(\"inputContainer\"),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n )}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <input\n aria-describedby={clsx(formFieldDescribedBy, inputDescribedBy)}\n aria-labelledby={clsx(formFieldLabelledBy, inputLabelledBy)}\n aria-invalid={\n !isReadOnly ? isOutOfRange(value, min, max) : undefined\n }\n aria-valuemax={\n !isReadOnly\n ? toFloat(toFixedDecimalPlaces(max, decimalPlaces))\n : undefined\n }\n aria-valuemin={\n !isReadOnly\n ? toFloat(toFixedDecimalPlaces(min, decimalPlaces))\n : undefined\n }\n aria-valuenow={\n value && !Number.isNaN(toFloat(value)) && !isReadOnly\n ? toFloat(toFixedDecimalPlaces(toFloat(value), decimalPlaces))\n : undefined\n }\n className={clsx(\n withBaseName(\"input\"),\n withBaseName(`inputTextAlign${capitalize(textAlign)}`),\n inputClassName,\n )}\n disabled={isDisabled}\n onBlur={handleInputBlur}\n onChange={handleInputChange}\n onFocus={!isDisabled ? handleInputFocus : undefined}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n aria-readonly={isReadOnly ? \"true\" : undefined}\n ref={forkedInputRef}\n required={isRequired}\n // Workaround to have readonly conveyed by screen readers (https://github.com/jpmorganchase/salt-ds/issues/4586)\n role={isReadOnly ? \"textbox\" : \"spinbutton\"}\n tabIndex={isDisabled ? -1 : 0}\n value={value}\n {...restInputProps}\n />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n\n {!hideButtons && !isReadOnly && (\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonIncrement\"),\n )}\n {...incrementButtonProps}\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"stepperButtonDecrement\"),\n )}\n {...decrementButtonProps}\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["StepperInput","stepperInputCss"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salt-ds/lab",
3
- "version": "1.0.0-alpha.60",
3
+ "version": "1.0.0-alpha.61",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,9 +21,9 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "@floating-ui/react": "^0.26.28",
24
- "@salt-ds/core": "^1.40.0",
24
+ "@salt-ds/core": "^1.41.0",
25
25
  "@salt-ds/date-adapters": "0.1.0-alpha.2",
26
- "@salt-ds/icons": "^1.13.1",
26
+ "@salt-ds/icons": "^1.13.2",
27
27
  "@salt-ds/styles": "0.2.1",
28
28
  "@salt-ds/window": "0.1.1",
29
29
  "@types/react-window": "^1.8.2",