@comitor/ui 3.0.0 → 3.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.
Files changed (110) hide show
  1. package/README.md +5 -1
  2. package/dist/components/composite/confirm-dialog.js +56 -35
  3. package/dist/components/composite/confirm-dialog.js.map +1 -1
  4. package/dist/components/composite/search-filter-bar-constants.d.ts +3 -0
  5. package/dist/components/composite/search-filter-bar-constants.js.map +1 -1
  6. package/dist/components/composite/table-pagination-constants.d.ts +3 -1
  7. package/dist/components/composite/table-pagination-constants.js.map +1 -1
  8. package/dist/components/composite/table-pagination.js +10 -2
  9. package/dist/components/composite/table-pagination.js.map +1 -1
  10. package/dist/components/composite/text-utils.d.ts +4 -23
  11. package/dist/components/composite/text-utils.js +1 -11
  12. package/dist/components/composite/text-utils.js.map +1 -1
  13. package/dist/components/composite/toast.d.ts +2 -1
  14. package/dist/components/composite/toast.js +3 -9
  15. package/dist/components/composite/toast.js.map +1 -1
  16. package/dist/components/ui/action-bar.js +45 -1
  17. package/dist/components/ui/action-bar.js.map +1 -1
  18. package/dist/components/ui/banner.d.ts +8 -0
  19. package/dist/components/ui/banner.js +149 -35
  20. package/dist/components/ui/banner.js.map +1 -1
  21. package/dist/components/ui/circular-progress.js +10 -2
  22. package/dist/components/ui/circular-progress.js.map +1 -1
  23. package/dist/components/ui/kanban.js +9 -3
  24. package/dist/components/ui/kanban.js.map +1 -1
  25. package/dist/components/ui/key-value.js +70 -76
  26. package/dist/components/ui/key-value.js.map +1 -1
  27. package/dist/components/ui/mask-input-constants.d.ts +34 -2
  28. package/dist/components/ui/mask-input-constants.js +87 -76
  29. package/dist/components/ui/mask-input-constants.js.map +1 -1
  30. package/dist/components/ui/mask-input.d.ts +6 -5
  31. package/dist/components/ui/mask-input.js +23 -21
  32. package/dist/components/ui/mask-input.js.map +1 -1
  33. package/dist/components/ui/mention.d.ts +14 -2
  34. package/dist/components/ui/mention.js +33 -6
  35. package/dist/components/ui/mention.js.map +1 -1
  36. package/dist/components/ui/phone-input.d.ts +18 -8
  37. package/dist/components/ui/phone-input.js +125 -35
  38. package/dist/components/ui/phone-input.js.map +1 -1
  39. package/dist/components/ui/rating.js +4 -2
  40. package/dist/components/ui/rating.js.map +1 -1
  41. package/dist/components/ui/scroll-spy.js +46 -31
  42. package/dist/components/ui/scroll-spy.js.map +1 -1
  43. package/dist/components/ui/slider.d.ts +1 -1
  44. package/dist/components/ui/slider.js +15 -1
  45. package/dist/components/ui/slider.js.map +1 -1
  46. package/dist/components/ui/sonner.js +2 -0
  47. package/dist/components/ui/sonner.js.map +1 -1
  48. package/dist/components/ui/stepper.js +26 -3
  49. package/dist/components/ui/stepper.js.map +1 -1
  50. package/dist/components/ui/time-picker.d.ts +24 -4
  51. package/dist/components/ui/time-picker.js +425 -162
  52. package/dist/components/ui/time-picker.js.map +1 -1
  53. package/dist/components/ui/timeline.js +45 -9
  54. package/dist/components/ui/timeline.js.map +1 -1
  55. package/dist/components/ui/toggle-group.js +12 -1
  56. package/dist/components/ui/toggle-group.js.map +1 -1
  57. package/dist/components/ui/tour.js +3 -2
  58. package/dist/components/ui/tour.js.map +1 -1
  59. package/dist/data-grid/data-grid-cell-variants.js +4 -4
  60. package/dist/data-grid/data-grid-cell-variants.js.map +1 -1
  61. package/dist/data-grid/data-grid-cell-wrapper.d.ts +1 -1
  62. package/dist/data-grid/data-grid-cell-wrapper.js +6 -0
  63. package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -1
  64. package/dist/data-grid/data-grid-row.js +1 -1
  65. package/dist/data-grid/data-grid-row.js.map +1 -1
  66. package/dist/data-grid/data-grid-select-column.js +6 -2
  67. package/dist/data-grid/data-grid-select-column.js.map +1 -1
  68. package/dist/data-grid/data-grid-skeleton.d.ts +5 -0
  69. package/dist/data-grid/data-grid-skeleton.js +1 -4
  70. package/dist/data-grid/data-grid-skeleton.js.map +1 -1
  71. package/dist/data-grid/data-grid.d.ts +1 -1
  72. package/dist/data-grid/data-grid.js +3 -2
  73. package/dist/data-grid/data-grid.js.map +1 -1
  74. package/dist/data-grid/filters.js +3 -2
  75. package/dist/data-grid/filters.js.map +1 -1
  76. package/dist/data-grid/types.d.ts +7 -0
  77. package/dist/data-grid/use-data-grid.d.ts +1 -0
  78. package/dist/data-grid/use-data-grid.js +70 -24
  79. package/dist/data-grid/use-data-grid.js.map +1 -1
  80. package/dist/data-grid/utils.d.ts +7 -0
  81. package/dist/data-grid/utils.js +3 -1
  82. package/dist/data-grid/utils.js.map +1 -1
  83. package/dist/i18n/locale-provider.d.ts +18 -0
  84. package/dist/i18n/locale-provider.js.map +1 -1
  85. package/dist/i18n/namespaces/rating.js +2 -1
  86. package/dist/i18n/namespaces/rating.js.map +1 -1
  87. package/dist/i18n/namespaces/search-filter-bar.js +8 -6
  88. package/dist/i18n/namespaces/search-filter-bar.js.map +1 -1
  89. package/dist/i18n/namespaces/shell.d.ts +4 -0
  90. package/dist/i18n/namespaces/shell.js +1 -1
  91. package/dist/i18n/namespaces/shell.js.map +1 -1
  92. package/dist/i18n/namespaces/table-pagination.js +6 -4
  93. package/dist/i18n/namespaces/table-pagination.js.map +1 -1
  94. package/dist/i18n/namespaces/toast.d.ts +3 -2
  95. package/dist/i18n/namespaces/toast.js.map +1 -1
  96. package/dist/index.d.ts +2 -1
  97. package/dist/lib/collect-item-elements.d.ts +47 -0
  98. package/dist/lib/collect-item-elements.js +22 -0
  99. package/dist/lib/collect-item-elements.js.map +1 -0
  100. package/dist/lib/text-search.d.ts +32 -0
  101. package/dist/lib/text-search.js +17 -0
  102. package/dist/lib/text-search.js.map +1 -0
  103. package/dist/lib/toast-language.d.ts +8 -0
  104. package/dist/lib/toast-language.js +19 -0
  105. package/dist/lib/toast-language.js.map +1 -0
  106. package/dist/shell/app-shell.d.ts +1 -0
  107. package/dist/shell/index.d.ts +2 -1
  108. package/dist/shell/shell-context.d.ts +1 -0
  109. package/dist/shell/utils.d.ts +2 -1
  110. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/kanban.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/kanban) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\nimport {\n type Announcements,\n type CollisionDetection,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragCancelEvent,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n type DragOverEvent,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n type DroppableContainer,\n defaultDropAnimationSideEffects,\n getFirstCollision,\n KeyboardCode,\n type KeyboardCoordinateGetter,\n KeyboardSensor,\n MeasuringStrategy,\n MouseSensor,\n pointerWithin,\n rectIntersection,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors\n} from \"@dnd-kit/core\";\nimport {\n type AnimateLayoutChanges,\n arrayMove,\n defaultAnimateLayoutChanges,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n useSortable,\n verticalListSortingStrategy\n} from \"@dnd-kit/sortable\";\nimport { CSS, isKeyboardEvent } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { useComitorLabels } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { useComposedRefs } from \"../../lib/compose-refs.js\";\nimport { useIsomorphicLayoutEffect } from \"../../lib/use-isomorphic-layout-effect.js\";\nimport type { KanbanLabels } from \"./kanban-constants.js\";\n\nconst directions = new Set<string>([KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left]);\n\nfunction getIsDirectionCode(code: string): code is KeyboardCode {\n return directions.has(code);\n}\n\nconst coordinateGetter: KeyboardCoordinateGetter = (event, { context }) => {\n const { active, droppableRects, droppableContainers, collisionRect } = context;\n\n if (getIsDirectionCode(event.code)) {\n event.preventDefault();\n\n if (!active || !collisionRect) return;\n\n const filteredContainers: DroppableContainer[] = [];\n\n /*\n * ⚠ Khác thượng nguồn: `continue` chứ không `return`. Vòng lặp này chép từ ví dụ \"multiple\n * containers\" của dnd-kit, nơi nó là `forEach` — ở đó `return` nghĩa là BỎ QUA MỘT mục. Bản\n * gốc đổi sang `for…of` nhưng giữ `return`, nên chỉ cần MỘT vùng thả chưa đo được rect là\n * cả hàm trả `undefined` và phím mũi tên không di chuyển được gì nữa.\n */\n for (const entry of droppableContainers.getEnabled()) {\n if (!entry || entry?.disabled) continue;\n\n const rect = droppableRects.get(entry.id);\n\n if (!rect) continue;\n\n const data = entry.data.current;\n\n if (data) {\n const { type, children } = data;\n\n if (type === \"container\" && children?.length > 0) {\n if (active.data.current?.type !== \"container\") {\n continue;\n }\n }\n }\n\n switch (event.code) {\n case KeyboardCode.Down:\n if (collisionRect.top < rect.top) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Up:\n if (collisionRect.top > rect.top) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Left:\n if (collisionRect.left >= rect.left + rect.width) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Right:\n if (collisionRect.left + collisionRect.width <= rect.left) {\n filteredContainers.push(entry);\n }\n break;\n }\n }\n\n const collisions = closestCorners({\n active,\n collisionRect: collisionRect,\n droppableRects,\n droppableContainers: filteredContainers,\n pointerCoordinates: null\n });\n const closestId = getFirstCollision(collisions, \"id\");\n\n if (closestId != null) {\n const newDroppable = droppableContainers.get(closestId);\n const newNode = newDroppable?.node.current;\n const newRect = newDroppable?.rect.current;\n\n if (newNode && newRect) {\n if (newDroppable.id === \"placeholder\") {\n return {\n x: newRect.left + (newRect.width - collisionRect.width) / 2,\n y: newRect.top + (newRect.height - collisionRect.height) / 2\n };\n }\n\n if (newDroppable.data.current?.type === \"container\") {\n return {\n x: newRect.left + 20,\n y: newRect.top + 74\n };\n }\n\n return {\n x: newRect.left,\n y: newRect.top\n };\n }\n }\n }\n\n return undefined;\n};\n\n/*\n * ⚠ Khác thượng nguồn: bản gốc bỏ qua MỌI thao tác khi `event.activatorEvent.defaultPrevented`\n * — một lối để app huỷ kéo bằng cách gọi `preventDefault()` trong `onDragStart` của mình. Nhưng\n * `KeyboardSensor` của dnd-kit TỰ gọi `preventDefault()` lên chính phím Space/Enter kích hoạt\n * (để trang không cuộn), và `activatorEvent` là đúng event đó. Hệ quả ở bản gốc: kéo bằng bàn\n * phím nhấc được thẻ nhưng `activeId` không bao giờ được gán, `onDragOver`/`onDragEnd` đều\n * thoát sớm — thả xong thẻ vẫn nằm nguyên chỗ cũ. Đã đo trên trình duyệt thật với phím thật:\n * Space → ArrowRight → Space, vùng `aria-live` đọc \"item was dropped at position 1 of 2 in\n * doing\" trong khi `onValueChange` KHÔNG được gọi lần nào — trình đọc màn hình báo đã thả, dữ\n * liệu không đổi. Lối huỷ bằng `preventDefault()` vì thế chỉ còn hiệu lực với chuột/cảm ứng;\n * với bàn phím, dùng `cancelDrop` của dnd-kit.\n */\nfunction isDragPrevented(event: { activatorEvent: Event }) {\n return event.activatorEvent.defaultPrevented && !isKeyboardEvent(event.activatorEvent);\n}\n\nconst ROOT_NAME = \"Kanban\";\nconst BOARD_NAME = \"KanbanBoard\";\nconst COLUMN_NAME = \"KanbanColumn\";\nconst COLUMN_HANDLE_NAME = \"KanbanColumnHandle\";\nconst ITEM_NAME = \"KanbanItem\";\nconst ITEM_HANDLE_NAME = \"KanbanItemHandle\";\nconst OVERLAY_NAME = \"KanbanOverlay\";\n\ninterface KanbanContextValue<T> {\n id: string;\n items: Record<UniqueIdentifier, T[]>;\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n orientation: \"horizontal\" | \"vertical\";\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n labels: KanbanLabels;\n}\n\nconst KanbanContext = React.createContext<KanbanContextValue<unknown> | null>(null);\n\nfunction useKanbanContext(consumerName: string) {\n const context = React.useContext(KanbanContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue<T> {\n /**\n * Trả về định danh duy nhất của mỗi thẻ. BẮT BUỘC khi thẻ là object.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype KanbanProps<T> = Omit<DndContextProps, \"collisionDetection\"> &\n (T extends object ? GetItemValue<T> : Partial<GetItemValue<T>>) & {\n value: Record<UniqueIdentifier, T[]>;\n onValueChange?: (columns: Record<UniqueIdentifier, T[]>) => void;\n onMove?: (event: DragEndEvent & { activeIndex: number; overIndex: number }) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"horizontal\" | \"vertical\";\n flatCursor?: boolean;\n /**\n * Lời xướng cho trình đọc màn hình, hướng dẫn bàn phím và tên tay cầm kéo — ghi đè TỪNG khoá.\n * Không truyền thì theo namespace `kanban` của `ComitorLocaleProvider` (mặc định tiếng Anh).\n *\n * ⚠ Thêm so với thượng nguồn: bản gốc chôn cứng câu tiếng Anh (\"Picked up item at position\n * 2 of 5\") trong component; chỉ đổi được bằng cách viết lại cả `accessibility.announcements`,\n * tức tự tính lại vị trí/tổng số. Ở đây các hàm nhận sẵn `{ variant, value, position, total,\n * column }`. `accessibility` truyền thẳng vẫn được tôn trọng và THẮNG `labels`.\n */\n labels?: Partial<KanbanLabels>;\n };\n\nfunction Kanban<T>(props: KanbanProps<T>) {\n const {\n value,\n onValueChange,\n modifiers,\n strategy = verticalListSortingStrategy,\n orientation = \"horizontal\",\n onMove,\n getItemValue: getItemValueProp,\n accessibility,\n flatCursor = false,\n labels: labelsProp,\n ...kanbanProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState<UniqueIdentifier | null>(null);\n const lastOverIdRef = React.useRef<UniqueIdentifier | null>(null);\n const hasMovedRef = React.useRef(false);\n /*\n * ⚠ Khác thượng nguồn: `onDragOver` ghi thẳng mỗi lần đổi chỗ ra `onValueChange` (kéo tới\n * đâu, dữ liệu đổi tới đó), nên bản gốc huỷ bằng Escape KHÔNG trả thẻ về chỗ cũ — trái với\n * chính hướng dẫn bàn phím nó đọc cho người dùng (\"press escape to cancel\"). Chụp giá trị lúc\n * nhấc để `onDragCancel` trả lại, đúng như ví dụ \"multiple containers\" gốc của dnd-kit.\n */\n const valueAtDragStartRef = React.useRef<Record<UniqueIdentifier, T[]> | null>(null);\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter\n })\n );\n\n const labels = useComitorLabels(\"kanban\", labelsProp);\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"`getItemValue` là bắt buộc khi thẻ là object\");\n }\n return getItemValueProp ? getItemValueProp(item) : (item as UniqueIdentifier);\n },\n [getItemValueProp]\n );\n\n const getColumn = React.useCallback(\n (targetId: UniqueIdentifier) => {\n if (targetId in value) return targetId;\n\n for (const [columnId, columnItems] of Object.entries(value)) {\n if (columnItems.some((item) => getItemValue(item) === targetId)) {\n return columnId;\n }\n }\n\n return null;\n },\n [value, getItemValue]\n );\n\n const collisionDetection: CollisionDetection = React.useCallback(\n (args) => {\n if (activeId && activeId in value) {\n return closestCenter({\n ...args,\n droppableContainers: args.droppableContainers.filter((container) => container.id in value)\n });\n }\n\n const pointerIntersections = pointerWithin(args);\n const intersections = pointerIntersections.length > 0 ? pointerIntersections : rectIntersection(args);\n let overId = getFirstCollision(intersections, \"id\");\n\n if (!overId) {\n if (hasMovedRef.current) {\n lastOverIdRef.current = activeId;\n }\n return lastOverIdRef.current ? [{ id: lastOverIdRef.current }] : [];\n }\n\n if (overId in value) {\n const containerItems = value[overId];\n if (containerItems && containerItems.length > 0) {\n const closestItem = closestCenter({\n ...args,\n droppableContainers: args.droppableContainers.filter(\n (container) =>\n container.id !== overId && containerItems.some((item) => getItemValue(item) === container.id)\n )\n });\n\n if (closestItem.length > 0) {\n overId = closestItem[0]?.id ?? overId;\n }\n }\n }\n\n lastOverIdRef.current = overId;\n return [{ id: overId }];\n },\n [activeId, value, getItemValue]\n );\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n kanbanProps.onDragStart?.(event);\n\n if (isDragPrevented(event)) return;\n setActiveId(event.active.id);\n valueAtDragStartRef.current = value;\n },\n [value, kanbanProps.onDragStart]\n );\n\n const onDragOver = React.useCallback(\n (event: DragOverEvent) => {\n kanbanProps.onDragOver?.(event);\n\n if (isDragPrevented(event)) return;\n\n const { active, over } = event;\n if (!over) return;\n\n const activeColumn = getColumn(active.id);\n const overColumn = getColumn(over.id);\n\n if (!activeColumn || !overColumn) return;\n\n if (activeColumn === overColumn) {\n const items = value[activeColumn];\n if (!items) return;\n\n const activeIndex = items.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = items.findIndex((item) => getItemValue(item) === over.id);\n\n if (activeIndex !== overIndex) {\n const newColumns = { ...value };\n newColumns[activeColumn] = arrayMove(items, activeIndex, overIndex);\n onValueChange?.(newColumns);\n }\n } else {\n const activeItems = value[activeColumn];\n const overItems = value[overColumn];\n\n if (!activeItems || !overItems) return;\n\n const activeIndex = activeItems.findIndex((item) => getItemValue(item) === active.id);\n\n if (activeIndex === -1) return;\n\n const activeItem = activeItems[activeIndex];\n if (!activeItem) return;\n\n const updatedItems = {\n ...value,\n [activeColumn]: activeItems.filter((item) => getItemValue(item) !== active.id),\n [overColumn]: [...overItems, activeItem]\n };\n\n onValueChange?.(updatedItems);\n hasMovedRef.current = true;\n }\n },\n [value, getColumn, getItemValue, onValueChange, kanbanProps.onDragOver]\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n kanbanProps.onDragEnd?.(event);\n\n if (isDragPrevented(event)) return;\n\n valueAtDragStartRef.current = null;\n\n const { active, over } = event;\n\n if (!over) {\n setActiveId(null);\n return;\n }\n\n if (active.id in value && over.id in value) {\n const activeIndex = Object.keys(value).indexOf(active.id as string);\n const overIndex = Object.keys(value).indexOf(over.id as string);\n\n if (activeIndex !== overIndex) {\n const orderedColumns = Object.keys(value);\n const newOrder = arrayMove(orderedColumns, activeIndex, overIndex);\n\n const newColumns: Record<UniqueIdentifier, T[]> = {};\n for (const key of newOrder) {\n const items = value[key];\n if (items) {\n newColumns[key] = items;\n }\n }\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(newColumns);\n }\n }\n } else {\n const activeColumn = getColumn(active.id);\n const overColumn = getColumn(over.id);\n\n if (!activeColumn || !overColumn) {\n setActiveId(null);\n return;\n }\n\n if (activeColumn === overColumn) {\n const items = value[activeColumn];\n if (!items) {\n setActiveId(null);\n return;\n }\n\n const activeIndex = items.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = items.findIndex((item) => getItemValue(item) === over.id);\n\n if (activeIndex !== overIndex) {\n const newColumns = { ...value };\n newColumns[activeColumn] = arrayMove(items, activeIndex, overIndex);\n if (onMove) {\n onMove({\n ...event,\n activeIndex,\n overIndex\n });\n } else {\n onValueChange?.(newColumns);\n }\n }\n }\n }\n\n setActiveId(null);\n hasMovedRef.current = false;\n },\n [value, getColumn, getItemValue, onValueChange, onMove, kanbanProps.onDragEnd]\n );\n\n const onDragCancel = React.useCallback(\n (event: DragCancelEvent) => {\n kanbanProps.onDragCancel?.(event);\n\n if (isDragPrevented(event)) return;\n\n // Trả lại dữ liệu lúc nhấc — xem chú thích ở `valueAtDragStartRef`.\n const valueAtDragStart = valueAtDragStartRef.current;\n valueAtDragStartRef.current = null;\n if (valueAtDragStart && valueAtDragStart !== value) {\n onValueChange?.(valueAtDragStart);\n }\n\n setActiveId(null);\n hasMovedRef.current = false;\n },\n [value, onValueChange, kanbanProps.onDragCancel]\n );\n\n /*\n * ⚠ Khác thượng nguồn: câu chữ đi qua `labels` (theo ngôn ngữ, ghi đè được); phần TÍNH vị trí và\n * tổng số giữ nguyên bản gốc.\n */\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(active.id as string) + 1\n : (() => {\n const column = getColumn(active.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === active.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(active.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n return labels.pickedUp({ variant, value: active.id, position, total });\n },\n onDragOver({ active, over }) {\n if (!over) return;\n\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(over.id as string) + 1\n : (() => {\n const column = getColumn(over.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === over.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(over.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n const overColumn = getColumn(over.id);\n const activeColumn = getColumn(active.id);\n\n if (isColumn) {\n return labels.moved({ variant, value: active.id, position, total });\n }\n\n if (activeColumn !== overColumn) {\n return labels.moved({ variant, value: active.id, position, total, column: overColumn ?? undefined });\n }\n\n return labels.moved({ variant, value: active.id, position, total });\n },\n onDragEnd({ active, over }) {\n if (!over) return;\n\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(over.id as string) + 1\n : (() => {\n const column = getColumn(over.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === over.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(over.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n const overColumn = getColumn(over.id);\n const activeColumn = getColumn(active.id);\n\n if (isColumn) {\n return labels.dropped({ variant, value: active.id, position, total });\n }\n\n if (activeColumn !== overColumn) {\n return labels.dropped({ variant, value: active.id, position, total, column: overColumn ?? undefined });\n }\n\n return labels.dropped({ variant, value: active.id, position, total });\n },\n onDragCancel({ active }) {\n const isColumn = active.id in value;\n return labels.cancelled({ variant: isColumn ? \"column\" : \"item\", value: active.id });\n }\n }),\n [value, getColumn, getItemValue, labels]\n );\n\n const contextValue = React.useMemo<KanbanContextValue<T>>(\n () => ({\n id,\n items: value,\n modifiers,\n strategy,\n orientation,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n labels\n }),\n [id, value, activeId, modifiers, strategy, orientation, getItemValue, flatCursor, labels]\n );\n\n return (\n <KanbanContext.Provider value={contextValue as KanbanContextValue<unknown>}>\n <DndContext\n collisionDetection={collisionDetection}\n modifiers={modifiers}\n sensors={sensors}\n {...kanbanProps}\n id={id}\n measuring={{\n droppable: {\n strategy: MeasuringStrategy.Always\n }\n }}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDragEnd={onDragEnd}\n onDragCancel={onDragCancel}\n accessibility={{\n announcements,\n screenReaderInstructions: {\n draggable: labels.instructions\n },\n ...accessibility\n }}\n />\n </KanbanContext.Provider>\n );\n}\n\nconst KanbanBoardContext = React.createContext<boolean>(false);\n\ninterface KanbanBoardProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nfunction KanbanBoard(props: KanbanBoardProps) {\n const { asChild, className, ref, ...boardProps } = props;\n\n const context = useKanbanContext(BOARD_NAME);\n\n const columns = React.useMemo(() => {\n return Object.keys(context.items);\n }, [context.items]);\n\n const BoardPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanBoardContext.Provider value={true}>\n <SortableContext\n items={columns}\n strategy={context.orientation === \"horizontal\" ? horizontalListSortingStrategy : verticalListSortingStrategy}\n >\n <BoardPrimitive\n aria-orientation={context.orientation}\n data-orientation={context.orientation}\n data-slot=\"kanban-board\"\n {...boardProps}\n ref={ref}\n className={cn(\n \"flex size-full gap-4\",\n context.orientation === \"horizontal\" ? \"flex-row\" : \"flex-col\",\n className\n )}\n />\n </SortableContext>\n </KanbanBoardContext.Provider>\n );\n}\n\ninterface KanbanColumnContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst KanbanColumnContext = React.createContext<KanbanColumnContextValue | null>(null);\n\nfunction useKanbanColumnContext(consumerName: string) {\n const context = React.useContext(KanbanColumnContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${COLUMN_NAME}\\``);\n }\n return context;\n}\n\nconst animateLayoutChanges: AnimateLayoutChanges = (args) =>\n defaultAnimateLayoutChanges({ ...args, wasDragging: true });\n\ninterface KanbanColumnProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n children: React.ReactNode;\n asChild?: boolean;\n asHandle?: boolean;\n disabled?: boolean;\n}\n\nfunction KanbanColumn(props: KanbanColumnProps) {\n const { value, asChild, asHandle, disabled, className, style, ref, ...columnProps } = props;\n\n const id = React.useId();\n const context = useKanbanContext(COLUMN_NAME);\n const inBoard = React.useContext(KanbanBoardContext);\n const inOverlay = React.useContext(KanbanOverlayContext);\n\n if (!inBoard && !inOverlay) {\n throw new Error(`\\`${COLUMN_NAME}\\` phải nằm bên trong \\`${BOARD_NAME}\\` hoặc \\`${OVERLAY_NAME}\\``);\n }\n\n if (value === \"\") {\n throw new Error(`\\`value\\` của \\`${COLUMN_NAME}\\` không được là chuỗi rỗng`);\n }\n\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled,\n animateLayoutChanges,\n // ⚠ Khác thượng nguồn: dnd-kit mặc định đọc vai trò là \"sortable\" (tiếng Anh).\n attributes: { roleDescription: context.labels.columnRoleDescription }\n });\n\n const onNodeRefChange = React.useCallback(\n (node: HTMLElement | null) => {\n if (disabled) return;\n setNodeRef(node);\n },\n [disabled, setNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onNodeRefChange);\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Transform.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const items = React.useMemo(() => {\n const columnItems = context.items[value] ?? [];\n return columnItems.map((item) => context.getItemValue(item));\n }, [context.items, value, context.getItemValue]);\n\n const columnContext = React.useMemo<KanbanColumnContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ColumnPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanColumnContext.Provider value={columnContext}>\n <SortableContext\n items={items}\n strategy={context.orientation === \"horizontal\" ? horizontalListSortingStrategy : verticalListSortingStrategy}\n >\n <ColumnPrimitive\n id={id}\n // ⚠ Khác thượng nguồn: `disabled={false}` từng ra `data-disabled=\"false\"` — thuộc tính\n // VẪN CÓ MẶT, nên mọi selector `[data-disabled]` khớp nhầm cột đang bật.\n data-disabled={disabled ? \"\" : undefined}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"kanban-column\"\n {...columnProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: `bg-zinc-100 dark:bg-zinc-900` là thang mặc định của Tailwind\n * (cổng màu chặn) → `bg-muted`, tự lật theo theme. Khung cột là viền TRANG TRÍ (không\n * bấm được, không mang trạng thái) nên `border-border` là đúng vai trò.\n */\n \"flex size-full flex-col gap-2 rounded-lg border border-border bg-muted p-2.5 aria-disabled:pointer-events-none aria-disabled:opacity-50\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-dragging:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled,\n // ⚠ Khác thượng nguồn: bản sao trong `KanbanOverlay` được nâng lên bằng bóng nổi.\n \"shadow-overlay\": inOverlay\n },\n className\n )}\n />\n </SortableContext>\n </KanbanColumnContext.Provider>\n );\n}\n\ninterface KanbanColumnHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction KanbanColumnHandle(props: KanbanColumnHandleProps) {\n const { asChild, disabled, className, ref, ...columnHandleProps } = props;\n\n const context = useKanbanContext(COLUMN_HANDLE_NAME);\n const columnContext = useKanbanColumnContext(COLUMN_HANDLE_NAME);\n\n const isDisabled = disabled ?? columnContext.disabled;\n\n const { setActivatorNodeRef } = columnContext;\n\n const onActivatorNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (isDisabled) return;\n setActivatorNodeRef(node);\n },\n [isDisabled, setActivatorNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onActivatorNodeRef);\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n /*\n * ⚠ Khác thượng nguồn: tay cầm gần như luôn chỉ chứa một icon (GripVertical) → nút KHÔNG\n * TÊN. Tên mặc định đứng TRƯỚC `{...columnHandleProps}` nên `aria-label` của app (hoặc của\n * phần tử con khi `asChild`) vẫn thắng.\n */\n aria-label={context.labels.columnHandleLabel}\n aria-controls={columnContext.id}\n data-disabled={isDisabled ? \"\" : undefined}\n data-dragging={columnContext.isDragging ? \"\" : undefined}\n data-slot=\"kanban-column-handle\"\n {...columnHandleProps}\n {...(isDisabled ? {} : columnContext.attributes)}\n {...(isDisabled ? {} : columnContext.listeners)}\n ref={composedRef}\n className={cn(\n \"select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-dragging:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\ninterface KanbanItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst KanbanItemContext = React.createContext<KanbanItemContextValue | null>(null);\n\nfunction useKanbanItemContext(consumerName: string) {\n const context = React.useContext(KanbanItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface KanbanItemProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nfunction KanbanItem(props: KanbanItemProps) {\n const { value, style, asHandle, asChild, disabled, className, ref, ...itemProps } = props;\n\n const id = React.useId();\n const context = useKanbanContext(ITEM_NAME);\n const inBoard = React.useContext(KanbanBoardContext);\n const inOverlay = React.useContext(KanbanOverlayContext);\n\n if (!inBoard && !inOverlay) {\n throw new Error(`\\`${ITEM_NAME}\\` phải nằm bên trong \\`${BOARD_NAME}\\``);\n }\n\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled,\n // ⚠ Khác thượng nguồn: dnd-kit mặc định đọc vai trò là \"sortable\" (tiếng Anh).\n attributes: { roleDescription: context.labels.itemRoleDescription }\n });\n\n if (value === \"\") {\n throw new Error(`\\`value\\` của \\`${ITEM_NAME}\\` không được là chuỗi rỗng`);\n }\n\n // Giữ ổn định để React không gỡ rồi gắn lại ref node của dnd-kit mỗi lượt render — việc đó\n // kích hoạt đo lại vùng thả ngay giữa lúc kéo.\n const onNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (disabled) return;\n setNodeRef(node);\n },\n [disabled, setNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onNodeRef);\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Transform.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo<KanbanItemContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanItemContext.Provider value={itemContext}>\n <ItemPrimitive\n id={id}\n // ⚠ Khác thượng nguồn: xem chú thích `data-disabled` ở `KanbanColumn`.\n data-disabled={disabled ? \"\" : undefined}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"kanban-item\"\n {...itemProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n // Viền focus cùng khuôn với `Checkbox`/`RadioGroup` của gói.\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-dragging:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled,\n // ⚠ Khác thượng nguồn: bản sao trong `KanbanOverlay` được nâng lên bằng bóng nổi.\n // Bóng theo bo góc của CHÍNH phần tử — dùng `asChild` lên thẻ để bóng ôm đúng góc.\n \"shadow-overlay\": inOverlay\n },\n className\n )}\n />\n </KanbanItemContext.Provider>\n );\n}\n\ninterface KanbanItemHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction KanbanItemHandle(props: KanbanItemHandleProps) {\n const { asChild, disabled, className, ref, ...itemHandleProps } = props;\n\n const context = useKanbanContext(ITEM_HANDLE_NAME);\n const itemContext = useKanbanItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const { setActivatorNodeRef } = itemContext;\n\n const onActivatorNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (isDisabled) return;\n setActivatorNodeRef(node);\n },\n [isDisabled, setActivatorNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onActivatorNodeRef);\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n // ⚠ Khác thượng nguồn: tên mặc định cho tay cầm chỉ có icon — xem `KanbanColumnHandle`.\n aria-label={context.labels.itemHandleLabel}\n aria-controls={itemContext.id}\n data-disabled={isDisabled ? \"\" : undefined}\n data-dragging={itemContext.isDragging ? \"\" : undefined}\n data-slot=\"kanban-item-handle\"\n {...itemHandleProps}\n {...(isDisabled ? {} : itemContext.attributes)}\n {...(isDisabled ? {} : itemContext.listeners)}\n ref={composedRef}\n className={cn(\n \"select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-dragging:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\nconst KanbanOverlayContext = React.createContext(false);\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\"\n }\n }\n })\n};\n\ninterface KanbanOverlayProps extends Omit<React.ComponentProps<typeof DragOverlay>, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?: React.ReactNode | ((params: { value: UniqueIdentifier; variant: \"column\" | \"item\" }) => React.ReactNode);\n}\n\nfunction KanbanOverlay(props: KanbanOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useKanbanContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n\n // ⚠ Khác thượng nguồn: `useIsomorphicLayoutEffect` thay `React.useLayoutEffect` — an toàn khi SSR.\n useIsomorphicLayoutEffect(() => setMounted(true), []);\n\n const container = containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const variant = context.activeId && context.activeId in context.items ? \"column\" : \"item\";\n\n return ReactDOM.createPortal(\n <DragOverlay\n dropAnimation={dropAnimation}\n modifiers={context.modifiers}\n className={cn(!context.flatCursor && \"cursor-grabbing\")}\n {...overlayProps}\n >\n <KanbanOverlayContext.Provider value={true}>\n {context.activeId && children\n ? typeof children === \"function\"\n ? children({\n value: context.activeId,\n variant\n })\n : children\n : null}\n </KanbanOverlayContext.Provider>\n </DragOverlay>,\n container\n );\n}\n\nexport {\n Kanban,\n KanbanBoard,\n type KanbanBoardProps,\n KanbanColumn,\n KanbanColumnHandle,\n type KanbanColumnHandleProps,\n type KanbanColumnProps,\n KanbanItem,\n KanbanItemHandle,\n type KanbanItemHandleProps,\n type KanbanItemProps,\n KanbanOverlay,\n type KanbanOverlayProps,\n type KanbanProps\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/kanban.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/kanban) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\nimport {\n type Announcements,\n type CollisionDetection,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragCancelEvent,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n type DragOverEvent,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n type DroppableContainer,\n defaultDropAnimationSideEffects,\n getFirstCollision,\n KeyboardCode,\n type KeyboardCoordinateGetter,\n KeyboardSensor,\n MeasuringStrategy,\n MouseSensor,\n pointerWithin,\n rectIntersection,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors\n} from \"@dnd-kit/core\";\nimport {\n type AnimateLayoutChanges,\n arrayMove,\n defaultAnimateLayoutChanges,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n useSortable,\n verticalListSortingStrategy\n} from \"@dnd-kit/sortable\";\nimport { CSS, isKeyboardEvent } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { useComitorLabels } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { useComposedRefs } from \"../../lib/compose-refs.js\";\nimport { useIsomorphicLayoutEffect } from \"../../lib/use-isomorphic-layout-effect.js\";\nimport type { KanbanLabels } from \"./kanban-constants.js\";\n\nconst directions = new Set<string>([KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left]);\n\nfunction getIsDirectionCode(code: string): code is KeyboardCode {\n return directions.has(code);\n}\n\nconst coordinateGetter: KeyboardCoordinateGetter = (event, { context }) => {\n const { active, droppableRects, droppableContainers, collisionRect } = context;\n\n if (getIsDirectionCode(event.code)) {\n event.preventDefault();\n\n if (!active || !collisionRect) return;\n\n const filteredContainers: DroppableContainer[] = [];\n\n /*\n * ⚠ Khác thượng nguồn: `continue` chứ không `return`. Vòng lặp này chép từ ví dụ \"multiple\n * containers\" của dnd-kit, nơi nó là `forEach` — ở đó `return` nghĩa là BỎ QUA MỘT mục. Bản\n * gốc đổi sang `for…of` nhưng giữ `return`, nên chỉ cần MỘT vùng thả chưa đo được rect là\n * cả hàm trả `undefined` và phím mũi tên không di chuyển được gì nữa.\n */\n for (const entry of droppableContainers.getEnabled()) {\n if (!entry || entry?.disabled) continue;\n\n const rect = droppableRects.get(entry.id);\n\n if (!rect) continue;\n\n const data = entry.data.current;\n\n if (data) {\n const { type, children } = data;\n\n if (type === \"container\" && children?.length > 0) {\n if (active.data.current?.type !== \"container\") {\n continue;\n }\n }\n }\n\n switch (event.code) {\n case KeyboardCode.Down:\n if (collisionRect.top < rect.top) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Up:\n if (collisionRect.top > rect.top) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Left:\n if (collisionRect.left >= rect.left + rect.width) {\n filteredContainers.push(entry);\n }\n break;\n case KeyboardCode.Right:\n if (collisionRect.left + collisionRect.width <= rect.left) {\n filteredContainers.push(entry);\n }\n break;\n }\n }\n\n const collisions = closestCorners({\n active,\n collisionRect: collisionRect,\n droppableRects,\n droppableContainers: filteredContainers,\n pointerCoordinates: null\n });\n const closestId = getFirstCollision(collisions, \"id\");\n\n if (closestId != null) {\n const newDroppable = droppableContainers.get(closestId);\n const newNode = newDroppable?.node.current;\n const newRect = newDroppable?.rect.current;\n\n if (newNode && newRect) {\n if (newDroppable.id === \"placeholder\") {\n return {\n x: newRect.left + (newRect.width - collisionRect.width) / 2,\n y: newRect.top + (newRect.height - collisionRect.height) / 2\n };\n }\n\n if (newDroppable.data.current?.type === \"container\") {\n return {\n x: newRect.left + 20,\n y: newRect.top + 74\n };\n }\n\n return {\n x: newRect.left,\n y: newRect.top\n };\n }\n }\n }\n\n return undefined;\n};\n\n/*\n * ⚠ Khác thượng nguồn: bản gốc bỏ qua MỌI thao tác khi `event.activatorEvent.defaultPrevented`\n * — một lối để app huỷ kéo bằng cách gọi `preventDefault()` trong `onDragStart` của mình. Nhưng\n * `KeyboardSensor` của dnd-kit TỰ gọi `preventDefault()` lên chính phím Space/Enter kích hoạt\n * (để trang không cuộn), và `activatorEvent` là đúng event đó. Hệ quả ở bản gốc: kéo bằng bàn\n * phím nhấc được thẻ nhưng `activeId` không bao giờ được gán, `onDragOver`/`onDragEnd` đều\n * thoát sớm — thả xong thẻ vẫn nằm nguyên chỗ cũ. Đã đo trên trình duyệt thật với phím thật:\n * Space → ArrowRight → Space, vùng `aria-live` đọc \"item was dropped at position 1 of 2 in\n * doing\" trong khi `onValueChange` KHÔNG được gọi lần nào — trình đọc màn hình báo đã thả, dữ\n * liệu không đổi. Lối huỷ bằng `preventDefault()` vì thế chỉ còn hiệu lực với chuột/cảm ứng;\n * với bàn phím, dùng `cancelDrop` của dnd-kit.\n */\nfunction isDragPrevented(event: { activatorEvent: Event }) {\n return event.activatorEvent.defaultPrevented && !isKeyboardEvent(event.activatorEvent);\n}\n\nconst ROOT_NAME = \"Kanban\";\nconst BOARD_NAME = \"KanbanBoard\";\nconst COLUMN_NAME = \"KanbanColumn\";\nconst COLUMN_HANDLE_NAME = \"KanbanColumnHandle\";\nconst ITEM_NAME = \"KanbanItem\";\nconst ITEM_HANDLE_NAME = \"KanbanItemHandle\";\nconst OVERLAY_NAME = \"KanbanOverlay\";\n\ninterface KanbanContextValue<T> {\n id: string;\n items: Record<UniqueIdentifier, T[]>;\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n orientation: \"horizontal\" | \"vertical\";\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n labels: KanbanLabels;\n}\n\nconst KanbanContext = React.createContext<KanbanContextValue<unknown> | null>(null);\n\nfunction useKanbanContext(consumerName: string) {\n const context = React.useContext(KanbanContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue<T> {\n /**\n * Trả về định danh duy nhất của mỗi thẻ. BẮT BUỘC khi thẻ là object.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype KanbanProps<T> = Omit<DndContextProps, \"collisionDetection\"> &\n (T extends object ? GetItemValue<T> : Partial<GetItemValue<T>>) & {\n value: Record<UniqueIdentifier, T[]>;\n onValueChange?: (columns: Record<UniqueIdentifier, T[]>) => void;\n onMove?: (event: DragEndEvent & { activeIndex: number; overIndex: number }) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"horizontal\" | \"vertical\";\n flatCursor?: boolean;\n /**\n * Lời xướng cho trình đọc màn hình, hướng dẫn bàn phím và tên tay cầm kéo — ghi đè TỪNG khoá.\n * Không truyền thì theo namespace `kanban` của `ComitorLocaleProvider` (mặc định tiếng Anh).\n *\n * ⚠ Thêm so với thượng nguồn: bản gốc chôn cứng câu tiếng Anh (\"Picked up item at position\n * 2 of 5\") trong component; chỉ đổi được bằng cách viết lại cả `accessibility.announcements`,\n * tức tự tính lại vị trí/tổng số. Ở đây các hàm nhận sẵn `{ variant, value, position, total,\n * column }`. `accessibility` truyền thẳng vẫn được tôn trọng và THẮNG `labels`.\n */\n labels?: Partial<KanbanLabels>;\n };\n\nfunction Kanban<T>(props: KanbanProps<T>) {\n const {\n value,\n onValueChange,\n modifiers,\n strategy = verticalListSortingStrategy,\n orientation = \"horizontal\",\n onMove,\n getItemValue: getItemValueProp,\n accessibility,\n flatCursor = false,\n labels: labelsProp,\n ...kanbanProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState<UniqueIdentifier | null>(null);\n const lastOverIdRef = React.useRef<UniqueIdentifier | null>(null);\n const hasMovedRef = React.useRef(false);\n /*\n * ⚠ Khác thượng nguồn: `onDragOver` ghi thẳng mỗi lần đổi chỗ ra `onValueChange` (kéo tới\n * đâu, dữ liệu đổi tới đó), nên bản gốc huỷ bằng Escape KHÔNG trả thẻ về chỗ cũ — trái với\n * chính hướng dẫn bàn phím nó đọc cho người dùng (\"press escape to cancel\"). Chụp giá trị lúc\n * nhấc để `onDragCancel` trả lại, đúng như ví dụ \"multiple containers\" gốc của dnd-kit.\n */\n const valueAtDragStartRef = React.useRef<Record<UniqueIdentifier, T[]> | null>(null);\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter\n })\n );\n\n const labels = useComitorLabels(\"kanban\", labelsProp);\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"`getItemValue` là bắt buộc khi thẻ là object\");\n }\n return getItemValueProp ? getItemValueProp(item) : (item as UniqueIdentifier);\n },\n [getItemValueProp]\n );\n\n const getColumn = React.useCallback(\n (targetId: UniqueIdentifier) => {\n if (targetId in value) return targetId;\n\n for (const [columnId, columnItems] of Object.entries(value)) {\n if (columnItems.some((item) => getItemValue(item) === targetId)) {\n return columnId;\n }\n }\n\n return null;\n },\n [value, getItemValue]\n );\n\n const collisionDetection: CollisionDetection = React.useCallback(\n (args) => {\n if (activeId && activeId in value) {\n return closestCenter({\n ...args,\n droppableContainers: args.droppableContainers.filter((container) => container.id in value)\n });\n }\n\n const pointerIntersections = pointerWithin(args);\n const intersections = pointerIntersections.length > 0 ? pointerIntersections : rectIntersection(args);\n let overId = getFirstCollision(intersections, \"id\");\n\n if (!overId) {\n if (hasMovedRef.current) {\n lastOverIdRef.current = activeId;\n }\n return lastOverIdRef.current ? [{ id: lastOverIdRef.current }] : [];\n }\n\n if (overId in value) {\n const containerItems = value[overId];\n if (containerItems && containerItems.length > 0) {\n const closestItem = closestCenter({\n ...args,\n droppableContainers: args.droppableContainers.filter(\n (container) =>\n container.id !== overId && containerItems.some((item) => getItemValue(item) === container.id)\n )\n });\n\n if (closestItem.length > 0) {\n overId = closestItem[0]?.id ?? overId;\n }\n }\n }\n\n lastOverIdRef.current = overId;\n return [{ id: overId }];\n },\n [activeId, value, getItemValue]\n );\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n kanbanProps.onDragStart?.(event);\n\n if (isDragPrevented(event)) return;\n setActiveId(event.active.id);\n valueAtDragStartRef.current = value;\n },\n [value, kanbanProps.onDragStart]\n );\n\n const onDragOver = React.useCallback(\n (event: DragOverEvent) => {\n kanbanProps.onDragOver?.(event);\n\n if (isDragPrevented(event)) return;\n\n const { active, over } = event;\n if (!over) return;\n\n const activeColumn = getColumn(active.id);\n const overColumn = getColumn(over.id);\n\n if (!activeColumn || !overColumn) return;\n\n if (activeColumn === overColumn) {\n const items = value[activeColumn];\n if (!items) return;\n\n const activeIndex = items.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = items.findIndex((item) => getItemValue(item) === over.id);\n\n if (activeIndex !== overIndex) {\n const newColumns = { ...value };\n newColumns[activeColumn] = arrayMove(items, activeIndex, overIndex);\n onValueChange?.(newColumns);\n }\n } else {\n const activeItems = value[activeColumn];\n const overItems = value[overColumn];\n\n if (!activeItems || !overItems) return;\n\n const activeIndex = activeItems.findIndex((item) => getItemValue(item) === active.id);\n\n if (activeIndex === -1) return;\n\n const activeItem = activeItems[activeIndex];\n if (!activeItem) return;\n\n const updatedItems = {\n ...value,\n [activeColumn]: activeItems.filter((item) => getItemValue(item) !== active.id),\n [overColumn]: [...overItems, activeItem]\n };\n\n onValueChange?.(updatedItems);\n hasMovedRef.current = true;\n }\n },\n [value, getColumn, getItemValue, onValueChange, kanbanProps.onDragOver]\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n kanbanProps.onDragEnd?.(event);\n\n if (isDragPrevented(event)) return;\n\n valueAtDragStartRef.current = null;\n\n const { active, over } = event;\n\n if (!over) {\n setActiveId(null);\n return;\n }\n\n if (active.id in value && over.id in value) {\n const activeIndex = Object.keys(value).indexOf(active.id as string);\n const overIndex = Object.keys(value).indexOf(over.id as string);\n\n if (activeIndex !== overIndex) {\n const orderedColumns = Object.keys(value);\n const newOrder = arrayMove(orderedColumns, activeIndex, overIndex);\n\n const newColumns: Record<UniqueIdentifier, T[]> = {};\n for (const key of newOrder) {\n const items = value[key];\n if (items) {\n newColumns[key] = items;\n }\n }\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(newColumns);\n }\n }\n } else {\n const activeColumn = getColumn(active.id);\n const overColumn = getColumn(over.id);\n\n if (!activeColumn || !overColumn) {\n setActiveId(null);\n return;\n }\n\n if (activeColumn === overColumn) {\n const items = value[activeColumn];\n if (!items) {\n setActiveId(null);\n return;\n }\n\n const activeIndex = items.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = items.findIndex((item) => getItemValue(item) === over.id);\n\n if (activeIndex !== overIndex) {\n const newColumns = { ...value };\n newColumns[activeColumn] = arrayMove(items, activeIndex, overIndex);\n if (onMove) {\n onMove({\n ...event,\n activeIndex,\n overIndex\n });\n } else {\n onValueChange?.(newColumns);\n }\n }\n }\n }\n\n setActiveId(null);\n hasMovedRef.current = false;\n },\n [value, getColumn, getItemValue, onValueChange, onMove, kanbanProps.onDragEnd]\n );\n\n const onDragCancel = React.useCallback(\n (event: DragCancelEvent) => {\n kanbanProps.onDragCancel?.(event);\n\n if (isDragPrevented(event)) return;\n\n // Trả lại dữ liệu lúc nhấc — xem chú thích ở `valueAtDragStartRef`.\n const valueAtDragStart = valueAtDragStartRef.current;\n valueAtDragStartRef.current = null;\n if (valueAtDragStart && valueAtDragStart !== value) {\n onValueChange?.(valueAtDragStart);\n }\n\n setActiveId(null);\n hasMovedRef.current = false;\n },\n [value, onValueChange, kanbanProps.onDragCancel]\n );\n\n /*\n * ⚠ Khác thượng nguồn: câu chữ đi qua `labels` (theo ngôn ngữ, ghi đè được); phần TÍNH vị trí và\n * tổng số giữ nguyên bản gốc.\n */\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(active.id as string) + 1\n : (() => {\n const column = getColumn(active.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === active.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(active.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n return labels.pickedUp({ variant, value: active.id, position, total });\n },\n onDragOver({ active, over }) {\n if (!over) return;\n\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(over.id as string) + 1\n : (() => {\n const column = getColumn(over.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === over.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(over.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n const overColumn = getColumn(over.id);\n const activeColumn = getColumn(active.id);\n\n if (isColumn) {\n return labels.moved({ variant, value: active.id, position, total });\n }\n\n if (activeColumn !== overColumn) {\n return labels.moved({ variant, value: active.id, position, total, column: overColumn ?? undefined });\n }\n\n return labels.moved({ variant, value: active.id, position, total });\n },\n onDragEnd({ active, over }) {\n if (!over) return;\n\n const isColumn = active.id in value;\n const variant = isColumn ? \"column\" : \"item\";\n const position = isColumn\n ? Object.keys(value).indexOf(over.id as string) + 1\n : (() => {\n const column = getColumn(over.id);\n if (!column || !value[column]) return 1;\n return value[column].findIndex((item) => getItemValue(item) === over.id) + 1;\n })();\n const total = isColumn\n ? Object.keys(value).length\n : (() => {\n const column = getColumn(over.id);\n return column ? (value[column]?.length ?? 0) : 0;\n })();\n\n const overColumn = getColumn(over.id);\n const activeColumn = getColumn(active.id);\n\n if (isColumn) {\n return labels.dropped({ variant, value: active.id, position, total });\n }\n\n if (activeColumn !== overColumn) {\n return labels.dropped({ variant, value: active.id, position, total, column: overColumn ?? undefined });\n }\n\n return labels.dropped({ variant, value: active.id, position, total });\n },\n onDragCancel({ active }) {\n const isColumn = active.id in value;\n return labels.cancelled({ variant: isColumn ? \"column\" : \"item\", value: active.id });\n }\n }),\n [value, getColumn, getItemValue, labels]\n );\n\n const contextValue = React.useMemo<KanbanContextValue<T>>(\n () => ({\n id,\n items: value,\n modifiers,\n strategy,\n orientation,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor,\n labels\n }),\n [id, value, activeId, modifiers, strategy, orientation, getItemValue, flatCursor, labels]\n );\n\n return (\n <KanbanContext.Provider value={contextValue as KanbanContextValue<unknown>}>\n <DndContext\n collisionDetection={collisionDetection}\n modifiers={modifiers}\n sensors={sensors}\n {...kanbanProps}\n id={id}\n measuring={{\n droppable: {\n strategy: MeasuringStrategy.Always\n }\n }}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDragEnd={onDragEnd}\n onDragCancel={onDragCancel}\n accessibility={{\n announcements,\n screenReaderInstructions: {\n draggable: labels.instructions\n },\n ...accessibility\n }}\n />\n </KanbanContext.Provider>\n );\n}\n\nconst KanbanBoardContext = React.createContext<boolean>(false);\n\ninterface KanbanBoardProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nfunction KanbanBoard(props: KanbanBoardProps) {\n const { asChild, className, ref, ...boardProps } = props;\n\n const context = useKanbanContext(BOARD_NAME);\n\n const columns = React.useMemo(() => {\n return Object.keys(context.items);\n }, [context.items]);\n\n const BoardPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanBoardContext.Provider value={true}>\n <SortableContext\n items={columns}\n strategy={context.orientation === \"horizontal\" ? horizontalListSortingStrategy : verticalListSortingStrategy}\n >\n {/*\n * ⚠ Khác thượng nguồn (3.0.1): bỏ `aria-orientation`. Thuộc tính đó chỉ hợp lệ trên vài vai trò\n * (listbox, tablist, toolbar, scrollbar…), còn bảng là một `<div>` KHÔNG vai trò — axe báo\n * \"ARIA attribute is not allowed\", và trình đọc màn hình bỏ qua nó. `2.1.0` đã gỡ đúng lỗi\n * này khỏi `Timeline`, sót ở đây. Hướng vẫn có ở `data-orientation` cho CSS.\n */}\n <BoardPrimitive\n data-orientation={context.orientation}\n data-slot=\"kanban-board\"\n {...boardProps}\n ref={ref}\n className={cn(\n \"flex size-full gap-4\",\n context.orientation === \"horizontal\" ? \"flex-row\" : \"flex-col\",\n className\n )}\n />\n </SortableContext>\n </KanbanBoardContext.Provider>\n );\n}\n\ninterface KanbanColumnContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst KanbanColumnContext = React.createContext<KanbanColumnContextValue | null>(null);\n\nfunction useKanbanColumnContext(consumerName: string) {\n const context = React.useContext(KanbanColumnContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${COLUMN_NAME}\\``);\n }\n return context;\n}\n\nconst animateLayoutChanges: AnimateLayoutChanges = (args) =>\n defaultAnimateLayoutChanges({ ...args, wasDragging: true });\n\ninterface KanbanColumnProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n children: React.ReactNode;\n asChild?: boolean;\n asHandle?: boolean;\n disabled?: boolean;\n}\n\nfunction KanbanColumn(props: KanbanColumnProps) {\n const { value, asChild, asHandle, disabled, className, style, ref, ...columnProps } = props;\n\n const id = React.useId();\n const context = useKanbanContext(COLUMN_NAME);\n const inBoard = React.useContext(KanbanBoardContext);\n const inOverlay = React.useContext(KanbanOverlayContext);\n\n if (!inBoard && !inOverlay) {\n throw new Error(`\\`${COLUMN_NAME}\\` phải nằm bên trong \\`${BOARD_NAME}\\` hoặc \\`${OVERLAY_NAME}\\``);\n }\n\n if (value === \"\") {\n throw new Error(`\\`value\\` của \\`${COLUMN_NAME}\\` không được là chuỗi rỗng`);\n }\n\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled,\n animateLayoutChanges,\n // ⚠ Khác thượng nguồn: dnd-kit mặc định đọc vai trò là \"sortable\" (tiếng Anh).\n attributes: { roleDescription: context.labels.columnRoleDescription }\n });\n\n const onNodeRefChange = React.useCallback(\n (node: HTMLElement | null) => {\n if (disabled) return;\n setNodeRef(node);\n },\n [disabled, setNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onNodeRefChange);\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Transform.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const items = React.useMemo(() => {\n const columnItems = context.items[value] ?? [];\n return columnItems.map((item) => context.getItemValue(item));\n }, [context.items, value, context.getItemValue]);\n\n const columnContext = React.useMemo<KanbanColumnContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ColumnPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanColumnContext.Provider value={columnContext}>\n <SortableContext\n items={items}\n strategy={context.orientation === \"horizontal\" ? horizontalListSortingStrategy : verticalListSortingStrategy}\n >\n <ColumnPrimitive\n id={id}\n // ⚠ Khác thượng nguồn: `disabled={false}` từng ra `data-disabled=\"false\"` — thuộc tính\n // VẪN CÓ MẶT, nên mọi selector `[data-disabled]` khớp nhầm cột đang bật.\n data-disabled={disabled ? \"\" : undefined}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"kanban-column\"\n {...columnProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: `bg-zinc-100 dark:bg-zinc-900` là thang mặc định của Tailwind\n * (cổng màu chặn) → `bg-muted`, tự lật theo theme. Khung cột là viền TRANG TRÍ (không\n * bấm được, không mang trạng thái) nên `border-border` là đúng vai trò.\n */\n \"flex size-full flex-col gap-2 rounded-lg border border-border bg-muted p-2.5 aria-disabled:pointer-events-none aria-disabled:opacity-50\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-dragging:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled,\n // ⚠ Khác thượng nguồn: bản sao trong `KanbanOverlay` được nâng lên bằng bóng nổi.\n \"shadow-overlay\": inOverlay\n },\n className\n )}\n />\n </SortableContext>\n </KanbanColumnContext.Provider>\n );\n}\n\ninterface KanbanColumnHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction KanbanColumnHandle(props: KanbanColumnHandleProps) {\n const { asChild, disabled, className, ref, ...columnHandleProps } = props;\n\n const context = useKanbanContext(COLUMN_HANDLE_NAME);\n const columnContext = useKanbanColumnContext(COLUMN_HANDLE_NAME);\n\n const isDisabled = disabled ?? columnContext.disabled;\n\n const { setActivatorNodeRef } = columnContext;\n\n const onActivatorNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (isDisabled) return;\n setActivatorNodeRef(node);\n },\n [isDisabled, setActivatorNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onActivatorNodeRef);\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n /*\n * ⚠ Khác thượng nguồn: tay cầm gần như luôn chỉ chứa một icon (GripVertical) → nút KHÔNG\n * TÊN. Tên mặc định đứng TRƯỚC `{...columnHandleProps}` nên `aria-label` của app (hoặc của\n * phần tử con khi `asChild`) vẫn thắng.\n */\n aria-label={context.labels.columnHandleLabel}\n aria-controls={columnContext.id}\n data-disabled={isDisabled ? \"\" : undefined}\n data-dragging={columnContext.isDragging ? \"\" : undefined}\n data-slot=\"kanban-column-handle\"\n {...columnHandleProps}\n {...(isDisabled ? {} : columnContext.attributes)}\n {...(isDisabled ? {} : columnContext.listeners)}\n ref={composedRef}\n className={cn(\n // `touch-none`: xem `KanbanItemHandle`.\n \"touch-none select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-dragging:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\ninterface KanbanItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst KanbanItemContext = React.createContext<KanbanItemContextValue | null>(null);\n\nfunction useKanbanItemContext(consumerName: string) {\n const context = React.useContext(KanbanItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` phải nằm bên trong \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface KanbanItemProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nfunction KanbanItem(props: KanbanItemProps) {\n const { value, style, asHandle, asChild, disabled, className, ref, ...itemProps } = props;\n\n const id = React.useId();\n const context = useKanbanContext(ITEM_NAME);\n const inBoard = React.useContext(KanbanBoardContext);\n const inOverlay = React.useContext(KanbanOverlayContext);\n\n if (!inBoard && !inOverlay) {\n throw new Error(`\\`${ITEM_NAME}\\` phải nằm bên trong \\`${BOARD_NAME}\\``);\n }\n\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled,\n // ⚠ Khác thượng nguồn: dnd-kit mặc định đọc vai trò là \"sortable\" (tiếng Anh).\n attributes: { roleDescription: context.labels.itemRoleDescription }\n });\n\n if (value === \"\") {\n throw new Error(`\\`value\\` của \\`${ITEM_NAME}\\` không được là chuỗi rỗng`);\n }\n\n // Giữ ổn định để React không gỡ rồi gắn lại ref node của dnd-kit mỗi lượt render — việc đó\n // kích hoạt đo lại vùng thả ngay giữa lúc kéo.\n const onNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (disabled) return;\n setNodeRef(node);\n },\n [disabled, setNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onNodeRef);\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Transform.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo<KanbanItemContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n <KanbanItemContext.Provider value={itemContext}>\n <ItemPrimitive\n id={id}\n // ⚠ Khác thượng nguồn: xem chú thích `data-disabled` ở `KanbanColumn`.\n data-disabled={disabled ? \"\" : undefined}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"kanban-item\"\n {...itemProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n // Viền focus cùng khuôn với `Checkbox`/`RadioGroup` của gói.\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-dragging:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled,\n // ⚠ Khác thượng nguồn: bản sao trong `KanbanOverlay` được nâng lên bằng bóng nổi.\n // Bóng theo bo góc của CHÍNH phần tử — dùng `asChild` lên thẻ để bóng ôm đúng góc.\n \"shadow-overlay\": inOverlay\n },\n className\n )}\n />\n </KanbanItemContext.Provider>\n );\n}\n\ninterface KanbanItemHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction KanbanItemHandle(props: KanbanItemHandleProps) {\n const { asChild, disabled, className, ref, ...itemHandleProps } = props;\n\n const context = useKanbanContext(ITEM_HANDLE_NAME);\n const itemContext = useKanbanItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const { setActivatorNodeRef } = itemContext;\n\n const onActivatorNodeRef = React.useCallback(\n (node: HTMLElement | null) => {\n if (isDisabled) return;\n setActivatorNodeRef(node);\n },\n [isDisabled, setActivatorNodeRef]\n );\n\n const composedRef = useComposedRefs(ref, onActivatorNodeRef);\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n // ⚠ Khác thượng nguồn: tên mặc định cho tay cầm chỉ có icon — xem `KanbanColumnHandle`.\n aria-label={context.labels.itemHandleLabel}\n aria-controls={itemContext.id}\n data-disabled={isDisabled ? \"\" : undefined}\n data-dragging={itemContext.isDragging ? \"\" : undefined}\n data-slot=\"kanban-item-handle\"\n {...itemHandleProps}\n {...(isDisabled ? {} : itemContext.attributes)}\n {...(isDisabled ? {} : itemContext.listeners)}\n ref={composedRef}\n className={cn(\n /*\n * ⚠ Khác thượng nguồn (3.0.1): `touch-none` trên tay cầm. `KanbanItem asHandle` (cả thẻ là tay\n * cầm) đã có nó, tay cầm RỜI thì không — trên màn cảm ứng, vuốt bắt đầu từ tay cầm bị trình\n * duyệt nhận làm cuộn trang, cảm biến chạm của dnd-kit mất sự kiện và thẻ không nhấc lên.\n * Trang Patterns của comitor-ds từng phải tự thêm lớp này cho từng tay cầm.\n */\n \"touch-none select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-dragging:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\nconst KanbanOverlayContext = React.createContext(false);\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\"\n }\n }\n })\n};\n\ninterface KanbanOverlayProps extends Omit<React.ComponentProps<typeof DragOverlay>, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?: React.ReactNode | ((params: { value: UniqueIdentifier; variant: \"column\" | \"item\" }) => React.ReactNode);\n}\n\nfunction KanbanOverlay(props: KanbanOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useKanbanContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n\n // ⚠ Khác thượng nguồn: `useIsomorphicLayoutEffect` thay `React.useLayoutEffect` — an toàn khi SSR.\n useIsomorphicLayoutEffect(() => setMounted(true), []);\n\n const container = containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const variant = context.activeId && context.activeId in context.items ? \"column\" : \"item\";\n\n return ReactDOM.createPortal(\n <DragOverlay\n dropAnimation={dropAnimation}\n modifiers={context.modifiers}\n className={cn(!context.flatCursor && \"cursor-grabbing\")}\n {...overlayProps}\n >\n <KanbanOverlayContext.Provider value={true}>\n {context.activeId && children\n ? typeof children === \"function\"\n ? children({\n value: context.activeId,\n variant\n })\n : children\n : null}\n </KanbanOverlayContext.Provider>\n </DragOverlay>,\n container\n );\n}\n\nexport {\n Kanban,\n KanbanBoard,\n type KanbanBoardProps,\n KanbanColumn,\n KanbanColumnHandle,\n type KanbanColumnHandleProps,\n type KanbanColumnProps,\n KanbanItem,\n KanbanItemHandle,\n type KanbanItemHandleProps,\n type KanbanItemProps,\n KanbanOverlay,\n type KanbanOverlayProps,\n type KanbanProps\n};\n"],"mappings":"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","names":[]}
@@ -65,6 +65,42 @@ function useKeyValueContext(consumerName) {
65
65
  }
66
66
  return context;
67
67
  }
68
+ function commitItemField(store, context, itemId, field, text) {
69
+ const state = store.getState();
70
+ const newValue = state.value.map((item) => item.id === itemId ? { ...item, [field]: text } : item);
71
+ store.setState("value", newValue);
72
+ const updatedItemData = newValue.find((item) => item.id === itemId);
73
+ if (!updatedItemData) return;
74
+ const errors = {};
75
+ if (context.onKeyValidate) {
76
+ const keyError = context.onKeyValidate(updatedItemData.key, newValue);
77
+ if (keyError) errors.key = keyError;
78
+ }
79
+ if (!context.allowDuplicateKeys) {
80
+ const duplicateKey = newValue.find(
81
+ (item) => item.id !== updatedItemData.id && item.key === updatedItemData.key && updatedItemData.key !== ""
82
+ );
83
+ if (duplicateKey) {
84
+ errors.key = context.labels.duplicateKey;
85
+ }
86
+ }
87
+ if (context.onValueValidate) {
88
+ const valueError = context.onValueValidate(updatedItemData.value, updatedItemData.key, newValue);
89
+ if (valueError) errors.value = valueError;
90
+ }
91
+ const newErrorsState = { ...state.errors };
92
+ if (Object.keys(errors).length > 0) {
93
+ newErrorsState[itemId] = errors;
94
+ } else {
95
+ delete newErrorsState[itemId];
96
+ }
97
+ store.setState("errors", newErrorsState);
98
+ }
99
+ function useTrimDraft(committed) {
100
+ const [draft, setDraft] = React.useState(null);
101
+ const shown = draft !== null && draft.trim() === committed ? draft : committed;
102
+ return [shown, setDraft];
103
+ }
68
104
  function KeyValue(props) {
69
105
  const {
70
106
  value: valueProp,
@@ -258,6 +294,7 @@ function KeyValueItem(props) {
258
294
  function KeyValueKeyInput(props) {
259
295
  const {
260
296
  onChange: onChangeProp,
297
+ onBlur: onBlurProp,
261
298
  onPaste: onPasteProp,
262
299
  asChild,
263
300
  disabled,
@@ -280,52 +317,29 @@ function KeyValueKeyInput(props) {
280
317
  }, [focusedId, itemData.id]);
281
318
  const propsRef = useAsRef({
282
319
  onChange: onChangeProp,
320
+ onBlur: onBlurProp,
283
321
  onPaste: onPasteProp
284
322
  });
285
323
  const isDisabled = disabled || context.disabled;
286
324
  const isReadOnly = readOnly || context.readOnly;
287
325
  const isRequired = required || context.required;
288
326
  const isInvalid = errors[itemData.id]?.key !== void 0;
327
+ const [shownKey, setKeyDraft] = useTrimDraft(itemData.key);
289
328
  const onChange = React.useCallback(
290
329
  (event) => {
291
- const state = store.getState();
292
- const newValue = state.value.map((item) => {
293
- if (item.id !== itemData.id) return item;
294
- const updated = { ...item, key: event.target.value };
295
- if (context.trim) updated.key = updated.key.trim();
296
- return updated;
297
- });
298
- store.setState("value", newValue);
299
- const updatedItemData = newValue.find((item) => item.id === itemData.id);
300
- if (updatedItemData) {
301
- const errors2 = {};
302
- if (context.onKeyValidate) {
303
- const keyError = context.onKeyValidate(updatedItemData.key, newValue);
304
- if (keyError) errors2.key = keyError;
305
- }
306
- if (!context.allowDuplicateKeys) {
307
- const duplicateKey = newValue.find(
308
- (item) => item.id !== updatedItemData.id && item.key === updatedItemData.key && updatedItemData.key !== ""
309
- );
310
- if (duplicateKey) {
311
- errors2.key = context.labels.duplicateKey;
312
- }
313
- }
314
- if (context.onValueValidate) {
315
- const valueError = context.onValueValidate(updatedItemData.value, updatedItemData.key, newValue);
316
- if (valueError) errors2.value = valueError;
317
- }
318
- const newErrorsState = { ...state.errors };
319
- if (Object.keys(errors2).length > 0) {
320
- newErrorsState[itemData.id] = errors2;
321
- } else {
322
- delete newErrorsState[itemData.id];
323
- }
324
- store.setState("errors", newErrorsState);
325
- }
330
+ const text = event.target.value;
331
+ if (context.trim) setKeyDraft(text);
332
+ commitItemField(store, context, itemData.id, "key", context.trim ? text.trim() : text);
326
333
  propsRef.current.onChange?.(event);
327
334
  },
328
- [store, itemData.id, context, propsRef]
335
+ [store, itemData.id, context, propsRef, setKeyDraft]
336
+ );
337
+ const onBlur = React.useCallback(
338
+ (event) => {
339
+ propsRef.current.onBlur?.(event);
340
+ setKeyDraft(null);
341
+ },
342
+ [propsRef, setKeyDraft]
329
343
  );
330
344
  const onPaste = React.useCallback(
331
345
  (event) => {
@@ -395,8 +409,9 @@ function KeyValueKeyInput(props) {
395
409
  placeholder: context.keyPlaceholder,
396
410
  ...keyInputProps,
397
411
  ref: composedRef,
398
- value: itemData.key,
412
+ value: shownKey,
399
413
  onChange,
414
+ onBlur,
400
415
  onPaste
401
416
  }
402
417
  );
@@ -404,6 +419,7 @@ function KeyValueKeyInput(props) {
404
419
  function KeyValueValueInput(props) {
405
420
  const {
406
421
  onChange: onChangeProp,
422
+ onBlur: onBlurProp,
407
423
  asChild,
408
424
  disabled,
409
425
  readOnly,
@@ -418,53 +434,30 @@ function KeyValueValueInput(props) {
418
434
  const store = useStoreContext(VALUE_INPUT_NAME);
419
435
  const errors = useStore((state) => state.errors);
420
436
  const propsRef = useAsRef({
421
- onChange: onChangeProp
437
+ onChange: onChangeProp,
438
+ onBlur: onBlurProp
422
439
  });
423
440
  const isDisabled = disabled || context.disabled;
424
441
  const isReadOnly = readOnly || context.readOnly;
425
442
  const isRequired = required || context.required;
426
443
  const isInvalid = errors[itemData.id]?.value !== void 0;
427
444
  const maxHeight = maxRows ? `calc(${maxRows} * 1.5em + 1rem)` : void 0;
445
+ const [shownValue, setValueDraft] = useTrimDraft(itemData.value);
428
446
  const onChange = React.useCallback(
429
447
  (event) => {
430
448
  propsRef.current.onChange?.(event);
431
- const state = store.getState();
432
- const newValue = state.value.map((item) => {
433
- if (item.id !== itemData.id) return item;
434
- const updated = { ...item, value: event.target.value };
435
- if (context.trim) updated.value = updated.value.trim();
436
- return updated;
437
- });
438
- store.setState("value", newValue);
439
- const updatedItemData = newValue.find((item) => item.id === itemData.id);
440
- if (updatedItemData) {
441
- const errors2 = {};
442
- if (context.onKeyValidate) {
443
- const keyError = context.onKeyValidate(updatedItemData.key, newValue);
444
- if (keyError) errors2.key = keyError;
445
- }
446
- if (!context.allowDuplicateKeys) {
447
- const duplicateKey = newValue.find(
448
- (item) => item.id !== updatedItemData.id && item.key === updatedItemData.key && updatedItemData.key !== ""
449
- );
450
- if (duplicateKey) {
451
- errors2.key = context.labels.duplicateKey;
452
- }
453
- }
454
- if (context.onValueValidate) {
455
- const valueError = context.onValueValidate(updatedItemData.value, updatedItemData.key, newValue);
456
- if (valueError) errors2.value = valueError;
457
- }
458
- const newErrorsState = { ...state.errors };
459
- if (Object.keys(errors2).length > 0) {
460
- newErrorsState[itemData.id] = errors2;
461
- } else {
462
- delete newErrorsState[itemData.id];
463
- }
464
- store.setState("errors", newErrorsState);
465
- }
449
+ const text = event.target.value;
450
+ if (context.trim) setValueDraft(text);
451
+ commitItemField(store, context, itemData.id, "value", context.trim ? text.trim() : text);
466
452
  },
467
- [store, itemData.id, context, propsRef]
453
+ [store, itemData.id, context, propsRef, setValueDraft]
454
+ );
455
+ const onBlur = React.useCallback(
456
+ (event) => {
457
+ propsRef.current.onBlur?.(event);
458
+ setValueDraft(null);
459
+ },
460
+ [propsRef, setValueDraft]
468
461
  );
469
462
  const ValueInputPrimitive = asChild ? Slot : Textarea;
470
463
  return /* @__PURE__ */ jsx(
@@ -500,8 +493,9 @@ function KeyValueValueInput(props) {
500
493
  ...style,
501
494
  ...maxHeight && { maxHeight }
502
495
  },
503
- value: itemData.value,
504
- onChange
496
+ value: shownValue,
497
+ onChange,
498
+ onBlur
505
499
  }
506
500
  );
507
501
  }