@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":"VirtualTableCell.es.js","names":[],"sources":["../../../src/components/VirtualTable/VirtualTableCell.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { deepEqual as equal } from \"fast-equals\"\n\nimport { CellRendererParams, VirtualTableColumn } from \"./VirtualTableProps\";\n\ntype VirtualTableCellProps<T> = {\n dataKey: string;\n column: VirtualTableColumn;\n columns: VirtualTableColumn[];\n rowData: T | undefined;\n cellData: unknown;\n rowIndex: number;\n columnIndex: number;\n cellRenderer: (props: CellRendererParams<T>) => React.ReactNode;\n // Sortable props\n sortableNodeRef?: (node: HTMLElement | null) => void;\n sortableStyle?: React.CSSProperties;\n sortableAttributes?: Record<string, unknown>;\n isDragging?: boolean;\n isDraggable?: boolean;\n frozen?: boolean;\n extraData?: unknown;\n};\n\nexport const VirtualTableCell = React.memo<VirtualTableCellProps<unknown>>(\n function VirtualTableCell<T>(props: VirtualTableCellProps<T>) {\n // `undefined` is a row that exists but has not been read: the\n // renderer is still asked, with no `rowData`, so it can draw a\n // placeholder (see `VirtualTableProps.data`).\n return props.rowData !== null ? props.cellRenderer(\n {\n cellData: props.cellData,\n rowData: props.rowData,\n rowIndex: props.rowIndex,\n isScrolling: false,\n column: props.column,\n columns: props.columns,\n columnIndex: props.columnIndex,\n width: props.column.width,\n sortableNodeRef: props.sortableNodeRef,\n sortableStyle: props.sortableStyle,\n sortableAttributes: props.sortableAttributes,\n isDragging: props.isDragging,\n isDraggable: props.isDraggable,\n frozen: props.frozen,\n extraData: props.extraData\n } as CellRendererParams<T>\n ) : null;\n },\n areCellPropsEqual\n);\n\n/**\n * Every prop the cell hands `cellRenderer` is compared, and so is\n * `cellRenderer` itself: a cell that kept the renderer it was first given kept\n * every value that renderer closed over — inline editing switched off, a\n * permission revoked, a new row-actions builder — until its row changed.\n *\n * Values that a parent rebuilds on each render (the row, its cell value, the\n * column, `extraData`) are compared by value; `deepEqual` returns at once for\n * the same reference. Functions and `columns` are compared by reference —\n * `VirtualTable` holds `columns` by value already.\n */\nfunction areCellPropsEqual(a: VirtualTableCellProps<unknown>, b: VirtualTableCellProps<unknown>): boolean {\n return a.cellRenderer === b.cellRenderer &&\n a.columns === b.columns &&\n a.dataKey === b.dataKey &&\n a.rowIndex === b.rowIndex &&\n a.columnIndex === b.columnIndex &&\n a.isDragging === b.isDragging &&\n a.isDraggable === b.isDraggable &&\n a.frozen === b.frozen &&\n a.sortableNodeRef === b.sortableNodeRef &&\n a.sortableStyle === b.sortableStyle &&\n a.sortableAttributes === b.sortableAttributes &&\n equal(a.column, b.column) &&\n equal(a.cellData, b.cellData) &&\n equal(a.extraData, b.extraData) &&\n equal(a.rowData, b.rowData);\n}\n"],"mappings":";;;AAyBA,IAAa,mBAAmB,MAAM,KAClC,SAAS,iBAAoB,OAAiC;CAI1D,OAAO,MAAM,YAAY,OAAO,MAAM,aAClC;EACI,UAAU,MAAM;EAChB,SAAS,MAAM;EACf,UAAU,MAAM;EAChB,aAAa;EACb,QAAQ,MAAM;EACd,SAAS,MAAM;EACf,aAAa,MAAM;EACnB,OAAO,MAAM,OAAO;EACpB,iBAAiB,MAAM;EACvB,eAAe,MAAM;EACrB,oBAAoB,MAAM;EAC1B,YAAY,MAAM;EAClB,aAAa,MAAM;EACnB,QAAQ,MAAM;EACd,WAAW,MAAM;CACrB,CACJ,IAAI;AACR,GACA,iBACJ;;;;;;;;;;;;AAaA,SAAS,kBAAkB,GAAmC,GAA4C;CACtG,OAAO,EAAE,iBAAiB,EAAE,gBACxB,EAAE,YAAY,EAAE,WAChB,EAAE,YAAY,EAAE,WAChB,EAAE,aAAa,EAAE,YACjB,EAAE,gBAAgB,EAAE,eACpB,EAAE,eAAe,EAAE,cACnB,EAAE,gBAAgB,EAAE,eACpB,EAAE,WAAW,EAAE,UACf,EAAE,oBAAoB,EAAE,mBACxB,EAAE,kBAAkB,EAAE,iBACtB,EAAE,uBAAuB,EAAE,sBAC3B,UAAM,EAAE,QAAQ,EAAE,MAAM,KACxB,UAAM,EAAE,UAAU,EAAE,QAAQ,KAC5B,UAAM,EAAE,WAAW,EAAE,SAAS,KAC9B,UAAM,EAAE,SAAS,EAAE,OAAO;AAClC"}
@@ -0,0 +1,209 @@
1
+ import { defaultBorderMixin } from "../../styles.es.js";
2
+ import { cls } from "../../util/cls.es.js";
3
+ import { Button } from "../Button.es.js";
4
+ import { ErrorBoundary } from "../ErrorBoundary.es.js";
5
+ import { IconButton } from "../IconButton.es.js";
6
+ import { Popover } from "../Popover.es.js";
7
+ import { Badge } from "../Badge.es.js";
8
+ import React, { useCallback, useEffect, useState } from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { ArrowUpIcon, FilterIcon } from "lucide-react";
11
+ import { deepEqual } from "fast-equals";
12
+ //#region src/components/VirtualTable/VirtualTableHeader.tsx
13
+ /**
14
+ * What the next click on this column's sort control will do, spelled out for
15
+ * the tooltip and for screen readers. An unlabelled arrow that means three
16
+ * different things depending on the state it is in is a control you have to
17
+ * click to learn.
18
+ */
19
+ function sortActionTitle(sort, sortPosition) {
20
+ const rank = sortPosition !== void 0 ? ` (sort key ${sortPosition + 1})` : "";
21
+ const addKey = " — shift-click to add it under the current sort instead";
22
+ if (sort === "asc") return `Sorted ascending${rank}. Click to sort descending.${addKey}`;
23
+ if (sort === "desc") return `Sorted descending${rank}. Click to remove this sort.${addKey}`;
24
+ return `Click to sort ascending.${addKey}`;
25
+ }
26
+ var VirtualTableHeader = React.memo(function VirtualTableHeader({ resizeHandleRef, columnIndex, isResizingIndex, sort, sortPosition, onColumnSort, onFilterUpdate, filter, column, onClickResizeColumn, createFilterField, AdditionalHeaderWidget, isDragging, isDraggable }) {
27
+ const [onHover, setOnHover] = useState(false);
28
+ const [openFilter, setOpenFilter] = React.useState(false);
29
+ const [hidden, setHidden] = React.useState(false);
30
+ const handleSettingsClick = useCallback((_event) => {
31
+ setOpenFilter(true);
32
+ }, []);
33
+ const update = useCallback((filterForProperty, newOpenFilterState) => {
34
+ onFilterUpdate(column, filterForProperty);
35
+ if (newOpenFilterState !== void 0) setOpenFilter(newOpenFilterState);
36
+ }, [column, onFilterUpdate]);
37
+ const hovered = !(isResizingIndex !== columnIndex && isResizingIndex > 0) && (onHover || isResizingIndex === columnIndex);
38
+ return /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxs("div", {
39
+ className: cls("flex py-0 px-3 h-full text-xs uppercase font-semibold relative select-none items-center", isDragging ? "bg-primary-bg" : "bg-surface-sheet", "text-text-secondary hover:text-text-primary dark:text-text-secondary-dark dark:hover:text-text-primary-dark", !isDragging && "hover:bg-surface-hover", column.frozen ? "sticky left-0 z-10" : "relative z-0", isDraggable && "cursor-grab"),
40
+ style: {
41
+ left: column.frozen ? 0 : void 0,
42
+ minWidth: column.width,
43
+ maxWidth: column.width
44
+ },
45
+ onMouseEnter: () => setOnHover(true),
46
+ onMouseMove: () => setOnHover(true),
47
+ onMouseLeave: () => setOnHover(false),
48
+ children: [
49
+ /* @__PURE__ */ jsx("div", {
50
+ className: "overflow-hidden grow",
51
+ children: /* @__PURE__ */ jsxs("div", {
52
+ className: `flex items-center justify-${column.headerAlign} flex-row`,
53
+ children: [column.icon && /* @__PURE__ */ jsx("div", {
54
+ className: "flex-shrink-0 flex items-center justify-center mr-1",
55
+ children: React.isValidElement(column.icon) ? React.cloneElement(column.icon, {
56
+ size: 14,
57
+ className: cls(column.icon.props?.className, "flex-shrink-0")
58
+ }) : column.icon
59
+ }), /* @__PURE__ */ jsx("div", {
60
+ className: "truncate -webkit-box w-full mr-1 overflow-hidden",
61
+ style: {
62
+ WebkitBoxOrient: "vertical",
63
+ WebkitLineClamp: 2,
64
+ justifyContent: column.align
65
+ },
66
+ children: column.title
67
+ })]
68
+ })
69
+ }),
70
+ /* @__PURE__ */ jsxs(Fragment, { children: [AdditionalHeaderWidget && /* @__PURE__ */ jsx(AdditionalHeaderWidget, { onHover: onHover || openFilter }), column.sortable && (sort || hovered || openFilter) && /* @__PURE__ */ jsxs("div", {
71
+ className: "flex-shrink-0 flex items-center",
72
+ children: [/* @__PURE__ */ jsx(Badge, {
73
+ color: "secondary",
74
+ invisible: !sort,
75
+ children: /* @__PURE__ */ jsxs(IconButton, {
76
+ size: "small",
77
+ className: onHover || openFilter ? "bg-surface-card" : void 0,
78
+ title: sortActionTitle(sort, sortPosition),
79
+ "aria-label": sortActionTitle(sort, sortPosition),
80
+ onClick: (event) => {
81
+ onColumnSort(column.key, event.shiftKey);
82
+ },
83
+ children: [
84
+ !sort && /* @__PURE__ */ jsx(ArrowUpIcon, {
85
+ size: 14,
86
+ className: "flex-shrink-0"
87
+ }),
88
+ sort === "asc" && /* @__PURE__ */ jsx(ArrowUpIcon, {
89
+ size: 14,
90
+ className: "flex-shrink-0"
91
+ }),
92
+ sort === "desc" && /* @__PURE__ */ jsx(ArrowUpIcon, {
93
+ size: 14,
94
+ className: "flex-shrink-0 rotate-180"
95
+ })
96
+ ]
97
+ })
98
+ }), sort && sortPosition !== void 0 && /* @__PURE__ */ jsx("span", {
99
+ className: "flex-shrink-0 -ml-0.5 mr-0.5 text-[10px] font-semibold leading-none tabular-nums text-text-secondary dark:text-text-secondary-dark",
100
+ "aria-hidden": true,
101
+ children: sortPosition + 1
102
+ })]
103
+ })] }),
104
+ column.filter && createFilterField && /* @__PURE__ */ jsx("div", {
105
+ className: "flex-shrink-0",
106
+ children: /* @__PURE__ */ jsx(Badge, {
107
+ color: "secondary",
108
+ invisible: !filter,
109
+ children: /* @__PURE__ */ jsx(Popover, {
110
+ open: openFilter,
111
+ onOpenChange: setOpenFilter,
112
+ className: hidden ? "hidden" : void 0,
113
+ modal: true,
114
+ trigger: /* @__PURE__ */ jsx(IconButton, {
115
+ "aria-label": column.title ? `Filter ${column.title}` : "Filter",
116
+ className: onHover || openFilter ? "bg-surface-card" : void 0,
117
+ size: "small",
118
+ onClick: handleSettingsClick,
119
+ children: /* @__PURE__ */ jsx(FilterIcon, {
120
+ size: 14,
121
+ className: "flex-shrink-0"
122
+ })
123
+ }),
124
+ children: /* @__PURE__ */ jsx(FilterForm, {
125
+ column,
126
+ filter,
127
+ onHover,
128
+ onFilterUpdate: update,
129
+ createFilterField,
130
+ hidden,
131
+ setHidden
132
+ })
133
+ })
134
+ })
135
+ }),
136
+ column.resizable && /* @__PURE__ */ jsx("div", {
137
+ ref: resizeHandleRef,
138
+ "data-no-dnd": "true",
139
+ className: cls("absolute h-full w-[6px] top-0 right-0 cursor-col-resize", hovered && "bg-hairline-strong"),
140
+ onPointerDown: (e) => {
141
+ e.stopPropagation();
142
+ if (onClickResizeColumn) onClickResizeColumn(columnIndex, column);
143
+ }
144
+ })
145
+ ]
146
+ }) });
147
+ }, deepEqual);
148
+ function FilterForm({ column, onFilterUpdate, filter, onHover, createFilterField, hidden, setHidden }) {
149
+ const id = column.key;
150
+ const [filterInternal, setFilterInternal] = useState(filter);
151
+ useEffect(() => {
152
+ setFilterInternal(filter);
153
+ }, [filter]);
154
+ if (!column.filter) return null;
155
+ const submit = () => {
156
+ onFilterUpdate(filterInternal, false);
157
+ };
158
+ const reset = (_e) => {
159
+ onFilterUpdate(void 0, false);
160
+ };
161
+ const filterIsSet = !!filter;
162
+ const filterField = createFilterField({
163
+ id,
164
+ filterValue: filterInternal,
165
+ setFilterValue: setFilterInternal,
166
+ column,
167
+ hidden,
168
+ setHidden
169
+ });
170
+ if (!filterField) return null;
171
+ return /* @__PURE__ */ jsxs("form", {
172
+ noValidate: true,
173
+ onSubmit: (e) => {
174
+ e.stopPropagation();
175
+ e.preventDefault();
176
+ submit();
177
+ },
178
+ className: "text-surface-900 dark:text-white",
179
+ children: [
180
+ /* @__PURE__ */ jsx("div", {
181
+ className: cls(defaultBorderMixin, "py-4 px-6 typography-label border-b"),
182
+ children: column.title ?? id
183
+ }),
184
+ filterField && /* @__PURE__ */ jsx("div", {
185
+ className: "m-4 w-[400px]",
186
+ children: filterField
187
+ }),
188
+ /* @__PURE__ */ jsxs("div", {
189
+ className: "flex justify-end m-4",
190
+ children: [/* @__PURE__ */ jsx(Button, {
191
+ className: "mr-4",
192
+ disabled: !filterIsSet,
193
+ variant: "text",
194
+ type: "reset",
195
+ "aria-label": "filter clear",
196
+ onClick: reset,
197
+ children: "Clear"
198
+ }), /* @__PURE__ */ jsx(Button, {
199
+ type: "submit",
200
+ children: "Filter"
201
+ })]
202
+ })
203
+ ]
204
+ });
205
+ }
206
+ //#endregion
207
+ export { VirtualTableHeader };
208
+
209
+ //# sourceMappingURL=VirtualTableHeader.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualTableHeader.es.js","names":[],"sources":["../../../src/components/VirtualTable/VirtualTableHeader.tsx"],"sourcesContent":["import { ArrowUpIcon, FilterIcon } from \"lucide-react\";\nimport { iconSize } from \"../../icons/Icon\";\n\nimport React, { RefObject, useCallback, useEffect, useState } from \"react\";\nimport { deepEqual as equal } from \"fast-equals\";\n\nimport { VirtualTableColumn, VirtualTableSort, VirtualTableWhereFilterOp } from \"./VirtualTableProps\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport { Badge } from \"../Badge\";\nimport { Button } from \"../Button\";\nimport { IconButton } from \"../IconButton\";\nimport { Popover } from \"../Popover\";\nimport { defaultBorderMixin } from \"../../styles\";\nimport { cls } from \"../../util/cls\";\ninterface FilterFormProps<T> {\n column: VirtualTableColumn<T>;\n onFilterUpdate: (filter?: [VirtualTableWhereFilterOp, unknown], newOpenFilterState?: boolean) => void;\n filter?: [VirtualTableWhereFilterOp, unknown];\n onHover: boolean,\n createFilterField: (props: FilterFormFieldProps<T>) => React.ReactNode;\n hidden: boolean;\n setHidden: (hidden: boolean) => void;\n}\n\nexport type FilterFormFieldProps<CustomProps> = {\n id: React.Key,\n filterValue: [VirtualTableWhereFilterOp, unknown] | undefined,\n setFilterValue: (filterValue?: [VirtualTableWhereFilterOp, unknown]) => void;\n column: VirtualTableColumn<CustomProps>;\n hidden: boolean;\n setHidden: (hidden: boolean) => void;\n};\n\ntype VirtualTableHeaderProps<M extends object> = {\n resizeHandleRef: React.Ref<HTMLDivElement>;\n columnIndex: number;\n isResizingIndex: number;\n column: VirtualTableColumn<unknown>;\n onColumnSort: (key: Extract<keyof M, string>, additive?: boolean) => void;\n filter?: [VirtualTableWhereFilterOp, unknown];\n sort: VirtualTableSort;\n /**\n * This column's zero-based rank in a multi-key sort, or `undefined` when\n * only one column is sorted and a rank would say nothing.\n */\n sortPosition?: number;\n onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, unknown]) => void;\n onClickResizeColumn?: (columnIndex: number, column: VirtualTableColumn) => void;\n createFilterField?: (props: FilterFormFieldProps<unknown>) => React.ReactNode;\n AdditionalHeaderWidget?: (props: { onHover: boolean }) => React.ReactNode;\n isDragging?: boolean;\n isDraggable?: boolean;\n};\n\n/**\n * What the next click on this column's sort control will do, spelled out for\n * the tooltip and for screen readers. An unlabelled arrow that means three\n * different things depending on the state it is in is a control you have to\n * click to learn.\n */\nfunction sortActionTitle(sort: VirtualTableSort, sortPosition?: number): string {\n const rank = sortPosition !== undefined ? ` (sort key ${sortPosition + 1})` : \"\";\n const addKey = \" — shift-click to add it under the current sort instead\";\n if (sort === \"asc\") return `Sorted ascending${rank}. Click to sort descending.${addKey}`;\n if (sort === \"desc\") return `Sorted descending${rank}. Click to remove this sort.${addKey}`;\n return `Click to sort ascending.${addKey}`;\n}\n\nexport const VirtualTableHeader = React.memo<VirtualTableHeaderProps<Record<string, unknown>>>(\n function VirtualTableHeader<M extends object>({\n resizeHandleRef,\n columnIndex,\n isResizingIndex,\n sort,\n sortPosition,\n onColumnSort,\n onFilterUpdate,\n filter,\n column,\n onClickResizeColumn,\n createFilterField,\n AdditionalHeaderWidget,\n isDragging,\n isDraggable\n }: VirtualTableHeaderProps<M>) {\n\n const [onHover, setOnHover] = useState(false);\n\n const [openFilter, setOpenFilter] = React.useState(false);\n const [hidden, setHidden] = React.useState(false);\n\n const handleSettingsClick = useCallback((_event: React.MouseEvent) => {\n setOpenFilter(true);\n }, []);\n\n const update = useCallback((filterForProperty?: [VirtualTableWhereFilterOp, unknown], newOpenFilterState?: boolean) => {\n onFilterUpdate(column, filterForProperty);\n if (newOpenFilterState !== undefined)\n setOpenFilter(newOpenFilterState);\n }, [column, onFilterUpdate]);\n\n const thisColumnIsResizing = isResizingIndex === columnIndex;\n const anotherColumnIsResizing = isResizingIndex !== columnIndex && isResizingIndex > 0;\n\n const hovered = !anotherColumnIsResizing && (onHover || thisColumnIsResizing);\n\n return (\n <ErrorBoundary>\n <div\n className={cls(\"flex py-0 px-3 h-full text-xs uppercase font-semibold relative select-none items-center\",\n isDragging\n ? \"bg-primary-bg\"\n : \"bg-surface-sheet\",\n \"text-text-secondary hover:text-text-primary dark:text-text-secondary-dark dark:hover:text-text-primary-dark\",\n !isDragging && \"hover:bg-surface-hover\",\n column.frozen ? \"sticky left-0 z-10\" : \"relative z-0\",\n isDraggable && \"cursor-grab\"\n )}\n style={{\n left: column.frozen ? 0 : undefined,\n minWidth: column.width,\n maxWidth: column.width\n }}\n onMouseEnter={() => setOnHover(true)}\n onMouseMove={() => setOnHover(true)}\n onMouseLeave={() => setOnHover(false)}\n >\n\n <div className=\"overflow-hidden grow\">\n <div\n className={`flex items-center justify-${column.headerAlign} flex-row`}>\n\n {column.icon && (\n <div className=\"flex-shrink-0 flex items-center justify-center mr-1\">\n {React.isValidElement(column.icon) ? (\n React.cloneElement(column.icon as React.ReactElement<any>, {\n size: 14,\n className: cls((column.icon as React.ReactElement<any>).props?.className, \"flex-shrink-0\")\n })\n ) : (\n column.icon\n )}\n </div>\n )}\n\n <div\n className=\"truncate -webkit-box w-full mr-1 overflow-hidden\"\n style={{\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: 2,\n justifyContent: column.align\n }}>\n {column.title}\n </div>\n\n </div>\n </div>\n <>\n\n {AdditionalHeaderWidget &&\n <AdditionalHeaderWidget onHover={onHover || openFilter}/>}\n\n {column.sortable && (sort || hovered || openFilter) &&\n <div className=\"flex-shrink-0 flex items-center\">\n <Badge color=\"secondary\"\n invisible={!sort}>\n <IconButton\n size={\"small\"}\n className={onHover || openFilter ? \"bg-surface-card\" : undefined}\n // Shift keeps the sort already in place\n // and adds this column beneath it, which\n // is how a two-key order is built from\n // header clicks. Plain click still\n // replaces the whole sort, so the common\n // case takes no modifier and nothing a\n // user knew before stops working.\n title={sortActionTitle(sort, sortPosition)}\n aria-label={sortActionTitle(sort, sortPosition)}\n onClick={(event: React.MouseEvent) => {\n onColumnSort(column.key as Extract<keyof M, string>, event.shiftKey);\n }}\n >\n {!sort &&\n <ArrowUpIcon size={14} className=\"flex-shrink-0\" />}\n {sort === \"asc\" &&\n <ArrowUpIcon size={14} className=\"flex-shrink-0\" />}\n {sort === \"desc\" &&\n <ArrowUpIcon size={14} className=\"flex-shrink-0 rotate-180\" />}\n </IconButton>\n </Badge>\n {/* The rank, shown only once there is more than\n one key: two arrows with no numbers beside\n them say a table is sorted by both columns\n and nothing about which one decides. */}\n {sort && sortPosition !== undefined && (\n <span\n className=\"flex-shrink-0 -ml-0.5 mr-0.5 text-[10px] font-semibold leading-none tabular-nums text-text-secondary dark:text-text-secondary-dark\"\n aria-hidden={true}\n >\n {sortPosition + 1}\n </span>\n )}\n </div>\n }\n </>\n\n {column.filter && createFilterField && <div className=\"flex-shrink-0\">\n <Badge color=\"secondary\"\n invisible={!filter}>\n\n <Popover\n open={openFilter}\n onOpenChange={setOpenFilter}\n className={hidden ? \"hidden\" : undefined}\n modal={true}\n trigger={\n <IconButton\n aria-label={column.title ? `Filter ${column.title}` : \"Filter\"}\n className={onHover || openFilter ? \"bg-surface-card\" : undefined}\n size={\"small\"}\n onClick={handleSettingsClick}>\n <FilterIcon size={14} className=\"flex-shrink-0\"/>\n </IconButton>}\n >\n <FilterForm column={column}\n filter={filter}\n onHover={onHover}\n onFilterUpdate={update}\n createFilterField={createFilterField}\n hidden={hidden}\n setHidden={setHidden}/>\n\n </Popover>\n\n </Badge>\n\n </div>}\n\n {column.resizable && <div\n ref={resizeHandleRef as React.Ref<HTMLDivElement>}\n data-no-dnd=\"true\"\n className={cls(\n \"absolute h-full w-[6px] top-0 right-0 cursor-col-resize\",\n hovered && \"bg-hairline-strong\"\n )}\n onPointerDown={(e) => {\n e.stopPropagation();\n if (onClickResizeColumn) {\n onClickResizeColumn(columnIndex, column);\n }\n }}\n />}\n </div>\n\n </ErrorBoundary>\n );\n }, equal) as React.FunctionComponent<VirtualTableHeaderProps<Record<string, unknown>>>;\n\nfunction FilterForm<M>({\n column,\n onFilterUpdate,\n filter,\n onHover,\n createFilterField,\n hidden,\n setHidden\n}: FilterFormProps<M>) {\n\n const id = column.key;\n\n const [filterInternal, setFilterInternal] = useState<[VirtualTableWhereFilterOp, unknown] | undefined>(filter);\n\n useEffect(() => {\n setFilterInternal(filter);\n }, [filter]);\n\n if (!column.filter) return null;\n\n const submit = () => {\n onFilterUpdate(filterInternal, false);\n };\n\n const reset = (_e: React.MouseEvent) => {\n onFilterUpdate(undefined, false);\n };\n\n const filterIsSet = !!filter;\n\n const filterField = createFilterField({\n id,\n filterValue: filterInternal,\n setFilterValue: setFilterInternal,\n column,\n hidden,\n setHidden\n });\n\n if (!filterField) return null;\n return (\n <form noValidate={true}\n onSubmit={(e) => {\n e.stopPropagation();\n e.preventDefault();\n submit();\n }}\n className={\"text-surface-900 dark:text-white\"}>\n <div\n className={cls(defaultBorderMixin, \"py-4 px-6 typography-label border-b\")}>\n {column.title ?? id}\n </div>\n {filterField && <div className=\"m-4 w-[400px]\">\n {filterField}\n </div>}\n <div className=\"flex justify-end m-4\">\n <Button\n className=\"mr-4\"\n disabled={!filterIsSet}\n variant={\"text\"}\n type=\"reset\"\n aria-label=\"filter clear\"\n onClick={reset}>Clear</Button>\n <Button\n type=\"submit\">Filter</Button>\n </div>\n </form>\n );\n\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4DA,SAAS,gBAAgB,MAAwB,cAA+B;CAC5E,MAAM,OAAO,iBAAiB,KAAA,IAAY,cAAc,eAAe,EAAE,KAAK;CAC9E,MAAM,SAAS;CACf,IAAI,SAAS,OAAO,OAAO,mBAAmB,KAAK,6BAA6B;CAChF,IAAI,SAAS,QAAQ,OAAO,oBAAoB,KAAK,8BAA8B;CACnF,OAAO,2BAA2B;AACtC;AAEA,IAAa,qBAAqB,MAAM,KACpC,SAAS,mBAAqC,EAC1C,iBACA,aACA,iBACA,MACA,cACA,cACA,gBACA,QACA,QACA,qBACA,mBACA,wBACA,YACA,eAC2B;CAE3B,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,CAAC,YAAY,iBAAiB,MAAM,SAAS,KAAK;CACxD,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,KAAK;CAEhD,MAAM,sBAAsB,aAAa,WAA6B;EAClE,cAAc,IAAI;CACtB,GAAG,CAAC,CAAC;CAEL,MAAM,SAAS,aAAa,mBAA0D,uBAAiC;EACnH,eAAe,QAAQ,iBAAiB;EACxC,IAAI,uBAAuB,KAAA,GACvB,cAAc,kBAAkB;CACxC,GAAG,CAAC,QAAQ,cAAc,CAAC;CAK3B,MAAM,UAAU,EAFgB,oBAAoB,eAAe,kBAAkB,OAExC,WAHhB,oBAAoB;CAKjD,OACI,oBAAC,eAAD,EAAA,UACI,qBAAC,OAAD;EACI,WAAW,IAAI,2FACX,aACM,kBACA,oBACN,+GACA,CAAC,cAAc,0BACf,OAAO,SAAS,uBAAuB,gBACvC,eAAe,aACnB;EACA,OAAO;GACH,MAAM,OAAO,SAAS,IAAI,KAAA;GAC1B,UAAU,OAAO;GACjB,UAAU,OAAO;EACrB;EACA,oBAAoB,WAAW,IAAI;EACnC,mBAAmB,WAAW,IAAI;EAClC,oBAAoB,WAAW,KAAK;YAjBxC;GAoBI,oBAAC,OAAD;IAAK,WAAU;cACX,qBAAC,OAAD;KACI,WAAW,6BAA6B,OAAO,YAAY;eAD/D,CAGK,OAAO,QACJ,oBAAC,OAAD;MAAK,WAAU;gBACV,MAAM,eAAe,OAAO,IAAI,IAC7B,MAAM,aAAa,OAAO,MAAiC;OACvD,MAAM;OACN,WAAW,IAAK,OAAO,KAAiC,OAAO,WAAW,eAAe;MAC7F,CAAC,IAED,OAAO;KAEV,CAAA,GAGT,oBAAC,OAAD;MACI,WAAU;MACV,OAAO;OACH,iBAAiB;OACjB,iBAAiB;OACjB,gBAAgB,OAAO;MAC3B;gBACC,OAAO;KACP,CAAA,CAEJ;;GACJ,CAAA;GACL,qBAAA,UAAA,EAAA,UAAA,CAEK,0BACG,oBAAC,wBAAD,EAAwB,SAAS,WAAW,WAAY,CAAA,GAE3D,OAAO,aAAa,QAAQ,WAAW,eACpC,qBAAC,OAAD;IAAK,WAAU;cAAf,CACI,oBAAC,OAAD;KAAO,OAAM;KACT,WAAW,CAAC;eACZ,qBAAC,YAAD;MACI,MAAM;MACN,WAAW,WAAW,aAAa,oBAAoB,KAAA;MAQvD,OAAO,gBAAgB,MAAM,YAAY;MACzC,cAAY,gBAAgB,MAAM,YAAY;MAC9C,UAAU,UAA4B;OAClC,aAAa,OAAO,KAAiC,MAAM,QAAQ;MACvE;gBAdJ;OAgBK,CAAC,QACE,oBAAC,aAAD;QAAa,MAAM;QAAI,WAAU;OAAiB,CAAA;OACrD,SAAS,SACN,oBAAC,aAAD;QAAa,MAAM;QAAI,WAAU;OAAiB,CAAA;OACrD,SAAS,UACN,oBAAC,aAAD;QAAa,MAAM;QAAI,WAAU;OAA4B,CAAA;MACzD;;IACT,CAAA,GAKN,QAAQ,iBAAiB,KAAA,KACtB,oBAAC,QAAD;KACI,WAAU;KACV,eAAa;eAEZ,eAAe;IACd,CAAA,CAET;KAEX,EAAA,CAAA;GAED,OAAO,UAAU,qBAAqB,oBAAC,OAAD;IAAK,WAAU;cAClD,oBAAC,OAAD;KAAO,OAAM;KACT,WAAW,CAAC;eAEZ,oBAAC,SAAD;MACI,MAAM;MACN,cAAc;MACd,WAAW,SAAS,WAAW,KAAA;MAC/B,OAAO;MACP,SACI,oBAAC,YAAD;OACI,cAAY,OAAO,QAAQ,UAAU,OAAO,UAAU;OACtD,WAAW,WAAW,aAAa,oBAAoB,KAAA;OACvD,MAAM;OACN,SAAS;iBACT,oBAAC,YAAD;QAAY,MAAM;QAAI,WAAU;OAAgB,CAAA;MACxC,CAAA;gBAEhB,oBAAC,YAAD;OAAoB;OACR;OACC;OACT,gBAAgB;OACG;OACX;OACG;MAAW,CAAA;KAErB,CAAA;IAEN,CAAA;GAEN,CAAA;GAEJ,OAAO,aAAa,oBAAC,OAAD;IACjB,KAAK;IACL,eAAY;IACZ,WAAW,IACP,2DACA,WAAW,oBACf;IACA,gBAAgB,MAAM;KAClB,EAAE,gBAAgB;KAClB,IAAI,qBACA,oBAAoB,aAAa,MAAM;IAE/C;GACH,CAAA;EACA;IAEM,CAAA;AAEvB,GAAG,SAAK;AAEZ,SAAS,WAAc,EACnB,QACA,gBACA,QACA,SACA,mBACA,QACA,aACmB;CAEnB,MAAM,KAAK,OAAO;CAElB,MAAM,CAAC,gBAAgB,qBAAqB,SAA2D,MAAM;CAE7G,gBAAgB;EACZ,kBAAkB,MAAM;CAC5B,GAAG,CAAC,MAAM,CAAC;CAEX,IAAI,CAAC,OAAO,QAAQ,OAAO;CAE3B,MAAM,eAAe;EACjB,eAAe,gBAAgB,KAAK;CACxC;CAEA,MAAM,SAAS,OAAyB;EACpC,eAAe,KAAA,GAAW,KAAK;CACnC;CAEA,MAAM,cAAc,CAAC,CAAC;CAEtB,MAAM,cAAc,kBAAkB;EAClC;EACA,aAAa;EACb,gBAAgB;EAChB;EACA;EACA;CACJ,CAAC;CAED,IAAI,CAAC,aAAa,OAAO;CACzB,OACI,qBAAC,QAAD;EAAM,YAAY;EACd,WAAW,MAAM;GACb,EAAE,gBAAgB;GAClB,EAAE,eAAe;GACjB,OAAO;EACX;EACA,WAAW;YANf;GAOI,oBAAC,OAAD;IACI,WAAW,IAAI,oBAAoB,qCAAqC;cACvE,OAAO,SAAS;GAChB,CAAA;GACJ,eAAe,oBAAC,OAAD;IAAK,WAAU;cAC1B;GACA,CAAA;GACL,qBAAC,OAAD;IAAK,WAAU;cAAf,CACI,oBAAC,QAAD;KACI,WAAU;KACV,UAAU,CAAC;KACX,SAAS;KACT,MAAK;KACL,cAAW;KACX,SAAS;eAAO;IAAa,CAAA,GACjC,oBAAC,QAAD;KACI,MAAK;eAAS;IAAc,CAAA,CAC/B;;EACH;;AAGd"}
@@ -0,0 +1,166 @@
1
+ import { defaultBorderMixin } from "../../styles.es.js";
2
+ import { cls } from "../../util/cls.es.js";
3
+ import { ErrorBoundary } from "../ErrorBoundary.es.js";
4
+ import { VirtualTableHeader } from "./VirtualTableHeader.es.js";
5
+ import React, { createRef, useCallback, useEffect, useMemo, useState } from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { useSortable } from "@dnd-kit/sortable";
8
+ //#region src/components/VirtualTable/VirtualTableHeaderRow.tsx
9
+ var SortableColumnHeader = ({ column, columnIndex, columnRefs, isResizing, onFilterUpdate, filter, sortIndex, sortCount, onColumnSort, onClickResizeColumn, createFilterField, isDragging, isDraggable }) => {
10
+ const [isPressing, setIsPressing] = useState(false);
11
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
12
+ id: column.key,
13
+ disabled: !isDraggable || column.frozen
14
+ });
15
+ const style = {
16
+ transform: transform ? `translateX(${transform.x}px)` : void 0,
17
+ transition: isDragging ? void 0 : transition,
18
+ minWidth: column.width,
19
+ maxWidth: column.width,
20
+ width: column.width
21
+ };
22
+ const combinedListeners = isDraggable ? {
23
+ ...listeners,
24
+ onPointerDown: (e) => {
25
+ setIsPressing(true);
26
+ listeners?.onPointerDown?.(e);
27
+ },
28
+ onPointerUp: () => setIsPressing(false),
29
+ onPointerCancel: () => setIsPressing(false)
30
+ } : {};
31
+ React.useEffect(() => {
32
+ if (!isDragging) setIsPressing(false);
33
+ }, [isDragging]);
34
+ return /* @__PURE__ */ jsx("div", {
35
+ ref: setNodeRef,
36
+ style,
37
+ className: cls("flex-shrink-0 h-full", column.frozen && "sticky left-0 z-10"),
38
+ ...attributes,
39
+ ...combinedListeners,
40
+ children: /* @__PURE__ */ jsx(VirtualTableHeader, {
41
+ resizeHandleRef: columnRefs[columnIndex],
42
+ columnIndex,
43
+ isResizingIndex: isResizing,
44
+ onFilterUpdate,
45
+ filter,
46
+ sort: sortIndex.get(column.key)?.direction,
47
+ sortPosition: sortCount > 1 ? sortIndex.get(column.key)?.position : void 0,
48
+ onColumnSort,
49
+ onClickResizeColumn,
50
+ column,
51
+ createFilterField,
52
+ AdditionalHeaderWidget: column.AdditionalHeaderWidget,
53
+ isDragging: isDragging || isPressing,
54
+ isDraggable
55
+ })
56
+ });
57
+ };
58
+ var VirtualTableHeaderRow = ({ columns, sortIndex, onColumnSort, onFilterUpdate, filter, onColumnResize, onColumnResizeEnd, createFilterField, AddColumnComponent, onColumnsOrderChange, data, cellRenderer: CellRenderer, rowHeight = 54, draggingColumnId, headerHeight = 40 }) => {
59
+ const columnRefs = useMemo(() => columns.map(() => createRef()), [columns.length]);
60
+ const [isResizing, setIsResizing] = useState(-1);
61
+ const adjustWidthColumn = useCallback((index, width, end) => {
62
+ const column = columns[index];
63
+ const minWidth = 100;
64
+ const maxWidth = 800;
65
+ const newWidth = width > maxWidth ? maxWidth : width < minWidth ? minWidth : width;
66
+ const params = {
67
+ width: newWidth,
68
+ key: column.key,
69
+ column: {
70
+ ...column,
71
+ width: newWidth
72
+ }
73
+ };
74
+ if (!end) onColumnResize(params);
75
+ else onColumnResizeEnd(params);
76
+ }, [
77
+ columns,
78
+ onColumnResize,
79
+ onColumnResizeEnd
80
+ ]);
81
+ const getEventNewWidth = useCallback((e) => {
82
+ if (isResizing >= 0) {
83
+ const left = columnRefs[isResizing].current?.parentElement?.getBoundingClientRect().left;
84
+ if (!left) return;
85
+ return e.clientX - left;
86
+ }
87
+ }, [columnRefs, isResizing]);
88
+ const setCursorDocument = useCallback((isResizing) => {
89
+ document.body.style.cursor = isResizing ? "col-resize" : "auto";
90
+ }, []);
91
+ const handleOnMouseMove = useCallback((e) => {
92
+ e.stopPropagation();
93
+ e.preventDefault();
94
+ const newWidth = getEventNewWidth(e);
95
+ if (newWidth) adjustWidthColumn(isResizing, newWidth, false);
96
+ }, [
97
+ adjustWidthColumn,
98
+ getEventNewWidth,
99
+ isResizing
100
+ ]);
101
+ const handleOnMouseUp = useCallback((e) => {
102
+ e.stopPropagation();
103
+ e.preventDefault();
104
+ const newWidth = getEventNewWidth(e);
105
+ if (newWidth) adjustWidthColumn(isResizing, newWidth, true);
106
+ setIsResizing(-1);
107
+ setCursorDocument(false);
108
+ }, [
109
+ adjustWidthColumn,
110
+ getEventNewWidth,
111
+ isResizing,
112
+ setCursorDocument
113
+ ]);
114
+ const removeResizingListeners = useCallback(() => {
115
+ document.removeEventListener("mousemove", handleOnMouseMove);
116
+ document.removeEventListener("mouseup", handleOnMouseUp);
117
+ }, [handleOnMouseMove, handleOnMouseUp]);
118
+ const attachResizeListeners = useCallback(() => {
119
+ document.addEventListener("mousemove", handleOnMouseMove);
120
+ document.addEventListener("mouseup", handleOnMouseUp);
121
+ }, [handleOnMouseMove, handleOnMouseUp]);
122
+ useEffect(() => {
123
+ if (isResizing >= 0) attachResizeListeners();
124
+ else removeResizingListeners();
125
+ return () => {
126
+ removeResizingListeners();
127
+ };
128
+ }, [
129
+ attachResizeListeners,
130
+ isResizing,
131
+ removeResizingListeners
132
+ ]);
133
+ const onClickResizeColumn = useCallback((index) => {
134
+ setIsResizing(index);
135
+ setCursorDocument(true);
136
+ }, [setCursorDocument]);
137
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", {
138
+ className: cls(defaultBorderMixin, "z-20 sticky min-w-full flex w-fit flex-row top-0 left-0 border-b bg-surface-sheet"),
139
+ style: { height: headerHeight },
140
+ children: [columns.map((column, columnIndex) => {
141
+ const columnFilter = column && filter && filter[column.key] ? filter[column.key] : void 0;
142
+ const filterForThisProperty = columnFilter ? Array.isArray(columnFilter[0]) ? columnFilter[0] : columnFilter : void 0;
143
+ const isDraggable = !column.frozen && !!onColumnsOrderChange;
144
+ const isDragging = draggingColumnId === column.key;
145
+ return /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(SortableColumnHeader, {
146
+ column,
147
+ columnIndex,
148
+ columnRefs,
149
+ isResizing,
150
+ onFilterUpdate,
151
+ filter: filterForThisProperty,
152
+ sortIndex,
153
+ sortCount: sortIndex.size,
154
+ onColumnSort,
155
+ onClickResizeColumn,
156
+ createFilterField,
157
+ isDragging,
158
+ isDraggable
159
+ }) }, "header_" + column.key);
160
+ }), AddColumnComponent && /* @__PURE__ */ jsx(AddColumnComponent, {})]
161
+ }) });
162
+ };
163
+ //#endregion
164
+ export { VirtualTableHeaderRow };
165
+
166
+ //# sourceMappingURL=VirtualTableHeaderRow.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualTableHeaderRow.es.js","names":[],"sources":["../../../src/components/VirtualTable/VirtualTableHeaderRow.tsx"],"sourcesContent":["import React, { createRef, useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { VirtualTableColumn, VirtualTableWhereFilterOp } from \"./VirtualTableProps\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport { VirtualTableHeader } from \"./VirtualTableHeader\";\nimport { VirtualTableContextProps } from \"./types\";\nimport { defaultBorderMixin } from \"../../styles\";\nimport { cls } from \"../../util/cls\";import { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\n\n// Sortable column header wrapper\nconst SortableColumnHeader = ({\n column,\n columnIndex,\n columnRefs,\n isResizing,\n onFilterUpdate,\n filter,\n sortIndex,\n sortCount,\n onColumnSort,\n onClickResizeColumn,\n createFilterField,\n isDragging,\n isDraggable\n}: {\n column: VirtualTableColumn;\n columnIndex: number;\n columnRefs: React.Ref<HTMLDivElement>[];\n isResizing: number;\n onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, unknown]) => void;\n filter: [VirtualTableWhereFilterOp, unknown] | undefined;\n sortIndex: Map<string, { direction: \"asc\" | \"desc\"; position: number }>;\n sortCount: number;\n onColumnSort: (key: string, additive?: boolean) => void;\n onClickResizeColumn: (index: number) => void;\n createFilterField: ((props: import(\"./VirtualTableHeader\").FilterFormFieldProps<unknown>) => React.ReactNode) | undefined;\n isDragging: boolean;\n isDraggable: boolean;\n}) => {\n const [isPressing, setIsPressing] = useState(false);\n\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition\n } = useSortable({\n id: column.key,\n disabled: !isDraggable || column.frozen\n });\n\n const style = {\n // Only use translate, ignore any scale transforms\n transform: transform ? `translateX(${transform.x}px)` : undefined,\n // Don't transition the dragged item - only other items should animate\n transition: isDragging ? undefined : transition,\n minWidth: column.width,\n maxWidth: column.width,\n width: column.width\n };\n\n // Combine our press handlers with dnd-kit listeners\n const combinedListeners = isDraggable ? {\n ...listeners,\n onPointerDown: (e: React.PointerEvent) => {\n setIsPressing(true);\n listeners?.onPointerDown?.(e);\n },\n onPointerUp: () => setIsPressing(false),\n onPointerCancel: () => setIsPressing(false)\n } : {};\n\n // Reset pressing state when drag ends\n React.useEffect(() => {\n if (!isDragging) {\n setIsPressing(false);\n }\n }, [isDragging]);\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={cls(\n \"flex-shrink-0 h-full\",\n column.frozen && \"sticky left-0 z-10\"\n )}\n {...attributes}\n {...combinedListeners}\n >\n <VirtualTableHeader\n resizeHandleRef={columnRefs[columnIndex]}\n columnIndex={columnIndex}\n isResizingIndex={isResizing}\n onFilterUpdate={onFilterUpdate}\n filter={filter}\n sort={sortIndex.get(column.key)?.direction}\n sortPosition={sortCount > 1 ? sortIndex.get(column.key)?.position : undefined}\n onColumnSort={onColumnSort}\n onClickResizeColumn={onClickResizeColumn}\n column={column}\n createFilterField={createFilterField}\n AdditionalHeaderWidget={column.AdditionalHeaderWidget}\n isDragging={isDragging || isPressing}\n isDraggable={isDraggable}/>\n </div>\n );\n};\n\nexport const VirtualTableHeaderRow = ({\n columns,\n sortIndex,\n onColumnSort,\n onFilterUpdate,\n filter,\n onColumnResize,\n onColumnResizeEnd,\n createFilterField,\n AddColumnComponent,\n onColumnsOrderChange,\n data,\n cellRenderer: CellRenderer,\n rowHeight = 54,\n draggingColumnId,\n headerHeight = 40\n}: VirtualTableContextProps<Record<string, unknown>>) => {\n\n const columnRefs = useMemo(() => columns.map(() => createRef<HTMLDivElement>()), [columns.length]);\n const [isResizing, setIsResizing] = useState(-1);\n\n const adjustWidthColumn = useCallback((index: number, width: number, end: boolean) => {\n const column = columns[index];\n const minWidth = 100;\n const maxWidth = 800;\n const newWidth = width > maxWidth ? maxWidth : (width < minWidth ? minWidth : width);\n const params = {\n width: newWidth,\n key: column.key as string,\n column: {\n ...column,\n width: newWidth\n } as VirtualTableColumn\n };\n if (!end)\n onColumnResize(params);\n else\n onColumnResizeEnd(params);\n }, [columns, onColumnResize, onColumnResizeEnd]);\n\n const getEventNewWidth = useCallback((e: MouseEvent) => {\n if (isResizing >= 0) {\n const left = columnRefs[isResizing].current?.parentElement?.getBoundingClientRect().left;\n if (!left) return;\n return e.clientX - left;\n }\n return undefined;\n }, [columnRefs, isResizing]);\n\n const setCursorDocument = useCallback((isResizing: boolean) => {\n document.body.style.cursor = isResizing ? \"col-resize\" : \"auto\";\n }, []);\n\n const handleOnMouseMove = useCallback((e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n const newWidth = getEventNewWidth(e);\n if (newWidth)\n adjustWidthColumn(isResizing, newWidth, false);\n }, [adjustWidthColumn, getEventNewWidth, isResizing]);\n\n const handleOnMouseUp = useCallback((e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n const newWidth = getEventNewWidth(e);\n if (newWidth)\n adjustWidthColumn(isResizing, newWidth, true);\n setIsResizing(-1);\n setCursorDocument(false);\n }, [adjustWidthColumn, getEventNewWidth, isResizing, setCursorDocument]);\n\n const removeResizingListeners = useCallback(() => {\n document.removeEventListener(\"mousemove\", handleOnMouseMove);\n document.removeEventListener(\"mouseup\", handleOnMouseUp);\n }, [handleOnMouseMove, handleOnMouseUp]);\n\n const attachResizeListeners = useCallback(() => {\n document.addEventListener(\"mousemove\", handleOnMouseMove);\n document.addEventListener(\"mouseup\", handleOnMouseUp);\n }, [handleOnMouseMove, handleOnMouseUp]);\n\n useEffect(() => {\n if (isResizing >= 0) {\n attachResizeListeners();\n } else {\n removeResizingListeners();\n }\n return () => {\n removeResizingListeners();\n };\n }, [attachResizeListeners, isResizing, removeResizingListeners]);\n\n const onClickResizeColumn = useCallback((index: number) => {\n setIsResizing(index);\n setCursorDocument(true);\n }, [setCursorDocument]);\n\n return (\n <>\n <div\n className={cls(defaultBorderMixin, \"z-20 sticky min-w-full flex w-fit flex-row top-0 left-0 border-b bg-surface-sheet\")}\n style={{ height: headerHeight }}>\n {columns.map((column, columnIndex) => {\n const columnFilter = column && filter && filter[column.key] ? filter[column.key] : undefined;\n const filterForThisProperty: [VirtualTableWhereFilterOp, unknown] | undefined =\n columnFilter\n ? (Array.isArray(columnFilter[0]) ? (columnFilter as [VirtualTableWhereFilterOp, unknown][])[0] : (columnFilter as [VirtualTableWhereFilterOp, unknown]))\n : undefined;\n\n const isDraggable = !column.frozen && !!onColumnsOrderChange;\n const isDragging = draggingColumnId === column.key;\n\n return (\n <ErrorBoundary key={\"header_\" + column.key}>\n <SortableColumnHeader\n column={column}\n columnIndex={columnIndex}\n columnRefs={columnRefs}\n isResizing={isResizing}\n onFilterUpdate={onFilterUpdate}\n filter={filterForThisProperty}\n sortIndex={sortIndex}\n sortCount={sortIndex.size}\n onColumnSort={onColumnSort}\n onClickResizeColumn={onClickResizeColumn}\n createFilterField={createFilterField}\n isDragging={isDragging}\n isDraggable={isDraggable}\n />\n </ErrorBoundary>\n );\n })}\n\n {AddColumnComponent && <AddColumnComponent/>}\n\n </div>\n </>\n );\n};\n"],"mappings":"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"}
@@ -22,9 +22,11 @@ export type OnRowClickParams<T extends object> = {
22
22
  */
23
23
  export interface VirtualTableProps<T extends object> {
24
24
  /**
25
- * Array of arbitrary data
25
+ * Array of arbitrary data. A position holding `undefined` is a row that
26
+ * exists but has not been read yet: it is drawn, and its cells are
27
+ * rendered with no `rowData`, so the renderer can show a placeholder.
26
28
  */
27
- data?: T[];
29
+ data?: (T | undefined)[];
28
30
  /**
29
31
  * Properties displayed in this collection. If this property is not set
30
32
  * every property is displayed, you can filter
@@ -145,6 +147,15 @@ export interface VirtualTableProps<T extends object> {
145
147
  * Initial scroll position
146
148
  */
147
149
  initialScroll?: number;
150
+ /**
151
+ * Called with the positions in `data` of the rows on screen — not the
152
+ * ones drawn ahead of them — end exclusive, each time they change. While
153
+ * the table is still scrolling to `initialScroll`, the rows there.
154
+ */
155
+ onRowsRendered?: (range: {
156
+ start: number;
157
+ end: number;
158
+ }) => void;
148
159
  /**
149
160
  * Callback when columns are reordered via drag-and-drop.
150
161
  * @param columns The new column order
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
2
  import { VirtualTableRowProps } from "./types.js";
3
3
  /**
4
- * The same fix `VirtualTable` carries, one level down: `React.memo` takes the
5
- * props type as its own type argument, so the annotation on the call pins the
6
- * row type at the boundary and discards the `<T>` the inner function declares.
7
- * Pinned, the row a caller passes in and the row its `onRowClick` and
8
- * `rowClassName` receive were unrelated types, which is what every consumer was
9
- * paying for with a cast.
4
+ * Not memoised itself: `VirtualTableRowRenderer` (in `VirtualTable`) decides
5
+ * when a row is drawn again, from the inputs its cells are built from. A memo
6
+ * here could only compare the `children` it is handed, and those are new
7
+ * elements every time the renderer runs — it deep-compared every cell element
8
+ * and the full `columns` array each one carries, to find them unequal.
10
9
  */
11
- export declare const VirtualTableRow: <T extends object>(props: VirtualTableRowProps<T>) => React.ReactElement | null;
10
+ export declare function VirtualTableRow<T extends object>({ rowData, rowIndex, children, onRowClick, rowHeight, style, hoverRow, rowClassName }: VirtualTableRowProps<T>): React.JSX.Element;
@@ -0,0 +1,41 @@
1
+ import { cls } from "../../util/cls.es.js";
2
+ import { useCallback } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/VirtualTable/VirtualTableRow.tsx
5
+ /**
6
+ * Not memoised itself: `VirtualTableRowRenderer` (in `VirtualTable`) decides
7
+ * when a row is drawn again, from the inputs its cells are built from. A memo
8
+ * here could only compare the `children` it is handed, and those are new
9
+ * elements every time the renderer runs — it deep-compared every cell element
10
+ * and the full `columns` array each one carries, to find them unequal.
11
+ */
12
+ function VirtualTableRow({ rowData, rowIndex, children, onRowClick, rowHeight, style, hoverRow, rowClassName }) {
13
+ const onClick = useCallback((event) => {
14
+ if (onRowClick && rowData) onRowClick({
15
+ rowData,
16
+ rowIndex,
17
+ event
18
+ });
19
+ }, [
20
+ onRowClick,
21
+ rowData,
22
+ rowIndex
23
+ ]);
24
+ return /* @__PURE__ */ jsx("div", {
25
+ className: cls("group flex min-w-full text-sm border-b border-hairline bg-surface-card", rowClassName && rowData ? rowClassName(rowData) : "", {
26
+ "hover:!bg-surface-card-hover": hoverRow,
27
+ "cursor-pointer ": onRowClick
28
+ }),
29
+ onClick,
30
+ style: {
31
+ ...style,
32
+ height: rowHeight,
33
+ width: "fit-content"
34
+ },
35
+ children
36
+ });
37
+ }
38
+ //#endregion
39
+ export { VirtualTableRow };
40
+
41
+ //# sourceMappingURL=VirtualTableRow.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualTableRow.es.js","names":[],"sources":["../../../src/components/VirtualTable/VirtualTableRow.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\n\nimport { VirtualTableRowProps } from \"./types\";\nimport { cls } from \"../../util/cls\";\n\n/**\n * Not memoised itself: `VirtualTableRowRenderer` (in `VirtualTable`) decides\n * when a row is drawn again, from the inputs its cells are built from. A memo\n * here could only compare the `children` it is handed, and those are new\n * elements every time the renderer runs — it deep-compared every cell element\n * and the full `columns` array each one carries, to find them unequal.\n */\nexport function VirtualTableRow<T extends object>({\n rowData,\n rowIndex,\n children,\n onRowClick,\n rowHeight,\n style,\n hoverRow,\n rowClassName\n}: VirtualTableRowProps<T>) {\n\n const onClick = useCallback((event: React.SyntheticEvent) => {\n // A row with no data yet is not a row anyone clicked *on*.\n if (onRowClick && rowData)\n onRowClick({\n rowData,\n rowIndex,\n event\n })\n }, [onRowClick, rowData, rowIndex]);\n\n return (\n <div\n className={cls(\n \"group flex min-w-full text-sm border-b border-hairline bg-surface-card\",\n rowClassName && rowData ? rowClassName(rowData) : \"\",\n {\n \"hover:!bg-surface-card-hover\": hoverRow,\n \"cursor-pointer \": onRowClick\n }\n )}\n onClick={onClick}\n style={{\n ...(style),\n height: rowHeight,\n width: \"fit-content\"\n }}\n >\n {children}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,gBAAkC,EAC9C,SACA,UACA,UACA,YACA,WACA,OACA,UACA,gBACwB;CAExB,MAAM,UAAU,aAAa,UAAgC;EAEzD,IAAI,cAAc,SACd,WAAW;GACP;GACA;GACA;EACJ,CAAC;CACT,GAAG;EAAC;EAAY;EAAS;CAAQ,CAAC;CAElC,OACI,oBAAC,OAAD;EACI,WAAW,IACP,0EACA,gBAAgB,UAAU,aAAa,OAAO,IAAI,IAClD;GACI,gCAAgC;GAChC,mBAAmB;EACvB,CACJ;EACS;EACT,OAAO;GACH,GAAI;GACJ,QAAQ;GACR,OAAO;EACX;EAEC;CACA,CAAA;AAEb"}
@@ -1,8 +1,9 @@
1
1
  import React from "react";
2
+ import { type DateTimeFieldMode } from "../../DateTimeField.js";
2
3
  export declare function VirtualTableDateField(props: {
3
4
  name?: string;
4
5
  error?: Error;
5
- mode?: "date" | "date_time";
6
+ mode?: DateTimeFieldMode;
6
7
  timezone?: string;
7
8
  internalValue: Date | undefined | null;
8
9
  updateValue: (newValue: (Date | null)) => void;
@@ -0,0 +1,71 @@
1
+ import { focusedDisabled } from "../../../styles.es.js";
2
+ import { cls } from "../../../util/cls.es.js";
3
+ import { DateTimeField } from "../../DateTimeField.es.js";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/components/VirtualTable/fields/VirtualTableDateField.tsx
7
+ function VirtualTableDateField(props) {
8
+ const { name, disabled, error, mode, timezone, internalValue, updateValue, small = false, locale, pickerButton = true, inputRef } = props;
9
+ const [focused, setFocused] = useState(false);
10
+ const focusedRef = useRef(false);
11
+ const [draft, setDraft] = useState(null);
12
+ const draftRef = useRef(null);
13
+ const timerRef = useRef(void 0);
14
+ const updateValueRef = useRef(updateValue);
15
+ useEffect(() => {
16
+ updateValueRef.current = updateValue;
17
+ }, [updateValue]);
18
+ const commit = useCallback(() => {
19
+ clearTimeout(timerRef.current);
20
+ const pending = draftRef.current;
21
+ if (!pending) return;
22
+ draftRef.current = null;
23
+ setDraft(null);
24
+ updateValueRef.current(pending.value);
25
+ }, []);
26
+ const onDateChange = (dateValue) => {
27
+ const pending = { value: dateValue ?? null };
28
+ draftRef.current = pending;
29
+ setDraft(pending);
30
+ clearTimeout(timerRef.current);
31
+ if (!focusedRef.current) commit();
32
+ else if (!pending.value || pending.value.getFullYear() >= 1e3) timerRef.current = setTimeout(commit, 400);
33
+ };
34
+ useEffect(() => () => {
35
+ clearTimeout(timerRef.current);
36
+ if (draftRef.current) updateValueRef.current(draftRef.current.value);
37
+ }, []);
38
+ const shownValue = draft ? draft.value : internalValue;
39
+ return /* @__PURE__ */ jsx("div", {
40
+ className: "w-full h-full flex items-center",
41
+ onFocus: () => {
42
+ focusedRef.current = true;
43
+ setFocused(true);
44
+ },
45
+ onBlur: () => {
46
+ focusedRef.current = false;
47
+ setFocused(false);
48
+ commit();
49
+ },
50
+ children: /* @__PURE__ */ jsx(DateTimeField, {
51
+ value: shownValue ?? void 0,
52
+ onChange: onDateChange,
53
+ disabled,
54
+ error: Boolean(error),
55
+ "aria-label": name,
56
+ invisible: true,
57
+ pickerButton,
58
+ inputRef,
59
+ size: small ? "small" : "medium",
60
+ inputClassName: cls("w-full h-full", focusedDisabled, !pickerButton && "px-0", !shownValue && !focused && "text-transparent"),
61
+ className: cls("w-full h-full", focusedDisabled),
62
+ mode,
63
+ timezone,
64
+ locale
65
+ })
66
+ });
67
+ }
68
+ //#endregion
69
+ export { VirtualTableDateField };
70
+
71
+ //# sourceMappingURL=VirtualTableDateField.es.js.map