@salt-ds/core 1.53.0 → 1.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/css/salt-core.css +47 -45
  3. package/dist-cjs/avatar/Avatar.css.js +1 -1
  4. package/dist-cjs/badge/Badge.css.js +1 -1
  5. package/dist-cjs/combo-box/ComboBox.js +2 -1
  6. package/dist-cjs/combo-box/ComboBox.js.map +1 -1
  7. package/dist-cjs/index.js +2 -0
  8. package/dist-cjs/index.js.map +1 -1
  9. package/dist-cjs/menu/MenuBase.js +5 -2
  10. package/dist-cjs/menu/MenuBase.js.map +1 -1
  11. package/dist-cjs/menu/MenuContext.js +3 -1
  12. package/dist-cjs/menu/MenuContext.js.map +1 -1
  13. package/dist-cjs/menu/MenuItem.js +5 -0
  14. package/dist-cjs/menu/MenuItem.js.map +1 -1
  15. package/dist-cjs/multiline-input/MultilineInput.js +2 -1
  16. package/dist-cjs/multiline-input/MultilineInput.js.map +1 -1
  17. package/dist-cjs/number-input/NumberInput.js +7 -7
  18. package/dist-cjs/number-input/NumberInput.js.map +1 -1
  19. package/dist-cjs/number-input/internal/useLongPressPointerAction.js +63 -0
  20. package/dist-cjs/number-input/internal/useLongPressPointerAction.js.map +1 -0
  21. package/dist-cjs/pill/Pill.js +72 -9
  22. package/dist-cjs/pill/Pill.js.map +1 -1
  23. package/dist-cjs/pill/PillCheckIcon.css.js +6 -0
  24. package/dist-cjs/pill/PillCheckIcon.css.js.map +1 -0
  25. package/dist-cjs/pill/PillCheckIcon.js +48 -0
  26. package/dist-cjs/pill/PillCheckIcon.js.map +1 -0
  27. package/dist-cjs/pill/PillGroup.css.js +6 -0
  28. package/dist-cjs/pill/PillGroup.css.js.map +1 -0
  29. package/dist-cjs/pill/PillGroup.js +83 -0
  30. package/dist-cjs/pill/PillGroup.js.map +1 -0
  31. package/dist-cjs/pill/PillGroupContext.js +27 -0
  32. package/dist-cjs/pill/PillGroupContext.js.map +1 -0
  33. package/dist-cjs/pill-input/PillInput.js +1 -0
  34. package/dist-cjs/pill-input/PillInput.js.map +1 -1
  35. package/dist-cjs/slider/internal/useRangeSliderThumb.js +14 -5
  36. package/dist-cjs/slider/internal/useRangeSliderThumb.js.map +1 -1
  37. package/dist-cjs/slider/internal/useSliderThumb.js +14 -5
  38. package/dist-cjs/slider/internal/useSliderThumb.js.map +1 -1
  39. package/dist-cjs/tag/Tag.css.js +1 -1
  40. package/dist-cjs/toggle-button/ToggleButton.css.js +1 -1
  41. package/dist-es/avatar/Avatar.css.js +1 -1
  42. package/dist-es/badge/Badge.css.js +1 -1
  43. package/dist-es/combo-box/ComboBox.js +3 -2
  44. package/dist-es/combo-box/ComboBox.js.map +1 -1
  45. package/dist-es/index.js +1 -0
  46. package/dist-es/index.js.map +1 -1
  47. package/dist-es/menu/MenuBase.js +5 -2
  48. package/dist-es/menu/MenuBase.js.map +1 -1
  49. package/dist-es/menu/MenuContext.js +3 -1
  50. package/dist-es/menu/MenuContext.js.map +1 -1
  51. package/dist-es/menu/MenuItem.js +6 -1
  52. package/dist-es/menu/MenuItem.js.map +1 -1
  53. package/dist-es/multiline-input/MultilineInput.js +3 -2
  54. package/dist-es/multiline-input/MultilineInput.js.map +1 -1
  55. package/dist-es/number-input/NumberInput.js +7 -7
  56. package/dist-es/number-input/NumberInput.js.map +1 -1
  57. package/dist-es/number-input/internal/useLongPressPointerAction.js +61 -0
  58. package/dist-es/number-input/internal/useLongPressPointerAction.js.map +1 -0
  59. package/dist-es/pill/Pill.js +74 -11
  60. package/dist-es/pill/Pill.js.map +1 -1
  61. package/dist-es/pill/PillCheckIcon.css.js +4 -0
  62. package/dist-es/pill/PillCheckIcon.css.js.map +1 -0
  63. package/dist-es/pill/PillCheckIcon.js +46 -0
  64. package/dist-es/pill/PillCheckIcon.js.map +1 -0
  65. package/dist-es/pill/PillGroup.css.js +4 -0
  66. package/dist-es/pill/PillGroup.css.js.map +1 -0
  67. package/dist-es/pill/PillGroup.js +81 -0
  68. package/dist-es/pill/PillGroup.js.map +1 -0
  69. package/dist-es/pill/PillGroupContext.js +24 -0
  70. package/dist-es/pill/PillGroupContext.js.map +1 -0
  71. package/dist-es/pill-input/PillInput.js +1 -0
  72. package/dist-es/pill-input/PillInput.js.map +1 -1
  73. package/dist-es/slider/internal/useRangeSliderThumb.js +14 -5
  74. package/dist-es/slider/internal/useRangeSliderThumb.js.map +1 -1
  75. package/dist-es/slider/internal/useSliderThumb.js +14 -5
  76. package/dist-es/slider/internal/useSliderThumb.js.map +1 -1
  77. package/dist-es/tag/Tag.css.js +1 -1
  78. package/dist-es/toggle-button/ToggleButton.css.js +1 -1
  79. package/dist-types/menu/MenuContext.d.ts +2 -0
  80. package/dist-types/number-input/internal/useLongPressPointerAction.d.ts +2 -0
  81. package/dist-types/pill/Pill.d.ts +1 -0
  82. package/dist-types/pill/PillCheckIcon.d.ts +7 -0
  83. package/dist-types/pill/PillGroup.d.ts +34 -0
  84. package/dist-types/pill/PillGroupContext.d.ts +9 -0
  85. package/dist-types/pill/index.d.ts +1 -0
  86. package/package.json +1 -1
  87. package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js +0 -50
  88. package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js.map +0 -1
  89. package/dist-es/number-input/internal/useActivateWhileMouseDown.js +0 -48
  90. package/dist-es/number-input/internal/useActivateWhileMouseDown.js.map +0 -1
  91. package/dist-types/number-input/internal/useActivateWhileMouseDown.d.ts +0 -5
@@ -40,6 +40,7 @@ function MenuBase(props) {
40
40
  );
41
41
  const [activeIndex, setActiveIndex] = React.useState(null);
42
42
  const [focusInside, setFocusInside] = React.useState(false);
43
+ const [triggerDisabled, setTriggerDisabled] = React.useState(false);
43
44
  const isNested = parentId != null;
44
45
  const { x, y, strategy, elements, refs, context } = useFloatingUI.useFloatingUI({
45
46
  nodeId,
@@ -71,7 +72,7 @@ function MenuBase(props) {
71
72
  const { getReferenceProps, getFloatingProps, getItemProps } = react.useInteractions(
72
73
  [
73
74
  react.useHover(context, {
74
- enabled: isNested && !focusInside,
75
+ enabled: isNested && !focusInside && !triggerDisabled,
75
76
  handleClose: react.safePolygon({ blockPointerEvents: true })
76
77
  }),
77
78
  react.useClick(context, {
@@ -124,7 +125,9 @@ function MenuBase(props) {
124
125
  elementsRef,
125
126
  focusInside,
126
127
  setFocusInside,
127
- isNested
128
+ isNested,
129
+ triggerDisabled,
130
+ setTriggerDisabled
128
131
  },
129
132
  children
130
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MenuBase.js","sources":["../src/menu/MenuBase.tsx"],"sourcesContent":["import {\n FloatingNode,\n flip,\n limitShift,\n offset,\n type ReferenceType,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useFloatingTree,\n useHover,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n type UseFloatingUIProps,\n useControlled,\n useFloatingUI,\n useIsomorphicLayoutEffect,\n} from \"../utils\";\nimport { MenuContext } from \"./MenuContext\";\n\nexport interface MenuBaseProps {\n children?: ReactNode;\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * If true, the menu will be open by default.\n */\n defaultOpen?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (newOpen: boolean) => void;\n /**\n * Set the placement of the Menu component relative to the trigger element. Defaults to `bottom-start` if it's the root menu or `right-start` if it's nested.\n */\n placement?: UseFloatingUIProps[\"placement\"];\n /**\n * Function that returns a [virtual element](https://floating-ui.com/docs/virtual-elements). If this is provided, it will override MenuTrigger.\n */\n getVirtualElement?: () => ReferenceType | null;\n}\n\nexport function MenuBase(props: MenuBaseProps) {\n const {\n children,\n defaultOpen,\n open,\n onOpenChange,\n placement,\n getVirtualElement,\n } = props;\n const parentId = useFloatingParentNodeId();\n const nodeId = useFloatingNodeId();\n const tree = useFloatingTree();\n const elementsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n const [openState, setOpenState] = useControlled({\n controlled: open,\n default: Boolean(defaultOpen),\n name: \"ListControl\",\n state: \"open\",\n });\n\n const setOpen = useCallback(\n (newOpen: boolean) => {\n setOpenState(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange],\n );\n\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const [focusInside, setFocusInside] = useState(false);\n\n const isNested = parentId != null;\n\n const { x, y, strategy, elements, refs, context } = useFloatingUI({\n nodeId,\n open: openState,\n onOpenChange: setOpen,\n strategy: !getVirtualElement ? \"absolute\" : \"fixed\",\n placement:\n placement ??\n (isNested || getVirtualElement ? \"right-start\" : \"bottom-start\"),\n middleware: [\n // Align the nested menu by shifting it by var(--salt-spacing-fixed-100)\n offset(\n isNested ? { crossAxis: -1, mainAxis: 2 } : !getVirtualElement ? 1 : 0,\n ),\n flip({}),\n shift({ limiter: limitShift() }),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `${availableHeight}px`,\n });\n },\n }),\n ],\n });\n\n useIsomorphicLayoutEffect(() => {\n if (getVirtualElement) {\n refs.setPositionReference(getVirtualElement());\n }\n }, [getVirtualElement, refs]);\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [\n useHover(context, {\n enabled: isNested && !focusInside,\n handleClose: safePolygon({ blockPointerEvents: true }),\n }),\n useClick(context, {\n event: \"mousedown\",\n toggle: !isNested,\n ignoreMouse: isNested,\n }),\n useRole(context, { role: \"menu\" }),\n useDismiss(context, { bubbles: true }),\n useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n nested: isNested,\n onNavigate: setActiveIndex,\n }),\n ],\n );\n\n const getPanelPosition = () => ({\n top: y ?? 0,\n left: x ?? 0,\n position: strategy,\n width: elements.floating?.offsetWidth,\n height: elements.floating?.offsetHeight,\n });\n\n useEffect(() => {\n if (!tree) return;\n\n function handleItemClick() {\n setOpen(false);\n }\n\n tree.events.on(\"click\", handleItemClick);\n\n return () => {\n tree.events.off(\"click\", handleItemClick);\n };\n }, [tree, setOpen]);\n\n return (\n <FloatingNode id={nodeId}>\n <MenuContext.Provider\n value={{\n openState,\n getReferenceProps,\n getFloatingProps,\n refs,\n getPanelPosition,\n getItemProps,\n activeIndex,\n context,\n elementsRef,\n focusInside,\n setFocusInside,\n isNested,\n }}\n >\n {children}\n </MenuContext.Provider>\n </FloatingNode>\n );\n}\n"],"names":["useFloatingParentNodeId","useFloatingNodeId","useFloatingTree","useRef","useControlled","useCallback","useState","useFloatingUI","offset","flip","shift","limitShift","size","elements","useIsomorphicLayoutEffect","useInteractions","useHover","safePolygon","useClick","useRole","useDismiss","useListNavigation","useEffect","jsx","FloatingNode","MenuContext"],"mappings":"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"}
1
+ {"version":3,"file":"MenuBase.js","sources":["../src/menu/MenuBase.tsx"],"sourcesContent":["import {\n FloatingNode,\n flip,\n limitShift,\n offset,\n type ReferenceType,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useFloatingTree,\n useHover,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n type UseFloatingUIProps,\n useControlled,\n useFloatingUI,\n useIsomorphicLayoutEffect,\n} from \"../utils\";\nimport { MenuContext } from \"./MenuContext\";\n\nexport interface MenuBaseProps {\n children?: ReactNode;\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * If true, the menu will be open by default.\n */\n defaultOpen?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (newOpen: boolean) => void;\n /**\n * Set the placement of the Menu component relative to the trigger element. Defaults to `bottom-start` if it's the root menu or `right-start` if it's nested.\n */\n placement?: UseFloatingUIProps[\"placement\"];\n /**\n * Function that returns a [virtual element](https://floating-ui.com/docs/virtual-elements). If this is provided, it will override MenuTrigger.\n */\n getVirtualElement?: () => ReferenceType | null;\n}\n\nexport function MenuBase(props: MenuBaseProps) {\n const {\n children,\n defaultOpen,\n open,\n onOpenChange,\n placement,\n getVirtualElement,\n } = props;\n const parentId = useFloatingParentNodeId();\n const nodeId = useFloatingNodeId();\n const tree = useFloatingTree();\n const elementsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n const [openState, setOpenState] = useControlled({\n controlled: open,\n default: Boolean(defaultOpen),\n name: \"ListControl\",\n state: \"open\",\n });\n\n const setOpen = useCallback(\n (newOpen: boolean) => {\n setOpenState(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange],\n );\n\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const [focusInside, setFocusInside] = useState(false);\n const [triggerDisabled, setTriggerDisabled] = useState(false);\n\n const isNested = parentId != null;\n\n const { x, y, strategy, elements, refs, context } = useFloatingUI({\n nodeId,\n open: openState,\n onOpenChange: setOpen,\n strategy: !getVirtualElement ? \"absolute\" : \"fixed\",\n placement:\n placement ??\n (isNested || getVirtualElement ? \"right-start\" : \"bottom-start\"),\n middleware: [\n // Align the nested menu by shifting it by var(--salt-spacing-fixed-100)\n offset(\n isNested ? { crossAxis: -1, mainAxis: 2 } : !getVirtualElement ? 1 : 0,\n ),\n flip({}),\n shift({ limiter: limitShift() }),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `${availableHeight}px`,\n });\n },\n }),\n ],\n });\n\n useIsomorphicLayoutEffect(() => {\n if (getVirtualElement) {\n refs.setPositionReference(getVirtualElement());\n }\n }, [getVirtualElement, refs]);\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [\n useHover(context, {\n enabled: isNested && !focusInside && !triggerDisabled,\n handleClose: safePolygon({ blockPointerEvents: true }),\n }),\n useClick(context, {\n event: \"mousedown\",\n toggle: !isNested,\n ignoreMouse: isNested,\n }),\n useRole(context, { role: \"menu\" }),\n useDismiss(context, { bubbles: true }),\n useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n nested: isNested,\n onNavigate: setActiveIndex,\n }),\n ],\n );\n\n const getPanelPosition = () => ({\n top: y ?? 0,\n left: x ?? 0,\n position: strategy,\n width: elements.floating?.offsetWidth,\n height: elements.floating?.offsetHeight,\n });\n\n useEffect(() => {\n if (!tree) return;\n\n function handleItemClick() {\n setOpen(false);\n }\n\n tree.events.on(\"click\", handleItemClick);\n\n return () => {\n tree.events.off(\"click\", handleItemClick);\n };\n }, [tree, setOpen]);\n\n return (\n <FloatingNode id={nodeId}>\n <MenuContext.Provider\n value={{\n openState,\n getReferenceProps,\n getFloatingProps,\n refs,\n getPanelPosition,\n getItemProps,\n activeIndex,\n context,\n elementsRef,\n focusInside,\n setFocusInside,\n isNested,\n triggerDisabled,\n setTriggerDisabled,\n }}\n >\n {children}\n </MenuContext.Provider>\n </FloatingNode>\n );\n}\n"],"names":["useFloatingParentNodeId","useFloatingNodeId","useFloatingTree","useRef","useControlled","useCallback","useState","useFloatingUI","offset","flip","shift","limitShift","size","elements","useIsomorphicLayoutEffect","useInteractions","useHover","safePolygon","useClick","useRole","useDismiss","useListNavigation","useEffect","jsx","FloatingNode","MenuContext"],"mappings":"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"}
@@ -19,7 +19,9 @@ const MenuContext = createContext.createContext("MenuContext", {
19
19
  elementsRef: { current: [] },
20
20
  focusInside: false,
21
21
  setFocusInside: () => void 0,
22
- isNested: false
22
+ isNested: false,
23
+ triggerDisabled: false,
24
+ setTriggerDisabled: () => void 0
23
25
  });
24
26
  function useMenuContext() {
25
27
  return React.useContext(MenuContext);
@@ -1 +1 @@
1
- {"version":3,"file":"MenuContext.js","sources":["../src/menu/MenuContext.ts"],"sourcesContent":["import type { useInteractions } from \"@floating-ui/react\";\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n useContext,\n} from \"react\";\nimport { createContext, type UseFloatingUIReturn } from \"../utils\";\n\ntype UseInteractionsReturn = ReturnType<typeof useInteractions>;\n\nexport interface MenuContextValue\n extends Pick<\n UseInteractionsReturn,\n \"getItemProps\" | \"getReferenceProps\" | \"getFloatingProps\"\n >,\n Partial<Pick<UseFloatingUIReturn, \"context\" | \"refs\">> {\n openState: boolean;\n activeIndex: number | null;\n getPanelPosition: () => Record<string, unknown>;\n elementsRef: MutableRefObject<(HTMLDivElement | null)[]>;\n focusInside: boolean;\n setFocusInside: Dispatch<SetStateAction<boolean>>;\n isNested: boolean;\n}\n\nexport const MenuContext = createContext<MenuContextValue>(\"MenuContext\", {\n openState: false,\n getReferenceProps: () => ({}),\n getFloatingProps: () => ({}),\n getPanelPosition: () => ({}),\n getItemProps: () => ({}),\n activeIndex: null,\n elementsRef: { current: [] },\n focusInside: false,\n setFocusInside: () => undefined,\n isNested: false,\n});\n\nexport function useMenuContext() {\n return useContext(MenuContext);\n}\n"],"names":["createContext","useContext"],"mappings":";;;;;;;;;;;AA0BO,MAAM,WAAA,GAAcA,4BAAgC,aAAA,EAAe;AAAA,EACxE,SAAA,EAAW,KAAA;AAAA,EACX,iBAAA,EAAmB,OAAO,EAAC,CAAA;AAAA,EAC3B,gBAAA,EAAkB,OAAO,EAAC,CAAA;AAAA,EAC1B,gBAAA,EAAkB,OAAO,EAAC,CAAA;AAAA,EAC1B,YAAA,EAAc,OAAO,EAAC,CAAA;AAAA,EACtB,WAAA,EAAa,IAAA;AAAA,EACb,WAAA,EAAa,EAAE,OAAA,EAAS,EAAC,EAAE;AAAA,EAC3B,WAAA,EAAa,KAAA;AAAA,EACb,gBAAgB,MAAM,MAAA;AAAA,EACtB,QAAA,EAAU;AACZ,CAAC;AAEM,SAAS,cAAA,GAAiB;AAC/B,EAAA,OAAOC,iBAAW,WAAW,CAAA;AAC/B;;;;;"}
1
+ {"version":3,"file":"MenuContext.js","sources":["../src/menu/MenuContext.ts"],"sourcesContent":["import type { useInteractions } from \"@floating-ui/react\";\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n useContext,\n} from \"react\";\nimport { createContext, type UseFloatingUIReturn } from \"../utils\";\n\ntype UseInteractionsReturn = ReturnType<typeof useInteractions>;\n\nexport interface MenuContextValue\n extends Pick<\n UseInteractionsReturn,\n \"getItemProps\" | \"getReferenceProps\" | \"getFloatingProps\"\n >,\n Partial<Pick<UseFloatingUIReturn, \"context\" | \"refs\">> {\n openState: boolean;\n activeIndex: number | null;\n getPanelPosition: () => Record<string, unknown>;\n elementsRef: MutableRefObject<(HTMLDivElement | null)[]>;\n focusInside: boolean;\n setFocusInside: Dispatch<SetStateAction<boolean>>;\n isNested: boolean;\n triggerDisabled: boolean;\n setTriggerDisabled: (disabled: boolean) => void;\n}\n\nexport const MenuContext = createContext<MenuContextValue>(\"MenuContext\", {\n openState: false,\n getReferenceProps: () => ({}),\n getFloatingProps: () => ({}),\n getPanelPosition: () => ({}),\n getItemProps: () => ({}),\n activeIndex: null,\n elementsRef: { current: [] },\n focusInside: false,\n setFocusInside: () => undefined,\n isNested: false,\n triggerDisabled: false,\n setTriggerDisabled: () => undefined,\n});\n\nexport function useMenuContext() {\n return useContext(MenuContext);\n}\n"],"names":["createContext","useContext"],"mappings":";;;;;;;;;;;AA4BO,MAAM,WAAA,GAAcA,4BAAgC,aAAA,EAAe;AAAA,EACxE,SAAA,EAAW,KAAA;AAAA,EACX,iBAAA,EAAmB,OAAO,EAAC,CAAA;AAAA,EAC3B,gBAAA,EAAkB,OAAO,EAAC,CAAA;AAAA,EAC1B,gBAAA,EAAkB,OAAO,EAAC,CAAA;AAAA,EAC1B,YAAA,EAAc,OAAO,EAAC,CAAA;AAAA,EACtB,WAAA,EAAa,IAAA;AAAA,EACb,WAAA,EAAa,EAAE,OAAA,EAAS,EAAC,EAAE;AAAA,EAC3B,WAAA,EAAa,KAAA;AAAA,EACb,gBAAgB,MAAM,MAAA;AAAA,EACtB,QAAA,EAAU,KAAA;AAAA,EACV,eAAA,EAAiB,KAAA;AAAA,EACjB,oBAAoB,MAAM;AAC5B,CAAC;AAEM,SAAS,cAAA,GAAiB;AAC/B,EAAA,OAAOC,iBAAW,WAAW,CAAA;AAC/B;;;;;"}
@@ -13,6 +13,7 @@ var useForkRef = require('../utils/useForkRef.js');
13
13
  require('../utils/useId.js');
14
14
  require('../salt-provider/SaltProvider.js');
15
15
  require('../viewport/ViewportProvider.js');
16
+ var MenuContext = require('./MenuContext.js');
16
17
  var MenuItem$1 = require('./MenuItem.css.js');
17
18
  var MenuPanelContext = require('./MenuPanelContext.js');
18
19
  var MenuTriggerContext = require('./MenuTriggerContext.js');
@@ -30,6 +31,7 @@ const MenuItem = React.forwardRef(
30
31
  ...rest
31
32
  } = props;
32
33
  const { triggersSubmenu, blurActive } = MenuTriggerContext.useIsMenuTrigger();
34
+ const { setTriggerDisabled } = MenuContext.useMenuContext();
33
35
  const { ExpandGroupIcon } = SemanticIconProvider.useIcon();
34
36
  const { activeIndex, getItemProps, setFocusInside } = MenuPanelContext.useMenuPanelContext();
35
37
  const item = react.useListItem();
@@ -42,6 +44,9 @@ const MenuItem = React.forwardRef(
42
44
  window: targetWindow
43
45
  });
44
46
  const handleRef = useForkRef.useForkRef(ref, item.ref);
47
+ React.useEffect(() => {
48
+ setTriggerDisabled(!!disabled);
49
+ }, [disabled, setTriggerDisabled]);
45
50
  return /* @__PURE__ */ jsxRuntime.jsxs(
46
51
  "div",
47
52
  {
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItem.js","sources":["../src/menu/MenuItem.tsx"],"sourcesContent":["import { useFloatingTree, useListItem } from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type FocusEvent,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n} from \"react\";\nimport { useIcon } from \"../semantic-icon-provider\";\nimport { makePrefixer, useForkRef } from \"../utils\";\nimport menuItemCss from \"./MenuItem.css\";\nimport { useMenuPanelContext } from \"./MenuPanelContext\";\nimport { useIsMenuTrigger } from \"./MenuTriggerContext\";\nexport interface MenuItemProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * If `true`, the item will be disabled.\n */\n disabled?: boolean;\n}\n\nconst withBaseName = makePrefixer(\"saltMenuItem\");\n\nexport const MenuItem = forwardRef<HTMLDivElement, MenuItemProps>(\n function MenuItem(props, ref) {\n const {\n children,\n className,\n disabled,\n onClick,\n onFocus,\n onKeyDown,\n ...rest\n } = props;\n\n const { triggersSubmenu, blurActive } = useIsMenuTrigger();\n const { ExpandGroupIcon } = useIcon();\n const { activeIndex, getItemProps, setFocusInside } = useMenuPanelContext();\n const item = useListItem();\n const tree = useFloatingTree();\n const active = item.index === activeIndex;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-menu-item\",\n css: menuItemCss,\n window: targetWindow,\n });\n const handleRef = useForkRef<HTMLDivElement>(ref, item.ref);\n return (\n <div\n className={clsx(\n withBaseName(),\n {\n [withBaseName(\"blurActive\")]: blurActive,\n },\n className,\n )}\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n {...getItemProps({\n tabIndex: disabled ? undefined : active ? 0 : -1,\n onKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n const element = event.currentTarget;\n onKeyDown?.(event);\n if (\n (event.key === \" \" || event.key === \"Enter\") &&\n !triggersSubmenu &&\n !disabled\n ) {\n event.preventDefault();\n const { view, ...eventInit } = event;\n queueMicrotask(() => {\n element.dispatchEvent(\n new window.MouseEvent(\"click\", eventInit),\n );\n });\n tree?.events.emit(\"click\");\n }\n },\n onClick(event: MouseEvent<HTMLDivElement>) {\n if (!disabled) {\n onClick?.(event);\n if (!triggersSubmenu) {\n tree?.events.emit(\"click\");\n }\n }\n },\n onFocus(event: FocusEvent<HTMLDivElement>) {\n onFocus?.(event);\n setFocusInside(true);\n },\n ...rest,\n })}\n ref={handleRef}\n >\n {children}\n {triggersSubmenu && (\n <ExpandGroupIcon className={withBaseName(\"expandIcon\")} aria-hidden />\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MenuItem","useIsMenuTrigger","useIcon","useMenuPanelContext","useListItem","useFloatingTree","useWindow","useComponentCssInjection","menuItemCss","useForkRef","jsxs","clsx"],"mappings":"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"}
1
+ {"version":3,"file":"MenuItem.js","sources":["../src/menu/MenuItem.tsx"],"sourcesContent":["import { useFloatingTree, useListItem } from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type FocusEvent,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n useEffect,\n} from \"react\";\nimport { useIcon } from \"../semantic-icon-provider\";\nimport { makePrefixer, useForkRef } from \"../utils\";\nimport { useMenuContext } from \"./MenuContext\";\nimport menuItemCss from \"./MenuItem.css\";\nimport { useMenuPanelContext } from \"./MenuPanelContext\";\nimport { useIsMenuTrigger } from \"./MenuTriggerContext\";\nexport interface MenuItemProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * If `true`, the item will be disabled.\n */\n disabled?: boolean;\n}\n\nconst withBaseName = makePrefixer(\"saltMenuItem\");\n\nexport const MenuItem = forwardRef<HTMLDivElement, MenuItemProps>(\n function MenuItem(props, ref) {\n const {\n children,\n className,\n disabled,\n onClick,\n onFocus,\n onKeyDown,\n ...rest\n } = props;\n\n const { triggersSubmenu, blurActive } = useIsMenuTrigger();\n const { setTriggerDisabled } = useMenuContext();\n const { ExpandGroupIcon } = useIcon();\n const { activeIndex, getItemProps, setFocusInside } = useMenuPanelContext();\n const item = useListItem();\n const tree = useFloatingTree();\n const active = item.index === activeIndex;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-menu-item\",\n css: menuItemCss,\n window: targetWindow,\n });\n const handleRef = useForkRef<HTMLDivElement>(ref, item.ref);\n\n useEffect(() => {\n setTriggerDisabled(!!disabled);\n }, [disabled, setTriggerDisabled]);\n\n return (\n <div\n className={clsx(\n withBaseName(),\n {\n [withBaseName(\"blurActive\")]: blurActive,\n },\n className,\n )}\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n {...getItemProps({\n tabIndex: disabled ? undefined : active ? 0 : -1,\n onKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n const element = event.currentTarget;\n onKeyDown?.(event);\n if (\n (event.key === \" \" || event.key === \"Enter\") &&\n !triggersSubmenu &&\n !disabled\n ) {\n event.preventDefault();\n const { view, ...eventInit } = event;\n queueMicrotask(() => {\n element.dispatchEvent(\n new window.MouseEvent(\"click\", eventInit),\n );\n });\n tree?.events.emit(\"click\");\n }\n },\n onClick(event: MouseEvent<HTMLDivElement>) {\n if (!disabled) {\n onClick?.(event);\n if (!triggersSubmenu) {\n tree?.events.emit(\"click\");\n }\n }\n },\n onFocus(event: FocusEvent<HTMLDivElement>) {\n onFocus?.(event);\n setFocusInside(true);\n },\n ...rest,\n })}\n ref={handleRef}\n >\n {children}\n {triggersSubmenu && (\n <ExpandGroupIcon className={withBaseName(\"expandIcon\")} aria-hidden />\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MenuItem","useIsMenuTrigger","useMenuContext","useIcon","useMenuPanelContext","useListItem","useFloatingTree","useWindow","useComponentCssInjection","menuItemCss","useForkRef","useEffect","jsxs","clsx"],"mappings":"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"}
@@ -10,6 +10,7 @@ var useFormFieldProps = require('../form-field-context/useFormFieldProps.js');
10
10
  var StatusAdornment = require('../status-adornment/StatusAdornment.js');
11
11
  var makePrefixer = require('../utils/makePrefixer.js');
12
12
  var useControlled = require('../utils/useControlled.js');
13
+ var useIsomorphicLayoutEffect = require('../utils/useIsomorphicLayoutEffect.js');
13
14
  require('../utils/useFloatingUI/useFloatingUI.js');
14
15
  var useForkRef = require('../utils/useForkRef.js');
15
16
  require('../utils/useId.js');
@@ -112,7 +113,7 @@ const MultilineInput = React.forwardRef(
112
113
  onChange == null ? void 0 : onChange(event);
113
114
  changeHeight();
114
115
  };
115
- React.useLayoutEffect(() => {
116
+ useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
116
117
  changeHeight();
117
118
  }, [value, changeHeight]);
118
119
  const handleBlur = (event) => {
@@ -1 +1 @@
1
- {"version":3,"file":"MultilineInput.js","sources":["../src/multiline-input/MultilineInput.tsx"],"sourcesContent":["import { 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 forwardRef,\n type ReactNode,\n type Ref,\n type TextareaHTMLAttributes,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useFormFieldProps } from \"../form-field-context\";\nimport { StatusAdornment } from \"../status-adornment\";\nimport type { DataAttributes } from \"../types\";\nimport { makePrefixer, useControlled, useForkRef } from \"../utils\";\n\nimport multilineInputCss from \"./MultilineInput.css\";\n\nconst withBaseName = makePrefixer(\"saltMultilineInput\");\n\nexport interface MultilineInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"defaultValue\">,\n Pick<\n ComponentPropsWithoutRef<\"textarea\">,\n \"disabled\" | \"value\" | \"defaultValue\" | \"placeholder\"\n > {\n /**\n * Styling variant with full border. Defaults to false\n */\n bordered?: boolean;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * If `true`, the component is read only.\n */\n readOnly?: boolean;\n /**\n * The default minimum number of rows. Defaults to 3\n */\n rows?: number;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#Attributes) applied to the `textarea` element.\n */\n textAreaProps?: Partial<TextareaHTMLAttributes<HTMLTextAreaElement>> &\n DataAttributes;\n /**\n * Optional ref for the textarea component\n */\n textAreaRef?: Ref<HTMLTextAreaElement>;\n /**\n * Validation status.\n */\n validationStatus?: \"error\" | \"warning\" | \"success\";\n /**\n * Styling variant. Defaults to \"primary\".\n */\n variant?: \"primary\" | \"secondary\";\n}\n\nexport const MultilineInput = forwardRef<HTMLDivElement, MultilineInputProps>(\n function MultilineInput(\n {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n bordered = false,\n className: classNameProp,\n disabled,\n endAdornment,\n id,\n placeholder,\n readOnly,\n role,\n rows = 3,\n startAdornment,\n style,\n textAreaProps = {},\n textAreaRef,\n value: valueProp,\n defaultValue: defaultValueProp = valueProp === undefined ? \"\" : undefined,\n validationStatus: validationStatusProp,\n variant = \"primary\",\n ...other\n },\n ref,\n ) {\n const [inputElement, setInputElement] =\n useState<HTMLTextAreaElement | null>(null);\n const handleInputElement = useCallback(\n (element: HTMLTextAreaElement | null) => {\n setInputElement(element);\n },\n [],\n );\n const handleRef = useForkRef(handleInputElement, textAreaRef);\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-multiline-input\",\n css: multilineInputCss,\n window: targetWindow,\n });\n\n const restA11yProps = {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n };\n\n const [focused, setFocused] = useState(false);\n\n const {\n \"aria-describedby\": textAreaDescribedBy,\n \"aria-labelledby\": textAreaLabelledBy,\n onBlur,\n onChange,\n onFocus,\n required: textAreaRequired,\n ...restTextAreaProps\n } = textAreaProps;\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 = readOnly || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : textAreaRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValueProp,\n name: \"MultilineInput\",\n state: \"value\",\n });\n\n const previousHeight = useRef<string | undefined>(undefined);\n\n const changeHeight = useCallback(() => {\n const input = inputElement;\n\n if (!input) return;\n\n const hasBeenManuallyResized =\n previousHeight.current !== undefined &&\n input.style.height !== previousHeight.current;\n if (!hasBeenManuallyResized) {\n const previousOverflow = input.style.overflow;\n input.style.overflow = \"hidden\";\n input.style.height = \"auto\";\n input.scrollHeight; // Needed to work around Firefox bug. https://bugzilla.mozilla.org/show_bug.cgi?id=1787062\n const newHeight = `${\n input.scrollHeight + (input.offsetHeight - input.clientHeight)\n }px`;\n input.style.height = newHeight;\n previousHeight.current = newHeight;\n input.style.overflow = previousOverflow;\n }\n }, [inputElement]);\n\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n const value = event.target.value;\n setValue(value);\n onChange?.(event);\n changeHeight();\n };\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: We want to run this effect when value changes in a controlled component.\n useLayoutEffect(() => {\n changeHeight();\n }, [value, changeHeight]);\n\n const handleBlur = (event: FocusEvent<HTMLTextAreaElement>) => {\n onBlur?.(event);\n setFocused(false);\n };\n\n const handleFocus = (event: FocusEvent<HTMLTextAreaElement>) => {\n onFocus?.(event);\n setFocused(true);\n };\n\n const multilineInputStyles = {\n \"--saltMultilineInput-rows\": rows,\n ...style,\n };\n\n return (\n <div\n className={clsx(\n withBaseName(),\n withBaseName(variant),\n {\n [withBaseName(\"withAdornmentRow\")]: endAdornment,\n [withBaseName(\"bordered\")]: bordered,\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus ?? \"\")]: validationStatus,\n },\n classNameProp,\n )}\n ref={ref}\n style={multilineInputStyles}\n {...other}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <div className={withBaseName(\"wrapper\")}>\n <textarea\n aria-describedby={clsx(formFieldDescribedBy, textAreaDescribedBy)}\n aria-labelledby={clsx(formFieldLabelledBy, textAreaLabelledBy)}\n className={clsx(withBaseName(\"textarea\"), textAreaProps?.className)}\n disabled={isDisabled}\n id={id}\n readOnly={isReadOnly}\n ref={handleRef}\n required={isRequired}\n role={role}\n rows={rows}\n tabIndex={isDisabled ? -1 : 0}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={!isDisabled ? handleFocus : undefined}\n placeholder={placeholder}\n value={value}\n {...restA11yProps}\n {...restTextAreaProps}\n />\n </div>\n <div className={withBaseName(\"suffixAdornments\")}>\n {!isDisabled && validationStatus && (\n <div className={withBaseName(\"statusAdornmentContainer\")}>\n <StatusAdornment status={validationStatus} />\n </div>\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n </div>\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MultilineInput","useState","useCallback","useForkRef","useWindow","useComponentCssInjection","multilineInputCss","useFormFieldProps","useControlled","useRef","value","useLayoutEffect","jsxs","clsx","jsx","StatusAdornment"],"mappings":"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"}
1
+ {"version":3,"file":"MultilineInput.js","sources":["../src/multiline-input/MultilineInput.tsx"],"sourcesContent":["import { 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 forwardRef,\n type ReactNode,\n type Ref,\n type TextareaHTMLAttributes,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { useFormFieldProps } from \"../form-field-context\";\nimport { StatusAdornment } from \"../status-adornment\";\nimport type { DataAttributes } from \"../types\";\nimport {\n makePrefixer,\n useControlled,\n useForkRef,\n useIsomorphicLayoutEffect,\n} from \"../utils\";\n\nimport multilineInputCss from \"./MultilineInput.css\";\n\nconst withBaseName = makePrefixer(\"saltMultilineInput\");\n\nexport interface MultilineInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"defaultValue\">,\n Pick<\n ComponentPropsWithoutRef<\"textarea\">,\n \"disabled\" | \"value\" | \"defaultValue\" | \"placeholder\"\n > {\n /**\n * Styling variant with full border. Defaults to false\n */\n bordered?: boolean;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * If `true`, the component is read only.\n */\n readOnly?: boolean;\n /**\n * The default minimum number of rows. Defaults to 3\n */\n rows?: number;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#Attributes) applied to the `textarea` element.\n */\n textAreaProps?: Partial<TextareaHTMLAttributes<HTMLTextAreaElement>> &\n DataAttributes;\n /**\n * Optional ref for the textarea component\n */\n textAreaRef?: Ref<HTMLTextAreaElement>;\n /**\n * Validation status.\n */\n validationStatus?: \"error\" | \"warning\" | \"success\";\n /**\n * Styling variant. Defaults to \"primary\".\n */\n variant?: \"primary\" | \"secondary\";\n}\n\nexport const MultilineInput = forwardRef<HTMLDivElement, MultilineInputProps>(\n function MultilineInput(\n {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n bordered = false,\n className: classNameProp,\n disabled,\n endAdornment,\n id,\n placeholder,\n readOnly,\n role,\n rows = 3,\n startAdornment,\n style,\n textAreaProps = {},\n textAreaRef,\n value: valueProp,\n defaultValue: defaultValueProp = valueProp === undefined ? \"\" : undefined,\n validationStatus: validationStatusProp,\n variant = \"primary\",\n ...other\n },\n ref,\n ) {\n const [inputElement, setInputElement] =\n useState<HTMLTextAreaElement | null>(null);\n const handleInputElement = useCallback(\n (element: HTMLTextAreaElement | null) => {\n setInputElement(element);\n },\n [],\n );\n const handleRef = useForkRef(handleInputElement, textAreaRef);\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-multiline-input\",\n css: multilineInputCss,\n window: targetWindow,\n });\n\n const restA11yProps = {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n };\n\n const [focused, setFocused] = useState(false);\n\n const {\n \"aria-describedby\": textAreaDescribedBy,\n \"aria-labelledby\": textAreaLabelledBy,\n onBlur,\n onChange,\n onFocus,\n required: textAreaRequired,\n ...restTextAreaProps\n } = textAreaProps;\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 = readOnly || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : textAreaRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValueProp,\n name: \"MultilineInput\",\n state: \"value\",\n });\n\n const previousHeight = useRef<string | undefined>(undefined);\n\n const changeHeight = useCallback(() => {\n const input = inputElement;\n\n if (!input) return;\n\n const hasBeenManuallyResized =\n previousHeight.current !== undefined &&\n input.style.height !== previousHeight.current;\n if (!hasBeenManuallyResized) {\n const previousOverflow = input.style.overflow;\n input.style.overflow = \"hidden\";\n input.style.height = \"auto\";\n input.scrollHeight; // Needed to work around Firefox bug. https://bugzilla.mozilla.org/show_bug.cgi?id=1787062\n const newHeight = `${\n input.scrollHeight + (input.offsetHeight - input.clientHeight)\n }px`;\n input.style.height = newHeight;\n previousHeight.current = newHeight;\n input.style.overflow = previousOverflow;\n }\n }, [inputElement]);\n\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n const value = event.target.value;\n setValue(value);\n onChange?.(event);\n changeHeight();\n };\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: We want to run this effect when value changes in a controlled component.\n useIsomorphicLayoutEffect(() => {\n changeHeight();\n }, [value, changeHeight]);\n\n const handleBlur = (event: FocusEvent<HTMLTextAreaElement>) => {\n onBlur?.(event);\n setFocused(false);\n };\n\n const handleFocus = (event: FocusEvent<HTMLTextAreaElement>) => {\n onFocus?.(event);\n setFocused(true);\n };\n\n const multilineInputStyles = {\n \"--saltMultilineInput-rows\": rows,\n ...style,\n };\n\n return (\n <div\n className={clsx(\n withBaseName(),\n withBaseName(variant),\n {\n [withBaseName(\"withAdornmentRow\")]: endAdornment,\n [withBaseName(\"bordered\")]: bordered,\n [withBaseName(\"focused\")]: !isDisabled && focused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(validationStatus ?? \"\")]: validationStatus,\n },\n classNameProp,\n )}\n ref={ref}\n style={multilineInputStyles}\n {...other}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <div className={withBaseName(\"wrapper\")}>\n <textarea\n aria-describedby={clsx(formFieldDescribedBy, textAreaDescribedBy)}\n aria-labelledby={clsx(formFieldLabelledBy, textAreaLabelledBy)}\n className={clsx(withBaseName(\"textarea\"), textAreaProps?.className)}\n disabled={isDisabled}\n id={id}\n readOnly={isReadOnly}\n ref={handleRef}\n required={isRequired}\n role={role}\n rows={rows}\n tabIndex={isDisabled ? -1 : 0}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={!isDisabled ? handleFocus : undefined}\n placeholder={placeholder}\n value={value}\n {...restA11yProps}\n {...restTextAreaProps}\n />\n </div>\n <div className={withBaseName(\"suffixAdornments\")}>\n {!isDisabled && validationStatus && (\n <div className={withBaseName(\"statusAdornmentContainer\")}>\n <StatusAdornment status={validationStatus} />\n </div>\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n </div>\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MultilineInput","useState","useCallback","useForkRef","useWindow","useComponentCssInjection","multilineInputCss","useFormFieldProps","useControlled","useRef","value","useIsomorphicLayoutEffect","jsxs","clsx","jsx","StatusAdornment"],"mappings":"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"}
@@ -18,7 +18,7 @@ var useForkRef = require('../utils/useForkRef.js');
18
18
  var useId = require('../utils/useId.js');
19
19
  require('../salt-provider/SaltProvider.js');
20
20
  require('../viewport/ViewportProvider.js');
21
- var useActivateWhileMouseDown = require('./internal/useActivateWhileMouseDown.js');
21
+ var useLongPressPointerAction = require('./internal/useLongPressPointerAction.js');
22
22
  var NumberInput$1 = require('./NumberInput.css.js');
23
23
 
24
24
  const withBaseName = makePrefixer.makePrefixer("saltNumberInput");
@@ -230,7 +230,7 @@ const NumberInput = React.forwardRef(
230
230
  const parsedValue = parse(newValue);
231
231
  commit(event ?? null, parsedValue, newValue);
232
232
  };
233
- const { activate: activateDecrement } = useActivateWhileMouseDown.useActivateWhileMouseDown(
233
+ const activateDecrement = useLongPressPointerAction.useLongPressPointerAction(
234
234
  decrementValue,
235
235
  floatValue <= min
236
236
  );
@@ -247,7 +247,7 @@ const NumberInput = React.forwardRef(
247
247
  const parsedValue = parse(newValue);
248
248
  commit(event ?? null, parsedValue, newValue);
249
249
  };
250
- const { activate: activateIncrement } = useActivateWhileMouseDown.useActivateWhileMouseDown(
250
+ const activateIncrement = useLongPressPointerAction.useLongPressPointerAction(
251
251
  incrementValue,
252
252
  floatValue >= max
253
253
  );
@@ -296,7 +296,7 @@ const NumberInput = React.forwardRef(
296
296
  }
297
297
  inputOnKeyDown == null ? void 0 : inputOnKeyDown(event);
298
298
  };
299
- const handleIncrementMouseDown = (event, disableIncrement2) => {
299
+ const handleIncrementPointerDown = (event, disableIncrement2) => {
300
300
  event.preventDefault();
301
301
  if (!disableIncrement2) {
302
302
  setIsEditing(false);
@@ -305,7 +305,7 @@ const NumberInput = React.forwardRef(
305
305
  inputRef.current.select();
306
306
  }
307
307
  };
308
- const handleDecrementMouseDown = (event, disableDecrement2) => {
308
+ const handleDecrementPointerDown = (event, disableDecrement2) => {
309
309
  event.preventDefault();
310
310
  if (!disableDecrement2) {
311
311
  setIsEditing(false);
@@ -395,7 +395,7 @@ const NumberInput = React.forwardRef(
395
395
  tabIndex: -1,
396
396
  disabled: disableIncrement,
397
397
  className: withBaseName("increment"),
398
- onMouseDown: (event) => handleIncrementMouseDown(event, disableIncrement),
398
+ onPointerDown: (event) => handleIncrementPointerDown(event, disableIncrement),
399
399
  children: /* @__PURE__ */ jsxRuntime.jsx(IncreaseIcon, { "aria-hidden": true })
400
400
  }
401
401
  ),
@@ -407,7 +407,7 @@ const NumberInput = React.forwardRef(
407
407
  tabIndex: -1,
408
408
  disabled: disableDecrement,
409
409
  className: withBaseName("decrement"),
410
- onMouseDown: (event) => handleDecrementMouseDown(event, disableDecrement),
410
+ onPointerDown: (event) => handleDecrementPointerDown(event, disableDecrement),
411
411
  children: /* @__PURE__ */ jsxRuntime.jsx(DecreaseIcon, { "aria-hidden": true })
412
412
  }
413
413
  )
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.js","sources":["../src/number-input/NumberInput.tsx"],"sourcesContent":["import { 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 forwardRef,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEventHandler,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { Button } from \"../button\";\nimport { useFormFieldProps } from \"../form-field-context\";\nimport { useIcon } from \"../semantic-icon-provider\";\nimport { StatusAdornment } from \"../status-adornment\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport {\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useId,\n} from \"../utils\";\nimport { useActivateWhileMouseDown } from \"./internal/useActivateWhileMouseDown\";\nimport numberInputCss from \"./NumberInput.css\";\n\nconst withBaseName = makePrefixer(\"saltNumberInput\");\n\nexport interface NumberInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"onChange\" | \"defaultValue\" | \"value\"\n > {\n /**\n * Styling variant with full border.\n * @default false\n */\n bordered?: boolean;\n /**\n * A boolean that, when true, ensures the input value is clamped within the specified min and max range upon losing focus.\n * @default false\n */\n clamp?: boolean;\n /**\n * Number of decimal places allowed (only used by default parser/formatter).\n * Defaults to the decimal scale of either the initial value provided or the step, whichever is greater.\n * For high precision of larger numbers, consider a custom parser/formatter from a third-party library.\n */\n decimalScale?: number;\n /**\n * Custom decrement function to override the default increment behavior, use when higher precision or large numbers are required\n * value: current value\n * step: step value\n * stepMultiplier: step multiplier value, when using shift key navigation\n */\n decrement?: (value: string, step: number, stepMultiplier: number) => string;\n /**\n * The default value. Use when the component is uncontrolled.\n */\n defaultValue?: number | string;\n /**\n * Disable the `NumberInput`.\n * @default false\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * @default \"—\"\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component.\n */\n endAdornment?: ReactNode;\n /**\n * Callback to format the NumberInput value.\n * For high precision or large numbers, consider creating a custom parser/format using a third-party library.\n */\n format?: (value: string) => string;\n /**\n * Hide the number buttons.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * Custom increment function to override the default increment behavior, use when higher precision or large numbers are required\n * value: current value\n * step: step value\n * stepMultiplier: step multiplier value, when using shift key navigation\n */\n increment?: (value: string, step: number, stepMultiplier: number) => string;\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 * Callback that matches on values as you type and determines whether the value can be entered.\n */\n pattern?: (inputValue: string) => boolean;\n /**\n * The maximum value that can be selected.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback function that is triggered when the value changes via user input or increment/decrement.\n * Use `onNumberChange` if you want stable number, after blur or through increment/decrement\n *\n * @param event - The event that triggers the value change, can be null if called by long-press of increment/decrement\n * @param value - value as string\n */\n onChange?: (event: SyntheticEvent | null, value: string) => void;\n /**\n * Callback function that is triggered when the value changes via increment/decrement or on blur.\n *\n * @param event - The event that triggers the change, can be null if called by long-press of increment/decrement\n * @param value - The committed, parsed number value or null if an empty value\n */\n onNumberChange?: (event: SyntheticEvent | null, value: number | null) => void;\n /**\n * Callback to parse the NumberInput value, used with the `format` callback.\n * For high precision or large numbers, consider creating a custom parser/format using a third-party library. * Return null for empty input.\n */\n parse?: (value: string) => number | null;\n /**\n * A string displayed in a dimmed color when the `NumberInput` value is empty.\n */\n placeholder?: string;\n /**\n * A boolean property that controls the read-only state of the `NumberInput`.\n * - When set to `true`, the `NumberInput` becomes read-only, preventing user edits.\n * - When set to `false` or omitted, the `NumberInput` is 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 `NumberInput` buttons or Up Arrow and Down Arrow keys.\n * @default 1\n */\n step?: number;\n /**\n * Defines the factor by which the step value is multiplied to determine the maximum increment or decrement when the Shift key\n * is held while pressing the Up Arrow or Down Arrow keys for faster adjustments of the value.\n * @default 2\n */\n stepMultiplier?: number;\n /**\n * Specifies the alignment of the text within the `NumberInput`.\n *\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.\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * Value of the `NumberInput`, to be used when in a controlled state.\n */\n value?: number | string;\n}\n\nexport const isOutOfRange = (\n value: number | string,\n min: number,\n max: number,\n) => {\n if (typeof value === \"string\" && !value.length) {\n return true;\n }\n const floatValue =\n typeof value === \"string\" ? Number.parseFloat(value) : value;\n return Number.isNaN(floatValue) || floatValue > max || floatValue < min;\n};\n\nfunction getNumberPrecision(num: number | string) {\n const numStr = String(num);\n\n if (numStr.includes(\"e\") || numStr.includes(\"E\")) {\n const [base, exponent] = numStr.split(/[eE]/);\n const decimalPart = base.split(\".\")[1] || \"\";\n const precision = decimalPart.length - Number.parseInt(exponent, 10);\n return Math.max(0, precision);\n }\n\n if (numStr.includes(\".\")) {\n return numStr.split(\".\")[1].length;\n }\n\n return 0;\n}\n\nconst defaultPattern: NumberInputProps[\"pattern\"] = (inputValue) =>\n /^[+-]?(\\d+(\\.\\d*)?|\\.\\d*)?$/.test(inputValue);\n\nconst defaultDecrement = (\n value: string,\n step: number,\n stepMultiplier: number,\n parse: (v: string) => number | null,\n) => {\n const parsedValue = parse(value) ?? 0;\n const decrementStep = step * stepMultiplier;\n return String(parsedValue - decrementStep);\n};\n\nconst defaultIncrement = (\n value: string,\n step: number,\n stepMultiplier: number,\n parse: (v: string) => number | null,\n) => {\n const parsedValue = parse(value) ?? 0;\n const incrementStep = step * stepMultiplier;\n return String(parsedValue + incrementStep);\n};\n\nconst defaultFormat = (value: string, decimalScale: number): string => {\n const sanitized = value.trim();\n if (!sanitized.length) {\n return \"\";\n }\n const floatValue = Number.parseFloat(sanitized);\n const updatedValue = Number.isNaN(floatValue)\n ? sanitized\n : floatValue.toFixed(decimalScale);\n return String(updatedValue);\n};\n\nconst defaultParse = (value: string, decimalScale: number): number | null => {\n const sanitizedValue = value.trim();\n if (!sanitizedValue.length) {\n return null;\n }\n if (\n sanitizedValue === \".\" ||\n sanitizedValue === \"+\" ||\n sanitizedValue === \"-\"\n ) {\n return 0;\n }\n const floatString = Number.parseFloat(value).toFixed(decimalScale);\n return Number.parseFloat(floatString);\n};\n\nexport const NumberInput = forwardRef<HTMLDivElement, NumberInputProps>(\n function NumberInput(\n {\n \"aria-valuetext\": ariaValueTextProp,\n bordered,\n className,\n clamp,\n step = 1,\n stepMultiplier = 2,\n value: valueProp,\n defaultValue,\n decimalScale = Math.max(\n getNumberPrecision(valueProp ?? defaultValue ?? 0),\n getNumberPrecision(step),\n ),\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n format = (v: string) => defaultFormat(v, decimalScale),\n hideButtons,\n id,\n pattern = defaultPattern,\n inputProps = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onBlur,\n onChange,\n onMouseUp,\n onNumberChange,\n parse = (v: string) => defaultParse(v, decimalScale),\n placeholder,\n readOnly,\n startAdornment,\n decrement = (v, s, m) => defaultDecrement(v, s, m, parse),\n increment = (v, s, m) => defaultIncrement(v, s, m, parse),\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-number-input\",\n css: numberInputCss,\n window: targetWindow,\n });\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 = readOnly || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n const validationStatusId = useId(id);\n const inputRef = useRef<HTMLInputElement>(null);\n const handleInputRef = useForkRef(inputRefProp, inputRef);\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputProps;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [isFocused, setIsFocused] = useState(false);\n const [isEditing, setIsEditing] = useState(false);\n const { DecreaseIcon, IncreaseIcon } = useIcon();\n\n const [value, setValue] = useControlled({\n controlled: valueProp !== undefined ? String(valueProp) : undefined,\n default: String(defaultValue ?? \"\"),\n name: \"NumberInput\",\n state: \"value\",\n });\n\n // Committed values are complete numbers, created through blur or increment/decrement, not partial entries such as \"0.\" created by input/onChange.\n const lastCommitValue = useRef<string>(value);\n const commit = (\n event: SyntheticEvent | null,\n newNumber: number | null,\n newInputValue: string,\n ) => {\n let safeNumber = newNumber;\n if (safeNumber !== null && !Number.isNaN(safeNumber)) {\n safeNumber = Math.max(\n Number.MIN_SAFE_INTEGER,\n Math.min(Number.MAX_SAFE_INTEGER, safeNumber),\n );\n if (clamp) {\n safeNumber = Math.max(min, Math.min(max, safeNumber));\n }\n } else {\n // If not a valid number, treat as null\n safeNumber = null;\n }\n const commitValue =\n safeNumber !== null ? format(String(safeNumber)) : newInputValue;\n if (commitValue !== value) {\n setValue(commitValue);\n onChange?.(event, commitValue);\n }\n if (lastCommitValue.current !== commitValue) {\n onNumberChange?.(event, safeNumber);\n lastCommitValue.current = commitValue;\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setIsFocused(false);\n onBlur?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setIsEditing(false);\n inputOnBlur?.(event);\n const parsedValue = parse(value);\n commit(event, parsedValue, value);\n };\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setIsEditing(false);\n inputOnFocus?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const inputValue = event.currentTarget.value;\n\n if (!inputValue.length) {\n setValue(\"\");\n onChange?.(event, \"\");\n return;\n }\n const validValue = pattern ? pattern(inputValue) : true;\n\n if (validValue) {\n setIsEditing(true);\n onChange?.(event, event.target.value);\n setValue(inputValue);\n } else {\n event.preventDefault();\n }\n };\n\n let floatValue = parse(value) ?? 0;\n floatValue = Math.max(\n Number.MIN_SAFE_INTEGER,\n Math.min(Number.MAX_SAFE_INTEGER, floatValue),\n );\n if (clamp) {\n floatValue = Math.max(min, Math.min(max, floatValue));\n }\n\n const decrementValue = (event?: SyntheticEvent, block?: boolean) => {\n const validValue = parse(value) ?? 0;\n if (Number.isNaN(validValue)) {\n return;\n }\n const newValue = decrement(\n String(validValue),\n step,\n block ? stepMultiplier : 1,\n );\n const parsedValue = parse(newValue);\n commit(event ?? null, parsedValue, newValue);\n };\n\n const { activate: activateDecrement } = useActivateWhileMouseDown(\n decrementValue,\n floatValue <= min,\n );\n\n const incrementValue = (event?: SyntheticEvent, block?: boolean) => {\n const validValue = parse(value) ?? 0;\n if (Number.isNaN(validValue)) {\n return;\n }\n const newValue = increment(\n String(validValue),\n step,\n block ? stepMultiplier : 1,\n );\n const parsedValue = parse(newValue);\n commit(event ?? null, parsedValue, newValue);\n };\n\n const { activate: activateIncrement } = useActivateWhileMouseDown(\n incrementValue,\n floatValue >= max,\n );\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus();\n }\n }, [isFocused]);\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 const newValue = String(min);\n commit(event, min, newValue);\n break;\n }\n case \"End\": {\n event.preventDefault();\n const newValue = String(max);\n commit(event, max, newValue);\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 inputOnKeyDown?.(event);\n };\n\n const handleIncrementMouseDown = (\n event: SyntheticEvent,\n disableIncrement: boolean,\n ) => {\n event.preventDefault();\n if (!disableIncrement) {\n setIsEditing(false);\n activateIncrement(event);\n } else if (inputRef.current) {\n inputRef.current.select();\n }\n };\n\n const handleDecrementMouseDown = (\n event: SyntheticEvent,\n disableDecrement: boolean,\n ) => {\n event.preventDefault();\n if (!disableDecrement) {\n setIsEditing(false);\n activateDecrement(event);\n } else if (inputRef.current) {\n inputRef.current.select();\n }\n };\n\n const handleContainerMouseUp: MouseEventHandler<HTMLDivElement> = (\n event,\n ) => {\n setIsFocused(true);\n onMouseUp?.(event);\n };\n\n let renderedValue: string;\n if (isEditing) {\n renderedValue = value;\n } else if (!value?.length) {\n renderedValue = \"\";\n } else {\n renderedValue = format(\n Number.isNaN(floatValue) ? value : String(floatValue),\n );\n }\n\n const disableDecrement = disabled || floatValue - step < min;\n const disableIncrement = disabled || floatValue + step > max;\n return (\n <div\n className={clsx(\n withBaseName(),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: isFocused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(\"hiddenButtons\")]: hideButtons,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n className,\n )}\n onBlur={handleBlur}\n onMouseUp={handleContainerMouseUp}\n {...restProps}\n ref={ref}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n {/* biome-ignore lint/a11y/useAriaPropsSupportedByRole: Biome can't detect the role is determined by variable, aria-valuemax is only used when the role is appropriate. */}\n <input\n aria-describedby={\n clsx(formFieldDescribedBy, inputDescribedBy) || undefined\n }\n aria-labelledby={\n clsx(formFieldLabelledBy, inputLabelledBy) || undefined\n }\n aria-invalid={\n !isReadOnly && renderedValue.length\n ? isOutOfRange(floatValue, min, max) ||\n validationStatus === \"error\"\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={handleInputFocus}\n onKeyDown={isReadOnly ? undefined : handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n aria-readonly={isReadOnly ? \"true\" : undefined}\n ref={handleInputRef}\n required={isRequired}\n aria-valuemax={!isReadOnly && renderedValue.length ? max : undefined}\n aria-valuemin={!isReadOnly && renderedValue.length ? min : undefined}\n aria-valuenow={!isReadOnly ? floatValue : undefined}\n aria-valuetext={\n !isReadOnly\n ? renderedValue.length\n ? (ariaValueTextProp ?? renderedValue)\n : \"Empty\"\n : undefined\n }\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={\n isReadOnly && renderedValue.length === 0\n ? emptyReadOnlyMarker\n : renderedValue\n }\n {...restInputProps}\n />\n <div className={withBaseName(\"activationIndicator\")} />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} id={validationStatusId} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n {!isReadOnly && (\n <div className={clsx(withBaseName(\"buttonContainer\"))}>\n <Button\n aria-hidden={true}\n appearance=\"transparent\"\n tabIndex={-1}\n disabled={disableIncrement}\n className={withBaseName(\"increment\")}\n onMouseDown={(event) =>\n handleIncrementMouseDown(event, disableIncrement)\n }\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n aria-hidden={true}\n appearance=\"transparent\"\n tabIndex={-1}\n disabled={disableDecrement}\n className={withBaseName(\"decrement\")}\n onMouseDown={(event) =>\n handleDecrementMouseDown(event, disableDecrement)\n }\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","NumberInput","useWindow","useComponentCssInjection","numberInputCss","useFormFieldProps","useId","useRef","useForkRef","useState","useIcon","useControlled","useActivateWhileMouseDown","useEffect","disableIncrement","disableDecrement","jsxs","clsx","jsx","capitalize","StatusAdornment","Button"],"mappings":"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"}
1
+ {"version":3,"file":"NumberInput.js","sources":["../src/number-input/NumberInput.tsx"],"sourcesContent":["import { 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 forwardRef,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEventHandler,\n type PointerEvent,\n type ReactNode,\n type Ref,\n type SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { Button } from \"../button\";\nimport { useFormFieldProps } from \"../form-field-context\";\nimport { useIcon } from \"../semantic-icon-provider\";\nimport { StatusAdornment } from \"../status-adornment\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport {\n capitalize,\n makePrefixer,\n useControlled,\n useForkRef,\n useId,\n} from \"../utils\";\nimport { useLongPressPointerAction } from \"./internal/useLongPressPointerAction\";\nimport numberInputCss from \"./NumberInput.css\";\n\nconst withBaseName = makePrefixer(\"saltNumberInput\");\n\nexport interface NumberInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"onChange\" | \"defaultValue\" | \"value\"\n > {\n /**\n * Styling variant with full border.\n * @default false\n */\n bordered?: boolean;\n /**\n * A boolean that, when true, ensures the input value is clamped within the specified min and max range upon losing focus.\n * @default false\n */\n clamp?: boolean;\n /**\n * Number of decimal places allowed (only used by default parser/formatter).\n * Defaults to the decimal scale of either the initial value provided or the step, whichever is greater.\n * For high precision of larger numbers, consider a custom parser/formatter from a third-party library.\n */\n decimalScale?: number;\n /**\n * Custom decrement function to override the default increment behavior, use when higher precision or large numbers are required\n * value: current value\n * step: step value\n * stepMultiplier: step multiplier value, when using shift key navigation\n */\n decrement?: (value: string, step: number, stepMultiplier: number) => string;\n /**\n * The default value. Use when the component is uncontrolled.\n */\n defaultValue?: number | string;\n /**\n * Disable the `NumberInput`.\n * @default false\n */\n disabled?: boolean;\n /**\n * The marker to use in an empty read only Input.\n * @default \"—\"\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component.\n */\n endAdornment?: ReactNode;\n /**\n * Callback to format the NumberInput value.\n * For high precision or large numbers, consider creating a custom parser/format using a third-party library.\n */\n format?: (value: string) => string;\n /**\n * Hide the number buttons.\n * @default false\n */\n hideButtons?: boolean;\n /**\n * Custom increment function to override the default increment behavior, use when higher precision or large numbers are required\n * value: current value\n * step: step value\n * stepMultiplier: step multiplier value, when using shift key navigation\n */\n increment?: (value: string, step: number, stepMultiplier: number) => string;\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 * Callback that matches on values as you type and determines whether the value can be entered.\n */\n pattern?: (inputValue: string) => boolean;\n /**\n * The maximum value that can be selected.\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number;\n /**\n * The minimum value that can be selected.\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number;\n /**\n * Callback function that is triggered when the value changes via user input or increment/decrement.\n * Use `onNumberChange` if you want stable number, after blur or through increment/decrement\n *\n * @param event - The event that triggers the value change, can be null if called by long-press of increment/decrement\n * @param value - value as string\n */\n onChange?: (event: SyntheticEvent | null, value: string) => void;\n /**\n * Callback function that is triggered when the value changes via increment/decrement or on blur.\n *\n * @param event - The event that triggers the change, can be null if called by long-press of increment/decrement\n * @param value - The committed, parsed number value or null if an empty value\n */\n onNumberChange?: (event: SyntheticEvent | null, value: number | null) => void;\n /**\n * Callback to parse the NumberInput value, used with the `format` callback.\n * For high precision or large numbers, consider creating a custom parser/format using a third-party library. * Return null for empty input.\n */\n parse?: (value: string) => number | null;\n /**\n * A string displayed in a dimmed color when the `NumberInput` value is empty.\n */\n placeholder?: string;\n /**\n * A boolean property that controls the read-only state of the `NumberInput`.\n * - When set to `true`, the `NumberInput` becomes read-only, preventing user edits.\n * - When set to `false` or omitted, the `NumberInput` is 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 `NumberInput` buttons or Up Arrow and Down Arrow keys.\n * @default 1\n */\n step?: number;\n /**\n * Defines the factor by which the step value is multiplied to determine the maximum increment or decrement when the Shift key\n * is held while pressing the Up Arrow or Down Arrow keys for faster adjustments of the value.\n * @default 2\n */\n stepMultiplier?: number;\n /**\n * Specifies the alignment of the text within the `NumberInput`.\n *\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.\n * @default \"primary\"\n */\n variant?: \"primary\" | \"secondary\";\n /**\n * Value of the `NumberInput`, to be used when in a controlled state.\n */\n value?: number | string;\n}\n\nexport const isOutOfRange = (\n value: number | string,\n min: number,\n max: number,\n) => {\n if (typeof value === \"string\" && !value.length) {\n return true;\n }\n const floatValue =\n typeof value === \"string\" ? Number.parseFloat(value) : value;\n return Number.isNaN(floatValue) || floatValue > max || floatValue < min;\n};\n\nfunction getNumberPrecision(num: number | string) {\n const numStr = String(num);\n\n if (numStr.includes(\"e\") || numStr.includes(\"E\")) {\n const [base, exponent] = numStr.split(/[eE]/);\n const decimalPart = base.split(\".\")[1] || \"\";\n const precision = decimalPart.length - Number.parseInt(exponent, 10);\n return Math.max(0, precision);\n }\n\n if (numStr.includes(\".\")) {\n return numStr.split(\".\")[1].length;\n }\n\n return 0;\n}\n\nconst defaultPattern: NumberInputProps[\"pattern\"] = (inputValue) =>\n /^[+-]?(\\d+(\\.\\d*)?|\\.\\d*)?$/.test(inputValue);\n\nconst defaultDecrement = (\n value: string,\n step: number,\n stepMultiplier: number,\n parse: (v: string) => number | null,\n) => {\n const parsedValue = parse(value) ?? 0;\n const decrementStep = step * stepMultiplier;\n return String(parsedValue - decrementStep);\n};\n\nconst defaultIncrement = (\n value: string,\n step: number,\n stepMultiplier: number,\n parse: (v: string) => number | null,\n) => {\n const parsedValue = parse(value) ?? 0;\n const incrementStep = step * stepMultiplier;\n return String(parsedValue + incrementStep);\n};\n\nconst defaultFormat = (value: string, decimalScale: number): string => {\n const sanitized = value.trim();\n if (!sanitized.length) {\n return \"\";\n }\n const floatValue = Number.parseFloat(sanitized);\n const updatedValue = Number.isNaN(floatValue)\n ? sanitized\n : floatValue.toFixed(decimalScale);\n return String(updatedValue);\n};\n\nconst defaultParse = (value: string, decimalScale: number): number | null => {\n const sanitizedValue = value.trim();\n if (!sanitizedValue.length) {\n return null;\n }\n if (\n sanitizedValue === \".\" ||\n sanitizedValue === \"+\" ||\n sanitizedValue === \"-\"\n ) {\n return 0;\n }\n const floatString = Number.parseFloat(value).toFixed(decimalScale);\n return Number.parseFloat(floatString);\n};\n\nexport const NumberInput = forwardRef<HTMLDivElement, NumberInputProps>(\n function NumberInput(\n {\n \"aria-valuetext\": ariaValueTextProp,\n bordered,\n className,\n clamp,\n step = 1,\n stepMultiplier = 2,\n value: valueProp,\n defaultValue,\n decimalScale = Math.max(\n getNumberPrecision(valueProp ?? defaultValue ?? 0),\n getNumberPrecision(step),\n ),\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n format = (v: string) => defaultFormat(v, decimalScale),\n hideButtons,\n id,\n pattern = defaultPattern,\n inputProps = {},\n inputRef: inputRefProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onBlur,\n onChange,\n onMouseUp,\n onNumberChange,\n parse = (v: string) => defaultParse(v, decimalScale),\n placeholder,\n readOnly,\n startAdornment,\n decrement = (v, s, m) => defaultDecrement(v, s, m, parse),\n increment = (v, s, m) => defaultIncrement(v, s, m, parse),\n textAlign = \"left\",\n validationStatus: validationStatusProp,\n variant = \"primary\",\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-number-input\",\n css: numberInputCss,\n window: targetWindow,\n });\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 = readOnly || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n const validationStatusId = useId(id);\n const inputRef = useRef<HTMLInputElement>(null);\n const handleInputRef = useForkRef(inputRefProp, inputRef);\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n className: inputClassName,\n onBlur: inputOnBlur,\n onFocus: inputOnFocus,\n required: inputRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputProps;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputRequired;\n\n const [isFocused, setIsFocused] = useState(false);\n const [isEditing, setIsEditing] = useState(false);\n const { DecreaseIcon, IncreaseIcon } = useIcon();\n\n const [value, setValue] = useControlled({\n controlled: valueProp !== undefined ? String(valueProp) : undefined,\n default: String(defaultValue ?? \"\"),\n name: \"NumberInput\",\n state: \"value\",\n });\n\n // Committed values are complete numbers, created through blur or increment/decrement, not partial entries such as \"0.\" created by input/onChange.\n const lastCommitValue = useRef<string>(value);\n const commit = (\n event: SyntheticEvent | null,\n newNumber: number | null,\n newInputValue: string,\n ) => {\n let safeNumber = newNumber;\n if (safeNumber !== null && !Number.isNaN(safeNumber)) {\n safeNumber = Math.max(\n Number.MIN_SAFE_INTEGER,\n Math.min(Number.MAX_SAFE_INTEGER, safeNumber),\n );\n if (clamp) {\n safeNumber = Math.max(min, Math.min(max, safeNumber));\n }\n } else {\n // If not a valid number, treat as null\n safeNumber = null;\n }\n const commitValue =\n safeNumber !== null ? format(String(safeNumber)) : newInputValue;\n if (commitValue !== value) {\n setValue(commitValue);\n onChange?.(event, commitValue);\n }\n if (lastCommitValue.current !== commitValue) {\n onNumberChange?.(event, safeNumber);\n lastCommitValue.current = commitValue;\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setIsFocused(false);\n onBlur?.(event);\n };\n\n const handleInputBlur = (event: FocusEvent<HTMLInputElement>) => {\n setIsEditing(false);\n inputOnBlur?.(event);\n const parsedValue = parse(value);\n commit(event, parsedValue, value);\n };\n\n const handleInputFocus = (event: FocusEvent<HTMLInputElement>) => {\n setIsEditing(false);\n inputOnFocus?.(event);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const inputValue = event.currentTarget.value;\n\n if (!inputValue.length) {\n setValue(\"\");\n onChange?.(event, \"\");\n return;\n }\n const validValue = pattern ? pattern(inputValue) : true;\n\n if (validValue) {\n setIsEditing(true);\n onChange?.(event, event.target.value);\n setValue(inputValue);\n } else {\n event.preventDefault();\n }\n };\n\n let floatValue = parse(value) ?? 0;\n floatValue = Math.max(\n Number.MIN_SAFE_INTEGER,\n Math.min(Number.MAX_SAFE_INTEGER, floatValue),\n );\n if (clamp) {\n floatValue = Math.max(min, Math.min(max, floatValue));\n }\n\n const decrementValue = (event?: SyntheticEvent, block?: boolean) => {\n const validValue = parse(value) ?? 0;\n if (Number.isNaN(validValue)) {\n return;\n }\n const newValue = decrement(\n String(validValue),\n step,\n block ? stepMultiplier : 1,\n );\n const parsedValue = parse(newValue);\n commit(event ?? null, parsedValue, newValue);\n };\n\n const activateDecrement = useLongPressPointerAction(\n decrementValue,\n floatValue <= min,\n );\n\n const incrementValue = (event?: SyntheticEvent, block?: boolean) => {\n const validValue = parse(value) ?? 0;\n if (Number.isNaN(validValue)) {\n return;\n }\n const newValue = increment(\n String(validValue),\n step,\n block ? stepMultiplier : 1,\n );\n const parsedValue = parse(newValue);\n commit(event ?? null, parsedValue, newValue);\n };\n\n const activateIncrement = useLongPressPointerAction(\n incrementValue,\n floatValue >= max,\n );\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus();\n }\n }, [isFocused]);\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 const newValue = String(min);\n commit(event, min, newValue);\n break;\n }\n case \"End\": {\n event.preventDefault();\n const newValue = String(max);\n commit(event, max, newValue);\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 inputOnKeyDown?.(event);\n };\n\n const handleIncrementPointerDown = (\n event: PointerEvent,\n disableIncrement: boolean,\n ) => {\n event.preventDefault();\n if (!disableIncrement) {\n setIsEditing(false);\n activateIncrement(event);\n } else if (inputRef.current) {\n inputRef.current.select();\n }\n };\n\n const handleDecrementPointerDown = (\n event: PointerEvent,\n disableDecrement: boolean,\n ) => {\n event.preventDefault();\n if (!disableDecrement) {\n setIsEditing(false);\n activateDecrement(event);\n } else if (inputRef.current) {\n inputRef.current.select();\n }\n };\n\n const handleContainerMouseUp: MouseEventHandler<HTMLDivElement> = (\n event,\n ) => {\n setIsFocused(true);\n onMouseUp?.(event);\n };\n\n let renderedValue: string;\n if (isEditing) {\n renderedValue = value;\n } else if (!value?.length) {\n renderedValue = \"\";\n } else {\n renderedValue = format(\n Number.isNaN(floatValue) ? value : String(floatValue),\n );\n }\n\n const disableDecrement = disabled || floatValue - step < min;\n const disableIncrement = disabled || floatValue + step > max;\n return (\n <div\n className={clsx(\n withBaseName(),\n withBaseName(variant),\n {\n [withBaseName(\"focused\")]: isFocused,\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(\"hiddenButtons\")]: hideButtons,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n [withBaseName(\"bordered\")]: bordered,\n },\n className,\n )}\n onBlur={handleBlur}\n onMouseUp={handleContainerMouseUp}\n {...restProps}\n ref={ref}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n {/* biome-ignore lint/a11y/useAriaPropsSupportedByRole: Biome can't detect the role is determined by variable, aria-valuemax is only used when the role is appropriate. */}\n <input\n aria-describedby={\n clsx(formFieldDescribedBy, inputDescribedBy) || undefined\n }\n aria-labelledby={\n clsx(formFieldLabelledBy, inputLabelledBy) || undefined\n }\n aria-invalid={\n !isReadOnly && renderedValue.length\n ? isOutOfRange(floatValue, min, max) ||\n validationStatus === \"error\"\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={handleInputFocus}\n onKeyDown={isReadOnly ? undefined : handleInputKeyDown}\n placeholder={placeholder}\n readOnly={isReadOnly}\n aria-readonly={isReadOnly ? \"true\" : undefined}\n ref={handleInputRef}\n required={isRequired}\n aria-valuemax={!isReadOnly && renderedValue.length ? max : undefined}\n aria-valuemin={!isReadOnly && renderedValue.length ? min : undefined}\n aria-valuenow={!isReadOnly ? floatValue : undefined}\n aria-valuetext={\n !isReadOnly\n ? renderedValue.length\n ? (ariaValueTextProp ?? renderedValue)\n : \"Empty\"\n : undefined\n }\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={\n isReadOnly && renderedValue.length === 0\n ? emptyReadOnlyMarker\n : renderedValue\n }\n {...restInputProps}\n />\n <div className={withBaseName(\"activationIndicator\")} />\n {!isDisabled && validationStatus && (\n <StatusAdornment status={validationStatus} id={validationStatusId} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n {!isReadOnly && (\n <div className={clsx(withBaseName(\"buttonContainer\"))}>\n <Button\n aria-hidden={true}\n appearance=\"transparent\"\n tabIndex={-1}\n disabled={disableIncrement}\n className={withBaseName(\"increment\")}\n onPointerDown={(event) =>\n handleIncrementPointerDown(event, disableIncrement)\n }\n >\n <IncreaseIcon aria-hidden />\n </Button>\n <Button\n aria-hidden={true}\n appearance=\"transparent\"\n tabIndex={-1}\n disabled={disableDecrement}\n className={withBaseName(\"decrement\")}\n onPointerDown={(event) =>\n handleDecrementPointerDown(event, disableDecrement)\n }\n >\n <DecreaseIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","NumberInput","useWindow","useComponentCssInjection","numberInputCss","useFormFieldProps","useId","useRef","useForkRef","useState","useIcon","useControlled","useLongPressPointerAction","useEffect","disableIncrement","disableDecrement","jsxs","clsx","jsx","capitalize","StatusAdornment","Button"],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ var window = require('@salt-ds/window');
4
+ var React = require('react');
5
+ var useInterval = require('./useInterval.js');
6
+
7
+ const INITIAL_DELAY = 500;
8
+ const INTERVAL_DELAY = 100;
9
+ function useLongPressPointerAction(actionFn, isAtLimit) {
10
+ const [active, setActive] = React.useState(false);
11
+ const [delay, setDelay] = React.useState(INITIAL_DELAY);
12
+ const cancel = React.useCallback(() => {
13
+ setActive(false);
14
+ setDelay(INITIAL_DELAY);
15
+ }, []);
16
+ React.useEffect(() => {
17
+ if (isAtLimit) {
18
+ cancel();
19
+ }
20
+ }, [isAtLimit, cancel]);
21
+ const targetWindow = window.useWindow();
22
+ React.useEffect(() => {
23
+ if (targetWindow) {
24
+ targetWindow.addEventListener("pointerup", cancel);
25
+ targetWindow.addEventListener("pointercancel", cancel);
26
+ targetWindow.addEventListener("blur", cancel);
27
+ targetWindow.addEventListener("contextmenu", cancel);
28
+ }
29
+ return () => {
30
+ if (targetWindow) {
31
+ targetWindow.removeEventListener("pointerup", cancel);
32
+ targetWindow.removeEventListener("pointercancel", cancel);
33
+ targetWindow.removeEventListener("blur", cancel);
34
+ targetWindow.removeEventListener("contextmenu", cancel);
35
+ }
36
+ };
37
+ }, [cancel, targetWindow]);
38
+ const activate = React.useCallback(
39
+ (event) => {
40
+ if (event.pointerType === "mouse" && event.button === 0 || event.pointerType === "touch" || event.pointerType === "pen") {
41
+ actionFn(event);
42
+ setActive(true);
43
+ }
44
+ },
45
+ [actionFn]
46
+ );
47
+ useInterval.useInterval(
48
+ () => {
49
+ if (!active) {
50
+ return;
51
+ }
52
+ actionFn();
53
+ if (delay === INITIAL_DELAY) {
54
+ setDelay(INTERVAL_DELAY);
55
+ }
56
+ },
57
+ active ? delay : null
58
+ );
59
+ return activate;
60
+ }
61
+
62
+ exports.useLongPressPointerAction = useLongPressPointerAction;
63
+ //# sourceMappingURL=useLongPressPointerAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLongPressPointerAction.js","sources":["../src/number-input/internal/useLongPressPointerAction.ts"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport { type PointerEvent, useCallback, useEffect, useState } from \"react\";\nimport { useInterval } from \"./useInterval\";\n\nconst INITIAL_DELAY = 500;\nconst INTERVAL_DELAY = 100;\n\nexport function useLongPressPointerAction(\n actionFn: (event?: PointerEvent) => void,\n isAtLimit: boolean,\n) {\n const [active, setActive] = useState(false);\n const [delay, setDelay] = useState(INITIAL_DELAY);\n\n const cancel = useCallback(() => {\n setActive(false);\n setDelay(INITIAL_DELAY);\n }, []);\n\n useEffect(() => {\n if (isAtLimit) {\n cancel();\n }\n }, [isAtLimit, cancel]);\n\n const targetWindow = useWindow();\n useEffect(() => {\n if (targetWindow) {\n targetWindow.addEventListener(\"pointerup\", cancel);\n targetWindow.addEventListener(\"pointercancel\", cancel);\n targetWindow.addEventListener(\"blur\", cancel);\n targetWindow.addEventListener(\"contextmenu\", cancel); // Don't rely on this alone to cancel\n }\n return () => {\n if (targetWindow) {\n targetWindow.removeEventListener(\"pointerup\", cancel);\n targetWindow.removeEventListener(\"pointercancel\", cancel);\n targetWindow.removeEventListener(\"blur\", cancel);\n targetWindow.removeEventListener(\"contextmenu\", cancel);\n }\n };\n }, [cancel, targetWindow]);\n\n const activate = useCallback(\n (event: PointerEvent) => {\n // Only left mouse button, or any touch/pen\n if (\n (event.pointerType === \"mouse\" && event.button === 0) ||\n event.pointerType === \"touch\" ||\n event.pointerType === \"pen\"\n ) {\n actionFn(event);\n setActive(true);\n }\n },\n [actionFn],\n );\n\n useInterval(\n () => {\n if (!active) {\n return;\n }\n actionFn();\n if (delay === INITIAL_DELAY) {\n setDelay(INTERVAL_DELAY);\n }\n },\n active ? delay : null,\n );\n\n return activate;\n}\n"],"names":["useState","useCallback","useEffect","useWindow","useInterval"],"mappings":";;;;;;AAIA,MAAM,aAAA,GAAgB,GAAA;AACtB,MAAM,cAAA,GAAiB,GAAA;AAEhB,SAAS,yBAAA,CACd,UACA,SAAA,EACA;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,aAAa,CAAA;AAEhD,EAAA,MAAM,MAAA,GAASC,kBAAY,MAAM;AAC/B,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,QAAA,CAAS,aAAa,CAAA;AAAA,EACxB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;AAEtB,EAAA,MAAM,eAAeC,gBAAA,EAAU;AAC/B,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,CAAa,gBAAA,CAAiB,aAAa,MAAM,CAAA;AACjD,MAAA,YAAA,CAAa,gBAAA,CAAiB,iBAAiB,MAAM,CAAA;AACrD,MAAA,YAAA,CAAa,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AAC5C,MAAA,YAAA,CAAa,gBAAA,CAAiB,eAAe,MAAM,CAAA;AAAA,IACrD;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,CAAa,mBAAA,CAAoB,aAAa,MAAM,CAAA;AACpD,QAAA,YAAA,CAAa,mBAAA,CAAoB,iBAAiB,MAAM,CAAA;AACxD,QAAA,YAAA,CAAa,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAC/C,QAAA,YAAA,CAAa,mBAAA,CAAoB,eAAe,MAAM,CAAA;AAAA,MACxD;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,YAAY,CAAC,CAAA;AAEzB,EAAA,MAAM,QAAA,GAAWD,iBAAA;AAAA,IACf,CAAC,KAAA,KAAwB;AAEvB,MAAA,IACG,KAAA,CAAM,WAAA,KAAgB,OAAA,IAAW,KAAA,CAAM,MAAA,KAAW,CAAA,IACnD,KAAA,CAAM,WAAA,KAAgB,OAAA,IACtB,KAAA,CAAM,WAAA,KAAgB,KAAA,EACtB;AACA,QAAA,QAAA,CAAS,KAAK,CAAA;AACd,QAAA,SAAA,CAAU,IAAI,CAAA;AAAA,MAChB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAAG,uBAAA;AAAA,IACE,MAAM;AACJ,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA;AAAA,MACF;AACA,MAAA,QAAA,EAAS;AACT,MAAA,IAAI,UAAU,aAAA,EAAe;AAC3B,QAAA,QAAA,CAAS,cAAc,CAAA;AAAA,MACzB;AAAA,IACF,CAAA;AAAA,IACA,SAAS,KAAA,GAAQ;AAAA,GACnB;AAEA,EAAA,OAAO,QAAA;AACT;;;;"}