@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.
- package/dist/components/Alert.d.ts +6 -0
- package/dist/components/Alert.es.js +82 -0
- package/dist/components/Alert.es.js.map +1 -0
- package/dist/components/Autocomplete.es.js +53 -0
- package/dist/components/Autocomplete.es.js.map +1 -0
- package/dist/components/Avatar.d.ts +3 -1
- package/dist/components/Avatar.es.js +37 -0
- package/dist/components/Avatar.es.js.map +1 -0
- package/dist/components/Badge.es.js +27 -0
- package/dist/components/Badge.es.js.map +1 -0
- package/dist/components/BooleanSwitch.es.js +75 -0
- package/dist/components/BooleanSwitch.es.js.map +1 -0
- package/dist/components/BooleanSwitchWithLabel.es.js +55 -0
- package/dist/components/BooleanSwitchWithLabel.es.js.map +1 -0
- package/dist/components/Button.es.js +58 -0
- package/dist/components/Button.es.js.map +1 -0
- package/dist/components/Card.es.js +26 -0
- package/dist/components/Card.es.js.map +1 -0
- package/dist/components/CenteredView.es.js +23 -0
- package/dist/components/CenteredView.es.js.map +1 -0
- package/dist/components/Checkbox.es.js +62 -0
- package/dist/components/Checkbox.es.js.map +1 -0
- package/dist/components/Chip.es.js +72 -0
- package/dist/components/Chip.es.js.map +1 -0
- package/dist/components/CircularProgress.es.js +28 -0
- package/dist/components/CircularProgress.es.js.map +1 -0
- package/dist/components/CircularProgressCenter.es.js +30 -0
- package/dist/components/CircularProgressCenter.es.js.map +1 -0
- package/dist/components/Collapse.es.js +57 -0
- package/dist/components/Collapse.es.js.map +1 -0
- package/dist/components/ColorPicker.es.js +89 -0
- package/dist/components/ColorPicker.es.js.map +1 -0
- package/dist/components/Container.es.js +31 -0
- package/dist/components/Container.es.js.map +1 -0
- package/dist/components/DateTimeField.d.ts +11 -1
- package/dist/components/DateTimeField.es.js +253 -0
- package/dist/components/DateTimeField.es.js.map +1 -0
- package/dist/components/DebouncedTextField.es.js +93 -0
- package/dist/components/DebouncedTextField.es.js.map +1 -0
- package/dist/components/Dialog.es.js +98 -0
- package/dist/components/Dialog.es.js.map +1 -0
- package/dist/components/DialogActions.es.js +15 -0
- package/dist/components/DialogActions.es.js.map +1 -0
- package/dist/components/DialogContent.es.js +18 -0
- package/dist/components/DialogContent.es.js.map +1 -0
- package/dist/components/DialogTitle.es.js +26 -0
- package/dist/components/DialogTitle.es.js.map +1 -0
- package/dist/components/ErrorBoundary.es.js +158 -0
- package/dist/components/ErrorBoundary.es.js.map +1 -0
- package/dist/components/ExpandablePanel.es.js +91 -0
- package/dist/components/ExpandablePanel.es.js.map +1 -0
- package/dist/components/FileUpload.es.js +58 -0
- package/dist/components/FileUpload.es.js.map +1 -0
- package/dist/components/FilterChip.es.js +31 -0
- package/dist/components/FilterChip.es.js.map +1 -0
- package/dist/components/IconButton.es.js +52 -0
- package/dist/components/IconButton.es.js.map +1 -0
- package/dist/components/InfoLabel.es.js +18 -0
- package/dist/components/InfoLabel.es.js.map +1 -0
- package/dist/components/InputLabel.es.js +27 -0
- package/dist/components/InputLabel.es.js.map +1 -0
- package/dist/components/Label.es.js +18 -0
- package/dist/components/Label.es.js.map +1 -0
- package/dist/components/LoadingButton.es.js +21 -0
- package/dist/components/LoadingButton.es.js.map +1 -0
- package/dist/components/Markdown.es.js +88 -0
- package/dist/components/Markdown.es.js.map +1 -0
- package/dist/components/Menu.es.js +46 -0
- package/dist/components/Menu.es.js.map +1 -0
- package/dist/components/Menubar.es.js +142 -0
- package/dist/components/Menubar.es.js.map +1 -0
- package/dist/components/MultiSelect.d.ts +1 -7
- package/dist/components/MultiSelect.es.js +271 -0
- package/dist/components/MultiSelect.es.js.map +1 -0
- package/dist/components/Paper.es.js +16 -0
- package/dist/components/Paper.es.js.map +1 -0
- package/dist/components/Popover.es.js +113 -0
- package/dist/components/Popover.es.js.map +1 -0
- package/dist/components/RadioGroup.es.js +30 -0
- package/dist/components/RadioGroup.es.js.map +1 -0
- package/dist/components/ResizablePanels.d.ts +3 -1
- package/dist/components/ResizablePanels.es.js +137 -0
- package/dist/components/ResizablePanels.es.js.map +1 -0
- package/dist/components/SearchBar.es.js +82 -0
- package/dist/components/SearchBar.es.js.map +1 -0
- package/dist/components/Select.d.ts +8 -1
- package/dist/components/Select.es.js +300 -0
- package/dist/components/Select.es.js.map +1 -0
- package/dist/components/Separator.es.js +20 -0
- package/dist/components/Separator.es.js.map +1 -0
- package/dist/components/Sheet.es.js +73 -0
- package/dist/components/Sheet.es.js.map +1 -0
- package/dist/components/Skeleton.es.js +33 -0
- package/dist/components/Skeleton.es.js.map +1 -0
- package/dist/components/Slider.es.js +56 -0
- package/dist/components/Slider.es.js.map +1 -0
- package/dist/components/Table.d.ts +18 -3
- package/dist/components/Table.es.js +69 -0
- package/dist/components/Table.es.js.map +1 -0
- package/dist/components/Tabs.es.js +101 -0
- package/dist/components/Tabs.es.js.map +1 -0
- package/dist/components/TextField.d.ts +0 -8
- package/dist/components/TextField.es.js +111 -0
- package/dist/components/TextField.es.js.map +1 -0
- package/dist/components/TextareaAutosize.es.js +187 -0
- package/dist/components/TextareaAutosize.es.js.map +1 -0
- package/dist/components/ToggleButtonGroup.d.ts +6 -1
- package/dist/components/ToggleButtonGroup.es.js +35 -0
- package/dist/components/ToggleButtonGroup.es.js.map +1 -0
- package/dist/components/Tooltip.d.ts +24 -0
- package/dist/components/Tooltip.es.js +165 -0
- package/dist/components/Tooltip.es.js.map +1 -0
- package/dist/components/Typography.es.js +85 -0
- package/dist/components/Typography.es.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTable.es.js +516 -0
- package/dist/components/VirtualTable/VirtualTable.es.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableCell.es.js +40 -0
- package/dist/components/VirtualTable/VirtualTableCell.es.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTableHeader.es.js +209 -0
- package/dist/components/VirtualTable/VirtualTableHeader.es.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js +166 -0
- package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -2
- package/dist/components/VirtualTable/VirtualTableRow.d.ts +6 -7
- package/dist/components/VirtualTable/VirtualTableRow.es.js +41 -0
- package/dist/components/VirtualTable/VirtualTableRow.es.js.map +1 -0
- package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +2 -1
- package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js +71 -0
- package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js.map +1 -0
- package/dist/components/VirtualTable/fields/VirtualTableInput.es.js +73 -0
- package/dist/components/VirtualTable/fields/VirtualTableInput.es.js.map +1 -0
- package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js +47 -0
- package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js.map +1 -0
- package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js +83 -0
- package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js.map +1 -0
- package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js +22 -0
- package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js.map +1 -0
- package/dist/components/VirtualTable/selection/SelectionContext.es.js +23 -0
- package/dist/components/VirtualTable/selection/SelectionContext.es.js.map +1 -0
- package/dist/components/VirtualTable/selection/SelectionStore.es.js +43 -0
- package/dist/components/VirtualTable/selection/SelectionStore.es.js.map +1 -0
- package/dist/components/VirtualTable/types.d.ts +1 -1
- package/dist/components/common/SelectInputLabel.es.js +28 -0
- package/dist/components/common/SelectInputLabel.es.js.map +1 -0
- package/dist/components/index.es.js +64 -0
- package/dist/hooks/PortalContainerContext.es.js +40 -0
- package/dist/hooks/PortalContainerContext.es.js.map +1 -0
- package/dist/hooks/UiLabelsContext.d.ts +63 -0
- package/dist/hooks/UiLabelsContext.es.js +59 -0
- package/dist/hooks/UiLabelsContext.es.js.map +1 -0
- package/dist/hooks/useDebounceCallback.es.js +15 -0
- package/dist/hooks/useDebounceCallback.es.js.map +1 -0
- package/dist/hooks/useDebounceValue.es.js +19 -0
- package/dist/hooks/useDebounceValue.es.js.map +1 -0
- package/dist/hooks/useDebouncedCallback.es.js +36 -0
- package/dist/hooks/useDebouncedCallback.es.js.map +1 -0
- package/dist/hooks/useInjectStyles.es.js +27 -0
- package/dist/hooks/useInjectStyles.es.js.map +1 -0
- package/dist/hooks/useIsDarkMode.es.js +61 -0
- package/dist/hooks/useIsDarkMode.es.js.map +1 -0
- package/dist/hooks/useModalFocus.es.js +81 -0
- package/dist/hooks/useModalFocus.es.js.map +1 -0
- package/dist/hooks/useOutsideAlerter.es.js +41 -0
- package/dist/hooks/useOutsideAlerter.es.js.map +1 -0
- package/dist/hooks/useRestoreInterruptedFocus.es.js +61 -0
- package/dist/hooks/useRestoreInterruptedFocus.es.js.map +1 -0
- package/dist/icons/GitHubIcon.es.js +23 -0
- package/dist/icons/GitHubIcon.es.js.map +1 -0
- package/dist/icons/HandleIcon.es.js +60 -0
- package/dist/icons/HandleIcon.es.js.map +1 -0
- package/dist/icons/Icon.es.js +25 -0
- package/dist/icons/Icon.es.js.map +1 -0
- package/dist/icons/LucideIconByName.d.ts +12 -9
- package/dist/icons/LucideIconByName.es.js +83 -0
- package/dist/icons/LucideIconByName.es.js.map +1 -0
- package/dist/icons/cool_icon_keys.es.js +55 -0
- package/dist/icons/cool_icon_keys.es.js.map +1 -0
- package/dist/icons/icon_keys.es.js +1941 -0
- package/dist/icons/icon_keys.es.js.map +1 -0
- package/dist/icons/index.d.ts +4 -3
- package/dist/icons/index.es.js +8 -0
- package/dist/icons/lucide_icon_map.d.ts +12 -0
- package/dist/icons/lucide_icon_map.es.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +87 -9563
- package/dist/styles.es.js +158 -0
- package/dist/styles.es.js.map +1 -0
- package/dist/util/chip_colors.es.js +290 -0
- package/dist/util/chip_colors.es.js.map +1 -0
- package/dist/util/cls.es.js +10 -0
- package/dist/util/cls.es.js.map +1 -0
- package/dist/util/debounce.es.js +22 -0
- package/dist/util/debounce.es.js.map +1 -0
- package/dist/util/hash.es.js +16 -0
- package/dist/util/hash.es.js.map +1 -0
- package/dist/util/keys.es.js +37 -0
- package/dist/util/keys.es.js.map +1 -0
- package/dist/util/lazy_chunk.es.js +96 -0
- package/dist/util/lazy_chunk.es.js.map +1 -0
- package/dist/views/CardView.d.ts +26 -2
- package/dist/views/CardView.es.js +435 -0
- package/dist/views/CardView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionCardView.es.js +179 -0
- package/dist/views/CollectionView/CollectionCardView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionKanbanView.es.js +172 -0
- package/dist/views/CollectionView/CollectionKanbanView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionListView.es.js +156 -0
- package/dist/views/CollectionView/CollectionListView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionTableView.es.js +149 -0
- package/dist/views/CollectionView/CollectionTableView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionView.es.js +197 -0
- package/dist/views/CollectionView/CollectionView.es.js.map +1 -0
- package/dist/views/CollectionView/CollectionViewToolbar.es.js +155 -0
- package/dist/views/CollectionView/CollectionViewToolbar.es.js.map +1 -0
- package/dist/views/CollectionView/DefaultCellRenderer.es.js +302 -0
- package/dist/views/CollectionView/DefaultCellRenderer.es.js.map +1 -0
- package/dist/views/CollectionView/resolveTitleProperty.es.js +56 -0
- package/dist/views/CollectionView/resolveTitleProperty.es.js.map +1 -0
- package/dist/views/CollectionView/utils.es.js +19 -0
- package/dist/views/CollectionView/utils.es.js.map +1 -0
- package/dist/views/Kanban/Board.es.js +237 -0
- package/dist/views/Kanban/Board.es.js.map +1 -0
- package/dist/views/Kanban/BoardColumn.es.js +81 -0
- package/dist/views/Kanban/BoardColumn.es.js.map +1 -0
- package/dist/views/Kanban/BoardColumnTitle.es.js +27 -0
- package/dist/views/Kanban/BoardColumnTitle.es.js.map +1 -0
- package/dist/views/Kanban/BoardSortableList.es.js +98 -0
- package/dist/views/Kanban/BoardSortableList.es.js.map +1 -0
- package/dist/views/Kanban/placement.es.js +27 -0
- package/dist/views/Kanban/placement.es.js.map +1 -0
- package/dist/views/KanbanView.es.js +11 -0
- package/dist/views/KanbanView.es.js.map +1 -0
- package/dist/views/ListView.d.ts +15 -2
- package/dist/views/ListView.es.js +245 -0
- package/dist/views/ListView.es.js.map +1 -0
- package/dist/views/useScrollParentRestoration.d.ts +8 -1
- package/dist/views/useScrollParentRestoration.es.js +75 -0
- package/dist/views/useScrollParentRestoration.es.js.map +1 -0
- package/package.json +2 -2
- 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":"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"}
|
|
@@ -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
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
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
|
|
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?:
|
|
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
|