@comitor/ui 0.3.1 → 0.3.2

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.
@@ -40,7 +40,7 @@ function ContextMenuSubTrigger({ className, inset, children, ...props }) {
40
40
  );
41
41
  }
42
42
  function ContextMenuSubContent({ className, ...props }) {
43
- return /* @__PURE__ */ jsx(
43
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
44
44
  ContextMenuPrimitive.SubContent,
45
45
  {
46
46
  "data-slot": "context-menu-sub-content",
@@ -50,7 +50,7 @@ function ContextMenuSubContent({ className, ...props }) {
50
50
  ),
51
51
  ...props
52
52
  }
53
- );
53
+ ) });
54
54
  }
55
55
  function ContextMenuContent({ className, ...props }) {
56
56
  return /* @__PURE__ */ jsx(ContextMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/context-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * ContextMenu — menu chuột phải (Radix ContextMenu).\n *\n * Dùng cho thao tác nhanh trên thẻ task, dòng bảng, mục sidebar. Cấu trúc mục\n * giống `DropdownMenu` (cùng biến thể `destructive`, `inset`) để hai menu nhìn như một.\n * Vì chuột phải không có trên thiết bị cảm ứng, mọi thao tác ở đây phải có đường\n * thay thế (nút \"…\" mở DropdownMenu).\n */\n\nexport type ContextMenuProps = React.ComponentProps<typeof ContextMenuPrimitive.Root>;\n\nfunction ContextMenu({ ...props }: ContextMenuProps) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nexport type ContextMenuTriggerProps = React.ComponentProps<typeof ContextMenuPrimitive.Trigger>;\n\nfunction ContextMenuTrigger({ ...props }: ContextMenuTriggerProps) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nexport type ContextMenuGroupProps = React.ComponentProps<typeof ContextMenuPrimitive.Group>;\n\nfunction ContextMenuGroup({ ...props }: ContextMenuGroupProps) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nexport type ContextMenuPortalProps = React.ComponentProps<typeof ContextMenuPrimitive.Portal>;\n\nfunction ContextMenuPortal({ ...props }: ContextMenuPortalProps) {\n return <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />;\n}\n\nexport type ContextMenuSubProps = React.ComponentProps<typeof ContextMenuPrimitive.Sub>;\n\nfunction ContextMenuSub({ ...props }: ContextMenuSubProps) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nexport type ContextMenuRadioGroupProps = React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>;\n\nfunction ContextMenuRadioGroup({ ...props }: ContextMenuRadioGroupProps) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nexport type ContextMenuSubTriggerProps = React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction ContextMenuSubTrigger({ className, inset, children, ...props }: ContextMenuSubTriggerProps) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nexport type ContextMenuSubContentProps = React.ComponentProps<typeof ContextMenuPrimitive.SubContent>;\n\nfunction ContextMenuSubContent({ className, ...props }: ContextMenuSubContentProps) {\n return (\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type ContextMenuContentProps = React.ComponentProps<typeof ContextMenuPrimitive.Content>;\n\nfunction ContextMenuContent({ className, ...props }: ContextMenuContentProps) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport type ContextMenuItemVariant = \"default\" | \"destructive\";\n\nexport type ContextMenuItemProps = React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: ContextMenuItemVariant;\n};\n\nfunction ContextMenuItem({ className, inset, variant = \"default\", ...props }: ContextMenuItemProps) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type ContextMenuCheckboxItemProps = React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>;\n\nfunction ContextMenuCheckboxItem({ className, children, checked, ...props }: ContextMenuCheckboxItemProps) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nexport type ContextMenuRadioItemProps = React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>;\n\nfunction ContextMenuRadioItem({ className, children, ...props }: ContextMenuRadioItemProps) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nexport type ContextMenuLabelProps = React.ComponentProps<typeof ContextMenuPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction ContextMenuLabel({ className, inset, ...props }: ContextMenuLabelProps) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset}\n className={cn(\"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type ContextMenuSeparatorProps = React.ComponentProps<typeof ContextMenuPrimitive.Separator>;\n\nfunction ContextMenuSeparator({ className, ...props }: ContextMenuSeparatorProps) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type ContextMenuShortcutProps = React.ComponentProps<\"span\">;\n\nfunction ContextMenuShortcut({ className, ...props }: ContextMenuShortcutProps) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuPortal,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/context-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * ContextMenu — menu chuột phải (Radix ContextMenu).\n *\n * Dùng cho thao tác nhanh trên thẻ task, dòng bảng, mục sidebar. Cấu trúc mục\n * giống `DropdownMenu` (cùng biến thể `destructive`, `inset`) để hai menu nhìn như một.\n * Vì chuột phải không có trên thiết bị cảm ứng, mọi thao tác ở đây phải có đường\n * thay thế (nút \"…\" mở DropdownMenu).\n */\n\nexport type ContextMenuProps = React.ComponentProps<typeof ContextMenuPrimitive.Root>;\n\nfunction ContextMenu({ ...props }: ContextMenuProps) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nexport type ContextMenuTriggerProps = React.ComponentProps<typeof ContextMenuPrimitive.Trigger>;\n\nfunction ContextMenuTrigger({ ...props }: ContextMenuTriggerProps) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nexport type ContextMenuGroupProps = React.ComponentProps<typeof ContextMenuPrimitive.Group>;\n\nfunction ContextMenuGroup({ ...props }: ContextMenuGroupProps) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nexport type ContextMenuPortalProps = React.ComponentProps<typeof ContextMenuPrimitive.Portal>;\n\nfunction ContextMenuPortal({ ...props }: ContextMenuPortalProps) {\n return <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />;\n}\n\nexport type ContextMenuSubProps = React.ComponentProps<typeof ContextMenuPrimitive.Sub>;\n\nfunction ContextMenuSub({ ...props }: ContextMenuSubProps) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nexport type ContextMenuRadioGroupProps = React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>;\n\nfunction ContextMenuRadioGroup({ ...props }: ContextMenuRadioGroupProps) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nexport type ContextMenuSubTriggerProps = React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction ContextMenuSubTrigger({ className, inset, children, ...props }: ContextMenuSubTriggerProps) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\n/*\n * ─ VÌ SAO `SubContent` PHẢI BỌC `Portal` ─\n *\n * Không bọc thì Radix render nó (kèm lớp bọc định vị `position: fixed`) làm CON của\n * `ContextMenuContent`, mà `ContextMenuContent` có `overflow-x-hidden overflow-y-auto`. `position: fixed`\n * bình thường thoát được `overflow` — TRỪ KHI có tổ tiên tạo containing block cho nó, và\n * `ContextMenuContent` tạo đúng thứ đó: các lớp `data-[state=open]:animate-in` / `zoom-in-95` /\n * `slide-in-from-*` animate `transform`, với `animation-fill-mode: both` nên transform CÒN LẠI\n * sau khi hiệu ứng chạy xong (`scale(1)` vẫn là transform, không phải `none`).\n *\n * Hệ quả: submenu mở sang BÊN CẠNH menu cha, tức hoàn toàn nằm ngoài hộp của cha theo chiều\n * ngang, và bị `overflow-x-hidden` cắt sạch. Người dùng thấy mục có mũi tên ▸ mà bấm/rê vào\n * không ra gì — không lỗi, không cảnh báo.\n *\n * Đây là hồi quy đã biết của shadcn/ui: nó xuất hiện đúng lúc `ContextMenuContent` được thêm\n * `max-h-… overflow-y-auto`. Bọc `Portal` đưa submenu ra thẳng `document.body`, thoát cả\n * `overflow` lẫn containing block.\n *\n * ⚠ Đừng \"sửa\" bằng cách bỏ `overflow-y-auto` ở `ContextMenuContent`: lớp đó có việc của nó (menu\n * dài hơn màn hình thì phải cuộn được).\n */\nexport type ContextMenuSubContentProps = React.ComponentProps<typeof ContextMenuPrimitive.SubContent>;\n\nfunction ContextMenuSubContent({ className, ...props }: ContextMenuSubContentProps) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport type ContextMenuContentProps = React.ComponentProps<typeof ContextMenuPrimitive.Content>;\n\nfunction ContextMenuContent({ className, ...props }: ContextMenuContentProps) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport type ContextMenuItemVariant = \"default\" | \"destructive\";\n\nexport type ContextMenuItemProps = React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: ContextMenuItemVariant;\n};\n\nfunction ContextMenuItem({ className, inset, variant = \"default\", ...props }: ContextMenuItemProps) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type ContextMenuCheckboxItemProps = React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>;\n\nfunction ContextMenuCheckboxItem({ className, children, checked, ...props }: ContextMenuCheckboxItemProps) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nexport type ContextMenuRadioItemProps = React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>;\n\nfunction ContextMenuRadioItem({ className, children, ...props }: ContextMenuRadioItemProps) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nexport type ContextMenuLabelProps = React.ComponentProps<typeof ContextMenuPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction ContextMenuLabel({ className, inset, ...props }: ContextMenuLabelProps) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset}\n className={cn(\"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type ContextMenuSeparatorProps = React.ComponentProps<typeof ContextMenuPrimitive.Separator>;\n\nfunction ContextMenuSeparator({ className, ...props }: ContextMenuSeparatorProps) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type ContextMenuShortcutProps = React.ComponentProps<\"span\">;\n\nfunction ContextMenuShortcut({ className, ...props }: ContextMenuShortcutProps) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuPortal,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger\n};\n"],"mappings":"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","names":[]}
@@ -135,7 +135,7 @@ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
135
135
  );
136
136
  }
137
137
  function DropdownMenuSubContent({ className, ...props }) {
138
- return /* @__PURE__ */ jsx(
138
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
139
139
  DropdownMenuPrimitive.SubContent,
140
140
  {
141
141
  "data-slot": "dropdown-menu-sub-content",
@@ -145,7 +145,7 @@ function DropdownMenuSubContent({ className, ...props }) {
145
145
  ),
146
146
  ...props
147
147
  }
148
- );
148
+ ) });
149
149
  }
150
150
  export {
151
151
  DropdownMenu,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/dropdown-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * DropdownMenu — menu bung ra từ một nút (Radix DropdownMenu).\n *\n * Xương sống của UserMenu, menu thao tác trên dòng bảng, WorkspaceSwitcher.\n * `DropdownMenuItem` có `variant=\"destructive\"` cho mục nguy hiểm (Xóa, Đăng xuất)\n * và `inset` để thụt lề cho ngang hàng với mục có icon chọn.\n */\n\nexport type DropdownMenuProps = React.ComponentProps<typeof DropdownMenuPrimitive.Root>;\n\nfunction DropdownMenu({ ...props }: DropdownMenuProps) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nexport type DropdownMenuPortalProps = React.ComponentProps<typeof DropdownMenuPrimitive.Portal>;\n\nfunction DropdownMenuPortal({ ...props }: DropdownMenuPortalProps) {\n return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nexport type DropdownMenuTriggerProps = React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>;\n\nfunction DropdownMenuTrigger({ ...props }: DropdownMenuTriggerProps) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof DropdownMenuPrimitive.Content>;\n\nfunction DropdownMenuContent({ className, sideOffset = 4, ...props }: DropdownMenuContentProps) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuGroupProps = React.ComponentProps<typeof DropdownMenuPrimitive.Group>;\n\nfunction DropdownMenuGroup({ ...props }: DropdownMenuGroupProps) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nexport type DropdownMenuItemVariant = \"default\" | \"destructive\";\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n /** Thụt lề trái để thẳng hàng với mục có ô đánh dấu. */\n inset?: boolean;\n /** \"destructive\" tô đỏ cho thao tác nguy hiểm. Mặc định \"default\". */\n variant?: DropdownMenuItemVariant;\n};\n\nfunction DropdownMenuItem({ className, inset, variant = \"default\", ...props }: DropdownMenuItemProps) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuCheckboxItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>;\n\nfunction DropdownMenuCheckboxItem({ className, children, checked, ...props }: DropdownMenuCheckboxItemProps) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nexport type DropdownMenuRadioGroupProps = React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>;\n\nfunction DropdownMenuRadioGroup({ ...props }: DropdownMenuRadioGroupProps) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nexport type DropdownMenuRadioItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>;\n\nfunction DropdownMenuRadioItem({ className, children, ...props }: DropdownMenuRadioItemProps) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nexport type DropdownMenuLabelProps = React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuLabel({ className, inset, ...props }: DropdownMenuLabelProps) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuSeparatorProps = React.ComponentProps<typeof DropdownMenuPrimitive.Separator>;\n\nfunction DropdownMenuSeparator({ className, ...props }: DropdownMenuSeparatorProps) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuShortcutProps = React.ComponentProps<\"span\">;\n\nfunction DropdownMenuShortcut({ className, ...props }: DropdownMenuShortcutProps) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuSubProps = React.ComponentProps<typeof DropdownMenuPrimitive.Sub>;\n\nfunction DropdownMenuSub({ ...props }: DropdownMenuSubProps) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nexport type DropdownMenuSubTriggerProps = React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuSubTrigger({ className, inset, children, ...props }: DropdownMenuSubTriggerProps) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nexport type DropdownMenuSubContentProps = React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>;\n\nfunction DropdownMenuSubContent({ className, ...props }: DropdownMenuSubContentProps) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/dropdown-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * DropdownMenu — menu bung ra từ một nút (Radix DropdownMenu).\n *\n * Xương sống của UserMenu, menu thao tác trên dòng bảng, WorkspaceSwitcher.\n * `DropdownMenuItem` có `variant=\"destructive\"` cho mục nguy hiểm (Xóa, Đăng xuất)\n * và `inset` để thụt lề cho ngang hàng với mục có icon chọn.\n */\n\nexport type DropdownMenuProps = React.ComponentProps<typeof DropdownMenuPrimitive.Root>;\n\nfunction DropdownMenu({ ...props }: DropdownMenuProps) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nexport type DropdownMenuPortalProps = React.ComponentProps<typeof DropdownMenuPrimitive.Portal>;\n\nfunction DropdownMenuPortal({ ...props }: DropdownMenuPortalProps) {\n return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nexport type DropdownMenuTriggerProps = React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>;\n\nfunction DropdownMenuTrigger({ ...props }: DropdownMenuTriggerProps) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof DropdownMenuPrimitive.Content>;\n\nfunction DropdownMenuContent({ className, sideOffset = 4, ...props }: DropdownMenuContentProps) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuGroupProps = React.ComponentProps<typeof DropdownMenuPrimitive.Group>;\n\nfunction DropdownMenuGroup({ ...props }: DropdownMenuGroupProps) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nexport type DropdownMenuItemVariant = \"default\" | \"destructive\";\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n /** Thụt lề trái để thẳng hàng với mục có ô đánh dấu. */\n inset?: boolean;\n /** \"destructive\" tô đỏ cho thao tác nguy hiểm. Mặc định \"default\". */\n variant?: DropdownMenuItemVariant;\n};\n\nfunction DropdownMenuItem({ className, inset, variant = \"default\", ...props }: DropdownMenuItemProps) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuCheckboxItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>;\n\nfunction DropdownMenuCheckboxItem({ className, children, checked, ...props }: DropdownMenuCheckboxItemProps) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nexport type DropdownMenuRadioGroupProps = React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>;\n\nfunction DropdownMenuRadioGroup({ ...props }: DropdownMenuRadioGroupProps) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nexport type DropdownMenuRadioItemProps = React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>;\n\nfunction DropdownMenuRadioItem({ className, children, ...props }: DropdownMenuRadioItemProps) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nexport type DropdownMenuLabelProps = React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuLabel({ className, inset, ...props }: DropdownMenuLabelProps) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuSeparatorProps = React.ComponentProps<typeof DropdownMenuPrimitive.Separator>;\n\nfunction DropdownMenuSeparator({ className, ...props }: DropdownMenuSeparatorProps) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuShortcutProps = React.ComponentProps<\"span\">;\n\nfunction DropdownMenuShortcut({ className, ...props }: DropdownMenuShortcutProps) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport type DropdownMenuSubProps = React.ComponentProps<typeof DropdownMenuPrimitive.Sub>;\n\nfunction DropdownMenuSub({ ...props }: DropdownMenuSubProps) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nexport type DropdownMenuSubTriggerProps = React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuSubTrigger({ className, inset, children, ...props }: DropdownMenuSubTriggerProps) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\n/*\n * ─ VÌ SAO `SubContent` PHẢI BỌC `Portal` ─\n *\n * Không bọc thì Radix render nó (kèm lớp bọc định vị `position: fixed`) làm CON của\n * `DropdownMenuContent`, mà `DropdownMenuContent` có `overflow-x-hidden overflow-y-auto`. `position: fixed`\n * bình thường thoát được `overflow` — TRỪ KHI có tổ tiên tạo containing block cho nó, và\n * `DropdownMenuContent` tạo đúng thứ đó: các lớp `data-[state=open]:animate-in` / `zoom-in-95` /\n * `slide-in-from-*` animate `transform`, với `animation-fill-mode: both` nên transform CÒN LẠI\n * sau khi hiệu ứng chạy xong (`scale(1)` vẫn là transform, không phải `none`).\n *\n * Hệ quả: submenu mở sang BÊN CẠNH menu cha, tức hoàn toàn nằm ngoài hộp của cha theo chiều\n * ngang, và bị `overflow-x-hidden` cắt sạch. Người dùng thấy mục có mũi tên ▸ mà bấm/rê vào\n * không ra gì — không lỗi, không cảnh báo.\n *\n * Đây là hồi quy đã biết của shadcn/ui: nó xuất hiện đúng lúc `DropdownMenuContent` được thêm\n * `max-h-… overflow-y-auto`. Bọc `Portal` đưa submenu ra thẳng `document.body`, thoát cả\n * `overflow` lẫn containing block.\n *\n * ⚠ Đừng \"sửa\" bằng cách bỏ `overflow-y-auto` ở `DropdownMenuContent`: lớp đó có việc của nó (menu\n * dài hơn màn hình thì phải cuộn được).\n */\nexport type DropdownMenuSubContentProps = React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>;\n\nfunction DropdownMenuSubContent({ className, ...props }: DropdownMenuSubContentProps) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger\n};\n"],"mappings":";AAkBS,cAuEL,YAvEK;AAhBT,YAAY,2BAA2B;AACvC,SAAS,WAAW,kBAAkB,kBAAkB;AAExD,SAAS,UAAU;AAYnB,SAAS,aAAa,EAAE,GAAG,MAAM,GAAsB;AACrD,SAAO,oBAAC,sBAAsB,MAAtB,EAA2B,aAAU,iBAAiB,GAAG,OAAO;AAC1E;AAIA,SAAS,mBAAmB,EAAE,GAAG,MAAM,GAA4B;AACjE,SAAO,oBAAC,sBAAsB,QAAtB,EAA6B,aAAU,wBAAwB,GAAG,OAAO;AACnF;AAIA,SAAS,oBAAoB,EAAE,GAAG,MAAM,GAA6B;AACnE,SAAO,oBAAC,sBAAsB,SAAtB,EAA8B,aAAU,yBAAyB,GAAG,OAAO;AACrF;AAIA,SAAS,oBAAoB,EAAE,WAAW,aAAa,GAAG,GAAG,MAAM,GAA6B;AAC9F,SACE,oBAAC,sBAAsB,QAAtB,EACC;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAIA,SAAS,kBAAkB,EAAE,GAAG,MAAM,GAA2B;AAC/D,SAAO,oBAAC,sBAAsB,OAAtB,EAA4B,aAAU,uBAAuB,GAAG,OAAO;AACjF;AAWA,SAAS,iBAAiB,EAAE,WAAW,OAAO,UAAU,WAAW,GAAG,MAAM,GAA0B;AACpG,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,gBAAc;AAAA,MAKd,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,yBAAyB,EAAE,WAAW,UAAU,SAAS,GAAG,MAAM,GAAkC;AAC3G,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAK,WAAU,iFACd,8BAAC,sBAAsB,eAAtB,EACC,8BAAC,aAAU,WAAU,UAAS,GAChC,GACF;AAAA,QACC;AAAA;AAAA;AAAA,EACH;AAEJ;AAIA,SAAS,uBAAuB,EAAE,GAAG,MAAM,GAAgC;AACzE,SAAO,oBAAC,sBAAsB,YAAtB,EAAiC,aAAU,6BAA6B,GAAG,OAAO;AAC5F;AAIA,SAAS,sBAAsB,EAAE,WAAW,UAAU,GAAG,MAAM,GAA+B;AAC5F,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAK,WAAU,iFACd,8BAAC,sBAAsB,eAAtB,EACC,8BAAC,cAAW,WAAU,uBAAsB,GAC9C,GACF;AAAA,QACC;AAAA;AAAA;AAAA,EACH;AAEJ;AAMA,SAAS,kBAAkB,EAAE,WAAW,OAAO,GAAG,MAAM,GAA2B;AACjF,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,WAAW,GAAG,qDAAqD,SAAS;AAAA,MAC3E,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,sBAAsB,EAAE,WAAW,GAAG,MAAM,GAA+B;AAClF,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,6BAA6B,SAAS;AAAA,MACnD,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,qBAAqB,EAAE,WAAW,GAAG,MAAM,GAA8B;AAChF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,yDAAyD,SAAS;AAAA,MAC/E,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,gBAAgB,EAAE,GAAG,MAAM,GAAyB;AAC3D,SAAO,oBAAC,sBAAsB,KAAtB,EAA0B,aAAU,qBAAqB,GAAG,OAAO;AAC7E;AAMA,SAAS,uBAAuB,EAAE,WAAW,OAAO,UAAU,GAAG,MAAM,GAAgC;AACrG,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD,oBAAC,oBAAiB,WAAU,kBAAiB;AAAA;AAAA;AAAA,EAC/C;AAEJ;AAyBA,SAAS,uBAAuB,EAAE,WAAW,GAAG,MAAM,GAAgC;AACpF,SACE,oBAAC,sBAAsB,QAAtB,EACC;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;","names":[]}
@@ -163,7 +163,7 @@ function MenubarSubTrigger({ className, inset, children, ...props }) {
163
163
  );
164
164
  }
165
165
  function MenubarSubContent({ className, ...props }) {
166
- return /* @__PURE__ */ jsx(
166
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Portal, { children: /* @__PURE__ */ jsx(
167
167
  MenubarPrimitive.SubContent,
168
168
  {
169
169
  "data-slot": "menubar-sub-content",
@@ -173,7 +173,7 @@ function MenubarSubContent({ className, ...props }) {
173
173
  ),
174
174
  ...props
175
175
  }
176
- );
176
+ ) });
177
177
  }
178
178
  export {
179
179
  Menubar,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/menubar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * Menubar — thanh menu ngang kiểu ứng dụng desktop (Radix Menubar).\n *\n * Dùng cho màn hình soạn thảo/bảng tính (Docs, Sheets nội bộ) — nơi cần nhóm lệnh\n * cố định. KHÔNG dùng làm điều hướng chính của app: điều hướng nằm ở Sidebar/AppHeader.\n */\n\nexport type MenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\n\nfunction Menubar({ className, ...props }: MenubarProps) {\n return (\n <MenubarPrimitive.Root\n data-slot=\"menubar\"\n className={cn(\"bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\n\nfunction MenubarMenu({ ...props }: MenubarMenuProps) {\n return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />;\n}\n\nexport type MenubarGroupProps = React.ComponentProps<typeof MenubarPrimitive.Group>;\n\nfunction MenubarGroup({ ...props }: MenubarGroupProps) {\n return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />;\n}\n\nexport type MenubarPortalProps = React.ComponentProps<typeof MenubarPrimitive.Portal>;\n\nfunction MenubarPortal({ ...props }: MenubarPortalProps) {\n return <MenubarPrimitive.Portal data-slot=\"menubar-portal\" {...props} />;\n}\n\nexport type MenubarRadioGroupProps = React.ComponentProps<typeof MenubarPrimitive.RadioGroup>;\n\nfunction MenubarRadioGroup({ ...props }: MenubarRadioGroupProps) {\n return <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />;\n}\n\nexport type MenubarTriggerProps = React.ComponentProps<typeof MenubarPrimitive.Trigger>;\n\nfunction MenubarTrigger({ className, ...props }: MenubarTriggerProps) {\n return (\n <MenubarPrimitive.Trigger\n data-slot=\"menubar-trigger\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type MenubarContentProps = React.ComponentProps<typeof MenubarPrimitive.Content>;\n\nfunction MenubarContent({\n className,\n align = \"start\",\n alignOffset = -4,\n sideOffset = 8,\n ...props\n}: MenubarContentProps) {\n return (\n <MenubarPortal>\n <MenubarPrimitive.Content\n data-slot=\"menubar-content\"\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </MenubarPortal>\n );\n}\n\nexport type MenubarItemVariant = \"default\" | \"destructive\";\n\nexport type MenubarItemProps = React.ComponentProps<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n variant?: MenubarItemVariant;\n};\n\nfunction MenubarItem({ className, inset, variant = \"default\", ...props }: MenubarItemProps) {\n return (\n <MenubarPrimitive.Item\n data-slot=\"menubar-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type MenubarCheckboxItemProps = React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>;\n\nfunction MenubarCheckboxItem({ className, children, checked, ...props }: MenubarCheckboxItemProps) {\n return (\n <MenubarPrimitive.CheckboxItem\n data-slot=\"menubar-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n );\n}\n\nexport type MenubarRadioItemProps = React.ComponentProps<typeof MenubarPrimitive.RadioItem>;\n\nfunction MenubarRadioItem({ className, children, ...props }: MenubarRadioItemProps) {\n return (\n <MenubarPrimitive.RadioItem\n data-slot=\"menubar-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n );\n}\n\nexport type MenubarLabelProps = React.ComponentProps<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction MenubarLabel({ className, inset, ...props }: MenubarLabelProps) {\n return (\n <MenubarPrimitive.Label\n data-slot=\"menubar-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarSeparatorProps = React.ComponentProps<typeof MenubarPrimitive.Separator>;\n\nfunction MenubarSeparator({ className, ...props }: MenubarSeparatorProps) {\n return (\n <MenubarPrimitive.Separator\n data-slot=\"menubar-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarShortcutProps = React.ComponentProps<\"span\">;\n\nfunction MenubarShortcut({ className, ...props }: MenubarShortcutProps) {\n return (\n <span\n data-slot=\"menubar-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarSubProps = React.ComponentProps<typeof MenubarPrimitive.Sub>;\n\nfunction MenubarSub({ ...props }: MenubarSubProps) {\n return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />;\n}\n\nexport type MenubarSubTriggerProps = React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction MenubarSubTrigger({ className, inset, children, ...props }: MenubarSubTriggerProps) {\n return (\n <MenubarPrimitive.SubTrigger\n data-slot=\"menubar-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto h-4 w-4\" />\n </MenubarPrimitive.SubTrigger>\n );\n}\n\nexport type MenubarSubContentProps = React.ComponentProps<typeof MenubarPrimitive.SubContent>;\n\nfunction MenubarSubContent({ className, ...props }: MenubarSubContentProps) {\n return (\n <MenubarPrimitive.SubContent\n data-slot=\"menubar-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarLabel,\n MenubarMenu,\n MenubarPortal,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/menubar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * Menubar — thanh menu ngang kiểu ứng dụng desktop (Radix Menubar).\n *\n * Dùng cho màn hình soạn thảo/bảng tính (Docs, Sheets nội bộ) — nơi cần nhóm lệnh\n * cố định. KHÔNG dùng làm điều hướng chính của app: điều hướng nằm ở Sidebar/AppHeader.\n */\n\nexport type MenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\n\nfunction Menubar({ className, ...props }: MenubarProps) {\n return (\n <MenubarPrimitive.Root\n data-slot=\"menubar\"\n className={cn(\"bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\n\nfunction MenubarMenu({ ...props }: MenubarMenuProps) {\n return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />;\n}\n\nexport type MenubarGroupProps = React.ComponentProps<typeof MenubarPrimitive.Group>;\n\nfunction MenubarGroup({ ...props }: MenubarGroupProps) {\n return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />;\n}\n\nexport type MenubarPortalProps = React.ComponentProps<typeof MenubarPrimitive.Portal>;\n\nfunction MenubarPortal({ ...props }: MenubarPortalProps) {\n return <MenubarPrimitive.Portal data-slot=\"menubar-portal\" {...props} />;\n}\n\nexport type MenubarRadioGroupProps = React.ComponentProps<typeof MenubarPrimitive.RadioGroup>;\n\nfunction MenubarRadioGroup({ ...props }: MenubarRadioGroupProps) {\n return <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />;\n}\n\nexport type MenubarTriggerProps = React.ComponentProps<typeof MenubarPrimitive.Trigger>;\n\nfunction MenubarTrigger({ className, ...props }: MenubarTriggerProps) {\n return (\n <MenubarPrimitive.Trigger\n data-slot=\"menubar-trigger\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type MenubarContentProps = React.ComponentProps<typeof MenubarPrimitive.Content>;\n\nfunction MenubarContent({\n className,\n align = \"start\",\n alignOffset = -4,\n sideOffset = 8,\n ...props\n}: MenubarContentProps) {\n return (\n <MenubarPortal>\n <MenubarPrimitive.Content\n data-slot=\"menubar-content\"\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </MenubarPortal>\n );\n}\n\nexport type MenubarItemVariant = \"default\" | \"destructive\";\n\nexport type MenubarItemProps = React.ComponentProps<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n variant?: MenubarItemVariant;\n};\n\nfunction MenubarItem({ className, inset, variant = \"default\", ...props }: MenubarItemProps) {\n return (\n <MenubarPrimitive.Item\n data-slot=\"menubar-item\"\n data-inset={inset}\n data-variant={variant}\n // `text-destructive-ink` chứ KHÔNG `text-destructive`: `--destructive` là màu NỀN (nút xoá),\n // ghim một giá trị cho cả hai theme nên làm CHỮ trên nền popover tối chỉ được 3,53:1 ✗ —\n // và tệ thêm khi focus vì nền chuyển sang `bg-destructive/20` (2,98:1 ✗). Bậc ink đạt cả\n // hai theme, cả hai nền: 7,15:1 / 6,18:1 (light, nghỉ / focus) · 6,42:1 / 5,42:1 (dark).\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-ink data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive-ink data-[variant=destructive]:*:[svg]:!text-destructive-ink [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type MenubarCheckboxItemProps = React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>;\n\nfunction MenubarCheckboxItem({ className, children, checked, ...props }: MenubarCheckboxItemProps) {\n return (\n <MenubarPrimitive.CheckboxItem\n data-slot=\"menubar-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n );\n}\n\nexport type MenubarRadioItemProps = React.ComponentProps<typeof MenubarPrimitive.RadioItem>;\n\nfunction MenubarRadioItem({ className, children, ...props }: MenubarRadioItemProps) {\n return (\n <MenubarPrimitive.RadioItem\n data-slot=\"menubar-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n );\n}\n\nexport type MenubarLabelProps = React.ComponentProps<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n};\n\nfunction MenubarLabel({ className, inset, ...props }: MenubarLabelProps) {\n return (\n <MenubarPrimitive.Label\n data-slot=\"menubar-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarSeparatorProps = React.ComponentProps<typeof MenubarPrimitive.Separator>;\n\nfunction MenubarSeparator({ className, ...props }: MenubarSeparatorProps) {\n return (\n <MenubarPrimitive.Separator\n data-slot=\"menubar-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarShortcutProps = React.ComponentProps<\"span\">;\n\nfunction MenubarShortcut({ className, ...props }: MenubarShortcutProps) {\n return (\n <span\n data-slot=\"menubar-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport type MenubarSubProps = React.ComponentProps<typeof MenubarPrimitive.Sub>;\n\nfunction MenubarSub({ ...props }: MenubarSubProps) {\n return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />;\n}\n\nexport type MenubarSubTriggerProps = React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n};\n\nfunction MenubarSubTrigger({ className, inset, children, ...props }: MenubarSubTriggerProps) {\n return (\n <MenubarPrimitive.SubTrigger\n data-slot=\"menubar-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto h-4 w-4\" />\n </MenubarPrimitive.SubTrigger>\n );\n}\n\n/*\n * ─ VÌ SAO `SubContent` PHẢI BỌC `Portal` ─\n *\n * Không bọc thì Radix render nó (kèm lớp bọc định vị `position: fixed`) làm CON của\n * `MenubarContent`, mà `MenubarContent` có `overflow-x-hidden overflow-y-auto`. `position: fixed`\n * bình thường thoát được `overflow` — TRỪ KHI có tổ tiên tạo containing block cho nó, và\n * `MenubarContent` tạo đúng thứ đó: các lớp `data-[state=open]:animate-in` / `zoom-in-95` /\n * `slide-in-from-*` animate `transform`, với `animation-fill-mode: both` nên transform CÒN LẠI\n * sau khi hiệu ứng chạy xong (`scale(1)` vẫn là transform, không phải `none`).\n *\n * Hệ quả: submenu mở sang BÊN CẠNH menu cha, tức hoàn toàn nằm ngoài hộp của cha theo chiều\n * ngang, và bị `overflow-x-hidden` cắt sạch. Người dùng thấy mục có mũi tên ▸ mà bấm/rê vào\n * không ra gì — không lỗi, không cảnh báo.\n *\n * Đây là hồi quy đã biết của shadcn/ui: nó xuất hiện đúng lúc `MenubarContent` được thêm\n * `max-h-… overflow-y-auto`. Bọc `Portal` đưa submenu ra thẳng `document.body`, thoát cả\n * `overflow` lẫn containing block.\n *\n * ⚠ Đừng \"sửa\" bằng cách bỏ `overflow-y-auto` ở `MenubarContent`: lớp đó có việc của nó (menu\n * dài hơn màn hình thì phải cuộn được).\n */\nexport type MenubarSubContentProps = React.ComponentProps<typeof MenubarPrimitive.SubContent>;\n\nfunction MenubarSubContent({ className, ...props }: MenubarSubContentProps) {\n return (\n <MenubarPrimitive.Portal>\n <MenubarPrimitive.SubContent\n data-slot=\"menubar-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-overlay\",\n className\n )}\n {...props}\n />\n </MenubarPrimitive.Portal>\n );\n}\n\nexport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarLabel,\n MenubarMenu,\n MenubarPortal,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comitor/ui",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Comitor design system — Shadcn/UI tùy biến theo brand Comitor + component dùng chung cho hệ sinh thái SaaS (Tasks, Chat, CRM, HR…)",
5
5
  "license": "MIT",
6
6
  "type": "module",