@comitor/ui 3.13.2 → 3.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/composite/combobox.js +2 -2
- package/dist/components/composite/combobox.js.map +1 -1
- package/dist/components/composite/command-palette.js +1 -1
- package/dist/components/composite/command-palette.js.map +1 -1
- package/dist/components/composite/date-picker.js +1 -1
- package/dist/components/composite/date-picker.js.map +1 -1
- package/dist/components/ui/command.js +1 -1
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/input-otp.js +1 -1
- package/dist/components/ui/input-otp.js.map +1 -1
- package/dist/components/ui/input.js +4 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/key-value.js +3 -3
- package/dist/components/ui/key-value.js.map +1 -1
- package/dist/components/ui/mask-input.js +1 -1
- package/dist/components/ui/mask-input.js.map +1 -1
- package/dist/components/ui/mention.js +1 -1
- package/dist/components/ui/mention.js.map +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/tags-input.js +1 -1
- package/dist/components/ui/tags-input.js.map +1 -1
- package/dist/components/ui/time-picker.js +2 -2
- package/dist/components/ui/time-picker.js.map +1 -1
- package/package.json +1 -1
- package/styles.css +30 -0
|
@@ -57,7 +57,7 @@ function TagsInputList({ className, ...props }) {
|
|
|
57
57
|
* · `min-h-10 py-2` → `min-h-9 py-1.5`: cao đúng `h-9` của `Input` khi chưa có thẻ, để
|
|
58
58
|
* đứng cạnh các ô khác trong cùng một form không lệch dòng.
|
|
59
59
|
*/
|
|
60
|
-
"flex min-h-9 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-3 py-1.5 text-sm text-foreground transition-colors duration-150 ease-out hover:not-focus-within:border-control-edge-strong focus-within:border-primary-ink focus-within:ring-2 focus-within:ring-ring/50 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-muted has-[input:disabled]:opacity-50",
|
|
60
|
+
"flex min-h-9 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-3 py-1.5 text-base md:text-sm text-foreground transition-colors duration-150 ease-out hover:not-focus-within:border-control-edge-strong focus-within:border-primary-ink focus-within:ring-2 focus-within:ring-ring/50 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-muted has-[input:disabled]:opacity-50",
|
|
61
61
|
className
|
|
62
62
|
),
|
|
63
63
|
...props
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/tags-input.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/tags-input) — 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 * as TagsInputPrimitive from \"@diceui/tags-input\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { X } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * TagsInput — ô nhập THẺ TỰ DO: gõ chữ rồi Enter (hoặc gõ dấu phân cách) để thành một thẻ.\n * Dùng cho nhãn tự đặt trên task / bản ghi CRM, danh sách người nhận email.\n *\n * ⚠ KHÁC `MultiCombobox`: `MultiCombobox` chọn nhiều giá trị từ một danh sách CỐ ĐỊNH; TagsInput\n * nhận giá trị người dùng TỰ GÕ, không có danh sách gợi ý. Đừng gộp hai thứ — giá trị hợp lệ\n * của chúng khác nhau về bản chất (có trong tập ⇄ bất kỳ chuỗi nào qua được `onValidate`).\n *\n * Phần lõi (bàn phím, dán, sửa tại chỗ, input ẩn cho form) là gói headless `@diceui/tags-input`;\n * file này chỉ phủ style theo token của Comitor.\n */\ntype TagsInputProps = React.ComponentProps<typeof TagsInputPrimitive.Root>;\n\nfunction TagsInput({ className, dir: dirProp, ...props }: TagsInputProps) {\n /*\n * ⚠ Khác thượng nguồn: `@diceui/shared` có `useDirection` RIÊNG, đọc một `DirectionContext` mà\n * gói không xuất ra — nên `DirectionProvider` của Radix (nguồn hướng chữ của mọi component khác\n * trong gói, vd `Rating`) không tới được nó, và app RTL thấy ô thẻ vẫn chạy LTR. Đọc hướng từ\n * Radix rồi truyền xuống bằng prop `dir` (prop của app vẫn thắng).\n */\n const dir = useDirection(dirProp);\n\n return (\n <TagsInputPrimitive.Root\n data-slot=\"tags-input\"\n dir={dir}\n // ⚠ Khác thượng nguồn: bản gốc ghim `w-[380px]` (kích thước của trang demo). Primitive của\n // gói luôn `w-full` như `Input` — bề rộng là việc của bố cục bên ngoài.\n className={cn(\"flex w-full flex-col gap-2\", className)}\n {...props}\n />\n );\n}\n\ntype TagsInputLabelProps = React.ComponentProps<typeof TagsInputPrimitive.Label>;\n\nfunction TagsInputLabel({ className, ...props }: TagsInputLabelProps) {\n return (\n <TagsInputPrimitive.Label\n data-slot=\"tags-input-label\"\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: `peer-disabled:` của bản gốc không bao giờ khớp — nhãn đứng TRƯỚC ô\n * nhập, mà `peer-*` chỉ nhìn anh em đứng trước. Trạng thái vô hiệu nằm ở `data-disabled` của\n * gốc `TagsInput`, nên đọc bằng `in-data-disabled:`. Mức mờ theo `Label` của gói (50).\n */\n \"text-sm leading-none font-medium in-data-disabled:cursor-not-allowed in-data-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype TagsInputListProps = React.ComponentProps<\"div\">;\n\nfunction TagsInputList({ className, ...props }: TagsInputListProps) {\n return (\n <div\n data-slot=\"tags-input-list\"\n className={cn(\n /*\n * Khung này là \"ô nhập\" mà người dùng nhìn thấy (thẻ + ô gõ nằm chung), nên nó mặc đúng bộ\n * viền của `Input`: `border-input` lúc nghỉ, đậm lên `--control-edge-strong` khi rê chuột,\n * `--primary-ink` + vòng `ring/50` khi có focus BÊN TRONG. Số đo ở chú thích đầu `input.tsx`.\n *\n * ⚠ Khác thượng nguồn:\n * · `focus-within:ring-1 ring-ring` → khuôn focus của `Input` (ring-2 ring/50 + viền ink).\n * · rê chuột lúc đang focus KHÔNG được đè viền focus: `focus-within` xếp TRƯỚC `hover`\n * trong thứ tự biến thể của Tailwind v4, nên hover phải kèm `not-focus-within`.\n * · `disabled:` trên một `<div>` không bao giờ khớp → `has-[input:disabled]:` (gốc vô\n * hiệu thì gói đặt `disabled` THẬT lên ô gõ bên trong). Chọn `:disabled` gốc của HTML\n * chứ không `data-disabled` vì đó là trạng thái mà WCAG 1.4.3/1.4.11 miễn trừ — và là\n * trạng thái duy nhất cổng màu nhận ra là \"vô hiệu\".\n * · `min-h-10 py-2` → `min-h-9 py-1.5`: cao đúng `h-9` của `Input` khi chưa có thẻ, để\n * đứng cạnh các ô khác trong cùng một form không lệch dòng.\n */\n \"flex min-h-9 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-3 py-1.5 text-sm text-foreground transition-colors duration-150 ease-out hover:not-focus-within:border-control-edge-strong focus-within:border-primary-ink focus-within:ring-2 focus-within:ring-ring/50 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-muted has-[input:disabled]:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype TagsInputInputProps = React.ComponentProps<typeof TagsInputPrimitive.Input>;\n\nfunction TagsInputInput({ className, ...props }: TagsInputInputProps) {\n return (\n <TagsInputPrimitive.Input\n data-slot=\"tags-input-input\"\n className={cn(\n // `min-w-0` (thêm): ô gõ là mục flex co giãn — thiếu nó thì chiều rộng tối thiểu nội tại\n // của `<input>` đẩy hàng thẻ xuống dòng sớm.\n \"min-w-0 flex-1 bg-transparent outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ninterface TagsInputItemProps extends React.ComponentProps<typeof TagsInputPrimitive.Item> {\n /**\n * Tên cho trình đọc màn hình của nút xoá thẻ — mặc định khoá `deleteLabel` của namespace\n * `tagsInput` (`ComitorLocaleProvider`).\n *\n * ⚠ Thêm so với thượng nguồn. Nút xoá chỉ có một icon ✕; gói headless đặt cho nó\n * `aria-labelledby` trỏ vào CHỮ của thẻ, nên trình đọc màn hình đọc \"react, nút\" — nghe như\n * một nút mang tên thẻ chứ không phải nút xoá thẻ. Là HÀM vì giá trị thẻ chèn vào giữa câu.\n */\n deleteLabel?: (value: string) => string;\n}\n\nfunction TagsInputItem({ className, children, deleteLabel: deleteLabelProp, ...props }: TagsInputItemProps) {\n const t = useComitorMessages(\"tagsInput\");\n const deleteLabel = deleteLabelProp ?? t.deleteLabel;\n return (\n <TagsInputPrimitive.Item\n data-slot=\"tags-input-item\"\n /*\n * ⚠ Khác thượng nguồn (a11y): gói đặt `aria-labelledby` lên thẻ — một `<div>` KHÔNG có role,\n * mà ARIA 1.2 CẤM đặt tên cho vai trò `generic` (axe: `aria-prohibited-attr`). Chữ của thẻ đã\n * nằm ngay bên trong nên gỡ đi không mất gì.\n */\n aria-labelledby={undefined}\n className={cn(\n /*\n * Viền thẻ là viền TRANG TRÍ (`--border`, mặc định của `@layer base`): thẻ không phải một\n * control — control là nút ✕ bên trong. Thẻ đang được chọn bằng bàn phím tô\n * `bg-accent`/`text-accent-foreground`, cùng cặp với mục đang sáng của `CommandItem`.\n * ⚠ Khác thượng nguồn: `ring-1 ring-ring` lúc sửa tại chỗ → khuôn `ring-2 ring-ring/50`\n * của gói; `px-2.5 py-1` → `px-2 py-0.5` để thẻ lọt khung cao `h-9`.\n */\n \"inline-flex max-w-[calc(100%-8px)] items-center gap-1.5 rounded border bg-transparent px-2 py-0.5 text-sm focus:outline-hidden data-disabled:cursor-not-allowed data-disabled:opacity-50 data-editable:select-none data-editing:bg-transparent data-editing:ring-2 data-editing:ring-ring/50 [&:not([data-editing])]:pr-1 [&[data-highlighted]:not([data-editing])]:bg-accent [&[data-highlighted]:not([data-editing])]:text-accent-foreground\",\n className\n )}\n {...props}\n >\n <TagsInputPrimitive.ItemText className=\"truncate\">{children}</TagsInputPrimitive.ItemText>\n <TagsInputPrimitive.ItemDelete\n /*\n * ⚠ Khác thượng nguồn (a11y):\n * · Tên nút: gói đặt `aria-labelledby` = chữ của thẻ (xem `deleteLabel`). `aria-labelledby`\n * THẮNG `aria-label` trong phép tính tên, nên phải gỡ nó ra (props của ta được trải SAU\n * props của gói, nên `undefined` ở đây xoá được thuộc tính).\n * · `tabIndex`: gói đặt `disabled ? undefined : -1` — tức ngược: nút ĐANG dùng được thì\n * ra khỏi thứ tự Tab (đúng thiết kế: bàn phím xoá thẻ bằng ←/Backspace/Delete từ ô gõ),\n * còn nút VÔ HIỆU thì lại lọt VÀO thứ tự Tab, nhận focus mà bấm không làm gì. Ghim -1\n * cho cả hai trạng thái; trình đọc màn hình ở chế độ duyệt vẫn bấm được nút.\n */\n aria-labelledby={undefined}\n aria-label={deleteLabel(props.value)}\n tabIndex={-1}\n className=\"size-4 shrink-0 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100\"\n >\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </TagsInputPrimitive.ItemDelete>\n </TagsInputPrimitive.Item>\n );\n}\n\ntype TagsInputClearProps = React.ComponentProps<typeof TagsInputPrimitive.Clear>;\n\n/**\n * Nút xoá hết thẻ. Không có nội dung mặc định (đúng thượng nguồn) — app tự đặt chữ/icon bên\n * trong; nếu chỉ đặt icon thì PHẢI kèm `aria-label` (vd \"Xoá tất cả thẻ\").\n */\nfunction TagsInputClear({ ...props }: TagsInputClearProps) {\n return <TagsInputPrimitive.Clear data-slot=\"tags-input-clear\" {...props} />;\n}\n\nexport {\n TagsInput,\n TagsInputClear,\n type TagsInputClearProps,\n TagsInputInput,\n type TagsInputInputProps,\n TagsInputItem,\n type TagsInputItemProps,\n TagsInputLabel,\n type TagsInputLabelProps,\n TagsInputList,\n type TagsInputListProps,\n type TagsInputProps\n};\n"],"mappings":";AAqCI,cA+FA,YA/FA;AA9BJ,YAAY,wBAAwB;AACpC,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,UAAU;AAenB,SAAS,UAAU,EAAE,WAAW,KAAK,SAAS,GAAG,MAAM,GAAmB;AAOxE,QAAM,MAAM,aAAa,OAAO;AAEhC,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MAGA,WAAW,GAAG,8BAA8B,SAAS;AAAA,MACpD,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,cAAc,EAAE,WAAW,GAAG,MAAM,GAAuB;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAiBT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA,QAGT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAcA,SAAS,cAAc,EAAE,WAAW,UAAU,aAAa,iBAAiB,GAAG,MAAM,GAAuB;AAC1G,QAAM,IAAI,mBAAmB,WAAW;AACxC,QAAM,cAAc,mBAAmB,EAAE;AACzC,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MAMV,mBAAiB;AAAA,MACjB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,4BAAC,mBAAmB,UAAnB,EAA4B,WAAU,YAAY,UAAS;AAAA,QAC5D;AAAA,UAAC,mBAAmB;AAAA,UAAnB;AAAA,YAWC,mBAAiB;AAAA,YACjB,cAAY,YAAY,MAAM,KAAK;AAAA,YACnC,UAAU;AAAA,YACV,WAAU;AAAA,YAEV,8BAAC,KAAE,eAAY,QAAO,WAAU,YAAW;AAAA;AAAA,QAC7C;AAAA;AAAA;AAAA,EACF;AAEJ;AAQA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAwB;AACzD,SAAO,oBAAC,mBAAmB,OAAnB,EAAyB,aAAU,oBAAoB,GAAG,OAAO;AAC3E;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/tags-input.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/tags-input) — 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 * as TagsInputPrimitive from \"@diceui/tags-input\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { X } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * TagsInput — ô nhập THẺ TỰ DO: gõ chữ rồi Enter (hoặc gõ dấu phân cách) để thành một thẻ.\n * Dùng cho nhãn tự đặt trên task / bản ghi CRM, danh sách người nhận email.\n *\n * ⚠ KHÁC `MultiCombobox`: `MultiCombobox` chọn nhiều giá trị từ một danh sách CỐ ĐỊNH; TagsInput\n * nhận giá trị người dùng TỰ GÕ, không có danh sách gợi ý. Đừng gộp hai thứ — giá trị hợp lệ\n * của chúng khác nhau về bản chất (có trong tập ⇄ bất kỳ chuỗi nào qua được `onValidate`).\n *\n * Phần lõi (bàn phím, dán, sửa tại chỗ, input ẩn cho form) là gói headless `@diceui/tags-input`;\n * file này chỉ phủ style theo token của Comitor.\n */\ntype TagsInputProps = React.ComponentProps<typeof TagsInputPrimitive.Root>;\n\nfunction TagsInput({ className, dir: dirProp, ...props }: TagsInputProps) {\n /*\n * ⚠ Khác thượng nguồn: `@diceui/shared` có `useDirection` RIÊNG, đọc một `DirectionContext` mà\n * gói không xuất ra — nên `DirectionProvider` của Radix (nguồn hướng chữ của mọi component khác\n * trong gói, vd `Rating`) không tới được nó, và app RTL thấy ô thẻ vẫn chạy LTR. Đọc hướng từ\n * Radix rồi truyền xuống bằng prop `dir` (prop của app vẫn thắng).\n */\n const dir = useDirection(dirProp);\n\n return (\n <TagsInputPrimitive.Root\n data-slot=\"tags-input\"\n dir={dir}\n // ⚠ Khác thượng nguồn: bản gốc ghim `w-[380px]` (kích thước của trang demo). Primitive của\n // gói luôn `w-full` như `Input` — bề rộng là việc của bố cục bên ngoài.\n className={cn(\"flex w-full flex-col gap-2\", className)}\n {...props}\n />\n );\n}\n\ntype TagsInputLabelProps = React.ComponentProps<typeof TagsInputPrimitive.Label>;\n\nfunction TagsInputLabel({ className, ...props }: TagsInputLabelProps) {\n return (\n <TagsInputPrimitive.Label\n data-slot=\"tags-input-label\"\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: `peer-disabled:` của bản gốc không bao giờ khớp — nhãn đứng TRƯỚC ô\n * nhập, mà `peer-*` chỉ nhìn anh em đứng trước. Trạng thái vô hiệu nằm ở `data-disabled` của\n * gốc `TagsInput`, nên đọc bằng `in-data-disabled:`. Mức mờ theo `Label` của gói (50).\n */\n \"text-sm leading-none font-medium in-data-disabled:cursor-not-allowed in-data-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype TagsInputListProps = React.ComponentProps<\"div\">;\n\nfunction TagsInputList({ className, ...props }: TagsInputListProps) {\n return (\n <div\n data-slot=\"tags-input-list\"\n className={cn(\n /*\n * Khung này là \"ô nhập\" mà người dùng nhìn thấy (thẻ + ô gõ nằm chung), nên nó mặc đúng bộ\n * viền của `Input`: `border-input` lúc nghỉ, đậm lên `--control-edge-strong` khi rê chuột,\n * `--primary-ink` + vòng `ring/50` khi có focus BÊN TRONG. Số đo ở chú thích đầu `input.tsx`.\n *\n * ⚠ Khác thượng nguồn:\n * · `focus-within:ring-1 ring-ring` → khuôn focus của `Input` (ring-2 ring/50 + viền ink).\n * · rê chuột lúc đang focus KHÔNG được đè viền focus: `focus-within` xếp TRƯỚC `hover`\n * trong thứ tự biến thể của Tailwind v4, nên hover phải kèm `not-focus-within`.\n * · `disabled:` trên một `<div>` không bao giờ khớp → `has-[input:disabled]:` (gốc vô\n * hiệu thì gói đặt `disabled` THẬT lên ô gõ bên trong). Chọn `:disabled` gốc của HTML\n * chứ không `data-disabled` vì đó là trạng thái mà WCAG 1.4.3/1.4.11 miễn trừ — và là\n * trạng thái duy nhất cổng màu nhận ra là \"vô hiệu\".\n * · `min-h-10 py-2` → `min-h-9 py-1.5`: cao đúng `h-9` của `Input` khi chưa có thẻ, để\n * đứng cạnh các ô khác trong cùng một form không lệch dòng.\n */\n \"flex min-h-9 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-3 py-1.5 text-base md:text-sm text-foreground transition-colors duration-150 ease-out hover:not-focus-within:border-control-edge-strong focus-within:border-primary-ink focus-within:ring-2 focus-within:ring-ring/50 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-muted has-[input:disabled]:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype TagsInputInputProps = React.ComponentProps<typeof TagsInputPrimitive.Input>;\n\nfunction TagsInputInput({ className, ...props }: TagsInputInputProps) {\n return (\n <TagsInputPrimitive.Input\n data-slot=\"tags-input-input\"\n className={cn(\n // `min-w-0` (thêm): ô gõ là mục flex co giãn — thiếu nó thì chiều rộng tối thiểu nội tại\n // của `<input>` đẩy hàng thẻ xuống dòng sớm.\n \"min-w-0 flex-1 bg-transparent outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\ninterface TagsInputItemProps extends React.ComponentProps<typeof TagsInputPrimitive.Item> {\n /**\n * Tên cho trình đọc màn hình của nút xoá thẻ — mặc định khoá `deleteLabel` của namespace\n * `tagsInput` (`ComitorLocaleProvider`).\n *\n * ⚠ Thêm so với thượng nguồn. Nút xoá chỉ có một icon ✕; gói headless đặt cho nó\n * `aria-labelledby` trỏ vào CHỮ của thẻ, nên trình đọc màn hình đọc \"react, nút\" — nghe như\n * một nút mang tên thẻ chứ không phải nút xoá thẻ. Là HÀM vì giá trị thẻ chèn vào giữa câu.\n */\n deleteLabel?: (value: string) => string;\n}\n\nfunction TagsInputItem({ className, children, deleteLabel: deleteLabelProp, ...props }: TagsInputItemProps) {\n const t = useComitorMessages(\"tagsInput\");\n const deleteLabel = deleteLabelProp ?? t.deleteLabel;\n return (\n <TagsInputPrimitive.Item\n data-slot=\"tags-input-item\"\n /*\n * ⚠ Khác thượng nguồn (a11y): gói đặt `aria-labelledby` lên thẻ — một `<div>` KHÔNG có role,\n * mà ARIA 1.2 CẤM đặt tên cho vai trò `generic` (axe: `aria-prohibited-attr`). Chữ của thẻ đã\n * nằm ngay bên trong nên gỡ đi không mất gì.\n */\n aria-labelledby={undefined}\n className={cn(\n /*\n * Viền thẻ là viền TRANG TRÍ (`--border`, mặc định của `@layer base`): thẻ không phải một\n * control — control là nút ✕ bên trong. Thẻ đang được chọn bằng bàn phím tô\n * `bg-accent`/`text-accent-foreground`, cùng cặp với mục đang sáng của `CommandItem`.\n * ⚠ Khác thượng nguồn: `ring-1 ring-ring` lúc sửa tại chỗ → khuôn `ring-2 ring-ring/50`\n * của gói; `px-2.5 py-1` → `px-2 py-0.5` để thẻ lọt khung cao `h-9`.\n */\n \"inline-flex max-w-[calc(100%-8px)] items-center gap-1.5 rounded border bg-transparent px-2 py-0.5 text-sm focus:outline-hidden data-disabled:cursor-not-allowed data-disabled:opacity-50 data-editable:select-none data-editing:bg-transparent data-editing:ring-2 data-editing:ring-ring/50 [&:not([data-editing])]:pr-1 [&[data-highlighted]:not([data-editing])]:bg-accent [&[data-highlighted]:not([data-editing])]:text-accent-foreground\",\n className\n )}\n {...props}\n >\n <TagsInputPrimitive.ItemText className=\"truncate\">{children}</TagsInputPrimitive.ItemText>\n <TagsInputPrimitive.ItemDelete\n /*\n * ⚠ Khác thượng nguồn (a11y):\n * · Tên nút: gói đặt `aria-labelledby` = chữ của thẻ (xem `deleteLabel`). `aria-labelledby`\n * THẮNG `aria-label` trong phép tính tên, nên phải gỡ nó ra (props của ta được trải SAU\n * props của gói, nên `undefined` ở đây xoá được thuộc tính).\n * · `tabIndex`: gói đặt `disabled ? undefined : -1` — tức ngược: nút ĐANG dùng được thì\n * ra khỏi thứ tự Tab (đúng thiết kế: bàn phím xoá thẻ bằng ←/Backspace/Delete từ ô gõ),\n * còn nút VÔ HIỆU thì lại lọt VÀO thứ tự Tab, nhận focus mà bấm không làm gì. Ghim -1\n * cho cả hai trạng thái; trình đọc màn hình ở chế độ duyệt vẫn bấm được nút.\n */\n aria-labelledby={undefined}\n aria-label={deleteLabel(props.value)}\n tabIndex={-1}\n className=\"size-4 shrink-0 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100\"\n >\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </TagsInputPrimitive.ItemDelete>\n </TagsInputPrimitive.Item>\n );\n}\n\ntype TagsInputClearProps = React.ComponentProps<typeof TagsInputPrimitive.Clear>;\n\n/**\n * Nút xoá hết thẻ. Không có nội dung mặc định (đúng thượng nguồn) — app tự đặt chữ/icon bên\n * trong; nếu chỉ đặt icon thì PHẢI kèm `aria-label` (vd \"Xoá tất cả thẻ\").\n */\nfunction TagsInputClear({ ...props }: TagsInputClearProps) {\n return <TagsInputPrimitive.Clear data-slot=\"tags-input-clear\" {...props} />;\n}\n\nexport {\n TagsInput,\n TagsInputClear,\n type TagsInputClearProps,\n TagsInputInput,\n type TagsInputInputProps,\n TagsInputItem,\n type TagsInputItemProps,\n TagsInputLabel,\n type TagsInputLabelProps,\n TagsInputList,\n type TagsInputListProps,\n type TagsInputProps\n};\n"],"mappings":";AAqCI,cA+FA,YA/FA;AA9BJ,YAAY,wBAAwB;AACpC,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,UAAU;AAenB,SAAS,UAAU,EAAE,WAAW,KAAK,SAAS,GAAG,MAAM,GAAmB;AAOxE,QAAM,MAAM,aAAa,OAAO;AAEhC,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MAGA,WAAW,GAAG,8BAA8B,SAAS;AAAA,MACpD,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,cAAc,EAAE,WAAW,GAAG,MAAM,GAAuB;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAiBT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA,QAGT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAcA,SAAS,cAAc,EAAE,WAAW,UAAU,aAAa,iBAAiB,GAAG,MAAM,GAAuB;AAC1G,QAAM,IAAI,mBAAmB,WAAW;AACxC,QAAM,cAAc,mBAAmB,EAAE;AACzC,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MAMV,mBAAiB;AAAA,MACjB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,4BAAC,mBAAmB,UAAnB,EAA4B,WAAU,YAAY,UAAS;AAAA,QAC5D;AAAA,UAAC,mBAAmB;AAAA,UAAnB;AAAA,YAWC,mBAAiB;AAAA,YACjB,cAAY,YAAY,MAAM,KAAK;AAAA,YACnC,UAAU;AAAA,YACV,WAAU;AAAA,YAEV,8BAAC,KAAE,eAAY,QAAO,WAAU,YAAW;AAAA;AAAA,QAC7C;AAAA;AAAA;AAAA,EACF;AAEJ;AAQA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAwB;AACzD,SAAO,oBAAC,mBAAmB,OAAnB,EAAyB,aAAU,oBAAoB,GAAG,OAAO;AAC3E;","names":[]}
|
|
@@ -684,7 +684,7 @@ function TimePickerInputGroup(props) {
|
|
|
684
684
|
* `--primary-ink` + quầng `ring-2 ring-ring/50` KHÔNG offset (quy ước họ ô nhập —
|
|
685
685
|
* xem `InputGroup`), lỗi viền `--destructive-ink`. Số đo ở chú thích đầu `input.tsx`.
|
|
686
686
|
*/
|
|
687
|
-
"flex h-9 w-full cursor-text items-center gap-0.5 rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground transition-colors duration-150 ease-out outline-none hover:border-control-edge-strong",
|
|
687
|
+
"flex h-9 w-full cursor-text items-center gap-0.5 rounded-md border border-input bg-background px-3 py-2 text-base md:text-sm text-foreground transition-colors duration-150 ease-out outline-none hover:border-control-edge-strong",
|
|
688
688
|
"has-[input:focus]:border-primary-ink has-[input:focus]:ring-2 has-[input:focus]:ring-ring/50",
|
|
689
689
|
invalid && "border-destructive-ink hover:border-destructive-ink has-[input:focus]:border-destructive-ink has-[input:focus]:ring-destructive/30",
|
|
690
690
|
/*
|
|
@@ -1273,7 +1273,7 @@ function TimePickerInput(props) {
|
|
|
1273
1273
|
disabled: isDisabled,
|
|
1274
1274
|
readOnly: isReadOnly,
|
|
1275
1275
|
className: cn(
|
|
1276
|
-
"inline-flex h-full items-center justify-center border-0 bg-transparent text-center text-sm tabular-nums transition-colors outline-none focus:bg-transparent disabled:cursor-not-allowed disabled:opacity-50",
|
|
1276
|
+
"inline-flex h-full items-center justify-center border-0 bg-transparent text-center text-base md:text-sm tabular-nums transition-colors outline-none focus:bg-transparent disabled:cursor-not-allowed disabled:opacity-50",
|
|
1277
1277
|
className
|
|
1278
1278
|
),
|
|
1279
1279
|
style: { width: segmentWidth, ...style },
|