@comitor/ui 1.10.0 → 1.11.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/README.md +15 -4
- package/dist/data-grid/compose-refs.d.ts +19 -0
- package/dist/data-grid/compose-refs.js +41 -0
- package/dist/data-grid/compose-refs.js.map +1 -0
- package/dist/data-grid/data-grid-cell-variants.d.ts +15 -0
- package/dist/data-grid/data-grid-cell-variants.js +1734 -0
- package/dist/data-grid/data-grid-cell-variants.js.map +1 -0
- package/dist/data-grid/data-grid-cell-wrapper.d.ts +9 -0
- package/dist/data-grid/data-grid-cell-wrapper.js +179 -0
- package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -0
- package/dist/data-grid/data-grid-cell.d.ts +8 -0
- package/dist/data-grid/data-grid-cell.js +101 -0
- package/dist/data-grid/data-grid-cell.js.map +1 -0
- package/dist/data-grid/data-grid-column-header.d.ts +12 -0
- package/dist/data-grid/data-grid-column-header.js +205 -0
- package/dist/data-grid/data-grid-column-header.js.map +1 -0
- package/dist/data-grid/data-grid-context-menu.d.ts +12 -0
- package/dist/data-grid/data-grid-context-menu.js +160 -0
- package/dist/data-grid/data-grid-context-menu.js.map +1 -0
- package/dist/data-grid/data-grid-filter-menu.d.ts +12 -0
- package/dist/data-grid/data-grid-filter-menu.js +714 -0
- package/dist/data-grid/data-grid-filter-menu.js.map +1 -0
- package/dist/data-grid/data-grid-keyboard-shortcuts.d.ts +20 -0
- package/dist/data-grid/data-grid-keyboard-shortcuts.js +227 -0
- package/dist/data-grid/data-grid-keyboard-shortcuts.js.map +1 -0
- package/dist/data-grid/data-grid-paste-dialog.d.ts +11 -0
- package/dist/data-grid/data-grid-paste-dialog.js +103 -0
- package/dist/data-grid/data-grid-paste-dialog.js.map +1 -0
- package/dist/data-grid/data-grid-presence.d.ts +14 -0
- package/dist/data-grid/data-grid-presence.js +16 -0
- package/dist/data-grid/data-grid-presence.js.map +1 -0
- package/dist/data-grid/data-grid-row-height-menu.d.ts +15 -0
- package/dist/data-grid/data-grid-row-height-menu.js +56 -0
- package/dist/data-grid/data-grid-row-height-menu.js.map +1 -0
- package/dist/data-grid/data-grid-row.d.ts +28 -0
- package/dist/data-grid/data-grid-row.js +206 -0
- package/dist/data-grid/data-grid-row.js.map +1 -0
- package/dist/data-grid/data-grid-search.d.ts +10 -0
- package/dist/data-grid/data-grid-search.js +183 -0
- package/dist/data-grid/data-grid-search.js.map +1 -0
- package/dist/data-grid/data-grid-select-column.d.ts +12 -0
- package/dist/data-grid/data-grid-select-column.js +177 -0
- package/dist/data-grid/data-grid-select-column.js.map +1 -0
- package/dist/data-grid/data-grid-skeleton.d.ts +13 -0
- package/dist/data-grid/data-grid-skeleton.js +52 -0
- package/dist/data-grid/data-grid-skeleton.js.map +1 -0
- package/dist/data-grid/data-grid-sort-menu.d.ts +12 -0
- package/dist/data-grid/data-grid-sort-menu.js +271 -0
- package/dist/data-grid/data-grid-sort-menu.js.map +1 -0
- package/dist/data-grid/data-grid-view-menu.d.ts +13 -0
- package/dist/data-grid/data-grid-view-menu.js +66 -0
- package/dist/data-grid/data-grid-view-menu.js.map +1 -0
- package/dist/data-grid/data-grid.d.ts +32 -0
- package/dist/data-grid/data-grid.js +235 -0
- package/dist/data-grid/data-grid.js.map +1 -0
- package/dist/data-grid/filters.d.ts +31 -0
- package/dist/data-grid/filters.js +212 -0
- package/dist/data-grid/filters.js.map +1 -0
- package/dist/data-grid/index.d.ts +22 -0
- package/dist/data-grid/index.js +77 -0
- package/dist/data-grid/index.js.map +1 -0
- package/dist/data-grid/messages.d.ts +280 -0
- package/dist/data-grid/messages.js +279 -0
- package/dist/data-grid/messages.js.map +1 -0
- package/dist/data-grid/sortable.d.ts +50 -0
- package/dist/data-grid/sortable.js +361 -0
- package/dist/data-grid/sortable.js.map +1 -0
- package/dist/data-grid/toast.d.ts +10 -0
- package/dist/data-grid/toast.js +21 -0
- package/dist/data-grid/toast.js.map +1 -0
- package/dist/data-grid/types.d.ts +189 -0
- package/dist/data-grid/types.js +1 -0
- package/dist/data-grid/types.js.map +1 -0
- package/dist/data-grid/use-as-ref.d.ts +5 -0
- package/dist/data-grid/use-as-ref.js +13 -0
- package/dist/data-grid/use-as-ref.js.map +1 -0
- package/dist/data-grid/use-badge-overflow.d.ts +24 -0
- package/dist/data-grid/use-badge-overflow.js +123 -0
- package/dist/data-grid/use-badge-overflow.js.map +1 -0
- package/dist/data-grid/use-callback-ref.d.ts +10 -0
- package/dist/data-grid/use-callback-ref.js +12 -0
- package/dist/data-grid/use-callback-ref.js.map +1 -0
- package/dist/data-grid/use-data-grid-undo-redo.d.ts +33 -0
- package/dist/data-grid/use-data-grid-undo-redo.js +345 -0
- package/dist/data-grid/use-data-grid-undo-redo.js.map +1 -0
- package/dist/data-grid/use-data-grid.d.ts +92 -0
- package/dist/data-grid/use-data-grid.js +2692 -0
- package/dist/data-grid/use-data-grid.js.map +1 -0
- package/dist/data-grid/use-debounced-callback.d.ts +6 -0
- package/dist/data-grid/use-debounced-callback.js +19 -0
- package/dist/data-grid/use-debounced-callback.js.map +1 -0
- package/dist/data-grid/use-isomorphic-layout-effect.d.ts +5 -0
- package/dist/data-grid/use-isomorphic-layout-effect.js +6 -0
- package/dist/data-grid/use-isomorphic-layout-effect.js.map +1 -0
- package/dist/data-grid/use-lazy-ref.d.ts +5 -0
- package/dist/data-grid/use-lazy-ref.js +12 -0
- package/dist/data-grid/use-lazy-ref.js.map +1 -0
- package/dist/data-grid/utils.d.ts +73 -0
- package/dist/data-grid/utils.js +408 -0
- package/dist/data-grid/utils.js.map +1 -0
- package/package.json +33 -15
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data-grid/data-grid-cell-variants.tsx"],"sourcesContent":["\"use client\";\n\nimport { vi } from \"date-fns/locale\";\nimport { Check, Upload, X } from \"lucide-react\";\nimport * as React from \"react\";\nimport { Badge, badgeVariants } from \"../components/ui/badge.js\";\nimport { Button } from \"../components/ui/button.js\";\nimport { Calendar } from \"../components/ui/calendar.js\";\nimport { Checkbox } from \"../components/ui/checkbox.js\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator\n} from \"../components/ui/command.js\";\nimport { Popover, PopoverAnchor, PopoverContent } from \"../components/ui/popover.js\";\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from \"../components/ui/select.js\";\nimport { Skeleton } from \"../components/ui/skeleton.js\";\nimport { Textarea } from \"../components/ui/textarea.js\";\nimport { cn } from \"../lib/cn.js\";\nimport { DataGridCellWrapper } from \"./data-grid-cell-wrapper.js\";\nimport { msg } from \"./messages.js\";\nimport { toastError, toastMessage } from \"./toast.js\";\nimport type { DataGridCellProps, FileCellData } from \"./types.js\";\nimport { useBadgeOverflow } from \"./use-badge-overflow.js\";\nimport { useDebouncedCallback } from \"./use-debounced-callback.js\";\nimport {\n formatDateForDisplay,\n formatDateToString,\n formatFileSize,\n generateFileId,\n getCellKey,\n getFileIcon,\n getLineCount,\n getUrlHref,\n parseLocalDate\n} from \"./utils.js\";\n\nexport function ShortTextCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isEditing,\n isFocused,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = cell.getValue() as string;\n const [value, setValue] = React.useState(initialValue);\n const cellRef = React.useRef<HTMLDivElement>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const prevIsEditingRef = React.useRef(false);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(initialValue);\n if (cellRef.current && !isEditing) {\n cellRef.current.textContent = initialValue;\n }\n }\n\n const onBlur = React.useCallback(() => {\n // Read the current value directly from the DOM to avoid stale state\n const currentValue = cellRef.current?.textContent ?? \"\";\n if (!readOnly && currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: currentValue });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, rowIndex, columnId, initialValue, readOnly]);\n\n const onInput = React.useCallback((event: React.FormEvent<HTMLDivElement>) => {\n const currentValue = event.currentTarget.textContent ?? \"\";\n setValue(currentValue);\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing) {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const currentValue = cellRef.current?.textContent ?? \"\";\n if (currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: currentValue\n });\n }\n tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const currentValue = cellRef.current?.textContent ?? \"\";\n if (currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: currentValue\n });\n }\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setValue(initialValue);\n cellRef.current?.blur();\n }\n } else if (isFocused && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n // Handle typing to pre-fill the value when editing starts\n setValue(event.key);\n\n queueMicrotask(() => {\n if (cellRef.current && cellRef.current.contentEditable === \"true\") {\n cellRef.current.textContent = event.key;\n const range = document.createRange();\n const selection = window.getSelection();\n range.selectNodeContents(cellRef.current);\n range.collapse(false);\n selection?.removeAllRanges();\n selection?.addRange(range);\n }\n });\n }\n },\n [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId]\n );\n\n React.useEffect(() => {\n const wasEditing = prevIsEditingRef.current;\n prevIsEditingRef.current = isEditing;\n\n if (isEditing && !wasEditing && cellRef.current) {\n cellRef.current.focus();\n\n if (!cellRef.current.textContent && value) {\n cellRef.current.textContent = value;\n }\n\n if (cellRef.current.textContent) {\n const range = document.createRange();\n const selection = window.getSelection();\n range.selectNodeContents(cellRef.current);\n range.collapse(false);\n selection?.removeAllRanges();\n selection?.addRange(range);\n }\n }\n }, [isEditing, value]);\n\n const displayValue = !isEditing ? (value ?? \"\") : \"\";\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n <div\n role=\"textbox\"\n data-slot=\"grid-cell-content\"\n contentEditable={isEditing}\n tabIndex={-1}\n ref={cellRef}\n onBlur={onBlur}\n onInput={onInput}\n suppressContentEditableWarning\n className={cn(\"size-full overflow-hidden outline-none\", {\n \"whitespace-nowrap [&_*]:inline [&_*]:whitespace-nowrap [&_br]:hidden\": isEditing\n })}\n >\n {displayValue}\n </div>\n </DataGridCellWrapper>\n );\n}\n\nexport function LongTextCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = cell.getValue() as string;\n const [value, setValue] = React.useState(initialValue ?? \"\");\n const textareaRef = React.useRef<HTMLTextAreaElement>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const pendingCharRef = React.useRef<string | null>(null);\n const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(initialValue ?? \"\");\n }\n\n const debouncedSave = useDebouncedCallback((newValue: string) => {\n if (!readOnly) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValue });\n }\n }, 300);\n\n const onSave = React.useCallback(() => {\n // Immediately save any pending changes and close the popover\n if (!readOnly && value !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, value, initialValue, rowIndex, columnId, readOnly]);\n\n const onCancel = React.useCallback(() => {\n // Restore the original value\n setValue(initialValue ?? \"\");\n if (!readOnly) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: initialValue });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, initialValue, rowIndex, columnId, readOnly]);\n\n const onOpenChange = React.useCallback(\n (open: boolean) => {\n if (open && !readOnly) {\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n // Immediately save any pending changes when closing\n if (!readOnly && value !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n }\n tableMeta?.onCellEditingStop?.();\n }\n },\n [tableMeta, value, initialValue, rowIndex, columnId, readOnly]\n );\n\n const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n React.useCallback((event) => {\n event.preventDefault();\n if (textareaRef.current) {\n textareaRef.current.focus();\n const length = textareaRef.current.value.length;\n textareaRef.current.setSelectionRange(length, length);\n\n // Insert pending character using execCommand so it's part of undo history\n // Use requestAnimationFrame to ensure focus has fully settled\n if (pendingCharRef.current) {\n const char = pendingCharRef.current;\n pendingCharRef.current = null;\n requestAnimationFrame(() => {\n if (textareaRef.current && document.activeElement === textareaRef.current) {\n document.execCommand(\"insertText\", false, char);\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n });\n } else {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n }\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isFocused && !isEditing && !readOnly && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n // Store the character to be inserted after textarea focuses\n // This ensures it's part of the textarea's undo history\n pendingCharRef.current = event.key;\n }\n },\n [isFocused, isEditing, readOnly]\n );\n\n const onBlur = React.useCallback(() => {\n // Immediately save any pending changes on blur\n if (!readOnly && value !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, value, initialValue, rowIndex, columnId, readOnly]);\n\n const onChange = React.useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = event.target.value;\n setValue(newValue);\n debouncedSave(newValue);\n },\n [debouncedSave]\n );\n\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onCancel();\n } else if (event.key === \"Enter\" && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n onSave();\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n // Save any pending changes\n if (value !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n }\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n return;\n }\n // Stop propagation to prevent grid navigation\n event.stopPropagation();\n },\n [onSave, onCancel, value, initialValue, tableMeta, rowIndex, columnId]\n );\n\n return (\n <Popover open={isEditing} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n <span data-slot=\"grid-cell-content\">{value}</span>\n </DataGridCellWrapper>\n </PopoverAnchor>\n <PopoverContent\n data-grid-cell-editor=\"\"\n align=\"start\"\n side=\"bottom\"\n sideOffset={sideOffset}\n className=\"w-[400px] rounded-none p-0\"\n onOpenAutoFocus={onOpenAutoFocus}\n >\n <Textarea\n placeholder={msg.cell.longTextPlaceholder}\n aria-label={msg.cell.longTextPlaceholder}\n className=\"max-h-[300px] min-h-[150px] resize-none overflow-y-auto rounded-none border-0 shadow-none focus-visible:ring-1 focus-visible:ring-ring/30\"\n ref={textareaRef}\n value={value}\n onBlur={onBlur}\n onChange={onChange}\n onKeyDown={onKeyDown}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\nexport function NumberCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = cell.getValue() as number;\n const [value, setValue] = React.useState(String(initialValue ?? \"\"));\n const inputRef = React.useRef<HTMLInputElement>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const cellOpts = cell.column.columnDef.meta?.cell;\n const numberCellOpts = cellOpts?.variant === \"number\" ? cellOpts : null;\n const min = numberCellOpts?.min;\n const max = numberCellOpts?.max;\n const step = numberCellOpts?.step;\n\n const prevIsEditingRef = React.useRef(false);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(String(initialValue ?? \"\"));\n }\n\n const onBlur = React.useCallback(() => {\n const numValue = value === \"\" ? null : Number(value);\n if (!readOnly && numValue !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: numValue });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, rowIndex, columnId, initialValue, value, readOnly]);\n\n const onChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setValue(event.target.value);\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing) {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const numValue = value === \"\" ? null : Number(value);\n if (numValue !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: numValue });\n }\n tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const numValue = value === \"\" ? null : Number(value);\n if (numValue !== initialValue) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: numValue });\n }\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setValue(String(initialValue ?? \"\"));\n inputRef.current?.blur();\n }\n } else if (isFocused) {\n // Handle Backspace to start editing with empty value\n if (event.key === \"Backspace\") {\n setValue(\"\");\n } else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n // Handle typing to pre-fill the value when editing starts\n setValue(event.key);\n }\n }\n },\n [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, value]\n );\n\n React.useEffect(() => {\n const wasEditing = prevIsEditingRef.current;\n prevIsEditingRef.current = isEditing;\n\n // Only focus when we start editing (transition from false to true)\n if (isEditing && !wasEditing && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isEditing]);\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n {isEditing ? (\n <input\n type=\"number\"\n ref={inputRef}\n value={value}\n min={min}\n max={max}\n step={step}\n className=\"w-full border-none bg-transparent p-0 outline-none focus-visible:outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n onBlur={onBlur}\n onChange={onChange}\n />\n ) : (\n <span data-slot=\"grid-cell-content\">{value}</span>\n )}\n </DataGridCellWrapper>\n );\n}\n\nexport function UrlCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isEditing,\n isFocused,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = cell.getValue() as string;\n const [value, setValue] = React.useState(initialValue ?? \"\");\n const cellRef = React.useRef<HTMLDivElement>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const prevIsEditingRef = React.useRef(false);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(initialValue ?? \"\");\n if (cellRef.current && !isEditing) {\n cellRef.current.textContent = initialValue ?? \"\";\n }\n }\n\n const onBlur = React.useCallback(() => {\n const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n\n if (!readOnly && currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: currentValue || null\n });\n }\n tableMeta?.onCellEditingStop?.();\n }, [tableMeta, rowIndex, columnId, initialValue, readOnly]);\n\n const onInput = React.useCallback((event: React.FormEvent<HTMLDivElement>) => {\n const currentValue = event.currentTarget.textContent ?? \"\";\n setValue(currentValue);\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing) {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n if (!readOnly && currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: currentValue || null\n });\n }\n tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n if (!readOnly && currentValue !== initialValue) {\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: currentValue || null\n });\n }\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setValue(initialValue ?? \"\");\n cellRef.current?.blur();\n }\n } else if (isFocused && !readOnly && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n // Handle typing to pre-fill the value when editing starts\n setValue(event.key);\n\n queueMicrotask(() => {\n if (cellRef.current && cellRef.current.contentEditable === \"true\") {\n cellRef.current.textContent = event.key;\n const range = document.createRange();\n const selection = window.getSelection();\n range.selectNodeContents(cellRef.current);\n range.collapse(false);\n selection?.removeAllRanges();\n selection?.addRange(range);\n }\n });\n }\n },\n [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onLinkClick = React.useCallback(\n (event: React.MouseEvent<HTMLAnchorElement>) => {\n if (isEditing) {\n event.preventDefault();\n return;\n }\n\n // Check if URL was rejected due to dangerous protocol\n const href = getUrlHref(value);\n if (!href) {\n event.preventDefault();\n toastError(msg.cell.invalidUrlTitle, msg.cell.invalidUrlDescription);\n return;\n }\n\n // Stop propagation to prevent grid from interfering with link navigation\n event.stopPropagation();\n },\n [isEditing, value]\n );\n\n React.useEffect(() => {\n const wasEditing = prevIsEditingRef.current;\n prevIsEditingRef.current = isEditing;\n\n if (isEditing && !wasEditing && cellRef.current) {\n cellRef.current.focus();\n\n if (!cellRef.current.textContent && value) {\n cellRef.current.textContent = value;\n }\n\n if (cellRef.current.textContent) {\n const range = document.createRange();\n const selection = window.getSelection();\n range.selectNodeContents(cellRef.current);\n range.collapse(false);\n selection?.removeAllRanges();\n selection?.addRange(range);\n }\n }\n }, [isEditing, value]);\n\n const displayValue = !isEditing ? (value ?? \"\") : \"\";\n const urlHref = displayValue ? getUrlHref(displayValue) : \"\";\n const isDangerousUrl = displayValue && !urlHref;\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n {!isEditing && displayValue ? (\n <div data-slot=\"grid-cell-content\" className=\"size-full overflow-hidden\">\n <a\n data-focused={isFocused && !isDangerousUrl ? \"\" : undefined}\n data-invalid={isDangerousUrl ? \"\" : undefined}\n href={urlHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"truncate text-link-ink underline decoration-link-ink underline-offset-2 hover:text-link-ink-hover hover:decoration-link-ink-hover data-[invalid]:cursor-not-allowed data-[focused]:text-foreground data-[invalid]:text-destructive-ink data-[focused]:decoration-foreground/50 data-[invalid]:decoration-destructive-ink data-[focused]:hover:decoration-foreground/70 data-[invalid]:hover:decoration-destructive-ink\"\n onClick={onLinkClick}\n >\n {displayValue}\n </a>\n </div>\n ) : (\n <div\n role=\"textbox\"\n data-slot=\"grid-cell-content\"\n contentEditable={isEditing}\n tabIndex={-1}\n ref={cellRef}\n onBlur={onBlur}\n onInput={onInput}\n suppressContentEditableWarning\n className={cn(\"size-full overflow-hidden outline-none focus-visible:outline-none\", {\n \"whitespace-nowrap [&_*]:inline [&_*]:whitespace-nowrap [&_br]:hidden\": isEditing\n })}\n >\n {displayValue}\n </div>\n )}\n </DataGridCellWrapper>\n );\n}\n\nexport function CheckboxCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: Omit<DataGridCellProps<TData>, \"isEditing\">) {\n const initialValue = cell.getValue() as boolean;\n const [value, setValue] = React.useState(Boolean(initialValue));\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(Boolean(initialValue));\n }\n\n const onCheckedChange = React.useCallback(\n (checked: boolean) => {\n if (readOnly) return;\n setValue(checked);\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: checked });\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isFocused && !readOnly && (event.key === \" \" || event.key === \"Enter\")) {\n event.preventDefault();\n event.stopPropagation();\n onCheckedChange(!value);\n } else if (isFocused && event.key === \"Tab\") {\n event.preventDefault();\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n },\n [isFocused, value, onCheckedChange, tableMeta, readOnly]\n );\n\n const onWrapperClick = React.useCallback(\n (event: React.MouseEvent) => {\n if (isFocused && !readOnly) {\n event.preventDefault();\n event.stopPropagation();\n onCheckedChange(!value);\n }\n },\n [isFocused, value, onCheckedChange, readOnly]\n );\n\n const onCheckboxClick = React.useCallback((event: React.MouseEvent) => {\n event.stopPropagation();\n }, []);\n\n const onCheckboxMouseDown = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n }, []);\n\n const onCheckboxDoubleClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n }, []);\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={false}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n className=\"flex size-full justify-center\"\n onClick={onWrapperClick}\n onKeyDown={onWrapperKeyDown}\n >\n <Checkbox\n checked={value}\n onCheckedChange={onCheckedChange}\n disabled={readOnly}\n onClick={onCheckboxClick}\n onMouseDown={onCheckboxMouseDown}\n onDoubleClick={onCheckboxDoubleClick}\n />\n </DataGridCellWrapper>\n );\n}\n\nexport function SelectCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = (cell.getValue() ?? undefined) as string | undefined;\n\n const [value, setValue] = React.useState(initialValue);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const cellOpts = cell.column.columnDef.meta?.cell;\n const options = React.useMemo(() => (cellOpts?.variant === \"select\" ? cellOpts.options : []), [cellOpts]);\n const optionByValue = React.useMemo(() => new Map(options.map((option) => [option.value, option])), [options]);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(initialValue);\n }\n\n const onValueChange = React.useCallback(\n (newValue: string) => {\n if (readOnly) return;\n setValue(newValue);\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValue });\n tableMeta?.onCellEditingStop?.();\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onOpenChange = React.useCallback(\n (open: boolean) => {\n if (open && !readOnly) {\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n tableMeta?.onCellEditingStop?.();\n }\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing && event.key === \"Escape\") {\n event.preventDefault();\n setValue(initialValue);\n tableMeta?.onCellEditingStop?.();\n } else if (isFocused && event.key === \"Tab\") {\n event.preventDefault();\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n },\n [isEditing, isFocused, initialValue, tableMeta]\n );\n\n const displayLabel = value ? (optionByValue.get(value)?.label ?? value) : null;\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n {isEditing ? (\n <Select value={value} onValueChange={onValueChange} open={isEditing} onOpenChange={onOpenChange}>\n <SelectTrigger\n aria-label={cell.column.columnDef.meta?.label ?? columnId}\n className=\"size-full items-start border-none bg-transparent p-0 shadow-none focus:ring-0 focus-visible:ring-0 [&>span]:line-clamp-none [&_svg]:hidden\"\n >\n {displayLabel ? (\n // span (không dùng <Badge> vì Badge render <div>, đặt trong <button> là HTML sai)\n <span className={cn(badgeVariants({ variant: \"secondary\" }), \"whitespace-pre-wrap px-1.5 py-px\")}>\n <SelectValue />\n </span>\n ) : (\n <SelectValue />\n )}\n </SelectTrigger>\n <SelectContent\n data-grid-cell-editor=\"\"\n // compensate for the wrapper padding\n align=\"start\"\n alignOffset={-8}\n sideOffset={-8}\n className=\"min-w-[calc(var(--radix-select-trigger-width)+16px)]\"\n >\n <SelectGroup>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n ) : displayLabel ? (\n <Badge data-slot=\"grid-cell-content\" variant=\"secondary\" className=\"whitespace-pre-wrap px-1.5 py-px\">\n {displayLabel}\n </Badge>\n ) : null}\n </DataGridCellWrapper>\n );\n}\n\nexport function MultiSelectCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const cellValue = React.useMemo(() => {\n const value = cell.getValue() as string[];\n return value ?? [];\n }, [cell]);\n\n const cellKey = getCellKey(rowIndex, columnId);\n const prevCellKeyRef = React.useRef(cellKey);\n\n const [selectedValues, setSelectedValues] = React.useState<string[]>(cellValue);\n const [searchValue, setSearchValue] = React.useState(\"\");\n const containerRef = React.useRef<HTMLDivElement>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const cellOpts = cell.column.columnDef.meta?.cell;\n const options = React.useMemo(() => (cellOpts?.variant === \"multi-select\" ? cellOpts.options : []), [cellOpts]);\n const optionByValue = React.useMemo(() => new Map(options.map((option) => [option.value, option])), [options]);\n const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n const prevCellValueRef = React.useRef(cellValue);\n if (cellValue !== prevCellValueRef.current) {\n prevCellValueRef.current = cellValue;\n setSelectedValues(cellValue);\n }\n\n if (prevCellKeyRef.current !== cellKey) {\n prevCellKeyRef.current = cellKey;\n setSearchValue(\"\");\n }\n\n const onValueChange = React.useCallback(\n (value: string) => {\n if (readOnly) return;\n let newValues: string[] = [];\n setSelectedValues((curr) => {\n newValues = curr.includes(value) ? curr.filter((v) => v !== value) : [...curr, value];\n return newValues;\n });\n queueMicrotask(() => {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValues });\n inputRef.current?.focus();\n });\n setSearchValue(\"\");\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const removeValue = React.useCallback(\n (valueToRemove: string, event?: React.MouseEvent) => {\n if (readOnly) return;\n event?.stopPropagation();\n event?.preventDefault();\n let newValues: string[] = [];\n setSelectedValues((curr) => {\n newValues = curr.filter((v) => v !== valueToRemove);\n return newValues;\n });\n queueMicrotask(() => {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValues });\n inputRef.current?.focus();\n });\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const clearAll = React.useCallback(() => {\n if (readOnly) return;\n setSelectedValues([]);\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: [] });\n queueMicrotask(() => inputRef.current?.focus());\n }, [tableMeta, rowIndex, columnId, readOnly]);\n\n const onOpenChange = React.useCallback(\n (open: boolean) => {\n if (open && !readOnly) {\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n setSearchValue(\"\");\n tableMeta?.onCellEditingStop?.();\n }\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n React.useCallback((event) => {\n event.preventDefault();\n inputRef.current?.focus();\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing && event.key === \"Escape\") {\n event.preventDefault();\n setSelectedValues(cellValue);\n setSearchValue(\"\");\n tableMeta?.onCellEditingStop?.();\n } else if (isFocused && event.key === \"Tab\") {\n event.preventDefault();\n setSearchValue(\"\");\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n },\n [isEditing, isFocused, cellValue, tableMeta]\n );\n\n const onInputKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Backspace\" && searchValue === \"\") {\n event.preventDefault();\n let newValues: string[] | null = null;\n setSelectedValues((curr) => {\n if (curr.length === 0) return curr;\n newValues = curr.slice(0, -1);\n return newValues;\n });\n queueMicrotask(() => {\n if (newValues !== null) {\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValues });\n }\n inputRef.current?.focus();\n });\n }\n if (event.key === \"Escape\") {\n event.stopPropagation();\n }\n },\n [searchValue, tableMeta, rowIndex, columnId]\n );\n\n const displayLabels = selectedValues.map((val) => optionByValue.get(val)?.label ?? val).filter(Boolean);\n\n const selectedValuesSet = React.useMemo(() => new Set(selectedValues), [selectedValues]);\n\n const lineCount = getLineCount(rowHeight);\n\n const { visibleItems: visibleLabels, hiddenCount: hiddenBadgeCount } = useBadgeOverflow({\n items: displayLabels,\n getLabel: (label) => label,\n containerRef,\n lineCount\n });\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n {isEditing ? (\n <Popover open={isEditing} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <div className=\"absolute inset-0\" />\n </PopoverAnchor>\n <PopoverContent\n data-grid-cell-editor=\"\"\n align=\"start\"\n sideOffset={sideOffset}\n className=\"w-[300px] rounded-none p-0\"\n onOpenAutoFocus={onOpenAutoFocus}\n >\n <Command className=\"[&_[data-slot=command-input-wrapper]]:h-auto [&_[data-slot=command-input-wrapper]]:gap-0 [&_[data-slot=command-input-wrapper]]:border-none [&_[data-slot=command-input-wrapper]]:p-0 [&_[data-slot=command-input-wrapper]_svg]:hidden\">\n <div className=\"flex min-h-9 flex-wrap items-center gap-1 border-b px-3 py-1.5\">\n {selectedValues.map((value) => {\n const label = optionByValue.get(value)?.label ?? value;\n\n return (\n <Badge key={value} variant=\"secondary\" className=\"gap-1 px-1.5 py-px\">\n {label}\n <button\n type=\"button\"\n aria-label={`${msg.cell.clearAll}: ${label}`}\n onClick={(event) => removeValue(value, event)}\n onPointerDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n >\n <X aria-hidden=\"true\" className=\"size-3\" />\n </button>\n </Badge>\n );\n })}\n <CommandInput\n ref={inputRef}\n value={searchValue}\n onValueChange={setSearchValue}\n onKeyDown={onInputKeyDown}\n placeholder={msg.cell.optionSearchPlaceholder}\n aria-label={msg.cell.optionSearchPlaceholder}\n className=\"h-auto flex-1 p-0\"\n />\n </div>\n <CommandList className=\"max-h-full\">\n <CommandEmpty>{msg.cell.optionEmpty}</CommandEmpty>\n <CommandGroup className=\"max-h-[300px] scroll-py-1 overflow-y-auto overflow-x-hidden\">\n {options.map((option) => {\n const isSelected = selectedValuesSet.has(option.value);\n\n return (\n <CommandItem key={option.value} value={option.label} onSelect={() => onValueChange(option.value)}>\n <div\n className={cn(\n \"flex size-4 items-center justify-center rounded-sm border border-choice-edge\",\n isSelected ? \"border-control-on bg-control-on text-control-check\" : \"[&_svg]:invisible\"\n )}\n >\n <Check className=\"size-3\" />\n </div>\n <span>{option.label}</span>\n </CommandItem>\n );\n })}\n </CommandGroup>\n {selectedValues.length > 0 && (\n <>\n <CommandSeparator />\n <CommandGroup>\n <CommandItem onSelect={clearAll} className=\"justify-center text-muted-foreground\">\n {msg.cell.clearAll}\n </CommandItem>\n </CommandGroup>\n </>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n ) : null}\n {displayLabels.length > 0 ? (\n <div className=\"flex flex-wrap items-center gap-1 overflow-hidden\">\n {visibleLabels.map((label, index) => (\n <Badge key={selectedValues[index]} variant=\"secondary\" className=\"px-1.5 py-px\">\n {label}\n </Badge>\n ))}\n {hiddenBadgeCount > 0 && (\n <Badge variant=\"outline\" className=\"px-1.5 py-px text-muted-foreground\">\n +{hiddenBadgeCount}\n </Badge>\n )}\n </div>\n ) : null}\n </DataGridCellWrapper>\n );\n}\n\nexport function DateCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const initialValue = cell.getValue() as string;\n const [value, setValue] = React.useState(initialValue ?? \"\");\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const prevInitialValueRef = React.useRef(initialValue);\n if (initialValue !== prevInitialValueRef.current) {\n prevInitialValueRef.current = initialValue;\n setValue(initialValue ?? \"\");\n }\n\n // Parse date as local time to avoid timezone shifts\n const selectedDate = value ? (parseLocalDate(value) ?? undefined) : undefined;\n\n const onDateSelect = React.useCallback(\n (date: Date | undefined) => {\n if (!date || readOnly) return;\n\n // Format using local date components to avoid timezone issues\n const formattedDate = formatDateToString(date);\n setValue(formattedDate);\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: formattedDate });\n tableMeta?.onCellEditingStop?.();\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onOpenChange = React.useCallback(\n (open: boolean) => {\n if (open && !readOnly) {\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n tableMeta?.onCellEditingStop?.();\n }\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing && event.key === \"Escape\") {\n event.preventDefault();\n setValue(initialValue);\n tableMeta?.onCellEditingStop?.();\n } else if (isFocused && event.key === \"Tab\") {\n event.preventDefault();\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n },\n [isEditing, isFocused, initialValue, tableMeta]\n );\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n onKeyDown={onWrapperKeyDown}\n >\n <Popover open={isEditing} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <span data-slot=\"grid-cell-content\">{formatDateForDisplay(value)}</span>\n </PopoverAnchor>\n {isEditing && (\n <PopoverContent data-grid-cell-editor=\"\" align=\"start\" alignOffset={-8} className=\"w-auto p-0\">\n <Calendar\n mode=\"single\"\n locale={vi}\n autoFocus\n defaultMonth={selectedDate ?? new Date()}\n selected={selectedDate}\n onSelect={(date) => {\n if (date) onDateSelect(date);\n }}\n />\n </PopoverContent>\n )}\n </Popover>\n </DataGridCellWrapper>\n );\n}\n\nexport function FileCell<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n rowHeight,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly\n}: DataGridCellProps<TData>) {\n const cellValue = React.useMemo(() => (cell.getValue() as FileCellData[]) ?? [], [cell]);\n\n const cellKey = getCellKey(rowIndex, columnId);\n const prevCellKeyRef = React.useRef(cellKey);\n\n const labelId = React.useId();\n const descriptionId = React.useId();\n\n const [files, setFiles] = React.useState<FileCellData[]>(cellValue);\n const [uploadingFiles, setUploadingFiles] = React.useState<Set<string>>(new Set());\n const [deletingFiles, setDeletingFiles] = React.useState<Set<string>>(new Set());\n const [isDraggingOver, setIsDraggingOver] = React.useState(false);\n const [isDragging, setIsDragging] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const isUploading = uploadingFiles.size > 0;\n const isDeleting = deletingFiles.size > 0;\n const isPending = isUploading || isDeleting;\n const containerRef = React.useRef<HTMLDivElement>(null);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n const dropzoneRef = React.useRef<HTMLDivElement>(null);\n const cellOpts = cell.column.columnDef.meta?.cell;\n const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n const fileCellOpts = cellOpts?.variant === \"file\" ? cellOpts : null;\n const maxFileSize = fileCellOpts?.maxFileSize ?? 10 * 1024 * 1024;\n const maxFiles = fileCellOpts?.maxFiles ?? 10;\n const accept = fileCellOpts?.accept;\n const multiple = fileCellOpts?.multiple ?? false;\n\n const acceptedTypes = React.useMemo(() => (accept ? accept.split(\",\").map((t) => t.trim()) : null), [accept]);\n\n const prevCellValueRef = React.useRef(cellValue);\n if (cellValue !== prevCellValueRef.current) {\n prevCellValueRef.current = cellValue;\n for (const file of files) {\n if (file.url) {\n URL.revokeObjectURL(file.url);\n }\n }\n setFiles(cellValue);\n setError(null);\n }\n\n if (prevCellKeyRef.current !== cellKey) {\n prevCellKeyRef.current = cellKey;\n setError(null);\n }\n\n const validateFile = React.useCallback(\n (file: File): string | null => {\n if (maxFileSize && file.size > maxFileSize) {\n return msg.file.tooLarge(formatFileSize(maxFileSize));\n }\n if (acceptedTypes) {\n const fileExtension = `.${file.name.split(\".\").pop()}`;\n const isAccepted = acceptedTypes.some((type) => {\n if (type.endsWith(\"/*\")) {\n const baseType = type.slice(0, -2);\n return file.type.startsWith(`${baseType}/`);\n }\n if (type.startsWith(\".\")) {\n return fileExtension.toLowerCase() === type.toLowerCase();\n }\n return file.type === type;\n });\n if (!isAccepted) {\n return msg.file.wrongType;\n }\n }\n return null;\n },\n [maxFileSize, acceptedTypes]\n );\n\n const addFiles = React.useCallback(\n async (newFiles: File[], skipUpload = false) => {\n if (readOnly || isPending) return;\n setError(null);\n\n if (maxFiles && files.length + newFiles.length > maxFiles) {\n const errorMessage = msg.file.tooMany(maxFiles);\n setError(errorMessage);\n toastMessage(errorMessage);\n setTimeout(() => {\n setError(null);\n }, 2000);\n return;\n }\n\n const rejectedFiles: Array<{ name: string; reason: string }> = [];\n const filesToValidate: File[] = [];\n\n for (const file of newFiles) {\n const validationError = validateFile(file);\n if (validationError) {\n rejectedFiles.push({ name: file.name, reason: validationError });\n continue;\n }\n filesToValidate.push(file);\n }\n\n if (rejectedFiles.length > 0) {\n const firstError = rejectedFiles[0];\n if (firstError) {\n setError(firstError.reason);\n\n const truncatedName = firstError.name.length > 20 ? `${firstError.name.slice(0, 20)}...` : firstError.name;\n\n if (rejectedFiles.length === 1) {\n toastMessage(firstError.reason, msg.file.rejectedOne(truncatedName));\n } else {\n toastMessage(firstError.reason, msg.file.rejectedMany(truncatedName, rejectedFiles.length - 1));\n }\n\n setTimeout(() => {\n setError(null);\n }, 2000);\n }\n }\n\n if (filesToValidate.length > 0) {\n if (!skipUpload) {\n const tempFiles = filesToValidate.map((f) => ({\n id: generateFileId(),\n name: f.name,\n size: f.size,\n type: f.type,\n url: undefined\n }));\n const filesWithTemp = [...files, ...tempFiles];\n setFiles(filesWithTemp);\n\n const uploadingIds = new Set(tempFiles.map((f) => f.id));\n setUploadingFiles(uploadingIds);\n\n let uploadedFiles: FileCellData[] = [];\n\n if (tableMeta?.onFilesUpload) {\n try {\n uploadedFiles = await tableMeta.onFilesUpload({\n files: filesToValidate,\n rowIndex,\n columnId\n });\n } catch (error) {\n toastError(error instanceof Error ? error.message : msg.file.uploadFailed(filesToValidate.length));\n setFiles((prev) => prev.filter((f) => !uploadingIds.has(f.id)));\n setUploadingFiles(new Set());\n return;\n }\n } else {\n uploadedFiles = filesToValidate.map((f, i) => ({\n id: tempFiles[i]?.id ?? generateFileId(),\n name: f.name,\n size: f.size,\n type: f.type,\n url: URL.createObjectURL(f)\n }));\n }\n\n const finalFiles = filesWithTemp\n .map((f) => {\n if (uploadingIds.has(f.id)) {\n return uploadedFiles.find((uf) => uf.name === f.name) ?? f;\n }\n return f;\n })\n .filter((f) => f.url !== undefined);\n\n setFiles(finalFiles);\n setUploadingFiles(new Set());\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: finalFiles });\n } else {\n const newFilesData: FileCellData[] = filesToValidate.map((f) => ({\n id: generateFileId(),\n name: f.name,\n size: f.size,\n type: f.type,\n url: URL.createObjectURL(f)\n }));\n const updatedFiles = [...files, ...newFilesData];\n setFiles(updatedFiles);\n tableMeta?.onDataUpdate?.({\n rowIndex,\n columnId,\n value: updatedFiles\n });\n }\n }\n },\n [files, maxFiles, validateFile, tableMeta, rowIndex, columnId, readOnly, isPending]\n );\n\n const removeFile = React.useCallback(\n async (fileId: string) => {\n if (readOnly || isPending) return;\n setError(null);\n\n const fileToRemove = files.find((f) => f.id === fileId);\n if (!fileToRemove) return;\n\n setDeletingFiles((prev) => new Set(prev).add(fileId));\n\n if (tableMeta?.onFilesDelete) {\n try {\n await tableMeta.onFilesDelete({\n fileIds: [fileId],\n rowIndex,\n columnId\n });\n } catch (error) {\n toastError(error instanceof Error ? error.message : msg.file.deleteFailed(fileToRemove.name));\n setDeletingFiles((prev) => {\n const next = new Set(prev);\n next.delete(fileId);\n return next;\n });\n return;\n }\n }\n\n if (fileToRemove.url?.startsWith(\"blob:\")) {\n URL.revokeObjectURL(fileToRemove.url);\n }\n\n const updatedFiles = files.filter((f) => f.id !== fileId);\n setFiles(updatedFiles);\n setDeletingFiles((prev) => {\n const next = new Set(prev);\n next.delete(fileId);\n return next;\n });\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: updatedFiles });\n },\n [files, tableMeta, rowIndex, columnId, readOnly, isPending]\n );\n\n const clearAll = React.useCallback(async () => {\n if (readOnly || isPending) return;\n setError(null);\n\n const fileIds = files.map((f) => f.id);\n setDeletingFiles(new Set(fileIds));\n\n if (tableMeta?.onFilesDelete && files.length > 0) {\n try {\n await tableMeta.onFilesDelete({\n fileIds,\n rowIndex,\n columnId\n });\n } catch (error) {\n toastError(error instanceof Error ? error.message : msg.file.deleteFailedMany);\n setDeletingFiles(new Set());\n return;\n }\n }\n\n for (const file of files) {\n if (file.url?.startsWith(\"blob:\")) {\n URL.revokeObjectURL(file.url);\n }\n }\n setFiles([]);\n setDeletingFiles(new Set());\n tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: [] });\n }, [files, tableMeta, rowIndex, columnId, readOnly, isPending]);\n\n const onCellDragEnter = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer.types.includes(\"Files\")) {\n setIsDraggingOver(true);\n }\n }, []);\n\n const onCellDragLeave = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const rect = event.currentTarget.getBoundingClientRect();\n const x = event.clientX;\n const y = event.clientY;\n\n if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {\n setIsDraggingOver(false);\n }\n }, []);\n\n const onCellDragOver = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n const onCellDrop = React.useCallback(\n (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setIsDraggingOver(false);\n\n const droppedFiles = Array.from(event.dataTransfer.files);\n if (droppedFiles.length > 0) {\n addFiles(droppedFiles, false);\n }\n },\n [addFiles]\n );\n\n const onDropzoneDragEnter = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setIsDragging(true);\n }, []);\n\n const onDropzoneDragLeave = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const rect = event.currentTarget.getBoundingClientRect();\n const x = event.clientX;\n const y = event.clientY;\n\n if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {\n setIsDragging(false);\n }\n }, []);\n\n const onDropzoneDragOver = React.useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n const onDropzoneDrop = React.useCallback(\n (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setIsDragging(false);\n\n const droppedFiles = Array.from(event.dataTransfer.files);\n addFiles(droppedFiles, false);\n },\n [addFiles]\n );\n\n const onDropzoneClick = React.useCallback(() => {\n fileInputRef.current?.click();\n }, []);\n\n const onDropzoneKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onDropzoneClick();\n }\n },\n [onDropzoneClick]\n );\n\n const onFileInputChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const selectedFiles = Array.from(event.target.files ?? []);\n addFiles(selectedFiles, false);\n event.target.value = \"\";\n },\n [addFiles]\n );\n\n const onOpenChange = React.useCallback(\n (open: boolean) => {\n if (open && !readOnly) {\n setError(null);\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n setError(null);\n tableMeta?.onCellEditingStop?.();\n }\n },\n [tableMeta, rowIndex, columnId, readOnly]\n );\n\n const onEscapeKeyDown: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onEscapeKeyDown\"]> =\n React.useCallback((event) => {\n // Prevent the escape key from propagating to the data grid's keyboard handler\n // which would call blurCell() and remove focus from the cell\n event.stopPropagation();\n }, []);\n\n const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n React.useCallback((event) => {\n event.preventDefault();\n queueMicrotask(() => {\n dropzoneRef.current?.focus();\n });\n }, []);\n\n const onWrapperKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isEditing) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setFiles(cellValue);\n setError(null);\n tableMeta?.onCellEditingStop?.();\n } else if (event.key === \" \") {\n event.preventDefault();\n onDropzoneClick();\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n } else if (isFocused && event.key === \"Enter\") {\n event.preventDefault();\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else if (isFocused && event.key === \"Tab\") {\n event.preventDefault();\n tableMeta?.onCellEditingStop?.({\n direction: event.shiftKey ? \"left\" : \"right\"\n });\n }\n },\n [isEditing, isFocused, cellValue, tableMeta, onDropzoneClick, rowIndex, columnId]\n );\n\n React.useEffect(() => {\n return () => {\n for (const file of files) {\n if (file.url) {\n URL.revokeObjectURL(file.url);\n }\n }\n };\n }, [files]);\n\n const lineCount = getLineCount(rowHeight);\n\n const { visibleItems: visibleFiles, hiddenCount: hiddenFileCount } = useBadgeOverflow({\n items: files,\n getLabel: (file) => file.name,\n containerRef,\n lineCount,\n cacheKeyPrefix: \"file\",\n iconSize: 12,\n maxWidth: 100\n });\n\n return (\n <DataGridCellWrapper<TData>\n ref={containerRef}\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n className={cn({\n \"ring-1 ring-primary/80 ring-inset\": isDraggingOver\n })}\n onDragEnter={onCellDragEnter}\n onDragLeave={onCellDragLeave}\n onDragOver={onCellDragOver}\n onDrop={onCellDrop}\n onKeyDown={onWrapperKeyDown}\n >\n {isEditing ? (\n <Popover open={isEditing} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <div className=\"absolute inset-0\" />\n </PopoverAnchor>\n <PopoverContent\n data-grid-cell-editor=\"\"\n align=\"start\"\n sideOffset={sideOffset}\n className=\"w-[400px] rounded-none p-0\"\n onEscapeKeyDown={onEscapeKeyDown}\n onOpenAutoFocus={onOpenAutoFocus}\n >\n <div className=\"flex flex-col gap-2 p-3\">\n <span id={labelId} className=\"sr-only\">\n {msg.file.uploadLabel}\n </span>\n <div\n role=\"region\"\n aria-labelledby={labelId}\n aria-describedby={descriptionId}\n aria-invalid={!!error}\n aria-disabled={isPending}\n data-dragging={isDragging ? \"\" : undefined}\n data-invalid={error ? \"\" : undefined}\n data-disabled={isPending ? \"\" : undefined}\n tabIndex={isDragging || isPending ? -1 : 0}\n className=\"flex cursor-pointer flex-col items-center justify-center gap-2 rounded-md border-2 border-dashed p-6 outline-none transition-colors hover:bg-accent/30 focus-visible:border-primary-ink focus-visible:outline-none data-[disabled]:pointer-events-none data-[dragging]:border-primary-ink data-[invalid]:border-destructive-ink data-[dragging]:bg-accent/30 data-[disabled]:opacity-50\"\n ref={dropzoneRef}\n onClick={onDropzoneClick}\n onDragEnter={onDropzoneDragEnter}\n onDragLeave={onDropzoneDragLeave}\n onDragOver={onDropzoneDragOver}\n onDrop={onDropzoneDrop}\n onKeyDown={onDropzoneKeyDown}\n >\n <Upload aria-hidden=\"true\" className=\"size-8 text-muted-foreground\" />\n <div className=\"text-center text-sm\">\n <p className=\"font-medium\">{isDragging ? msg.file.dropHere : msg.file.dragHere}</p>\n <p className=\"text-muted-foreground text-xs\">{msg.file.browse}</p>\n </div>\n <p id={descriptionId} className=\"text-muted-foreground text-xs\">\n {msg.file.limits(maxFileSize ? formatFileSize(maxFileSize) : undefined, maxFiles)}\n </p>\n </div>\n <input\n type=\"file\"\n aria-labelledby={labelId}\n aria-describedby={descriptionId}\n multiple={multiple}\n accept={accept}\n className=\"sr-only\"\n ref={fileInputRef}\n onChange={onFileInputChange}\n />\n {files.length > 0 && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-muted-foreground text-xs\">{msg.file.count(files.length)}</p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-6 px-2 text-muted-foreground text-xs\"\n onClick={clearAll}\n disabled={isPending}\n >\n {msg.file.clearAll}\n </Button>\n </div>\n <div className=\"max-h-[200px] space-y-1 overflow-y-auto\">\n {files.map((file) => {\n const FileIcon = getFileIcon(file.type);\n const isFileUploading = uploadingFiles.has(file.id);\n const isFileDeleting = deletingFiles.has(file.id);\n const isFilePending = isFileUploading || isFileDeleting;\n\n return (\n <div\n key={file.id}\n data-pending={isFilePending ? \"\" : undefined}\n className=\"flex items-center gap-2 rounded-md border bg-muted/50 px-2 py-1.5 data-[pending]:opacity-60\"\n >\n {FileIcon && <FileIcon className=\"size-4 shrink-0 text-muted-foreground\" />}\n <div className=\"flex-1 overflow-hidden\">\n <p className=\"truncate text-sm\">{file.name}</p>\n <p className=\"text-muted-foreground text-xs\">\n {isFileUploading\n ? msg.file.uploading\n : isFileDeleting\n ? msg.file.deleting\n : formatFileSize(file.size)}\n </p>\n </div>\n <Button\n type=\"button\"\n aria-label={`${msg.file.remove}: ${file.name}`}\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-5 rounded-sm\"\n onClick={() => removeFile(file.id)}\n disabled={isPending}\n >\n <X aria-hidden=\"true\" className=\"size-3\" />\n </Button>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n ) : null}\n {isDraggingOver ? (\n <div className=\"flex items-center justify-center gap-2 text-primary-ink text-sm\">\n <Upload aria-hidden=\"true\" className=\"size-4\" />\n <span>{msg.file.dropHere}</span>\n </div>\n ) : files.length > 0 ? (\n <div className=\"flex flex-wrap items-center gap-1 overflow-hidden\">\n {visibleFiles.map((file) => {\n const isUploading = uploadingFiles.has(file.id);\n\n if (isUploading) {\n return (\n <Skeleton\n key={file.id}\n className=\"h-5 shrink-0 px-1.5\"\n style={{\n width: `${Math.min(file.name.length * 8 + 30, 100)}px`\n }}\n />\n );\n }\n\n const FileIcon = getFileIcon(file.type);\n\n return (\n <Badge key={file.id} variant=\"secondary\" className=\"gap-1 px-1.5 py-px\">\n {FileIcon && <FileIcon className=\"size-3 shrink-0\" />}\n <span className=\"max-w-[100px] truncate\">{file.name}</span>\n </Badge>\n );\n })}\n {hiddenFileCount > 0 && (\n <Badge variant=\"outline\" className=\"px-1.5 py-px text-muted-foreground\">\n +{hiddenFileCount}\n </Badge>\n )}\n </div>\n ) : null}\n </DataGridCellWrapper>\n );\n}\n"],"mappings":"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","names":["isSelected","error","isUploading"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { DataGridCellProps } from './types.js';
|
|
3
|
+
import '@tanstack/react-table';
|
|
4
|
+
|
|
5
|
+
interface DataGridCellWrapperProps<TData> extends DataGridCellProps<TData>, React.ComponentProps<"div"> {
|
|
6
|
+
}
|
|
7
|
+
declare function DataGridCellWrapper<TData>({ tableMeta, rowIndex, columnId, isEditing, isFocused, isSelected, isSearchMatch, isActiveSearchMatch, readOnly, rowHeight, className, onClick: onClickProp, onKeyDown: onKeyDownProp, ref, ...props }: DataGridCellWrapperProps<TData>): React.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { DataGridCellWrapper };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { useComposedRefs } from "./compose-refs.js";
|
|
6
|
+
import { useDataGridPresence } from "./data-grid-presence.js";
|
|
7
|
+
import { getCellKey } from "./utils.js";
|
|
8
|
+
function DataGridCellWrapper({
|
|
9
|
+
tableMeta,
|
|
10
|
+
rowIndex,
|
|
11
|
+
columnId,
|
|
12
|
+
isEditing,
|
|
13
|
+
isFocused,
|
|
14
|
+
isSelected,
|
|
15
|
+
isSearchMatch,
|
|
16
|
+
isActiveSearchMatch,
|
|
17
|
+
readOnly,
|
|
18
|
+
rowHeight,
|
|
19
|
+
className,
|
|
20
|
+
onClick: onClickProp,
|
|
21
|
+
onKeyDown: onKeyDownProp,
|
|
22
|
+
ref,
|
|
23
|
+
...props
|
|
24
|
+
}) {
|
|
25
|
+
const cellMapRef = tableMeta?.cellMapRef;
|
|
26
|
+
const cellPresence = useDataGridPresence(getCellKey(rowIndex, columnId));
|
|
27
|
+
const onCellChange = React.useCallback(
|
|
28
|
+
(node) => {
|
|
29
|
+
if (!cellMapRef) return;
|
|
30
|
+
const cellKey = getCellKey(rowIndex, columnId);
|
|
31
|
+
if (node) {
|
|
32
|
+
cellMapRef.current.set(cellKey, node);
|
|
33
|
+
} else {
|
|
34
|
+
cellMapRef.current.delete(cellKey);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
[rowIndex, columnId, cellMapRef]
|
|
38
|
+
);
|
|
39
|
+
const composedRef = useComposedRefs(ref, onCellChange);
|
|
40
|
+
const onClick = React.useCallback(
|
|
41
|
+
(event) => {
|
|
42
|
+
if (!isEditing) {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
onClickProp?.(event);
|
|
45
|
+
if (isFocused && !readOnly) {
|
|
46
|
+
tableMeta?.onCellEditingStart?.(rowIndex, columnId);
|
|
47
|
+
} else {
|
|
48
|
+
tableMeta?.onCellClick?.(rowIndex, columnId, event);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
[tableMeta, rowIndex, columnId, isEditing, isFocused, readOnly, onClickProp]
|
|
53
|
+
);
|
|
54
|
+
const onContextMenu = React.useCallback(
|
|
55
|
+
(event) => {
|
|
56
|
+
if (!isEditing) {
|
|
57
|
+
tableMeta?.onCellContextMenu?.(rowIndex, columnId, event);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[tableMeta, rowIndex, columnId, isEditing]
|
|
61
|
+
);
|
|
62
|
+
const onDoubleClick = React.useCallback(
|
|
63
|
+
(event) => {
|
|
64
|
+
if (!isEditing) {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
tableMeta?.onCellDoubleClick?.(rowIndex, columnId);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
[tableMeta, rowIndex, columnId, isEditing]
|
|
70
|
+
);
|
|
71
|
+
const onKeyDown = React.useCallback(
|
|
72
|
+
(event) => {
|
|
73
|
+
onKeyDownProp?.(event);
|
|
74
|
+
if (event.defaultPrevented) return;
|
|
75
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Home" || event.key === "End" || event.key === "PageUp" || event.key === "PageDown" || event.key === "Tab") {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (isFocused && !isEditing && !readOnly) {
|
|
79
|
+
if (event.key === "F2" || event.key === "Enter") {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
event.stopPropagation();
|
|
82
|
+
tableMeta?.onCellEditingStart?.(rowIndex, columnId);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (event.key === " ") {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
event.stopPropagation();
|
|
88
|
+
tableMeta?.onCellEditingStart?.(rowIndex, columnId);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
event.stopPropagation();
|
|
94
|
+
tableMeta?.onCellEditingStart?.(rowIndex, columnId);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
[onKeyDownProp, isFocused, isEditing, readOnly, tableMeta, rowIndex, columnId]
|
|
99
|
+
);
|
|
100
|
+
const onMouseDown = React.useCallback(
|
|
101
|
+
(event) => {
|
|
102
|
+
if (!isEditing) {
|
|
103
|
+
tableMeta?.onCellMouseDown?.(rowIndex, columnId, event);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
[tableMeta, rowIndex, columnId, isEditing]
|
|
107
|
+
);
|
|
108
|
+
const onMouseEnter = React.useCallback(() => {
|
|
109
|
+
if (!isEditing) {
|
|
110
|
+
tableMeta?.onCellMouseEnter?.(rowIndex, columnId);
|
|
111
|
+
}
|
|
112
|
+
}, [tableMeta, rowIndex, columnId, isEditing]);
|
|
113
|
+
const onMouseUp = React.useCallback(() => {
|
|
114
|
+
if (!isEditing) {
|
|
115
|
+
tableMeta?.onCellMouseUp?.();
|
|
116
|
+
}
|
|
117
|
+
}, [tableMeta, isEditing]);
|
|
118
|
+
return /* @__PURE__ */ jsx(
|
|
119
|
+
"div",
|
|
120
|
+
{
|
|
121
|
+
role: "button",
|
|
122
|
+
"data-slot": "grid-cell-wrapper",
|
|
123
|
+
"data-editing": isEditing ? "" : void 0,
|
|
124
|
+
"data-focused": isFocused ? "" : void 0,
|
|
125
|
+
"data-selected": isSelected ? "" : void 0,
|
|
126
|
+
tabIndex: isFocused && !isEditing ? 0 : -1,
|
|
127
|
+
...props,
|
|
128
|
+
ref: composedRef,
|
|
129
|
+
className: cn(
|
|
130
|
+
/*
|
|
131
|
+
* ─ BA TÍN HIỆU MÀU CỦA MỘT Ô, VÀ VÌ SAO CHÚNG KHÔNG PHẢI TINT CỦA `--primary`/`--warning` ─
|
|
132
|
+
*
|
|
133
|
+
* Bản gốc tô `bg-primary/10` cho vùng chọn và `bg-warning/20`÷`/50` cho kết quả tìm kiếm.
|
|
134
|
+
* Cả hai đều là bậc TÔ NỀN pha loãng, và `pnpm lint:a11y` bác đúng chỗ: 1,05:1 (light) ·
|
|
135
|
+
* 1,21:1 (dark) cho vùng chọn — dưới xa ngưỡng 3:1 của WCAG 1.4.11 cho thông tin thị giác.
|
|
136
|
+
* Một dấu hiệu không nhìn thấy là một dấu hiệu GIẢ.
|
|
137
|
+
*
|
|
138
|
+
* Thay bằng đúng hai bậc mà hợp đồng màu cấp cho việc này:
|
|
139
|
+
* • vùng chọn → `--accent`, bậc tint TRẠNG THÁI (Tabs/Switch/Progress nói "đang bật"
|
|
140
|
+
* bằng chính nó). Là token BỀ MẶT nên nó được phép nhạt: nghĩa vụ 3:1
|
|
141
|
+
* không rơi lên tint, mà rơi lên NÉT đi kèm.
|
|
142
|
+
* • tìm kiếm → viền `--warning-ink` (6,51:1 light · 11,60:1 dark trên nền ô) — ĐÂY mới
|
|
143
|
+
* là thứ mang thông tin; ô đang đứng thì thêm nền `--warning` đặc + chữ
|
|
144
|
+
* `--warning-foreground` (12,26:1) cho khác hẳn các ô còn lại.
|
|
145
|
+
*
|
|
146
|
+
* `border-transparent` ở bậc nghỉ để bật/tắt viền KHÔNG xô layout 1px (cùng cách
|
|
147
|
+
* `TableRow` giữ bề rộng viền không đổi giữa hai trạng thái).
|
|
148
|
+
*/
|
|
149
|
+
// has-[[role=checkbox]] = ô kiểu checkbox (Radix render <button role="checkbox">)
|
|
150
|
+
"size-full border border-transparent px-2 py-1.5 text-start text-sm outline-none focus-visible:outline-none has-[[role=checkbox]]:pt-2.5",
|
|
151
|
+
{
|
|
152
|
+
"ring-1 ring-inset": isFocused || !!cellPresence,
|
|
153
|
+
"ring-ring": isFocused && !cellPresence,
|
|
154
|
+
"border-warning-ink": isSearchMatch || isActiveSearchMatch,
|
|
155
|
+
"bg-warning text-warning-foreground": isActiveSearchMatch,
|
|
156
|
+
"bg-accent": isSelected && !isEditing && !isActiveSearchMatch,
|
|
157
|
+
"cursor-default": !isEditing,
|
|
158
|
+
"[&_[data-slot=grid-cell-content]]:line-clamp-1": !isEditing && rowHeight === "short",
|
|
159
|
+
"[&_[data-slot=grid-cell-content]]:line-clamp-2": !isEditing && rowHeight === "medium",
|
|
160
|
+
"[&_[data-slot=grid-cell-content]]:line-clamp-3": !isEditing && rowHeight === "tall",
|
|
161
|
+
"[&_[data-slot=grid-cell-content]]:line-clamp-4": !isEditing && rowHeight === "extra-tall"
|
|
162
|
+
},
|
|
163
|
+
className
|
|
164
|
+
),
|
|
165
|
+
style: cellPresence ? { "--tw-ring-color": cellPresence.color } : void 0,
|
|
166
|
+
onClick,
|
|
167
|
+
onContextMenu,
|
|
168
|
+
onDoubleClick,
|
|
169
|
+
onMouseDown,
|
|
170
|
+
onMouseEnter,
|
|
171
|
+
onMouseUp,
|
|
172
|
+
onKeyDown
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
DataGridCellWrapper
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=data-grid-cell-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data-grid/data-grid-cell-wrapper.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport { useComposedRefs } from \"./compose-refs.js\";\nimport { useDataGridPresence } from \"./data-grid-presence.js\";\nimport type { DataGridCellProps } from \"./types.js\";\nimport { getCellKey } from \"./utils.js\";\n\ninterface DataGridCellWrapperProps<TData> extends DataGridCellProps<TData>, React.ComponentProps<\"div\"> {}\n\nexport function DataGridCellWrapper<TData>({\n tableMeta,\n rowIndex,\n columnId,\n isEditing,\n isFocused,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly,\n rowHeight,\n className,\n onClick: onClickProp,\n onKeyDown: onKeyDownProp,\n ref,\n ...props\n}: DataGridCellWrapperProps<TData>) {\n const cellMapRef = tableMeta?.cellMapRef;\n const cellPresence = useDataGridPresence(getCellKey(rowIndex, columnId));\n\n const onCellChange = React.useCallback(\n (node: HTMLDivElement | null) => {\n if (!cellMapRef) return;\n\n const cellKey = getCellKey(rowIndex, columnId);\n\n if (node) {\n cellMapRef.current.set(cellKey, node);\n } else {\n cellMapRef.current.delete(cellKey);\n }\n },\n [rowIndex, columnId, cellMapRef]\n );\n\n const composedRef = useComposedRefs(ref, onCellChange);\n\n const onClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!isEditing) {\n event.preventDefault();\n onClickProp?.(event);\n if (isFocused && !readOnly) {\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n } else {\n tableMeta?.onCellClick?.(rowIndex, columnId, event);\n }\n }\n },\n [tableMeta, rowIndex, columnId, isEditing, isFocused, readOnly, onClickProp]\n );\n\n const onContextMenu = React.useCallback(\n (event: React.MouseEvent) => {\n if (!isEditing) {\n tableMeta?.onCellContextMenu?.(rowIndex, columnId, event);\n }\n },\n [tableMeta, rowIndex, columnId, isEditing]\n );\n\n const onDoubleClick = React.useCallback(\n (event: React.MouseEvent) => {\n if (!isEditing) {\n event.preventDefault();\n tableMeta?.onCellDoubleClick?.(rowIndex, columnId);\n }\n },\n [tableMeta, rowIndex, columnId, isEditing]\n );\n\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n onKeyDownProp?.(event);\n\n if (event.defaultPrevented) return;\n\n if (\n event.key === \"ArrowUp\" ||\n event.key === \"ArrowDown\" ||\n event.key === \"ArrowLeft\" ||\n event.key === \"ArrowRight\" ||\n event.key === \"Home\" ||\n event.key === \"End\" ||\n event.key === \"PageUp\" ||\n event.key === \"PageDown\" ||\n event.key === \"Tab\"\n ) {\n return;\n }\n\n if (isFocused && !isEditing && !readOnly) {\n if (event.key === \"F2\" || event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n return;\n }\n\n if (event.key === \" \") {\n event.preventDefault();\n event.stopPropagation();\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n return;\n }\n\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n event.preventDefault();\n event.stopPropagation();\n tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n }\n }\n },\n [onKeyDownProp, isFocused, isEditing, readOnly, tableMeta, rowIndex, columnId]\n );\n\n const onMouseDown = React.useCallback(\n (event: React.MouseEvent) => {\n if (!isEditing) {\n tableMeta?.onCellMouseDown?.(rowIndex, columnId, event);\n }\n },\n [tableMeta, rowIndex, columnId, isEditing]\n );\n\n const onMouseEnter = React.useCallback(() => {\n if (!isEditing) {\n tableMeta?.onCellMouseEnter?.(rowIndex, columnId);\n }\n }, [tableMeta, rowIndex, columnId, isEditing]);\n\n const onMouseUp = React.useCallback(() => {\n if (!isEditing) {\n tableMeta?.onCellMouseUp?.();\n }\n }, [tableMeta, isEditing]);\n\n return (\n <div\n role=\"button\"\n data-slot=\"grid-cell-wrapper\"\n data-editing={isEditing ? \"\" : undefined}\n data-focused={isFocused ? \"\" : undefined}\n data-selected={isSelected ? \"\" : undefined}\n tabIndex={isFocused && !isEditing ? 0 : -1}\n {...props}\n ref={composedRef}\n className={cn(\n /*\n * ─ BA TÍN HIỆU MÀU CỦA MỘT Ô, VÀ VÌ SAO CHÚNG KHÔNG PHẢI TINT CỦA `--primary`/`--warning` ─\n *\n * Bản gốc tô `bg-primary/10` cho vùng chọn và `bg-warning/20`÷`/50` cho kết quả tìm kiếm.\n * Cả hai đều là bậc TÔ NỀN pha loãng, và `pnpm lint:a11y` bác đúng chỗ: 1,05:1 (light) ·\n * 1,21:1 (dark) cho vùng chọn — dưới xa ngưỡng 3:1 của WCAG 1.4.11 cho thông tin thị giác.\n * Một dấu hiệu không nhìn thấy là một dấu hiệu GIẢ.\n *\n * Thay bằng đúng hai bậc mà hợp đồng màu cấp cho việc này:\n * • vùng chọn → `--accent`, bậc tint TRẠNG THÁI (Tabs/Switch/Progress nói \"đang bật\"\n * bằng chính nó). Là token BỀ MẶT nên nó được phép nhạt: nghĩa vụ 3:1\n * không rơi lên tint, mà rơi lên NÉT đi kèm.\n * • tìm kiếm → viền `--warning-ink` (6,51:1 light · 11,60:1 dark trên nền ô) — ĐÂY mới\n * là thứ mang thông tin; ô đang đứng thì thêm nền `--warning` đặc + chữ\n * `--warning-foreground` (12,26:1) cho khác hẳn các ô còn lại.\n *\n * `border-transparent` ở bậc nghỉ để bật/tắt viền KHÔNG xô layout 1px (cùng cách\n * `TableRow` giữ bề rộng viền không đổi giữa hai trạng thái).\n */\n // has-[[role=checkbox]] = ô kiểu checkbox (Radix render <button role=\"checkbox\">)\n \"size-full border border-transparent px-2 py-1.5 text-start text-sm outline-none focus-visible:outline-none has-[[role=checkbox]]:pt-2.5\",\n {\n \"ring-1 ring-inset\": isFocused || !!cellPresence,\n \"ring-ring\": isFocused && !cellPresence,\n \"border-warning-ink\": isSearchMatch || isActiveSearchMatch,\n \"bg-warning text-warning-foreground\": isActiveSearchMatch,\n \"bg-accent\": isSelected && !isEditing && !isActiveSearchMatch,\n \"cursor-default\": !isEditing,\n \"[&_[data-slot=grid-cell-content]]:line-clamp-1\": !isEditing && rowHeight === \"short\",\n \"[&_[data-slot=grid-cell-content]]:line-clamp-2\": !isEditing && rowHeight === \"medium\",\n \"[&_[data-slot=grid-cell-content]]:line-clamp-3\": !isEditing && rowHeight === \"tall\",\n \"[&_[data-slot=grid-cell-content]]:line-clamp-4\": !isEditing && rowHeight === \"extra-tall\"\n },\n className\n )}\n style={cellPresence ? ({ \"--tw-ring-color\": cellPresence.color } as React.CSSProperties) : undefined}\n onClick={onClick}\n onContextMenu={onContextMenu}\n onDoubleClick={onDoubleClick}\n onMouseDown={onMouseDown}\n onMouseEnter={onMouseEnter}\n onMouseUp={onMouseUp}\n onKeyDown={onKeyDown}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { DataGridCellProps } from './types.js';
|
|
3
|
+
import '@tanstack/react-table';
|
|
4
|
+
|
|
5
|
+
declare const DataGridCell: typeof DataGridCellImpl;
|
|
6
|
+
declare function DataGridCellImpl<TData>({ cell, tableMeta, rowIndex, columnId, isFocused, isEditing, isSelected, isSearchMatch, isActiveSearchMatch, readOnly, rowHeight }: DataGridCellProps<TData>): React.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { DataGridCell };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
CheckboxCell,
|
|
6
|
+
DateCell,
|
|
7
|
+
FileCell,
|
|
8
|
+
LongTextCell,
|
|
9
|
+
MultiSelectCell,
|
|
10
|
+
NumberCell,
|
|
11
|
+
SelectCell,
|
|
12
|
+
ShortTextCell,
|
|
13
|
+
UrlCell
|
|
14
|
+
} from "./data-grid-cell-variants.js";
|
|
15
|
+
const DataGridCell = React.memo(DataGridCellImpl, (prev, next) => {
|
|
16
|
+
if (prev.isFocused !== next.isFocused) return false;
|
|
17
|
+
if (prev.isEditing !== next.isEditing) return false;
|
|
18
|
+
if (prev.isSelected !== next.isSelected) return false;
|
|
19
|
+
if (prev.isSearchMatch !== next.isSearchMatch) return false;
|
|
20
|
+
if (prev.isActiveSearchMatch !== next.isActiveSearchMatch) return false;
|
|
21
|
+
if (prev.readOnly !== next.readOnly) return false;
|
|
22
|
+
if (prev.rowIndex !== next.rowIndex) return false;
|
|
23
|
+
if (prev.columnId !== next.columnId) return false;
|
|
24
|
+
if (prev.rowHeight !== next.rowHeight) return false;
|
|
25
|
+
const prevValue = prev.cell.row.original[prev.columnId];
|
|
26
|
+
const nextValue = next.cell.row.original[next.columnId];
|
|
27
|
+
if (prevValue !== nextValue) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (prev.cell.row.id !== next.cell.row.id) return false;
|
|
31
|
+
return true;
|
|
32
|
+
});
|
|
33
|
+
function DataGridCellImpl({
|
|
34
|
+
cell,
|
|
35
|
+
tableMeta,
|
|
36
|
+
rowIndex,
|
|
37
|
+
columnId,
|
|
38
|
+
isFocused,
|
|
39
|
+
isEditing,
|
|
40
|
+
isSelected,
|
|
41
|
+
isSearchMatch,
|
|
42
|
+
isActiveSearchMatch,
|
|
43
|
+
readOnly,
|
|
44
|
+
rowHeight
|
|
45
|
+
}) {
|
|
46
|
+
const cellOpts = cell.column.columnDef.meta?.cell;
|
|
47
|
+
const variant = cellOpts?.variant ?? "text";
|
|
48
|
+
let Comp;
|
|
49
|
+
switch (variant) {
|
|
50
|
+
case "short-text":
|
|
51
|
+
Comp = ShortTextCell;
|
|
52
|
+
break;
|
|
53
|
+
case "long-text":
|
|
54
|
+
Comp = LongTextCell;
|
|
55
|
+
break;
|
|
56
|
+
case "number":
|
|
57
|
+
Comp = NumberCell;
|
|
58
|
+
break;
|
|
59
|
+
case "url":
|
|
60
|
+
Comp = UrlCell;
|
|
61
|
+
break;
|
|
62
|
+
case "checkbox":
|
|
63
|
+
Comp = CheckboxCell;
|
|
64
|
+
break;
|
|
65
|
+
case "select":
|
|
66
|
+
Comp = SelectCell;
|
|
67
|
+
break;
|
|
68
|
+
case "multi-select":
|
|
69
|
+
Comp = MultiSelectCell;
|
|
70
|
+
break;
|
|
71
|
+
case "date":
|
|
72
|
+
Comp = DateCell;
|
|
73
|
+
break;
|
|
74
|
+
case "file":
|
|
75
|
+
Comp = FileCell;
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
Comp = ShortTextCell;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
Comp,
|
|
83
|
+
{
|
|
84
|
+
cell,
|
|
85
|
+
tableMeta,
|
|
86
|
+
rowIndex,
|
|
87
|
+
columnId,
|
|
88
|
+
rowHeight,
|
|
89
|
+
isEditing,
|
|
90
|
+
isFocused,
|
|
91
|
+
isSelected,
|
|
92
|
+
isSearchMatch,
|
|
93
|
+
isActiveSearchMatch,
|
|
94
|
+
readOnly
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
DataGridCell
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=data-grid-cell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data-grid/data-grid-cell.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n CheckboxCell,\n DateCell,\n FileCell,\n LongTextCell,\n MultiSelectCell,\n NumberCell,\n SelectCell,\n ShortTextCell,\n UrlCell\n} from \"./data-grid-cell-variants.js\";\nimport type { DataGridCellProps } from \"./types.js\";\n\nexport const DataGridCell = React.memo(DataGridCellImpl, (prev, next) => {\n // Fast path: check stable primitive props first\n if (prev.isFocused !== next.isFocused) return false;\n if (prev.isEditing !== next.isEditing) return false;\n if (prev.isSelected !== next.isSelected) return false;\n if (prev.isSearchMatch !== next.isSearchMatch) return false;\n if (prev.isActiveSearchMatch !== next.isActiveSearchMatch) return false;\n if (prev.readOnly !== next.readOnly) return false;\n if (prev.rowIndex !== next.rowIndex) return false;\n if (prev.columnId !== next.columnId) return false;\n if (prev.rowHeight !== next.rowHeight) return false;\n\n // Check cell value using row.original instead of getValue() for stability\n // getValue() is unstable and recreates on every render, breaking memoization\n const prevValue = (prev.cell.row.original as Record<string, unknown>)[prev.columnId];\n const nextValue = (next.cell.row.original as Record<string, unknown>)[next.columnId];\n if (prevValue !== nextValue) {\n return false;\n }\n\n // Check cell/row identity\n if (prev.cell.row.id !== next.cell.row.id) return false;\n\n return true;\n}) as typeof DataGridCellImpl;\n\nfunction DataGridCellImpl<TData>({\n cell,\n tableMeta,\n rowIndex,\n columnId,\n isFocused,\n isEditing,\n isSelected,\n isSearchMatch,\n isActiveSearchMatch,\n readOnly,\n rowHeight\n}: DataGridCellProps<TData>) {\n const cellOpts = cell.column.columnDef.meta?.cell;\n const variant = cellOpts?.variant ?? \"text\";\n\n let Comp: React.ComponentType<DataGridCellProps<TData>>;\n\n switch (variant) {\n case \"short-text\":\n Comp = ShortTextCell;\n break;\n case \"long-text\":\n Comp = LongTextCell;\n break;\n case \"number\":\n Comp = NumberCell;\n break;\n case \"url\":\n Comp = UrlCell;\n break;\n case \"checkbox\":\n Comp = CheckboxCell;\n break;\n case \"select\":\n Comp = SelectCell;\n break;\n case \"multi-select\":\n Comp = MultiSelectCell;\n break;\n case \"date\":\n Comp = DateCell;\n break;\n case \"file\":\n Comp = FileCell;\n break;\n\n default:\n Comp = ShortTextCell;\n break;\n }\n\n return (\n <Comp\n cell={cell}\n tableMeta={tableMeta}\n rowIndex={rowIndex}\n columnId={columnId}\n rowHeight={rowHeight}\n isEditing={isEditing}\n isFocused={isFocused}\n isSelected={isSelected}\n isSearchMatch={isSearchMatch}\n isActiveSearchMatch={isActiveSearchMatch}\n readOnly={readOnly}\n />\n );\n}\n"],"mappings":";AAgGI;AA9FJ,YAAY,WAAW;AAEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,MAAM,eAAe,MAAM,KAAK,kBAAkB,CAAC,MAAM,SAAS;AAEvE,MAAI,KAAK,cAAc,KAAK,UAAW,QAAO;AAC9C,MAAI,KAAK,cAAc,KAAK,UAAW,QAAO;AAC9C,MAAI,KAAK,eAAe,KAAK,WAAY,QAAO;AAChD,MAAI,KAAK,kBAAkB,KAAK,cAAe,QAAO;AACtD,MAAI,KAAK,wBAAwB,KAAK,oBAAqB,QAAO;AAClE,MAAI,KAAK,aAAa,KAAK,SAAU,QAAO;AAC5C,MAAI,KAAK,aAAa,KAAK,SAAU,QAAO;AAC5C,MAAI,KAAK,aAAa,KAAK,SAAU,QAAO;AAC5C,MAAI,KAAK,cAAc,KAAK,UAAW,QAAO;AAI9C,QAAM,YAAa,KAAK,KAAK,IAAI,SAAqC,KAAK,QAAQ;AACnF,QAAM,YAAa,KAAK,KAAK,IAAI,SAAqC,KAAK,QAAQ;AACnF,MAAI,cAAc,WAAW;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,IAAI,GAAI,QAAO;AAElD,SAAO;AACT,CAAC;AAED,SAAS,iBAAwB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,WAAW,KAAK,OAAO,UAAU,MAAM;AAC7C,QAAM,UAAU,UAAU,WAAW;AAErC,MAAI;AAEJ,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IACF,KAAK;AACH,aAAO;AACP;AAAA,IAEF;AACE,aAAO;AACP;AAAA,EACJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Header, Table } from '@tanstack/react-table';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { DropdownMenuTrigger } from '../components/ui/dropdown-menu.js';
|
|
4
|
+
import '@radix-ui/react-dropdown-menu';
|
|
5
|
+
|
|
6
|
+
interface DataGridColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {
|
|
7
|
+
header: Header<TData, TValue>;
|
|
8
|
+
table: Table<TData>;
|
|
9
|
+
}
|
|
10
|
+
declare function DataGridColumnHeader<TData, TValue>({ header, table, className, onPointerDown, ...props }: DataGridColumnHeaderProps<TData, TValue>): React.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { DataGridColumnHeader };
|