@comitor/ui 1.11.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +35 -0
- package/README.md +23 -7
- package/dist/components/ui/action-bar-constants.d.ts +31 -0
- package/dist/components/ui/action-bar-constants.js +9 -0
- package/dist/components/ui/action-bar-constants.js.map +1 -0
- package/dist/components/ui/action-bar.d.ts +67 -0
- package/dist/components/ui/action-bar.js +522 -0
- package/dist/components/ui/action-bar.js.map +1 -0
- package/dist/components/ui/badge-overflow.d.ts +30 -0
- package/dist/components/ui/badge-overflow.js +179 -0
- package/dist/components/ui/badge-overflow.js.map +1 -0
- package/dist/components/ui/banner.d.ts +79 -0
- package/dist/components/ui/banner.js +518 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/circular-progress.d.ts +50 -0
- package/dist/components/ui/circular-progress.js +266 -0
- package/dist/components/ui/circular-progress.js.map +1 -0
- package/dist/components/ui/cropper-constants.d.ts +34 -0
- package/dist/components/ui/cropper-constants.js +10 -0
- package/dist/components/ui/cropper-constants.js.map +1 -0
- package/dist/components/ui/cropper.d.ts +106 -0
- package/dist/components/ui/cropper.js +1269 -0
- package/dist/components/ui/cropper.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +1 -1
- package/dist/components/ui/drawer.js +2 -2
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/kanban-constants.d.ts +61 -0
- package/dist/components/ui/kanban-constants.js +21 -0
- package/dist/components/ui/kanban-constants.js.map +1 -0
- package/dist/components/ui/kanban.d.ts +72 -0
- package/dist/components/ui/kanban.js +787 -0
- package/dist/components/ui/kanban.js.map +1 -0
- package/dist/components/ui/key-value-constants.d.ts +33 -0
- package/dist/components/ui/key-value-constants.js +11 -0
- package/dist/components/ui/key-value-constants.js.map +1 -0
- package/dist/components/ui/key-value.d.ts +96 -0
- package/dist/components/ui/key-value.js +641 -0
- package/dist/components/ui/key-value.js.map +1 -0
- package/dist/components/ui/mask-input-constants.d.ts +99 -0
- package/dist/components/ui/mask-input-constants.js +601 -0
- package/dist/components/ui/mask-input-constants.js.map +1 -0
- package/dist/components/ui/mask-input.d.ts +36 -0
- package/dist/components/ui/mask-input.js +558 -0
- package/dist/components/ui/mask-input.js.map +1 -0
- package/dist/components/ui/mention.d.ts +31 -0
- package/dist/components/ui/mention.js +128 -0
- package/dist/components/ui/mention.js.map +1 -0
- package/dist/components/ui/phone-input-constants.d.ts +54 -0
- package/dist/components/ui/phone-input-constants.js +9 -0
- package/dist/components/ui/phone-input-constants.js.map +1 -0
- package/dist/components/ui/phone-input.d.ts +85 -0
- package/dist/components/ui/phone-input.js +743 -0
- package/dist/components/ui/phone-input.js.map +1 -0
- package/dist/components/ui/rating.d.ts +56 -0
- package/dist/components/ui/rating.js +646 -0
- package/dist/components/ui/rating.js.map +1 -0
- package/dist/components/ui/responsive-dialog.d.ts +35 -0
- package/dist/components/ui/responsive-dialog.js +193 -0
- package/dist/components/ui/responsive-dialog.js.map +1 -0
- package/dist/components/ui/scroll-spy.d.ts +42 -0
- package/dist/components/ui/scroll-spy.js +334 -0
- package/dist/components/ui/scroll-spy.js.map +1 -0
- package/dist/components/ui/stepper-constants.d.ts +29 -0
- package/dist/components/ui/stepper-constants.js +9 -0
- package/dist/components/ui/stepper-constants.js.map +1 -0
- package/dist/components/ui/stepper.d.ts +80 -0
- package/dist/components/ui/stepper.js +902 -0
- package/dist/components/ui/stepper.js.map +1 -0
- package/dist/components/ui/tags-input.d.ts +41 -0
- package/dist/components/ui/tags-input.js +127 -0
- package/dist/components/ui/tags-input.js.map +1 -0
- package/dist/components/ui/time-picker-constants.d.ts +48 -0
- package/dist/components/ui/time-picker-constants.js +14 -0
- package/dist/components/ui/time-picker-constants.js.map +1 -0
- package/dist/components/ui/time-picker.d.ts +115 -0
- package/dist/components/ui/time-picker.js +1620 -0
- package/dist/components/ui/time-picker.js.map +1 -0
- package/dist/components/ui/timeline.d.ts +32 -0
- package/dist/components/ui/timeline.js +559 -0
- package/dist/components/ui/timeline.js.map +1 -0
- package/dist/components/ui/tour-constants.d.ts +39 -0
- package/dist/components/ui/tour-constants.js +12 -0
- package/dist/components/ui/tour-constants.js.map +1 -0
- package/dist/components/ui/tour.d.ts +124 -0
- package/dist/components/ui/tour.js +1207 -0
- package/dist/components/ui/tour.js.map +1 -0
- package/dist/data-grid/data-grid-cell-variants.js +10 -6
- package/dist/data-grid/data-grid-cell-variants.js.map +1 -1
- package/dist/data-grid/data-grid-cell-wrapper.js +1 -1
- package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -1
- package/dist/data-grid/data-grid-column-header.js +4 -2
- package/dist/data-grid/data-grid-column-header.js.map +1 -1
- package/dist/data-grid/data-grid-context-menu.js +5 -4
- package/dist/data-grid/data-grid-context-menu.js.map +1 -1
- package/dist/data-grid/data-grid-filter-menu.d.ts +12 -1
- package/dist/data-grid/data-grid-filter-menu.js +28 -17
- package/dist/data-grid/data-grid-filter-menu.js.map +1 -1
- package/dist/data-grid/data-grid-keyboard-shortcuts.d.ts +12 -1
- package/dist/data-grid/data-grid-keyboard-shortcuts.js +7 -5
- package/dist/data-grid/data-grid-keyboard-shortcuts.js.map +1 -1
- package/dist/data-grid/data-grid-locale.d.ts +24 -0
- package/dist/data-grid/data-grid-locale.js +25 -0
- package/dist/data-grid/data-grid-locale.js.map +1 -0
- package/dist/data-grid/data-grid-paste-dialog.js +3 -2
- package/dist/data-grid/data-grid-paste-dialog.js.map +1 -1
- package/dist/data-grid/data-grid-row-height-menu.d.ts +11 -1
- package/dist/data-grid/data-grid-row-height-menu.js +25 -28
- package/dist/data-grid/data-grid-row-height-menu.js.map +1 -1
- package/dist/data-grid/data-grid-row.js +1 -1
- package/dist/data-grid/data-grid-row.js.map +1 -1
- package/dist/data-grid/data-grid-search.js +6 -5
- package/dist/data-grid/data-grid-search.js.map +1 -1
- package/dist/data-grid/data-grid-select-column.js +3 -1
- package/dist/data-grid/data-grid-select-column.js.map +1 -1
- package/dist/data-grid/data-grid-sort-menu.d.ts +12 -1
- package/dist/data-grid/data-grid-sort-menu.js +25 -13
- package/dist/data-grid/data-grid-sort-menu.js.map +1 -1
- package/dist/data-grid/data-grid-view-menu.d.ts +12 -1
- package/dist/data-grid/data-grid-view-menu.js +12 -4
- package/dist/data-grid/data-grid-view-menu.js.map +1 -1
- package/dist/data-grid/data-grid.d.ts +14 -2
- package/dist/data-grid/data-grid.js +7 -4
- package/dist/data-grid/data-grid.js.map +1 -1
- package/dist/data-grid/filters.d.ts +17 -21
- package/dist/data-grid/filters.js +73 -52
- package/dist/data-grid/filters.js.map +1 -1
- package/dist/data-grid/index.d.ts +4 -1
- package/dist/data-grid/index.js +20 -2
- package/dist/data-grid/index.js.map +1 -1
- package/dist/data-grid/messages-en.d.ts +294 -0
- package/dist/data-grid/messages-en.js +279 -0
- package/dist/data-grid/messages-en.js.map +1 -0
- package/dist/data-grid/messages-vi.d.ts +12 -0
- package/dist/data-grid/messages-vi.js +279 -0
- package/dist/data-grid/messages-vi.js.map +1 -0
- package/dist/data-grid/messages.d.ts +549 -262
- package/dist/data-grid/messages.js +16 -275
- package/dist/data-grid/messages.js.map +1 -1
- package/dist/data-grid/sortable.js +1 -1
- package/dist/data-grid/sortable.js.map +1 -1
- package/dist/data-grid/use-data-grid-undo-redo.d.ts +13 -1
- package/dist/data-grid/use-data-grid-undo-redo.js +13 -10
- package/dist/data-grid/use-data-grid-undo-redo.js.map +1 -1
- package/dist/data-grid/use-data-grid.d.ts +281 -1
- package/dist/data-grid/use-data-grid.js +24 -19
- package/dist/data-grid/use-data-grid.js.map +1 -1
- package/dist/data-grid/utils.d.ts +9 -1
- package/dist/data-grid/utils.js +3 -2
- package/dist/data-grid/utils.js.map +1 -1
- package/dist/index.d.ts +31 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/use-as-ref.js.map +1 -0
- package/dist/lib/use-is-mobile.d.ts +10 -0
- package/dist/lib/use-is-mobile.js +21 -0
- package/dist/lib/use-is-mobile.js.map +1 -0
- package/dist/lib/use-isomorphic-layout-effect.js.map +1 -0
- package/dist/lib/use-lazy-ref.js.map +1 -0
- package/dist/lib/visually-hidden-input.d.ts +12 -0
- package/dist/lib/visually-hidden-input.js +105 -0
- package/dist/lib/visually-hidden-input.js.map +1 -0
- package/package.json +5 -1
- package/styles.css +19 -0
- package/dist/data-grid/compose-refs.js.map +0 -1
- package/dist/data-grid/use-as-ref.js.map +0 -1
- package/dist/data-grid/use-isomorphic-layout-effect.js.map +0 -1
- package/dist/data-grid/use-lazy-ref.js.map +0 -1
- /package/dist/{data-grid → lib}/compose-refs.d.ts +0 -0
- /package/dist/{data-grid → lib}/compose-refs.js +0 -0
- /package/dist/{data-grid → lib}/use-as-ref.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-as-ref.js +0 -0
- /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.js +0 -0
- /package/dist/{data-grid → lib}/use-lazy-ref.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-lazy-ref.js +0 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "../components/ui/dropdown-menu.js";
|
|
13
13
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../components/ui/tooltip.js";
|
|
14
14
|
import { cn } from "../lib/cn.js";
|
|
15
|
-
import {
|
|
15
|
+
import { useDataGridMessages } from "./data-grid-locale.js";
|
|
16
16
|
import { getColumnVariant } from "./utils.js";
|
|
17
17
|
function DataGridColumnHeader({
|
|
18
18
|
header,
|
|
@@ -21,6 +21,7 @@ function DataGridColumnHeader({
|
|
|
21
21
|
onPointerDown,
|
|
22
22
|
...props
|
|
23
23
|
}) {
|
|
24
|
+
const msg = useDataGridMessages();
|
|
24
25
|
const column = header.column;
|
|
25
26
|
const label = column.columnDef.meta?.label ? column.columnDef.meta.label : typeof column.columnDef.header === "string" ? column.columnDef.header : column.id;
|
|
26
27
|
const isAnyColumnResizing = table.getState().columnSizingInfo.isResizingColumn;
|
|
@@ -91,7 +92,7 @@ function DataGridColumnHeader({
|
|
|
91
92
|
] }),
|
|
92
93
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
93
94
|
] }),
|
|
94
|
-
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "shrink-0 text-muted-foreground" })
|
|
95
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3.5 shrink-0 text-muted-foreground" })
|
|
95
96
|
]
|
|
96
97
|
}
|
|
97
98
|
),
|
|
@@ -172,6 +173,7 @@ const DataGridColumnResizer = React.memo(DataGridColumnResizerImpl, (prev, next)
|
|
|
172
173
|
return true;
|
|
173
174
|
});
|
|
174
175
|
function DataGridColumnResizerImpl({ header, table, label }) {
|
|
176
|
+
const msg = useDataGridMessages();
|
|
175
177
|
const defaultColumnDef = table._getDefaultColumnDef();
|
|
176
178
|
const onDoubleClick = React.useCallback(() => {
|
|
177
179
|
header.column.resetSize();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data-grid/data-grid-column-header.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ColumnSort, Header, SortDirection, SortingState, Table } from \"@tanstack/react-table\";\nimport { ChevronDownIcon, ChevronUpIcon, EyeOffIcon, PinIcon, PinOffIcon, XIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger\n} from \"../components/ui/dropdown-menu.js\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../components/ui/tooltip.js\";\nimport { cn } from \"../lib/cn.js\";\nimport { msg } from \"./messages.js\";\nimport { getColumnVariant } from \"./utils.js\";\n\ninterface DataGridColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {\n header: Header<TData, TValue>;\n table: Table<TData>;\n}\n\nexport function DataGridColumnHeader<TData, TValue>({\n header,\n table,\n className,\n onPointerDown,\n ...props\n}: DataGridColumnHeaderProps<TData, TValue>) {\n const column = header.column;\n const label = column.columnDef.meta?.label\n ? column.columnDef.meta.label\n : typeof column.columnDef.header === \"string\"\n ? column.columnDef.header\n : column.id;\n\n const isAnyColumnResizing = table.getState().columnSizingInfo.isResizingColumn;\n\n const cellVariant = column.columnDef.meta?.cell;\n const columnVariant = getColumnVariant(cellVariant?.variant);\n\n const pinnedPosition = column.getIsPinned();\n const isPinnedLeft = pinnedPosition === \"left\";\n const isPinnedRight = pinnedPosition === \"right\";\n\n const onSortingChange = React.useCallback(\n (direction: SortDirection) => {\n table.setSorting((prev: SortingState) => {\n const existingSortIndex = prev.findIndex((sort) => sort.id === column.id);\n const newSort: ColumnSort = {\n id: column.id,\n desc: direction === \"desc\"\n };\n\n if (existingSortIndex >= 0) {\n const updated = [...prev];\n updated[existingSortIndex] = newSort;\n return updated;\n } else {\n return [...prev, newSort];\n }\n });\n },\n [column.id, table]\n );\n\n const onSortRemove = React.useCallback(() => {\n table.setSorting((prev: SortingState) => prev.filter((sort) => sort.id !== column.id));\n }, [column.id, table]);\n\n const onLeftPin = React.useCallback(() => {\n column.pin(\"left\");\n }, [column]);\n\n const onRightPin = React.useCallback(() => {\n column.pin(\"right\");\n }, [column]);\n\n const onUnpin = React.useCallback(() => {\n column.pin(false);\n }, [column]);\n\n const onTriggerPointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLButtonElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented) return;\n\n if (event.button !== 0) {\n return;\n }\n table.options.meta?.onColumnClick?.(column.id);\n },\n [table.options.meta, column.id, onPointerDown]\n );\n\n return (\n <>\n <DropdownMenu modal={false}>\n <DropdownMenuTrigger\n className={cn(\n \"flex size-full items-center justify-between gap-2 p-2 text-sm hover:bg-accent/40 data-[state=open]:bg-accent/40 [&_svg]:size-4\",\n isAnyColumnResizing && \"pointer-events-none\",\n className\n )}\n onPointerDown={onTriggerPointerDown}\n {...props}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n {columnVariant && (\n <Tooltip delayDuration={100}>\n <TooltipTrigger asChild>\n <columnVariant.icon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n </TooltipTrigger>\n {/* `TooltipContent` của gói TỰ portal ra ngoài — cần thiết vì hộp lưới\n có overflow-auto, không portal thì tooltip bị cắt. */}\n <TooltipContent side=\"top\">{columnVariant.label}</TooltipContent>\n </Tooltip>\n )}\n <span className=\"truncate\">{label}</span>\n </div>\n <ChevronDownIcon className=\"shrink-0 text-muted-foreground\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" sideOffset={0} className=\"w-60\">\n {column.getCanSort() && (\n <>\n <DropdownMenuCheckboxItem\n className=\"gap-2 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"asc\"}\n onSelect={() => onSortingChange(\"asc\")}\n >\n <ChevronUpIcon />\n {msg.column.sortAsc}\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n className=\"gap-2 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"desc\"}\n onSelect={() => onSortingChange(\"desc\")}\n >\n <ChevronDownIcon />\n {msg.column.sortDesc}\n </DropdownMenuCheckboxItem>\n {column.getIsSorted() && (\n <DropdownMenuItem onSelect={onSortRemove}>\n <XIcon />\n {msg.column.removeSort}\n </DropdownMenuItem>\n )}\n </>\n )}\n {column.getCanPin() && (\n <>\n {column.getCanSort() && <DropdownMenuSeparator />}\n\n {isPinnedLeft ? (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onUnpin}>\n <PinOffIcon />\n {msg.column.unpinLeft}\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onLeftPin}>\n <PinIcon />\n {msg.column.pinLeft}\n </DropdownMenuItem>\n )}\n {isPinnedRight ? (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onUnpin}>\n <PinOffIcon />\n {msg.column.unpinRight}\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onRightPin}>\n <PinIcon />\n {msg.column.pinRight}\n </DropdownMenuItem>\n )}\n </>\n )}\n {column.getCanHide() && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"[&_svg]:text-muted-foreground\"\n onSelect={() => column.toggleVisibility(false)}\n >\n <EyeOffIcon />\n {msg.column.hide}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n {header.column.getCanResize() && <DataGridColumnResizer header={header} table={table} label={label} />}\n </>\n );\n}\n\nconst DataGridColumnResizer = React.memo(DataGridColumnResizerImpl, (prev, next) => {\n const prevColumn = prev.header.column;\n const nextColumn = next.header.column;\n\n if (prevColumn.getIsResizing() !== nextColumn.getIsResizing() || prevColumn.getSize() !== nextColumn.getSize()) {\n return false;\n }\n\n if (prev.label !== next.label) return false;\n\n return true;\n}) as typeof DataGridColumnResizerImpl;\n\ninterface DataGridColumnResizerProps<TData, TValue> extends DataGridColumnHeaderProps<TData, TValue> {\n label: string;\n}\n\nfunction DataGridColumnResizerImpl<TData, TValue>({ header, table, label }: DataGridColumnResizerProps<TData, TValue>) {\n const defaultColumnDef = table._getDefaultColumnDef();\n\n const onDoubleClick = React.useCallback(() => {\n header.column.resetSize();\n }, [header.column]);\n\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={msg.column.resize(label)}\n aria-valuenow={header.column.getSize()}\n aria-valuemin={defaultColumnDef.minSize}\n aria-valuemax={defaultColumnDef.maxSize}\n tabIndex={0}\n className={cn(\n // Tay kéo chỉ hiện khi rê/focus/đang kéo, nên nó CHỈ mang đúng một màu — `--primary-ink`\n // (bậc NÉT). `--primary` trần là bậc tô NỀN: gold #E8B824 chỉ 1,73:1 với nền trang ở\n // light, tức một tay kéo nhìn thấy được ở dark mà gần như vô hình ở light.\n \"absolute -end-px top-0 z-50 h-full w-0.5 cursor-ew-resize touch-none select-none bg-primary-ink transition-opacity after:absolute after:inset-y-0 after:start-1/2 after:h-full after:w-[18px] after:-translate-x-1/2 after:content-[''] focus:outline-none\",\n header.column.getIsResizing() ? \"opacity-100\" : \"opacity-0 hover:opacity-100 focus:opacity-100\"\n )}\n onDoubleClick={onDoubleClick}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/data-grid/data-grid-column-header.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ColumnSort, Header, SortDirection, SortingState, Table } from \"@tanstack/react-table\";\nimport { ChevronDownIcon, ChevronUpIcon, EyeOffIcon, PinIcon, PinOffIcon, XIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger\n} from \"../components/ui/dropdown-menu.js\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../components/ui/tooltip.js\";\nimport { cn } from \"../lib/cn.js\";\nimport { useDataGridMessages } from \"./data-grid-locale.js\";\nimport { getColumnVariant } from \"./utils.js\";\n\ninterface DataGridColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {\n header: Header<TData, TValue>;\n table: Table<TData>;\n}\n\nexport function DataGridColumnHeader<TData, TValue>({\n header,\n table,\n className,\n onPointerDown,\n ...props\n}: DataGridColumnHeaderProps<TData, TValue>) {\n const msg = useDataGridMessages();\n\n const column = header.column;\n const label = column.columnDef.meta?.label\n ? column.columnDef.meta.label\n : typeof column.columnDef.header === \"string\"\n ? column.columnDef.header\n : column.id;\n\n const isAnyColumnResizing = table.getState().columnSizingInfo.isResizingColumn;\n\n const cellVariant = column.columnDef.meta?.cell;\n const columnVariant = getColumnVariant(cellVariant?.variant);\n\n const pinnedPosition = column.getIsPinned();\n const isPinnedLeft = pinnedPosition === \"left\";\n const isPinnedRight = pinnedPosition === \"right\";\n\n const onSortingChange = React.useCallback(\n (direction: SortDirection) => {\n table.setSorting((prev: SortingState) => {\n const existingSortIndex = prev.findIndex((sort) => sort.id === column.id);\n const newSort: ColumnSort = {\n id: column.id,\n desc: direction === \"desc\"\n };\n\n if (existingSortIndex >= 0) {\n const updated = [...prev];\n updated[existingSortIndex] = newSort;\n return updated;\n } else {\n return [...prev, newSort];\n }\n });\n },\n [column.id, table]\n );\n\n const onSortRemove = React.useCallback(() => {\n table.setSorting((prev: SortingState) => prev.filter((sort) => sort.id !== column.id));\n }, [column.id, table]);\n\n const onLeftPin = React.useCallback(() => {\n column.pin(\"left\");\n }, [column]);\n\n const onRightPin = React.useCallback(() => {\n column.pin(\"right\");\n }, [column]);\n\n const onUnpin = React.useCallback(() => {\n column.pin(false);\n }, [column]);\n\n const onTriggerPointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLButtonElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented) return;\n\n if (event.button !== 0) {\n return;\n }\n table.options.meta?.onColumnClick?.(column.id);\n },\n [table.options.meta, column.id, onPointerDown]\n );\n\n return (\n <>\n <DropdownMenu modal={false}>\n <DropdownMenuTrigger\n className={cn(\n \"flex size-full items-center justify-between gap-2 p-2 text-sm hover:bg-accent/40 data-[state=open]:bg-accent/40 [&_svg]:size-4\",\n isAnyColumnResizing && \"pointer-events-none\",\n className\n )}\n onPointerDown={onTriggerPointerDown}\n {...props}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n {columnVariant && (\n <Tooltip delayDuration={100}>\n <TooltipTrigger asChild>\n <columnVariant.icon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n </TooltipTrigger>\n {/* `TooltipContent` của gói TỰ portal ra ngoài — cần thiết vì hộp lưới\n có overflow-auto, không portal thì tooltip bị cắt. */}\n <TooltipContent side=\"top\">{columnVariant.label}</TooltipContent>\n </Tooltip>\n )}\n <span className=\"truncate\">{label}</span>\n </div>\n <ChevronDownIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" sideOffset={0} className=\"w-60\">\n {column.getCanSort() && (\n <>\n <DropdownMenuCheckboxItem\n className=\"gap-2 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"asc\"}\n onSelect={() => onSortingChange(\"asc\")}\n >\n <ChevronUpIcon />\n {msg.column.sortAsc}\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n className=\"gap-2 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-muted-foreground\"\n checked={column.getIsSorted() === \"desc\"}\n onSelect={() => onSortingChange(\"desc\")}\n >\n <ChevronDownIcon />\n {msg.column.sortDesc}\n </DropdownMenuCheckboxItem>\n {column.getIsSorted() && (\n <DropdownMenuItem onSelect={onSortRemove}>\n <XIcon />\n {msg.column.removeSort}\n </DropdownMenuItem>\n )}\n </>\n )}\n {column.getCanPin() && (\n <>\n {column.getCanSort() && <DropdownMenuSeparator />}\n\n {isPinnedLeft ? (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onUnpin}>\n <PinOffIcon />\n {msg.column.unpinLeft}\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onLeftPin}>\n <PinIcon />\n {msg.column.pinLeft}\n </DropdownMenuItem>\n )}\n {isPinnedRight ? (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onUnpin}>\n <PinOffIcon />\n {msg.column.unpinRight}\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onSelect={onRightPin}>\n <PinIcon />\n {msg.column.pinRight}\n </DropdownMenuItem>\n )}\n </>\n )}\n {column.getCanHide() && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"[&_svg]:text-muted-foreground\"\n onSelect={() => column.toggleVisibility(false)}\n >\n <EyeOffIcon />\n {msg.column.hide}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n {header.column.getCanResize() && <DataGridColumnResizer header={header} table={table} label={label} />}\n </>\n );\n}\n\nconst DataGridColumnResizer = React.memo(DataGridColumnResizerImpl, (prev, next) => {\n const prevColumn = prev.header.column;\n const nextColumn = next.header.column;\n\n if (prevColumn.getIsResizing() !== nextColumn.getIsResizing() || prevColumn.getSize() !== nextColumn.getSize()) {\n return false;\n }\n\n if (prev.label !== next.label) return false;\n\n return true;\n}) as typeof DataGridColumnResizerImpl;\n\ninterface DataGridColumnResizerProps<TData, TValue> extends DataGridColumnHeaderProps<TData, TValue> {\n label: string;\n}\n\nfunction DataGridColumnResizerImpl<TData, TValue>({ header, table, label }: DataGridColumnResizerProps<TData, TValue>) {\n const msg = useDataGridMessages();\n const defaultColumnDef = table._getDefaultColumnDef();\n\n const onDoubleClick = React.useCallback(() => {\n header.column.resetSize();\n }, [header.column]);\n\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={msg.column.resize(label)}\n aria-valuenow={header.column.getSize()}\n aria-valuemin={defaultColumnDef.minSize}\n aria-valuemax={defaultColumnDef.maxSize}\n tabIndex={0}\n className={cn(\n // Tay kéo chỉ hiện khi rê/focus/đang kéo, nên nó CHỈ mang đúng một màu — `--primary-ink`\n // (bậc NÉT). `--primary` trần là bậc tô NỀN: gold #E8B824 chỉ 1,73:1 với nền trang ở\n // light, tức một tay kéo nhìn thấy được ở dark mà gần như vô hình ở light.\n \"absolute -end-px top-0 z-50 h-full w-0.5 cursor-ew-resize touch-none select-none bg-primary-ink transition-opacity after:absolute after:inset-y-0 after:start-1/2 after:h-full after:w-[18px] after:-translate-x-1/2 after:content-[''] focus:outline-none\",\n header.column.getIsResizing() ? \"opacity-100\" : \"opacity-0 hover:opacity-100 focus:opacity-100\"\n )}\n onDoubleClick={onDoubleClick}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
DropdownMenuSeparator,
|
|
10
10
|
DropdownMenuTrigger
|
|
11
11
|
} from "../components/ui/dropdown-menu.js";
|
|
12
|
-
import {
|
|
12
|
+
import { useAsRef } from "../lib/use-as-ref.js";
|
|
13
|
+
import { useDataGridMessages } from "./data-grid-locale.js";
|
|
13
14
|
import { toastSuccess } from "./toast.js";
|
|
14
|
-
import { useAsRef } from "./use-as-ref.js";
|
|
15
15
|
import { getEmptyCellValue, parseCellKey } from "./utils.js";
|
|
16
16
|
function DataGridContextMenu({ tableMeta, columns, contextMenu }) {
|
|
17
17
|
const onContextMenuOpenChange = tableMeta?.onContextMenuOpenChange;
|
|
@@ -60,6 +60,7 @@ function ContextMenuImpl({
|
|
|
60
60
|
onCellsCopy,
|
|
61
61
|
onCellsCut
|
|
62
62
|
}) {
|
|
63
|
+
const msg = useDataGridMessages();
|
|
63
64
|
const propsRef = useAsRef({
|
|
64
65
|
dataGridRef,
|
|
65
66
|
selectionState,
|
|
@@ -115,7 +116,7 @@ function ContextMenuImpl({
|
|
|
115
116
|
}
|
|
116
117
|
onDataUpdate2?.(updates);
|
|
117
118
|
toastSuccess(msg.toast.cellsCleared(updates.length));
|
|
118
|
-
}, [propsRef]);
|
|
119
|
+
}, [propsRef, msg]);
|
|
119
120
|
const onDelete = React.useCallback(async () => {
|
|
120
121
|
const { selectionState: selectionState2, onRowsDelete: onRowsDelete2 } = propsRef.current;
|
|
121
122
|
if (!selectionState2?.selectedCells || selectionState2.selectedCells.size === 0) return;
|
|
@@ -128,7 +129,7 @@ function ContextMenuImpl({
|
|
|
128
129
|
const rowCount = rowIndicesArray.length;
|
|
129
130
|
await onRowsDelete2?.(rowIndicesArray);
|
|
130
131
|
toastSuccess(msg.toast.rowsDeleted(rowCount));
|
|
131
|
-
}, [propsRef]);
|
|
132
|
+
}, [propsRef, msg]);
|
|
132
133
|
return /* @__PURE__ */ jsxs(DropdownMenu, { open: contextMenu.open, onOpenChange: onContextMenuOpenChange, children: [
|
|
133
134
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { style: triggerStyle }),
|
|
134
135
|
/* @__PURE__ */ jsxs(DropdownMenuContent, { "data-grid-popover": "", align: "start", className: "w-48", onCloseAutoFocus, children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data-grid/data-grid-context-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ColumnDef, TableMeta } from \"@tanstack/react-table\";\nimport { CopyIcon, EraserIcon, ScissorsIcon, Trash2Icon } from \"lucide-react\";\nimport * as React from \"react\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger\n} from \"../components/ui/dropdown-menu.js\";\nimport { msg } from \"./messages.js\";\nimport { toastSuccess } from \"./toast.js\";\nimport type { CellUpdate, ContextMenuState } from \"./types.js\";\nimport { useAsRef } from \"./use-as-ref.js\";\nimport { getEmptyCellValue, parseCellKey } from \"./utils.js\";\n\ninterface DataGridContextMenuProps<TData> {\n tableMeta: TableMeta<TData>;\n columns: Array<ColumnDef<TData>>;\n contextMenu: ContextMenuState;\n}\n\nexport function DataGridContextMenu<TData>({ tableMeta, columns, contextMenu }: DataGridContextMenuProps<TData>) {\n const onContextMenuOpenChange = tableMeta?.onContextMenuOpenChange;\n const selectionState = tableMeta?.selectionState;\n const dataGridRef = tableMeta?.dataGridRef;\n const onDataUpdate = tableMeta?.onDataUpdate;\n const onRowsDelete = tableMeta?.onRowsDelete;\n const onCellsCopy = tableMeta?.onCellsCopy;\n const onCellsCut = tableMeta?.onCellsCut;\n\n if (!contextMenu.open) return null;\n\n return (\n <ContextMenu\n tableMeta={tableMeta}\n columns={columns}\n dataGridRef={dataGridRef}\n contextMenu={contextMenu}\n onContextMenuOpenChange={onContextMenuOpenChange}\n selectionState={selectionState}\n onDataUpdate={onDataUpdate}\n onRowsDelete={onRowsDelete}\n onCellsCopy={onCellsCopy}\n onCellsCut={onCellsCut}\n />\n );\n}\n\ninterface ContextMenuProps<TData>\n extends Pick<\n TableMeta<TData>,\n | \"dataGridRef\"\n | \"onContextMenuOpenChange\"\n | \"selectionState\"\n | \"onDataUpdate\"\n | \"onRowsDelete\"\n | \"onCellsCopy\"\n | \"onCellsCut\"\n | \"readOnly\"\n >,\n Required<Pick<TableMeta<TData>, \"contextMenu\">> {\n tableMeta: TableMeta<TData>;\n columns: Array<ColumnDef<TData>>;\n}\n\nconst ContextMenu = React.memo(ContextMenuImpl, (prev, next) => {\n if (prev.contextMenu.open !== next.contextMenu.open) return false;\n if (!next.contextMenu.open) return true;\n if (prev.contextMenu.x !== next.contextMenu.x) return false;\n if (prev.contextMenu.y !== next.contextMenu.y) return false;\n\n const prevSize = prev.selectionState?.selectedCells?.size ?? 0;\n const nextSize = next.selectionState?.selectedCells?.size ?? 0;\n if (prevSize !== nextSize) return false;\n\n return true;\n}) as typeof ContextMenuImpl;\n\nfunction ContextMenuImpl<TData>({\n tableMeta,\n columns,\n dataGridRef,\n contextMenu,\n onContextMenuOpenChange,\n selectionState,\n onDataUpdate,\n onRowsDelete,\n onCellsCopy,\n onCellsCut\n}: ContextMenuProps<TData>) {\n const propsRef = useAsRef({\n dataGridRef,\n selectionState,\n onDataUpdate,\n onRowsDelete,\n onCellsCopy,\n onCellsCut,\n columns\n });\n\n const triggerStyle = React.useMemo<React.CSSProperties>(\n () => ({\n position: \"fixed\",\n left: `${contextMenu.x}px`,\n top: `${contextMenu.y}px`,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: 0,\n border: \"none\",\n background: \"transparent\",\n pointerEvents: \"none\",\n opacity: 0\n }),\n [contextMenu.x, contextMenu.y]\n );\n\n const onCloseAutoFocus: NonNullable<React.ComponentProps<typeof DropdownMenuContent>[\"onCloseAutoFocus\"]> =\n React.useCallback(\n (event) => {\n event.preventDefault();\n propsRef.current.dataGridRef?.current?.focus();\n },\n [propsRef]\n );\n\n const onCopy = React.useCallback(() => {\n propsRef.current.onCellsCopy?.();\n }, [propsRef]);\n\n const onCut = React.useCallback(() => {\n propsRef.current.onCellsCut?.();\n }, [propsRef]);\n\n const onClear = React.useCallback(() => {\n const { selectionState, columns, onDataUpdate } = propsRef.current;\n\n if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n const updates: Array<CellUpdate> = [];\n\n for (const cellKey of selectionState.selectedCells) {\n const { rowIndex, columnId } = parseCellKey(cellKey);\n\n // Get column from columns array\n const column = columns.find((col) => {\n if (col.id) return col.id === columnId;\n if (\"accessorKey\" in col) return col.accessorKey === columnId;\n return false;\n });\n const cellVariant = column?.meta?.cell?.variant;\n\n const emptyValue = getEmptyCellValue(cellVariant);\n\n updates.push({ rowIndex, columnId, value: emptyValue });\n }\n\n onDataUpdate?.(updates);\n\n toastSuccess(msg.toast.cellsCleared(updates.length));\n }, [propsRef]);\n\n const onDelete = React.useCallback(async () => {\n const { selectionState, onRowsDelete } = propsRef.current;\n\n if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n const rowIndices = new Set<number>();\n for (const cellKey of selectionState.selectedCells) {\n const { rowIndex } = parseCellKey(cellKey);\n rowIndices.add(rowIndex);\n }\n\n const rowIndicesArray = Array.from(rowIndices).sort((a, b) => a - b);\n const rowCount = rowIndicesArray.length;\n\n await onRowsDelete?.(rowIndicesArray);\n\n toastSuccess(msg.toast.rowsDeleted(rowCount));\n }, [propsRef]);\n\n return (\n <DropdownMenu open={contextMenu.open} onOpenChange={onContextMenuOpenChange}>\n <DropdownMenuTrigger style={triggerStyle} />\n <DropdownMenuContent data-grid-popover=\"\" align=\"start\" className=\"w-48\" onCloseAutoFocus={onCloseAutoFocus}>\n <DropdownMenuItem onSelect={onCopy}>\n <CopyIcon />\n {msg.contextMenu.copy}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={onCut} disabled={tableMeta?.readOnly}>\n <ScissorsIcon />\n {msg.contextMenu.cut}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={onClear} disabled={tableMeta?.readOnly}>\n <EraserIcon />\n {msg.contextMenu.clear}\n </DropdownMenuItem>\n {onRowsDelete && (\n <>\n <DropdownMenuSeparator />\n {/* `variant=\"destructive\"` của gói đã đi qua `--destructive-ink` (bậc CHỮ) cho cả\n chữ, icon và nền focus — đừng tự viết lại bằng `text-destructive` (bậc TÔ NỀN). */}\n <DropdownMenuItem variant=\"destructive\" onSelect={onDelete}>\n <Trash2Icon />\n {msg.contextMenu.deleteRows}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":["selectionState","columns","onDataUpdate","onRowsDelete"]}
|
|
1
|
+
{"version":3,"sources":["../../src/data-grid/data-grid-context-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ColumnDef, TableMeta } from \"@tanstack/react-table\";\nimport { CopyIcon, EraserIcon, ScissorsIcon, Trash2Icon } from \"lucide-react\";\nimport * as React from \"react\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger\n} from \"../components/ui/dropdown-menu.js\";\nimport { useAsRef } from \"../lib/use-as-ref.js\";\nimport { useDataGridMessages } from \"./data-grid-locale.js\";\nimport { toastSuccess } from \"./toast.js\";\nimport type { CellUpdate, ContextMenuState } from \"./types.js\";\nimport { getEmptyCellValue, parseCellKey } from \"./utils.js\";\n\ninterface DataGridContextMenuProps<TData> {\n tableMeta: TableMeta<TData>;\n columns: Array<ColumnDef<TData>>;\n contextMenu: ContextMenuState;\n}\n\nexport function DataGridContextMenu<TData>({ tableMeta, columns, contextMenu }: DataGridContextMenuProps<TData>) {\n const onContextMenuOpenChange = tableMeta?.onContextMenuOpenChange;\n const selectionState = tableMeta?.selectionState;\n const dataGridRef = tableMeta?.dataGridRef;\n const onDataUpdate = tableMeta?.onDataUpdate;\n const onRowsDelete = tableMeta?.onRowsDelete;\n const onCellsCopy = tableMeta?.onCellsCopy;\n const onCellsCut = tableMeta?.onCellsCut;\n\n if (!contextMenu.open) return null;\n\n return (\n <ContextMenu\n tableMeta={tableMeta}\n columns={columns}\n dataGridRef={dataGridRef}\n contextMenu={contextMenu}\n onContextMenuOpenChange={onContextMenuOpenChange}\n selectionState={selectionState}\n onDataUpdate={onDataUpdate}\n onRowsDelete={onRowsDelete}\n onCellsCopy={onCellsCopy}\n onCellsCut={onCellsCut}\n />\n );\n}\n\ninterface ContextMenuProps<TData>\n extends Pick<\n TableMeta<TData>,\n | \"dataGridRef\"\n | \"onContextMenuOpenChange\"\n | \"selectionState\"\n | \"onDataUpdate\"\n | \"onRowsDelete\"\n | \"onCellsCopy\"\n | \"onCellsCut\"\n | \"readOnly\"\n >,\n Required<Pick<TableMeta<TData>, \"contextMenu\">> {\n tableMeta: TableMeta<TData>;\n columns: Array<ColumnDef<TData>>;\n}\n\nconst ContextMenu = React.memo(ContextMenuImpl, (prev, next) => {\n if (prev.contextMenu.open !== next.contextMenu.open) return false;\n if (!next.contextMenu.open) return true;\n if (prev.contextMenu.x !== next.contextMenu.x) return false;\n if (prev.contextMenu.y !== next.contextMenu.y) return false;\n\n const prevSize = prev.selectionState?.selectedCells?.size ?? 0;\n const nextSize = next.selectionState?.selectedCells?.size ?? 0;\n if (prevSize !== nextSize) return false;\n\n return true;\n}) as typeof ContextMenuImpl;\n\nfunction ContextMenuImpl<TData>({\n tableMeta,\n columns,\n dataGridRef,\n contextMenu,\n onContextMenuOpenChange,\n selectionState,\n onDataUpdate,\n onRowsDelete,\n onCellsCopy,\n onCellsCut\n}: ContextMenuProps<TData>) {\n const msg = useDataGridMessages();\n\n const propsRef = useAsRef({\n dataGridRef,\n selectionState,\n onDataUpdate,\n onRowsDelete,\n onCellsCopy,\n onCellsCut,\n columns\n });\n\n const triggerStyle = React.useMemo<React.CSSProperties>(\n () => ({\n position: \"fixed\",\n left: `${contextMenu.x}px`,\n top: `${contextMenu.y}px`,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: 0,\n border: \"none\",\n background: \"transparent\",\n pointerEvents: \"none\",\n opacity: 0\n }),\n [contextMenu.x, contextMenu.y]\n );\n\n const onCloseAutoFocus: NonNullable<React.ComponentProps<typeof DropdownMenuContent>[\"onCloseAutoFocus\"]> =\n React.useCallback(\n (event) => {\n event.preventDefault();\n propsRef.current.dataGridRef?.current?.focus();\n },\n [propsRef]\n );\n\n const onCopy = React.useCallback(() => {\n propsRef.current.onCellsCopy?.();\n }, [propsRef]);\n\n const onCut = React.useCallback(() => {\n propsRef.current.onCellsCut?.();\n }, [propsRef]);\n\n const onClear = React.useCallback(() => {\n const { selectionState, columns, onDataUpdate } = propsRef.current;\n\n if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n const updates: Array<CellUpdate> = [];\n\n for (const cellKey of selectionState.selectedCells) {\n const { rowIndex, columnId } = parseCellKey(cellKey);\n\n // Get column from columns array\n const column = columns.find((col) => {\n if (col.id) return col.id === columnId;\n if (\"accessorKey\" in col) return col.accessorKey === columnId;\n return false;\n });\n const cellVariant = column?.meta?.cell?.variant;\n\n const emptyValue = getEmptyCellValue(cellVariant);\n\n updates.push({ rowIndex, columnId, value: emptyValue });\n }\n\n onDataUpdate?.(updates);\n\n toastSuccess(msg.toast.cellsCleared(updates.length));\n }, [propsRef, msg]);\n\n const onDelete = React.useCallback(async () => {\n const { selectionState, onRowsDelete } = propsRef.current;\n\n if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n const rowIndices = new Set<number>();\n for (const cellKey of selectionState.selectedCells) {\n const { rowIndex } = parseCellKey(cellKey);\n rowIndices.add(rowIndex);\n }\n\n const rowIndicesArray = Array.from(rowIndices).sort((a, b) => a - b);\n const rowCount = rowIndicesArray.length;\n\n await onRowsDelete?.(rowIndicesArray);\n\n toastSuccess(msg.toast.rowsDeleted(rowCount));\n }, [propsRef, msg]);\n\n return (\n <DropdownMenu open={contextMenu.open} onOpenChange={onContextMenuOpenChange}>\n <DropdownMenuTrigger style={triggerStyle} />\n <DropdownMenuContent data-grid-popover=\"\" align=\"start\" className=\"w-48\" onCloseAutoFocus={onCloseAutoFocus}>\n <DropdownMenuItem onSelect={onCopy}>\n <CopyIcon />\n {msg.contextMenu.copy}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={onCut} disabled={tableMeta?.readOnly}>\n <ScissorsIcon />\n {msg.contextMenu.cut}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={onClear} disabled={tableMeta?.readOnly}>\n <EraserIcon />\n {msg.contextMenu.clear}\n </DropdownMenuItem>\n {onRowsDelete && (\n <>\n <DropdownMenuSeparator />\n {/* `variant=\"destructive\"` của gói đã đi qua `--destructive-ink` (bậc CHỮ) cho cả\n chữ, icon và nền focus — đừng tự viết lại bằng `text-destructive` (bậc TÔ NỀN). */}\n <DropdownMenuItem variant=\"destructive\" onSelect={onDelete}>\n <Trash2Icon />\n {msg.contextMenu.deleteRows}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":["selectionState","columns","onDataUpdate","onRowsDelete"]}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { Table } from '@tanstack/react-table';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { PopoverContent } from '../components/ui/popover.js';
|
|
4
|
+
import { DataGridLocale } from './messages.js';
|
|
5
|
+
import { DataGridMessages } from './messages-en.js';
|
|
4
6
|
import '@radix-ui/react-popover';
|
|
7
|
+
import './messages-vi.js';
|
|
5
8
|
|
|
6
9
|
interface DataGridFilterMenuProps<TData> extends React.ComponentProps<typeof PopoverContent> {
|
|
7
10
|
table: Table<TData>;
|
|
8
11
|
disabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Ngôn ngữ của menu: `"en"` (mặc định) · `"vi"`, hoặc cả một bảng chuỗi tự soạn.
|
|
14
|
+
*
|
|
15
|
+
* ⚠ Thanh công cụ nằm NGOÀI `<DataGrid>`, nên `locale` truyền cho lưới không với tới đây. Bọc
|
|
16
|
+
* cả màn bằng `DataGridLocaleProvider` (một lần, đúng cho mọi mảnh), hoặc truyền prop này cho
|
|
17
|
+
* từng menu. Prop thắng provider.
|
|
18
|
+
*/
|
|
19
|
+
locale?: DataGridLocale | DataGridMessages;
|
|
9
20
|
}
|
|
10
|
-
declare function DataGridFilterMenu<TData>({ table, disabled, className, ...props }: DataGridFilterMenuProps<TData>): React.JSX.Element;
|
|
21
|
+
declare function DataGridFilterMenu<TData>({ table, disabled, className, locale, ...props }: DataGridFilterMenuProps<TData>): React.JSX.Element;
|
|
11
22
|
|
|
12
23
|
export { DataGridFilterMenu };
|
|
@@ -19,8 +19,8 @@ import { Input } from "../components/ui/input.js";
|
|
|
19
19
|
import { Popover, PopoverContent, PopoverTrigger } from "../components/ui/popover.js";
|
|
20
20
|
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select.js";
|
|
21
21
|
import { cn } from "../lib/cn.js";
|
|
22
|
+
import { DataGridLocaleProvider, useDataGridMessages, useResolvedDataGridMessages } from "./data-grid-locale.js";
|
|
22
23
|
import { getDefaultOperator, getOperatorsForVariant } from "./filters.js";
|
|
23
|
-
import { msg } from "./messages.js";
|
|
24
24
|
import { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay } from "./sortable.js";
|
|
25
25
|
import { useDebouncedCallback } from "./use-debounced-callback.js";
|
|
26
26
|
import { formatDate } from "./utils.js";
|
|
@@ -28,7 +28,14 @@ const FILTER_SHORTCUT_KEY = "f";
|
|
|
28
28
|
const REMOVE_FILTER_SHORTCUTS = /* @__PURE__ */ new Set(["backspace", "delete"]);
|
|
29
29
|
const FILTER_DEBOUNCE_MS = 300;
|
|
30
30
|
const OPERATORS_WITHOUT_VALUE = /* @__PURE__ */ new Set(["isEmpty", "isNotEmpty", "isTrue", "isFalse"]);
|
|
31
|
-
function DataGridFilterMenu({
|
|
31
|
+
function DataGridFilterMenu({
|
|
32
|
+
table,
|
|
33
|
+
disabled,
|
|
34
|
+
className,
|
|
35
|
+
locale,
|
|
36
|
+
...props
|
|
37
|
+
}) {
|
|
38
|
+
const msg = useResolvedDataGridMessages(locale);
|
|
32
39
|
const dir = useDirection();
|
|
33
40
|
const id = React.useId();
|
|
34
41
|
const labelId = React.useId();
|
|
@@ -113,18 +120,19 @@ function DataGridFilterMenu({ table, disabled, className, ...props }) {
|
|
|
113
120
|
},
|
|
114
121
|
[columnFilters.length, onFiltersReset]
|
|
115
122
|
);
|
|
116
|
-
return /* @__PURE__ */ jsxs(Sortable, { value: columnFilters, onValueChange: table.setColumnFilters, getItemValue: (item) => item.id, children: [
|
|
123
|
+
return /* @__PURE__ */ jsx(DataGridLocaleProvider, { locale: msg, children: /* @__PURE__ */ jsxs(Sortable, { value: columnFilters, onValueChange: table.setColumnFilters, getItemValue: (item) => item.id, children: [
|
|
117
124
|
/* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
118
125
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
119
126
|
Button,
|
|
120
127
|
{
|
|
121
128
|
dir,
|
|
122
129
|
variant: "outline",
|
|
123
|
-
|
|
130
|
+
size: "sm",
|
|
131
|
+
className: "font-normal",
|
|
124
132
|
onKeyDown: onTriggerKeyDown,
|
|
125
133
|
disabled,
|
|
126
134
|
children: [
|
|
127
|
-
/* @__PURE__ */ jsx(ListFilter, { "aria-hidden": "true", className: "text-muted-foreground" }),
|
|
135
|
+
/* @__PURE__ */ jsx(ListFilter, { "aria-hidden": "true", className: "size-3.5 text-muted-foreground" }),
|
|
128
136
|
msg.filter.trigger,
|
|
129
137
|
columnFilters.length > 0 && /* @__PURE__ */ jsx(
|
|
130
138
|
"span",
|
|
@@ -204,7 +212,7 @@ function DataGridFilterMenu({ table, disabled, className, ...props }) {
|
|
|
204
212
|
/* @__PURE__ */ jsx("div", { className: "size-8 shrink-0 rounded-sm bg-muted" }),
|
|
205
213
|
/* @__PURE__ */ jsx("div", { className: "size-8 shrink-0 rounded-sm bg-muted" })
|
|
206
214
|
] }) })
|
|
207
|
-
] });
|
|
215
|
+
] }) });
|
|
208
216
|
}
|
|
209
217
|
function DataGridFilterItem({
|
|
210
218
|
filter,
|
|
@@ -218,6 +226,7 @@ function DataGridFilterItem({
|
|
|
218
226
|
onFilterUpdate,
|
|
219
227
|
onFilterRemove
|
|
220
228
|
}) {
|
|
229
|
+
const msg = useDataGridMessages();
|
|
221
230
|
const fieldListboxId = `${filterItemId}-field-listbox`;
|
|
222
231
|
const fieldTriggerId = `${filterItemId}-field-trigger`;
|
|
223
232
|
const operatorListboxId = `${filterItemId}-operator-listbox`;
|
|
@@ -386,10 +395,10 @@ function DataGridFilterItem({
|
|
|
386
395
|
size: "icon",
|
|
387
396
|
className: "size-8 rounded",
|
|
388
397
|
onClick: () => onFilterRemove(filter.id),
|
|
389
|
-
children: /* @__PURE__ */ jsx(Trash2, { "aria-hidden": "true" })
|
|
398
|
+
children: /* @__PURE__ */ jsx(Trash2, { "aria-hidden": "true", className: "size-3.5" })
|
|
390
399
|
}
|
|
391
400
|
),
|
|
392
|
-
/* @__PURE__ */ jsx(SortableItemHandle, { asChild: true, children: /* @__PURE__ */ jsx(Button, { "aria-label": msg.filter.drag, variant: "outline", size: "icon", className: "size-8 rounded", children: /* @__PURE__ */ jsx(GripVertical, { "aria-hidden": "true" }) }) })
|
|
401
|
+
/* @__PURE__ */ jsx(SortableItemHandle, { asChild: true, children: /* @__PURE__ */ jsx(Button, { "aria-label": msg.filter.drag, variant: "outline", size: "icon", className: "size-8 rounded", children: /* @__PURE__ */ jsx(GripVertical, { "aria-hidden": "true", className: "size-3.5" }) }) })
|
|
393
402
|
]
|
|
394
403
|
}
|
|
395
404
|
) });
|
|
@@ -398,7 +407,7 @@ function DataGridFilterInput({
|
|
|
398
407
|
variant,
|
|
399
408
|
operator,
|
|
400
409
|
dir,
|
|
401
|
-
placeholder
|
|
410
|
+
placeholder,
|
|
402
411
|
value,
|
|
403
412
|
endValue,
|
|
404
413
|
column,
|
|
@@ -406,6 +415,8 @@ function DataGridFilterInput({
|
|
|
406
415
|
onValueChange,
|
|
407
416
|
onEndValueChange
|
|
408
417
|
}) {
|
|
418
|
+
const msg = useDataGridMessages();
|
|
419
|
+
const inputPlaceholder = placeholder ?? msg.filter.valuePlaceholder;
|
|
409
420
|
const [showValueSelector, setShowValueSelector] = React.useState(false);
|
|
410
421
|
const [localValue, setLocalValue] = React.useState(value);
|
|
411
422
|
const [localEndValue, setLocalEndValue] = React.useState(endValue);
|
|
@@ -467,8 +478,8 @@ function DataGridFilterInput({
|
|
|
467
478
|
id: inputId,
|
|
468
479
|
type: "number",
|
|
469
480
|
inputMode: "numeric",
|
|
470
|
-
placeholder,
|
|
471
|
-
"aria-label":
|
|
481
|
+
placeholder: inputPlaceholder,
|
|
482
|
+
"aria-label": inputPlaceholder,
|
|
472
483
|
value: localValue ?? "",
|
|
473
484
|
onChange: (event) => {
|
|
474
485
|
const val = event.target.value;
|
|
@@ -500,7 +511,7 @@ function DataGridFilterInput({
|
|
|
500
511
|
!startDate && "text-muted-foreground"
|
|
501
512
|
),
|
|
502
513
|
children: [
|
|
503
|
-
/* @__PURE__ */ jsx(CalendarIcon, { "aria-hidden": "true" }),
|
|
514
|
+
/* @__PURE__ */ jsx(CalendarIcon, { "aria-hidden": "true", className: "size-3.5" }),
|
|
504
515
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: displayValue })
|
|
505
516
|
]
|
|
506
517
|
}
|
|
@@ -535,7 +546,7 @@ function DataGridFilterInput({
|
|
|
535
546
|
variant: "outline",
|
|
536
547
|
className: cn("h-8 w-full justify-start gap-2 rounded font-normal", !dateValue && "text-muted-foreground"),
|
|
537
548
|
children: [
|
|
538
|
-
/* @__PURE__ */ jsx(CalendarIcon, { "aria-hidden": "true" }),
|
|
549
|
+
/* @__PURE__ */ jsx(CalendarIcon, { "aria-hidden": "true", className: "size-3.5" }),
|
|
539
550
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: dateValue ? formatDate(dateValue) : msg.filter.pickDate })
|
|
540
551
|
]
|
|
541
552
|
}
|
|
@@ -575,7 +586,7 @@ function DataGridFilterInput({
|
|
|
575
586
|
dir,
|
|
576
587
|
variant: "outline",
|
|
577
588
|
className: "h-8 w-full justify-start rounded font-normal",
|
|
578
|
-
children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children:
|
|
589
|
+
children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: inputPlaceholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
579
590
|
selectedOptionsWithIcons.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex items-center -space-x-2 rtl:space-x-reverse", children: selectedOptionsWithIcons.map(
|
|
580
591
|
(selectedOption2) => selectedOption2.icon && /* @__PURE__ */ jsx("div", { className: "rounded-full border bg-background p-0.5", children: /* @__PURE__ */ jsx(selectedOption2.icon, { className: "size-3.5" }) }, selectedOption2.value)
|
|
581
592
|
) }),
|
|
@@ -624,7 +635,7 @@ function DataGridFilterInput({
|
|
|
624
635
|
children: selectedOption ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
625
636
|
selectedOption.icon && /* @__PURE__ */ jsx(selectedOption.icon, {}),
|
|
626
637
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption.label })
|
|
627
|
-
] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children:
|
|
638
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: inputPlaceholder })
|
|
628
639
|
}
|
|
629
640
|
) }),
|
|
630
641
|
/* @__PURE__ */ jsx(PopoverContent, { id: inputListboxId, dir, align: "start", className: "w-[200px] p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
|
|
@@ -695,8 +706,8 @@ function DataGridFilterInput({
|
|
|
695
706
|
{
|
|
696
707
|
id: inputId,
|
|
697
708
|
type: "text",
|
|
698
|
-
placeholder,
|
|
699
|
-
"aria-label":
|
|
709
|
+
placeholder: inputPlaceholder,
|
|
710
|
+
"aria-label": inputPlaceholder,
|
|
700
711
|
className: "h-8 w-full rounded",
|
|
701
712
|
value: localValue ?? "",
|
|
702
713
|
onChange: (event) => {
|