@salt-ds/core 1.44.0 → 1.45.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 (108) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/css/salt-core.css +449 -11
  3. package/dist-cjs/combo-box/ComboBox.js +4 -1
  4. package/dist-cjs/combo-box/ComboBox.js.map +1 -1
  5. package/dist-cjs/dropdown/Dropdown.js +6 -2
  6. package/dist-cjs/dropdown/Dropdown.js.map +1 -1
  7. package/dist-cjs/index.js +4 -0
  8. package/dist-cjs/index.js.map +1 -1
  9. package/dist-cjs/list-box/ListBox.js +6 -2
  10. package/dist-cjs/list-box/ListBox.js.map +1 -1
  11. package/dist-cjs/list-control/ListControlState.js +6 -5
  12. package/dist-cjs/list-control/ListControlState.js.map +1 -1
  13. package/dist-cjs/stepper/Step.css.js +6 -0
  14. package/dist-cjs/stepper/Step.css.js.map +1 -0
  15. package/dist-cjs/stepper/Step.js +166 -0
  16. package/dist-cjs/stepper/Step.js.map +1 -0
  17. package/dist-cjs/stepper/Stepper.css.js +6 -0
  18. package/dist-cjs/stepper/Stepper.css.js.map +1 -0
  19. package/dist-cjs/stepper/Stepper.js +40 -0
  20. package/dist-cjs/stepper/Stepper.js.map +1 -0
  21. package/dist-cjs/stepper/internal/StepConnector.css.js +6 -0
  22. package/dist-cjs/stepper/internal/StepConnector.css.js.map +1 -0
  23. package/dist-cjs/stepper/internal/StepConnector.js +27 -0
  24. package/dist-cjs/stepper/internal/StepConnector.js.map +1 -0
  25. package/dist-cjs/stepper/internal/StepExpandTrigger.css.js +6 -0
  26. package/dist-cjs/stepper/internal/StepExpandTrigger.css.js.map +1 -0
  27. package/dist-cjs/stepper/internal/StepExpandTrigger.js +45 -0
  28. package/dist-cjs/stepper/internal/StepExpandTrigger.js.map +1 -0
  29. package/dist-cjs/stepper/internal/StepIcon.css.js +6 -0
  30. package/dist-cjs/stepper/internal/StepIcon.css.js.map +1 -0
  31. package/dist-cjs/stepper/internal/StepIcon.js +62 -0
  32. package/dist-cjs/stepper/internal/StepIcon.js.map +1 -0
  33. package/dist-cjs/stepper/internal/StepScreenReaderOnly.js +13 -0
  34. package/dist-cjs/stepper/internal/StepScreenReaderOnly.js.map +1 -0
  35. package/dist-cjs/stepper/internal/StepText.css.js +6 -0
  36. package/dist-cjs/stepper/internal/StepText.css.js.map +1 -0
  37. package/dist-cjs/stepper/internal/StepText.js +50 -0
  38. package/dist-cjs/stepper/internal/StepText.js.map +1 -0
  39. package/dist-cjs/stepper/internal/StepperProvider.js +19 -0
  40. package/dist-cjs/stepper/internal/StepperProvider.js.map +1 -0
  41. package/dist-cjs/toggle-button/ToggleButton.css.js +1 -1
  42. package/dist-cjs/toggle-button/ToggleButton.js +32 -19
  43. package/dist-cjs/toggle-button/ToggleButton.js.map +1 -1
  44. package/dist-cjs/toggle-button-group/ToggleButtonGroup.css.js +1 -1
  45. package/dist-cjs/toggle-button-group/ToggleButtonGroup.js +30 -6
  46. package/dist-cjs/toggle-button-group/ToggleButtonGroup.js.map +1 -1
  47. package/dist-cjs/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
  48. package/dist-es/combo-box/ComboBox.js +4 -1
  49. package/dist-es/combo-box/ComboBox.js.map +1 -1
  50. package/dist-es/dropdown/Dropdown.js +6 -2
  51. package/dist-es/dropdown/Dropdown.js.map +1 -1
  52. package/dist-es/index.js +2 -0
  53. package/dist-es/index.js.map +1 -1
  54. package/dist-es/list-box/ListBox.js +6 -2
  55. package/dist-es/list-box/ListBox.js.map +1 -1
  56. package/dist-es/list-control/ListControlState.js +6 -5
  57. package/dist-es/list-control/ListControlState.js.map +1 -1
  58. package/dist-es/stepper/Step.css.js +4 -0
  59. package/dist-es/stepper/Step.css.js.map +1 -0
  60. package/dist-es/stepper/Step.js +164 -0
  61. package/dist-es/stepper/Step.js.map +1 -0
  62. package/dist-es/stepper/Stepper.css.js +4 -0
  63. package/dist-es/stepper/Stepper.css.js.map +1 -0
  64. package/dist-es/stepper/Stepper.js +38 -0
  65. package/dist-es/stepper/Stepper.js.map +1 -0
  66. package/dist-es/stepper/internal/StepConnector.css.js +4 -0
  67. package/dist-es/stepper/internal/StepConnector.css.js.map +1 -0
  68. package/dist-es/stepper/internal/StepConnector.js +25 -0
  69. package/dist-es/stepper/internal/StepConnector.js.map +1 -0
  70. package/dist-es/stepper/internal/StepExpandTrigger.css.js +4 -0
  71. package/dist-es/stepper/internal/StepExpandTrigger.css.js.map +1 -0
  72. package/dist-es/stepper/internal/StepExpandTrigger.js +43 -0
  73. package/dist-es/stepper/internal/StepExpandTrigger.js.map +1 -0
  74. package/dist-es/stepper/internal/StepIcon.css.js +4 -0
  75. package/dist-es/stepper/internal/StepIcon.css.js.map +1 -0
  76. package/dist-es/stepper/internal/StepIcon.js +60 -0
  77. package/dist-es/stepper/internal/StepIcon.js.map +1 -0
  78. package/dist-es/stepper/internal/StepScreenReaderOnly.js +11 -0
  79. package/dist-es/stepper/internal/StepScreenReaderOnly.js.map +1 -0
  80. package/dist-es/stepper/internal/StepText.css.js +4 -0
  81. package/dist-es/stepper/internal/StepText.css.js.map +1 -0
  82. package/dist-es/stepper/internal/StepText.js +48 -0
  83. package/dist-es/stepper/internal/StepText.js.map +1 -0
  84. package/dist-es/stepper/internal/StepperProvider.js +15 -0
  85. package/dist-es/stepper/internal/StepperProvider.js.map +1 -0
  86. package/dist-es/toggle-button/ToggleButton.css.js +1 -1
  87. package/dist-es/toggle-button/ToggleButton.js +32 -19
  88. package/dist-es/toggle-button/ToggleButton.js.map +1 -1
  89. package/dist-es/toggle-button-group/ToggleButtonGroup.css.js +1 -1
  90. package/dist-es/toggle-button-group/ToggleButtonGroup.js +30 -6
  91. package/dist-es/toggle-button-group/ToggleButtonGroup.js.map +1 -1
  92. package/dist-es/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
  93. package/dist-types/combo-box/useComboBox.d.ts +7 -7
  94. package/dist-types/index.d.ts +1 -0
  95. package/dist-types/list-control/ListControlState.d.ts +7 -7
  96. package/dist-types/stepper/Step.d.ts +46 -0
  97. package/dist-types/stepper/Stepper.d.ts +9 -0
  98. package/dist-types/stepper/index.d.ts +2 -0
  99. package/dist-types/stepper/internal/StepConnector.d.ts +1 -0
  100. package/dist-types/stepper/internal/StepExpandTrigger.d.ts +5 -0
  101. package/dist-types/stepper/internal/StepIcon.d.ts +8 -0
  102. package/dist-types/stepper/internal/StepScreenReaderOnly.d.ts +5 -0
  103. package/dist-types/stepper/internal/StepText.d.ts +5 -0
  104. package/dist-types/stepper/internal/StepperProvider.d.ts +9 -0
  105. package/dist-types/toggle-button/ToggleButton.d.ts +25 -1
  106. package/dist-types/toggle-button-group/ToggleButtonGroup.d.ts +16 -2
  107. package/dist-types/toggle-button-group/ToggleButtonGroupContext.d.ts +6 -2
  108. package/package.json +1 -1
package/dist-es/index.js CHANGED
@@ -90,6 +90,8 @@ export { StackLayout } from './stack-layout/StackLayout.js';
90
90
  export { StatusAdornment } from './status-adornment/StatusAdornment.js';
91
91
  export { StatusIndicator } from './status-indicator/StatusIndicator.js';
92
92
  export { VALIDATION_NAMED_STATUS } from './status-indicator/ValidationStatus.js';
93
+ export { Stepper } from './stepper/Stepper.js';
94
+ export { Step } from './stepper/Step.js';
93
95
  export { Text } from './text/Text.js';
94
96
  export { Code } from './text/Code.js';
95
97
  export { Display1, Display2, Display3, Display4 } from './text/Display.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -83,14 +83,18 @@ const ListBox = forwardRef(function ListBox2(props, ref) {
83
83
  }
84
84
  };
85
85
  const handleKeyDown = (event) => {
86
+ var _a;
86
87
  onKeyDown == null ? void 0 : onKeyDown(event);
87
88
  if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
88
89
  event.preventDefault();
89
90
  event.stopPropagation();
90
91
  handleTypeahead(event);
91
92
  }
92
- const activeOption = activeState ?? getFirstOption().data;
93
- let newActive = null;
93
+ const activeOption = activeState ?? ((_a = getFirstOption()) == null ? void 0 : _a.data);
94
+ if (activeOption === void 0) {
95
+ return;
96
+ }
97
+ let newActive = void 0;
94
98
  switch (event.key) {
95
99
  case "ArrowDown":
96
100
  newActive = getOptionAfter(activeOption) ?? getLastOption();
@@ -1 +1 @@
1
- {"version":3,"file":"ListBox.js","sources":["../src/list-box/ListBox.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type ForwardedRef,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n forwardRef,\n useRef,\n} from \"react\";\nimport {\n ListControlContext,\n type OptionValue,\n} from \"../list-control/ListControlContext\";\nimport {\n type ListControlProps,\n defaultValueToString,\n useListControl,\n} from \"../list-control/ListControlState\";\nimport { makePrefixer, useForkRef } from \"../utils\";\n\nimport listBoxCss from \"./ListBox.css\";\n\nexport type ListBoxProps<Item = string> = {\n /**\n * If `true`, the list box will be disabled.\n */\n disabled?: boolean;\n /**\n * If `false`, the list box will have not a border.\n */\n bordered?: boolean;\n /**\n * The options to display in the list box.\n */\n children?: ReactNode;\n /**\n * If `true`, the list box will be multiselect.\n */\n multiselect?: boolean;\n} & ComponentPropsWithoutRef<\"div\"> &\n Omit<ListControlProps<Item>, \"onOpenChange\">;\n\nconst withBaseName = makePrefixer(\"saltListBox\");\n\nexport const ListBox = forwardRef(function ListBox<Item>(\n props: ListBoxProps<Item>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const {\n bordered,\n className,\n children,\n defaultSelected,\n disabled,\n selected,\n onSelectionChange,\n multiselect,\n valueToString = defaultValueToString,\n onKeyDown,\n onFocus,\n onBlur,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-list-box\",\n css: listBoxCss,\n window: targetWindow,\n });\n\n const listControl = useListControl<Item>({\n multiselect,\n defaultSelected,\n selected,\n onSelectionChange,\n valueToString,\n disabled,\n });\n\n const {\n activeState,\n setActive,\n getOptionAtIndex,\n getIndexOfOption,\n getOptionsMatching,\n getOptionFromSearch,\n getFirstOption,\n getLastOption,\n getOptionAfter,\n getOptionBefore,\n getOptionPageAbove,\n getOptionPageBelow,\n selectedState,\n select,\n setFocusVisibleState,\n setFocusedState,\n listRef,\n } = listControl;\n\n const typeaheadString = useRef(\"\");\n const typeaheadTimeout = useRef<number | undefined>();\n\n const handleTypeahead = (event: KeyboardEvent<HTMLDivElement>) => {\n if (typeaheadTimeout.current) {\n clearTimeout(typeaheadTimeout.current);\n }\n typeaheadString.current += event.key;\n typeaheadTimeout.current = window.setTimeout(() => {\n typeaheadString.current = \"\";\n }, 500);\n\n let newOption = getOptionFromSearch(typeaheadString.current, activeState);\n\n if (!newOption) {\n newOption = getOptionFromSearch(typeaheadString.current);\n }\n\n if (newOption) {\n setActive(newOption);\n setFocusVisibleState(true);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n event.stopPropagation();\n handleTypeahead(event);\n }\n\n const activeOption = activeState ?? getFirstOption().data;\n\n let newActive: { data: OptionValue<Item>; element: HTMLElement } | null =\n null;\n switch (event.key) {\n case \"ArrowDown\":\n newActive = getOptionAfter(activeOption) ?? getLastOption();\n break;\n case \"ArrowUp\":\n newActive = getOptionBefore(activeOption) ?? getFirstOption();\n break;\n case \"Home\":\n newActive = getFirstOption();\n break;\n case \"End\":\n newActive = getLastOption();\n break;\n case \"PageUp\":\n newActive = getOptionPageAbove(activeOption);\n break;\n case \"PageDown\":\n newActive = getOptionPageBelow(activeOption);\n break;\n case \"Enter\":\n case \" \":\n if (\n Boolean(activeState?.disabled) ||\n (typeaheadString.current.trim().length > 0 && event.key === \" \")\n ) {\n event.preventDefault();\n return;\n }\n\n if (!activeState) {\n return;\n }\n\n event.preventDefault();\n select(event, activeState);\n\n break;\n }\n\n if (newActive && newActive.data.id !== activeState?.id) {\n event.preventDefault();\n setActive(newActive.data);\n setFocusVisibleState(true);\n }\n };\n\n const wasMouseDown = useRef(false);\n\n const handleMouseDown = () => {\n wasMouseDown.current = true;\n };\n\n const handleFocus = (event: FocusEvent<HTMLDivElement>) => {\n if (wasMouseDown.current) {\n wasMouseDown.current = false;\n return;\n }\n\n setFocusVisibleState(true);\n wasMouseDown.current = false;\n\n // We check the active index because the active item may have been removed\n const activeIndex = activeState ? getIndexOfOption(activeState) : -1;\n let newActive = undefined;\n\n // If the active item is still in the list, we don't need to do anything\n if (activeIndex > 0) {\n return;\n }\n\n // If we have selected an item, we should make that the active item\n if (selectedState.length > 0) {\n newActive = getOptionsMatching(\n (option) => option.value === selectedState[0],\n ).pop();\n }\n\n // If we still don't have an active item, we should just select the first item\n if (!newActive) {\n newActive = getOptionAtIndex(0);\n }\n\n setActive(newActive?.data);\n setFocusedState(true);\n onFocus?.(event);\n };\n\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n setFocusedState(false);\n setActive(undefined);\n onBlur?.(event);\n };\n\n const handleListMouseOver = () => {\n setFocusVisibleState(false);\n setActive(undefined);\n };\n\n const handleRef = useForkRef(listRef, ref);\n\n return (\n <ListControlContext.Provider value={listControl}>\n <div\n className={clsx(\n withBaseName(),\n { [withBaseName(\"bordered\")]: bordered },\n className,\n )}\n role=\"listbox\"\n aria-activedescendant={activeState?.id}\n aria-disabled={disabled || undefined}\n aria-multiselectable={multiselect}\n tabIndex={disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onMouseOver={handleListMouseOver}\n onMouseDown={handleMouseDown}\n ref={handleRef}\n {...rest}\n >\n {children}\n </div>\n </ListControlContext.Provider>\n );\n}) as <Item = string>(\n props: ListBoxProps<Item> & { ref?: Ref<HTMLDivElement> },\n) => JSX.Element;\n"],"names":["ListBox","listBoxCss"],"mappings":"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"}
1
+ {"version":3,"file":"ListBox.js","sources":["../src/list-box/ListBox.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type FocusEvent,\n type ForwardedRef,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n forwardRef,\n useRef,\n} from \"react\";\nimport {\n ListControlContext,\n type OptionValue,\n} from \"../list-control/ListControlContext\";\nimport {\n type ListControlProps,\n defaultValueToString,\n useListControl,\n} from \"../list-control/ListControlState\";\nimport { makePrefixer, useForkRef } from \"../utils\";\n\nimport listBoxCss from \"./ListBox.css\";\n\nexport type ListBoxProps<Item = string> = {\n /**\n * If `true`, the list box will be disabled.\n */\n disabled?: boolean;\n /**\n * If `false`, the list box will have not a border.\n */\n bordered?: boolean;\n /**\n * The options to display in the list box.\n */\n children?: ReactNode;\n /**\n * If `true`, the list box will be multiselect.\n */\n multiselect?: boolean;\n} & ComponentPropsWithoutRef<\"div\"> &\n Omit<ListControlProps<Item>, \"onOpenChange\">;\n\nconst withBaseName = makePrefixer(\"saltListBox\");\n\nexport const ListBox = forwardRef(function ListBox<Item>(\n props: ListBoxProps<Item>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const {\n bordered,\n className,\n children,\n defaultSelected,\n disabled,\n selected,\n onSelectionChange,\n multiselect,\n valueToString = defaultValueToString,\n onKeyDown,\n onFocus,\n onBlur,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-list-box\",\n css: listBoxCss,\n window: targetWindow,\n });\n\n const listControl = useListControl<Item>({\n multiselect,\n defaultSelected,\n selected,\n onSelectionChange,\n valueToString,\n disabled,\n });\n\n const {\n activeState,\n setActive,\n getOptionAtIndex,\n getIndexOfOption,\n getOptionsMatching,\n getOptionFromSearch,\n getFirstOption,\n getLastOption,\n getOptionAfter,\n getOptionBefore,\n getOptionPageAbove,\n getOptionPageBelow,\n selectedState,\n select,\n setFocusVisibleState,\n setFocusedState,\n listRef,\n } = listControl;\n\n const typeaheadString = useRef(\"\");\n const typeaheadTimeout = useRef<number | undefined>();\n\n const handleTypeahead = (event: KeyboardEvent<HTMLDivElement>) => {\n if (typeaheadTimeout.current) {\n clearTimeout(typeaheadTimeout.current);\n }\n typeaheadString.current += event.key;\n typeaheadTimeout.current = window.setTimeout(() => {\n typeaheadString.current = \"\";\n }, 500);\n\n let newOption = getOptionFromSearch(typeaheadString.current, activeState);\n\n if (!newOption) {\n newOption = getOptionFromSearch(typeaheadString.current);\n }\n\n if (newOption) {\n setActive(newOption);\n setFocusVisibleState(true);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n event.stopPropagation();\n handleTypeahead(event);\n }\n\n const activeOption = activeState ?? getFirstOption()?.data;\n\n if (activeOption === undefined) {\n return;\n }\n\n let newActive:\n | { data: OptionValue<Item>; element: HTMLElement }\n | undefined = undefined;\n switch (event.key) {\n case \"ArrowDown\":\n newActive = getOptionAfter(activeOption) ?? getLastOption();\n break;\n case \"ArrowUp\":\n newActive = getOptionBefore(activeOption) ?? getFirstOption();\n break;\n case \"Home\":\n newActive = getFirstOption();\n break;\n case \"End\":\n newActive = getLastOption();\n break;\n case \"PageUp\":\n newActive = getOptionPageAbove(activeOption);\n break;\n case \"PageDown\":\n newActive = getOptionPageBelow(activeOption);\n break;\n case \"Enter\":\n case \" \":\n if (\n Boolean(activeState?.disabled) ||\n (typeaheadString.current.trim().length > 0 && event.key === \" \")\n ) {\n event.preventDefault();\n return;\n }\n\n if (!activeState) {\n return;\n }\n\n event.preventDefault();\n select(event, activeState);\n\n break;\n }\n\n if (newActive && newActive.data.id !== activeState?.id) {\n event.preventDefault();\n setActive(newActive.data);\n setFocusVisibleState(true);\n }\n };\n\n const wasMouseDown = useRef(false);\n\n const handleMouseDown = () => {\n wasMouseDown.current = true;\n };\n\n const handleFocus = (event: FocusEvent<HTMLDivElement>) => {\n if (wasMouseDown.current) {\n wasMouseDown.current = false;\n return;\n }\n\n setFocusVisibleState(true);\n wasMouseDown.current = false;\n\n // We check the active index because the active item may have been removed\n const activeIndex = activeState ? getIndexOfOption(activeState) : -1;\n let newActive = undefined;\n\n // If the active item is still in the list, we don't need to do anything\n if (activeIndex > 0) {\n return;\n }\n\n // If we have selected an item, we should make that the active item\n if (selectedState.length > 0) {\n newActive = getOptionsMatching(\n (option) => option.value === selectedState[0],\n ).pop();\n }\n\n // If we still don't have an active item, we should just select the first item\n if (!newActive) {\n newActive = getOptionAtIndex(0);\n }\n\n setActive(newActive?.data);\n setFocusedState(true);\n onFocus?.(event);\n };\n\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n setFocusedState(false);\n setActive(undefined);\n onBlur?.(event);\n };\n\n const handleListMouseOver = () => {\n setFocusVisibleState(false);\n setActive(undefined);\n };\n\n const handleRef = useForkRef(listRef, ref);\n\n return (\n <ListControlContext.Provider value={listControl}>\n <div\n className={clsx(\n withBaseName(),\n { [withBaseName(\"bordered\")]: bordered },\n className,\n )}\n role=\"listbox\"\n aria-activedescendant={activeState?.id}\n aria-disabled={disabled || undefined}\n aria-multiselectable={multiselect}\n tabIndex={disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onMouseOver={handleListMouseOver}\n onMouseDown={handleMouseDown}\n ref={handleRef}\n {...rest}\n >\n {children}\n </div>\n </ListControlContext.Provider>\n );\n}) as <Item = string>(\n props: ListBoxProps<Item> & { ref?: Ref<HTMLDivElement> },\n) => JSX.Element;\n"],"names":["ListBox","listBoxCss"],"mappings":";;;;;;;;;;;;;;;AA8CA,MAAM,YAAA,GAAe,aAAa,aAAa,CAAA;AAExC,MAAM,OAAU,GAAA,UAAA,CAAW,SAASA,QAAAA,CACzC,OACA,GACA,EAAA;AACA,EAAM,MAAA;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAgB,GAAA,oBAAA;AAAA,IAChB,SAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,GAAG;AAAA,GACD,GAAA,KAAA;AACJ,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,eAAA;AAAA,IACR,GAAK,EAAAC,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,cAAc,cAAqB,CAAA;AAAA,IACvC,WAAA;AAAA,IACA,eAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,WAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,mBAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,MAAA;AAAA,IACA,oBAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACE,GAAA,WAAA;AAEJ,EAAM,MAAA,eAAA,GAAkB,OAAO,EAAE,CAAA;AACjC,EAAA,MAAM,mBAAmB,MAA2B,EAAA;AAEpD,EAAM,MAAA,eAAA,GAAkB,CAAC,KAAyC,KAAA;AAChE,IAAA,IAAI,iBAAiB,OAAS,EAAA;AAC5B,MAAA,YAAA,CAAa,iBAAiB,OAAO,CAAA;AAAA;AAEvC,IAAA,eAAA,CAAgB,WAAW,KAAM,CAAA,GAAA;AACjC,IAAiB,gBAAA,CAAA,OAAA,GAAU,MAAO,CAAA,UAAA,CAAW,MAAM;AACjD,MAAA,eAAA,CAAgB,OAAU,GAAA,EAAA;AAAA,OACzB,GAAG,CAAA;AAEN,IAAA,IAAI,SAAY,GAAA,mBAAA,CAAoB,eAAgB,CAAA,OAAA,EAAS,WAAW,CAAA;AAExE,IAAA,IAAI,CAAC,SAAW,EAAA;AACd,MAAY,SAAA,GAAA,mBAAA,CAAoB,gBAAgB,OAAO,CAAA;AAAA;AAGzD,IAAA,IAAI,SAAW,EAAA;AACb,MAAA,SAAA,CAAU,SAAS,CAAA;AACnB,MAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA;AAC3B,GACF;AAEA,EAAM,MAAA,aAAA,GAAgB,CAAC,KAAyC,KAAA;AA/HlE,IAAA,IAAA,EAAA;AAgII,IAAY,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAA,KAAA,CAAA;AAEZ,IAAA,IACE,KAAM,CAAA,GAAA,CAAI,MAAW,KAAA,CAAA,IACrB,CAAC,KAAA,CAAM,OACP,IAAA,CAAC,KAAM,CAAA,OAAA,IACP,CAAC,KAAA,CAAM,MACP,EAAA;AACA,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,KAAA,CAAM,eAAgB,EAAA;AACtB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA;AAGvB,IAAA,MAAM,YAAe,GAAA,WAAA,KAAA,CAAe,EAAe,GAAA,cAAA,EAAA,KAAf,IAAkB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA;AAEtD,IAAA,IAAI,iBAAiB,KAAW,CAAA,EAAA;AAC9B,MAAA;AAAA;AAGF,IAAA,IAAI,SAEY,GAAA,KAAA,CAAA;AAChB,IAAA,QAAQ,MAAM,GAAK;AAAA,MACjB,KAAK,WAAA;AACH,QAAY,SAAA,GAAA,cAAA,CAAe,YAAY,CAAA,IAAK,aAAc,EAAA;AAC1D,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAY,SAAA,GAAA,eAAA,CAAgB,YAAY,CAAA,IAAK,cAAe,EAAA;AAC5D,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,SAAA,GAAY,cAAe,EAAA;AAC3B,QAAA;AAAA,MACF,KAAK,KAAA;AACH,QAAA,SAAA,GAAY,aAAc,EAAA;AAC1B,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,SAAA,GAAY,mBAAmB,YAAY,CAAA;AAC3C,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,SAAA,GAAY,mBAAmB,YAAY,CAAA;AAC3C,QAAA;AAAA,MACF,KAAK,OAAA;AAAA,MACL,KAAK,GAAA;AACH,QAAA,IACE,OAAQ,CAAA,WAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAa,QAAQ,CAAA,IAC5B,eAAgB,CAAA,OAAA,CAAQ,IAAK,EAAA,CAAE,MAAS,GAAA,CAAA,IAAK,KAAM,CAAA,GAAA,KAAQ,GAC5D,EAAA;AACA,UAAA,KAAA,CAAM,cAAe,EAAA;AACrB,UAAA;AAAA;AAGF,QAAA,IAAI,CAAC,WAAa,EAAA;AAChB,UAAA;AAAA;AAGF,QAAA,KAAA,CAAM,cAAe,EAAA;AACrB,QAAA,MAAA,CAAO,OAAO,WAAW,CAAA;AAEzB,QAAA;AAAA;AAGJ,IAAA,IAAI,SAAa,IAAA,SAAA,CAAU,IAAK,CAAA,EAAA,MAAO,2CAAa,EAAI,CAAA,EAAA;AACtD,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,SAAA,CAAU,UAAU,IAAI,CAAA;AACxB,MAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA;AAC3B,GACF;AAEA,EAAM,MAAA,YAAA,GAAe,OAAO,KAAK,CAAA;AAEjC,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,YAAA,CAAa,OAAU,GAAA,IAAA;AAAA,GACzB;AAEA,EAAM,MAAA,WAAA,GAAc,CAAC,KAAsC,KAAA;AACzD,IAAA,IAAI,aAAa,OAAS,EAAA;AACxB,MAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AACvB,MAAA;AAAA;AAGF,IAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,IAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAGvB,IAAA,MAAM,WAAc,GAAA,WAAA,GAAc,gBAAiB,CAAA,WAAW,CAAI,GAAA,CAAA,CAAA;AAClE,IAAA,IAAI,SAAY,GAAA,KAAA,CAAA;AAGhB,IAAA,IAAI,cAAc,CAAG,EAAA;AACnB,MAAA;AAAA;AAIF,IAAI,IAAA,aAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,MAAY,SAAA,GAAA,kBAAA;AAAA,QACV,CAAC,MAAA,KAAW,MAAO,CAAA,KAAA,KAAU,cAAc,CAAC;AAAA,QAC5C,GAAI,EAAA;AAAA;AAIR,IAAA,IAAI,CAAC,SAAW,EAAA;AACd,MAAA,SAAA,GAAY,iBAAiB,CAAC,CAAA;AAAA;AAGhC,IAAA,SAAA,CAAU,uCAAW,IAAI,CAAA;AACzB,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAU,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,CAAA;AAAA,GACZ;AAEA,EAAM,MAAA,UAAA,GAAa,CAAC,KAAsC,KAAA;AACxD,IAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,IAAA,SAAA,CAAU,KAAS,CAAA,CAAA;AACnB,IAAS,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,KAAA,CAAA;AAAA,GACX;AAEA,EAAA,MAAM,sBAAsB,MAAM;AAChC,IAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,IAAA,SAAA,CAAU,KAAS,CAAA,CAAA;AAAA,GACrB;AAEA,EAAM,MAAA,SAAA,GAAY,UAAW,CAAA,OAAA,EAAS,GAAG,CAAA;AAEzC,EAAA,uBACG,GAAA,CAAA,kBAAA,CAAmB,QAAnB,EAAA,EAA4B,OAAO,WAClC,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA;AAAA,QACT,YAAa,EAAA;AAAA,QACb,EAAE,CAAC,YAAA,CAAa,UAAU,CAAC,GAAG,QAAS,EAAA;AAAA,QACvC;AAAA,OACF;AAAA,MACA,IAAK,EAAA,SAAA;AAAA,MACL,yBAAuB,WAAa,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAA,EAAA;AAAA,MACpC,iBAAe,QAAY,IAAA,KAAA,CAAA;AAAA,MAC3B,sBAAsB,EAAA,WAAA;AAAA,MACtB,QAAA,EAAU,WAAW,CAAK,CAAA,GAAA,CAAA;AAAA,MAC1B,SAAW,EAAA,aAAA;AAAA,MACX,MAAQ,EAAA,UAAA;AAAA,MACR,OAAS,EAAA,WAAA;AAAA,MACT,WAAa,EAAA,mBAAA;AAAA,MACb,WAAa,EAAA,eAAA;AAAA,MACb,GAAK,EAAA,SAAA;AAAA,MACJ,GAAG,IAAA;AAAA,MAEH;AAAA;AAAA,GAEL,EAAA,CAAA;AAEJ,CAAC;;;;"}
@@ -195,10 +195,11 @@ function useListControl(props) {
195
195
  };
196
196
  const listRef = useRef(null);
197
197
  const getOptionPageAbove = (start) => {
198
+ var _a;
198
199
  const list = listRef.current;
199
200
  let option = optionsRef.current.find((option2) => option2.data === start);
200
201
  if (!list || !option) {
201
- return null;
202
+ return void 0;
202
203
  }
203
204
  const containerRect = list.getBoundingClientRect();
204
205
  let optionRect = option.element.getBoundingClientRect();
@@ -207,9 +208,9 @@ function useListControl(props) {
207
208
  0,
208
209
  optionRect.y - listY + optionRect.height - containerRect.height
209
210
  );
210
- while (option && optionRect.y - listY > pageY) {
211
+ while (option && optionRect && optionRect.y - listY > pageY) {
211
212
  option = getOptionBefore(option.data);
212
- optionRect = option == null ? void 0 : option.element.getBoundingClientRect();
213
+ optionRect = (_a = option == null ? void 0 : option.element) == null ? void 0 : _a.getBoundingClientRect();
213
214
  }
214
215
  return option ?? getFirstOption();
215
216
  };
@@ -217,7 +218,7 @@ function useListControl(props) {
217
218
  const list = listRef.current;
218
219
  let option = optionsRef.current.find((option2) => option2.data === start);
219
220
  if (!list || !option) {
220
- return null;
221
+ return void 0;
221
222
  }
222
223
  const containerRect = list.getBoundingClientRect();
223
224
  let optionRect = option.element.getBoundingClientRect();
@@ -226,7 +227,7 @@ function useListControl(props) {
226
227
  list.scrollHeight,
227
228
  optionRect.y - listY - optionRect.height + containerRect.height
228
229
  );
229
- while (option && optionRect.y - listY < pageY) {
230
+ while (option && optionRect && optionRect.y - listY < pageY) {
230
231
  option = getOptionAfter(option.data);
231
232
  optionRect = option == null ? void 0 : option.element.getBoundingClientRect();
232
233
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ListControlState.js","sources":["../src/list-control/ListControlState.ts"],"sourcesContent":["import {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useControlled } from \"../utils\";\nimport type { OptionValue } from \"./ListControlContext\";\n\nexport type OpenChangeReason = \"input\" | \"manual\";\n\nexport type ListControlProps<Item> = {\n /**\n * If true, the control will be disabled.\n */\n disabled?: boolean;\n /**\n * If true, the control will be read-only.\n */\n readOnly?: boolean;\n /**\n * If true, the list will be open by default.\n */\n defaultOpen?: boolean;\n /**\n * If true, the list will be open. Useful for controlling the component.\n */\n open?: boolean;\n /**\n * Callback fired when the open state changes.\n */\n onOpenChange?: (newOpen: boolean, reason?: OpenChangeReason) => void;\n /**\n * The default selected options. If this is provided `defaultValue` should be provided as well.\n */\n defaultSelected?: Item[];\n /**\n * The selected options. The component will be controlled if this prop is provided.\n */\n selected?: Item[];\n /**\n * Callback fired when the selected options change.\n */\n onSelectionChange?: (event: SyntheticEvent, newSelected: Item[]) => void;\n /**\n * If true, multiple options can be selected.\n */\n multiselect?: boolean;\n /**\n * Callback used to convert an option's `value` to a string. This is needed when the value is different to the display value or the value is not a string.\n */\n valueToString?: (item: Item) => string;\n};\n\nfunction findElementPosition(\n elements: { element: HTMLElement }[],\n element: HTMLElement,\n) {\n if (elements.length === 0) {\n return [0, false] as const;\n }\n\n if (\n element.compareDocumentPosition(elements[elements.length - 1].element) &\n Node.DOCUMENT_POSITION_PRECEDING\n ) {\n return [-1, false] as const;\n }\n\n if (\n element.compareDocumentPosition(elements[0].element) &\n Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n return [0, false] as const;\n }\n\n let left = 0;\n let right = elements.length;\n let leftLast = 0;\n let rightLast = right;\n\n let exists = false;\n\n while (left < right) {\n const inPos = Math.floor((right + left) / 2);\n const compared = element.compareDocumentPosition(elements[inPos].element);\n if (compared & Node.DOCUMENT_POSITION_PRECEDING) {\n left = inPos;\n } else if (compared & Node.DOCUMENT_POSITION_FOLLOWING) {\n right = inPos;\n } else {\n right = inPos;\n left = inPos;\n exists = true;\n }\n // nothing has changed, must have found limits. insert between.\n if (leftLast === left && rightLast === right) {\n break;\n }\n leftLast = left;\n rightLast = right;\n }\n\n return [right, exists] as const;\n}\n\nexport function defaultValueToString<Item>(item: Item): string {\n return String(item);\n}\n\nexport function useListControl<Item>(props: ListControlProps<Item>) {\n const {\n open: openProp,\n defaultOpen,\n onOpenChange,\n multiselect,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n disabled,\n readOnly,\n valueToString = defaultValueToString,\n } = props;\n\n const [focusedState, setFocusedState] = useState(false);\n const [focusVisibleState, setFocusVisibleState] = useState(false);\n\n useEffect(() => {\n // remove focus when controlling disabled\n if (disabled && focusedState) {\n setFocusedState(false);\n setFocusVisibleState(false);\n }\n }, [disabled, focusedState]);\n\n const [activeState, setActiveState] = useState<OptionValue<Item> | undefined>(\n undefined,\n );\n\n const setActive = (option?: OptionValue<Item>) => {\n if (option) {\n setActiveState(option);\n } else {\n setActiveState(undefined);\n }\n };\n\n const [openState, setOpenState] = useControlled({\n controlled: openProp,\n default: Boolean(defaultOpen),\n name: \"ListControl\",\n state: \"open\",\n });\n\n const openKey = useRef<string | undefined>(undefined);\n\n const setOpen = (\n newOpen: boolean,\n reason?: OpenChangeReason,\n key?: string,\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n setOpenState(newOpen);\n openKey.current = key;\n\n if (newOpen !== openState) {\n onOpenChange?.(newOpen, reason);\n }\n };\n\n const [selectedState, setSelectedState] = useControlled({\n controlled: selectedProp,\n default: defaultSelected ?? [],\n name: \"ListControl\",\n state: \"selected\",\n });\n\n const select = (event: SyntheticEvent, option: OptionValue<Item>) => {\n if (option.disabled || readOnly || disabled) {\n return;\n }\n\n let newSelected = [option.value];\n\n if (multiselect) {\n if (selectedState.includes(option.value)) {\n newSelected = selectedState.filter((item) => item !== option.value);\n } else {\n newSelected = selectedState.concat([option.value]);\n }\n }\n\n setSelectedState(newSelected);\n onSelectionChange?.(event, newSelected);\n\n if (!multiselect) {\n setOpen(false);\n }\n };\n\n const clear = (event: SyntheticEvent) => {\n setSelectedState([]);\n if (selectedState.length !== 0) {\n onSelectionChange?.(event, []);\n }\n };\n\n const optionsRef = useRef<\n { data: OptionValue<Item>; element: HTMLElement }[]\n >([]);\n\n const register = useCallback(\n (optionValue: OptionValue<Item>, element: HTMLElement) => {\n const { id } = optionValue;\n const [index, exists] = findElementPosition(optionsRef.current, element);\n\n if (!exists) {\n if (index === -1) {\n optionsRef.current.push({ data: optionValue, element });\n } else {\n optionsRef.current.splice(index, 0, { data: optionValue, element });\n }\n }\n\n return () => {\n optionsRef.current = optionsRef.current.filter(\n (item) => item.data.id !== id,\n );\n };\n },\n [],\n );\n\n const getOptionAtIndex = (index: number) => {\n return optionsRef.current[index];\n };\n\n const getIndexOfOption = (option: OptionValue<Item>) => {\n return optionsRef.current.findIndex((item) => item.data.id === option.id);\n };\n\n const getOptionsMatching = (\n predicate: (option: OptionValue<Item>) => boolean,\n ) => {\n return optionsRef.current.filter((item) => predicate(item.data));\n };\n\n const getOptionFromSearch = (\n search: string,\n startFrom?: OptionValue<Item>,\n ) => {\n const collator = new Intl.Collator(\"en\", {\n usage: \"search\",\n sensitivity: \"base\",\n });\n\n const startIndex = startFrom ? getIndexOfOption(startFrom) + 1 : 0;\n const searchList = optionsRef.current.map((item) => item.data);\n\n let matches = searchList.filter(\n (option) =>\n collator.compare(\n valueToString(option.value).substring(0, search.length),\n search,\n ) === 0,\n );\n\n if (matches.length === 0) {\n const letters = search.split(\"\");\n const allSameLetter =\n letters.length > 0 &&\n letters.every((letter) => collator.compare(letter, letters[0]) === 0);\n if (allSameLetter) {\n matches = searchList.filter(\n (option) =>\n collator.compare(\n valueToString(option.value)[0].toLowerCase(),\n letters[0],\n ) === 0,\n );\n }\n }\n\n return matches.find((option) => getIndexOfOption(option) >= startIndex);\n };\n\n const getFirstOption = () => {\n return getOptionAtIndex(0);\n };\n\n const getLastOption = () => {\n return getOptionAtIndex(optionsRef.current.length - 1);\n };\n\n const getOptionBefore = (option: OptionValue<Item>) => {\n const index = getIndexOfOption(option);\n return getOptionAtIndex(index - 1);\n };\n\n const getOptionAfter = (option: OptionValue<Item>) => {\n const index = getIndexOfOption(option);\n return getOptionAtIndex(index + 1);\n };\n\n const listRef = useRef<HTMLDivElement>(null);\n\n const getOptionPageAbove = (start: OptionValue<Item>) => {\n const list = listRef.current;\n let option = optionsRef.current.find((option) => option.data === start);\n\n if (!list || !option) {\n return null;\n }\n\n const containerRect = list.getBoundingClientRect();\n let optionRect = option.element.getBoundingClientRect();\n\n const listY = containerRect.y - list.scrollTop;\n const pageY = Math.max(\n 0,\n optionRect.y - listY + optionRect.height - containerRect.height,\n );\n\n while (option && optionRect.y - listY > pageY) {\n option = getOptionBefore(option.data);\n optionRect = option?.element.getBoundingClientRect();\n }\n\n return option ?? getFirstOption();\n };\n\n const getOptionPageBelow = (start: OptionValue<Item>) => {\n const list = listRef.current;\n let option = optionsRef.current.find((option) => option.data === start);\n\n if (!list || !option) {\n return null;\n }\n\n const containerRect = list.getBoundingClientRect();\n let optionRect = option.element.getBoundingClientRect();\n\n const listY = containerRect.y - list.scrollTop;\n const pageY = Math.min(\n list.scrollHeight,\n optionRect.y - listY - optionRect.height + containerRect.height,\n );\n\n while (option && optionRect.y - listY < pageY) {\n option = getOptionAfter(option.data);\n optionRect = option?.element.getBoundingClientRect();\n }\n\n return option ?? getLastOption();\n };\n\n useEffect(() => {\n if (listRef.current) {\n const activeElement = optionsRef.current.find(\n (option) => option.data === activeState,\n )?.element;\n\n if (!activeElement) {\n return;\n }\n\n activeElement.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n }, [activeState]);\n\n return {\n multiselect: Boolean(multiselect),\n openState,\n setOpen,\n openKey,\n activeState,\n setActive,\n selectedState,\n setSelectedState,\n select,\n clear,\n focusVisibleState,\n setFocusVisibleState,\n focusedState,\n setFocusedState,\n listRef,\n options: optionsRef.current.map((option) => option.element),\n register,\n getOptionAtIndex,\n getIndexOfOption,\n getOptionsMatching,\n getOptionFromSearch,\n getOptionAfter,\n getOptionBefore,\n getOptionPageAbove,\n getOptionPageBelow,\n getFirstOption,\n getLastOption,\n valueToString,\n disabled,\n };\n}\n"],"names":["option"],"mappings":"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"}
1
+ {"version":3,"file":"ListControlState.js","sources":["../src/list-control/ListControlState.ts"],"sourcesContent":["import {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useControlled } from \"../utils\";\nimport type { OptionValue } from \"./ListControlContext\";\n\nexport type OpenChangeReason = \"input\" | \"manual\";\n\nexport type ListControlProps<Item> = {\n /**\n * If true, the control will be disabled.\n */\n disabled?: boolean;\n /**\n * If true, the control will be read-only.\n */\n readOnly?: boolean;\n /**\n * If true, the list will be open by default.\n */\n defaultOpen?: boolean;\n /**\n * If true, the list will be open. Useful for controlling the component.\n */\n open?: boolean;\n /**\n * Callback fired when the open state changes.\n */\n onOpenChange?: (newOpen: boolean, reason?: OpenChangeReason) => void;\n /**\n * The default selected options. If this is provided `defaultValue` should be provided as well.\n */\n defaultSelected?: Item[];\n /**\n * The selected options. The component will be controlled if this prop is provided.\n */\n selected?: Item[];\n /**\n * Callback fired when the selected options change.\n */\n onSelectionChange?: (event: SyntheticEvent, newSelected: Item[]) => void;\n /**\n * If true, multiple options can be selected.\n */\n multiselect?: boolean;\n /**\n * Callback used to convert an option's `value` to a string. This is needed when the value is different to the display value or the value is not a string.\n */\n valueToString?: (item: Item) => string;\n};\n\nfunction findElementPosition(\n elements: { element: HTMLElement }[],\n element: HTMLElement,\n) {\n if (elements.length === 0) {\n return [0, false] as const;\n }\n\n if (\n element.compareDocumentPosition(elements[elements.length - 1].element) &\n Node.DOCUMENT_POSITION_PRECEDING\n ) {\n return [-1, false] as const;\n }\n\n if (\n element.compareDocumentPosition(elements[0].element) &\n Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n return [0, false] as const;\n }\n\n let left = 0;\n let right = elements.length;\n let leftLast = 0;\n let rightLast = right;\n\n let exists = false;\n\n while (left < right) {\n const inPos = Math.floor((right + left) / 2);\n const compared = element.compareDocumentPosition(elements[inPos].element);\n if (compared & Node.DOCUMENT_POSITION_PRECEDING) {\n left = inPos;\n } else if (compared & Node.DOCUMENT_POSITION_FOLLOWING) {\n right = inPos;\n } else {\n right = inPos;\n left = inPos;\n exists = true;\n }\n // nothing has changed, must have found limits. insert between.\n if (leftLast === left && rightLast === right) {\n break;\n }\n leftLast = left;\n rightLast = right;\n }\n\n return [right, exists] as const;\n}\n\nexport function defaultValueToString<Item>(item: Item): string {\n return String(item);\n}\n\nexport function useListControl<Item>(props: ListControlProps<Item>) {\n const {\n open: openProp,\n defaultOpen,\n onOpenChange,\n multiselect,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n disabled,\n readOnly,\n valueToString = defaultValueToString,\n } = props;\n\n const [focusedState, setFocusedState] = useState(false);\n const [focusVisibleState, setFocusVisibleState] = useState(false);\n\n useEffect(() => {\n // remove focus when controlling disabled\n if (disabled && focusedState) {\n setFocusedState(false);\n setFocusVisibleState(false);\n }\n }, [disabled, focusedState]);\n\n const [activeState, setActiveState] = useState<OptionValue<Item> | undefined>(\n undefined,\n );\n\n const setActive = (option?: OptionValue<Item>) => {\n if (option) {\n setActiveState(option);\n } else {\n setActiveState(undefined);\n }\n };\n\n const [openState, setOpenState] = useControlled({\n controlled: openProp,\n default: Boolean(defaultOpen),\n name: \"ListControl\",\n state: \"open\",\n });\n\n const openKey = useRef<string | undefined>(undefined);\n\n const setOpen = (\n newOpen: boolean,\n reason?: OpenChangeReason,\n key?: string,\n ) => {\n if (disabled || readOnly) {\n return;\n }\n\n setOpenState(newOpen);\n openKey.current = key;\n\n if (newOpen !== openState) {\n onOpenChange?.(newOpen, reason);\n }\n };\n\n const [selectedState, setSelectedState] = useControlled({\n controlled: selectedProp,\n default: defaultSelected ?? [],\n name: \"ListControl\",\n state: \"selected\",\n });\n\n const select = (event: SyntheticEvent, option: OptionValue<Item>) => {\n if (option.disabled || readOnly || disabled) {\n return;\n }\n\n let newSelected = [option.value];\n\n if (multiselect) {\n if (selectedState.includes(option.value)) {\n newSelected = selectedState.filter((item) => item !== option.value);\n } else {\n newSelected = selectedState.concat([option.value]);\n }\n }\n\n setSelectedState(newSelected);\n onSelectionChange?.(event, newSelected);\n\n if (!multiselect) {\n setOpen(false);\n }\n };\n\n const clear = (event: SyntheticEvent) => {\n setSelectedState([]);\n if (selectedState.length !== 0) {\n onSelectionChange?.(event, []);\n }\n };\n\n const optionsRef = useRef<\n { data: OptionValue<Item>; element: HTMLElement }[]\n >([]);\n\n const register = useCallback(\n (optionValue: OptionValue<Item>, element: HTMLElement) => {\n const { id } = optionValue;\n const [index, exists] = findElementPosition(optionsRef.current, element);\n\n if (!exists) {\n if (index === -1) {\n optionsRef.current.push({ data: optionValue, element });\n } else {\n optionsRef.current.splice(index, 0, { data: optionValue, element });\n }\n }\n\n return () => {\n optionsRef.current = optionsRef.current.filter(\n (item) => item.data.id !== id,\n );\n };\n },\n [],\n );\n\n const getOptionAtIndex = (\n index: number,\n ): { data: OptionValue<Item>; element: HTMLElement } | undefined => {\n return optionsRef.current[index];\n };\n\n const getIndexOfOption = (option: OptionValue<Item>) => {\n return optionsRef.current.findIndex((item) => item.data.id === option.id);\n };\n\n const getOptionsMatching = (\n predicate: (option: OptionValue<Item>) => boolean,\n ) => {\n return optionsRef.current.filter((item) => predicate(item.data));\n };\n\n const getOptionFromSearch = (\n search: string,\n startFrom?: OptionValue<Item>,\n ) => {\n const collator = new Intl.Collator(\"en\", {\n usage: \"search\",\n sensitivity: \"base\",\n });\n\n const startIndex = startFrom ? getIndexOfOption(startFrom) + 1 : 0;\n const searchList = optionsRef.current.map((item) => item.data);\n\n let matches = searchList.filter(\n (option) =>\n collator.compare(\n valueToString(option.value).substring(0, search.length),\n search,\n ) === 0,\n );\n\n if (matches.length === 0) {\n const letters = search.split(\"\");\n const allSameLetter =\n letters.length > 0 &&\n letters.every((letter) => collator.compare(letter, letters[0]) === 0);\n if (allSameLetter) {\n matches = searchList.filter(\n (option) =>\n collator.compare(\n valueToString(option.value)[0].toLowerCase(),\n letters[0],\n ) === 0,\n );\n }\n }\n\n return matches.find((option) => getIndexOfOption(option) >= startIndex);\n };\n\n const getFirstOption = () => {\n return getOptionAtIndex(0);\n };\n\n const getLastOption = () => {\n return getOptionAtIndex(optionsRef.current.length - 1);\n };\n\n const getOptionBefore = (option: OptionValue<Item>) => {\n const index = getIndexOfOption(option);\n return getOptionAtIndex(index - 1);\n };\n\n const getOptionAfter = (option: OptionValue<Item>) => {\n const index = getIndexOfOption(option);\n return getOptionAtIndex(index + 1);\n };\n\n const listRef = useRef<HTMLDivElement>(null);\n\n const getOptionPageAbove = (start: OptionValue<Item>) => {\n const list = listRef.current;\n let option = optionsRef.current.find((option) => option.data === start);\n\n if (!list || !option) {\n return undefined;\n }\n\n const containerRect = list.getBoundingClientRect();\n let optionRect: DOMRect | undefined =\n option.element.getBoundingClientRect();\n\n const listY = containerRect.y - list.scrollTop;\n const pageY = Math.max(\n 0,\n optionRect.y - listY + optionRect.height - containerRect.height,\n );\n\n while (option && optionRect && optionRect.y - listY > pageY) {\n option = getOptionBefore(option.data);\n optionRect = option?.element?.getBoundingClientRect();\n }\n\n return option ?? getFirstOption();\n };\n\n const getOptionPageBelow = (start: OptionValue<Item>) => {\n const list = listRef.current;\n let option = optionsRef.current.find((option) => option.data === start);\n\n if (!list || !option) {\n return undefined;\n }\n\n const containerRect = list.getBoundingClientRect();\n let optionRect: DOMRect | undefined =\n option.element.getBoundingClientRect();\n\n const listY = containerRect.y - list.scrollTop;\n const pageY = Math.min(\n list.scrollHeight,\n optionRect.y - listY - optionRect.height + containerRect.height,\n );\n\n while (option && optionRect && optionRect.y - listY < pageY) {\n option = getOptionAfter(option.data);\n optionRect = option?.element.getBoundingClientRect();\n }\n\n return option ?? getLastOption();\n };\n\n useEffect(() => {\n if (listRef.current) {\n const activeElement = optionsRef.current.find(\n (option) => option.data === activeState,\n )?.element;\n\n if (!activeElement) {\n return;\n }\n\n activeElement.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n }, [activeState]);\n\n return {\n multiselect: Boolean(multiselect),\n openState,\n setOpen,\n openKey,\n activeState,\n setActive,\n selectedState,\n setSelectedState,\n select,\n clear,\n focusVisibleState,\n setFocusVisibleState,\n focusedState,\n setFocusedState,\n listRef,\n options: optionsRef.current.map((option) => option.element),\n register,\n getOptionAtIndex,\n getIndexOfOption,\n getOptionsMatching,\n getOptionFromSearch,\n getOptionAfter,\n getOptionBefore,\n getOptionPageAbove,\n getOptionPageBelow,\n getFirstOption,\n getLastOption,\n valueToString,\n disabled,\n };\n}\n"],"names":["option"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltStep {\n /* Copy of size calculations of <Icon /> */\n --step-icon-base-size: var(--salt-size-icon, 12px);\n --step-icon-size-multiplier: var(--saltIcon-size-multiplier, 1.5);\n --step-icon-size: calc(var(--step-icon-base-size) * var(--step-icon-size-multiplier));\n --step-depth: var(--saltStep-depth, 0);\n}\n\n.saltStepper-horizontal .saltStep {\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: repeat(3, min-content);\n grid-template-areas:\n \"icon\"\n \"label\"\n \"description\";\n justify-items: center;\n align-items: center;\n text-align: center;\n flex: 1;\n padding: 0 var(--salt-spacing-25);\n}\n\n.saltStepper-vertical .saltStep {\n display: grid;\n grid-template-columns: var(--step-icon-size) 1fr min-content;\n grid-template-areas:\n \"icon label expand\"\n \"connector description .\"\n \"stepper stepper stepper\";\n justify-items: start;\n align-items: start;\n gap: 0 var(--salt-spacing-100);\n width: 100%;\n transition-duration: inherit;\n transition-timing-function: inherit;\n transition-property: grid-template-rows;\n}\n\n.saltStepper-vertical .saltStep-terminal {\n grid-template-areas:\n \"icon label label\"\n \"connector description description\"\n \"stepper stepper stepper\";\n}\n\n.saltStepper-vertical > .saltStep.saltStep-expanded {\n grid-template-rows:\n var(--salt-size-base)\n min-content\n 1fr;\n}\n\n.saltStepper-vertical > .saltStep.saltStep-collapsed {\n grid-template-rows:\n var(--salt-size-base)\n min-content\n 0fr;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=Step.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,164 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import clsx from 'clsx';
5
+ import { useContext, useEffect } from 'react';
6
+ import { makePrefixer } from '../utils/makePrefixer.js';
7
+ import { useControlled } from '../utils/useControlled.js';
8
+ import '../utils/useFloatingUI/useFloatingUI.js';
9
+ import { useId } from '../utils/useId.js';
10
+ import '../salt-provider/SaltProvider.js';
11
+ import '../viewport/ViewportProvider.js';
12
+ import css_248z from './Step.css.js';
13
+ import { Stepper } from './Stepper.js';
14
+ import { StepConnector } from './internal/StepConnector.js';
15
+ import { StepExpandTrigger } from './internal/StepExpandTrigger.js';
16
+ import { StepIcon } from './internal/StepIcon.js';
17
+ import { StepScreenReaderOnly } from './internal/StepScreenReaderOnly.js';
18
+ import { StepText } from './internal/StepText.js';
19
+ import { StepDepthContext, StepperOrientationContext } from './internal/StepperProvider.js';
20
+
21
+ const withBaseName = makePrefixer("saltStep");
22
+ function Step({
23
+ id: idProp,
24
+ label,
25
+ description,
26
+ status,
27
+ stage = "pending",
28
+ expanded: expandedProp,
29
+ defaultExpanded,
30
+ onToggle,
31
+ className,
32
+ style,
33
+ children,
34
+ ...rest
35
+ }) {
36
+ const id = useId(idProp);
37
+ const targetWindow = useWindow();
38
+ const depth = useContext(StepDepthContext);
39
+ const orientation = useContext(StepperOrientationContext);
40
+ const hasNestedSteps = !!children;
41
+ const [expanded, setExpanded] = useControlled({
42
+ name: "Step",
43
+ state: "expanded",
44
+ controlled: expandedProp,
45
+ default: Boolean(defaultExpanded)
46
+ });
47
+ useComponentCssInjection({
48
+ testId: "salt-step",
49
+ css: css_248z,
50
+ window: targetWindow
51
+ });
52
+ useEffect(() => {
53
+ if (process.env.NODE_ENV !== "production") {
54
+ if (depth === -1) {
55
+ console.warn("<Step /> should be used within a <Stepper /> component!");
56
+ }
57
+ if (depth > 2) {
58
+ console.warn("<Step /> should not be nested more than 2 levels deep!");
59
+ }
60
+ if (orientation === "horizontal" && hasNestedSteps) {
61
+ console.warn(
62
+ "<Stepper /> does not support nested steps in horizontal orientation!"
63
+ );
64
+ }
65
+ }
66
+ }, [depth, orientation]);
67
+ const ariaCurrent = stage === "active" ? "step" : void 0;
68
+ const iconSizeMultiplier = depth === 0 ? 1.5 : 1;
69
+ const stageText = stage === "inprogress" ? "in progress" : stage;
70
+ const state = status || stageText;
71
+ const labelId = `${id}-label`;
72
+ const descriptionId = `${id}-description`;
73
+ const expandTriggerId = `${id}-expand-trigger`;
74
+ const nestedStepperId = `${id}-nested-stepper`;
75
+ const screenReaderOnly = {
76
+ stateId: `${id}-sr-only-state`,
77
+ stateText: state !== "active" ? state : "",
78
+ substepsId: `${id}-sr-only-substeps`,
79
+ substepsText: "substeps",
80
+ toggleSubstepsId: `${id}-sr-only-toggle-substeps`,
81
+ toggleSubstepsText: "toggle substeps"
82
+ };
83
+ return /* @__PURE__ */ jsxs(
84
+ "li",
85
+ {
86
+ id,
87
+ "aria-current": ariaCurrent,
88
+ className: clsx(
89
+ withBaseName(),
90
+ withBaseName(`stage-${stage}`),
91
+ withBaseName(`depth-${depth}`),
92
+ status && withBaseName(`status-${status}`),
93
+ !hasNestedSteps && withBaseName("terminal"),
94
+ hasNestedSteps && expanded && withBaseName("expanded"),
95
+ hasNestedSteps && !expanded && withBaseName("collapsed"),
96
+ className
97
+ ),
98
+ style: {
99
+ "--saltStep-depth": depth,
100
+ ...style
101
+ },
102
+ ...rest,
103
+ children: [
104
+ /* @__PURE__ */ jsx(StepScreenReaderOnly, { children: `${label} ${description !== void 0 ? description : ""} ${screenReaderOnly.stateText}` }),
105
+ hasNestedSteps && /* @__PURE__ */ jsxs(Fragment, { children: [
106
+ /* @__PURE__ */ jsx(
107
+ StepScreenReaderOnly,
108
+ {
109
+ id: screenReaderOnly.toggleSubstepsId,
110
+ "aria-hidden": true,
111
+ children: screenReaderOnly.toggleSubstepsText
112
+ }
113
+ ),
114
+ /* @__PURE__ */ jsx(StepScreenReaderOnly, { id: screenReaderOnly.substepsId, "aria-hidden": true, children: screenReaderOnly.substepsText }),
115
+ /* @__PURE__ */ jsx(StepScreenReaderOnly, { id: screenReaderOnly.stateId, "aria-hidden": true, children: screenReaderOnly.stateText })
116
+ ] }),
117
+ /* @__PURE__ */ jsx(StepConnector, {}),
118
+ /* @__PURE__ */ jsx(
119
+ StepIcon,
120
+ {
121
+ stage,
122
+ status,
123
+ sizeMultiplier: iconSizeMultiplier,
124
+ "aria-hidden": true
125
+ }
126
+ ),
127
+ label && /* @__PURE__ */ jsx(StepText, { id: labelId, purpose: "label", "aria-hidden": true, children: label }),
128
+ description && /* @__PURE__ */ jsx(StepText, { id: descriptionId, purpose: "description", "aria-hidden": true, children: description }),
129
+ hasNestedSteps && orientation === "vertical" && /* @__PURE__ */ jsx(
130
+ StepExpandTrigger,
131
+ {
132
+ id: expandTriggerId,
133
+ "aria-expanded": expanded,
134
+ "aria-controls": nestedStepperId,
135
+ "aria-labelledby": [
136
+ labelId,
137
+ descriptionId,
138
+ screenReaderOnly.stateId,
139
+ screenReaderOnly.toggleSubstepsId
140
+ ].join(" "),
141
+ expanded,
142
+ onClick: (event) => {
143
+ onToggle == null ? void 0 : onToggle(event);
144
+ setExpanded(!expanded);
145
+ }
146
+ }
147
+ ),
148
+ hasNestedSteps && orientation === "vertical" && /* @__PURE__ */ jsx(
149
+ Stepper,
150
+ {
151
+ id: nestedStepperId,
152
+ "aria-labelledby": [labelId, screenReaderOnly.substepsId].join(" "),
153
+ "aria-hidden": !expanded,
154
+ hidden: !expanded,
155
+ children
156
+ }
157
+ )
158
+ ]
159
+ }
160
+ );
161
+ }
162
+
163
+ export { Step };
164
+ //# sourceMappingURL=Step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.js","sources":["../src/stepper/Step.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport clsx from \"clsx\";\nimport {\n type CSSProperties,\n type ComponentPropsWithoutRef,\n type ReactNode,\n useContext,\n useEffect,\n} from \"react\";\nimport { makePrefixer, useControlled, useId } from \"../utils\";\n\nimport type { ButtonProps } from \"../button\";\nimport stepCSS from \"./Step.css\";\nimport { Stepper } from \"./Stepper\";\nimport { StepConnector } from \"./internal/StepConnector\";\nimport { StepExpandTrigger } from \"./internal/StepExpandTrigger\";\nimport { StepIcon } from \"./internal/StepIcon\";\nimport { StepScreenReaderOnly } from \"./internal/StepScreenReaderOnly\";\nimport { StepText } from \"./internal/StepText\";\nimport {\n StepDepthContext,\n StepperOrientationContext,\n} from \"./internal/StepperProvider\";\n\nexport interface StepProps\n extends Omit<ComponentPropsWithoutRef<\"li\">, \"onToggle\"> {\n /**\n * The label of the step\n */\n label?: ReactNode;\n /**\n * Description text is displayed just below the label\n **/\n description?: ReactNode;\n /**\n * Optional string to determine the status of the step.\n */\n status?: StepStatus;\n /**\n * The stage of the step\n */\n stage?: StepStage;\n /**\n * Whether the step item is expanded.\n */\n expanded?: boolean;\n /**\n * Initial expanded state of the step.\n */\n defaultExpanded?: boolean;\n /**\n * Callback fired when the step is toggled.\n */\n onToggle?: ButtonProps[\"onClick\"];\n}\n\nexport type StepId = string;\n\nexport type StepStatus = \"warning\" | \"error\";\n\nexport type StepStage =\n | \"pending\"\n | \"locked\"\n | \"completed\"\n | \"inprogress\"\n | \"active\";\n\nexport type StepDepth = number;\n\nexport interface StepProps\n extends Omit<ComponentPropsWithoutRef<\"li\">, \"onToggle\"> {\n label?: ReactNode;\n description?: ReactNode;\n status?: StepStatus;\n stage?: StepStage;\n expanded?: boolean;\n defaultExpanded?: boolean;\n onToggle?: ButtonProps[\"onClick\"];\n}\n\nconst withBaseName = makePrefixer(\"saltStep\");\n\nexport function Step({\n id: idProp,\n label,\n description,\n status,\n stage = \"pending\",\n expanded: expandedProp,\n defaultExpanded,\n onToggle,\n className,\n style,\n children,\n ...rest\n}: StepProps) {\n const id = useId(idProp);\n const targetWindow = useWindow();\n const depth = useContext(StepDepthContext);\n const orientation = useContext(StepperOrientationContext);\n\n const hasNestedSteps = !!children;\n\n const [expanded, setExpanded] = useControlled({\n name: \"Step\",\n state: \"expanded\",\n controlled: expandedProp,\n default: Boolean(defaultExpanded),\n });\n\n useComponentCssInjection({\n testId: \"salt-step\",\n css: stepCSS,\n window: targetWindow,\n });\n\n useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (depth === -1) {\n console.warn(\"<Step /> should be used within a <Stepper /> component!\");\n }\n if (depth > 2) {\n console.warn(\"<Step /> should not be nested more than 2 levels deep!\");\n }\n if (orientation === \"horizontal\" && hasNestedSteps) {\n console.warn(\n \"<Stepper /> does not support nested steps in horizontal orientation!\",\n );\n }\n }\n }, [depth, orientation]);\n\n const ariaCurrent = stage === \"active\" ? \"step\" : undefined;\n const iconSizeMultiplier = depth === 0 ? 1.5 : 1;\n const stageText = stage === \"inprogress\" ? \"in progress\" : stage;\n const state = status || stageText;\n\n const labelId = `${id}-label`;\n const descriptionId = `${id}-description`;\n const expandTriggerId = `${id}-expand-trigger`;\n const nestedStepperId = `${id}-nested-stepper`;\n\n const screenReaderOnly = {\n stateId: `${id}-sr-only-state`,\n stateText: state !== \"active\" ? state : \"\",\n substepsId: `${id}-sr-only-substeps`,\n substepsText: \"substeps\",\n toggleSubstepsId: `${id}-sr-only-toggle-substeps`,\n toggleSubstepsText: \"toggle substeps\",\n };\n\n return (\n <li\n id={id}\n aria-current={ariaCurrent}\n className={clsx(\n withBaseName(),\n withBaseName(`stage-${stage}`),\n withBaseName(`depth-${depth}`),\n status && withBaseName(`status-${status}`),\n !hasNestedSteps && withBaseName(\"terminal\"),\n hasNestedSteps && expanded && withBaseName(\"expanded\"),\n hasNestedSteps && !expanded && withBaseName(\"collapsed\"),\n className,\n )}\n style={\n {\n \"--saltStep-depth\": depth,\n ...style,\n } as CSSProperties\n }\n {...rest}\n >\n <StepScreenReaderOnly>\n {`${label} ${description !== undefined ? description : \"\"} ${screenReaderOnly.stateText}`}\n </StepScreenReaderOnly>\n {hasNestedSteps && (\n <>\n <StepScreenReaderOnly\n id={screenReaderOnly.toggleSubstepsId}\n aria-hidden\n >\n {screenReaderOnly.toggleSubstepsText}\n </StepScreenReaderOnly>\n <StepScreenReaderOnly id={screenReaderOnly.substepsId} aria-hidden>\n {screenReaderOnly.substepsText}\n </StepScreenReaderOnly>\n <StepScreenReaderOnly id={screenReaderOnly.stateId} aria-hidden>\n {screenReaderOnly.stateText}\n </StepScreenReaderOnly>\n </>\n )}\n <StepConnector />\n <StepIcon\n stage={stage}\n status={status}\n sizeMultiplier={iconSizeMultiplier}\n aria-hidden\n />\n {label && (\n <StepText id={labelId} purpose=\"label\" aria-hidden>\n {label}\n </StepText>\n )}\n {description && (\n <StepText id={descriptionId} purpose=\"description\" aria-hidden>\n {description}\n </StepText>\n )}\n {hasNestedSteps && orientation === \"vertical\" && (\n <StepExpandTrigger\n id={expandTriggerId}\n aria-expanded={expanded}\n aria-controls={nestedStepperId}\n aria-labelledby={[\n labelId,\n descriptionId,\n screenReaderOnly.stateId,\n screenReaderOnly.toggleSubstepsId,\n ].join(\" \")}\n expanded={expanded}\n onClick={(event) => {\n onToggle?.(event);\n setExpanded(!expanded);\n }}\n />\n )}\n {hasNestedSteps && orientation === \"vertical\" && (\n <Stepper\n id={nestedStepperId}\n aria-labelledby={[labelId, screenReaderOnly.substepsId].join(\" \")}\n aria-hidden={!expanded}\n hidden={!expanded}\n >\n {children}\n </Stepper>\n )}\n </li>\n );\n}\n"],"names":["stepCSS"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltStepper {\n grid-area: stepper;\n width: 100%;\n height: 100%;\n\n margin: 0;\n padding: 0;\n list-style-type: none;\n transition-duration: var(--salt-duration-perceptible);\n transition-timing-function: ease-in-out;\n transition-property: opacity, visibility;\n}\n\n@media (prefers-reduced-motion) {\n .saltStepper {\n transition-duration: var(--salt-duration-instant);\n }\n}\n\n.saltStepper-horizontal {\n display: flex;\n flex-direction: row;\n}\n\n.saltStepper-vertical {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.saltStepper-vertical > .saltStep.saltStep-expanded > .saltStepper {\n opacity: 1;\n visibility: visible;\n}\n\n.saltStepper-vertical > .saltStep.saltStep-collapsed > .saltStepper {\n opacity: 0;\n visibility: hidden;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=Stepper.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,38 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import { clsx } from 'clsx';
5
+ import { forwardRef, useContext } from 'react';
6
+ import { makePrefixer } from '../utils/makePrefixer.js';
7
+ import '../utils/useFloatingUI/useFloatingUI.js';
8
+ import '../utils/useId.js';
9
+ import '../salt-provider/SaltProvider.js';
10
+ import '../viewport/ViewportProvider.js';
11
+ import css_248z from './Stepper.css.js';
12
+ import { StepperOrientationContext, StepperProvider } from './internal/StepperProvider.js';
13
+
14
+ const withBaseName = makePrefixer("saltStepper");
15
+ const Stepper = forwardRef(
16
+ function Stepper2({ orientation: orientationProp, children, className, ...props }, ref) {
17
+ const targetWindow = useWindow();
18
+ const orientationContext = useContext(StepperOrientationContext);
19
+ const orientation = orientationProp || orientationContext;
20
+ useComponentCssInjection({
21
+ testId: "salt-Stepper",
22
+ css: css_248z,
23
+ window: targetWindow
24
+ });
25
+ return /* @__PURE__ */ jsx(StepperProvider, { orientation, children: /* @__PURE__ */ jsx(
26
+ "ol",
27
+ {
28
+ className: clsx(withBaseName(), withBaseName(orientation), className),
29
+ ref,
30
+ ...props,
31
+ children
32
+ }
33
+ ) });
34
+ }
35
+ );
36
+
37
+ export { Stepper };
38
+ //# sourceMappingURL=Stepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.js","sources":["../src/stepper/Stepper.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport { type ComponentPropsWithoutRef, forwardRef, useContext } from \"react\";\nimport { makePrefixer } from \"../utils\";\nimport StepperCSS from \"./Stepper.css\";\nimport {\n StepperOrientationContext,\n StepperProvider,\n} from \"./internal/StepperProvider\";\n\nconst withBaseName = makePrefixer(\"saltStepper\");\n\nexport type StepperOrientation = \"horizontal\" | \"vertical\";\n\nexport interface StepperProps extends ComponentPropsWithoutRef<\"ol\"> {\n /**\n * The orientation of the stepper: defaults to horizontal.\n */\n orientation?: StepperOrientation;\n}\n\nexport const Stepper = forwardRef<HTMLOListElement, StepperProps>(\n function Stepper(\n { orientation: orientationProp, children, className, ...props },\n ref,\n ) {\n const targetWindow = useWindow();\n const orientationContext = useContext(StepperOrientationContext);\n const orientation = orientationProp || orientationContext;\n\n useComponentCssInjection({\n testId: \"salt-Stepper\",\n css: StepperCSS,\n window: targetWindow,\n });\n\n return (\n <StepperProvider orientation={orientation}>\n <ol\n className={clsx(withBaseName(), withBaseName(orientation), className)}\n ref={ref}\n {...props}\n >\n {children}\n </ol>\n </StepperProvider>\n );\n },\n);\n"],"names":["Stepper","StepperCSS"],"mappings":";;;;;;;;;;;;;AAWA,MAAM,YAAA,GAAe,aAAa,aAAa,CAAA;AAWxC,MAAM,OAAU,GAAA,UAAA;AAAA,EACrB,SAASA,QACP,CAAA,EAAE,WAAa,EAAA,eAAA,EAAiB,UAAU,SAAW,EAAA,GAAG,KAAM,EAAA,EAC9D,GACA,EAAA;AACA,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAM,MAAA,kBAAA,GAAqB,WAAW,yBAAyB,CAAA;AAC/D,IAAA,MAAM,cAAc,eAAmB,IAAA,kBAAA;AAEvC,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,cAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IACE,uBAAA,GAAA,CAAC,mBAAgB,WACf,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,WAAW,IAAK,CAAA,YAAA,IAAgB,YAAa,CAAA,WAAW,GAAG,SAAS,CAAA;AAAA,QACpE,GAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEH;AAAA;AAAA,KAEL,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltStepConnector {\n grid-area: connector;\n\n transition-duration: inherit;\n transition-timing-function: inherit;\n transition-property: opacity, min-height;\n}\n\n.saltStepper-horizontal .saltStepConnector {\n position: absolute;\n transform: translateY(-100%);\n top: calc(var(--step-icon-size) / 2);\n left: calc(50% + calc(var(--step-icon-size) / 2 + var(--salt-spacing-100)));\n right: calc(-50% + calc(var(--step-icon-size) / 2 + var(--salt-spacing-100)));\n\n border-top-width: var(--salt-size-border-strong);\n border-top-style: var(--salt-track-borderStyle-incomplete);\n border-top-color: var(--salt-track-borderColor);\n}\n\n.saltStepper-horizontal .saltStep-stage-completed > .saltStepConnector,\n.saltStepper-horizontal .saltStep-stage-inprogress > .saltStepConnector {\n border-top-style: var(--salt-track-borderStyle-complete);\n}\n\n.saltStepper-vertical .saltStepConnector {\n min-height: var(--salt-size-base);\n align-self: stretch;\n justify-self: center;\n\n border-left-width: var(--salt-size-border-strong);\n border-left-style: var(--salt-track-borderStyle-incomplete);\n border-left-color: var(--salt-track-borderColor);\n}\n\n.saltStepper-vertical .saltStep-stage-completed > .saltStepConnector,\n.saltStepper-vertical .saltStep-stage-inprogress > .saltStepConnector {\n border-left-style: var(--salt-track-borderStyle-complete);\n}\n\n.saltStep-depth-0.saltStep:not(.saltStep-expanded):last-child > .saltStepConnector {\n opacity: 0;\n min-height: 0;\n}\n\n.saltStep-depth-0.saltStep-expanded:last-child .saltStep:not(.saltStep-expanded):last-child .saltStepConnector {\n opacity: 0;\n min-height: 0;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=StepConnector.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepConnector.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,25 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import 'react';
5
+ import { makePrefixer } from '../../utils/makePrefixer.js';
6
+ import 'clsx';
7
+ import '../../utils/useFloatingUI/useFloatingUI.js';
8
+ import '../../utils/useId.js';
9
+ import '../../salt-provider/SaltProvider.js';
10
+ import '../../viewport/ViewportProvider.js';
11
+ import css_248z from './StepConnector.css.js';
12
+
13
+ const withBaseName = makePrefixer("saltStepConnector");
14
+ function StepConnector() {
15
+ const targetWindow = useWindow();
16
+ useComponentCssInjection({
17
+ testId: "salt-step-connector",
18
+ css: css_248z,
19
+ window: targetWindow
20
+ });
21
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: withBaseName() });
22
+ }
23
+
24
+ export { StepConnector };
25
+ //# sourceMappingURL=StepConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepConnector.js","sources":["../src/stepper/internal/StepConnector.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { makePrefixer } from \"../../utils\";\n\nimport stepConnectorCSS from \"./StepConnector.css\";\n\nconst withBaseName = makePrefixer(\"saltStepConnector\");\n\nexport function StepConnector() {\n const targetWindow = useWindow();\n\n useComponentCssInjection({\n testId: \"salt-step-connector\",\n css: stepConnectorCSS,\n window: targetWindow,\n });\n\n return <div aria-hidden className={withBaseName()} />;\n}\n"],"names":["stepConnectorCSS"],"mappings":";;;;;;;;;;;;AAMA,MAAM,YAAA,GAAe,aAAa,mBAAmB,CAAA;AAE9C,SAAS,aAAgB,GAAA;AAC9B,EAAA,MAAM,eAAe,SAAU,EAAA;AAE/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,qBAAA;AAAA,IACR,GAAK,EAAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,2BAAQ,KAAI,EAAA,EAAA,aAAA,EAAW,IAAC,EAAA,SAAA,EAAW,cAAgB,EAAA,CAAA;AACrD;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltStepExpandTrigger {\n grid-area: expand;\n}\n\n.saltButton.saltStepExpandTrigger:focus-visible {\n outline-offset: calc(-1 * var(--salt-focused-outlineWidth));\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=StepExpandTrigger.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepExpandTrigger.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,43 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import clsx from 'clsx';
5
+ import { Button } from '../../button/Button.js';
6
+ import 'react';
7
+ import { useIcon } from '../../semantic-icon-provider/SemanticIconProvider.js';
8
+ import { makePrefixer } from '../../utils/makePrefixer.js';
9
+ import '../../utils/useFloatingUI/useFloatingUI.js';
10
+ import '../../utils/useId.js';
11
+ import '../../salt-provider/SaltProvider.js';
12
+ import '../../viewport/ViewportProvider.js';
13
+ import css_248z from './StepExpandTrigger.css.js';
14
+
15
+ const withBaseName = makePrefixer("saltStepExpandTrigger");
16
+ function StepExpandTrigger({
17
+ id,
18
+ expanded,
19
+ className,
20
+ ...props
21
+ }) {
22
+ const { CollapseIcon, ExpandIcon } = useIcon();
23
+ const targetWindow = useWindow();
24
+ useComponentCssInjection({
25
+ testId: "salt-step-expand-trigger",
26
+ css: css_248z,
27
+ window: targetWindow
28
+ });
29
+ return /* @__PURE__ */ jsx(
30
+ Button,
31
+ {
32
+ id,
33
+ sentiment: "neutral",
34
+ appearance: "transparent",
35
+ className: clsx(withBaseName(), className),
36
+ ...props,
37
+ children: expanded ? /* @__PURE__ */ jsx(CollapseIcon, { "aria-hidden": true }) : /* @__PURE__ */ jsx(ExpandIcon, { "aria-hidden": true })
38
+ }
39
+ );
40
+ }
41
+
42
+ export { StepExpandTrigger };
43
+ //# sourceMappingURL=StepExpandTrigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepExpandTrigger.js","sources":["../src/stepper/internal/StepExpandTrigger.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport clsx from \"clsx\";\nimport { Button, type ButtonProps } from \"../../button\";\nimport { useIcon } from \"../../semantic-icon-provider\";\nimport { makePrefixer } from \"../../utils\";\n\nimport stepExpandTriggerCSS from \"./StepExpandTrigger.css\";\n\nexport interface StepExpandTriggerProps extends ButtonProps {\n expanded: boolean;\n}\n\nconst withBaseName = makePrefixer(\"saltStepExpandTrigger\");\n\nexport function StepExpandTrigger({\n id,\n expanded,\n className,\n ...props\n}: StepExpandTriggerProps) {\n const { CollapseIcon, ExpandIcon } = useIcon();\n const targetWindow = useWindow();\n\n useComponentCssInjection({\n testId: \"salt-step-expand-trigger\",\n css: stepExpandTriggerCSS,\n window: targetWindow,\n });\n\n return (\n <Button\n id={id}\n sentiment=\"neutral\"\n appearance=\"transparent\"\n className={clsx(withBaseName(), className)}\n {...props}\n >\n {expanded ? <CollapseIcon aria-hidden /> : <ExpandIcon aria-hidden />}\n </Button>\n );\n}\n"],"names":["stepExpandTriggerCSS"],"mappings":";;;;;;;;;;;;;;AAaA,MAAM,YAAA,GAAe,aAAa,uBAAuB,CAAA;AAElD,SAAS,iBAAkB,CAAA;AAAA,EAChC,EAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAA2B,EAAA;AACzB,EAAA,MAAM,EAAE,YAAA,EAAc,UAAW,EAAA,GAAI,OAAQ,EAAA;AAC7C,EAAA,MAAM,eAAe,SAAU,EAAA;AAE/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,0BAAA;AAAA,IACR,GAAK,EAAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,SAAU,EAAA,SAAA;AAAA,MACV,UAAW,EAAA,aAAA;AAAA,MACX,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,MACxC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA,QAAA,uBAAY,YAAa,EAAA,EAAA,aAAA,EAAW,MAAC,CAAK,mBAAA,GAAA,CAAC,UAAW,EAAA,EAAA,aAAA,EAAW,IAAC,EAAA;AAAA;AAAA,GACrE;AAEJ;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltStepIcon {\n grid-area: icon;\n\n display: flex;\n justify-content: center;\n align-items: center;\n justify-self: center;\n}\n\n.saltStepper-vertical .saltStepIcon {\n height: var(--salt-size-base);\n}\n\n.saltStep-stage-pending > .saltStepIcon {\n --saltIcon-color: var(--salt-status-static-foreground);\n}\n\n.saltStep-stage-locked > .saltStepIcon {\n --saltIcon-color: var(--salt-status-static-foreground);\n}\n\n.saltStep-stage-inprogress > .saltStepIcon {\n --saltIcon-color: var(--salt-status-info-foreground-decorative);\n}\n\n.saltStep-stage-active > .saltStepIcon {\n --saltIcon-color: var(--salt-status-info-foreground-decorative);\n}\n\n.saltStep-stage-completed > .saltStepIcon {\n --saltIcon-color: var(--salt-status-success-foreground-decorative);\n}\n\n.saltStep-status-warning > .saltStepIcon {\n --saltIcon-color: var(--salt-status-warning-foreground-decorative);\n}\n\n.saltStep-status-error > .saltStepIcon {\n --saltIcon-color: var(--salt-status-error-foreground-decorative);\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=StepIcon.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepIcon.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}