flikkui 0.2.0-beta.2 → 0.2.0-beta.5

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 (269) hide show
  1. package/README.md +92 -0
  2. package/dist/components/ai/PromptInput/PromptInput.js +23 -15
  3. package/dist/components/ai/PromptSuggestions/PromptSuggestion.d.ts +27 -0
  4. package/dist/components/ai/PromptSuggestions/PromptSuggestion.js +62 -0
  5. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.d.ts +10 -0
  6. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +12 -0
  7. package/dist/components/ai/PromptSuggestions/PromptSuggestion.types.d.ts +53 -0
  8. package/dist/components/ai/PromptSuggestions/index.d.ts +4 -2
  9. package/dist/components/ai/index.d.ts +2 -12
  10. package/dist/components/charts/ActivityRings/ActivityRings.js +70 -58
  11. package/dist/components/charts/ActivityRings/ActivityRings.theme.js +0 -1
  12. package/dist/components/charts/ActivityRings/ActivityRings.types.d.ts +17 -0
  13. package/dist/components/charts/BarChart/BarChart.js +8 -4
  14. package/dist/components/charts/BarChart/BarChart.types.d.ts +14 -0
  15. package/dist/components/charts/DonutChart/DonutChart.js +11 -8
  16. package/dist/components/charts/DonutChart/DonutChart.theme.d.ts +3 -0
  17. package/dist/components/charts/DonutChart/DonutChart.theme.js +5 -4
  18. package/dist/components/charts/DonutChart/donut-utils.d.ts +5 -0
  19. package/dist/components/charts/DonutChart/donut-utils.js +26 -1
  20. package/dist/components/charts/Heatmap/Heatmap.theme.js +2 -2
  21. package/dist/components/charts/shared/ChartAxis/XAxis.d.ts +2 -2
  22. package/dist/components/charts/shared/ChartAxis/XAxis.js +4 -4
  23. package/dist/components/charts/shared/ChartAxis/YAxis.d.ts +2 -2
  24. package/dist/components/charts/shared/ChartAxis/YAxis.js +8 -7
  25. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +1 -1
  26. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +2 -2
  27. package/dist/components/charts/theme/chart.theme.d.ts +1 -1
  28. package/dist/components/charts/theme/chart.theme.js +39 -39
  29. package/dist/components/core/Accordion/Accordion.d.ts +1 -1
  30. package/dist/components/core/Accordion/Accordion.js +2 -2
  31. package/dist/components/core/Accordion/Accordion.types.d.ts +8 -0
  32. package/dist/components/core/Badge/Badge.js +11 -15
  33. package/dist/components/core/Badge/Badge.theme.js +7 -21
  34. package/dist/components/core/Badge/Badge.types.d.ts +9 -1
  35. package/dist/components/core/Button/Button.js +2 -2
  36. package/dist/components/core/Button/Button.theme.js +1 -1
  37. package/dist/components/core/Button/Button.types.d.ts +8 -0
  38. package/dist/components/core/Card/Card.js +8 -2
  39. package/dist/components/core/Card/Card.theme.js +1 -1
  40. package/dist/components/core/Card/Card.types.d.ts +24 -1
  41. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  42. package/dist/components/core/Drawer/Drawer.js +10 -40
  43. package/dist/components/core/Drawer/Drawer.theme.js +2 -1
  44. package/dist/components/core/Drawer/Drawer.types.d.ts +8 -0
  45. package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
  46. package/dist/components/core/Dropdown/Dropdown.js +2 -2
  47. package/dist/components/core/Dropdown/Dropdown.types.d.ts +8 -0
  48. package/dist/components/core/Metric/Metric.d.ts +1 -1
  49. package/dist/components/core/Metric/Metric.js +9 -5
  50. package/dist/components/core/Metric/Metric.theme.d.ts +1 -1
  51. package/dist/components/core/Metric/Metric.theme.js +38 -28
  52. package/dist/components/core/Metric/Metric.types.d.ts +27 -8
  53. package/dist/components/core/Modal/Modal.d.ts +1 -1
  54. package/dist/components/core/Modal/Modal.js +17 -40
  55. package/dist/components/core/Modal/Modal.theme.js +8 -3
  56. package/dist/components/core/Modal/Modal.types.d.ts +18 -0
  57. package/dist/components/core/Modal/index.d.ts +1 -1
  58. package/dist/components/core/Notification/Notification.js +2 -0
  59. package/dist/components/core/Pill/Pill.d.ts +6 -11
  60. package/dist/components/core/Pill/Pill.theme.d.ts +2 -2
  61. package/dist/components/core/Pill/Pill.types.d.ts +9 -22
  62. package/dist/components/core/Pill/index.d.ts +1 -1
  63. package/dist/components/core/Popover/Popover.d.ts +1 -1
  64. package/dist/components/core/Popover/Popover.js +2 -2
  65. package/dist/components/core/Popover/Popover.types.d.ts +8 -0
  66. package/dist/components/core/Progress/Progress.d.ts +28 -0
  67. package/dist/components/core/Progress/Progress.js +114 -0
  68. package/dist/components/core/Progress/Progress.theme.d.ts +5 -0
  69. package/dist/components/core/Progress/Progress.theme.js +33 -0
  70. package/dist/components/core/Progress/Progress.types.d.ts +92 -0
  71. package/dist/components/core/Progress/index.d.ts +2 -0
  72. package/dist/components/core/Table/Table.animations.d.ts +5 -16
  73. package/dist/components/core/Table/Table.animations.js +46 -0
  74. package/dist/components/core/Table/Table.d.ts +0 -27
  75. package/dist/components/core/Table/Table.js +58 -156
  76. package/dist/components/core/Table/Table.theme.js +28 -19
  77. package/dist/components/core/Table/Table.types.d.ts +95 -8
  78. package/dist/components/core/Table/Table.utils.d.ts +7 -0
  79. package/dist/components/core/Table/Table.utils.js +11 -1
  80. package/dist/components/core/Table/{components/TableActions/TableActions.d.ts → TableActions.d.ts} +3 -3
  81. package/dist/components/core/Table/{components/TableActions/TableActions.js → TableActions.js} +14 -24
  82. package/dist/components/core/Table/{components/TableActions/TableActionsMenu.d.ts → TableActionsMenu.d.ts} +1 -1
  83. package/dist/components/core/Table/{components/TableActions/TableActionsMenu.js → TableActionsMenu.js} +4 -4
  84. package/dist/components/core/Table/{components/core/TableBody.d.ts → TableBody.d.ts} +1 -1
  85. package/dist/components/core/Table/{components/core/TableBody.js → TableBody.js} +14 -20
  86. package/dist/components/core/Table/{components/core/TableCell.d.ts → TableCell.d.ts} +1 -9
  87. package/dist/components/core/Table/{components/core/TableCell.js → TableCell.js} +5 -13
  88. package/dist/components/core/Table/TableColumnManager.d.ts +3 -0
  89. package/dist/components/core/Table/TableColumnManager.js +34 -0
  90. package/dist/components/core/Table/{components/DeclarativeComponents.d.ts → TableDeclarative.d.ts} +1 -1
  91. package/dist/components/core/Table/{components/DeclarativeComponents.js → TableDeclarative.js} +6 -56
  92. package/dist/components/core/Table/TableFilter.d.ts +3 -0
  93. package/dist/components/core/Table/TableFilter.js +122 -0
  94. package/dist/components/core/Table/{components/core/TableHeader.d.ts → TableHeader.d.ts} +1 -1
  95. package/dist/components/core/Table/{components/core/TableHeader.js → TableHeader.js} +15 -29
  96. package/dist/components/core/Table/TablePagination.d.ts +7 -0
  97. package/dist/components/core/Table/{components/TablePagination/TablePagination.js → TablePagination.js} +5 -16
  98. package/dist/components/core/Table/TableRow.d.ts +8 -0
  99. package/dist/components/core/Table/TableRow.js +45 -0
  100. package/dist/components/core/Table/TableSelectionHeader.d.ts +7 -0
  101. package/dist/components/core/Table/{components/TableSelectionHeader/TableSelectionHeader.js → TableSelectionHeader.js} +4 -5
  102. package/dist/components/core/Table/hooks/index.d.ts +10 -0
  103. package/dist/components/core/Table/hooks/useTableColumns.d.ts +16 -0
  104. package/dist/components/core/Table/hooks/useTableColumns.js +67 -0
  105. package/dist/components/core/Table/hooks/useTableExpansion.d.ts +8 -0
  106. package/dist/components/core/Table/hooks/useTableExpansion.js +15 -0
  107. package/dist/components/core/Table/hooks/useTableFilter.d.ts +12 -0
  108. package/dist/components/core/Table/hooks/useTableFilter.js +37 -0
  109. package/dist/components/core/Table/hooks/useTablePagination.d.ts +12 -0
  110. package/dist/components/core/Table/hooks/useTablePagination.js +13 -0
  111. package/dist/components/core/Table/hooks/useTableSelection.d.ts +17 -0
  112. package/dist/components/core/Table/hooks/useTableSelection.js +40 -0
  113. package/dist/components/core/Table/index.d.ts +9 -8
  114. package/dist/components/core/Table/index.js +7 -5
  115. package/dist/components/core/Tabs/Tabs.js +2 -2
  116. package/dist/components/core/Tabs/Tabs.types.d.ts +8 -0
  117. package/dist/components/core/Tag/Tag.animations.d.ts +3 -0
  118. package/dist/components/core/Tag/Tag.animations.js +31 -0
  119. package/dist/components/core/Tag/Tag.d.ts +14 -0
  120. package/dist/components/core/Tag/Tag.js +45 -0
  121. package/dist/components/core/Tag/Tag.theme.d.ts +2 -0
  122. package/dist/components/core/Tag/Tag.theme.js +21 -0
  123. package/dist/components/core/Tag/Tag.types.d.ts +40 -0
  124. package/dist/components/core/Tag/index.d.ts +3 -0
  125. package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
  126. package/dist/components/core/Tooltip/Tooltip.js +3 -3
  127. package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
  128. package/dist/components/core/Tooltip/Tooltip.types.d.ts +17 -0
  129. package/dist/components/core/index.d.ts +2 -1
  130. package/dist/components/core/index.js +12 -5
  131. package/dist/components/effects/CustomCursor/CustomCursor.d.ts +0 -13
  132. package/dist/components/effects/CustomCursor/CustomCursor.js +26 -2
  133. package/dist/components/effects/CustomCursor/CustomCursor.theme.js +12 -1
  134. package/dist/components/effects/CustomCursor/CustomCursor.types.d.ts +14 -1
  135. package/dist/components/forms/Combobox/Combobox.d.ts +25 -0
  136. package/dist/components/forms/Combobox/Combobox.js +412 -0
  137. package/dist/components/forms/Combobox/Combobox.theme.d.ts +6 -0
  138. package/dist/components/forms/Combobox/Combobox.theme.js +60 -0
  139. package/dist/components/forms/Combobox/Combobox.types.d.ts +111 -0
  140. package/dist/components/forms/Combobox/index.d.ts +3 -0
  141. package/dist/components/forms/FileUpload/FileUpload.js +2 -0
  142. package/dist/components/forms/Input/Input.js +25 -28
  143. package/dist/components/forms/Input/inputMasks.d.ts +15 -0
  144. package/dist/components/forms/Input/inputMasks.js +72 -1
  145. package/dist/components/forms/InputTag/InputTag.d.ts +40 -0
  146. package/dist/components/forms/InputTag/InputTag.js +491 -0
  147. package/dist/components/forms/InputTag/InputTag.theme.d.ts +2 -0
  148. package/dist/components/forms/InputTag/InputTag.theme.js +16 -0
  149. package/dist/components/forms/InputTag/InputTag.types.d.ts +107 -0
  150. package/dist/components/forms/InputTag/index.d.ts +3 -0
  151. package/dist/components/forms/Select/Select.d.ts +101 -2
  152. package/dist/components/forms/Select/Select.js +128 -132
  153. package/dist/components/forms/Select/Select.theme.js +10 -14
  154. package/dist/components/forms/Select/Select.types.d.ts +6 -2
  155. package/dist/components/forms/Select/index.d.ts +7 -4
  156. package/dist/components/forms/Select/useSelectState.d.ts +66 -0
  157. package/dist/components/forms/Select/useSelectState.js +134 -0
  158. package/dist/components/forms/SelectExpand/SelectExpand.animations.d.ts +20 -0
  159. package/dist/components/forms/SelectExpand/SelectExpand.animations.js +74 -0
  160. package/dist/components/forms/SelectExpand/SelectExpand.d.ts +9 -0
  161. package/dist/components/forms/SelectExpand/SelectExpand.js +223 -0
  162. package/dist/components/forms/SelectExpand/SelectExpand.theme.d.ts +5 -0
  163. package/dist/components/forms/SelectExpand/SelectExpand.theme.js +74 -0
  164. package/dist/components/forms/SelectExpand/SelectExpand.types.d.ts +126 -0
  165. package/dist/components/forms/SelectExpand/index.d.ts +4 -0
  166. package/dist/components/forms/Switch/Switch.js +3 -3
  167. package/dist/components/forms/Switch/Switch.theme.d.ts +1 -1
  168. package/dist/components/forms/Switch/Switch.theme.js +2 -2
  169. package/dist/components/forms/TimePicker/TimePicker.animations.d.ts +0 -46
  170. package/dist/components/forms/TimePicker/TimePicker.d.ts +15 -6
  171. package/dist/components/forms/TimePicker/TimePicker.js +285 -124
  172. package/dist/components/forms/TimePicker/TimePicker.theme.d.ts +1 -1
  173. package/dist/components/forms/TimePicker/TimePicker.theme.js +39 -22
  174. package/dist/components/forms/TimePicker/TimePicker.types.d.ts +88 -34
  175. package/dist/components/forms/TimePicker/TimePickerContent.d.ts +7 -10
  176. package/dist/components/forms/TimePicker/TimePickerContent.js +149 -16
  177. package/dist/components/forms/TimePicker/TimePickerTrigger.d.ts +3 -3
  178. package/dist/components/forms/TimePicker/TimePickerTrigger.js +22 -19
  179. package/dist/components/forms/TimePicker/WheelColumn.d.ts +14 -0
  180. package/dist/components/forms/TimePicker/WheelColumn.js +90 -0
  181. package/dist/components/forms/TimePicker/index.d.ts +4 -1
  182. package/dist/components/forms/TimePicker/useWheelPicker.d.ts +37 -0
  183. package/dist/components/forms/TimePicker/useWheelPicker.js +138 -0
  184. package/dist/components/forms/forms.theme.d.ts +14 -0
  185. package/dist/components/forms/forms.theme.js +31 -0
  186. package/dist/components/forms/index.d.ts +9 -3
  187. package/dist/components/forms/index.js +73 -2
  188. package/dist/hooks/index.d.ts +0 -4
  189. package/dist/icons/Icon.d.ts +7 -0
  190. package/dist/icons/Icon.js +6 -2
  191. package/dist/index.js +21 -19
  192. package/dist/styles.css +1 -1
  193. package/dist/utils/index.d.ts +0 -1
  194. package/dist/utils/optimisticErrors.js +1 -70
  195. package/package.json +1 -1
  196. package/dist/components/ai/EditingIndicator/EditingIndicator.animations.d.ts +0 -31
  197. package/dist/components/ai/EditingIndicator/EditingIndicator.animations.js +0 -115
  198. package/dist/components/ai/EditingIndicator/EditingIndicator.d.ts +0 -35
  199. package/dist/components/ai/EditingIndicator/EditingIndicator.js +0 -94
  200. package/dist/components/ai/EditingIndicator/EditingIndicator.theme.d.ts +0 -2
  201. package/dist/components/ai/EditingIndicator/EditingIndicator.theme.js +0 -13
  202. package/dist/components/ai/EditingIndicator/EditingIndicator.types.d.ts +0 -54
  203. package/dist/components/ai/EditingIndicator/index.d.ts +0 -9
  204. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.d.ts +0 -3
  205. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.js +0 -126
  206. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.d.ts +0 -2
  207. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.js +0 -8
  208. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.types.d.ts +0 -45
  209. package/dist/components/ai/GenerativeRenderer/index.d.ts +0 -3
  210. package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.d.ts +0 -17
  211. package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.js +0 -56
  212. package/dist/components/ai/PresenceIndicator/PresenceIndicator.d.ts +0 -38
  213. package/dist/components/ai/PresenceIndicator/PresenceIndicator.js +0 -110
  214. package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.d.ts +0 -2
  215. package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.js +0 -13
  216. package/dist/components/ai/PresenceIndicator/PresenceIndicator.types.d.ts +0 -53
  217. package/dist/components/ai/PresenceIndicator/index.d.ts +0 -8
  218. package/dist/components/ai/PresenceProvider/PresenceContext.d.ts +0 -24
  219. package/dist/components/ai/PresenceProvider/PresenceContext.js +0 -34
  220. package/dist/components/ai/PresenceProvider/PresenceProvider.d.ts +0 -32
  221. package/dist/components/ai/PresenceProvider/PresenceProvider.js +0 -321
  222. package/dist/components/ai/PresenceProvider/PresenceProvider.types.d.ts +0 -140
  223. package/dist/components/ai/PresenceProvider/adapters/MockAdapter.d.ts +0 -102
  224. package/dist/components/ai/PresenceProvider/adapters/MockAdapter.js +0 -331
  225. package/dist/components/ai/PresenceProvider/adapters/PresenceAdapter.d.ts +0 -93
  226. package/dist/components/ai/PresenceProvider/adapters/SupabaseAdapter.d.ts +0 -134
  227. package/dist/components/ai/PresenceProvider/adapters/WebSocketAdapter.d.ts +0 -149
  228. package/dist/components/ai/PresenceProvider/adapters/index.d.ts +0 -11
  229. package/dist/components/ai/PresenceProvider/index.d.ts +0 -10
  230. package/dist/components/ai/PromptSuggestions/PromptSuggestions.d.ts +0 -27
  231. package/dist/components/ai/PromptSuggestions/PromptSuggestions.js +0 -61
  232. package/dist/components/ai/PromptSuggestions/PromptSuggestions.types.d.ts +0 -65
  233. package/dist/components/ai/VersionSlider/VersionSlider.d.ts +0 -3
  234. package/dist/components/ai/VersionSlider/VersionSlider.js +0 -97
  235. package/dist/components/ai/VersionSlider/VersionSlider.theme.d.ts +0 -2
  236. package/dist/components/ai/VersionSlider/VersionSlider.theme.js +0 -18
  237. package/dist/components/ai/VersionSlider/VersionSlider.types.d.ts +0 -77
  238. package/dist/components/ai/VersionSlider/index.d.ts +0 -3
  239. package/dist/components/core/Pill/Pill.animations.js +0 -25
  240. package/dist/components/core/Pill/Pill.js +0 -145
  241. package/dist/components/core/Pill/Pill.theme.js +0 -65
  242. package/dist/components/core/RetryBoundary/RetryBoundary.d.ts +0 -35
  243. package/dist/components/core/RetryBoundary/RetryBoundary.js +0 -154
  244. package/dist/components/core/RetryBoundary/RetryBoundary.theme.d.ts +0 -2
  245. package/dist/components/core/RetryBoundary/RetryBoundary.theme.js +0 -7
  246. package/dist/components/core/RetryBoundary/RetryBoundary.types.d.ts +0 -51
  247. package/dist/components/core/RetryBoundary/index.d.ts +0 -3
  248. package/dist/components/core/Table/components/TableActions/TableActions.types.d.ts +0 -40
  249. package/dist/components/core/Table/components/TableActions/index.d.ts +0 -3
  250. package/dist/components/core/Table/components/TableActionsMenu.d.ts +0 -6
  251. package/dist/components/core/Table/components/TablePagination/TablePagination.d.ts +0 -17
  252. package/dist/components/core/Table/components/TablePagination/TablePagination.types.d.ts +0 -21
  253. package/dist/components/core/Table/components/TablePagination/index.d.ts +0 -2
  254. package/dist/components/core/Table/components/TableSelectionHeader/TableSelectionHeader.d.ts +0 -15
  255. package/dist/components/core/Table/components/TableSelectionHeader/index.d.ts +0 -3
  256. package/dist/components/core/Table/components/core/TableRow.d.ts +0 -3
  257. package/dist/components/core/Table/components/core/TableRow.js +0 -44
  258. package/dist/components/core/Table/components/core/index.d.ts +0 -4
  259. package/dist/components/forms/OptimisticForm/OptimisticForm.d.ts +0 -33
  260. package/dist/components/forms/OptimisticForm/OptimisticForm.js +0 -87
  261. package/dist/components/forms/OptimisticForm/OptimisticForm.theme.d.ts +0 -2
  262. package/dist/components/forms/OptimisticForm/OptimisticForm.theme.js +0 -8
  263. package/dist/components/forms/OptimisticForm/OptimisticForm.types.d.ts +0 -74
  264. package/dist/components/forms/OptimisticForm/index.d.ts +0 -3
  265. package/dist/hooks/useOptimisticMutation.d.ts +0 -109
  266. package/dist/hooks/useOptimisticMutation.js +0 -171
  267. package/dist/hooks/usePresence.d.ts +0 -88
  268. package/dist/utils/presenceUtils.d.ts +0 -66
  269. package/dist/utils/presenceUtils.js +0 -107
@@ -1,18 +1,117 @@
1
1
  import React from "react";
2
- import type { SelectProps, SelectButtonProps, SelectOptionsProps, SelectOptionProps } from "./Select.types";
2
+ import type { SelectProps, SelectButtonProps, SelectOptionsProps, SelectOptionProps, SelectState, SelectSize, SelectThemeOverrides } from "./Select.types";
3
+ import { useSelectState, type UseSelectStateReturn, type UseSelectStateProps } from "./useSelectState";
4
+ /**
5
+ * Context value type for Select components
6
+ * Extends UseSelectStateReturn with additional component-specific properties
7
+ */
8
+ export interface SelectContextValue<T = any> extends UseSelectStateReturn<T> {
9
+ /** Size variant */
10
+ size: SelectSize;
11
+ /** Component state (default, disabled) */
12
+ state: SelectState;
13
+ /** Theme configuration */
14
+ theme: SelectThemeOverrides;
15
+ /** Whether search is enabled */
16
+ searchable: boolean;
17
+ /** Whether typeahead is enabled */
18
+ enableTypeahead: boolean;
19
+ /** Button ref (alias for triggerRef for backward compatibility) */
20
+ buttonRef: React.MutableRefObject<HTMLButtonElement | null>;
21
+ }
22
+ /**
23
+ * SelectContext - exported for external consumption
24
+ */
25
+ export declare const SelectContext: React.Context<SelectContextValue<any> | undefined>;
26
+ /**
27
+ * useSelectContext - Hook to consume SelectContext
28
+ * Throws if used outside of SelectProvider
29
+ */
30
+ export declare const useSelectContext: <T = any>() => SelectContextValue<T>;
31
+ /**
32
+ * Props for the SelectProvider component
33
+ */
34
+ export interface SelectProviderProps<T = any> {
35
+ /** Child components */
36
+ children: React.ReactNode;
37
+ /** State from useSelectState hook */
38
+ selectState: UseSelectStateReturn<T>;
39
+ /** Size variant */
40
+ size?: SelectSize;
41
+ /** Component state */
42
+ componentState?: SelectState;
43
+ /** Theme overrides */
44
+ theme?: SelectThemeOverrides;
45
+ /** Whether search is enabled */
46
+ searchable?: boolean;
47
+ /** Whether typeahead is enabled */
48
+ enableTypeahead?: boolean;
49
+ }
50
+ /**
51
+ * SelectProvider - Provides select context to children
52
+ *
53
+ * This component allows building custom dropdown components using Select primitives.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * const selectState = useSelectState({ options, value, onChange });
58
+ *
59
+ * <SelectProvider selectState={selectState} size="md">
60
+ * <MyCustomTrigger />
61
+ * <SelectOptions isOpen={selectState.isOpen}>
62
+ * {selectState.filteredOptions.map(option => (
63
+ * <SelectOption key={option.id} value={option.value}>
64
+ * {option.label}
65
+ * </SelectOption>
66
+ * ))}
67
+ * </SelectOptions>
68
+ * </SelectProvider>
69
+ * ```
70
+ */
71
+ export declare function SelectProvider<T = any>({ children, selectState, size, componentState, theme: themeOverrides, searchable, enableTypeahead, }: SelectProviderProps<T>): React.JSX.Element;
3
72
  /**
4
73
  * Select Button Component
5
74
  */
6
75
  export declare const SelectButton: React.FC<SelectButtonProps>;
76
+ /**
77
+ * Extended props for SelectOptions to support custom triggers
78
+ */
79
+ export interface SelectOptionsExtendedProps extends SelectOptionsProps {
80
+ /** Custom trigger ref - if provided, uses this instead of buttonRef from context */
81
+ triggerRef?: React.RefObject<HTMLElement>;
82
+ }
7
83
  /**
8
84
  * Select Options Component
9
85
  */
10
- export declare const SelectOptions: React.FC<SelectOptionsProps>;
86
+ export declare const SelectOptions: React.FC<SelectOptionsExtendedProps>;
11
87
  /**
12
88
  * Select Option Component
13
89
  */
14
90
  export declare const SelectOption: <T extends any>({ value, isSelected, disabled, className, onSelect, children, }: SelectOptionProps<T>) => React.JSX.Element;
15
91
  /**
16
92
  * Main Select Component
93
+ *
94
+ * A fully-featured select/dropdown component with support for:
95
+ * - Keyboard navigation
96
+ * - Search/filtering
97
+ * - Typeahead
98
+ * - Creatable options
99
+ * - Portal rendering
100
+ * - Custom theming
101
+ *
102
+ * @example
103
+ * ```tsx
104
+ * <Select
105
+ * options={[
106
+ * { id: "1", label: "Option 1", value: "option1" },
107
+ * { id: "2", label: "Option 2", value: "option2" },
108
+ * ]}
109
+ * value={selected}
110
+ * onChange={setSelected}
111
+ * placeholder="Select an option"
112
+ * />
113
+ * ```
17
114
  */
18
115
  export declare const Select: <T extends any>({ id, name, size, state, value, displayValue, placeholder, disabled, required, options, label, helperText, onChange, onFocus, onBlur, iconStart, iconEnd, theme: themeOverrides, className, wrapperClassName, searchable, searchPlaceholder, portal, placement, offset, enableTypeahead, creatable, onCreateOption, createLabel, children, }: SelectProps<T>) => React.JSX.Element;
116
+ export { useSelectState };
117
+ export type { UseSelectStateProps, UseSelectStateReturn };
@@ -1,4 +1,4 @@
1
- import React__default, { createContext, useState, useRef, useEffect, useContext } from 'react';
1
+ import React__default, { createContext, useRef, useCallback, useEffect, useContext } from 'react';
2
2
  import { AnimatePresence, motion } from 'motion/react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { selectTheme } from './Select.theme.js';
@@ -10,13 +10,17 @@ import { ChevronUpDownIcon } from '../../../icons/core/ChevronUpDown.js';
10
10
  import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
11
11
  import { cn } from '../../../utils/cn.js';
12
12
  import { isValidTypeaheadChar, findNextMatchingOption, TYPEAHEAD_TIMEOUT_MS } from '../../../utils/typeaheadUtils.js';
13
- import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
13
+ import { PlusIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline';
14
+ import { useSelectState } from './useSelectState.js';
14
15
 
16
+ // ============================================================================
17
+ // Dark Mode Hook
18
+ // ============================================================================
15
19
  /**
16
20
  * Hook to detect dark mode state from document
17
21
  */
18
22
  const useDarkMode = () => {
19
- const [isDark, setIsDark] = useState(false);
23
+ const [isDark, setIsDark] = React__default.useState(false);
20
24
  useEffect(() => {
21
25
  if (typeof document === "undefined")
22
26
  return;
@@ -41,14 +45,60 @@ const useDarkMode = () => {
41
45
  }, []);
42
46
  return isDark;
43
47
  };
48
+ /**
49
+ * SelectContext - exported for external consumption
50
+ */
44
51
  const SelectContext = createContext(undefined);
52
+ /**
53
+ * useSelectContext - Hook to consume SelectContext
54
+ * Throws if used outside of SelectProvider
55
+ */
45
56
  const useSelectContext = () => {
46
57
  const context = useContext(SelectContext);
47
58
  if (!context) {
48
- throw new Error("Select components must be used within a SelectContainer");
59
+ throw new Error("Select components must be used within a SelectProvider");
49
60
  }
50
61
  return context;
51
62
  };
63
+ /**
64
+ * SelectProvider - Provides select context to children
65
+ *
66
+ * This component allows building custom dropdown components using Select primitives.
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * const selectState = useSelectState({ options, value, onChange });
71
+ *
72
+ * <SelectProvider selectState={selectState} size="md">
73
+ * <MyCustomTrigger />
74
+ * <SelectOptions isOpen={selectState.isOpen}>
75
+ * {selectState.filteredOptions.map(option => (
76
+ * <SelectOption key={option.id} value={option.value}>
77
+ * {option.label}
78
+ * </SelectOption>
79
+ * ))}
80
+ * </SelectOptions>
81
+ * </SelectProvider>
82
+ * ```
83
+ */
84
+ function SelectProvider({ children, selectState, size = "md", componentState = "default", theme: themeOverrides, searchable = false, enableTypeahead = true, }) {
85
+ const theme = { ...selectTheme, ...(themeOverrides || {}) };
86
+ // Cast triggerRef to buttonRef for backward compatibility
87
+ const buttonRef = selectState.triggerRef;
88
+ const contextValue = {
89
+ ...selectState,
90
+ size,
91
+ state: componentState,
92
+ theme,
93
+ searchable,
94
+ enableTypeahead,
95
+ buttonRef,
96
+ };
97
+ return (React__default.createElement(SelectContext.Provider, { value: contextValue }, children));
98
+ }
99
+ // ============================================================================
100
+ // SelectButton Component
101
+ // ============================================================================
52
102
  /**
53
103
  * Select Button Component
54
104
  */
@@ -72,7 +122,8 @@ const SelectButton = ({ id, disabled, isOpen, state = "default", size = "md", ic
72
122
  "outline-2 outline-[var(--color-primary)] -outline-offset-1 ring-4 ring-[var(--color-primary)]/10"
73
123
  : "";
74
124
  return (React__default.createElement("div", { className: cn(buttonWrapperStyle) },
75
- React__default.createElement("button", { ref: buttonRef, id: id, type: "button", className: cn(baseStyle, sizeStyle, stateStyle, hoverStateStyle, activeFocusState, iconStartPadding, iconEndPadding, buttonStyle, className), onClick: onClick, onFocus: onFocus, onBlur: onBlur, disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox" },
125
+ React__default.createElement("button", { ref: buttonRef, id: id, type: "button", className: cn(baseStyle, sizeStyle, stateStyle, hoverStateStyle, activeFocusState, iconStartPadding, iconEndPadding, buttonStyle, className // User overrides take highest precedence
126
+ ), onClick: onClick, onFocus: onFocus, onBlur: onBlur, disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox" },
76
127
  iconStart && React__default.createElement("span", { className: iconStartStyle }, iconStart),
77
128
  children,
78
129
  iconEnd && React__default.createElement("span", { className: iconEndStyle }, iconEnd))));
@@ -80,17 +131,19 @@ const SelectButton = ({ id, disabled, isOpen, state = "default", size = "md", ic
80
131
  /**
81
132
  * Select Options Component
82
133
  */
83
- const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, children, portal = true, placement = "bottom-start", offset = 4, }) => {
134
+ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, children, portal = true, placement = "bottom-start", offset = 4, triggerRef: customTriggerRef, }) => {
84
135
  var _a;
85
- const { optionsRef, buttonRef, highlightedIndex, setHighlightedIndex, options, filteredOptions, searchable, searchValue, setSearchValue, enableTypeahead, typeaheadValue, setTypeaheadValue, typeaheadTimeoutRef, theme, } = useSelectContext();
136
+ const context = useSelectContext();
137
+ const { optionsRef, buttonRef, highlightedIndex, setHighlightedIndex, filteredOptions, searchable, searchValue, setSearchValue, enableTypeahead, typeaheadValue, setTypeaheadValue, typeaheadTimeoutRef, theme, selectOption, } = context;
138
+ // Use custom triggerRef if provided, otherwise fall back to buttonRef
139
+ const effectiveTriggerRef = customTriggerRef || buttonRef;
86
140
  // Detect dark mode for portal content
87
141
  const isDarkMode = useDarkMode();
88
142
  const searchInputRef = useRef(null);
89
143
  // Use enhanced dropdown positioning hook with direction-aware animations
90
- // Pass trigger width so dropdown matches trigger size
91
- const triggerWidth = ((_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0;
144
+ const triggerWidth = ((_a = effectiveTriggerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0;
92
145
  const { position, cssVariables, contentRef, isFlipped } = useSelectPortal({
93
- triggerRef: buttonRef,
146
+ triggerRef: effectiveTriggerRef,
94
147
  isOpen: isOpen || false,
95
148
  placement,
96
149
  offset,
@@ -103,7 +156,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
103
156
  // Convert maxHeight to a valid CSS value
104
157
  const maxHeightValue = typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight;
105
158
  // Combine refs for portal and legacy usage
106
- const combinedRef = React__default.useCallback((el) => {
159
+ const combinedRef = useCallback((el) => {
107
160
  if (optionsRef &&
108
161
  typeof optionsRef === "object" &&
109
162
  "current" in optionsRef) {
@@ -126,8 +179,8 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
126
179
  : optionsRef.current;
127
180
  if (currentContentRef &&
128
181
  !currentContentRef.contains(event.target) &&
129
- buttonRef.current &&
130
- !buttonRef.current.contains(event.target)) {
182
+ effectiveTriggerRef.current &&
183
+ !effectiveTriggerRef.current.contains(event.target)) {
131
184
  onClose === null || onClose === void 0 ? void 0 : onClose();
132
185
  }
133
186
  };
@@ -135,7 +188,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
135
188
  return () => {
136
189
  document.removeEventListener("mousedown", handleClickOutside);
137
190
  };
138
- }, [isOpen, onClose, optionsRef, buttonRef, contentRef, portal]);
191
+ }, [isOpen, onClose, optionsRef, effectiveTriggerRef, contentRef, portal]);
139
192
  // Handle keyboard navigation
140
193
  useEffect(() => {
141
194
  if (!isOpen)
@@ -203,9 +256,8 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
203
256
  highlightedIndex < filteredOptions.length) {
204
257
  const highlightedOption = filteredOptions[highlightedIndex];
205
258
  if (!highlightedOption.disabled) {
206
- const { value } = highlightedOption;
207
- const context = useSelectContext();
208
- context.selectOption(value);
259
+ const isCreateAction = highlightedOption.id === "__create__";
260
+ selectOption(highlightedOption.value, isCreateAction);
209
261
  onClose === null || onClose === void 0 ? void 0 : onClose();
210
262
  }
211
263
  }
@@ -226,25 +278,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
226
278
  setTypeaheadValue,
227
279
  typeaheadTimeoutRef,
228
280
  optionsRef,
229
- ]);
230
- // Reset search and highlighted index when closing
231
- useEffect(() => {
232
- if (!isOpen) {
233
- setSearchValue("");
234
- setHighlightedIndex(-1);
235
- setTypeaheadValue("");
236
- // Clear any pending typeahead timeout
237
- if (typeaheadTimeoutRef.current) {
238
- clearTimeout(typeaheadTimeoutRef.current);
239
- typeaheadTimeoutRef.current = null;
240
- }
241
- }
242
- }, [
243
- isOpen,
244
- setSearchValue,
245
- setHighlightedIndex,
246
- setTypeaheadValue,
247
- typeaheadTimeoutRef,
281
+ selectOption,
248
282
  ]);
249
283
  // Autofocus search input on open for searchable selects
250
284
  useEffect(() => {
@@ -282,10 +316,10 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
282
316
  maxHeight: searchable ? "none" : maxHeightValue,
283
317
  }),
284
318
  }, role: "listbox", tabIndex: -1, variants: animations, initial: "initial", animate: "visible", exit: "exit" },
285
- searchable && (React__default.createElement("div", { className: `sticky top-0 py-1 bg-white z-[10000] border-b border-[var(--color-border)] ${searchInputStyle}`, style: {
319
+ searchable && (React__default.createElement("div", { className: `sticky top-0 py-1 bg-white dark:bg-[var(--color-background-secondary)] z-[10000] border-b border-[var(--color-border)] ${searchInputStyle}`, style: {
286
320
  "--form-rounded": "0",
287
321
  } },
288
- React__default.createElement(Input, { placeholder: "Search...", value: searchValue, onChange: handleSearchChange, type: "search", ref: searchInputRef, className: "w-full block bg-white border-none outline-none !min-h-8 py-2 ring-0 shadow-none [&:focus]:outline-none [&:focus]:ring-0 [&:focus]:border-none [&:focus-visible]:outline-none [&:focus-visible]:ring-0 [&:focus-visible]:border-none", iconStart: React__default.createElement(MagnifyingGlassIcon, { strokeWidth: 2, className: "size-4 text-[var(--color-text-muted)] group-focus-within:text-[var(--color-primary)]" }), wrapperClassName: "!border-none !outline-none !ring-0 !shadow-none", inputGroupClassName: "!border-none !outline-none !ring-0 !shadow-none flex items-center", style: {
322
+ React__default.createElement(Input, { placeholder: "Search...", value: searchValue, onChange: handleSearchChange, type: "search", ref: searchInputRef, className: "w-full block bg-white dark:bg-[var(--color-background-secondary)] border-none outline-none !min-h-8 py-2 ring-0 shadow-none [&:focus]:outline-none [&:focus]:ring-0 [&:focus]:border-none [&:focus-visible]:outline-none [&:focus-visible]:ring-0 [&:focus-visible]:border-none", iconStart: React__default.createElement(MagnifyingGlassIcon, { strokeWidth: 2, className: "size-4 text-[var(--color-text-muted)] group-focus-within:text-[var(--color-primary)] dark:group-focus-within:text-white" }), wrapperClassName: "!border-none !outline-none !ring-0 !shadow-none", inputGroupClassName: "!border-none !outline-none !ring-0 !shadow-none flex items-center", style: {
289
323
  border: "none",
290
324
  outline: "none",
291
325
  boxShadow: "none",
@@ -297,15 +331,20 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
297
331
  }
298
332
  return optionsContent;
299
333
  };
334
+ // ============================================================================
335
+ // SelectOption Component
336
+ // ============================================================================
300
337
  /**
301
338
  * Select Option Component
302
339
  */
303
340
  const SelectOption = ({ value, isSelected, disabled, className = "", onSelect, children, }) => {
304
341
  var _a;
305
- const { highlightedIndex, setHighlightedIndex, options, filteredOptions, theme, selectOption, } = useSelectContext();
342
+ const { highlightedIndex, setHighlightedIndex, filteredOptions, theme, selectOption, } = useSelectContext();
306
343
  const optionStyle = theme.optionStyle || "";
307
344
  const selectedOptionStyle = theme.selectedOptionStyle || "";
308
345
  const disabledOptionStyle = theme.disabledOptionStyle || "";
346
+ const highlightedOptionStyle = theme.highlightedOptionStyle || "";
347
+ const createOptionStyleTheme = theme.createOptionStyle || "";
309
348
  // Find index of this option in filteredOptions (not options, to support create option)
310
349
  const optionIndex = filteredOptions.findIndex((option) => option.value === value);
311
350
  const isHighlighted = optionIndex === highlightedIndex;
@@ -320,78 +359,58 @@ const SelectOption = ({ value, isSelected, disabled, className = "", onSelect, c
320
359
  }
321
360
  };
322
361
  // Apply the hover style directly when keyboard navigating
323
- const keyboardHighlightStyle = isHighlighted
324
- ? "text-[var(--color-primary)] bg-[var(--color-primary-50)]/50"
325
- : "";
362
+ const keyboardHighlightStyle = isHighlighted ? highlightedOptionStyle : "";
326
363
  // Style create option differently
327
- const createOptionStyle = isCreateOption
328
- ? "font-medium text-[var(--color-primary)]"
329
- : "";
330
- return (React__default.createElement("div", { className: cn(optionStyle, isSelected && selectedOptionStyle, disabled && disabledOptionStyle, keyboardHighlightStyle, createOptionStyle, className), role: "option", "aria-selected": isSelected, "aria-disabled": disabled, "data-option-index": optionIndex, onMouseEnter: () => !disabled && setHighlightedIndex(optionIndex), onClick: handleClick }, children));
364
+ const createOptionStyle = isCreateOption ? createOptionStyleTheme : "";
365
+ return (React__default.createElement("div", { className: cn(optionStyle, isSelected && selectedOptionStyle, disabled && disabledOptionStyle, keyboardHighlightStyle, createOptionStyle, className // User overrides take highest precedence
366
+ ), role: "option", "aria-selected": isSelected, "aria-disabled": disabled, "data-option-index": optionIndex, onMouseEnter: () => !disabled && setHighlightedIndex(optionIndex), onClick: handleClick }, children));
331
367
  };
368
+ // ============================================================================
369
+ // Main Select Component
370
+ // ============================================================================
332
371
  /**
333
372
  * Main Select Component
373
+ *
374
+ * A fully-featured select/dropdown component with support for:
375
+ * - Keyboard navigation
376
+ * - Search/filtering
377
+ * - Typeahead
378
+ * - Creatable options
379
+ * - Portal rendering
380
+ * - Custom theming
381
+ *
382
+ * @example
383
+ * ```tsx
384
+ * <Select
385
+ * options={[
386
+ * { id: "1", label: "Option 1", value: "option1" },
387
+ * { id: "2", label: "Option 2", value: "option2" },
388
+ * ]}
389
+ * value={selected}
390
+ * onChange={setSelected}
391
+ * placeholder="Select an option"
392
+ * />
393
+ * ```
334
394
  */
335
395
  const Select = ({ id, name, size = "md", state = "default", value, displayValue, placeholder = "Select an option", disabled = false, required = false, options = [], label, helperText, onChange, onFocus, onBlur, iconStart, iconEnd, theme: themeOverrides, className = "", wrapperClassName = "", searchable = false, searchPlaceholder = "Search options...", portal = true, placement = "bottom-start", offset = 8, enableTypeahead = true, creatable = false, onCreateOption, createLabel, children, }) => {
336
396
  var _a;
337
397
  // Merge theme with overrides
338
398
  const theme = { ...selectTheme, ...(themeOverrides || {}) };
339
- // State
340
- const [isOpen, setIsOpen] = useState(false);
341
- const [selectedValue, setSelectedValue] = useState(value);
342
- const [highlightedIndex, setHighlightedIndex] = useState(-1);
343
- const [searchValue, setSearchValue] = useState("");
344
- // Typeahead state
345
- const [typeaheadValue, setTypeaheadValue] = useState("");
346
- const typeaheadTimeoutRef = useRef(null);
347
- // Refs
348
- const buttonRef = useRef(null);
349
- const optionsRef = useRef(null);
350
- // Update internal state when prop value changes
351
- useEffect(() => {
352
- setSelectedValue(value);
353
- }, [value]);
354
- // Get display value for the selected option
355
- const getOptionByValue = (searchValue) => {
356
- return options.find((option) => option.value === searchValue);
357
- };
358
- // Filter options based on search query
359
- const baseFilteredOptions = searchValue
360
- ? options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase()))
361
- : options;
362
- // Check if we should show the create option
363
- const shouldShowCreateOption = creatable &&
364
- searchable &&
365
- searchValue.trim() !== "" &&
366
- !baseFilteredOptions.some((option) => option.label.toLowerCase() === searchValue.toLowerCase());
367
- // Add create option if needed
368
- const filteredOptions = shouldShowCreateOption
369
- ? [
370
- {
371
- id: "__create__",
372
- label: typeof createLabel === "function"
373
- ? createLabel(searchValue)
374
- : createLabel || `Create "${searchValue}"`,
375
- value: searchValue,
376
- },
377
- ...baseFilteredOptions,
378
- ]
379
- : baseFilteredOptions;
380
- const selectedOption = getOptionByValue(selectedValue);
399
+ // Use the extracted state hook
400
+ const selectState = useSelectState({
401
+ options,
402
+ value,
403
+ onChange,
404
+ searchable,
405
+ creatable,
406
+ onCreateOption,
407
+ createLabel,
408
+ enableTypeahead,
409
+ });
410
+ const { isOpen, setIsOpen, selectedValue, filteredOptions, selectedOption, } = selectState;
411
+ // Cast triggerRef to buttonRef type
412
+ selectState.triggerRef;
381
413
  const computedDisplayValue = displayValue || (selectedOption ? selectedOption.label : placeholder);
382
- // Function to select an option
383
- const selectOption = (newValue, isCreateAction = false) => {
384
- if (isCreateAction && onCreateOption) {
385
- // Call onCreateOption callback if provided
386
- onCreateOption(String(newValue));
387
- }
388
- if (newValue !== selectedValue) {
389
- setSelectedValue(newValue);
390
- onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
391
- }
392
- setIsOpen(false);
393
- setSearchValue(""); // Clear search value after selection
394
- };
395
414
  // Button click handler
396
415
  const handleButtonClick = () => {
397
416
  if (!disabled) {
@@ -407,34 +426,7 @@ const Select = ({ id, name, size = "md", state = "default", value, displayValue,
407
426
  const defaultChevronIcon = React__default.createElement(ChevronUpDownIcon, { size: 16, className: "" });
408
427
  // Generate a unique ID if not provided
409
428
  const selectId = id || `select-${Math.random().toString(36).substring(2, 9)}`;
410
- return (React__default.createElement(SelectContext.Provider, { value: {
411
- isOpen,
412
- setIsOpen,
413
- selectedValue,
414
- setSelectedValue,
415
- highlightedIndex,
416
- setHighlightedIndex,
417
- options,
418
- filteredOptions,
419
- searchValue,
420
- setSearchValue,
421
- getOptionByValue,
422
- selectOption,
423
- size,
424
- state,
425
- theme,
426
- searchable,
427
- enableTypeahead,
428
- typeaheadValue,
429
- setTypeaheadValue,
430
- typeaheadTimeoutRef,
431
- buttonRef,
432
- optionsRef,
433
- creatable,
434
- createLabel,
435
- onCreateOption,
436
- hasCreateOption: shouldShowCreateOption,
437
- } },
429
+ return (React__default.createElement(SelectProvider, { selectState: selectState, size: size, componentState: state, theme: themeOverrides, searchable: searchable, enableTypeahead: enableTypeahead },
438
430
  React__default.createElement("div", { className: cn("relative", containerStyle, wrapperClassName) },
439
431
  label && (React__default.createElement(FormLabel, { htmlFor: selectId, required: required }, label)),
440
432
  React__default.createElement(SelectButton, { id: selectId, disabled: disabled, isOpen: isOpen, state: state, size: size, iconStart: iconStart, iconEnd: iconEnd || defaultChevronIcon, onClick: handleButtonClick, onFocus: onFocus, onBlur: onBlur, className: className },
@@ -442,10 +434,14 @@ const Select = ({ id, name, size = "md", state = "default", value, displayValue,
442
434
  ? theme.valueTextStyle
443
435
  : theme.placeholderTextStyle) }, computedDisplayValue)),
444
436
  React__default.createElement(SelectOptions, { isOpen: isOpen, onClose: () => setIsOpen(false), portal: portal, placement: placement, offset: offset }, children ||
445
- filteredOptions.map((option) => (React__default.createElement(SelectOption, { key: option.id, value: option.value, isSelected: option.value === selectedValue, disabled: option.disabled || false },
446
- React__default.createElement("span", { className: "block truncate" }, option.label))))),
437
+ filteredOptions.map((option) => {
438
+ const isCreateOption = option.id === "__create__";
439
+ return (React__default.createElement(SelectOption, { key: option.id, value: option.value, isSelected: option.value === selectedValue, disabled: option.disabled || false }, isCreateOption ? (React__default.createElement("span", { className: "flex items-center gap-2" },
440
+ React__default.createElement(PlusIcon, { className: "size-4 shrink-0" }),
441
+ React__default.createElement("span", { className: "block truncate" }, option.label))) : (React__default.createElement("span", { className: "block truncate" }, option.label))));
442
+ })),
447
443
  helperText && (React__default.createElement("p", { className: cn(helperTextStyle, helperTextStateStyle) }, helperText)),
448
444
  name && (React__default.createElement("input", { type: "hidden", name: name, value: selectedValue !== undefined ? String(selectedValue) : "" })))));
449
445
  };
450
446
 
451
- export { Select, SelectButton, SelectOption, SelectOptions };
447
+ export { Select, SelectButton, SelectContext, SelectOption, SelectOptions, SelectProvider, useSelectContext, useSelectState };
@@ -14,7 +14,7 @@ const selectTheme = {
14
14
  // Button style - bg-white for light mode only; dark mode bg comes from baseStyle (inputGroupBaseStyle)
15
15
  buttonStyle: "w-full cursor-pointer bg-white dark:bg-[var(--color-neutral-900)]",
16
16
  // Placeholder text style - matches Input placeholder styling
17
- placeholderTextStyle: "text-[var(--color-text-placeholder)] dark:text-[var(--color-neutral-500)]",
17
+ placeholderTextStyle: formsBaseTheme.placeholderStyle,
18
18
  // Selected value text style
19
19
  valueTextStyle: "text-[var(--color-text-primary)] dark:text-[var(--color-neutral-200)]",
20
20
  // Size variants - composed from atomic tokens
@@ -31,27 +31,23 @@ const selectTheme = {
31
31
  hoverStates: formsBaseTheme.hoverStates,
32
32
  // Options container style - Uses position: fixed for proper scroll behavior with standardized z-index
33
33
  // Width is controlled by trigger size via estimatedWidth parameter
34
- optionsContainerStyle: "fixed z-[1000] max-h-[var(--select-content-available-height,20rem)] overflow-auto overscroll-contain " +
35
- "rounded-[var(--form-rounded)] bg-[var(--color-background)]/90 backdrop-blur-md py-0 text-sm " +
36
- "shadow-real-lg ring-1 ring-slate-200 focus:outline-none " +
37
- "dark:bg-[var(--color-neutral-900)]/90 dark:ring-[var(--color-neutral-700)]",
34
+ optionsContainerStyle: formsBaseTheme.dropdownStyles.container + " py-0 border border-[var(--color-border)]",
38
35
  // Search input style
39
36
  searchInputStyle: "group",
40
37
  // Individual option style
41
- optionStyle: "relative cursor-pointer select-none py-2 px-3 text-[var(--color-text-primary)] " +
42
- "hover:text-[var(--color-primary)] hover:bg-[var(--color-primary-50)]/50 " +
43
- "dark:text-[var(--color-neutral-200)] dark:hover:text-[var(--color-primary-400)] dark:hover:bg-[var(--color-primary-900)]/50",
38
+ optionStyle: formsBaseTheme.dropdownStyles.option,
44
39
  // Selected option style
45
- selectedOptionStyle: "font-medium text-[var(--color-primary)] dark:text-[var(--color-primary-400)]",
40
+ selectedOptionStyle: formsBaseTheme.dropdownStyles.optionSelected,
41
+ // Highlighted option style (keyboard navigation)
42
+ highlightedOptionStyle: formsBaseTheme.dropdownStyles.optionHighlighted,
46
43
  // Disabled option style
47
- disabledOptionStyle: "cursor-not-allowed opacity-50 hover:bg-transparent hover:text-[var(--color-text-primary)]",
44
+ disabledOptionStyle: formsBaseTheme.dropdownStyles.optionDisabled,
45
+ // Create option style
46
+ createOptionStyle: formsBaseTheme.dropdownStyles.optionCreate,
48
47
  // Helper text style - inherited from common form theme
49
48
  helperTextStyle: formsBaseTheme.helperText,
50
49
  // Helper text state variants
51
- helperTextStates: {
52
- default: "text-[var(--color-text-muted)] dark:text-[var(--color-neutral-400)]",
53
- disabled: "text-[var(--color-text-disabled)] dark:text-[var(--color-neutral-600)]",
54
- },
50
+ helperTextStates: formsBaseTheme.helperTextStates,
55
51
  // Left icon style - inherited from common form theme
56
52
  iconStartStyle: formsBaseTheme.iconStyles.left,
57
53
  // Right icon style - inherited from common form theme
@@ -37,7 +37,7 @@ export interface SelectProps<T = any> extends SelectBaseProps {
37
37
  /** Currently selected option */
38
38
  value?: T;
39
39
  /** Custom display value to show in trigger (overrides selected option label) */
40
- displayValue?: string;
40
+ displayValue?: React.ReactNode;
41
41
  /** Placeholder text when no option is selected */
42
42
  placeholder?: string;
43
43
  /** Whether the select is disabled */
@@ -147,7 +147,7 @@ export interface SelectOptionProps<T = any> extends SelectBaseProps {
147
147
  children?: React.ReactNode;
148
148
  }
149
149
  export type SelectSize = "sm" | "md" | "lg";
150
- export type SelectState = "default" | "disabled";
150
+ export type SelectState = "default" | "disabled" | "invalid";
151
151
  /**
152
152
  * Theme overrides for the Select component
153
153
  */
@@ -180,8 +180,12 @@ export interface SelectThemeOverrides {
180
180
  optionStyle?: string;
181
181
  /** Style for selected options */
182
182
  selectedOptionStyle?: string;
183
+ /** Style for highlighted options (keyboard navigation) */
184
+ highlightedOptionStyle?: string;
183
185
  /** Style for disabled options */
184
186
  disabledOptionStyle?: string;
187
+ /** Style for create option */
188
+ createOptionStyle?: string;
185
189
  /** Style for the helper text */
186
190
  helperTextStyle?: string;
187
191
  /** State styles for the helper text */
@@ -1,4 +1,7 @@
1
- import { SelectButton, SelectOptions, SelectOption, Select } from './Select';
2
- export { SelectButton, SelectOptions, SelectOption, Select };
3
- export type { SelectProps, SelectOption as SelectOptionType, SelectSize, SelectState, SelectThemeOverrides } from './Select.types';
4
- export { selectTheme } from './Select.theme';
1
+ export { Select, SelectButton, SelectOptions, SelectOption, } from "./Select";
2
+ export { SelectProvider, SelectContext, useSelectContext, } from "./Select";
3
+ export { useSelectState, } from "./Select";
4
+ export { selectTheme } from "./Select.theme";
5
+ export type { SelectProps, SelectOption as SelectOptionType, SelectSize, SelectState, SelectThemeOverrides, SelectButtonProps, SelectOptionsProps, SelectOptionProps, } from "./Select.types";
6
+ export type { UseSelectStateProps, UseSelectStateReturn, } from "./useSelectState";
7
+ export type { SelectContextValue, SelectProviderProps, SelectOptionsExtendedProps, } from "./Select";