@rebasepro/ui 0.24.0 → 0.24.1-canary.gcb918fc

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 (241) hide show
  1. package/dist/components/Alert.d.ts +6 -0
  2. package/dist/components/Alert.es.js +82 -0
  3. package/dist/components/Alert.es.js.map +1 -0
  4. package/dist/components/Autocomplete.es.js +53 -0
  5. package/dist/components/Autocomplete.es.js.map +1 -0
  6. package/dist/components/Avatar.d.ts +3 -1
  7. package/dist/components/Avatar.es.js +37 -0
  8. package/dist/components/Avatar.es.js.map +1 -0
  9. package/dist/components/Badge.es.js +27 -0
  10. package/dist/components/Badge.es.js.map +1 -0
  11. package/dist/components/BooleanSwitch.es.js +75 -0
  12. package/dist/components/BooleanSwitch.es.js.map +1 -0
  13. package/dist/components/BooleanSwitchWithLabel.es.js +55 -0
  14. package/dist/components/BooleanSwitchWithLabel.es.js.map +1 -0
  15. package/dist/components/Button.es.js +58 -0
  16. package/dist/components/Button.es.js.map +1 -0
  17. package/dist/components/Card.es.js +26 -0
  18. package/dist/components/Card.es.js.map +1 -0
  19. package/dist/components/CenteredView.es.js +23 -0
  20. package/dist/components/CenteredView.es.js.map +1 -0
  21. package/dist/components/Checkbox.es.js +62 -0
  22. package/dist/components/Checkbox.es.js.map +1 -0
  23. package/dist/components/Chip.es.js +72 -0
  24. package/dist/components/Chip.es.js.map +1 -0
  25. package/dist/components/CircularProgress.es.js +28 -0
  26. package/dist/components/CircularProgress.es.js.map +1 -0
  27. package/dist/components/CircularProgressCenter.es.js +30 -0
  28. package/dist/components/CircularProgressCenter.es.js.map +1 -0
  29. package/dist/components/Collapse.es.js +57 -0
  30. package/dist/components/Collapse.es.js.map +1 -0
  31. package/dist/components/ColorPicker.es.js +89 -0
  32. package/dist/components/ColorPicker.es.js.map +1 -0
  33. package/dist/components/Container.es.js +31 -0
  34. package/dist/components/Container.es.js.map +1 -0
  35. package/dist/components/DateTimeField.d.ts +11 -1
  36. package/dist/components/DateTimeField.es.js +253 -0
  37. package/dist/components/DateTimeField.es.js.map +1 -0
  38. package/dist/components/DebouncedTextField.es.js +93 -0
  39. package/dist/components/DebouncedTextField.es.js.map +1 -0
  40. package/dist/components/Dialog.es.js +98 -0
  41. package/dist/components/Dialog.es.js.map +1 -0
  42. package/dist/components/DialogActions.es.js +15 -0
  43. package/dist/components/DialogActions.es.js.map +1 -0
  44. package/dist/components/DialogContent.es.js +18 -0
  45. package/dist/components/DialogContent.es.js.map +1 -0
  46. package/dist/components/DialogTitle.es.js +26 -0
  47. package/dist/components/DialogTitle.es.js.map +1 -0
  48. package/dist/components/ErrorBoundary.es.js +158 -0
  49. package/dist/components/ErrorBoundary.es.js.map +1 -0
  50. package/dist/components/ExpandablePanel.es.js +91 -0
  51. package/dist/components/ExpandablePanel.es.js.map +1 -0
  52. package/dist/components/FileUpload.es.js +58 -0
  53. package/dist/components/FileUpload.es.js.map +1 -0
  54. package/dist/components/FilterChip.es.js +31 -0
  55. package/dist/components/FilterChip.es.js.map +1 -0
  56. package/dist/components/IconButton.es.js +52 -0
  57. package/dist/components/IconButton.es.js.map +1 -0
  58. package/dist/components/InfoLabel.es.js +18 -0
  59. package/dist/components/InfoLabel.es.js.map +1 -0
  60. package/dist/components/InputLabel.es.js +27 -0
  61. package/dist/components/InputLabel.es.js.map +1 -0
  62. package/dist/components/Label.es.js +18 -0
  63. package/dist/components/Label.es.js.map +1 -0
  64. package/dist/components/LoadingButton.es.js +21 -0
  65. package/dist/components/LoadingButton.es.js.map +1 -0
  66. package/dist/components/Markdown.es.js +88 -0
  67. package/dist/components/Markdown.es.js.map +1 -0
  68. package/dist/components/Menu.es.js +46 -0
  69. package/dist/components/Menu.es.js.map +1 -0
  70. package/dist/components/Menubar.es.js +142 -0
  71. package/dist/components/Menubar.es.js.map +1 -0
  72. package/dist/components/MultiSelect.d.ts +1 -7
  73. package/dist/components/MultiSelect.es.js +271 -0
  74. package/dist/components/MultiSelect.es.js.map +1 -0
  75. package/dist/components/Paper.es.js +16 -0
  76. package/dist/components/Paper.es.js.map +1 -0
  77. package/dist/components/Popover.es.js +113 -0
  78. package/dist/components/Popover.es.js.map +1 -0
  79. package/dist/components/RadioGroup.es.js +30 -0
  80. package/dist/components/RadioGroup.es.js.map +1 -0
  81. package/dist/components/ResizablePanels.d.ts +3 -1
  82. package/dist/components/ResizablePanels.es.js +137 -0
  83. package/dist/components/ResizablePanels.es.js.map +1 -0
  84. package/dist/components/SearchBar.es.js +82 -0
  85. package/dist/components/SearchBar.es.js.map +1 -0
  86. package/dist/components/Select.d.ts +8 -1
  87. package/dist/components/Select.es.js +300 -0
  88. package/dist/components/Select.es.js.map +1 -0
  89. package/dist/components/Separator.es.js +20 -0
  90. package/dist/components/Separator.es.js.map +1 -0
  91. package/dist/components/Sheet.es.js +73 -0
  92. package/dist/components/Sheet.es.js.map +1 -0
  93. package/dist/components/Skeleton.es.js +33 -0
  94. package/dist/components/Skeleton.es.js.map +1 -0
  95. package/dist/components/Slider.es.js +56 -0
  96. package/dist/components/Slider.es.js.map +1 -0
  97. package/dist/components/Table.d.ts +18 -3
  98. package/dist/components/Table.es.js +69 -0
  99. package/dist/components/Table.es.js.map +1 -0
  100. package/dist/components/Tabs.es.js +101 -0
  101. package/dist/components/Tabs.es.js.map +1 -0
  102. package/dist/components/TextField.d.ts +0 -8
  103. package/dist/components/TextField.es.js +111 -0
  104. package/dist/components/TextField.es.js.map +1 -0
  105. package/dist/components/TextareaAutosize.es.js +187 -0
  106. package/dist/components/TextareaAutosize.es.js.map +1 -0
  107. package/dist/components/ToggleButtonGroup.d.ts +6 -1
  108. package/dist/components/ToggleButtonGroup.es.js +35 -0
  109. package/dist/components/ToggleButtonGroup.es.js.map +1 -0
  110. package/dist/components/Tooltip.d.ts +24 -0
  111. package/dist/components/Tooltip.es.js +165 -0
  112. package/dist/components/Tooltip.es.js.map +1 -0
  113. package/dist/components/Typography.es.js +85 -0
  114. package/dist/components/Typography.es.js.map +1 -0
  115. package/dist/components/VirtualTable/VirtualTable.es.js +516 -0
  116. package/dist/components/VirtualTable/VirtualTable.es.js.map +1 -0
  117. package/dist/components/VirtualTable/VirtualTableCell.d.ts +1 -1
  118. package/dist/components/VirtualTable/VirtualTableCell.es.js +40 -0
  119. package/dist/components/VirtualTable/VirtualTableCell.es.js.map +1 -0
  120. package/dist/components/VirtualTable/VirtualTableHeader.es.js +209 -0
  121. package/dist/components/VirtualTable/VirtualTableHeader.es.js.map +1 -0
  122. package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js +166 -0
  123. package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js.map +1 -0
  124. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -2
  125. package/dist/components/VirtualTable/VirtualTableRow.d.ts +6 -7
  126. package/dist/components/VirtualTable/VirtualTableRow.es.js +41 -0
  127. package/dist/components/VirtualTable/VirtualTableRow.es.js.map +1 -0
  128. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +2 -1
  129. package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js +71 -0
  130. package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js.map +1 -0
  131. package/dist/components/VirtualTable/fields/VirtualTableInput.es.js +73 -0
  132. package/dist/components/VirtualTable/fields/VirtualTableInput.es.js.map +1 -0
  133. package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js +47 -0
  134. package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js.map +1 -0
  135. package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js +83 -0
  136. package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js.map +1 -0
  137. package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js +22 -0
  138. package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js.map +1 -0
  139. package/dist/components/VirtualTable/selection/SelectionContext.es.js +23 -0
  140. package/dist/components/VirtualTable/selection/SelectionContext.es.js.map +1 -0
  141. package/dist/components/VirtualTable/selection/SelectionStore.es.js +43 -0
  142. package/dist/components/VirtualTable/selection/SelectionStore.es.js.map +1 -0
  143. package/dist/components/VirtualTable/types.d.ts +1 -1
  144. package/dist/components/common/SelectInputLabel.es.js +28 -0
  145. package/dist/components/common/SelectInputLabel.es.js.map +1 -0
  146. package/dist/components/index.es.js +64 -0
  147. package/dist/hooks/PortalContainerContext.es.js +40 -0
  148. package/dist/hooks/PortalContainerContext.es.js.map +1 -0
  149. package/dist/hooks/UiLabelsContext.d.ts +63 -0
  150. package/dist/hooks/UiLabelsContext.es.js +59 -0
  151. package/dist/hooks/UiLabelsContext.es.js.map +1 -0
  152. package/dist/hooks/useDebounceCallback.es.js +15 -0
  153. package/dist/hooks/useDebounceCallback.es.js.map +1 -0
  154. package/dist/hooks/useDebounceValue.es.js +19 -0
  155. package/dist/hooks/useDebounceValue.es.js.map +1 -0
  156. package/dist/hooks/useDebouncedCallback.es.js +36 -0
  157. package/dist/hooks/useDebouncedCallback.es.js.map +1 -0
  158. package/dist/hooks/useInjectStyles.es.js +27 -0
  159. package/dist/hooks/useInjectStyles.es.js.map +1 -0
  160. package/dist/hooks/useIsDarkMode.es.js +61 -0
  161. package/dist/hooks/useIsDarkMode.es.js.map +1 -0
  162. package/dist/hooks/useModalFocus.es.js +81 -0
  163. package/dist/hooks/useModalFocus.es.js.map +1 -0
  164. package/dist/hooks/useOutsideAlerter.es.js +41 -0
  165. package/dist/hooks/useOutsideAlerter.es.js.map +1 -0
  166. package/dist/hooks/useRestoreInterruptedFocus.es.js +61 -0
  167. package/dist/hooks/useRestoreInterruptedFocus.es.js.map +1 -0
  168. package/dist/icons/GitHubIcon.es.js +23 -0
  169. package/dist/icons/GitHubIcon.es.js.map +1 -0
  170. package/dist/icons/HandleIcon.es.js +60 -0
  171. package/dist/icons/HandleIcon.es.js.map +1 -0
  172. package/dist/icons/Icon.es.js +25 -0
  173. package/dist/icons/Icon.es.js.map +1 -0
  174. package/dist/icons/LucideIconByName.d.ts +12 -9
  175. package/dist/icons/LucideIconByName.es.js +83 -0
  176. package/dist/icons/LucideIconByName.es.js.map +1 -0
  177. package/dist/icons/cool_icon_keys.es.js +55 -0
  178. package/dist/icons/cool_icon_keys.es.js.map +1 -0
  179. package/dist/icons/icon_keys.es.js +1941 -0
  180. package/dist/icons/icon_keys.es.js.map +1 -0
  181. package/dist/icons/index.d.ts +4 -3
  182. package/dist/icons/index.es.js +8 -0
  183. package/dist/icons/lucide_icon_map.d.ts +12 -0
  184. package/dist/icons/lucide_icon_map.es.js +2 -0
  185. package/dist/index.d.ts +2 -0
  186. package/dist/index.es.js +87 -9563
  187. package/dist/styles.es.js +158 -0
  188. package/dist/styles.es.js.map +1 -0
  189. package/dist/util/chip_colors.es.js +290 -0
  190. package/dist/util/chip_colors.es.js.map +1 -0
  191. package/dist/util/cls.es.js +10 -0
  192. package/dist/util/cls.es.js.map +1 -0
  193. package/dist/util/debounce.es.js +22 -0
  194. package/dist/util/debounce.es.js.map +1 -0
  195. package/dist/util/hash.es.js +16 -0
  196. package/dist/util/hash.es.js.map +1 -0
  197. package/dist/util/keys.es.js +37 -0
  198. package/dist/util/keys.es.js.map +1 -0
  199. package/dist/util/lazy_chunk.es.js +96 -0
  200. package/dist/util/lazy_chunk.es.js.map +1 -0
  201. package/dist/views/CardView.d.ts +26 -2
  202. package/dist/views/CardView.es.js +435 -0
  203. package/dist/views/CardView.es.js.map +1 -0
  204. package/dist/views/CollectionView/CollectionCardView.es.js +179 -0
  205. package/dist/views/CollectionView/CollectionCardView.es.js.map +1 -0
  206. package/dist/views/CollectionView/CollectionKanbanView.es.js +172 -0
  207. package/dist/views/CollectionView/CollectionKanbanView.es.js.map +1 -0
  208. package/dist/views/CollectionView/CollectionListView.es.js +156 -0
  209. package/dist/views/CollectionView/CollectionListView.es.js.map +1 -0
  210. package/dist/views/CollectionView/CollectionTableView.es.js +149 -0
  211. package/dist/views/CollectionView/CollectionTableView.es.js.map +1 -0
  212. package/dist/views/CollectionView/CollectionView.es.js +197 -0
  213. package/dist/views/CollectionView/CollectionView.es.js.map +1 -0
  214. package/dist/views/CollectionView/CollectionViewToolbar.es.js +155 -0
  215. package/dist/views/CollectionView/CollectionViewToolbar.es.js.map +1 -0
  216. package/dist/views/CollectionView/DefaultCellRenderer.es.js +302 -0
  217. package/dist/views/CollectionView/DefaultCellRenderer.es.js.map +1 -0
  218. package/dist/views/CollectionView/resolveTitleProperty.es.js +56 -0
  219. package/dist/views/CollectionView/resolveTitleProperty.es.js.map +1 -0
  220. package/dist/views/CollectionView/utils.es.js +19 -0
  221. package/dist/views/CollectionView/utils.es.js.map +1 -0
  222. package/dist/views/Kanban/Board.es.js +237 -0
  223. package/dist/views/Kanban/Board.es.js.map +1 -0
  224. package/dist/views/Kanban/BoardColumn.es.js +81 -0
  225. package/dist/views/Kanban/BoardColumn.es.js.map +1 -0
  226. package/dist/views/Kanban/BoardColumnTitle.es.js +27 -0
  227. package/dist/views/Kanban/BoardColumnTitle.es.js.map +1 -0
  228. package/dist/views/Kanban/BoardSortableList.es.js +98 -0
  229. package/dist/views/Kanban/BoardSortableList.es.js.map +1 -0
  230. package/dist/views/Kanban/placement.es.js +27 -0
  231. package/dist/views/Kanban/placement.es.js.map +1 -0
  232. package/dist/views/KanbanView.es.js +11 -0
  233. package/dist/views/KanbanView.es.js.map +1 -0
  234. package/dist/views/ListView.d.ts +15 -2
  235. package/dist/views/ListView.es.js +245 -0
  236. package/dist/views/ListView.es.js.map +1 -0
  237. package/dist/views/useScrollParentRestoration.d.ts +8 -1
  238. package/dist/views/useScrollParentRestoration.es.js +75 -0
  239. package/dist/views/useScrollParentRestoration.es.js.map +1 -0
  240. package/package.json +2 -2
  241. package/dist/index.es.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiSelect.es.js","names":[],"sources":["../../src/components/MultiSelect.tsx"],"sourcesContent":["\n\"use client\";\nimport { CheckIcon, ChevronDownIcon, XIcon } from \"lucide-react\";\nimport { iconSize } from \"../icons/Icon\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\nimport { Children, useEffect, useState } from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { cls } from \"../util\";\n\nimport { Separator } from \"./Separator\";\nimport { Chip } from \"./Chip\";\nimport { SelectInputLabel } from \"./common/SelectInputLabel\";\nimport {\n defaultBorderMixin,\n fieldBackgroundDisabledMixin,\n fieldBackgroundHoverMixin,\n fieldBackgroundInvisibleMixin,\n fieldBackgroundMixin,\n focusedDisabled\n} from \"../styles\";\nimport { useInjectStyles } from \"../hooks\";\nimport { usePortalContainer } from \"../hooks/PortalContainerContext\";\n\nexport type MultiSelectValue = string | number | boolean;\n\n// Make the context properly generic\ninterface MultiSelectContextProps<T extends MultiSelectValue = string> {\n fieldValue?: T[];\n onItemClick: (v: T) => void;\n}\n\n// Create a proper generic context\nexport const MultiSelectContext = React.createContext<MultiSelectContextProps<MultiSelectValue>>(null! as MultiSelectContextProps<MultiSelectValue>);\n\n/**\n * Props for MultiSelect component\n */\ninterface MultiSelectProps<T extends MultiSelectValue = string> {\n modalPopover?: boolean;\n className?: string;\n open?: boolean,\n /** Put on the trigger button, so a `<label htmlFor>` can name it. */\n id?: string,\n onOpenChange?: (open: boolean) => void,\n value?: T[],\n inputClassName?: string,\n onValueChange?: (updatedValue: T[]) => void,\n placeholder?: React.ReactNode,\n size?: \"smallest\" | \"small\" | \"medium\" | \"large\",\n useChips?: boolean,\n label?: React.ReactNode | string,\n disabled?: boolean,\n error?: boolean,\n includeSelectAll?: boolean,\n includeClear?: boolean,\n inputRef?: React.Ref<HTMLButtonElement>,\n invisible?: boolean,\n /**\n * Whether the trigger draws its own chevron. A table cell turns it off:\n * the cell draws one opener for every kind of editor, in the same place.\n */\n chevron?: boolean,\n /**\n * Positions the list against this element instead of the trigger. A\n * table cell passes itself: chips that wrap make the trigger taller than\n * the cell that clips it, and the list belongs under what can be seen.\n */\n anchorRef?: React.RefObject<HTMLElement | null>,\n /**\n * Replaces everything the trigger draws — the values, the box, its\n * padding, its height and the chevron — with this node. For a caller that\n * frames the select itself: a table cell passes the preview it shows at\n * rest, so selecting the cell moves nothing.\n */\n triggerContent?: React.ReactNode,\n children: React.ReactNode;\n renderValues?: (values: T[]) => React.ReactNode;\n portalContainer?: HTMLElement | null;\n /**\n * Accessible name for the trigger.\n *\n * Without it the name is whatever the button happens to contain — the\n * selected chips, or nothing at all when the field is empty — so an empty\n * multi-select announced itself as an unnamed button. `label` cannot serve:\n * an entity form passes an element there, because the label carries the\n * property's type icon.\n */\n \"aria-label\"?: string;\n}\n\n/**\n * The popover's trigger, or — given an anchor — a plain child beside a\n * `Popover.Anchor` on that element. Not both: Radix's trigger registers itself\n * as the anchor through a ref callback, which under StrictMode runs again\n * after the custom anchor's effect and wins, leaving the list anchored to a\n * trigger the custom anchor then unmounts. The button toggles the list itself.\n */\nfunction MultiSelectTrigger({ anchorRef, children }: {\n anchorRef?: React.RefObject<HTMLElement | null>;\n children: React.ReactElement;\n}) {\n if (!anchorRef)\n return <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>;\n return <>\n <PopoverPrimitive.Anchor virtualRef={anchorRef}/>\n {children}\n </>;\n}\n\n// Use generic type for the forwarded ref\nexport const MultiSelect = React.forwardRef<\n HTMLButtonElement,\n MultiSelectProps\n>(\n (\n {\n value,\n id,\n size = \"large\",\n label,\n error,\n onValueChange,\n invisible,\n chevron = true,\n anchorRef,\n triggerContent,\n disabled,\n placeholder,\n modalPopover = true,\n includeClear = true,\n includeSelectAll = true,\n useChips = true,\n className,\n inputClassName,\n inputRef,\n children,\n renderValues,\n open,\n onOpenChange,\n portalContainer,\n \"aria-label\": ariaLabel\n },\n ref\n ) => {\n const [isMounted, setIsMounted] = useState(false);\n const [isPopoverOpen, setIsPopoverOpen] = useState(open ?? false);\n const [selectedValues, setSelectedValues] = useState<string[]>(value ?? []);\n\n // Get the portal container from context\n const contextContainer = usePortalContainer();\n\n // Prioritize manual prop, fallback to context container\n const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n const onPopoverOpenChange = (open: boolean) => {\n setIsPopoverOpen(open);\n onOpenChange?.(open);\n }\n\n useEffect(() => {\n setIsPopoverOpen(open ?? false);\n }, [open]);\n\n // Every option's value, as the strings an option click reports. Not\n // filtered through `Boolean`: an option whose value is \"\" is an option.\n const allValues = React.useMemo(() => {\n const values: string[] = [];\n Children.forEach(children, (child) => {\n if (React.isValidElement<MultiSelectItemProps>(child)\n && child.props.value !== undefined && child.props.value !== null) {\n values.push(String(child.props.value));\n }\n });\n return values;\n }, [children]);\n\n const allSelected = allValues.length > 0\n && allValues.every(v => selectedValues.some(s => String(s) === v));\n\n const optionsMap = React.useMemo(() => {\n const map = new Map<string, React.ReactNode>();\n Children.forEach(children, (child) => {\n if (React.isValidElement<MultiSelectItemProps>(child)) {\n map.set(String(child.props.value), child.props.children);\n }\n });\n return map;\n }, [children]);\n\n React.useEffect(() => {\n setSelectedValues(value ?? []);\n }, [value]);\n\n // Every edit goes through here: the options, (Select All), Backspace in\n // the search box, and the chip and clear icons, which sit inside the\n // trigger and so are not stopped by the button's native `disabled`.\n const updateValues = React.useCallback((values: string[]) => {\n if (disabled) return;\n setSelectedValues(values);\n onValueChange?.(values);\n }, [onValueChange, disabled]);\n\n const onItemClick = React.useCallback((newValue: MultiSelectValue) => {\n let newSelectedValues: string[];\n if (selectedValues.some(v => String(v) === String(newValue))) {\n newSelectedValues = selectedValues.filter(v => String(v) !== String(newValue));\n } else {\n newSelectedValues = [...selectedValues, String(newValue)];\n }\n updateValues(newSelectedValues);\n }, [selectedValues, updateValues]);\n\n const handleInputKeyDown = (\n event: React.KeyboardEvent<HTMLInputElement>\n ) => {\n if (event.key === \"Enter\") {\n onPopoverOpenChange(true);\n } else if (event.key === \"Backspace\" && !event.currentTarget.value) {\n const newSelectedValues = [...selectedValues];\n newSelectedValues.pop();\n updateValues(newSelectedValues);\n }\n };\n\n const toggleOption = (value: string) => {\n const newSelectedValues = selectedValues.some(v => String(v) === String(value))\n ? selectedValues.filter(v => String(v) !== String(value))\n : [...selectedValues, value];\n updateValues(newSelectedValues);\n };\n\n const handleClear = () => {\n updateValues([]);\n };\n\n const handleTogglePopover = () => {\n onPopoverOpenChange(!isPopoverOpen);\n };\n\n const toggleAll = () => {\n if (allSelected) {\n handleClear();\n } else {\n updateValues(allValues);\n }\n onPopoverOpenChange(false);\n };\n\n // Scoped to this popover. Unscoped, it reached every other cmdk list on\n // the page — the relation and user selectors set their own height on\n // the list and got a second, competing scroll container inside it.\n useInjectStyles(\"MultiSelect\", `\n[data-multi-select-content] [cmdk-group] {\n max-height: 45vh;\n overflow-y: auto;\n} `)\n\n const contextValue = React.useMemo(() => ({\n fieldValue: selectedValues,\n onItemClick\n }), [selectedValues, onItemClick]);\n\n const bare = triggerContent !== undefined;\n\n return (\n <MultiSelectContext.Provider value={contextValue}>\n\n {typeof label === \"string\" ? <SelectInputLabel error={error}>{label}</SelectInputLabel> : label}\n\n <PopoverPrimitive.Root\n open={isMounted && isPopoverOpen}\n onOpenChange={onPopoverOpenChange}\n modal={modalPopover}\n >\n <MultiSelectTrigger anchorRef={anchorRef}>\n <button\n ref={inputRef ?? ref}\n id={id}\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-label={ariaLabel ?? (typeof label === \"string\" ? label : undefined)}\n onClick={handleTogglePopover}\n className={bare\n ? cls(\"relative flex items-center w-full text-start select-none outline-none focus:outline-none focus-visible:outline-none\", className, inputClassName)\n : cls(\n // The control height, plus the 1px hairline on\n // each side when the field has one. `TextField`,\n // `Select` and `DateTimeField` set the height on\n // an inner element and draw the border around\n // it, so a bordered field is N + 2. This button\n // is both the box and the border, and under\n // border-box sizing the border ate into N: a\n // multi-select stood 2px short of every field\n // beside it. An invisible one has no border and\n // stays N, like theirs.\n invisible\n ? { smallest: \"min-h-[28px]\", small: \"min-h-[32px]\", medium: \"min-h-[40px]\", large: \"min-h-[48px]\" }[size]\n : { smallest: \"min-h-[30px]\", small: \"min-h-[34px]\", medium: \"min-h-[42px]\", large: \"min-h-[50px]\" }[size],\n {\n // Kept tight so the min-height above governs:\n // py-2 plus a medium Chip overflowed it and made\n // smallest/small render at the same height.\n \"py-0\": size === \"smallest\",\n \"py-0.5\": size === \"small\",\n \"py-1\": size === \"medium\" || size === \"large\"\n },\n {\n \"px-2\": size === \"small\" || size === \"smallest\",\n \"px-4\": size === \"medium\" || size === \"large\"\n },\n \"select-none rounded-lg text-sm\",\n // No `ring-0` here: it removed the only focus\n // indicator the trigger had, so tabbing onto an\n // enum-array field changed nothing on screen.\n \"outline-none focus:outline-none focus-visible:outline-none\",\n invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,\n // An invisible field has no hover fill of its own: whatever frames it (a table cell) carries the hover.\n disabled ? fieldBackgroundDisabledMixin : (invisible ? \"\" : fieldBackgroundHoverMixin),\n \"relative flex items-center\",\n className,\n inputClassName\n )}\n >\n {bare ? triggerContent : selectedValues.length > 0 ? (\n <div className=\"flex justify-between items-center w-full\">\n <div className=\"flex flex-wrap items-center gap-1.5 text-start\">\n {renderValues && renderValues(selectedValues)}\n {!renderValues && selectedValues.map((value) => {\n\n const optionChildren = optionsMap.get(String(value));\n if (!useChips) {\n return optionChildren;\n }\n return (\n <Chip\n size={size === \"smallest\" || size === \"small\" ? \"smallest\" : \"small\"}\n key={String(value)}\n className={cls(\"flex flex-row items-center p-1\")}\n >\n {optionChildren}\n <XIcon\n size={iconSize.smallest}\n onClick={(event) => {\n event.stopPropagation();\n toggleOption(value);\n }}\n />\n </Chip>\n );\n })}\n </div>\n <div className=\"flex items-center justify-between\">\n {includeClear && <XIcon\n className={\"ml-4\"}\n size={iconSize.small}\n onClick={(event) => {\n event.stopPropagation();\n handleClear();\n }}\n />}\n {chevron && <div className={cls(\"px-2 h-full flex items-center\")}>\n <ChevronDownIcon size={size === \"large\" ? iconSize.medium : iconSize.small}\n className={cls(\"transition\", isPopoverOpen ? \"rotate-180\" : \"\")}/>\n </div>}\n </div>\n </div>\n ) : (\n <div className=\"flex items-center justify-between w-full mx-auto\">\n <span className=\"text-sm\">\n {placeholder}\n </span>\n {chevron && <div className={cls(\"px-2 h-full flex items-center\")}>\n <ChevronDownIcon size={size === \"large\" ? iconSize.medium : iconSize.small}\n className={cls(\"transition\", isPopoverOpen ? \"rotate-180\" : \"\")}/>\n </div>}\n </div>\n )}\n </button>\n </MultiSelectTrigger>\n <PopoverPrimitive.Portal container={finalContainer}>\n <PopoverPrimitive.Content\n data-multi-select-content\n className={cls(\"z-50 overflow-hidden border bg-surface-card rounded-lg w-[400px]\", defaultBorderMixin)}\n align=\"start\"\n sideOffset={8}\n onEscapeKeyDown={() => onPopoverOpenChange(false)}\n >\n <CommandPrimitive>\n <div className={\"flex flex-row items-center\"}>\n <CommandPrimitive.Input\n className={cls(focusedDisabled, \"bg-transparent outline-none flex-1 h-full w-full m-4 flex-grow text-surface-accent-900 dark:text-white\")}\n placeholder=\"Search...\"\n onKeyDown={handleInputKeyDown}\n />\n {selectedValues.length > 0 && (\n <div\n onClick={handleClear}\n className=\"text-sm justify-center cursor-pointer py-3 px-4 text-text-secondary dark:text-text-secondary-dark\">\n Clear\n </div>\n )}\n </div>\n <Separator orientation={\"horizontal\"} className={\"my-0\"}/>\n <CommandPrimitive.List>\n <CommandPrimitive.Empty className={\"px-4 py-2 text-sm text-text-secondary dark:text-text-secondary-dark\"}>\n No results found.\n </CommandPrimitive.Empty>\n <CommandPrimitive.Group>\n {includeSelectAll && <CommandPrimitive.Item\n key=\"all\"\n onSelect={toggleAll}\n className={\n cls(\n \"flex flex-row items-center gap-1.5\",\n \"cursor-pointer\",\n \"m-1\",\n \"ring-offset-transparent\",\n \"p-1 rounded-md aria-[selected=true]:outline-none aria-[selected=true]:ring-2 aria-[selected=true]:ring-primary aria-[selected=true]:ring-primary/75 aria-[selected=true]:ring-offset-2\",\n \"aria-[selected=true]:bg-surface-active\",\n \"cursor-pointer p-2 rounded-md aria-[selected=true]:bg-surface-active\"\n )\n }\n >\n <InnerCheckBox checked={allSelected}/>\n <span className={\"text-sm text-text-secondary dark:text-text-secondary-dark\"}>(Select All)</span>\n </CommandPrimitive.Item>}\n {children}\n </CommandPrimitive.Group>\n </CommandPrimitive.List>\n </CommandPrimitive>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n </MultiSelectContext.Provider>\n );\n }\n);\n\nMultiSelect.displayName = \"MultiSelect\";\n\nexport interface MultiSelectItemProps<T extends MultiSelectValue = string> {\n value: T;\n children?: React.ReactNode,\n className?: string;\n}\n\nexport const MultiSelectItem = React.memo(function MultiSelectItem<T extends MultiSelectValue = string>({\n children,\n value,\n className\n}: MultiSelectItemProps<T>) {\n const context = React.useContext(MultiSelectContext);\n if (!context) throw new Error(\"MultiSelectItem must be used inside a MultiSelect\");\n const {\n fieldValue,\n onItemClick\n } = context;\n\n const isSelected = (fieldValue ?? []).some(v => String(v) === String(value));\n\n return <CommandPrimitive.Item\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onSelect={(_) => {\n onItemClick(value);\n }}\n className={cls(\n \"flex flex-row items-center gap-1.5\",\n isSelected ? \"bg-surface-active\" : \"\",\n \"cursor-pointer\",\n \"m-1\",\n \"ring-offset-transparent\",\n \"p-1 rounded-md aria-[selected=true]:outline-none aria-[selected=true]:ring-2 aria-[selected=true]:ring-primary aria-[selected=true]:ring-primary/75 aria-[selected=true]:ring-offset-2\",\n \"aria-[selected=true]:bg-surface-active\",\n \"cursor-pointer p-2 rounded-md aria-[selected=true]:bg-surface-active\",\n \"text-surface-accent-700 dark:text-surface-accent-300\",\n className\n )}\n >\n <InnerCheckBox checked={isSelected}/>\n {children}\n </CommandPrimitive.Item>;\n});\n\nconst InnerCheckBox = React.memo(function InnerCheckBox({ checked }: { checked: boolean }) {\n return <div className={cls(\n \"p-2\",\n \"w-8 h-8\",\n \"inline-flex items-center justify-center text-sm font-medium focus:outline-none transition-colors ease-in-out duration-150\"\n )}>\n <div\n className={cls(\n \"border-2 relative transition-colors ease-in-out duration-150\",\n \"w-4 h-4 rounded-sm flex items-center justify-center\",\n (checked ? \"bg-primary\" : \"bg-surface-card\"),\n (checked) ? \"text-surface-accent-100 dark:text-surface-accent-900\" : \"\",\n (checked ? \"border-transparent\" : \"border-surface-accent-800 dark:border-surface-accent-200\")\n )}>\n {checked && <CheckIcon size={iconSize.smallest} className={\"absolute\"}/>}\n </div>\n </div>\n});\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { paperMixin } from "../styles.es.js";
2
+ import { cls } from "../util/cls.es.js";
3
+ import "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/Paper.tsx
6
+ function Paper({ children, style, className }) {
7
+ return /* @__PURE__ */ jsx("div", {
8
+ className: cls(paperMixin, className),
9
+ style,
10
+ children
11
+ });
12
+ }
13
+ //#endregion
14
+ export { Paper };
15
+
16
+ //# sourceMappingURL=Paper.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Paper.es.js","names":[],"sources":["../../src/components/Paper.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { paperMixin } from \"../styles\";\nimport { cls } from \"../util\";\n\nexport function Paper({\n children,\n style,\n className\n }: {\n children: React.ReactNode;\n style?: React.CSSProperties;\n className?: string;\n\n}) {\n return (\n <div\n className={cls(paperMixin, className)}\n style={style}>\n {children}\n </div>\n )\n}\n"],"mappings":";;;;;AAKA,SAAgB,MAAM,EACI,UACA,OACA,aAMvB;CACC,OACI,oBAAC,OAAD;EACI,WAAW,IAAI,YAAY,SAAS;EAC7B;EACN;CACA,CAAA;AAEb"}
@@ -0,0 +1,113 @@
1
+ "use client";
2
+ import { focusedDisabled, paperMixin } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import { usePortalContainer } from "../hooks/PortalContainerContext.es.js";
5
+ import { useInjectStyles } from "../hooks/useInjectStyles.es.js";
6
+ import "react";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
9
+ //#region src/components/Popover.tsx
10
+ function Popover({ trigger, children, open, onOpenChange, side, sideOffset = 5, align, alignOffset, arrowPadding, sticky, hideWhenDetached, avoidCollisions, enabled = true, modal = false, portalContainer, className, onMouseEnter, onMouseLeave }) {
11
+ useInjectStyles("Popover", popoverStyles);
12
+ const contextContainer = usePortalContainer();
13
+ const finalContainer = portalContainer ?? contextContainer ?? void 0;
14
+ if (!enabled) return /* @__PURE__ */ jsx(Fragment, { children: trigger });
15
+ return /* @__PURE__ */ jsxs(PopoverPrimitive.Root, {
16
+ open,
17
+ onOpenChange,
18
+ modal,
19
+ children: [/* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
20
+ asChild: true,
21
+ children: trigger
22
+ }), /* @__PURE__ */ jsx(PopoverPrimitive.Portal, {
23
+ container: finalContainer,
24
+ children: /* @__PURE__ */ jsxs(PopoverPrimitive.Content, {
25
+ className: cls(paperMixin, focusedDisabled, "PopoverContent z-50", className),
26
+ side,
27
+ sideOffset,
28
+ align,
29
+ alignOffset,
30
+ arrowPadding,
31
+ sticky,
32
+ hideWhenDetached,
33
+ avoidCollisions,
34
+ onMouseEnter,
35
+ onMouseLeave,
36
+ children: [children, /* @__PURE__ */ jsx(PopoverPrimitive.Arrow, { className: "fill-surface-card" })]
37
+ })
38
+ })]
39
+ });
40
+ }
41
+ var popoverStyles = `
42
+ .PopoverContent {
43
+ animation-duration: 400ms;
44
+ animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
45
+ will-change: transform, opacity;
46
+ }
47
+ .PopoverContent[data-state='open'][data-side='top'] {
48
+ animation-name: popoverSlideDownAndFade;
49
+ }
50
+ .PopoverContent[data-state='open'][data-side='right'] {
51
+ animation-name: popoverSlideLeftAndFade;
52
+ }
53
+ .PopoverContent[data-state='open'][data-side='bottom'] {
54
+ animation-name: popoverSlideUpAndFade;
55
+ }
56
+ .PopoverContent[data-state='open'][data-side='left'] {
57
+ animation-name: popoverSlideRightAndFade;
58
+ }
59
+
60
+ @keyframes popoverSlideUpAndFade {
61
+ from {
62
+ opacity: 0;
63
+ transform: translateY(2px);
64
+ }
65
+ to {
66
+ opacity: 1;
67
+ transform: translateY(0);
68
+ }
69
+ }
70
+
71
+ @keyframes popoverSlideRightAndFade {
72
+ from {
73
+ opacity: 0;
74
+ transform: translateX(-2px);
75
+ }
76
+ to {
77
+ opacity: 1;
78
+ transform: translateX(0);
79
+ }
80
+ }
81
+
82
+ @keyframes popoverSlideDownAndFade {
83
+ from {
84
+ opacity: 0;
85
+ transform: translateY(-2px);
86
+ }
87
+ to {
88
+ opacity: 1;
89
+ transform: translateY(0);
90
+ }
91
+ }
92
+
93
+ @keyframes popoverSlideLeftAndFade {
94
+ from {
95
+ opacity: 0;
96
+ transform: translateX(2px);
97
+ }
98
+ to {
99
+ opacity: 1;
100
+ transform: translateX(0);
101
+ }
102
+ }
103
+
104
+ @media (prefers-reduced-motion: reduce) {
105
+ .PopoverContent[data-state] {
106
+ animation: none;
107
+ }
108
+ }
109
+ `;
110
+ //#endregion
111
+ export { Popover };
112
+
113
+ //# sourceMappingURL=Popover.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popover.es.js","names":[],"sources":["../../src/components/Popover.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\n\nimport { focusedDisabled, paperMixin } from \"../styles\";\nimport { cls } from \"../util\";\nimport { useInjectStyles } from \"../hooks\";\nimport { usePortalContainer } from \"../hooks/PortalContainerContext\";\n\nexport type PopoverSide = \"top\" | \"right\" | \"bottom\" | \"left\";\nexport type PopoverAlign = \"start\" | \"center\" | \"end\";\n\nexport interface PopoverProps {\n trigger: React.ReactNode;\n children: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n side?: PopoverSide;\n sideOffset?: number;\n align?: PopoverAlign;\n alignOffset?: number;\n arrowPadding?: number;\n sticky?: \"partial\" | \"always\";\n hideWhenDetached?: boolean;\n avoidCollisions?: boolean;\n enabled?: boolean;\n modal?: boolean;\n className?: string;\n portalContainer?: HTMLElement | null;\n onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;\n onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport function Popover({\n trigger,\n children,\n open,\n onOpenChange,\n side,\n sideOffset = 5,\n align,\n alignOffset,\n arrowPadding,\n sticky,\n hideWhenDetached,\n avoidCollisions,\n enabled = true,\n modal = false,\n portalContainer,\n className,\n onMouseEnter,\n onMouseLeave\n }: PopoverProps) {\n\n useInjectStyles(\"Popover\", popoverStyles);\n\n // Get the portal container from context\n const contextContainer = usePortalContainer();\n\n // Prioritize manual prop, fallback to context container\n const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;\n\n if (!enabled)\n return <>{trigger}</>;\n\n return <PopoverPrimitive.Root open={open}\n onOpenChange={onOpenChange}\n modal={modal}>\n\n <PopoverPrimitive.Trigger asChild>\n {trigger}\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal container={finalContainer}>\n <PopoverPrimitive.Content\n // `z-50`, the floating layer — see the note in `Menu`. Below it\n // a popover opened from inside a dialog or a side panel is\n // painted under the thing that owns its trigger.\n // `focusedDisabled`, as Menu and Select: the panel takes focus\n // when opened from the keyboard and is not a control to ring.\n className={cls(paperMixin, focusedDisabled,\n \"PopoverContent z-50\", className)}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n arrowPadding={arrowPadding}\n sticky={sticky}\n hideWhenDetached={hideWhenDetached}\n avoidCollisions={avoidCollisions}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}>\n\n {children}\n <PopoverPrimitive.Arrow className=\"fill-surface-card\"/>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>;\n}\n\nconst popoverStyles = `\n.PopoverContent {\n animation-duration: 400ms;\n animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n.PopoverContent[data-state='open'][data-side='top'] {\n animation-name: popoverSlideDownAndFade;\n}\n.PopoverContent[data-state='open'][data-side='right'] {\n animation-name: popoverSlideLeftAndFade;\n}\n.PopoverContent[data-state='open'][data-side='bottom'] {\n animation-name: popoverSlideUpAndFade;\n}\n.PopoverContent[data-state='open'][data-side='left'] {\n animation-name: popoverSlideRightAndFade;\n}\n\n@keyframes popoverSlideUpAndFade {\n from {\n opacity: 0;\n transform: translateY(2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes popoverSlideRightAndFade {\n from {\n opacity: 0;\n transform: translateX(-2px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes popoverSlideDownAndFade {\n from {\n opacity: 0;\n transform: translateY(-2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes popoverSlideLeftAndFade {\n from {\n opacity: 0;\n transform: translateX(2px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .PopoverContent[data-state] {\n animation: none;\n }\n}\n`;\n"],"mappings":";;;;;;;;;AAiCA,SAAgB,QAAQ,EACI,SACA,UACA,MACA,cACA,MACA,aAAa,GACb,OACA,aACA,cACA,QACA,kBACA,iBACA,UAAU,MACV,QAAQ,OACR,iBACA,WACA,cACA,gBACa;CAErC,gBAAgB,WAAW,aAAa;CAGxC,MAAM,mBAAmB,mBAAmB;CAG5C,MAAM,iBAAkB,mBAAmB,oBAAoB,KAAA;CAE/D,IAAI,CAAC,SACD,OAAO,oBAAA,UAAA,EAAA,UAAG,QAAU,CAAA;CAExB,OAAO,qBAAC,iBAAiB,MAAlB;EAA6B;EACQ;EACP;YAF9B,CAIH,oBAAC,iBAAiB,SAAlB;GAA0B,SAAA;aACrB;EACqB,CAAA,GAE1B,oBAAC,iBAAiB,QAAlB;GAAyB,WAAW;aAChC,qBAAC,iBAAiB,SAAlB;IAMI,WAAW,IAAI,YAAY,iBACvB,uBAAuB,SAAS;IAC9B;IACM;IACL;IACM;IACC;IACN;IACU;IACD;IACH;IACA;cAjBlB,CAmBK,UACD,oBAAC,iBAAiB,OAAlB,EAAwB,WAAU,oBAAoB,CAAA,CAChC;;EACL,CAAA,CACN;;AAC3B;AAEA,IAAM,gBAAgB"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { cls } from "../util/cls.es.js";
3
+ import * as React$1 from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
6
+ //#region src/components/RadioGroup.tsx
7
+ var RadioGroup = React$1.forwardRef(({ className, ...props }, ref) => {
8
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, {
9
+ className: cls("grid gap-2", className),
10
+ ...props,
11
+ ref
12
+ });
13
+ });
14
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
15
+ var RadioGroupItem = React$1.forwardRef(({ className, ...props }, ref) => {
16
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Item, {
17
+ ref,
18
+ className: cls("aspect-square h-4 w-4 rounded-full border border-primary text-primary focus:outline-hidden focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className),
19
+ ...props,
20
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, {
21
+ className: "flex items-center justify-center",
22
+ children: /* @__PURE__ */ jsx("div", { className: "h-2.5 w-2.5 fill-current text-current bg-primary rounded-full" })
23
+ })
24
+ });
25
+ });
26
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
27
+ //#endregion
28
+ export { RadioGroup, RadioGroupItem };
29
+
30
+ //# sourceMappingURL=RadioGroup.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup.es.js","names":[],"sources":["../../src/components/RadioGroup.tsx"],"sourcesContent":["\"use client\";\nimport * as React from \"react\"\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\"\nimport { cls } from \"../util\";\n\nexport interface RadioGroupProps {\n id?: string;\n children: React.ReactNode;\n name?: string\n required?: boolean;\n disabled?: boolean;\n /**\n * Whether keyboard navigation should loop around\n * @defaultValue false\n */\n loop?: boolean;\n defaultValue?: string;\n value?: string;\n\n onValueChange?(value: string): void;\n\n className?: string;\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({\n className,\n ...props\n }, ref) => {\n return (\n <RadioGroupPrimitive.Root\n className={cls(\"grid gap-2\", className)}\n {...props}\n ref={ref}\n />\n )\n})\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName\n\nexport interface RadioGroupItemProps {\n id?: string;\n value: string;\n checked?: boolean;\n required?: boolean;\n className?: string;\n disabled?: boolean;\n}\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({\n className,\n ...props\n }, ref) => {\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cls(\n \"aspect-square h-4 w-4 rounded-full border border-primary text-primary focus:outline-hidden focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <div className=\"h-2.5 w-2.5 fill-current text-current bg-primary rounded-full\"/>\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n})\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName\n\nexport { RadioGroup, RadioGroupItem }\n"],"mappings":";;;;;;AAwBA,IAAM,aAAa,QAAM,YAGtB,EACI,WACA,GAAG,SACJ,QAAQ;CACV,OACI,oBAAC,oBAAoB,MAArB;EACI,WAAW,IAAI,cAAc,SAAS;EACtC,GAAI;EACC;CACR,CAAA;AAET,CAAC;AACD,WAAW,cAAc,oBAAoB,KAAK;AAUlD,IAAM,iBAAiB,QAAM,YAG1B,EACI,WACA,GAAG,SACJ,QAAQ;CACV,OACI,oBAAC,oBAAoB,MAArB;EACS;EACL,WAAW,IACP,6NACA,SACJ;EACA,GAAI;YAEJ,oBAAC,oBAAoB,WAArB;GAA+B,WAAU;aACrC,oBAAC,OAAD,EAAK,WAAU,gEAAgE,CAAA;EACpD,CAAA;CACT,CAAA;AAElC,CAAC;AACD,eAAe,cAAc,oBAAoB,KAAK"}
@@ -14,5 +14,7 @@ export type ResizablePanelsProps = {
14
14
  animateLayout?: boolean;
15
15
  className?: string;
16
16
  stacked?: boolean;
17
+ /** Accessible name of the divider, e.g. "Resize the list". */
18
+ dividerAriaLabel?: string;
17
19
  };
18
- export declare function ResizablePanels({ firstPanel, secondPanel, showFirstPanel, showSecondPanel, panelSizePercent, onPanelSizeChange, minPanelSizePx, orientation, animateLayout, className, stacked }: ResizablePanelsProps): React.JSX.Element;
20
+ export declare function ResizablePanels({ firstPanel, secondPanel, showFirstPanel, showSecondPanel, panelSizePercent, onPanelSizeChange, minPanelSizePx, orientation, animateLayout, className, stacked, dividerAriaLabel }: ResizablePanelsProps): React.JSX.Element;
@@ -0,0 +1,137 @@
1
+ import { cls } from "../util/cls.es.js";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/ResizablePanels.tsx
5
+ /** How far an arrow key moves the divider, in percent; Shift moves it further. */
6
+ var KEY_STEP = 2;
7
+ var KEY_STEP_LARGE = 10;
8
+ function ResizablePanels({ firstPanel, secondPanel, showFirstPanel = true, showSecondPanel = true, panelSizePercent, onPanelSizeChange, minPanelSizePx = 200, orientation = "horizontal", animateLayout = true, className, stacked = false, dividerAriaLabel }) {
9
+ const containerRef = useRef(null);
10
+ const isResizingRef = useRef(false);
11
+ const firstPanelRef = useRef(null);
12
+ const startPosRef = useRef(0);
13
+ const startSizeRef = useRef(0);
14
+ const [isResizing, setIsResizing] = useState(false);
15
+ const isHorizontal = orientation === "horizontal";
16
+ const handleResizeStart = useCallback((e) => {
17
+ if (!showFirstPanel || !showSecondPanel) return;
18
+ e.preventDefault();
19
+ isResizingRef.current = true;
20
+ setIsResizing(true);
21
+ startPosRef.current = isHorizontal ? e.clientX : e.clientY;
22
+ if (firstPanelRef.current) {
23
+ const rect = firstPanelRef.current.getBoundingClientRect();
24
+ startSizeRef.current = isHorizontal ? rect.width : rect.height;
25
+ }
26
+ document.body.style.cursor = isHorizontal ? "col-resize" : "row-resize";
27
+ document.body.style.userSelect = "none";
28
+ }, [
29
+ isHorizontal,
30
+ showFirstPanel,
31
+ showSecondPanel
32
+ ]);
33
+ useEffect(() => {
34
+ const handleMouseMove = (e) => {
35
+ if (!isResizingRef.current || !containerRef.current) return;
36
+ const delta = (isHorizontal ? e.clientX : e.clientY) - startPosRef.current;
37
+ let newSize = startSizeRef.current + delta;
38
+ const containerRect = containerRef.current.getBoundingClientRect();
39
+ const maxSize = (isHorizontal ? containerRect.width : containerRect.height) - minPanelSizePx;
40
+ newSize = Math.max(minPanelSizePx, Math.min(newSize, maxSize));
41
+ if (firstPanelRef.current) firstPanelRef.current.style.flexBasis = `${newSize}px`;
42
+ };
43
+ const handleMouseUp = () => {
44
+ if (isResizingRef.current && containerRef.current && firstPanelRef.current) {
45
+ const containerRect = containerRef.current.getBoundingClientRect();
46
+ const firstPanelRect = firstPanelRef.current.getBoundingClientRect();
47
+ const containerSize = isHorizontal ? containerRect.width : containerRect.height;
48
+ const finalSize = isHorizontal ? firstPanelRect.width : firstPanelRect.height;
49
+ if (containerSize > 0) {
50
+ const newPercent = finalSize / containerSize * 100;
51
+ firstPanelRef.current.style.flexBasis = `${newPercent}%`;
52
+ onPanelSizeChange(Math.max(0, Math.min(100, newPercent)));
53
+ }
54
+ isResizingRef.current = false;
55
+ setIsResizing(false);
56
+ document.body.style.cursor = "";
57
+ document.body.style.userSelect = "";
58
+ }
59
+ };
60
+ window.addEventListener("pointermove", handleMouseMove);
61
+ window.addEventListener("pointerup", handleMouseUp);
62
+ window.addEventListener("pointercancel", handleMouseUp);
63
+ return () => {
64
+ window.removeEventListener("pointermove", handleMouseMove);
65
+ window.removeEventListener("pointerup", handleMouseUp);
66
+ window.removeEventListener("pointercancel", handleMouseUp);
67
+ };
68
+ }, [
69
+ onPanelSizeChange,
70
+ isHorizontal,
71
+ minPanelSizePx
72
+ ]);
73
+ const handleKeyDown = useCallback((e) => {
74
+ const back = isHorizontal ? "ArrowLeft" : "ArrowUp";
75
+ const forward = isHorizontal ? "ArrowRight" : "ArrowDown";
76
+ if (e.key !== back && e.key !== forward) return;
77
+ e.preventDefault();
78
+ const step = (e.shiftKey ? KEY_STEP_LARGE : KEY_STEP) * (e.key === forward ? 1 : -1);
79
+ let min = 0;
80
+ let max = 100;
81
+ const container = containerRef.current?.getBoundingClientRect();
82
+ const total = container ? isHorizontal ? container.width : container.height : 0;
83
+ if (total > 0) {
84
+ min = Math.min(50, minPanelSizePx / total * 100);
85
+ max = Math.max(50, 100 - minPanelSizePx / total * 100);
86
+ }
87
+ onPanelSizeChange(Math.max(min, Math.min(max, panelSizePercent + step)));
88
+ }, [
89
+ isHorizontal,
90
+ minPanelSizePx,
91
+ onPanelSizeChange,
92
+ panelSizePercent
93
+ ]);
94
+ const appliedBasis = !showFirstPanel ? "0%" : showSecondPanel ? `${panelSizePercent}%` : "100%";
95
+ return /* @__PURE__ */ jsxs("div", {
96
+ ref: containerRef,
97
+ className: cls("relative w-full h-full flex overflow-hidden", !stacked && (isHorizontal ? "flex-row" : "flex-col"), className),
98
+ children: [
99
+ /* @__PURE__ */ jsx("div", {
100
+ ref: firstPanelRef,
101
+ className: cls(stacked ? "absolute inset-0" : "relative flex-shrink-0", "flex flex-col overflow-hidden", !stacked && !isResizing && animateLayout && "transition-[flex-basis] duration-150 ease-out", !showFirstPanel && "hidden"),
102
+ style: stacked ? void 0 : {
103
+ flexBasis: appliedBasis,
104
+ minWidth: isHorizontal && showFirstPanel && showSecondPanel ? `${minPanelSizePx}px` : void 0,
105
+ minHeight: !isHorizontal && showFirstPanel && showSecondPanel ? `${minPanelSizePx}px` : void 0,
106
+ maxWidth: showSecondPanel ? void 0 : "100%",
107
+ maxHeight: showSecondPanel ? void 0 : "100%"
108
+ },
109
+ children: firstPanel
110
+ }),
111
+ !stacked && showFirstPanel && showSecondPanel && /* @__PURE__ */ jsx("div", {
112
+ role: "separator",
113
+ tabIndex: 0,
114
+ "aria-label": dividerAriaLabel,
115
+ "aria-orientation": isHorizontal ? "vertical" : "horizontal",
116
+ "aria-valuenow": Math.round(panelSizePercent),
117
+ "aria-valuemin": 0,
118
+ "aria-valuemax": 100,
119
+ className: cls("relative z-10 flex flex-shrink-0 items-center justify-center border-transparent touch-none group/divider", isHorizontal ? "border-l w-px h-full cursor-col-resize" : "border-t h-px w-full cursor-row-resize"),
120
+ onPointerDown: handleResizeStart,
121
+ onKeyDown: handleKeyDown,
122
+ children: /* @__PURE__ */ jsx("div", {
123
+ className: cls("absolute flex items-center justify-center group", isHorizontal ? "w-4 h-full cursor-col-resize top-0" : "h-4 w-full cursor-row-resize left-0"),
124
+ children: /* @__PURE__ */ jsx("div", { className: cls("bg-primary/60 dark:bg-primary rounded-full opacity-0 group-hover:opacity-100 group-focus-visible/divider:opacity-100 transition-all duration-200", isHorizontal ? "w-1 h-8" : "h-1 w-8") })
125
+ })
126
+ }),
127
+ /* @__PURE__ */ jsx("div", {
128
+ className: cls(stacked ? "absolute inset-0" : "flex-grow relative min-w-0 min-h-0", "flex flex-col overflow-hidden", !showSecondPanel && "hidden"),
129
+ children: secondPanel
130
+ })
131
+ ]
132
+ });
133
+ }
134
+ //#endregion
135
+ export { ResizablePanels };
136
+
137
+ //# sourceMappingURL=ResizablePanels.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResizablePanels.es.js","names":[],"sources":["../../src/components/ResizablePanels.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { cls } from \"../util\";\nimport { defaultBorderMixin } from \"../styles\";\n\nexport type ResizablePanelsProps = {\n firstPanel: React.ReactNode;\n secondPanel: React.ReactNode;\n /** Whether the first panel is visible (e.g. Sidebar) */\n showFirstPanel?: boolean;\n /** Whether the second panel is visible (e.g. Results) */\n showSecondPanel?: boolean;\n /** 0-100 representing the width/height of the first panel */\n panelSizePercent: number;\n onPanelSizeChange: (sizePercent: number) => void;\n minPanelSizePx?: number;\n orientation?: \"horizontal\" | \"vertical\";\n animateLayout?: boolean;\n className?: string;\n stacked?: boolean;\n /** Accessible name of the divider, e.g. \"Resize the list\". */\n dividerAriaLabel?: string;\n};\n\n/** How far an arrow key moves the divider, in percent; Shift moves it further. */\nconst KEY_STEP = 2;\nconst KEY_STEP_LARGE = 10;\n\nexport function ResizablePanels({\n firstPanel,\n secondPanel,\n showFirstPanel = true,\n showSecondPanel = true,\n panelSizePercent,\n onPanelSizeChange,\n minPanelSizePx = 200,\n orientation = \"horizontal\",\n animateLayout = true,\n className,\n stacked = false,\n dividerAriaLabel\n}: ResizablePanelsProps) {\n\n const containerRef = useRef<HTMLDivElement>(null);\n const isResizingRef = useRef(false);\n\n // For local layout tracking without triggering React rerenders during drag\n const firstPanelRef = useRef<HTMLDivElement>(null);\n const startPosRef = useRef(0);\n const startSizeRef = useRef(0);\n\n const [isResizing, setIsResizing] = useState(false);\n const isHorizontal = orientation === \"horizontal\";\n\n // Pointer events, not mouse events: a mouse-only handle could not be\n // dragged on a tablet.\n const handleResizeStart = useCallback((e: React.PointerEvent) => {\n if (!showFirstPanel || !showSecondPanel) return;\n\n e.preventDefault();\n isResizingRef.current = true;\n setIsResizing(true);\n\n startPosRef.current = isHorizontal ? e.clientX : e.clientY;\n\n if (firstPanelRef.current) {\n const rect = firstPanelRef.current.getBoundingClientRect();\n startSizeRef.current = isHorizontal ? rect.width : rect.height;\n }\n\n document.body.style.cursor = isHorizontal ? \"col-resize\" : \"row-resize\";\n document.body.style.userSelect = \"none\";\n }, [isHorizontal, showFirstPanel, showSecondPanel]);\n\n useEffect(() => {\n const handleMouseMove = (e: PointerEvent) => {\n if (!isResizingRef.current || !containerRef.current) return;\n\n const currentPos = isHorizontal ? e.clientX : e.clientY;\n const delta = currentPos - startPosRef.current; // Dragging right/down increases first panel size\n\n let newSize = startSizeRef.current + delta;\n\n const containerRect = containerRef.current.getBoundingClientRect();\n const containerTotal = isHorizontal ? containerRect.width : containerRect.height;\n\n // Limit the maximum size to prevent pushing the second panel offscreen\n const maxSize = containerTotal - minPanelSizePx;\n\n newSize = Math.max(minPanelSizePx, Math.min(newSize, maxSize));\n\n // Directly update the DOM for performance while dragging\n if (firstPanelRef.current) {\n firstPanelRef.current.style.flexBasis = `${newSize}px`;\n }\n };\n\n const handleMouseUp = () => {\n if (isResizingRef.current && containerRef.current && firstPanelRef.current) {\n // Calculate the final percentage\n const containerRect = containerRef.current.getBoundingClientRect();\n const firstPanelRect = firstPanelRef.current.getBoundingClientRect();\n\n const containerSize = isHorizontal ? containerRect.width : containerRect.height;\n const finalSize = isHorizontal ? firstPanelRect.width : firstPanelRect.height;\n\n // Pre-set the DOM to the exact % value BEFORE re-enabling transitions.\n // This prevents the visual \"snap\" that occurs when switching from px → %\n // with the CSS transition active.\n if (containerSize > 0) {\n const newPercent = (finalSize / containerSize) * 100;\n firstPanelRef.current.style.flexBasis = `${newPercent}%`;\n onPanelSizeChange(Math.max(0, Math.min(100, newPercent)));\n }\n\n isResizingRef.current = false;\n setIsResizing(false);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n }\n };\n\n window.addEventListener(\"pointermove\", handleMouseMove);\n window.addEventListener(\"pointerup\", handleMouseUp);\n window.addEventListener(\"pointercancel\", handleMouseUp);\n\n return () => {\n window.removeEventListener(\"pointermove\", handleMouseMove);\n window.removeEventListener(\"pointerup\", handleMouseUp);\n window.removeEventListener(\"pointercancel\", handleMouseUp);\n };\n }, [onPanelSizeChange, isHorizontal, minPanelSizePx]);\n\n // The arrow keys move the divider by a step, within the same bounds a drag has.\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n const back = isHorizontal ? \"ArrowLeft\" : \"ArrowUp\";\n const forward = isHorizontal ? \"ArrowRight\" : \"ArrowDown\";\n if (e.key !== back && e.key !== forward) return;\n e.preventDefault();\n const step = (e.shiftKey ? KEY_STEP_LARGE : KEY_STEP) * (e.key === forward ? 1 : -1);\n let min = 0;\n let max = 100;\n const container = containerRef.current?.getBoundingClientRect();\n const total = container ? (isHorizontal ? container.width : container.height) : 0;\n if (total > 0) {\n min = Math.min(50, (minPanelSizePx / total) * 100);\n max = Math.max(50, 100 - (minPanelSizePx / total) * 100);\n }\n onPanelSizeChange(Math.max(min, Math.min(max, panelSizePercent + step)));\n }, [isHorizontal, minPanelSizePx, onPanelSizeChange, panelSizePercent]);\n\n // Calculate applied size\n const appliedBasis = !showFirstPanel ? \"0%\" : (showSecondPanel ? `${panelSizePercent}%` : \"100%\");\n\n return (\n <div\n ref={containerRef}\n className={cls(\n \"relative w-full h-full flex overflow-hidden\",\n !stacked && (isHorizontal ? \"flex-row\" : \"flex-col\"),\n className\n )}\n >\n {/* First Panel */}\n <div\n ref={firstPanelRef}\n className={cls(\n stacked ? \"absolute inset-0\" : \"relative flex-shrink-0\",\n \"flex flex-col overflow-hidden\",\n !stacked && !isResizing && animateLayout && \"transition-[flex-basis] duration-150 ease-out\",\n !showFirstPanel && \"hidden\"\n )}\n style={stacked ? undefined : {\n flexBasis: appliedBasis,\n minWidth: isHorizontal && showFirstPanel && showSecondPanel ? `${minPanelSizePx}px` : undefined,\n minHeight: !isHorizontal && showFirstPanel && showSecondPanel ? `${minPanelSizePx}px` : undefined,\n maxWidth: showSecondPanel ? undefined : \"100%\",\n maxHeight: showSecondPanel ? undefined : \"100%\"\n }}\n >\n {firstPanel}\n </div>\n\n {/* Divider */}\n {!stacked && showFirstPanel && showSecondPanel && (\n <div\n // The divider is a handle, not a rule: invisible until the\n // pointer is on it. The two panels it separates already\n // differ by a surface step, and a permanent 1px line between\n // them was one of six on the split record view where the\n // reference draws one.\n role=\"separator\"\n tabIndex={0}\n aria-label={dividerAriaLabel}\n // The line between side-by-side panels is vertical.\n aria-orientation={isHorizontal ? \"vertical\" : \"horizontal\"}\n aria-valuenow={Math.round(panelSizePercent)}\n aria-valuemin={0}\n aria-valuemax={100}\n className={cls(\n \"relative z-10 flex flex-shrink-0 items-center justify-center border-transparent touch-none group/divider\",\n isHorizontal ? \"border-l w-px h-full cursor-col-resize\" : \"border-t h-px w-full cursor-row-resize\"\n )}\n onPointerDown={handleResizeStart}\n onKeyDown={handleKeyDown}\n >\n {/* Transparent Hit Area with Pill inside */}\n <div className={cls(\n \"absolute flex items-center justify-center group\",\n isHorizontal ? \"w-4 h-full cursor-col-resize top-0\" : \"h-4 w-full cursor-row-resize left-0\"\n )}>\n <div className={cls(\n \"bg-primary/60 dark:bg-primary rounded-full opacity-0 group-hover:opacity-100 group-focus-visible/divider:opacity-100 transition-all duration-200\",\n isHorizontal ? \"w-1 h-8\" : \"h-1 w-8\"\n )}/>\n </div>\n </div>\n )}\n\n {/* Second Panel */}\n <div\n className={cls(\n stacked ? \"absolute inset-0\" : \"flex-grow relative min-w-0 min-h-0\",\n \"flex flex-col overflow-hidden\",\n !showSecondPanel && \"hidden\"\n )}\n >\n {secondPanel}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ import { defaultBorderMixin } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import { useDebounceValue } from "../hooks/useDebounceValue.es.js";
5
+ import { iconSize } from "../icons/Icon.es.js";
6
+ import { CircularProgress } from "./CircularProgress.es.js";
7
+ import { IconButton } from "./IconButton.es.js";
8
+ import { useUiLabels } from "../hooks/UiLabelsContext.es.js";
9
+ import React, { useCallback, useState } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ import { SearchIcon, XIcon } from "lucide-react";
12
+ //#region src/components/SearchBar.tsx
13
+ function SearchBar({ onClick, onTextSearch, placeholder, expandable = false, size = "medium", innerClassName, className, autoFocus, disabled, loading, inputRef, initialValue }) {
14
+ const labels = useUiLabels();
15
+ const placeholderText = placeholder ?? labels.search;
16
+ const [searchText, setSearchText] = useState(initialValue ?? "");
17
+ const [active, setActive] = useState(false);
18
+ const deferredValues = useDebounceValue(searchText, 200);
19
+ /**
20
+ * Debounce on SearchIcon text update
21
+ */
22
+ React.useEffect(() => {
23
+ if (!onTextSearch) return;
24
+ if (deferredValues) onTextSearch(deferredValues);
25
+ else onTextSearch(void 0);
26
+ }, [deferredValues]);
27
+ const clearText = useCallback(() => {
28
+ if (!onTextSearch) return;
29
+ setSearchText("");
30
+ onTextSearch(void 0);
31
+ }, [onTextSearch]);
32
+ const heightClass = {
33
+ smallest: "h-[28px]",
34
+ small: "h-[32px]",
35
+ medium: "h-[40px]",
36
+ large: "h-[48px]"
37
+ }[size];
38
+ const iconPaddingClass = size === "smallest" || size === "small" ? "px-2" : size === "medium" ? "px-3" : "px-4";
39
+ const inputPaddingClass = size === "smallest" || size === "small" ? "pl-8" : size === "medium" ? "pl-10" : "pl-12";
40
+ return /* @__PURE__ */ jsxs("div", {
41
+ role: "search",
42
+ "aria-label": labels.search,
43
+ onClick,
44
+ className: cls("relative transition-all", heightClass, "bg-surface-field border", defaultBorderMixin, "focus-within:ring-1 focus-within:ring-primary/60 focus-within:border-primary focus-within:shadow-[0_0_0_3px_rgba(0,112,244,0.1)]", "rounded-full overflow-hidden", className),
45
+ children: [
46
+ /* @__PURE__ */ jsx("div", {
47
+ className: cls("absolute p-0 h-full pointer-events-none flex items-center justify-center top-0", iconPaddingClass),
48
+ children: loading ? /* @__PURE__ */ jsx(CircularProgress, { size: "smallest" }) : /* @__PURE__ */ jsx(SearchIcon, {
49
+ className: "text-text-disabled dark:text-text-disabled-dark",
50
+ size: size === "smallest" ? 14 : size === "small" ? 18 : 20
51
+ })
52
+ }),
53
+ /* @__PURE__ */ jsx("input", {
54
+ value: searchText ?? "",
55
+ ref: inputRef,
56
+ onClick,
57
+ placeholder: placeholderText,
58
+ "aria-label": placeholderText,
59
+ readOnly: !onTextSearch,
60
+ disabled,
61
+ onChange: onTextSearch ? (event) => {
62
+ setSearchText(event.target.value);
63
+ } : void 0,
64
+ autoFocus,
65
+ onFocus: () => setActive(true),
66
+ onBlur: () => setActive(false),
67
+ className: cls((disabled || loading) && "pointer-events-none", "placeholder-text-disabled dark:placeholder-text-disabled-dark", "relative flex items-center transition-all bg-transparent outline-none focus:outline-none focus:ring-0 appearance-none border-none focus:border-transparent", inputPaddingClass, "h-full w-full text-current", size === "small" ? "text-sm" : "", expandable ? active ? "w-[220px]" : "w-[180px]" : "", innerClassName)
68
+ }),
69
+ searchText ? /* @__PURE__ */ jsx(IconButton, {
70
+ className: `${size === "small" ? "mr-0 top-0" : "mr-1 top-0"} absolute right-0 z-10`,
71
+ size: "small",
72
+ "aria-label": labels.clearSearch,
73
+ onClick: clearText,
74
+ children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest })
75
+ }) : /* @__PURE__ */ jsx("div", { style: { width: 26 } })
76
+ ]
77
+ });
78
+ }
79
+ //#endregion
80
+ export { SearchBar };
81
+
82
+ //# sourceMappingURL=SearchBar.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchBar.es.js","names":[],"sources":["../../src/components/SearchBar.tsx"],"sourcesContent":["\n\"use client\";\nimport { SearchIcon, XIcon } from \"lucide-react\";\nimport { iconSize } from \"../icons/Icon\";\nimport React, { useCallback, useState } from \"react\";\n\nimport { defaultBorderMixin } from \"../styles\";\nimport { CircularProgress } from \"./CircularProgress\";\nimport { IconButton } from \"./IconButton\";\n\nimport { cls } from \"../util\";\nimport { useDebounceValue } from \"../hooks\";\nimport { useUiLabels } from \"../hooks/UiLabelsContext\";\n\ninterface SearchBarProps {\n onClick?: () => void;\n onTextSearch?: (searchString?: string) => void;\n placeholder?: string;\n expandable?: boolean;\n /**\n * Size of the search bar.\n * - \"small\": 32px height (matches TextField small)\n * - \"medium\": 44px height (matches TextField medium)\n * @default \"medium\"\n */\n size?: \"smallest\" | \"small\" | \"medium\" | \"large\";\n innerClassName?: string;\n className?: string;\n autoFocus?: boolean;\n disabled?: boolean;\n loading?: boolean;\n inputRef?: React.Ref<HTMLInputElement>;\n /**\n * Optional initial value for the search input, e.g. from URL params.\n */\n initialValue?: string;\n}\n\nexport function SearchBar({\n onClick,\n onTextSearch,\n placeholder,\n expandable = false,\n size = \"medium\",\n innerClassName,\n className,\n autoFocus,\n disabled,\n loading,\n inputRef,\n initialValue\n}: SearchBarProps) {\n\n const labels = useUiLabels();\n const placeholderText = placeholder ?? labels.search;\n\n const [searchText, setSearchText] = useState<string>(initialValue ?? \"\");\n const [active, setActive] = useState<boolean>(false);\n\n const deferredValues = useDebounceValue(searchText, 200);\n\n /**\n * Debounce on SearchIcon text update\n */\n React.useEffect(() => {\n if (!onTextSearch) return;\n if (deferredValues) {\n onTextSearch(deferredValues);\n } else {\n onTextSearch(undefined);\n }\n }, [deferredValues]);\n\n const clearText = useCallback(() => {\n if (!onTextSearch) return;\n setSearchText(\"\");\n onTextSearch(undefined);\n }, [onTextSearch]);\n\n // Height classes matching TextField sizes\n // Heights come from the shared control scale (styles.ts) so a SearchBar\n // lines up with the Button and Select beside it in a toolbar.\n const heightClass = { smallest: \"h-[28px]\", small: \"h-[32px]\", medium: \"h-[40px]\", large: \"h-[48px]\" }[size];\n const iconPaddingClass = size === \"smallest\" || size === \"small\" ? \"px-2\" : size === \"medium\" ? \"px-3\" : \"px-4\";\n const inputPaddingClass = size === \"smallest\" || size === \"small\" ? \"pl-8\" : size === \"medium\" ? \"pl-10\" : \"pl-12\";\n\n return (\n <div\n role=\"search\"\n aria-label={labels.search}\n onClick={onClick}\n className={cls(\"relative transition-all\",\n heightClass,\n \"bg-surface-field border\",\n defaultBorderMixin,\n \"focus-within:ring-1 focus-within:ring-primary/60 focus-within:border-primary focus-within:shadow-[0_0_0_3px_rgba(0,112,244,0.1)]\",\n \"rounded-full overflow-hidden\",\n className)}>\n <div\n className={cls(\"absolute p-0 h-full pointer-events-none flex items-center justify-center top-0\", iconPaddingClass)}>\n {loading ? <CircularProgress size={\"smallest\"}/> : <SearchIcon className={\"text-text-disabled dark:text-text-disabled-dark\"} size={size === \"smallest\" ? 14 : size === \"small\" ? 18 : 20}/>}\n </div>\n <input\n value={searchText ?? \"\"}\n ref={inputRef}\n onClick={onClick}\n placeholder={placeholderText}\n aria-label={placeholderText}\n readOnly={!onTextSearch}\n disabled={disabled}\n onChange={onTextSearch\n ? (event) => {\n setSearchText(event.target.value);\n }\n : undefined}\n autoFocus={autoFocus}\n onFocus={() => setActive(true)}\n onBlur={() => setActive(false)}\n className={cls(\n (disabled || loading) && \"pointer-events-none\",\n \"placeholder-text-disabled dark:placeholder-text-disabled-dark\",\n \"relative flex items-center transition-all bg-transparent outline-none focus:outline-none focus:ring-0 appearance-none border-none focus:border-transparent\",\n inputPaddingClass, \"h-full w-full text-current\",\n size === \"small\" ? \"text-sm\" : \"\",\n expandable ? (active ? \"w-[220px]\" : \"w-[180px]\") : \"\",\n innerClassName\n )}\n />\n {searchText\n ? <IconButton\n className={`${size === \"small\" ? \"mr-0 top-0\" : \"mr-1 top-0\"} absolute right-0 z-10`}\n size={\"small\"}\n aria-label={labels.clearSearch}\n onClick={clearText}>\n <XIcon size={iconSize.smallest}/>\n </IconButton>\n : <div style={{ width: 26 }}/>\n }\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsCA,SAAgB,UAAU,EACtB,SACA,cACA,aACA,aAAa,OACb,OAAO,UACP,gBACA,WACA,WACA,UACA,SACA,UACA,gBACe;CAEf,MAAM,SAAS,YAAY;CAC3B,MAAM,kBAAkB,eAAe,OAAO;CAE9C,MAAM,CAAC,YAAY,iBAAiB,SAAiB,gBAAgB,EAAE;CACvE,MAAM,CAAC,QAAQ,aAAa,SAAkB,KAAK;CAEnD,MAAM,iBAAiB,iBAAiB,YAAY,GAAG;;;;CAKvD,MAAM,gBAAgB;EAClB,IAAI,CAAC,cAAc;EACnB,IAAI,gBACA,aAAa,cAAc;OAE3B,aAAa,KAAA,CAAS;CAE9B,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,YAAY,kBAAkB;EAChC,IAAI,CAAC,cAAc;EACnB,cAAc,EAAE;EAChB,aAAa,KAAA,CAAS;CAC1B,GAAG,CAAC,YAAY,CAAC;CAKjB,MAAM,cAAc;EAAE,UAAU;EAAY,OAAO;EAAY,QAAQ;EAAY,OAAO;CAAW,EAAE;CACvG,MAAM,mBAAmB,SAAS,cAAc,SAAS,UAAU,SAAS,SAAS,WAAW,SAAS;CACzG,MAAM,oBAAoB,SAAS,cAAc,SAAS,UAAU,SAAS,SAAS,WAAW,UAAU;CAE3G,OACI,qBAAC,OAAD;EACI,MAAK;EACL,cAAY,OAAO;EACV;EACT,WAAW,IAAI,2BACX,aACA,2BACA,oBACA,oIACA,gCACA,SAAS;YAVjB;GAWI,oBAAC,OAAD;IACI,WAAW,IAAI,kFAAkF,gBAAgB;cAChH,UAAU,oBAAC,kBAAD,EAAkB,MAAM,WAAY,CAAA,IAAI,oBAAC,YAAD;KAAY,WAAW;KAAmD,MAAM,SAAS,aAAa,KAAK,SAAS,UAAU,KAAK;IAAI,CAAA;GACzL,CAAA;GACL,oBAAC,SAAD;IACI,OAAO,cAAc;IACrB,KAAK;IACI;IACT,aAAa;IACb,cAAY;IACZ,UAAU,CAAC;IACD;IACV,UAAU,gBACH,UAAU;KACT,cAAc,MAAM,OAAO,KAAK;IACpC,IACE,KAAA;IACK;IACX,eAAe,UAAU,IAAI;IAC7B,cAAc,UAAU,KAAK;IAC7B,WAAW,KACN,YAAY,YAAY,uBACzB,iEACA,8JACA,mBAAmB,8BACnB,SAAS,UAAU,YAAY,IAC/B,aAAc,SAAS,cAAc,cAAe,IACpD,cACJ;GACH,CAAA;GACA,aACK,oBAAC,YAAD;IACE,WAAW,GAAG,SAAS,UAAU,eAAe,aAAa;IAC7D,MAAM;IACN,cAAY,OAAO;IACnB,SAAS;cACT,oBAAC,OAAD,EAAO,MAAM,SAAS,SAAU,CAAA;GACxB,CAAA,IACV,oBAAC,OAAD,EAAK,OAAO,EAAE,OAAO,GAAG,EAAG,CAAA;EAEhC;;AAEb"}
@@ -54,8 +54,15 @@ export type SelectItemProps<T extends SelectValue = string> = {
54
54
  children?: React.ReactNode;
55
55
  disabled?: boolean;
56
56
  className?: string;
57
+ /**
58
+ * The text a letter typed on the focused select matches this option by.
59
+ * Defaults to the option's text. Set it when the option is drawn by a
60
+ * component (a chip, an icon with a name inside it): a closed select with
61
+ * more than 50 options does not render them, so their text cannot be read.
62
+ */
63
+ textValue?: string;
57
64
  };
58
- export declare const SelectItem: React.MemoExoticComponent<(<T extends SelectValue = string>({ value, children, disabled, className }: SelectItemProps<T>) => React.JSX.Element)>;
65
+ export declare const SelectItem: React.MemoExoticComponent<(<T extends SelectValue = string>({ value, children, disabled, className, textValue }: SelectItemProps<T>) => React.JSX.Element)>;
59
66
  export type SelectGroupProps = {
60
67
  label: React.ReactNode;
61
68
  children: React.ReactNode;