@mantine/core 9.4.3-alpha.0 → 9.5.1-alpha.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 (185) hide show
  1. package/cjs/components/Accordion/Accordion.cjs +5 -2
  2. package/cjs/components/Accordion/Accordion.cjs.map +1 -1
  3. package/cjs/components/AngleSlider/AngleSlider.cjs +4 -1
  4. package/cjs/components/AngleSlider/AngleSlider.cjs.map +1 -1
  5. package/cjs/components/Avatar/AvatarGroup/AvatarGroup.cjs +15 -14
  6. package/cjs/components/Avatar/AvatarGroup/AvatarGroup.cjs.map +1 -1
  7. package/cjs/components/Cascader/Cascader.cjs +371 -0
  8. package/cjs/components/Cascader/Cascader.cjs.map +1 -0
  9. package/cjs/components/Cascader/Cascader.module.cjs +18 -0
  10. package/cjs/components/Cascader/Cascader.module.cjs.map +1 -0
  11. package/cjs/components/Cascader/CascaderColumns.cjs +136 -0
  12. package/cjs/components/Cascader/CascaderColumns.cjs.map +1 -0
  13. package/cjs/components/Cascader/flatten-cascader-paths.cjs +26 -0
  14. package/cjs/components/Cascader/flatten-cascader-paths.cjs.map +1 -0
  15. package/cjs/components/Cascader/get-cascader-columns.cjs +30 -0
  16. package/cjs/components/Cascader/get-cascader-columns.cjs.map +1 -0
  17. package/cjs/components/Cascader/get-cascader-path-options.cjs +19 -0
  18. package/cjs/components/Cascader/get-cascader-path-options.cjs.map +1 -0
  19. package/cjs/components/Cascader/use-cascader.cjs +135 -0
  20. package/cjs/components/Cascader/use-cascader.cjs.map +1 -0
  21. package/cjs/components/ColorPicker/converters/converters.cjs +5 -0
  22. package/cjs/components/ColorPicker/converters/parsers.cjs +5 -0
  23. package/cjs/components/Combobox/use-combobox/use-combobox.cjs +6 -2
  24. package/cjs/components/Combobox/use-combobox/use-combobox.cjs.map +1 -1
  25. package/cjs/components/ComboboxPopover/ComboboxPopover.cjs +2 -1
  26. package/cjs/components/ComboboxPopover/ComboboxPopover.cjs.map +1 -1
  27. package/cjs/components/Drawer/DrawerStack.cjs +1 -1
  28. package/cjs/components/Drawer/DrawerStack.cjs.map +1 -1
  29. package/cjs/components/FloatingIndicator/FloatingIndicator.cjs +2 -1
  30. package/cjs/components/FloatingIndicator/FloatingIndicator.cjs.map +1 -1
  31. package/cjs/components/FloatingWindow/FloatingWindow.cjs +34 -10
  32. package/cjs/components/FloatingWindow/FloatingWindow.cjs.map +1 -1
  33. package/cjs/components/FloatingWindow/FloatingWindow.context.cjs +8 -0
  34. package/cjs/components/FloatingWindow/FloatingWindow.context.cjs.map +1 -0
  35. package/cjs/components/FloatingWindow/FloatingWindow.module.cjs.map +1 -1
  36. package/cjs/components/FloatingWindow/FloatingWindowResizeHandle.cjs +186 -0
  37. package/cjs/components/FloatingWindow/FloatingWindowResizeHandle.cjs.map +1 -0
  38. package/cjs/components/Input/InputLabel/InputLabel.cjs +3 -1
  39. package/cjs/components/Input/InputLabel/InputLabel.cjs.map +1 -1
  40. package/cjs/components/Input/InputWrapper/InputWrapper.cjs.map +1 -1
  41. package/cjs/components/Modal/ModalStack.cjs +1 -1
  42. package/cjs/components/Modal/ModalStack.cjs.map +1 -1
  43. package/cjs/components/OverflowList/OverflowList.cjs +2 -1
  44. package/cjs/components/OverflowList/OverflowList.cjs.map +1 -1
  45. package/cjs/components/Pagination/PaginationEdges/PaginationEdges.cjs +1 -0
  46. package/cjs/components/ScrollArea/ScrollArea.cjs +7 -2
  47. package/cjs/components/ScrollArea/ScrollArea.cjs.map +1 -1
  48. package/cjs/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
  49. package/cjs/components/ScrollArea/ScrollAreaCorner/ScrollAreaCorner.cjs +1 -0
  50. package/cjs/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.cjs +8 -4
  51. package/cjs/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.cjs.map +1 -1
  52. package/cjs/components/ScrollArea/ScrollAreaThumb/ScrollAreaThumb.cjs +3 -1
  53. package/cjs/components/ScrollArea/ScrollAreaThumb/ScrollAreaThumb.cjs.map +1 -1
  54. package/cjs/components/SimpleGrid/SimpleGridVariables.cjs +1 -1
  55. package/cjs/components/SimpleGrid/SimpleGridVariables.cjs.map +1 -1
  56. package/cjs/components/Slider/RangeSlider/RangeSlider.cjs +18 -11
  57. package/cjs/components/Slider/RangeSlider/RangeSlider.cjs.map +1 -1
  58. package/cjs/components/Table/Table.components.cjs +1 -0
  59. package/cjs/components/TagsInput/TagsInput.cjs +2 -1
  60. package/cjs/components/TagsInput/TagsInput.cjs.map +1 -1
  61. package/cjs/components/Timeline/Timeline.cjs +5 -1
  62. package/cjs/components/Timeline/Timeline.cjs.map +1 -1
  63. package/cjs/components/Timeline/Timeline.module.cjs +2 -1
  64. package/cjs/components/Timeline/Timeline.module.cjs.map +1 -1
  65. package/cjs/components/Timeline/TimelineItem/TimelineItem.cjs +31 -20
  66. package/cjs/components/Timeline/TimelineItem/TimelineItem.cjs.map +1 -1
  67. package/cjs/components/Tree/TreeNode.cjs.map +1 -1
  68. package/cjs/components/Tree/use-tree.cjs +1 -1
  69. package/cjs/components/Tree/use-tree.cjs.map +1 -1
  70. package/cjs/components/TreeSelect/TreeSelect.cjs +3 -2
  71. package/cjs/components/TreeSelect/TreeSelect.cjs.map +1 -1
  72. package/cjs/core/Box/get-box-mod/get-box-mod.cjs +1 -0
  73. package/cjs/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.cjs +6 -5
  74. package/cjs/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.cjs.map +1 -1
  75. package/cjs/core/MantineProvider/merge-mantine-theme/merge-mantine-theme.cjs +2 -0
  76. package/cjs/core/MantineProvider/use-matches/use-matches.cjs +3 -2
  77. package/cjs/core/MantineProvider/use-matches/use-matches.cjs.map +1 -1
  78. package/cjs/index.cjs +7 -1
  79. package/esm/components/Accordion/Accordion.mjs +5 -2
  80. package/esm/components/Accordion/Accordion.mjs.map +1 -1
  81. package/esm/components/AngleSlider/AngleSlider.mjs +4 -1
  82. package/esm/components/AngleSlider/AngleSlider.mjs.map +1 -1
  83. package/esm/components/Avatar/AvatarGroup/AvatarGroup.mjs +15 -14
  84. package/esm/components/Avatar/AvatarGroup/AvatarGroup.mjs.map +1 -1
  85. package/esm/components/Cascader/Cascader.mjs +371 -0
  86. package/esm/components/Cascader/Cascader.mjs.map +1 -0
  87. package/esm/components/Cascader/Cascader.module.mjs +18 -0
  88. package/esm/components/Cascader/Cascader.module.mjs.map +1 -0
  89. package/esm/components/Cascader/CascaderColumns.mjs +135 -0
  90. package/esm/components/Cascader/CascaderColumns.mjs.map +1 -0
  91. package/esm/components/Cascader/flatten-cascader-paths.mjs +26 -0
  92. package/esm/components/Cascader/flatten-cascader-paths.mjs.map +1 -0
  93. package/esm/components/Cascader/get-cascader-columns.mjs +28 -0
  94. package/esm/components/Cascader/get-cascader-columns.mjs.map +1 -0
  95. package/esm/components/Cascader/get-cascader-path-options.mjs +19 -0
  96. package/esm/components/Cascader/get-cascader-path-options.mjs.map +1 -0
  97. package/esm/components/Cascader/use-cascader.mjs +135 -0
  98. package/esm/components/Cascader/use-cascader.mjs.map +1 -0
  99. package/esm/components/ColorPicker/converters/converters.mjs +1 -1
  100. package/esm/components/ColorPicker/converters/parsers.mjs +1 -1
  101. package/esm/components/Combobox/use-combobox/use-combobox.mjs +6 -2
  102. package/esm/components/Combobox/use-combobox/use-combobox.mjs.map +1 -1
  103. package/esm/components/ComboboxPopover/ComboboxPopover.mjs +2 -1
  104. package/esm/components/ComboboxPopover/ComboboxPopover.mjs.map +1 -1
  105. package/esm/components/Drawer/DrawerStack.mjs +1 -1
  106. package/esm/components/Drawer/DrawerStack.mjs.map +1 -1
  107. package/esm/components/FloatingIndicator/FloatingIndicator.mjs +2 -1
  108. package/esm/components/FloatingIndicator/FloatingIndicator.mjs.map +1 -1
  109. package/esm/components/FloatingWindow/FloatingWindow.context.mjs +8 -0
  110. package/esm/components/FloatingWindow/FloatingWindow.context.mjs.map +1 -0
  111. package/esm/components/FloatingWindow/FloatingWindow.mjs +35 -11
  112. package/esm/components/FloatingWindow/FloatingWindow.mjs.map +1 -1
  113. package/esm/components/FloatingWindow/FloatingWindow.module.mjs.map +1 -1
  114. package/esm/components/FloatingWindow/FloatingWindowResizeHandle.mjs +186 -0
  115. package/esm/components/FloatingWindow/FloatingWindowResizeHandle.mjs.map +1 -0
  116. package/esm/components/Input/InputLabel/InputLabel.mjs +3 -1
  117. package/esm/components/Input/InputLabel/InputLabel.mjs.map +1 -1
  118. package/esm/components/Input/InputWrapper/InputWrapper.mjs.map +1 -1
  119. package/esm/components/Modal/ModalStack.mjs +1 -1
  120. package/esm/components/Modal/ModalStack.mjs.map +1 -1
  121. package/esm/components/OverflowList/OverflowList.mjs +2 -1
  122. package/esm/components/OverflowList/OverflowList.mjs.map +1 -1
  123. package/esm/components/Pagination/PaginationEdges/PaginationEdges.mjs +1 -1
  124. package/esm/components/ScrollArea/ScrollArea.mjs +7 -2
  125. package/esm/components/ScrollArea/ScrollArea.mjs.map +1 -1
  126. package/esm/components/ScrollArea/ScrollArea.module.mjs.map +1 -1
  127. package/esm/components/ScrollArea/ScrollAreaCorner/ScrollAreaCorner.mjs +1 -1
  128. package/esm/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.mjs +8 -4
  129. package/esm/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.mjs.map +1 -1
  130. package/esm/components/ScrollArea/ScrollAreaThumb/ScrollAreaThumb.mjs +3 -2
  131. package/esm/components/ScrollArea/ScrollAreaThumb/ScrollAreaThumb.mjs.map +1 -1
  132. package/esm/components/SimpleGrid/SimpleGridVariables.mjs +1 -1
  133. package/esm/components/SimpleGrid/SimpleGridVariables.mjs.map +1 -1
  134. package/esm/components/Slider/RangeSlider/RangeSlider.mjs +18 -11
  135. package/esm/components/Slider/RangeSlider/RangeSlider.mjs.map +1 -1
  136. package/esm/components/Table/Table.components.mjs +1 -1
  137. package/esm/components/TagsInput/TagsInput.mjs +2 -1
  138. package/esm/components/TagsInput/TagsInput.mjs.map +1 -1
  139. package/esm/components/Timeline/Timeline.mjs +5 -1
  140. package/esm/components/Timeline/Timeline.mjs.map +1 -1
  141. package/esm/components/Timeline/Timeline.module.mjs +2 -1
  142. package/esm/components/Timeline/Timeline.module.mjs.map +1 -1
  143. package/esm/components/Timeline/TimelineItem/TimelineItem.mjs +31 -20
  144. package/esm/components/Timeline/TimelineItem/TimelineItem.mjs.map +1 -1
  145. package/esm/components/Tree/TreeNode.mjs.map +1 -1
  146. package/esm/components/Tree/use-tree.mjs +1 -1
  147. package/esm/components/Tree/use-tree.mjs.map +1 -1
  148. package/esm/components/TreeSelect/TreeSelect.mjs +3 -2
  149. package/esm/components/TreeSelect/TreeSelect.mjs.map +1 -1
  150. package/esm/core/Box/get-box-mod/get-box-mod.mjs +1 -1
  151. package/esm/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.mjs +6 -5
  152. package/esm/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.mjs.map +1 -1
  153. package/esm/core/MantineProvider/merge-mantine-theme/merge-mantine-theme.mjs +1 -1
  154. package/esm/core/MantineProvider/use-matches/use-matches.mjs +3 -2
  155. package/esm/core/MantineProvider/use-matches/use-matches.mjs.map +1 -1
  156. package/esm/index.mjs +5 -2
  157. package/lib/components/Accordion/Accordion.d.ts +2 -0
  158. package/lib/components/Cascader/Cascader.d.ts +114 -0
  159. package/lib/components/Cascader/CascaderColumns.d.ts +36 -0
  160. package/lib/components/Cascader/flatten-cascader-paths.d.ts +12 -0
  161. package/lib/components/Cascader/get-cascader-columns.d.ts +4 -0
  162. package/lib/components/Cascader/get-cascader-path-options.d.ts +2 -0
  163. package/lib/components/Cascader/index.d.ts +12 -0
  164. package/lib/components/Cascader/use-cascader.d.ts +25 -0
  165. package/lib/components/FloatingWindow/FloatingWindow.context.d.ts +30 -0
  166. package/lib/components/FloatingWindow/FloatingWindow.d.ts +16 -5
  167. package/lib/components/FloatingWindow/FloatingWindowResizeHandle.d.ts +11 -0
  168. package/lib/components/FloatingWindow/index.d.ts +2 -0
  169. package/lib/components/Input/InputWrapper/InputWrapper.d.ts +5 -5
  170. package/lib/components/Input/use-input-props.d.ts +4 -4
  171. package/lib/components/MaskInput/use-mask-input-props.d.ts +4 -4
  172. package/lib/components/ScrollArea/ScrollArea.d.ts +5 -0
  173. package/lib/components/Timeline/TimelineItem/TimelineItem.d.ts +5 -1
  174. package/lib/components/index.d.ts +1 -0
  175. package/package.json +3 -3
  176. package/styles/Cascader.css +215 -0
  177. package/styles/Cascader.layer.css +216 -0
  178. package/styles/FloatingWindow.css +2 -0
  179. package/styles/FloatingWindow.layer.css +2 -0
  180. package/styles/ScrollArea.css +58 -0
  181. package/styles/ScrollArea.layer.css +58 -0
  182. package/styles/Timeline.css +88 -14
  183. package/styles/Timeline.layer.css +88 -14
  184. package/styles.css +364 -14
  185. package/styles.layer.css +364 -14
@@ -0,0 +1,135 @@
1
+ "use client";
2
+ import { ScrollArea } from "../ScrollArea/ScrollArea.mjs";
3
+ import { UnstyledButton } from "../UnstyledButton/UnstyledButton.mjs";
4
+ import { AccordionChevron } from "../Accordion/AccordionChevron.mjs";
5
+ import { CheckIcon } from "../Checkbox/CheckIcon.mjs";
6
+ import { cascaderOptionHasChildren, getCascaderColumns } from "./get-cascader-columns.mjs";
7
+ import { useState } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ //#region packages/@mantine/core/src/components/Cascader/CascaderColumns.tsx
10
+ function getCascaderOptionId(listId, level, value) {
11
+ return listId ? `${listId}-${level}-${value}` : void 0;
12
+ }
13
+ function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon, checkIconPosition, renderOption, columnWidth, maxDisplayedLevels, previousLevelsControlLabel, nextLevelsControlLabel, maxDropdownHeight, nothingFoundMessage, getStyles, unstyled, scrollAreaProps, onOptionClick, onOptionMouseEnter, onColumnsMouseLeave, onPointerActivity, listId }) {
14
+ const allColumns = getCascaderColumns(data, activePath);
15
+ const totalColumns = allColumns.length;
16
+ const maxLevels = maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns;
17
+ const maxOffset = Math.max(0, totalColumns - maxLevels);
18
+ const focusedLevel = activePath.length - 1;
19
+ const showCheckIcon = withCheckIcon !== false;
20
+ const activePathKey = JSON.stringify(activePath);
21
+ const [windowState, setWindowState] = useState({
22
+ key: activePathKey,
23
+ offset: 0
24
+ });
25
+ const windowOffset = windowState.key === activePathKey ? windowState.offset : 0;
26
+ if (windowState.key !== activePathKey) setWindowState({
27
+ key: activePathKey,
28
+ offset: 0
29
+ });
30
+ const setWindowOffset = (updater) => setWindowState((current) => ({
31
+ key: activePathKey,
32
+ offset: updater(current.offset)
33
+ }));
34
+ const windowStart = Math.max(0, maxOffset - Math.min(windowOffset, maxOffset));
35
+ const windowEnd = Math.min(totalColumns, windowStart + maxLevels);
36
+ const visibleColumns = allColumns.slice(windowStart, windowEnd);
37
+ const hiddenBefore = windowStart;
38
+ const hiddenAfter = totalColumns - windowEnd;
39
+ const check = showCheckIcon ? /* @__PURE__ */ jsx(CheckIcon, { ...getStyles("columnOptionCheck") }) : null;
40
+ return /* @__PURE__ */ jsxs("div", {
41
+ ...getStyles("columnsList"),
42
+ role: "presentation",
43
+ onMouseLeave: onColumnsMouseLeave,
44
+ onMouseMove: onPointerActivity,
45
+ children: [
46
+ hiddenBefore > 0 && /* @__PURE__ */ jsx(UnstyledButton, {
47
+ ...getStyles("columnsOverflow"),
48
+ "data-position": "start",
49
+ tabIndex: -1,
50
+ unstyled,
51
+ "aria-label": previousLevelsControlLabel,
52
+ title: previousLevelsControlLabel,
53
+ onMouseDown: (event) => event.preventDefault(),
54
+ onClick: () => setWindowOffset((current) => Math.min(maxOffset, current + 1)),
55
+ children: /* @__PURE__ */ jsx(AccordionChevron, {})
56
+ }),
57
+ visibleColumns.map((options, index) => {
58
+ const level = windowStart + index;
59
+ return /* @__PURE__ */ jsx("div", {
60
+ "data-last": index === visibleColumns.length - 1 && hiddenAfter === 0 || void 0,
61
+ ...getStyles("column", { style: columnWidth ? {
62
+ width: columnWidth,
63
+ minWidth: columnWidth
64
+ } : void 0 }),
65
+ children: /* @__PURE__ */ jsx(ScrollArea.Autosize, {
66
+ mah: maxDropdownHeight ?? 260,
67
+ type: "scroll",
68
+ scrollbarSize: "var(--combobox-padding)",
69
+ role: "listbox",
70
+ ...scrollAreaProps,
71
+ ...getStyles("columnScroll"),
72
+ children: options.length === 0 ? /* @__PURE__ */ jsx("div", {
73
+ ...getStyles("columnEmpty"),
74
+ children: nothingFoundMessage
75
+ }) : options.map((option) => {
76
+ const isActive = activePath[level] === option.value;
77
+ const isCurrent = isActive && level === focusedLevel && keyboardNav;
78
+ const isInPath = isActive && level < focusedLevel;
79
+ const hasChildren = cascaderOptionHasChildren(option);
80
+ const isSelected = !!value && value.length === level + 1 && value[level] === option.value;
81
+ return /* @__PURE__ */ jsxs(UnstyledButton, {
82
+ id: getCascaderOptionId(listId, level, option.value),
83
+ role: "option",
84
+ "aria-selected": isCurrent || void 0,
85
+ "aria-disabled": option.disabled || void 0,
86
+ "data-active": isCurrent || void 0,
87
+ "data-in-path": isInPath || void 0,
88
+ "data-selected": isSelected || void 0,
89
+ "data-disabled": option.disabled || void 0,
90
+ tabIndex: -1,
91
+ unstyled,
92
+ onMouseDown: (event) => event.preventDefault(),
93
+ onClick: () => {
94
+ if (!option.disabled) onOptionClick(level, option);
95
+ },
96
+ onMouseEnter: () => {
97
+ if (!option.disabled) onOptionMouseEnter(level, option);
98
+ },
99
+ ...getStyles("columnOption"),
100
+ children: [
101
+ isSelected && checkIconPosition === "left" && check,
102
+ /* @__PURE__ */ jsx("span", {
103
+ ...getStyles("columnOptionLabel"),
104
+ children: renderOption ? renderOption(option, level) : option.label ?? option.value
105
+ }),
106
+ isSelected && checkIconPosition !== "left" && check,
107
+ hasChildren && /* @__PURE__ */ jsx("span", {
108
+ ...getStyles("columnOptionIcon"),
109
+ children: /* @__PURE__ */ jsx(AccordionChevron, {})
110
+ })
111
+ ]
112
+ }, option.value);
113
+ })
114
+ })
115
+ }, level);
116
+ }),
117
+ hiddenAfter > 0 && /* @__PURE__ */ jsx(UnstyledButton, {
118
+ ...getStyles("columnsOverflow"),
119
+ "data-position": "end",
120
+ tabIndex: -1,
121
+ unstyled,
122
+ "aria-label": nextLevelsControlLabel,
123
+ title: nextLevelsControlLabel,
124
+ onMouseDown: (event) => event.preventDefault(),
125
+ onClick: () => setWindowOffset((current) => Math.max(0, current - 1)),
126
+ children: /* @__PURE__ */ jsx(AccordionChevron, {})
127
+ })
128
+ ]
129
+ });
130
+ }
131
+ CascaderColumns.displayName = "@mantine/core/CascaderColumns";
132
+ //#endregion
133
+ export { CascaderColumns, getCascaderOptionId };
134
+
135
+ //# sourceMappingURL=CascaderColumns.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CascaderColumns.mjs","names":[],"sources":["../../../src/components/Cascader/CascaderColumns.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { GetStylesApi } from '../../core';\nimport { AccordionChevron } from '../Accordion';\nimport { CheckIcon } from '../Checkbox/CheckIcon';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { UnstyledButton } from '../UnstyledButton';\nimport type { CascaderOption, CascaderStylesNames } from './Cascader';\nimport { cascaderOptionHasChildren, getCascaderColumns } from './get-cascader-columns';\n\ntype CascaderColumnsGetStyles = GetStylesApi<{ props: any; stylesNames: CascaderStylesNames }>;\n\nexport interface CascaderColumnsProps {\n data: CascaderOption[];\n activePath: string[];\n value: string[] | null;\n keyboardNav: boolean;\n withCheckIcon: boolean | undefined;\n checkIconPosition: 'left' | 'right' | undefined;\n renderOption: ((option: CascaderOption, level: number) => React.ReactNode) | undefined;\n columnWidth: number | string | undefined;\n maxDisplayedLevels: number | undefined;\n previousLevelsControlLabel: string | undefined;\n nextLevelsControlLabel: string | undefined;\n maxDropdownHeight: number | string | undefined;\n nothingFoundMessage: React.ReactNode;\n getStyles: CascaderColumnsGetStyles;\n unstyled: boolean | undefined;\n scrollAreaProps: ScrollAreaProps | undefined;\n onOptionClick: (level: number, option: CascaderOption) => void;\n onOptionMouseEnter: (level: number, option: CascaderOption) => void;\n onColumnsMouseLeave: (() => void) | undefined;\n onPointerActivity: (() => void) | undefined;\n listId: string | undefined;\n}\n\nexport function getCascaderOptionId(listId: string | undefined, level: number, value: string) {\n return listId ? `${listId}-${level}-${value}` : undefined;\n}\n\nexport function CascaderColumns({\n data,\n activePath,\n value,\n keyboardNav,\n withCheckIcon,\n checkIconPosition,\n renderOption,\n columnWidth,\n maxDisplayedLevels,\n previousLevelsControlLabel,\n nextLevelsControlLabel,\n maxDropdownHeight,\n nothingFoundMessage,\n getStyles,\n unstyled,\n scrollAreaProps,\n onOptionClick,\n onOptionMouseEnter,\n onColumnsMouseLeave,\n onPointerActivity,\n listId,\n}: CascaderColumnsProps) {\n const allColumns = getCascaderColumns(data, activePath);\n const totalColumns = allColumns.length;\n const maxLevels =\n maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns;\n const maxOffset = Math.max(0, totalColumns - maxLevels);\n const focusedLevel = activePath.length - 1;\n const showCheckIcon = withCheckIcon !== false;\n\n // Manual left/right scrolling of the visible window. It is reset synchronously whenever the\n // active path changes so that the focused column always stays visible during navigation.\n const activePathKey = JSON.stringify(activePath);\n const [windowState, setWindowState] = useState({ key: activePathKey, offset: 0 });\n const windowOffset = windowState.key === activePathKey ? windowState.offset : 0;\n if (windowState.key !== activePathKey) {\n setWindowState({ key: activePathKey, offset: 0 });\n }\n const setWindowOffset = (updater: (current: number) => number) =>\n setWindowState((current) => ({ key: activePathKey, offset: updater(current.offset) }));\n\n const clampedOffset = Math.min(windowOffset, maxOffset);\n const windowStart = Math.max(0, maxOffset - clampedOffset);\n const windowEnd = Math.min(totalColumns, windowStart + maxLevels);\n const visibleColumns = allColumns.slice(windowStart, windowEnd);\n const hiddenBefore = windowStart;\n const hiddenAfter = totalColumns - windowEnd;\n\n const check = showCheckIcon ? <CheckIcon {...getStyles('columnOptionCheck')} /> : null;\n\n return (\n <div\n {...getStyles('columnsList')}\n role=\"presentation\"\n onMouseLeave={onColumnsMouseLeave}\n onMouseMove={onPointerActivity}\n >\n {hiddenBefore > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"start\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={previousLevelsControlLabel}\n title={previousLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.min(maxOffset, current + 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n\n {visibleColumns.map((options, index) => {\n const level = windowStart + index;\n const isLastColumn = index === visibleColumns.length - 1 && hiddenAfter === 0;\n\n return (\n <div\n key={level}\n data-last={isLastColumn || undefined}\n {...getStyles('column', {\n style: columnWidth ? { width: columnWidth, minWidth: columnWidth } : undefined,\n })}\n >\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 260}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n role=\"listbox\"\n {...scrollAreaProps}\n {...getStyles('columnScroll')}\n >\n {options.length === 0 ? (\n <div {...getStyles('columnEmpty')}>{nothingFoundMessage}</div>\n ) : (\n options.map((option) => {\n const isActive = activePath[level] === option.value;\n const isCurrent = isActive && level === focusedLevel && keyboardNav;\n // The trail only covers ancestor columns; the deepest column is not highlighted\n // during mouse navigation (only via the keyboard \"current\" state)\n const isInPath = isActive && level < focusedLevel;\n const hasChildren = cascaderOptionHasChildren(option);\n const isSelected =\n !!value && value.length === level + 1 && value[level] === option.value;\n\n return (\n <UnstyledButton\n key={option.value}\n id={getCascaderOptionId(listId, level, option.value)}\n role=\"option\"\n aria-selected={isCurrent || undefined}\n aria-disabled={option.disabled || undefined}\n data-active={isCurrent || undefined}\n data-in-path={isInPath || undefined}\n data-selected={isSelected || undefined}\n data-disabled={option.disabled || undefined}\n tabIndex={-1}\n unstyled={unstyled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (!option.disabled) {\n onOptionClick(level, option);\n }\n }}\n onMouseEnter={() => {\n if (!option.disabled) {\n onOptionMouseEnter(level, option);\n }\n }}\n {...getStyles('columnOption')}\n >\n {isSelected && checkIconPosition === 'left' && check}\n\n <span {...getStyles('columnOptionLabel')}>\n {renderOption\n ? renderOption(option, level)\n : (option.label ?? option.value)}\n </span>\n\n {isSelected && checkIconPosition !== 'left' && check}\n\n {hasChildren && (\n <span {...getStyles('columnOptionIcon')}>\n <AccordionChevron />\n </span>\n )}\n </UnstyledButton>\n );\n })\n )}\n </ScrollArea.Autosize>\n </div>\n );\n })}\n\n {hiddenAfter > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"end\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={nextLevelsControlLabel}\n title={nextLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.max(0, current - 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n </div>\n );\n}\n\nCascaderColumns.displayName = '@mantine/core/CascaderColumns';\n"],"mappings":";;;;;;;;;AAmCA,SAAgB,oBAAoB,QAA4B,OAAe,OAAe;CAC5F,OAAO,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,KAAA;AAClD;AAEA,SAAgB,gBAAgB,EAC9B,MACA,YACA,OACA,aACA,eACA,mBACA,cACA,aACA,oBACA,4BACA,wBACA,mBACA,qBACA,WACA,UACA,iBACA,eACA,oBACA,qBACA,mBACA,UACuB;CACvB,MAAM,aAAa,mBAAmB,MAAM,UAAU;CACtD,MAAM,eAAe,WAAW;CAChC,MAAM,YACJ,sBAAsB,qBAAqB,IAAI,qBAAqB;CACtE,MAAM,YAAY,KAAK,IAAI,GAAG,eAAe,SAAS;CACtD,MAAM,eAAe,WAAW,SAAS;CACzC,MAAM,gBAAgB,kBAAkB;CAIxC,MAAM,gBAAgB,KAAK,UAAU,UAAU;CAC/C,MAAM,CAAC,aAAa,kBAAkB,SAAS;EAAE,KAAK;EAAe,QAAQ;CAAE,CAAC;CAChF,MAAM,eAAe,YAAY,QAAQ,gBAAgB,YAAY,SAAS;CAC9E,IAAI,YAAY,QAAQ,eACtB,eAAe;EAAE,KAAK;EAAe,QAAQ;CAAE,CAAC;CAElD,MAAM,mBAAmB,YACvB,gBAAgB,aAAa;EAAE,KAAK;EAAe,QAAQ,QAAQ,QAAQ,MAAM;CAAE,EAAE;CAGvF,MAAM,cAAc,KAAK,IAAI,GAAG,YADV,KAAK,IAAI,cAAc,SACW,CAAC;CACzD,MAAM,YAAY,KAAK,IAAI,cAAc,cAAc,SAAS;CAChE,MAAM,iBAAiB,WAAW,MAAM,aAAa,SAAS;CAC9D,MAAM,eAAe;CACrB,MAAM,cAAc,eAAe;CAEnC,MAAM,QAAQ,gBAAgB,oBAAC,WAAD,EAAW,GAAI,UAAU,mBAAmB,EAAI,CAAA,IAAI;CAElF,OACE,qBAAC,OAAD;EACE,GAAI,UAAU,aAAa;EAC3B,MAAK;EACL,cAAc;EACd,aAAa;YAJf;GAMG,eAAe,KACd,oBAAC,gBAAD;IACE,GAAI,UAAU,iBAAiB;IAC/B,iBAAc;IACd,UAAU;IACA;IACV,cAAY;IACZ,OAAO;IACP,cAAc,UAAU,MAAM,eAAe;IAC7C,eAAe,iBAAiB,YAAY,KAAK,IAAI,WAAW,UAAU,CAAC,CAAC;cAE5E,oBAAC,kBAAD,CAAmB,CAAA;GACL,CAAA;GAGjB,eAAe,KAAK,SAAS,UAAU;IACtC,MAAM,QAAQ,cAAc;IAG5B,OACE,oBAAC,OAAD;KAEE,aALiB,UAAU,eAAe,SAAS,KAAK,gBAAgB,KAK7C,KAAA;KAC3B,GAAI,UAAU,UAAU,EACtB,OAAO,cAAc;MAAE,OAAO;MAAa,UAAU;KAAY,IAAI,KAAA,EACvE,CAAC;eAED,oBAAC,WAAW,UAAZ;MACE,KAAK,qBAAqB;MAC1B,MAAK;MACL,eAAc;MACd,MAAK;MACL,GAAI;MACJ,GAAI,UAAU,cAAc;gBAE3B,QAAQ,WAAW,IAClB,oBAAC,OAAD;OAAK,GAAI,UAAU,aAAa;iBAAI;MAAyB,CAAA,IAE7D,QAAQ,KAAK,WAAW;OACtB,MAAM,WAAW,WAAW,WAAW,OAAO;OAC9C,MAAM,YAAY,YAAY,UAAU,gBAAgB;OAGxD,MAAM,WAAW,YAAY,QAAQ;OACrC,MAAM,cAAc,0BAA0B,MAAM;OACpD,MAAM,aACJ,CAAC,CAAC,SAAS,MAAM,WAAW,QAAQ,KAAK,MAAM,WAAW,OAAO;OAEnE,OACE,qBAAC,gBAAD;QAEE,IAAI,oBAAoB,QAAQ,OAAO,OAAO,KAAK;QACnD,MAAK;QACL,iBAAe,aAAa,KAAA;QAC5B,iBAAe,OAAO,YAAY,KAAA;QAClC,eAAa,aAAa,KAAA;QAC1B,gBAAc,YAAY,KAAA;QAC1B,iBAAe,cAAc,KAAA;QAC7B,iBAAe,OAAO,YAAY,KAAA;QAClC,UAAU;QACA;QACV,cAAc,UAAU,MAAM,eAAe;QAC7C,eAAe;SACb,IAAI,CAAC,OAAO,UACV,cAAc,OAAO,MAAM;QAE/B;QACA,oBAAoB;SAClB,IAAI,CAAC,OAAO,UACV,mBAAmB,OAAO,MAAM;QAEpC;QACA,GAAI,UAAU,cAAc;kBAvB9B;SAyBG,cAAc,sBAAsB,UAAU;SAE/C,oBAAC,QAAD;UAAM,GAAI,UAAU,mBAAmB;oBACpC,eACG,aAAa,QAAQ,KAAK,IACzB,OAAO,SAAS,OAAO;SACxB,CAAA;SAEL,cAAc,sBAAsB,UAAU;SAE9C,eACC,oBAAC,QAAD;UAAM,GAAI,UAAU,kBAAkB;oBACpC,oBAAC,kBAAD,CAAmB,CAAA;SACf,CAAA;QAEM;UAvCT,OAAO,KAuCE;MAEpB,CAAC;KAEgB,CAAA;IAClB,GAzEE,KAyEF;GAET,CAAC;GAEA,cAAc,KACb,oBAAC,gBAAD;IACE,GAAI,UAAU,iBAAiB;IAC/B,iBAAc;IACd,UAAU;IACA;IACV,cAAY;IACZ,OAAO;IACP,cAAc,UAAU,MAAM,eAAe;IAC7C,eAAe,iBAAiB,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;cAEpE,oBAAC,kBAAD,CAAmB,CAAA;GACL,CAAA;EAEf;;AAET;AAEA,gBAAgB,cAAc"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ //#region packages/@mantine/core/src/components/Cascader/flatten-cascader-paths.ts
3
+ function flattenCascaderPaths(data) {
4
+ const result = [];
5
+ const walk = (nodes, parentPath, parentOptions, parentDisabled) => {
6
+ for (const node of nodes) {
7
+ const path = [...parentPath, node.value];
8
+ const options = [...parentOptions, node];
9
+ const disabled = parentDisabled || !!node.disabled;
10
+ const hasChildren = Array.isArray(node.children) && node.children.length > 0;
11
+ result.push({
12
+ path,
13
+ options,
14
+ leaf: !hasChildren,
15
+ disabled
16
+ });
17
+ if (hasChildren) walk(node.children, path, options, disabled);
18
+ }
19
+ };
20
+ walk(data, [], [], false);
21
+ return result;
22
+ }
23
+ //#endregion
24
+ export { flattenCascaderPaths };
25
+
26
+ //# sourceMappingURL=flatten-cascader-paths.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatten-cascader-paths.mjs","names":[],"sources":["../../../src/components/Cascader/flatten-cascader-paths.ts"],"sourcesContent":["import type { CascaderOption } from './Cascader';\n\nexport interface CascaderFlatPath {\n /** Values from root to node */\n path: string[];\n\n /** Option chain from root to node */\n options: CascaderOption[];\n\n /** `true` if the node has no children */\n leaf: boolean;\n\n /** `true` if the node or any of its ancestors is disabled */\n disabled: boolean;\n}\n\nexport function flattenCascaderPaths(data: CascaderOption[]): CascaderFlatPath[] {\n const result: CascaderFlatPath[] = [];\n\n const walk = (\n nodes: CascaderOption[],\n parentPath: string[],\n parentOptions: CascaderOption[],\n parentDisabled: boolean\n ) => {\n for (const node of nodes) {\n const path = [...parentPath, node.value];\n const options = [...parentOptions, node];\n const disabled = parentDisabled || !!node.disabled;\n const hasChildren = Array.isArray(node.children) && node.children.length > 0;\n\n result.push({ path, options, leaf: !hasChildren, disabled });\n\n if (hasChildren) {\n walk(node.children!, path, options, disabled);\n }\n }\n };\n\n walk(data, [], [], false);\n\n return result;\n}\n"],"mappings":";;AAgBA,SAAgB,qBAAqB,MAA4C;CAC/E,MAAM,SAA6B,CAAC;CAEpC,MAAM,QACJ,OACA,YACA,eACA,mBACG;EACH,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK,KAAK;GACvC,MAAM,UAAU,CAAC,GAAG,eAAe,IAAI;GACvC,MAAM,WAAW,kBAAkB,CAAC,CAAC,KAAK;GAC1C,MAAM,cAAc,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS;GAE3E,OAAO,KAAK;IAAE;IAAM;IAAS,MAAM,CAAC;IAAa;GAAS,CAAC;GAE3D,IAAI,aACF,KAAK,KAAK,UAAW,MAAM,SAAS,QAAQ;EAEhD;CACF;CAEA,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;CAExB,OAAO;AACT"}
@@ -0,0 +1,28 @@
1
+ "use client";
2
+ //#region packages/@mantine/core/src/components/Cascader/get-cascader-columns.ts
3
+ function cascaderOptionHasChildren(option) {
4
+ return Array.isArray(option.children) && option.children.length > 0;
5
+ }
6
+ function findCascaderOption(options, value) {
7
+ return options.find((option) => option.value === value);
8
+ }
9
+ function getCascaderColumns(data, activePath) {
10
+ const columns = [data];
11
+ let level = data;
12
+ for (let index = 0; index < activePath.length; index += 1) {
13
+ const node = findCascaderOption(level, activePath[index]);
14
+ if (!node) break;
15
+ const isLast = index === activePath.length - 1;
16
+ if (Array.isArray(node.children) && node.children.length > 0) {
17
+ if (!isLast) {
18
+ columns.push(node.children);
19
+ level = node.children;
20
+ }
21
+ } else break;
22
+ }
23
+ return columns;
24
+ }
25
+ //#endregion
26
+ export { cascaderOptionHasChildren, findCascaderOption, getCascaderColumns };
27
+
28
+ //# sourceMappingURL=get-cascader-columns.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-cascader-columns.mjs","names":[],"sources":["../../../src/components/Cascader/get-cascader-columns.ts"],"sourcesContent":["import type { CascaderOption } from './Cascader';\n\nexport function cascaderOptionHasChildren(option: CascaderOption): boolean {\n return Array.isArray(option.children) && option.children.length > 0;\n}\n\nexport function findCascaderOption(\n options: CascaderOption[],\n value: string\n): CascaderOption | undefined {\n return options.find((option) => option.value === value);\n}\n\nexport function getCascaderColumns(\n data: CascaderOption[],\n activePath: string[]\n): CascaderOption[][] {\n const columns: CascaderOption[][] = [data];\n let level = data;\n\n for (let index = 0; index < activePath.length; index += 1) {\n const node = findCascaderOption(level, activePath[index]);\n\n if (!node) {\n break;\n }\n\n const isLast = index === activePath.length - 1;\n\n if (Array.isArray(node.children) && node.children.length > 0) {\n if (!isLast) {\n columns.push(node.children);\n level = node.children;\n }\n // The deepest highlighted option is intentionally not expanded\n } else {\n break;\n }\n }\n\n return columns;\n}\n"],"mappings":";;AAEA,SAAgB,0BAA0B,QAAiC;CACzE,OAAO,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,SAAS;AACpE;AAEA,SAAgB,mBACd,SACA,OAC4B;CAC5B,OAAO,QAAQ,MAAM,WAAW,OAAO,UAAU,KAAK;AACxD;AAEA,SAAgB,mBACd,MACA,YACoB;CACpB,MAAM,UAA8B,CAAC,IAAI;CACzC,IAAI,QAAQ;CAEZ,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS,GAAG;EACzD,MAAM,OAAO,mBAAmB,OAAO,WAAW,MAAM;EAExD,IAAI,CAAC,MACH;EAGF,MAAM,SAAS,UAAU,WAAW,SAAS;EAE7C,IAAI,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS;OACrD,CAAC,QAAQ;IACX,QAAQ,KAAK,KAAK,QAAQ;IAC1B,QAAQ,KAAK;GACf;SAGA;CAEJ;CAEA,OAAO;AACT"}
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ //#region packages/@mantine/core/src/components/Cascader/get-cascader-path-options.ts
3
+ function getCascaderPathOptions(data, value) {
4
+ if (!value || value.length === 0) return [];
5
+ const options = [];
6
+ let level = data;
7
+ for (const currentValue of value) {
8
+ if (!level) break;
9
+ const node = level.find((option) => option.value === currentValue);
10
+ if (!node) break;
11
+ options.push(node);
12
+ level = node.children;
13
+ }
14
+ return options;
15
+ }
16
+ //#endregion
17
+ export { getCascaderPathOptions };
18
+
19
+ //# sourceMappingURL=get-cascader-path-options.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-cascader-path-options.mjs","names":[],"sources":["../../../src/components/Cascader/get-cascader-path-options.ts"],"sourcesContent":["import type { CascaderOption } from './Cascader';\n\nexport function getCascaderPathOptions(\n data: CascaderOption[],\n value: string[] | null | undefined\n): CascaderOption[] {\n if (!value || value.length === 0) {\n return [];\n }\n\n const options: CascaderOption[] = [];\n let level: CascaderOption[] | undefined = data;\n\n for (const currentValue of value) {\n if (!level) {\n break;\n }\n\n const node: CascaderOption | undefined = level.find((option) => option.value === currentValue);\n\n if (!node) {\n break;\n }\n\n options.push(node);\n level = node.children;\n }\n\n return options;\n}\n"],"mappings":";;AAEA,SAAgB,uBACd,MACA,OACkB;CAClB,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,OAAO,CAAC;CAGV,MAAM,UAA4B,CAAC;CACnC,IAAI,QAAsC;CAE1C,KAAK,MAAM,gBAAgB,OAAO;EAChC,IAAI,CAAC,OACH;EAGF,MAAM,OAAmC,MAAM,MAAM,WAAW,OAAO,UAAU,YAAY;EAE7F,IAAI,CAAC,MACH;EAGF,QAAQ,KAAK,IAAI;EACjB,QAAQ,KAAK;CACf;CAEA,OAAO;AACT"}
@@ -0,0 +1,135 @@
1
+ "use client";
2
+ import { cascaderOptionHasChildren, getCascaderColumns } from "./get-cascader-columns.mjs";
3
+ import { getCascaderPathOptions } from "./get-cascader-path-options.mjs";
4
+ import { useCallback, useMemo, useRef, useState } from "react";
5
+ import { useUncontrolled } from "@mantine/hooks";
6
+ //#region packages/@mantine/core/src/components/Cascader/use-cascader.ts
7
+ function pathsEqual(a, b) {
8
+ return !!a && a.length === b.length && a.every((item, index) => item === b[index]);
9
+ }
10
+ function findEnabledIndex(options, from, direction) {
11
+ let index = from + direction;
12
+ while (index >= 0 && index < options.length) {
13
+ if (!options[index].disabled) return index;
14
+ index += direction;
15
+ }
16
+ return -1;
17
+ }
18
+ function useCascader({ data, value, defaultValue, onChange, changeOnSelect, allowDeselect, expandTrigger, onLeafSelect }) {
19
+ const [keyboardNav, setKeyboardNav] = useState(false);
20
+ const [_value, setValue] = useUncontrolled({
21
+ value,
22
+ defaultValue,
23
+ finalValue: null,
24
+ onChange: (val) => onChange?.(val, getCascaderPathOptions(data, val))
25
+ });
26
+ const [activePath, setActivePath] = useState(() => _value ?? []);
27
+ const activePathRef = useRef(activePath);
28
+ activePathRef.current = activePath;
29
+ const resetActivePath = useCallback(() => {
30
+ setActivePath(_value ?? []);
31
+ }, [_value]);
32
+ const selectPath = useCallback((path) => {
33
+ setValue(allowDeselect && pathsEqual(_value, path) ? null : path);
34
+ }, [
35
+ allowDeselect,
36
+ _value,
37
+ setValue
38
+ ]);
39
+ const expandOption = useCallback((level, option) => {
40
+ const optionPath = [...activePathRef.current.slice(0, level), option.value];
41
+ const children = option.children;
42
+ if (Array.isArray(children) && children.length > 0) {
43
+ const first = findEnabledIndex(children, -1, 1);
44
+ setActivePath(first >= 0 ? [...optionPath, children[first].value] : optionPath);
45
+ } else setActivePath(optionPath);
46
+ }, []);
47
+ return {
48
+ value: _value,
49
+ setValue,
50
+ selectPath,
51
+ activePath,
52
+ setActivePath,
53
+ resetActivePath,
54
+ keyboardNav,
55
+ setKeyboardNav,
56
+ handleOptionClick: useCallback((level, option) => {
57
+ setKeyboardNav(false);
58
+ const path = [...activePath.slice(0, level), option.value];
59
+ if (cascaderOptionHasChildren(option)) {
60
+ if (changeOnSelect) selectPath(path);
61
+ expandOption(level, option);
62
+ if (changeOnSelect) onLeafSelect?.();
63
+ } else {
64
+ selectPath(path);
65
+ onLeafSelect?.();
66
+ }
67
+ }, [
68
+ activePath,
69
+ changeOnSelect,
70
+ selectPath,
71
+ expandOption,
72
+ onLeafSelect
73
+ ]),
74
+ handleOptionMouseEnter: useCallback((level, option) => {
75
+ setKeyboardNav(false);
76
+ if (expandTrigger !== "hover") return;
77
+ if (cascaderOptionHasChildren(option)) expandOption(level, option);
78
+ else setActivePath([...activePath.slice(0, level), option.value]);
79
+ }, [
80
+ expandTrigger,
81
+ activePath,
82
+ expandOption
83
+ ]),
84
+ handleColumnsKeyDown: useCallback((event) => {
85
+ setKeyboardNav(true);
86
+ const columns = getCascaderColumns(data, activePath);
87
+ const focusedLevel = Math.max(0, activePath.length - 1);
88
+ const currentColumn = columns[focusedLevel] ?? columns[0] ?? [];
89
+ const focusedIndex = currentColumn.findIndex((item) => item.value === activePath[focusedLevel]);
90
+ const focusedOption = focusedIndex >= 0 ? currentColumn[focusedIndex] : void 0;
91
+ switch (event.key) {
92
+ case "ArrowDown": {
93
+ const next = findEnabledIndex(currentColumn, focusedIndex, 1);
94
+ if (next >= 0) setActivePath([...activePath.slice(0, focusedLevel), currentColumn[next].value]);
95
+ return true;
96
+ }
97
+ case "ArrowUp": {
98
+ const prev = findEnabledIndex(currentColumn, focusedIndex < 0 ? currentColumn.length : focusedIndex, -1);
99
+ if (prev >= 0) setActivePath([...activePath.slice(0, focusedLevel), currentColumn[prev].value]);
100
+ return true;
101
+ }
102
+ case "ArrowRight":
103
+ if (focusedOption && cascaderOptionHasChildren(focusedOption)) expandOption(focusedLevel, focusedOption);
104
+ return true;
105
+ case "ArrowLeft":
106
+ if (activePath.length > 1) setActivePath(activePath.slice(0, -1));
107
+ return true;
108
+ case "Enter":
109
+ if (!focusedOption) return false;
110
+ if (cascaderOptionHasChildren(focusedOption)) {
111
+ if (changeOnSelect) selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);
112
+ expandOption(focusedLevel, focusedOption);
113
+ if (changeOnSelect) onLeafSelect?.();
114
+ } else {
115
+ selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);
116
+ onLeafSelect?.();
117
+ }
118
+ return true;
119
+ default: return false;
120
+ }
121
+ }, [
122
+ data,
123
+ activePath,
124
+ changeOnSelect,
125
+ selectPath,
126
+ expandOption,
127
+ onLeafSelect
128
+ ]),
129
+ pathOptions: useMemo(() => getCascaderPathOptions(data, _value), [data, _value])
130
+ };
131
+ }
132
+ //#endregion
133
+ export { useCascader };
134
+
135
+ //# sourceMappingURL=use-cascader.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-cascader.mjs","names":[],"sources":["../../../src/components/Cascader/use-cascader.ts"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport type { CascaderOption } from './Cascader';\nimport { cascaderOptionHasChildren, getCascaderColumns } from './get-cascader-columns';\nimport { getCascaderPathOptions } from './get-cascader-path-options';\n\nexport interface UseCascaderInput {\n data: CascaderOption[];\n value: string[] | null | undefined;\n defaultValue: string[] | null | undefined;\n onChange: ((value: string[] | null, options: CascaderOption[]) => void) | undefined;\n changeOnSelect: boolean | undefined;\n allowDeselect: boolean | undefined;\n expandTrigger: 'click' | 'hover' | undefined;\n onLeafSelect?: () => void;\n}\n\nfunction pathsEqual(a: string[] | null, b: string[]): boolean {\n return !!a && a.length === b.length && a.every((item, index) => item === b[index]);\n}\n\nfunction findEnabledIndex(options: CascaderOption[], from: number, direction: 1 | -1): number {\n let index = from + direction;\n\n while (index >= 0 && index < options.length) {\n if (!options[index].disabled) {\n return index;\n }\n index += direction;\n }\n\n return -1;\n}\n\nexport function useCascader({\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n allowDeselect,\n expandTrigger,\n onLeafSelect,\n}: UseCascaderInput) {\n const [keyboardNav, setKeyboardNav] = useState(false);\n\n const [_value, setValue] = useUncontrolled<string[] | null>({\n value: value as any,\n defaultValue: defaultValue as any,\n finalValue: null,\n onChange: (val) => onChange?.(val, getCascaderPathOptions(data, val)),\n });\n\n const [activePath, setActivePath] = useState<string[]>(() => _value ?? []);\n const activePathRef = useRef(activePath);\n activePathRef.current = activePath;\n\n const resetActivePath = useCallback(() => {\n setActivePath(_value ?? []);\n }, [_value]);\n\n const selectPath = useCallback(\n (path: string[]) => {\n setValue(allowDeselect && pathsEqual(_value, path) ? null : path);\n },\n [allowDeselect, _value, setValue]\n );\n\n const expandOption = useCallback((level: number, option: CascaderOption) => {\n const optionPath = [...activePathRef.current.slice(0, level), option.value];\n const children = option.children;\n\n if (Array.isArray(children) && children.length > 0) {\n const first = findEnabledIndex(children, -1, 1);\n setActivePath(first >= 0 ? [...optionPath, children[first].value] : optionPath);\n } else {\n setActivePath(optionPath);\n }\n }, []);\n\n const handleOptionClick = useCallback(\n (level: number, option: CascaderOption) => {\n setKeyboardNav(false);\n const path = [...activePath.slice(0, level), option.value];\n\n if (cascaderOptionHasChildren(option)) {\n if (changeOnSelect) {\n selectPath(path);\n }\n expandOption(level, option);\n if (changeOnSelect) {\n onLeafSelect?.();\n }\n } else {\n selectPath(path);\n onLeafSelect?.();\n }\n },\n [activePath, changeOnSelect, selectPath, expandOption, onLeafSelect]\n );\n\n const handleOptionMouseEnter = useCallback(\n (level: number, option: CascaderOption) => {\n setKeyboardNav(false);\n\n if (expandTrigger !== 'hover') {\n return;\n }\n\n if (cascaderOptionHasChildren(option)) {\n expandOption(level, option);\n } else {\n setActivePath([...activePath.slice(0, level), option.value]);\n }\n },\n [expandTrigger, activePath, expandOption]\n );\n\n const handleColumnsKeyDown = useCallback(\n (event: React.KeyboardEvent): boolean => {\n setKeyboardNav(true);\n const columns = getCascaderColumns(data, activePath);\n const focusedLevel = Math.max(0, activePath.length - 1);\n const currentColumn = columns[focusedLevel] ?? columns[0] ?? [];\n const focusedIndex = currentColumn.findIndex(\n (item) => item.value === activePath[focusedLevel]\n );\n const focusedOption = focusedIndex >= 0 ? currentColumn[focusedIndex] : undefined;\n\n switch (event.key) {\n case 'ArrowDown': {\n const next = findEnabledIndex(currentColumn, focusedIndex, 1);\n if (next >= 0) {\n setActivePath([...activePath.slice(0, focusedLevel), currentColumn[next].value]);\n }\n return true;\n }\n case 'ArrowUp': {\n const from = focusedIndex < 0 ? currentColumn.length : focusedIndex;\n const prev = findEnabledIndex(currentColumn, from, -1);\n if (prev >= 0) {\n setActivePath([...activePath.slice(0, focusedLevel), currentColumn[prev].value]);\n }\n return true;\n }\n case 'ArrowRight': {\n if (focusedOption && cascaderOptionHasChildren(focusedOption)) {\n expandOption(focusedLevel, focusedOption);\n }\n return true;\n }\n case 'ArrowLeft': {\n if (activePath.length > 1) {\n setActivePath(activePath.slice(0, -1));\n }\n return true;\n }\n case 'Enter': {\n if (!focusedOption) {\n return false;\n }\n\n if (cascaderOptionHasChildren(focusedOption)) {\n if (changeOnSelect) {\n selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);\n }\n expandOption(focusedLevel, focusedOption);\n if (changeOnSelect) {\n onLeafSelect?.();\n }\n } else {\n selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);\n onLeafSelect?.();\n }\n return true;\n }\n default:\n return false;\n }\n },\n [data, activePath, changeOnSelect, selectPath, expandOption, onLeafSelect]\n );\n\n const pathOptions = useMemo(() => getCascaderPathOptions(data, _value), [data, _value]);\n\n return {\n value: _value,\n setValue,\n selectPath,\n activePath,\n setActivePath,\n resetActivePath,\n keyboardNav,\n setKeyboardNav,\n handleOptionClick,\n handleOptionMouseEnter,\n handleColumnsKeyDown,\n pathOptions,\n };\n}\n"],"mappings":"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"}
@@ -79,6 +79,6 @@ function convertHsvaTo(format, color) {
79
79
  return CONVERTERS[format](color);
80
80
  }
81
81
  //#endregion
82
- export { convertHsvaTo };
82
+ export { convertHsvaTo, hsvaToHex, hsvaToHexa, hsvaToHsl, hsvaToRgba, hsvaToRgbaObject };
83
83
 
84
84
  //# sourceMappingURL=converters.mjs.map
@@ -139,6 +139,6 @@ function parseColor(color) {
139
139
  };
140
140
  }
141
141
  //#endregion
142
- export { isColorValid, parseColor, round };
142
+ export { isColorValid, parseColor, parseHex, parseHexa, parseHsla, parseHue, parseRgba, round };
143
143
 
144
144
  //# sourceMappingURL=parsers.mjs.map
@@ -74,7 +74,10 @@ function useCombobox({ defaultOpened, opened, onOpenedChange, onDropdownClose, o
74
74
  const selectActiveOption = useCallback(() => {
75
75
  const root = getRootElement(targetRef.current);
76
76
  const activeOption = findElementBySelector(`#${listId.current} [data-combobox-active]`, root);
77
- if (activeOption) return selectOption(findElementsBySelector(`#${listId.current} [data-combobox-option]`, root).findIndex((option) => option === activeOption));
77
+ if (activeOption) {
78
+ const index = findElementsBySelector(`#${listId.current} [data-combobox-option]`, root).findIndex((option) => option === activeOption);
79
+ return selectOption(index);
80
+ }
78
81
  return selectOption(0);
79
82
  }, [selectOption]);
80
83
  const selectNextOption = useCallback(() => {
@@ -89,7 +92,8 @@ function useCombobox({ defaultOpened, opened, onOpenedChange, onDropdownClose, o
89
92
  }, [selectOption, loop]);
90
93
  const selectFirstOption = useCallback(() => {
91
94
  const root = getRootElement(targetRef.current);
92
- return selectOption(getFirstIndex(findElementsBySelector(`#${listId.current} [data-combobox-option]`, root)));
95
+ const items = findElementsBySelector(`#${listId.current} [data-combobox-option]`, root);
96
+ return selectOption(getFirstIndex(items));
93
97
  }, [selectOption]);
94
98
  const updateSelectedOptionIndex = useCallback((target = "selected", options) => {
95
99
  if (typeof target === "number") {
@@ -1 +1 @@
1
- {"version":3,"file":"use-combobox.mjs","names":[],"sources":["../../../../src/components/Combobox/use-combobox/use-combobox.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { findElementBySelector, findElementsBySelector, getRootElement } from '../../../core/utils';\nimport { getFirstIndex, getNextIndex, getPreviousIndex } from './get-index/get-index';\n\nexport type ComboboxDropdownEventSource = 'keyboard' | 'mouse' | 'unknown';\n\nexport interface ComboboxStore {\n /** Current dropdown opened state */\n dropdownOpened: boolean;\n\n /** Opens dropdown */\n openDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Closes dropdown */\n closeDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Toggles dropdown opened state */\n toggleDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Selected option index ref */\n selectedOptionIndex: number;\n\n /** Returns currently selected option index or `-1` if none of the options is selected */\n getSelectedOptionIndex: () => number;\n\n /** Selects `Combobox.Option` by index */\n selectOption: (index: number) => void;\n\n /** Selects first `Combobox.Option` with `active` prop.\n * If there are no such options, the function does nothing.\n */\n selectActiveOption: () => string | null;\n\n /** Selects first `Combobox.Option` that is not disabled.\n * If there are no such options, the function does nothing.\n * */\n selectFirstOption: () => string | null;\n\n /** Selects next `Combobox.Option` that is not disabled.\n * If the current option is the last one, the function selects first option, if `loop` is true.\n */\n selectNextOption: () => string | null;\n\n /** Selects previous `Combobox.Option` that is not disabled.\n * If the current option is the first one, the function selects last option, if `loop` is true.\n * */\n selectPreviousOption: () => string | null;\n\n /** Resets selected option index to -1, removes `data-combobox-selected` from selected option */\n resetSelectedOption: () => void;\n\n /** Triggers `onClick` event of selected option.\n * If there is no selected option, the function does nothing.\n */\n clickSelectedOption: () => void;\n\n /** Updates selected option index to currently selected or active option.\n * The function is required to be used with searchable components to update selected option index\n * when options list changes based on search query.\n */\n updateSelectedOptionIndex: (\n target?: 'active' | 'selected' | number,\n options?: { scrollIntoView?: boolean }\n ) => void;\n\n /** List id, used for `aria-*` attributes */\n listId: string | null;\n\n /** Sets list id */\n setListId: (id: string) => void;\n\n /** Ref of `Combobox.Search` input */\n searchRef: React.RefObject<HTMLInputElement | null>;\n\n /** Moves focus to `Combobox.Search` input */\n focusSearchInput: () => void;\n\n /** Ref of the target element */\n targetRef: React.RefObject<HTMLElement | null>;\n\n /** Moves focus to the target element */\n focusTarget: () => void;\n}\n\nexport interface UseComboboxOptions {\n /** Default value for `dropdownOpened`, `false` by default. Used when the component is uncontrolled */\n defaultOpened?: boolean;\n\n /** Controlled `dropdownOpened` state. When set, the dropdown opened state is controlled by the parent component */\n opened?: boolean;\n\n /** Called when `dropdownOpened` state changes. Required for controlled mode */\n onOpenedChange?: (opened: boolean) => void;\n\n /** Called when dropdown closes with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown closure */\n onDropdownClose?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Called when dropdown opens with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown opening */\n onDropdownOpen?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Determines whether arrow key presses should loop through items (first to last and last to first). Defaults to `true` */\n loop?: boolean;\n\n /** `behavior` passed down to `element.scrollIntoView`. Controls the scrolling animation when options are scrolled into view. Defaults to `'instant'` */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function useCombobox({\n defaultOpened,\n opened,\n onOpenedChange,\n onDropdownClose,\n onDropdownOpen,\n loop = true,\n scrollBehavior = 'instant',\n}: UseComboboxOptions = {}): ComboboxStore {\n const [dropdownOpened, setDropdownOpened] = useUncontrolled({\n value: opened,\n defaultValue: defaultOpened,\n finalValue: false,\n onChange: onOpenedChange,\n });\n\n const listId = useRef<string | null>(null);\n const selectedOptionIndex = useRef<number>(-1);\n const searchRef = useRef<HTMLInputElement | null>(null);\n const targetRef = useRef<HTMLElement | null>(null);\n const focusSearchTimeout = useRef<number>(-1);\n const focusTargetTimeout = useRef<number>(-1);\n const selectedIndexUpdateTimeout = useRef<number>(-1);\n\n const openDropdown: ComboboxStore['openDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (!dropdownOpened) {\n setDropdownOpened(true);\n onDropdownOpen?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownOpen, dropdownOpened]\n );\n\n const closeDropdown: ComboboxStore['closeDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n setDropdownOpened(false);\n onDropdownClose?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownClose, dropdownOpened]\n );\n\n const toggleDropdown: ComboboxStore['toggleDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n closeDropdown(eventSource);\n } else {\n openDropdown(eventSource);\n }\n },\n [closeDropdown, openDropdown, dropdownOpened]\n );\n\n const clearSelectedItem = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const selected = findElementBySelector(`#${listId.current} [data-combobox-selected]`, root);\n selected?.removeAttribute('data-combobox-selected');\n selected?.removeAttribute('aria-selected');\n }, []);\n\n const selectOption = useCallback(\n (index: number) => {\n const root = getRootElement(targetRef.current);\n const list = findElementBySelector(`#${listId.current!}`, root);\n const items = list\n ? findElementsBySelector<HTMLDivElement>('[data-combobox-option]', list)\n : null;\n\n if (!items) {\n return null;\n }\n\n const nextIndex = index >= items!.length ? 0 : index < 0 ? items!.length - 1 : index;\n selectedOptionIndex.current = nextIndex;\n\n if (items?.[nextIndex] && !items[nextIndex].hasAttribute('data-combobox-disabled')) {\n clearSelectedItem();\n items[nextIndex].setAttribute('data-combobox-selected', 'true');\n items[nextIndex].setAttribute('aria-selected', 'true');\n items[nextIndex].scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n return items[nextIndex].id;\n }\n\n return null;\n },\n [scrollBehavior, clearSelectedItem]\n );\n\n const selectActiveOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const activeOption = findElementBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-active]`,\n root\n );\n\n if (activeOption) {\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option === activeOption);\n return selectOption(index);\n }\n\n return selectOption(0);\n }, [selectOption]);\n\n const selectNextOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getNextIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectPreviousOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getPreviousIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectFirstOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getFirstIndex(items));\n }, [selectOption]);\n\n const updateSelectedOptionIndex: ComboboxStore['updateSelectedOptionIndex'] = useCallback(\n (target = 'selected', options) => {\n if (typeof target === 'number') {\n selectedOptionIndex.current = target;\n const root = getRootElement(targetRef.current);\n\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n\n if (options?.scrollIntoView) {\n items[target]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n return;\n }\n\n selectedIndexUpdateTimeout.current = window.setTimeout(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option.hasAttribute(`data-combobox-${target}`));\n\n selectedOptionIndex.current = index;\n\n if (options?.scrollIntoView) {\n items[index]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n }, 0);\n },\n []\n );\n\n const resetSelectedOption = useCallback(() => {\n selectedOptionIndex.current = -1;\n clearSelectedItem();\n }, [clearSelectedItem]);\n\n const clickSelectedOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const item = items?.[selectedOptionIndex.current];\n item?.click();\n }, []);\n\n const setListId = useCallback((id: string) => {\n listId.current = id;\n }, []);\n\n const focusSearchInput = useCallback(() => {\n focusSearchTimeout.current = window.setTimeout(() => searchRef.current?.focus(), 0);\n }, []);\n\n const focusTarget = useCallback(() => {\n focusTargetTimeout.current = window.setTimeout(() => targetRef.current?.focus(), 0);\n }, []);\n\n const getSelectedOptionIndex = useCallback(() => selectedOptionIndex.current, []);\n\n useEffect(\n () => () => {\n window.clearTimeout(focusSearchTimeout.current);\n window.clearTimeout(focusTargetTimeout.current);\n window.clearTimeout(selectedIndexUpdateTimeout.current);\n },\n []\n );\n\n return {\n dropdownOpened,\n openDropdown,\n closeDropdown,\n toggleDropdown,\n\n selectedOptionIndex: selectedOptionIndex.current,\n getSelectedOptionIndex,\n selectOption,\n selectFirstOption,\n selectActiveOption,\n selectNextOption,\n selectPreviousOption,\n resetSelectedOption,\n updateSelectedOptionIndex,\n\n listId: listId.current,\n setListId,\n clickSelectedOption,\n\n searchRef,\n focusSearchInput,\n\n targetRef,\n focusTarget,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-combobox.mjs","names":[],"sources":["../../../../src/components/Combobox/use-combobox/use-combobox.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { findElementBySelector, findElementsBySelector, getRootElement } from '../../../core/utils';\nimport { getFirstIndex, getNextIndex, getPreviousIndex } from './get-index/get-index';\n\nexport type ComboboxDropdownEventSource = 'keyboard' | 'mouse' | 'unknown';\n\nexport interface ComboboxStore {\n /** Current dropdown opened state */\n dropdownOpened: boolean;\n\n /** Opens dropdown */\n openDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Closes dropdown */\n closeDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Toggles dropdown opened state */\n toggleDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Selected option index ref */\n selectedOptionIndex: number;\n\n /** Returns currently selected option index or `-1` if none of the options is selected */\n getSelectedOptionIndex: () => number;\n\n /** Selects `Combobox.Option` by index */\n selectOption: (index: number) => void;\n\n /** Selects first `Combobox.Option` with `active` prop.\n * If there are no such options, the function does nothing.\n */\n selectActiveOption: () => string | null;\n\n /** Selects first `Combobox.Option` that is not disabled.\n * If there are no such options, the function does nothing.\n * */\n selectFirstOption: () => string | null;\n\n /** Selects next `Combobox.Option` that is not disabled.\n * If the current option is the last one, the function selects first option, if `loop` is true.\n */\n selectNextOption: () => string | null;\n\n /** Selects previous `Combobox.Option` that is not disabled.\n * If the current option is the first one, the function selects last option, if `loop` is true.\n * */\n selectPreviousOption: () => string | null;\n\n /** Resets selected option index to -1, removes `data-combobox-selected` from selected option */\n resetSelectedOption: () => void;\n\n /** Triggers `onClick` event of selected option.\n * If there is no selected option, the function does nothing.\n */\n clickSelectedOption: () => void;\n\n /** Updates selected option index to currently selected or active option.\n * The function is required to be used with searchable components to update selected option index\n * when options list changes based on search query.\n */\n updateSelectedOptionIndex: (\n target?: 'active' | 'selected' | number,\n options?: { scrollIntoView?: boolean }\n ) => void;\n\n /** List id, used for `aria-*` attributes */\n listId: string | null;\n\n /** Sets list id */\n setListId: (id: string) => void;\n\n /** Ref of `Combobox.Search` input */\n searchRef: React.RefObject<HTMLInputElement | null>;\n\n /** Moves focus to `Combobox.Search` input */\n focusSearchInput: () => void;\n\n /** Ref of the target element */\n targetRef: React.RefObject<HTMLElement | null>;\n\n /** Moves focus to the target element */\n focusTarget: () => void;\n}\n\nexport interface UseComboboxOptions {\n /** Default value for `dropdownOpened`, `false` by default. Used when the component is uncontrolled */\n defaultOpened?: boolean;\n\n /** Controlled `dropdownOpened` state. When set, the dropdown opened state is controlled by the parent component */\n opened?: boolean;\n\n /** Called when `dropdownOpened` state changes. Required for controlled mode */\n onOpenedChange?: (opened: boolean) => void;\n\n /** Called when dropdown closes with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown closure */\n onDropdownClose?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Called when dropdown opens with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown opening */\n onDropdownOpen?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Determines whether arrow key presses should loop through items (first to last and last to first). Defaults to `true` */\n loop?: boolean;\n\n /** `behavior` passed down to `element.scrollIntoView`. Controls the scrolling animation when options are scrolled into view. Defaults to `'instant'` */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function useCombobox({\n defaultOpened,\n opened,\n onOpenedChange,\n onDropdownClose,\n onDropdownOpen,\n loop = true,\n scrollBehavior = 'instant',\n}: UseComboboxOptions = {}): ComboboxStore {\n const [dropdownOpened, setDropdownOpened] = useUncontrolled({\n value: opened,\n defaultValue: defaultOpened,\n finalValue: false,\n onChange: onOpenedChange,\n });\n\n const listId = useRef<string | null>(null);\n const selectedOptionIndex = useRef<number>(-1);\n const searchRef = useRef<HTMLInputElement | null>(null);\n const targetRef = useRef<HTMLElement | null>(null);\n const focusSearchTimeout = useRef<number>(-1);\n const focusTargetTimeout = useRef<number>(-1);\n const selectedIndexUpdateTimeout = useRef<number>(-1);\n\n const openDropdown: ComboboxStore['openDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (!dropdownOpened) {\n setDropdownOpened(true);\n onDropdownOpen?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownOpen, dropdownOpened]\n );\n\n const closeDropdown: ComboboxStore['closeDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n setDropdownOpened(false);\n onDropdownClose?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownClose, dropdownOpened]\n );\n\n const toggleDropdown: ComboboxStore['toggleDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n closeDropdown(eventSource);\n } else {\n openDropdown(eventSource);\n }\n },\n [closeDropdown, openDropdown, dropdownOpened]\n );\n\n const clearSelectedItem = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const selected = findElementBySelector(`#${listId.current} [data-combobox-selected]`, root);\n selected?.removeAttribute('data-combobox-selected');\n selected?.removeAttribute('aria-selected');\n }, []);\n\n const selectOption = useCallback(\n (index: number) => {\n const root = getRootElement(targetRef.current);\n const list = findElementBySelector(`#${listId.current!}`, root);\n const items = list\n ? findElementsBySelector<HTMLDivElement>('[data-combobox-option]', list)\n : null;\n\n if (!items) {\n return null;\n }\n\n const nextIndex = index >= items!.length ? 0 : index < 0 ? items!.length - 1 : index;\n selectedOptionIndex.current = nextIndex;\n\n if (items?.[nextIndex] && !items[nextIndex].hasAttribute('data-combobox-disabled')) {\n clearSelectedItem();\n items[nextIndex].setAttribute('data-combobox-selected', 'true');\n items[nextIndex].setAttribute('aria-selected', 'true');\n items[nextIndex].scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n return items[nextIndex].id;\n }\n\n return null;\n },\n [scrollBehavior, clearSelectedItem]\n );\n\n const selectActiveOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const activeOption = findElementBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-active]`,\n root\n );\n\n if (activeOption) {\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option === activeOption);\n return selectOption(index);\n }\n\n return selectOption(0);\n }, [selectOption]);\n\n const selectNextOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getNextIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectPreviousOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getPreviousIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectFirstOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getFirstIndex(items));\n }, [selectOption]);\n\n const updateSelectedOptionIndex: ComboboxStore['updateSelectedOptionIndex'] = useCallback(\n (target = 'selected', options) => {\n if (typeof target === 'number') {\n selectedOptionIndex.current = target;\n const root = getRootElement(targetRef.current);\n\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n\n if (options?.scrollIntoView) {\n items[target]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n return;\n }\n\n selectedIndexUpdateTimeout.current = window.setTimeout(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option.hasAttribute(`data-combobox-${target}`));\n\n selectedOptionIndex.current = index;\n\n if (options?.scrollIntoView) {\n items[index]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n }, 0);\n },\n []\n );\n\n const resetSelectedOption = useCallback(() => {\n selectedOptionIndex.current = -1;\n clearSelectedItem();\n }, [clearSelectedItem]);\n\n const clickSelectedOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const item = items?.[selectedOptionIndex.current];\n item?.click();\n }, []);\n\n const setListId = useCallback((id: string) => {\n listId.current = id;\n }, []);\n\n const focusSearchInput = useCallback(() => {\n focusSearchTimeout.current = window.setTimeout(() => searchRef.current?.focus(), 0);\n }, []);\n\n const focusTarget = useCallback(() => {\n focusTargetTimeout.current = window.setTimeout(() => targetRef.current?.focus(), 0);\n }, []);\n\n const getSelectedOptionIndex = useCallback(() => selectedOptionIndex.current, []);\n\n useEffect(\n () => () => {\n window.clearTimeout(focusSearchTimeout.current);\n window.clearTimeout(focusTargetTimeout.current);\n window.clearTimeout(selectedIndexUpdateTimeout.current);\n },\n []\n );\n\n return {\n dropdownOpened,\n openDropdown,\n closeDropdown,\n toggleDropdown,\n\n selectedOptionIndex: selectedOptionIndex.current,\n getSelectedOptionIndex,\n selectOption,\n selectFirstOption,\n selectActiveOption,\n selectNextOption,\n selectPreviousOption,\n resetSelectedOption,\n updateSelectedOptionIndex,\n\n listId: listId.current,\n setListId,\n clickSelectedOption,\n\n searchRef,\n focusSearchInput,\n\n targetRef,\n focusTarget,\n };\n}\n"],"mappings":";;;;;;AA4GA,SAAgB,YAAY,EAC1B,eACA,QACA,gBACA,iBACA,gBACA,OAAO,MACP,iBAAiB,cACK,CAAC,GAAkB;CACzC,MAAM,CAAC,gBAAgB,qBAAqB,gBAAgB;EAC1D,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU;CACZ,CAAC;CAED,MAAM,SAAS,OAAsB,IAAI;CACzC,MAAM,sBAAsB,OAAe,EAAE;CAC7C,MAAM,YAAY,OAAgC,IAAI;CACtD,MAAM,YAAY,OAA2B,IAAI;CACjD,MAAM,qBAAqB,OAAe,EAAE;CAC5C,MAAM,qBAAqB,OAAe,EAAE;CAC5C,MAAM,6BAA6B,OAAe,EAAE;CAEpD,MAAM,eAA8C,aACjD,cAAc,cAAc;EAC3B,IAAI,CAAC,gBAAgB;GACnB,kBAAkB,IAAI;GACtB,iBAAiB,WAAW;EAC9B;CACF,GACA;EAAC;EAAmB;EAAgB;CAAc,CACpD;CAEA,MAAM,gBAAgD,aACnD,cAAc,cAAc;EAC3B,IAAI,gBAAgB;GAClB,kBAAkB,KAAK;GACvB,kBAAkB,WAAW;EAC/B;CACF,GACA;EAAC;EAAmB;EAAiB;CAAc,CACrD;CAEA,MAAM,iBAAkD,aACrD,cAAc,cAAc;EAC3B,IAAI,gBACF,cAAc,WAAW;OAEzB,aAAa,WAAW;CAE5B,GACA;EAAC;EAAe;EAAc;CAAc,CAC9C;CAEA,MAAM,oBAAoB,kBAAkB;EAC1C,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,WAAW,sBAAsB,IAAI,OAAO,QAAQ,4BAA4B,IAAI;EAC1F,UAAU,gBAAgB,wBAAwB;EAClD,UAAU,gBAAgB,eAAe;CAC3C,GAAG,CAAC,CAAC;CAEL,MAAM,eAAe,aAClB,UAAkB;EACjB,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,OAAO,sBAAsB,IAAI,OAAO,WAAY,IAAI;EAC9D,MAAM,QAAQ,OACV,uBAAuC,0BAA0B,IAAI,IACrE;EAEJ,IAAI,CAAC,OACH,OAAO;EAGT,MAAM,YAAY,SAAS,MAAO,SAAS,IAAI,QAAQ,IAAI,MAAO,SAAS,IAAI;EAC/E,oBAAoB,UAAU;EAE9B,IAAI,QAAQ,cAAc,CAAC,MAAM,UAAU,CAAC,aAAa,wBAAwB,GAAG;GAClF,kBAAkB;GAClB,MAAM,UAAU,CAAC,aAAa,0BAA0B,MAAM;GAC9D,MAAM,UAAU,CAAC,aAAa,iBAAiB,MAAM;GACrD,MAAM,UAAU,CAAC,eAAe;IAAE,OAAO;IAAW,UAAU;GAAe,CAAC;GAC9E,OAAO,MAAM,UAAU,CAAC;EAC1B;EAEA,OAAO;CACT,GACA,CAAC,gBAAgB,iBAAiB,CACpC;CAEA,MAAM,qBAAqB,kBAAkB;EAC3C,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,eAAe,sBACnB,IAAI,OAAO,QAAQ,0BACnB,IACF;EAEA,IAAI,cAAc;GAKhB,MAAM,QAJQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IAEgB,CAAC,CAAC,WAAW,WAAW,WAAW,YAAY;GACjE,OAAO,aAAa,KAAK;EAC3B;EAEA,OAAO,aAAa,CAAC;CACvB,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,mBAAmB,kBAAkB;EACzC,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,QAAQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IACF;EACA,OAAO,aAAa,aAAa,oBAAoB,SAAS,OAAO,IAAI,CAAC;CAC5E,GAAG,CAAC,cAAc,IAAI,CAAC;CAEvB,MAAM,uBAAuB,kBAAkB;EAC7C,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,QAAQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IACF;EACA,OAAO,aAAa,iBAAiB,oBAAoB,SAAS,OAAO,IAAI,CAAC;CAChF,GAAG,CAAC,cAAc,IAAI,CAAC;CAEvB,MAAM,oBAAoB,kBAAkB;EAC1C,MAAM,OAAO,eAAe,UAAU,OAAO;EAC7C,MAAM,QAAQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IACF;EACA,OAAO,aAAa,cAAc,KAAK,CAAC;CAC1C,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,4BAAwE,aAC3E,SAAS,YAAY,YAAY;EAChC,IAAI,OAAO,WAAW,UAAU;GAC9B,oBAAoB,UAAU;GAC9B,MAAM,OAAO,eAAe,UAAU,OAAO;GAE7C,MAAM,QAAQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IACF;GAEA,IAAI,SAAS,gBACX,MAAM,OAAO,EAAE,eAAe;IAAE,OAAO;IAAW,UAAU;GAAe,CAAC;GAE9E;EACF;EAEA,2BAA2B,UAAU,OAAO,iBAAiB;GAC3D,MAAM,OAAO,eAAe,UAAU,OAAO;GAC7C,MAAM,QAAQ,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IACF;GACA,MAAM,QAAQ,MAAM,WAAW,WAAW,OAAO,aAAa,iBAAiB,QAAQ,CAAC;GAExF,oBAAoB,UAAU;GAE9B,IAAI,SAAS,gBACX,MAAM,MAAM,EAAE,eAAe;IAAE,OAAO;IAAW,UAAU;GAAe,CAAC;EAE/E,GAAG,CAAC;CACN,GACA,CAAC,CACH;CAEA,MAAM,sBAAsB,kBAAkB;EAC5C,oBAAoB,UAAU;EAC9B,kBAAkB;CACpB,GAAG,CAAC,iBAAiB,CAAC;CAEtB,MAAM,sBAAsB,kBAAkB;EAC5C,MAAM,OAAO,eAAe,UAAU,OAAO;EAM7C,CALc,uBACZ,IAAI,OAAO,QAAQ,0BACnB,IAEe,CAAC,GAAG,oBAAoB,SAAA,EACnC,MAAM;CACd,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,aAAa,OAAe;EAC5C,OAAO,UAAU;CACnB,GAAG,CAAC,CAAC;CAEL,MAAM,mBAAmB,kBAAkB;EACzC,mBAAmB,UAAU,OAAO,iBAAiB,UAAU,SAAS,MAAM,GAAG,CAAC;CACpF,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,kBAAkB;EACpC,mBAAmB,UAAU,OAAO,iBAAiB,UAAU,SAAS,MAAM,GAAG,CAAC;CACpF,GAAG,CAAC,CAAC;CAEL,MAAM,yBAAyB,kBAAkB,oBAAoB,SAAS,CAAC,CAAC;CAEhF,sBACc;EACV,OAAO,aAAa,mBAAmB,OAAO;EAC9C,OAAO,aAAa,mBAAmB,OAAO;EAC9C,OAAO,aAAa,2BAA2B,OAAO;CACxD,GACA,CAAC,CACH;CAEA,OAAO;EACL;EACA;EACA;EACA;EAEA,qBAAqB,oBAAoB;EACzC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,QAAQ,OAAO;EACf;EACA;EAEA;EACA;EAEA;EACA;CACF;AACF"}
@@ -146,7 +146,8 @@ const ComboboxPopover = genericFactory((_props) => {
146
146
  else setValue([...currentValue, option.value]);
147
147
  combobox.updateSelectedOptionIndex("selected");
148
148
  } else {
149
- setValue(allowDeselect && `${option.value}` === `${_value}` ? null : option.value);
149
+ const nextValue = allowDeselect && `${option.value}` === `${_value}` ? null : option.value;
150
+ setValue(nextValue);
150
151
  combobox.closeDropdown();
151
152
  }
152
153
  if (searchable) handleSearchChange("");