@fluentui/react-spinbutton 9.0.0-beta.9 → 9.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. package/CHANGELOG.json +558 -1
  2. package/CHANGELOG.md +163 -2
  3. package/README.md +4 -6
  4. package/dist/index.d.ts +49 -60
  5. package/lib/components/SpinButton/SpinButton.js.map +1 -1
  6. package/lib/components/SpinButton/SpinButton.types.js.map +1 -1
  7. package/lib/components/SpinButton/renderSpinButton.js.map +1 -1
  8. package/lib/components/SpinButton/useSpinButton.js +148 -111
  9. package/lib/components/SpinButton/useSpinButton.js.map +1 -1
  10. package/lib/components/SpinButton/useSpinButtonStyles.js +22 -16
  11. package/lib/components/SpinButton/useSpinButtonStyles.js.map +1 -1
  12. package/lib/index.js.map +1 -1
  13. package/lib/utils/clamp.js +6 -12
  14. package/lib/utils/clamp.js.map +1 -1
  15. package/lib/utils/getBound.js.map +1 -1
  16. package/lib/utils/precision.js.map +1 -1
  17. package/lib-commonjs/components/SpinButton/SpinButton.js.map +1 -1
  18. package/lib-commonjs/components/SpinButton/renderSpinButton.js.map +1 -1
  19. package/lib-commonjs/components/SpinButton/useSpinButton.js +146 -110
  20. package/lib-commonjs/components/SpinButton/useSpinButton.js.map +1 -1
  21. package/lib-commonjs/components/SpinButton/useSpinButtonStyles.js +22 -16
  22. package/lib-commonjs/components/SpinButton/useSpinButtonStyles.js.map +1 -1
  23. package/lib-commonjs/index.js.map +1 -1
  24. package/lib-commonjs/utils/clamp.js +10 -16
  25. package/lib-commonjs/utils/clamp.js.map +1 -1
  26. package/lib-commonjs/utils/getBound.js.map +1 -1
  27. package/lib-commonjs/utils/precision.js.map +1 -1
  28. package/package.json +13 -14
  29. package/lib/SpinButton.d.ts +0 -1
  30. package/lib/components/SpinButton/SpinButton.d.ts +0 -6
  31. package/lib/components/SpinButton/SpinButton.strings.d.ts +0 -2
  32. package/lib/components/SpinButton/SpinButton.strings.js +0 -5
  33. package/lib/components/SpinButton/SpinButton.strings.js.map +0 -1
  34. package/lib/components/SpinButton/SpinButton.types.d.ts +0 -141
  35. package/lib/components/SpinButton/index.d.ts +0 -5
  36. package/lib/components/SpinButton/renderSpinButton.d.ts +0 -5
  37. package/lib/components/SpinButton/useSpinButton.d.ts +0 -12
  38. package/lib/components/SpinButton/useSpinButtonStyles.d.ts +0 -7
  39. package/lib/index.d.ts +0 -2
  40. package/lib/tsdoc-metadata.json +0 -11
  41. package/lib/utils/clamp.d.ts +0 -1
  42. package/lib/utils/getBound.d.ts +0 -2
  43. package/lib/utils/index.d.ts +0 -3
  44. package/lib/utils/precision.d.ts +0 -14
  45. package/lib-commonjs/SpinButton.d.ts +0 -1
  46. package/lib-commonjs/components/SpinButton/SpinButton.d.ts +0 -6
  47. package/lib-commonjs/components/SpinButton/SpinButton.strings.d.ts +0 -2
  48. package/lib-commonjs/components/SpinButton/SpinButton.strings.js +0 -11
  49. package/lib-commonjs/components/SpinButton/SpinButton.strings.js.map +0 -1
  50. package/lib-commonjs/components/SpinButton/SpinButton.types.d.ts +0 -141
  51. package/lib-commonjs/components/SpinButton/index.d.ts +0 -5
  52. package/lib-commonjs/components/SpinButton/renderSpinButton.d.ts +0 -5
  53. package/lib-commonjs/components/SpinButton/useSpinButton.d.ts +0 -12
  54. package/lib-commonjs/components/SpinButton/useSpinButtonStyles.d.ts +0 -7
  55. package/lib-commonjs/index.d.ts +0 -2
  56. package/lib-commonjs/utils/clamp.d.ts +0 -1
  57. package/lib-commonjs/utils/getBound.d.ts +0 -2
  58. package/lib-commonjs/utils/index.d.ts +0 -3
  59. package/lib-commonjs/utils/precision.d.ts +0 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["components/SpinButton/useSpinButtonStyles.ts"],"names":[],"mappings":"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","sourcesContent":["import { SlotClassNames } from '@fluentui/react-utilities';\nimport { makeStyles, mergeClasses, shorthands } from '@griffel/react';\nimport type { SpinButtonSlots, SpinButtonState } from './SpinButton.types';\nimport { tokens } from '@fluentui/react-theme';\nimport { useInputStyles_unstable } from '@fluentui/react-input';\n\nexport const spinButtonClassNames: SlotClassNames<SpinButtonSlots> = {\n root: 'fui-SpinButton',\n input: 'fui-SpinButton__input',\n incrementButton: 'fui-SpinButton__incrementButton',\n decrementButton: 'fui-SpinButton__decrementButton',\n};\n\nconst spinButtonExtraClassNames = {\n buttonActive: 'fui-SpinButton__button_active',\n};\n\n// TODO(sharing) use theme values once available\nconst horizontalSpacing = {\n xs: '4px',\n};\n\nconst useRootStyles = makeStyles({\n base: {\n display: 'inline-grid',\n gridTemplateColumns: `1fr 24px`,\n gridTemplateRows: '1fr 1fr',\n columnGap: horizontalSpacing.xs,\n rowGap: 0,\n paddingRight: 0,\n position: 'relative',\n // Remove the border styles from react-input\n ...shorthands.border('0'),\n isolation: 'isolate',\n\n // Apply border styles on the ::before pseudo element.\n // We cannot use ::after since react-input uses that\n // for the selector styles.\n // Using the pseudo element allows us to place the border\n // above content in the component which ensures the buttons\n // line up visually with the border as expected. Without this\n // there is a bit of a gap which can become very noticeable\n // at high zoom or when OS zoom levels are not divisible by 2\n // (e.g., 150% on Windows in Firefox)\n // This is most noticeable on the \"outline\" appearance which is\n // also the default so it feels worth the extra ceremony to get right.\n '::before': {\n content: '\"\"',\n boxSizing: 'border-box',\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n pointerEvents: 'none',\n zIndex: 10,\n },\n\n '::after': {\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: 20,\n },\n },\n\n outline: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorNeutralStroke1),\n borderBottomColor: tokens.colorNeutralStrokeAccessible,\n },\n },\n\n outlineInteractive: {\n ':hover': {\n '::before': {\n ...shorthands.borderColor(tokens.colorNeutralStroke1Hover),\n borderBottomColor: tokens.colorNeutralStrokeAccessibleHover,\n },\n },\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':active,:focus-within': {\n '::before': {\n ...shorthands.borderColor(tokens.colorNeutralStroke1Pressed),\n borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed,\n },\n },\n },\n\n underline: {\n '::before': {\n ...shorthands.borderRadius(0), // corners look strange if rounded\n ...shorthands.borderBottom('1px', 'solid', tokens.colorNeutralStrokeAccessible),\n },\n },\n\n underlineInteractive: {\n ':hover': {\n '::before': {\n borderBottomColor: tokens.colorNeutralStrokeAccessibleHover,\n },\n },\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':active,:focus-within': {\n '::before': {\n borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed,\n },\n },\n },\n\n filled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorTransparentStroke),\n },\n },\n\n filledInteractive: {\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':hover,:focus-within': {\n '::before': {\n // also handles pressed border color (:active)\n ...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),\n },\n },\n },\n\n disabled: {\n '@media (forced-colors: active)': {\n ...shorthands.borderColor('GrayText'),\n },\n },\n\n outlineDisabled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorNeutralStrokeDisabled),\n ...shorthands.borderRadius(tokens.borderRadiusMedium), // because underline doesn't usually have a radius\n },\n },\n\n underlineDisabled: {\n '::before': {\n ...shorthands.borderBottom('1px', 'solid', tokens.colorTransparentStrokeDisabled),\n },\n },\n\n filledDisabled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorTransparentStrokeDisabled),\n },\n },\n});\n\nconst useInputStyles = makeStyles({\n base: {\n gridColumnStart: '1',\n gridColumnEnd: '2',\n gridRowStart: '1',\n gridRowEnd: '3',\n ...shorthands.padding(0),\n },\n});\n\nconst useButtonStyles = makeStyles({\n base: {\n display: 'inline-flex',\n width: '24px',\n alignItems: 'center',\n justifyContent: 'center',\n ...shorthands.border(0),\n position: 'absolute',\n\n outlineStyle: 'none',\n height: '100%',\n\n ':enabled:hover': {\n cursor: 'pointer',\n },\n\n ':active': {\n outlineStyle: 'none',\n },\n\n ':disabled': {\n cursor: 'not-allowed',\n },\n },\n\n incrementButton: {\n gridColumnStart: '2',\n gridColumnEnd: '3',\n gridRowStart: '1',\n gridRowEnd: '2',\n ...shorthands.borderRadius(0, tokens.borderRadiusMedium, 0, 0),\n },\n\n // TODO: revisit these padding numbers for aligning the icon.\n // Padding values aren't perfect.\n // The icon doesn't align perfectly with the Figma designs.\n // It's set in a 16x16px square but the artwork is inset from that\n // so I've had to compute the numbers by handle.\n // Additionally the design uses fractional values so these are\n // rounded to the nearest integer.\n incrementButtonSmall: {\n ...shorthands.padding('3px', '5px', '0px', '5px'),\n },\n\n incrementButtonMedium: {\n ...shorthands.padding('4px', '5px', '1px', '5px'),\n },\n\n decrementButton: {\n gridColumnStart: '2',\n gridColumnEnd: '3',\n gridRowStart: '2',\n gridRowEnd: '3',\n ...shorthands.borderRadius(0, 0, tokens.borderRadiusMedium, 0),\n },\n\n decrementButtonSmall: {\n ...shorthands.padding('0px', '5px', '3px', '5px'),\n },\n\n decrementButtonMedium: {\n ...shorthands.padding('1px', '5px', '4px', '5px'),\n },\n\n outline: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorSubtleBackgroundHover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n\n underline: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorSubtleBackgroundHover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n filledDarker: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorNeutralBackground3Hover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground3Pressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground3Pressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n filledLighter: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorNeutralBackground1Hover,\n },\n [`:active,&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground1Pressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n});\n\n// Cannot just disable button as they need to remain\n// exposed to ATs like screen readers.\nconst useButtonDisabledStyles = makeStyles({\n base: {\n cursor: 'not-allowed',\n\n ':hover': {\n cursor: 'not-allowed',\n },\n },\n\n outline: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n underline: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n filledDarker: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n filledLighter: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n});\n\n/**\n * Apply styling to the SpinButton slots based on the state\n */\nexport const useSpinButtonStyles_unstable = (state: SpinButtonState): SpinButtonState => {\n const { appearance, atBound, size } = state;\n const disabled = state.input.disabled;\n const filled = appearance.startsWith('filled');\n\n const rootStyles = useRootStyles();\n const buttonStyles = useButtonStyles();\n const buttonDisabledStyles = useButtonDisabledStyles();\n const inputStyles = useInputStyles();\n\n // Grab the root className here so we can be sure to merge is last\n const rootClassName = state.root.className;\n state.root.className = undefined;\n // Reuse react-input's styles without re-using the Input component.\n useInputStyles_unstable({\n size,\n appearance,\n input: state.input,\n root: state.root,\n components: {\n root: 'span',\n input: 'input',\n contentBefore: 'span',\n contentAfter: 'span',\n },\n });\n\n state.root.className = mergeClasses(\n state.root.className, // Get the classes from useInputStyles_unstable\n spinButtonClassNames.root,\n rootStyles.base,\n appearance === 'outline' && rootStyles.outline,\n appearance === 'underline' && rootStyles.underline,\n filled && rootStyles.filled,\n !disabled && appearance === 'outline' && rootStyles.outlineInteractive,\n !disabled && appearance === 'underline' && rootStyles.underlineInteractive,\n !disabled && filled && rootStyles.filledInteractive,\n disabled && rootStyles.disabled,\n disabled && appearance === 'outline' && rootStyles.outlineDisabled,\n disabled && appearance === 'underline' && rootStyles.underlineDisabled,\n disabled && filled && rootStyles.filledDisabled,\n rootClassName, // Make sure any original class name is applied last\n );\n\n state.incrementButton.className = mergeClasses(\n spinButtonClassNames.incrementButton,\n state.spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`,\n buttonStyles.base,\n buttonStyles.incrementButton,\n buttonStyles[appearance],\n size === 'small' ? buttonStyles.incrementButtonSmall : buttonStyles.incrementButtonMedium,\n (atBound === 'max' || atBound === 'both') && buttonDisabledStyles.base,\n (atBound === 'max' || atBound === 'both') && buttonDisabledStyles[appearance],\n state.incrementButton.className,\n );\n state.decrementButton.className = mergeClasses(\n spinButtonClassNames.decrementButton,\n state.spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`,\n buttonStyles.base,\n buttonStyles.decrementButton,\n buttonStyles[appearance],\n size === 'small' ? buttonStyles.decrementButtonSmall : buttonStyles.decrementButtonMedium,\n (atBound === 'min' || atBound === 'both') && buttonDisabledStyles.base,\n (atBound === 'min' || atBound === 'both') && buttonDisabledStyles[appearance],\n state.decrementButton.className,\n );\n\n state.input.className = mergeClasses(spinButtonClassNames.input, state.input.className, inputStyles.base);\n\n return state;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/SpinButton/useSpinButtonStyles.ts"],"names":[],"mappings":"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","sourcesContent":["import { SlotClassNames } from '@fluentui/react-utilities';\nimport { makeStyles, mergeClasses, shorthands } from '@griffel/react';\nimport type { SpinButtonSlots, SpinButtonState } from './SpinButton.types';\nimport { tokens } from '@fluentui/react-theme';\nimport { useInputStyles_unstable } from '@fluentui/react-input';\n\nexport const spinButtonClassNames: SlotClassNames<SpinButtonSlots> = {\n root: 'fui-SpinButton',\n input: 'fui-SpinButton__input',\n incrementButton: 'fui-SpinButton__incrementButton',\n decrementButton: 'fui-SpinButton__decrementButton',\n};\n\nconst spinButtonExtraClassNames = {\n buttonActive: 'fui-SpinButton__button_active',\n};\n\nconst useRootStyles = makeStyles({\n base: {\n display: 'inline-grid',\n gridTemplateColumns: `1fr 24px`,\n gridTemplateRows: '1fr 1fr',\n columnGap: tokens.spacingHorizontalXS,\n rowGap: 0,\n paddingRight: 0,\n position: 'relative',\n // Remove the border styles from react-input\n ...shorthands.border('0'),\n isolation: 'isolate',\n\n // Apply border styles on the ::before pseudo element.\n // We cannot use ::after since react-input uses that\n // for the selector styles.\n // Using the pseudo element allows us to place the border\n // above content in the component which ensures the buttons\n // line up visually with the border as expected. Without this\n // there is a bit of a gap which can become very noticeable\n // at high zoom or when OS zoom levels are not divisible by 2\n // (e.g., 150% on Windows in Firefox)\n // This is most noticeable on the \"outline\" appearance which is\n // also the default so it feels worth the extra ceremony to get right.\n '::before': {\n content: '\"\"',\n boxSizing: 'border-box',\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n pointerEvents: 'none',\n zIndex: 10,\n },\n\n '::after': {\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: 20,\n },\n },\n\n outline: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorNeutralStroke1),\n borderBottomColor: tokens.colorNeutralStrokeAccessible,\n },\n },\n\n outlineInteractive: {\n ':hover': {\n '::before': {\n ...shorthands.borderColor(tokens.colorNeutralStroke1Hover),\n borderBottomColor: tokens.colorNeutralStrokeAccessibleHover,\n },\n },\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':active,:focus-within': {\n '::before': {\n ...shorthands.borderColor(tokens.colorNeutralStroke1Pressed),\n borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed,\n },\n },\n },\n\n underline: {\n '::before': {\n ...shorthands.borderRadius(0), // corners look strange if rounded\n ...shorthands.borderBottom('1px', 'solid', tokens.colorNeutralStrokeAccessible),\n },\n },\n\n underlineInteractive: {\n ':hover': {\n '::before': {\n borderBottomColor: tokens.colorNeutralStrokeAccessibleHover,\n },\n },\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':active,:focus-within': {\n '::before': {\n borderBottomColor: tokens.colorNeutralStrokeAccessiblePressed,\n },\n },\n },\n\n filled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorTransparentStroke),\n },\n },\n\n filledInteractive: {\n // DO NOT add a space between the selectors! It changes the behavior of make-styles.\n ':hover,:focus-within': {\n '::before': {\n // also handles pressed border color (:active)\n ...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),\n },\n },\n },\n\n disabled: {\n '@media (forced-colors: active)': {\n ...shorthands.borderColor('GrayText'),\n },\n },\n\n outlineDisabled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorNeutralStrokeDisabled),\n ...shorthands.borderRadius(tokens.borderRadiusMedium), // because underline doesn't usually have a radius\n },\n },\n\n underlineDisabled: {\n '::before': {\n ...shorthands.borderBottom('1px', 'solid', tokens.colorTransparentStrokeDisabled),\n },\n },\n\n filledDisabled: {\n '::before': {\n ...shorthands.border('1px', 'solid', tokens.colorTransparentStrokeDisabled),\n },\n },\n});\n\nconst useInputStyles = makeStyles({\n base: {\n gridColumnStart: '1',\n gridColumnEnd: '2',\n gridRowStart: '1',\n gridRowEnd: '3',\n outlineStyle: 'none',\n ...shorthands.padding(0),\n },\n});\n\nconst useButtonStyles = makeStyles({\n base: {\n display: 'inline-flex',\n width: '24px',\n alignItems: 'center',\n justifyContent: 'center',\n ...shorthands.border(0),\n position: 'absolute',\n\n outlineStyle: 'none',\n height: '100%',\n\n ':enabled:hover': {\n cursor: 'pointer',\n },\n\n ':active': {\n outlineStyle: 'none',\n },\n\n ':disabled': {\n cursor: 'not-allowed',\n },\n },\n\n incrementButton: {\n gridColumnStart: '2',\n gridColumnEnd: '3',\n gridRowStart: '1',\n gridRowEnd: '2',\n ...shorthands.borderRadius(0, tokens.borderRadiusMedium, 0, 0),\n },\n\n // TODO: revisit these padding numbers for aligning the icon.\n // Padding values aren't perfect.\n // The icon doesn't align perfectly with the Figma designs.\n // It's set in a 16x16px square but the artwork is inset from that\n // so I've had to compute the numbers by handle.\n // Additionally the design uses fractional values so these are\n // rounded to the nearest integer.\n incrementButtonSmall: {\n ...shorthands.padding('3px', '5px', '0px', '5px'),\n },\n\n incrementButtonMedium: {\n ...shorthands.padding('4px', '5px', '1px', '5px'),\n },\n\n decrementButton: {\n gridColumnStart: '2',\n gridColumnEnd: '3',\n gridRowStart: '2',\n gridRowEnd: '3',\n ...shorthands.borderRadius(0, 0, tokens.borderRadiusMedium, 0),\n },\n\n decrementButtonSmall: {\n ...shorthands.padding('0px', '5px', '3px', '5px'),\n },\n\n decrementButtonMedium: {\n ...shorthands.padding('1px', '5px', '4px', '5px'),\n },\n\n outline: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorSubtleBackgroundHover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n\n underline: {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorSubtleBackgroundHover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n 'filled-darker': {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorNeutralBackground3Hover,\n },\n ':active': {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground3Pressed,\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground3Pressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n 'filled-lighter': {\n backgroundColor: 'transparent',\n color: tokens.colorNeutralForeground3,\n\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForeground3Hover,\n backgroundColor: tokens.colorNeutralBackground1Hover,\n },\n [`:active,&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForeground3Pressed,\n backgroundColor: tokens.colorNeutralBackground1Pressed,\n },\n },\n ':disabled': {\n color: tokens.colorNeutralForegroundDisabled,\n },\n },\n});\n\n// Cannot just disable button as they need to remain\n// exposed to ATs like screen readers.\nconst useButtonDisabledStyles = makeStyles({\n base: {\n cursor: 'not-allowed',\n\n ':hover': {\n cursor: 'not-allowed',\n },\n },\n\n outline: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n underline: {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n 'filled-darker': {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n\n 'filled-lighter': {\n color: tokens.colorNeutralForegroundDisabled,\n ':enabled': {\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n ':active': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n [`&.${spinButtonExtraClassNames.buttonActive}`]: {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: 'transparent',\n },\n },\n },\n});\n\n/**\n * Apply styling to the SpinButton slots based on the state\n */\nexport const useSpinButtonStyles_unstable = (state: SpinButtonState): SpinButtonState => {\n const { appearance, atBound, spinState, size } = state;\n const disabled = state.input.disabled;\n const filled = appearance.startsWith('filled');\n\n const rootStyles = useRootStyles();\n const buttonStyles = useButtonStyles();\n const buttonDisabledStyles = useButtonDisabledStyles();\n const inputStyles = useInputStyles();\n\n // Grab the root className here so we can be sure to merge is last\n const rootClassName = state.root.className;\n state.root.className = undefined;\n // Reuse react-input's styles without re-using the Input component.\n useInputStyles_unstable({\n size,\n appearance,\n input: state.input,\n root: state.root,\n components: {\n root: 'span',\n input: 'input',\n contentBefore: 'span',\n contentAfter: 'span',\n },\n });\n\n state.root.className = mergeClasses(\n state.root.className, // Get the classes from useInputStyles_unstable\n spinButtonClassNames.root,\n rootStyles.base,\n appearance === 'outline' && rootStyles.outline,\n appearance === 'underline' && rootStyles.underline,\n filled && rootStyles.filled,\n !disabled && appearance === 'outline' && rootStyles.outlineInteractive,\n !disabled && appearance === 'underline' && rootStyles.underlineInteractive,\n !disabled && filled && rootStyles.filledInteractive,\n disabled && rootStyles.disabled,\n disabled && appearance === 'outline' && rootStyles.outlineDisabled,\n disabled && appearance === 'underline' && rootStyles.underlineDisabled,\n disabled && filled && rootStyles.filledDisabled,\n rootClassName, // Make sure any original class name is applied last\n );\n\n state.incrementButton.className = mergeClasses(\n spinButtonClassNames.incrementButton,\n spinState === 'up' && `${spinButtonExtraClassNames.buttonActive}`,\n buttonStyles.base,\n buttonStyles.incrementButton,\n buttonStyles[appearance],\n size === 'small' ? buttonStyles.incrementButtonSmall : buttonStyles.incrementButtonMedium,\n (atBound === 'max' || atBound === 'both') && buttonDisabledStyles.base,\n (atBound === 'max' || atBound === 'both') && buttonDisabledStyles[appearance],\n state.incrementButton.className,\n );\n state.decrementButton.className = mergeClasses(\n spinButtonClassNames.decrementButton,\n spinState === 'down' && `${spinButtonExtraClassNames.buttonActive}`,\n buttonStyles.base,\n buttonStyles.decrementButton,\n buttonStyles[appearance],\n size === 'small' ? buttonStyles.decrementButtonSmall : buttonStyles.decrementButtonMedium,\n (atBound === 'min' || atBound === 'both') && buttonDisabledStyles.base,\n (atBound === 'min' || atBound === 'both') && buttonDisabledStyles[appearance],\n state.decrementButton.className,\n );\n\n state.input.className = mergeClasses(spinButtonClassNames.input, state.input.className, inputStyles.base);\n\n return state;\n};\n"],"sourceRoot":"../src/"}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"names":[],"mappings":"AAAA,SACE,UADF,EAEE,yBAFF,EAGE,oBAHF,EAIE,4BAJF,EAKE,sBALF,QAMO,cANP","sourcesContent":["export {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButton_unstable,\n} from './SpinButton';\nexport type {\n SpinButtonOnChangeData,\n SpinButtonChangeEvent,\n SpinButtonCommons,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonState,\n SpinButtonSpinState,\n SpinButtonBounds,\n SpinButtonStrings,\n} from './SpinButton';\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["index.ts"],"names":[],"mappings":"AAAA,SACE,UADF,EAEE,yBAFF,EAGE,oBAHF,EAIE,4BAJF,EAKE,sBALF,QAMO,cANP","sourcesContent":["export {\n SpinButton,\n renderSpinButton_unstable,\n spinButtonClassNames,\n useSpinButtonStyles_unstable,\n useSpinButton_unstable,\n} from './SpinButton';\nexport type {\n SpinButtonOnChangeData,\n SpinButtonChangeEvent,\n SpinButtonProps,\n SpinButtonSlots,\n SpinButtonState,\n SpinButtonSpinState,\n SpinButtonBounds,\n} from './SpinButton';\n"],"sourceRoot":"../src/"}
@@ -1,28 +1,22 @@
1
- export const clampWhenInRange = (oldValue, newValue, min, max) => {
2
- // When oldValue is in the range of [min, max] clamp newValue.
3
- // Don't clamp values outside this range so users get a
4
- // more natural behavior. For example, if the range is [5, 15]
5
- // and the user types 1 into the input we don't want to clamp
6
- // the value when they next press the increment button because
7
- // clamping would snap the value to 5 rather than increment to 2.
8
- let nextValue = newValue;
1
+ export const clamp = (value, min, max) => {
2
+ let nextValue = value;
9
3
 
10
- if (min !== undefined && oldValue >= min) {
4
+ if (min !== undefined) {
11
5
  if (max !== undefined && min > max) {
12
6
  const error = new Error();
13
7
 
14
8
  if (process.env.NODE_ENV !== 'production') {
15
9
  // eslint-disable-next-line no-console
16
- console.error([`"min" value "${min}" is greater than "max" value "${max}".`, '"min" must be less than or equal to "max".', `Returning value "${newValue}".`, error.stack].join());
10
+ console.error([`"min" value "${min}" is greater than "max" value "${max}".`, '"min" must be less than or equal to "max".', `Returning value "${value}".`, error.stack].join());
17
11
  }
18
12
 
19
- return newValue;
13
+ return value;
20
14
  }
21
15
 
22
16
  nextValue = Math.max(min, nextValue);
23
17
  }
24
18
 
25
- if (max !== undefined && oldValue <= max) {
19
+ if (max !== undefined) {
26
20
  nextValue = Math.min(max, nextValue);
27
21
  }
28
22
 
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/clamp.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,gBAAgB,GAAG,CAAC,QAAD,EAAmB,QAAnB,EAAqC,GAArC,EAAmD,GAAnD,KAA2E;AACzG;AACA;AACA;AACA;AACA;AACA;AACA,MAAI,SAAS,GAAG,QAAhB;;AACA,MAAI,GAAG,KAAK,SAAR,IAAqB,QAAQ,IAAI,GAArC,EAA0C;AACxC,QAAI,GAAG,KAAK,SAAR,IAAqB,GAAG,GAAG,GAA/B,EAAoC;AAClC,YAAM,KAAK,GAAG,IAAI,KAAJ,EAAd;;AACA,UAAI,OAAO,CAAC,GAAR,CAAY,QAAZ,KAAyB,YAA7B,EAA2C;AACzC;AACA,QAAA,OAAO,CAAC,KAAR,CACE,CACE,gBAAgB,GAAG,kCAAkC,GAAG,IAD1D,EAEE,4CAFF,EAGE,oBAAoB,QAAQ,IAH9B,EAIE,KAAK,CAAC,KAJR,EAKE,IALF,EADF;AAQD;;AACD,aAAO,QAAP;AACD;;AAED,IAAA,SAAS,GAAG,IAAI,CAAC,GAAL,CAAS,GAAT,EAAc,SAAd,CAAZ;AACD;;AAED,MAAI,GAAG,KAAK,SAAR,IAAqB,QAAQ,IAAI,GAArC,EAA0C;AACxC,IAAA,SAAS,GAAG,IAAI,CAAC,GAAL,CAAS,GAAT,EAAc,SAAd,CAAZ;AACD;;AAED,SAAO,SAAP;AACD,CAjCM","sourcesContent":["export const clampWhenInRange = (oldValue: number, newValue: number, min?: number, max?: number): number => {\n // When oldValue is in the range of [min, max] clamp newValue.\n // Don't clamp values outside this range so users get a\n // more natural behavior. For example, if the range is [5, 15]\n // and the user types 1 into the input we don't want to clamp\n // the value when they next press the increment button because\n // clamping would snap the value to 5 rather than increment to 2.\n let nextValue = newValue;\n if (min !== undefined && oldValue >= min) {\n if (max !== undefined && min > max) {\n const error = new Error();\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n [\n `\"min\" value \"${min}\" is greater than \"max\" value \"${max}\".`,\n '\"min\" must be less than or equal to \"max\".',\n `Returning value \"${newValue}\".`,\n error.stack,\n ].join(),\n );\n }\n return newValue;\n }\n\n nextValue = Math.max(min, nextValue);\n }\n\n if (max !== undefined && oldValue <= max) {\n nextValue = Math.min(max, nextValue);\n }\n\n return nextValue;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/clamp.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,KAAK,GAAG,CAAC,KAAD,EAAgB,GAAhB,EAA8B,GAA9B,KAAsD;EACzE,IAAI,SAAS,GAAG,KAAhB;;EACA,IAAI,GAAG,KAAK,SAAZ,EAAuB;IACrB,IAAI,GAAG,KAAK,SAAR,IAAqB,GAAG,GAAG,GAA/B,EAAoC;MAClC,MAAM,KAAK,GAAG,IAAI,KAAJ,EAAd;;MACA,IAAI,OAAO,CAAC,GAAR,CAAY,QAAZ,KAAyB,YAA7B,EAA2C;QACzC;QACA,OAAO,CAAC,KAAR,CACE,CACE,gBAAgB,GAAG,kCAAkC,GAAG,IAD1D,EAEE,4CAFF,EAGE,oBAAoB,KAAK,IAH3B,EAIE,KAAK,CAAC,KAJR,EAKE,IALF,EADF;MAQD;;MACD,OAAO,KAAP;IACD;;IAED,SAAS,GAAG,IAAI,CAAC,GAAL,CAAS,GAAT,EAAc,SAAd,CAAZ;EACD;;EAED,IAAI,GAAG,KAAK,SAAZ,EAAuB;IACrB,SAAS,GAAG,IAAI,CAAC,GAAL,CAAS,GAAT,EAAc,SAAd,CAAZ;EACD;;EAED,OAAO,SAAP;AACD,CA3BM","sourcesContent":["export const clamp = (value: number, min?: number, max?: number): number => {\n let nextValue = value;\n if (min !== undefined) {\n if (max !== undefined && min > max) {\n const error = new Error();\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n [\n `\"min\" value \"${min}\" is greater than \"max\" value \"${max}\".`,\n '\"min\" must be less than or equal to \"max\".',\n `Returning value \"${value}\".`,\n error.stack,\n ].join(),\n );\n }\n return value;\n }\n\n nextValue = Math.max(min, nextValue);\n }\n\n if (max !== undefined) {\n nextValue = Math.min(max, nextValue);\n }\n\n return nextValue;\n};\n"],"sourceRoot":"../src/"}
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/getBound.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,QAAQ,GAAG,CAAC,KAAD,EAAgB,GAAhB,EAA8B,GAA9B,KAAgE;AACtF,MAAI,GAAG,KAAK,SAAR,IAAqB,KAAK,KAAK,GAAnC,EAAwC;AACtC,QAAI,GAAG,KAAK,GAAZ,EAAiB;AACf,aAAO,MAAP;AACD;;AACD,WAAO,KAAP;AACD,GALD,MAKO,IAAI,GAAG,KAAK,SAAR,IAAqB,KAAK,KAAK,GAAnC,EAAwC;AAC7C,WAAO,KAAP;AACD;;AAED,SAAO,MAAP;AACD,CAXM","sourcesContent":["import type { SpinButtonBounds } from '../SpinButton';\n\nexport const getBound = (value: number, min?: number, max?: number): SpinButtonBounds => {\n if (min !== undefined && value === min) {\n if (max === min) {\n return 'both';\n }\n return 'min';\n } else if (max !== undefined && value === max) {\n return 'max';\n }\n\n return 'none';\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/getBound.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,QAAQ,GAAG,CAAC,KAAD,EAAgB,GAAhB,EAA8B,GAA9B,KAAgE;EACtF,IAAI,GAAG,KAAK,SAAR,IAAqB,KAAK,KAAK,GAAnC,EAAwC;IACtC,IAAI,GAAG,KAAK,GAAZ,EAAiB;MACf,OAAO,MAAP;IACD;;IACD,OAAO,KAAP;EACD,CALD,MAKO,IAAI,GAAG,KAAK,SAAR,IAAqB,KAAK,KAAK,GAAnC,EAAwC;IAC7C,OAAO,KAAP;EACD;;EAED,OAAO,MAAP;AACD,CAXM","sourcesContent":["import type { SpinButtonBounds } from '../SpinButton';\n\nexport const getBound = (value: number, min?: number, max?: number): SpinButtonBounds => {\n if (min !== undefined && value === min) {\n if (max === min) {\n return 'both';\n }\n return 'min';\n } else if (max !== undefined && value === max) {\n return 'max';\n }\n\n return 'none';\n};\n"],"sourceRoot":"../src/"}
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/precision.ts"],"names":[],"mappings":"AAAA;;;;;;AAMG;AACH,OAAM,SAAU,kBAAV,CAA6B,KAA7B,EAAmD;AACvD;;;;;AAKG;AACH,QAAM,MAAM,GAAG,0BAA0B,IAA1B,CAA+B,MAAM,CAAC,KAAD,CAArC,CAAf;;AACA,MAAI,CAAC,MAAL,EAAa;AACX,WAAO,CAAP;AACD;;AACD,MAAI,MAAM,CAAC,CAAD,CAAV,EAAe;AACb,WAAO,CAAC,MAAM,CAAC,CAAD,CAAN,CAAU,MAAlB;AACD;;AACD,MAAI,MAAM,CAAC,CAAD,CAAV,EAAe;AACb,WAAO,MAAM,CAAC,CAAD,CAAN,CAAU,MAAjB;AACD;;AACD,SAAO,CAAP;AACD;AAED;;;;AAIG;;AACH,OAAM,SAAU,cAAV,CAAyB,KAAzB,EAAwC,SAAxC,EAA2D,IAAA,GAAe,EAA1E,EAA4E;AAChF,QAAM,GAAG,GAAG,IAAI,CAAC,GAAL,CAAS,IAAT,EAAe,SAAf,CAAZ;AACA,SAAO,IAAI,CAAC,KAAL,CAAW,KAAK,GAAG,GAAnB,IAA0B,GAAjC;AACD","sourcesContent":["/**\n * Calculates a number's precision based on the number of trailing\n * zeros if the number does not have a decimal indicated by a negative\n * precision. Otherwise, it calculates the number of digits after\n * the decimal point indicated by a positive precision.\n * @param value - the value to determine the precision of\n */\nexport function calculatePrecision(value: number | string): number {\n /**\n * Group 1:\n * [1-9]([0]+$) matches trailing zeros\n * Group 2:\n * \\.([0-9]*) matches all digits after a decimal point.\n */\n const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\n if (!groups) {\n return 0;\n }\n if (groups[1]) {\n return -groups[1].length;\n }\n if (groups[2]) {\n return groups[2].length;\n }\n return 0;\n}\n\n/**\n * Rounds a number to a certain level of precision. Accepts negative precision.\n * @param value - The value that is being rounded.\n * @param precision - The number of decimal places to round the number to\n */\nexport function precisionRound(value: number, precision: number, base: number = 10): number {\n const exp = Math.pow(base, precision);\n return Math.round(value * exp) / exp;\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/precision.ts"],"names":[],"mappings":"AAAA;;;;;;AAMG;AACH,OAAM,SAAU,kBAAV,CAA6B,KAA7B,EAAmD;EACvD;;;;;AAKG;EACH,MAAM,MAAM,GAAG,0BAA0B,IAA1B,CAA+B,MAAM,CAAC,KAAD,CAArC,CAAf;;EACA,IAAI,CAAC,MAAL,EAAa;IACX,OAAO,CAAP;EACD;;EACD,IAAI,MAAM,CAAC,CAAD,CAAV,EAAe;IACb,OAAO,CAAC,MAAM,CAAC,CAAD,CAAN,CAAU,MAAlB;EACD;;EACD,IAAI,MAAM,CAAC,CAAD,CAAV,EAAe;IACb,OAAO,MAAM,CAAC,CAAD,CAAN,CAAU,MAAjB;EACD;;EACD,OAAO,CAAP;AACD;AAED;;;;AAIG;;AACH,OAAM,SAAU,cAAV,CAAyB,KAAzB,EAAwC,SAAxC,EAA2D,IAAA,GAAe,EAA1E,EAA4E;EAChF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAL,CAAS,IAAT,EAAe,SAAf,CAAZ;EACA,OAAO,IAAI,CAAC,KAAL,CAAW,KAAK,GAAG,GAAnB,IAA0B,GAAjC;AACD","sourcesContent":["/**\n * Calculates a number's precision based on the number of trailing\n * zeros if the number does not have a decimal indicated by a negative\n * precision. Otherwise, it calculates the number of digits after\n * the decimal point indicated by a positive precision.\n * @param value - the value to determine the precision of\n */\nexport function calculatePrecision(value: number | string): number {\n /**\n * Group 1:\n * [1-9]([0]+$) matches trailing zeros\n * Group 2:\n * \\.([0-9]*) matches all digits after a decimal point.\n */\n const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\n if (!groups) {\n return 0;\n }\n if (groups[1]) {\n return -groups[1].length;\n }\n if (groups[2]) {\n return groups[2].length;\n }\n return 0;\n}\n\n/**\n * Rounds a number to a certain level of precision. Accepts negative precision.\n * @param value - The value that is being rounded.\n * @param precision - The number of decimal places to round the number to\n */\nexport function precisionRound(value: number, precision: number, base: number = 10): number {\n const exp = Math.pow(base, precision);\n return Math.round(value * exp) / exp;\n}\n"],"sourceRoot":"../src/"}
@@ -1 +1 @@
1
- {"version":3,"sources":["components/SpinButton/SpinButton.tsx"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,eAAA,gBAAA,OAAA,CAAA,iBAAA,CAAA;;AACA,MAAA,kBAAA,gBAAA,OAAA,CAAA,oBAAA,CAAA;;AACA,MAAA,qBAAA,gBAAA,OAAA,CAAA,uBAAA,CAAA;AAIA;;AAEG;;;AACU,OAAA,CAAA,UAAA,gBAAmD,KAAK,CAAC,UAAN,CAAiB,CAAC,KAAD,EAAQ,GAAR,KAAe;AAC9F,QAAM,KAAK,GAAG,eAAA,CAAA,sBAAA,CAAuB,KAAvB,EAA8B,GAA9B,CAAd;AAEA,EAAA,qBAAA,CAAA,4BAAA,CAA6B,KAA7B;AACA,SAAO,kBAAA,CAAA,yBAAA,CAA0B,KAA1B,CAAP;AACD,CAL+D,CAAnD;AAOb,OAAA,CAAA,UAAA,CAAW,WAAX,GAAyB,YAAzB","sourcesContent":["import * as React from 'react';\nimport { useSpinButton_unstable } from './useSpinButton';\nimport { renderSpinButton_unstable } from './renderSpinButton';\nimport { useSpinButtonStyles_unstable } from './useSpinButtonStyles';\nimport type { SpinButtonProps } from './SpinButton.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\n\n/**\n * A SpinButton allows someone to incrementally adjust a value in small steps.\n */\nexport const SpinButton: ForwardRefComponent<SpinButtonProps> = React.forwardRef((props, ref) => {\n const state = useSpinButton_unstable(props, ref);\n\n useSpinButtonStyles_unstable(state);\n return renderSpinButton_unstable(state);\n});\n\nSpinButton.displayName = 'SpinButton';\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/SpinButton/SpinButton.tsx"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,eAAA,gBAAA,OAAA,CAAA,iBAAA,CAAA;;AACA,MAAA,kBAAA,gBAAA,OAAA,CAAA,oBAAA,CAAA;;AACA,MAAA,qBAAA,gBAAA,OAAA,CAAA,uBAAA,CAAA;AAIA;;AAEG;;;AACU,OAAA,CAAA,UAAA,gBAAmD,KAAK,CAAC,UAAN,CAAiB,CAAC,KAAD,EAAQ,GAAR,KAAe;EAC9F,MAAM,KAAK,GAAG,eAAA,CAAA,sBAAA,CAAuB,KAAvB,EAA8B,GAA9B,CAAd;EAEA,qBAAA,CAAA,4BAAA,CAA6B,KAA7B;EACA,OAAO,kBAAA,CAAA,yBAAA,CAA0B,KAA1B,CAAP;AACD,CAL+D,CAAnD;AAOb,OAAA,CAAA,UAAA,CAAW,WAAX,GAAyB,YAAzB","sourcesContent":["import * as React from 'react';\nimport { useSpinButton_unstable } from './useSpinButton';\nimport { renderSpinButton_unstable } from './renderSpinButton';\nimport { useSpinButtonStyles_unstable } from './useSpinButtonStyles';\nimport type { SpinButtonProps } from './SpinButton.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\n\n/**\n * A SpinButton allows someone to incrementally adjust a value in small steps.\n */\nexport const SpinButton: ForwardRefComponent<SpinButtonProps> = React.forwardRef((props, ref) => {\n const state = useSpinButton_unstable(props, ref);\n\n useSpinButtonStyles_unstable(state);\n return renderSpinButton_unstable(state);\n});\n\nSpinButton.displayName = 'SpinButton';\n"],"sourceRoot":"../src/"}
@@ -1 +1 @@
1
- {"version":3,"sources":["components/SpinButton/renderSpinButton.tsx"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;AAGA;;AAEG;;;AACI,MAAM,yBAAyB,GAAI,KAAD,IAA2B;AAClE;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA,QAAM;AAAE,IAAA,KAAF;AAAS,IAAA;AAAT,MAAuB,iBAAA,CAAA,QAAA,CAA0B,KAA1B,CAA7B;AAEA,SACE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,IAAP,EAAW,EAAA,GAAK,SAAS,CAAC;AAAf,GAAX,EACE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,KAAP,EAAY,EAAA,GAAK,SAAS,CAAC;AAAf,GAAZ,CADF,EAEE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,eAAP,EAAsB,EAAA,GAAK,SAAS,CAAC;AAAf,GAAtB,CAFF,EAGE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,eAAP,EAAsB,EAAA,GAAK,SAAS,CAAC;AAAf,GAAtB,CAHF,CADF;AAOD,CAhCM;;AAAM,OAAA,CAAA,yBAAA,GAAyB,yBAAzB","sourcesContent":["import * as React from 'react';\nimport { getSlots } from '@fluentui/react-utilities';\nimport type { SpinButtonState, SpinButtonSlots } from './SpinButton.types';\n\n/**\n * Render the final JSX of SpinButton\n */\nexport const renderSpinButton_unstable = (state: SpinButtonState) => {\n // Leaving this here for now.\n // This is the approach using react-input's Input component.\n // It has some Typescript problems and feels hacky.\n // const { slots, slotProps } = getSlots<SpinButtonSlots>(state);\n\n // const { contentAfter, ...otherInputSlotProps } = slotProps.input as SpinButtonSlots['input'];\n // const inputContentAfter = {\n // ...contentAfter,\n // children: (\n // <>\n // <slots.incrementButton {...slotProps.incrementButton} />\n // <slots.decrementButton {...slotProps.decrementButton} />\n // </>\n // ),\n // };\n\n // return (\n // <slots.root {...slotProps.root}>\n // <slots.input {...otherInputSlotProps} contentAfter={inputContentAfter}/>\n // </slots.root>\n // );\n\n const { slots, slotProps } = getSlots<SpinButtonSlots>(state);\n\n return (\n <slots.root {...slotProps.root}>\n <slots.input {...slotProps.input} />\n <slots.incrementButton {...slotProps.incrementButton} />\n <slots.decrementButton {...slotProps.decrementButton} />\n </slots.root>\n );\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/SpinButton/renderSpinButton.tsx"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;AAGA;;AAEG;;;AACI,MAAM,yBAAyB,GAAI,KAAD,IAA2B;EAClE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA,MAAM;IAAE,KAAF;IAAS;EAAT,IAAuB,iBAAA,CAAA,QAAA,CAA0B,KAA1B,CAA7B;EAEA,OACE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,IAAP,EAAW,EAAA,GAAK,SAAS,CAAC;EAAf,CAAX,EACE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,KAAP,EAAY,EAAA,GAAK,SAAS,CAAC;EAAf,CAAZ,CADF,EAEE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,eAAP,EAAsB,EAAA,GAAK,SAAS,CAAC;EAAf,CAAtB,CAFF,EAGE,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,eAAP,EAAsB,EAAA,GAAK,SAAS,CAAC;EAAf,CAAtB,CAHF,CADF;AAOD,CAhCM;;AAAM,OAAA,CAAA,yBAAA,GAAyB,yBAAzB","sourcesContent":["import * as React from 'react';\nimport { getSlots } from '@fluentui/react-utilities';\nimport type { SpinButtonState, SpinButtonSlots } from './SpinButton.types';\n\n/**\n * Render the final JSX of SpinButton\n */\nexport const renderSpinButton_unstable = (state: SpinButtonState) => {\n // Leaving this here for now.\n // This is the approach using react-input's Input component.\n // It has some Typescript problems and feels hacky.\n // const { slots, slotProps } = getSlots<SpinButtonSlots>(state);\n\n // const { contentAfter, ...otherInputSlotProps } = slotProps.input as SpinButtonSlots['input'];\n // const inputContentAfter = {\n // ...contentAfter,\n // children: (\n // <>\n // <slots.incrementButton {...slotProps.incrementButton} />\n // <slots.decrementButton {...slotProps.decrementButton} />\n // </>\n // ),\n // };\n\n // return (\n // <slots.root {...slotProps.root}>\n // <slots.input {...otherInputSlotProps} contentAfter={inputContentAfter}/>\n // </slots.root>\n // );\n\n const { slots, slotProps } = getSlots<SpinButtonSlots>(state);\n\n return (\n <slots.root {...slotProps.root}>\n <slots.input {...slotProps.input} />\n <slots.incrementButton {...slotProps.incrementButton} />\n <slots.decrementButton {...slotProps.decrementButton} />\n </slots.root>\n );\n};\n"],"sourceRoot":"../src/"}
@@ -11,8 +11,6 @@ const react_utilities_1 = /*#__PURE__*/require("@fluentui/react-utilities");
11
11
 
12
12
  const Keys = /*#__PURE__*/require("@fluentui/keyboard-keys");
13
13
 
14
- const SpinButton_strings_1 = /*#__PURE__*/require("./SpinButton.strings");
15
-
16
14
  const index_1 = /*#__PURE__*/require("../../utils/index");
17
15
 
18
16
  const react_icons_1 = /*#__PURE__*/require("@fluentui/react-icons");
@@ -36,10 +34,12 @@ const lerp = (start, end, percent) => start + (end - start) * percent;
36
34
 
37
35
 
38
36
  const useSpinButton_unstable = (props, ref) => {
37
+ var _a;
38
+
39
39
  const nativeProps = react_utilities_1.getPartitionedNativeProps({
40
40
  props,
41
41
  primarySlotTagName: 'input',
42
- excludedPropNames: ['onChange', 'size', 'min', 'max']
42
+ excludedPropNames: ['defaultValue', 'max', 'min', 'onChange', 'size', 'value']
43
43
  });
44
44
  const {
45
45
  value,
@@ -56,8 +56,7 @@ const useSpinButton_unstable = (props, ref) => {
56
56
  root,
57
57
  input,
58
58
  incrementButton,
59
- decrementButton,
60
- strings = SpinButton_strings_1.spinButtonDefaultStrings
59
+ decrementButton
61
60
  } = props;
62
61
  const precision = React.useMemo(() => {
63
62
  return precisionFromProps !== null && precisionFromProps !== void 0 ? precisionFromProps : Math.max(index_1.calculatePrecision(step), 0);
@@ -67,94 +66,44 @@ const useSpinButton_unstable = (props, ref) => {
67
66
  defaultState: defaultValue,
68
67
  initialState: 0
69
68
  });
70
- const [textValue, setTextValue] = React.useState(value !== undefined && displayValue !== undefined ? displayValue : String(currentValue));
71
- const [spinState, setSpinState] = React.useState('rest');
72
- const [atBound, setAtBound] = React.useState('none');
69
+ const isControlled = value !== undefined;
70
+ const [textValue, setTextValue] = React.useState(undefined);
71
+ const [keyboardSpinState, setKeyboardSpinState] = React.useState('rest');
73
72
  const internalState = React.useRef({
74
73
  value: currentValue,
75
- spinState,
74
+ spinState: 'rest',
76
75
  spinTime: 0,
77
- spinDelay: DEFAULT_SPIN_DELAY_MS
76
+ spinDelay: DEFAULT_SPIN_DELAY_MS,
77
+ atBound: currentValue !== null ? index_1.getBound(index_1.precisionRound(currentValue, precision), min, max) : 'none'
78
78
  });
79
- const state = {
80
- size,
81
- appearance,
82
- spinState,
83
- atBound,
84
- components: {
85
- root: 'span',
86
- input: 'input',
87
- incrementButton: 'button',
88
- decrementButton: 'button'
89
- },
90
- root: react_utilities_1.resolveShorthand(root, {
91
- required: true,
92
- defaultProps: nativeProps.root
93
- }),
94
- input: react_utilities_1.resolveShorthand(input, {
95
- required: true,
96
- defaultProps: {
97
- ref,
98
- autoComplete: 'off',
99
- role: 'spinbutton',
100
- appearance: appearance,
101
- type: 'text',
102
- ...nativeProps.primary
103
- }
104
- }),
105
- incrementButton: react_utilities_1.resolveShorthand(incrementButton, {
106
- required: true,
107
- defaultProps: {
108
- tabIndex: -1,
109
- children: React.createElement(react_icons_1.ChevronUp16Regular, null),
110
- disabled: nativeProps.primary.disabled,
111
- 'aria-label': strings.incrementButtonLabel.replace('{step}', step.toString())
112
- }
113
- }),
114
- decrementButton: react_utilities_1.resolveShorthand(decrementButton, {
115
- required: true,
116
- defaultProps: {
117
- tabIndex: -1,
118
- children: React.createElement(react_icons_1.ChevronDown16Regular, null),
119
- disabled: nativeProps.primary.disabled,
120
- 'aria-label': strings.decrementButtonLabel.replace('{step}', step.toString())
121
- }
122
- })
123
- };
124
79
  const [setStepTimeout, clearStepTimeout] = react_utilities_1.useTimeout();
125
- React.useEffect(() => {
126
- let newTextValue;
127
-
128
- if (value !== undefined) {
129
- const roundedValue = index_1.precisionRound(value, precision);
130
- newTextValue = displayValue !== null && displayValue !== void 0 ? displayValue : String(roundedValue);
131
- internalState.current.value = roundedValue;
132
- setAtBound(index_1.getBound(roundedValue, min, max));
133
- } else {
134
- newTextValue = String(index_1.precisionRound(currentValue, precision));
135
- internalState.current.value = currentValue;
136
- }
137
80
 
138
- setTextValue(newTextValue);
139
- }, [value, displayValue, currentValue, precision, setAtBound, min, max]);
81
+ const stepValue = (e, direction, startFrom) => {
82
+ let startValue = internalState.current.value;
140
83
 
141
- const handleInputChange = e => {
142
- if (!internalState.current.previousTextValue) {
143
- internalState.current.previousTextValue = textValue;
144
- }
84
+ if (startFrom) {
85
+ const num = parseFloat(startFrom);
145
86
 
146
- const newValue = e.target.value;
147
- setTextValue(newValue);
148
- };
87
+ if (!isNaN(num)) {
88
+ startValue = num;
89
+ }
90
+ }
149
91
 
150
- const stepValue = (e, direction) => {
92
+ const val = startValue;
151
93
  const dir = direction === 'up' || direction === 'upPage' ? 1 : -1;
152
94
  const stepSize = direction === 'upPage' || direction === 'downPage' ? stepPage : step;
153
- const val = internalState.current.value;
95
+
96
+ if (val === null) {
97
+ const stepStart = min === undefined ? 0 : min;
98
+ const nullStep = index_1.clamp(stepStart + stepSize * dir, min, max);
99
+ commit(e, nullStep);
100
+ return;
101
+ }
102
+
154
103
  let newValue = val + stepSize * dir;
155
104
 
156
105
  if (!Number.isNaN(newValue)) {
157
- newValue = index_1.clampWhenInRange(val, newValue, min, max);
106
+ newValue = index_1.clamp(newValue, min, max);
158
107
  }
159
108
 
160
109
  commit(e, newValue);
@@ -169,6 +118,15 @@ const useSpinButton_unstable = (props, ref) => {
169
118
  }
170
119
  };
171
120
 
121
+ const handleInputChange = e => {
122
+ if (!internalState.current.previousTextValue) {
123
+ internalState.current.previousTextValue = textValue;
124
+ }
125
+
126
+ const newValue = e.target.value;
127
+ setTextValue(newValue);
128
+ };
129
+
172
130
  const handleIncrementMouseDown = e => {
173
131
  internalState.current.spinState = 'up';
174
132
  stepValue(e, 'up');
@@ -192,43 +150,48 @@ const useSpinButton_unstable = (props, ref) => {
192
150
  };
193
151
 
194
152
  const handleKeyDown = e => {
153
+ let nextKeyboardSpinState = 'rest';
154
+
195
155
  if (e.key === Keys.ArrowUp) {
196
- stepValue(e, 'up');
197
- setSpinState('up');
156
+ stepValue(e, 'up', textValue);
157
+ nextKeyboardSpinState = 'up';
198
158
  } else if (e.key === Keys.ArrowDown) {
199
- stepValue(e, 'down');
200
- setSpinState('down');
159
+ stepValue(e, 'down', textValue);
160
+ nextKeyboardSpinState = 'down';
201
161
  } else if (e.key === Keys.PageUp) {
202
162
  e.preventDefault();
203
- stepValue(e, 'upPage');
204
- setSpinState('up');
163
+ stepValue(e, 'upPage', textValue);
164
+ nextKeyboardSpinState = 'up';
205
165
  } else if (e.key === Keys.PageDown) {
206
166
  e.preventDefault();
207
- stepValue(e, 'downPage');
208
- setSpinState('down');
167
+ stepValue(e, 'downPage', textValue);
168
+ nextKeyboardSpinState = 'down';
209
169
  } else if (!e.shiftKey && e.key === Keys.Home && min !== undefined) {
210
170
  commit(e, min);
211
- setSpinState('down');
171
+ nextKeyboardSpinState = 'down';
212
172
  } else if (!e.shiftKey && e.key === Keys.End && max !== undefined) {
213
173
  commit(e, max);
214
- setSpinState('up');
174
+ nextKeyboardSpinState = 'up';
215
175
  } else if (e.key === Keys.Enter) {
216
176
  commit(e, currentValue, textValue);
217
- setSpinState('rest');
177
+ internalState.current.previousTextValue = undefined;
218
178
  } else if (e.key === Keys.Escape) {
219
179
  if (internalState.current.previousTextValue) {
220
- setTextValue(internalState.current.previousTextValue);
180
+ setTextValue(undefined);
221
181
  internalState.current.previousTextValue = undefined;
222
182
  }
183
+ }
223
184
 
224
- setSpinState('rest');
225
- } else {
226
- setSpinState('rest');
185
+ if (keyboardSpinState !== nextKeyboardSpinState) {
186
+ setKeyboardSpinState(nextKeyboardSpinState);
227
187
  }
228
188
  };
229
189
 
230
190
  const handleKeyUp = e => {
231
- setSpinState('rest');
191
+ if (keyboardSpinState !== 'rest') {
192
+ setKeyboardSpinState('rest');
193
+ internalState.current.spinState = 'rest';
194
+ }
232
195
  };
233
196
 
234
197
  const commit = (e, newValue, newDisplayValue) => {
@@ -239,8 +202,12 @@ const useSpinButton_unstable = (props, ref) => {
239
202
  if (valueChanged) {
240
203
  roundedValue = index_1.precisionRound(newValue, precision);
241
204
  setCurrentValue(roundedValue);
242
- internalState.current.value = roundedValue;
243
- setAtBound(index_1.getBound(roundedValue, min, max));
205
+ } else if (displayValueChanged && !isControlled) {
206
+ const nextValue = parseFloat(newDisplayValue);
207
+
208
+ if (!isNaN(nextValue)) {
209
+ setCurrentValue(index_1.precisionRound(nextValue, precision));
210
+ }
244
211
  }
245
212
 
246
213
  if (valueChanged || displayValueChanged) {
@@ -249,23 +216,92 @@ const useSpinButton_unstable = (props, ref) => {
249
216
  displayValue: newDisplayValue
250
217
  });
251
218
  }
219
+
220
+ setTextValue(undefined);
252
221
  };
253
222
 
254
- state.input.value = textValue;
223
+ const state = {
224
+ size,
225
+ appearance,
226
+ spinState: keyboardSpinState,
227
+ atBound: internalState.current.atBound,
228
+ components: {
229
+ root: 'span',
230
+ input: 'input',
231
+ incrementButton: 'button',
232
+ decrementButton: 'button'
233
+ },
234
+ root: react_utilities_1.resolveShorthand(root, {
235
+ required: true,
236
+ defaultProps: nativeProps.root
237
+ }),
238
+ input: react_utilities_1.resolveShorthand(input, {
239
+ required: true,
240
+ defaultProps: {
241
+ ref,
242
+ autoComplete: 'off',
243
+ role: 'spinbutton',
244
+ appearance: appearance,
245
+ type: 'text',
246
+ ...nativeProps.primary
247
+ }
248
+ }),
249
+ incrementButton: react_utilities_1.resolveShorthand(incrementButton, {
250
+ required: true,
251
+ defaultProps: {
252
+ tabIndex: -1,
253
+ children: React.createElement(react_icons_1.ChevronUp16Regular, null),
254
+ disabled: nativeProps.primary.disabled,
255
+ 'aria-label': 'Increment value',
256
+ type: 'button'
257
+ }
258
+ }),
259
+ decrementButton: react_utilities_1.resolveShorthand(decrementButton, {
260
+ required: true,
261
+ defaultProps: {
262
+ tabIndex: -1,
263
+ children: React.createElement(react_icons_1.ChevronDown16Regular, null),
264
+ disabled: nativeProps.primary.disabled,
265
+ 'aria-label': 'Decrement value',
266
+ type: 'button'
267
+ }
268
+ })
269
+ };
270
+ let valueToDisplay;
271
+
272
+ if (textValue !== undefined) {
273
+ valueToDisplay = textValue;
274
+ } else if (value === null || currentValue === null) {
275
+ valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : '';
276
+ internalState.current.value = null;
277
+ internalState.current.atBound = 'none';
278
+ } else {
279
+ const roundedValue = index_1.precisionRound(currentValue, precision);
280
+ internalState.current.value = roundedValue;
281
+ internalState.current.atBound = index_1.getBound(roundedValue, min, max);
282
+
283
+ if (isControlled) {
284
+ valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : String(roundedValue);
285
+ } else {
286
+ valueToDisplay = String(roundedValue);
287
+ }
288
+ }
289
+
290
+ state.input.value = valueToDisplay;
255
291
  state.input['aria-valuemin'] = min;
256
292
  state.input['aria-valuemax'] = max;
257
- state.input['aria-valuenow'] = currentValue;
258
- state.input['aria-valuetext'] = value !== undefined && displayValue || undefined;
259
- state.input.onChange = react_utilities_1.useMergedEventCallbacks(state.input.onChange, handleInputChange);
260
- state.input.onBlur = react_utilities_1.useMergedEventCallbacks(state.input.onBlur, handleBlur);
261
- state.input.onKeyDown = react_utilities_1.useMergedEventCallbacks(state.input.onKeyDown, handleKeyDown);
262
- state.input.onKeyUp = react_utilities_1.useMergedEventCallbacks(state.input.onKeyUp, handleKeyUp);
263
- state.incrementButton.onMouseDown = react_utilities_1.useMergedEventCallbacks(handleIncrementMouseDown, state.incrementButton.onMouseDown);
264
- state.incrementButton.onMouseUp = react_utilities_1.useMergedEventCallbacks(state.incrementButton.onMouseUp, handleStepMouseUpOrLeave);
265
- state.incrementButton.onMouseLeave = react_utilities_1.useMergedEventCallbacks(state.incrementButton.onMouseLeave, handleStepMouseUpOrLeave);
266
- state.decrementButton.onMouseDown = react_utilities_1.useMergedEventCallbacks(handleDecrementMouseDown, state.decrementButton.onMouseDown);
267
- state.decrementButton.onMouseUp = react_utilities_1.useMergedEventCallbacks(state.decrementButton.onMouseUp, handleStepMouseUpOrLeave);
268
- state.decrementButton.onMouseLeave = react_utilities_1.useMergedEventCallbacks(state.decrementButton.onMouseLeave, handleStepMouseUpOrLeave);
293
+ state.input['aria-valuenow'] = currentValue !== null && currentValue !== void 0 ? currentValue : undefined;
294
+ state.input['aria-valuetext'] = (_a = state.input['aria-valuetext']) !== null && _a !== void 0 ? _a : value !== undefined && displayValue || undefined;
295
+ state.input.onChange = react_utilities_1.mergeCallbacks(state.input.onChange, handleInputChange);
296
+ state.input.onBlur = react_utilities_1.mergeCallbacks(state.input.onBlur, handleBlur);
297
+ state.input.onKeyDown = react_utilities_1.mergeCallbacks(state.input.onKeyDown, handleKeyDown);
298
+ state.input.onKeyUp = react_utilities_1.mergeCallbacks(state.input.onKeyUp, handleKeyUp);
299
+ state.incrementButton.onMouseDown = react_utilities_1.mergeCallbacks(handleIncrementMouseDown, state.incrementButton.onMouseDown);
300
+ state.incrementButton.onMouseUp = react_utilities_1.mergeCallbacks(state.incrementButton.onMouseUp, handleStepMouseUpOrLeave);
301
+ state.incrementButton.onMouseLeave = react_utilities_1.mergeCallbacks(state.incrementButton.onMouseLeave, handleStepMouseUpOrLeave);
302
+ state.decrementButton.onMouseDown = react_utilities_1.mergeCallbacks(handleDecrementMouseDown, state.decrementButton.onMouseDown);
303
+ state.decrementButton.onMouseUp = react_utilities_1.mergeCallbacks(state.decrementButton.onMouseUp, handleStepMouseUpOrLeave);
304
+ state.decrementButton.onMouseLeave = react_utilities_1.mergeCallbacks(state.decrementButton.onMouseLeave, handleStepMouseUpOrLeave);
269
305
  return state;
270
306
  };
271
307