@burtson-labs/ui 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,7 +58,7 @@ npx shadcn@latest add https://ui.burtson.ai/r/button.json
58
58
 
59
59
  ## <picture><source media="(prefers-color-scheme: dark)" srcset="https://icons.burtson.ai/svg-white/panel-grid.svg"/><img src="https://icons.burtson.ai/svg-black/panel-grid.svg" align="center" alt=""/></picture> Components
60
60
 
61
- Accordion · Alert · Alert Dialog · App Shell · Avatar · Badge · Breadcrumb · Button · Card · Checkbox · Collapsible · Combobox · Command · Copy Button · Dialog · Dropdown Menu · Empty State · Field · Icon Button · Input · Kbd · Label · Navigation Menu · Page Header · Pagination · Popover · Progress · Radio Group · Reasoning · Scroll Area · Secret Input · Select · Separator · Sheet · Skeleton · Slider · Spinner · Stat Card · Status · Steps · Switch · Table · Tabs · Textarea · Toast · Toaster · Toolbar · Tooltip
61
+ Accordion · Alert · Alert Dialog · App Shell · Avatar · Badge · Breadcrumb · Button · Card · Checkbox · Collapsible · Combobox · Command · Context Menu · Copy Button · Dialog · Dropdown Menu · Editor Tabs · Empty State · Field · Icon Button · Input · Kbd · Label · Menubar · Navigation Menu · Onboarding Checklist · Page Header · Pagination · Popover · Progress · Radio Group · Reasoning · Resizable · Scroll Area · Secret Input · Select · Separator · Sheet · Skeleton · Slider · Spinner · Stat Card · Status · Steps · Switch · Table · Tabs · Textarea · Toast · Toaster · Toolbar · Tooltip · Tour · Tree View
62
62
 
63
63
  Live previews and code for each one are at [ui.burtson.ai](https://ui.burtson.ai/docs/components/button).
64
64
 
@@ -0,0 +1,30 @@
1
+ import { ContextMenu as ContextMenuPrimitive } from 'radix-ui';
2
+ import * as React from 'react';
3
+ /**
4
+ * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep
5
+ * your element); the menu opens at the pointer, and from the keyboard with the
6
+ * context-menu key or Shift+F10 on the focused target. Same rows as
7
+ * DropdownMenu, so a command can appear in both.
8
+ */
9
+ declare function ContextMenu(props: React.ComponentProps<typeof ContextMenuPrimitive.Root>): React.JSX.Element;
10
+ declare function ContextMenuTrigger(props: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>): React.JSX.Element;
11
+ declare function ContextMenuGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.Group>): React.JSX.Element;
12
+ declare function ContextMenuContent({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Content>): React.JSX.Element;
13
+ declare function ContextMenuItem({ className, inset, variant, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
14
+ inset?: boolean;
15
+ variant?: 'default' | 'destructive';
16
+ }): React.JSX.Element;
17
+ declare function ContextMenuCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>): React.JSX.Element;
18
+ declare function ContextMenuRadioGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>): React.JSX.Element;
19
+ declare function ContextMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>): React.JSX.Element;
20
+ declare function ContextMenuLabel({ className, inset, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
21
+ inset?: boolean;
22
+ }): React.JSX.Element;
23
+ declare function ContextMenuSeparator({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>): React.JSX.Element;
24
+ declare function ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>): React.JSX.Element;
25
+ declare function ContextMenuSub(props: React.ComponentProps<typeof ContextMenuPrimitive.Sub>): React.JSX.Element;
26
+ declare function ContextMenuSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
27
+ inset?: boolean;
28
+ }): React.JSX.Element;
29
+ declare function ContextMenuSubContent({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>): React.JSX.Element;
30
+ export { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, };
@@ -0,0 +1,131 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { menuItemClasses, surfaceClasses } from "./popover.js";
3
+ import { ContextMenu } from "radix-ui";
4
+ import "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import ChevronRight from "@burtson-labs/icons/react/chevron-right";
7
+ import Check from "@burtson-labs/icons/react/check";
8
+ //#region src/components/context-menu.tsx
9
+ /**
10
+ * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep
11
+ * your element); the menu opens at the pointer, and from the keyboard with the
12
+ * context-menu key or Shift+F10 on the focused target. Same rows as
13
+ * DropdownMenu, so a command can appear in both.
14
+ */
15
+ function ContextMenu$1(props) {
16
+ return /* @__PURE__ */ jsx(ContextMenu.Root, {
17
+ "data-slot": "context-menu",
18
+ ...props
19
+ });
20
+ }
21
+ function ContextMenuTrigger(props) {
22
+ return /* @__PURE__ */ jsx(ContextMenu.Trigger, {
23
+ "data-slot": "context-menu-trigger",
24
+ ...props
25
+ });
26
+ }
27
+ function ContextMenuGroup(props) {
28
+ return /* @__PURE__ */ jsx(ContextMenu.Group, {
29
+ "data-slot": "context-menu-group",
30
+ ...props
31
+ });
32
+ }
33
+ function ContextMenuContent({ className, ...props }) {
34
+ return /* @__PURE__ */ jsx(ContextMenu.Portal, { children: /* @__PURE__ */ jsx(ContextMenu.Content, {
35
+ "data-slot": "context-menu-content",
36
+ className: cn(surfaceClasses, "max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1", className),
37
+ ...props
38
+ }) });
39
+ }
40
+ function ContextMenuItem({ className, inset, variant = "default", ...props }) {
41
+ return /* @__PURE__ */ jsx(ContextMenu.Item, {
42
+ "data-slot": "context-menu-item",
43
+ "data-inset": inset || void 0,
44
+ "data-variant": variant,
45
+ className: cn(menuItemClasses, "data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive", className),
46
+ ...props
47
+ });
48
+ }
49
+ function ContextMenuCheckboxItem({ className, children, checked, ...props }) {
50
+ return /* @__PURE__ */ jsxs(ContextMenu.CheckboxItem, {
51
+ "data-slot": "context-menu-checkbox-item",
52
+ className: cn(menuItemClasses, "pl-8", className),
53
+ checked,
54
+ ...props,
55
+ children: [/* @__PURE__ */ jsx("span", {
56
+ className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
57
+ children: /* @__PURE__ */ jsx(ContextMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, {
58
+ className: "size-4 text-foreground",
59
+ "aria-hidden": true
60
+ }) })
61
+ }), children]
62
+ });
63
+ }
64
+ function ContextMenuRadioGroup(props) {
65
+ return /* @__PURE__ */ jsx(ContextMenu.RadioGroup, {
66
+ "data-slot": "context-menu-radio-group",
67
+ ...props
68
+ });
69
+ }
70
+ function ContextMenuRadioItem({ className, children, ...props }) {
71
+ return /* @__PURE__ */ jsxs(ContextMenu.RadioItem, {
72
+ "data-slot": "context-menu-radio-item",
73
+ className: cn(menuItemClasses, "pl-8", className),
74
+ ...props,
75
+ children: [/* @__PURE__ */ jsx("span", {
76
+ className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
77
+ children: /* @__PURE__ */ jsx(ContextMenu.ItemIndicator, { children: /* @__PURE__ */ jsx("span", { className: "block size-2 rounded-full bg-foreground" }) })
78
+ }), children]
79
+ });
80
+ }
81
+ function ContextMenuLabel({ className, inset, ...props }) {
82
+ return /* @__PURE__ */ jsx(ContextMenu.Label, {
83
+ "data-slot": "context-menu-label",
84
+ "data-inset": inset || void 0,
85
+ className: cn("px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8", className),
86
+ ...props
87
+ });
88
+ }
89
+ function ContextMenuSeparator({ className, ...props }) {
90
+ return /* @__PURE__ */ jsx(ContextMenu.Separator, {
91
+ "data-slot": "context-menu-separator",
92
+ className: cn("-mx-1 my-1 h-px bg-border", className),
93
+ ...props
94
+ });
95
+ }
96
+ function ContextMenuShortcut({ className, ...props }) {
97
+ return /* @__PURE__ */ jsx("span", {
98
+ "data-slot": "context-menu-shortcut",
99
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
100
+ ...props
101
+ });
102
+ }
103
+ function ContextMenuSub(props) {
104
+ return /* @__PURE__ */ jsx(ContextMenu.Sub, {
105
+ "data-slot": "context-menu-sub",
106
+ ...props
107
+ });
108
+ }
109
+ function ContextMenuSubTrigger({ className, inset, children, ...props }) {
110
+ return /* @__PURE__ */ jsxs(ContextMenu.SubTrigger, {
111
+ "data-slot": "context-menu-sub-trigger",
112
+ "data-inset": inset || void 0,
113
+ className: cn(menuItemClasses, "data-[state=open]:bg-muted", className),
114
+ ...props,
115
+ children: [children, /* @__PURE__ */ jsx(ChevronRight, {
116
+ className: "ml-auto size-4",
117
+ "aria-hidden": true
118
+ })]
119
+ });
120
+ }
121
+ function ContextMenuSubContent({ className, ...props }) {
122
+ return /* @__PURE__ */ jsx(ContextMenu.Portal, { children: /* @__PURE__ */ jsx(ContextMenu.SubContent, {
123
+ "data-slot": "context-menu-sub-content",
124
+ className: cn(surfaceClasses, "min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden p-1", className),
125
+ ...props
126
+ }) });
127
+ }
128
+ //#endregion
129
+ export { ContextMenu$1 as ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger };
130
+
131
+ //# sourceMappingURL=context-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.js","names":["ContextMenu","ContextMenuPrimitive","itemClasses"],"sources":["../../src/components/context-menu.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport { ContextMenu as ContextMenuPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { menuItemClasses as itemClasses, surfaceClasses } from './popover';\n\n/**\n * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep\n * your element); the menu opens at the pointer, and from the keyboard with the\n * context-menu key or Shift+F10 on the focused target. Same rows as\n * DropdownMenu, so a command can appear in both.\n */\nfunction ContextMenu(props: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger(props: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nfunction ContextMenuGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nfunction ContextMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n surfaceClasses,\n 'max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nfunction ContextMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset || undefined}\n data-variant={variant}\n className={cn(\n itemClasses,\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(itemClasses, 'pl-8', className)}\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 <Check className=\"size-4 text-foreground\" aria-hidden />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction ContextMenuRadioGroup(\n props: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>,\n) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nfunction ContextMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <span className=\"block size-2 rounded-full bg-foreground\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nfunction ContextMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset || undefined}\n className={cn(\n 'px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSub(props: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset || undefined}\n className={cn(itemClasses, 'data-[state=open]:bg-muted', className)}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto size-4\" aria-hidden />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nfunction ContextMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n surfaceClasses,\n 'min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n};\n"],"mappings":"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"}
@@ -1,12 +1,11 @@
1
1
  import { cn } from "../lib/utils.js";
2
- import { surfaceClasses } from "./popover.js";
2
+ import { menuItemClasses, surfaceClasses } from "./popover.js";
3
3
  import { DropdownMenu } from "radix-ui";
4
4
  import "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import ChevronRight from "@burtson-labs/icons/react/chevron-right";
7
7
  import Check from "@burtson-labs/icons/react/check";
8
8
  //#region src/components/dropdown-menu.tsx
9
- var itemClasses = "relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] outline-hidden select-none focus:bg-muted focus:text-foreground 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 [&_svg:not([class*='text-'])]:text-muted-foreground";
10
9
  function DropdownMenu$1(props) {
11
10
  return /* @__PURE__ */ jsx(DropdownMenu.Root, {
12
11
  "data-slot": "dropdown-menu",
@@ -38,14 +37,14 @@ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
38
37
  "data-slot": "dropdown-menu-item",
39
38
  "data-inset": inset || void 0,
40
39
  "data-variant": variant,
41
- className: cn(itemClasses, "data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive", className),
40
+ className: cn(menuItemClasses, "data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive", className),
42
41
  ...props
43
42
  });
44
43
  }
45
44
  function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
46
45
  return /* @__PURE__ */ jsxs(DropdownMenu.CheckboxItem, {
47
46
  "data-slot": "dropdown-menu-checkbox-item",
48
- className: cn(itemClasses, "pl-8", className),
47
+ className: cn(menuItemClasses, "pl-8", className),
49
48
  checked,
50
49
  ...props,
51
50
  children: [/* @__PURE__ */ jsx("span", {
@@ -66,7 +65,7 @@ function DropdownMenuRadioGroup(props) {
66
65
  function DropdownMenuRadioItem({ className, children, ...props }) {
67
66
  return /* @__PURE__ */ jsxs(DropdownMenu.RadioItem, {
68
67
  "data-slot": "dropdown-menu-radio-item",
69
- className: cn(itemClasses, "pl-8", className),
68
+ className: cn(menuItemClasses, "pl-8", className),
70
69
  ...props,
71
70
  children: [/* @__PURE__ */ jsx("span", {
72
71
  className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
@@ -106,7 +105,7 @@ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
106
105
  return /* @__PURE__ */ jsxs(DropdownMenu.SubTrigger, {
107
106
  "data-slot": "dropdown-menu-sub-trigger",
108
107
  "data-inset": inset || void 0,
109
- className: cn(itemClasses, "data-[state=open]:bg-muted", className),
108
+ className: cn(menuItemClasses, "data-[state=open]:bg-muted", className),
110
109
  ...props,
111
110
  children: [children, /* @__PURE__ */ jsx(ChevronRight, {
112
111
  className: "ml-auto size-4",
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-menu.js","names":["DropdownMenu","DropdownMenuPrimitive"],"sources":["../../src/components/dropdown-menu.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { surfaceClasses } from './popover';\n\n// 32px rows, 8px radius; the focused row is a quiet fill, like an active tab.\nconst itemClasses =\n \"relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] outline-hidden select-none focus:bg-muted focus:text-foreground 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 [&_svg:not([class*='text-'])]:text-muted-foreground\";\n\nfunction DropdownMenu(props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuTrigger(props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuGroup(props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n surfaceClasses,\n 'max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1',\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset || undefined}\n data-variant={variant}\n className={cn(\n itemClasses,\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(itemClasses, 'pl-8', className)}\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 <Check className=\"size-4 text-foreground\" aria-hidden />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <span className=\"block size-2 rounded-full bg-foreground\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset || undefined}\n className={cn(\n 'px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub(props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset || undefined}\n className={cn(itemClasses, 'data-[state=open]:bg-muted', className)}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto size-4\" aria-hidden />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n surfaceClasses,\n 'min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden p-1',\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 DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-menu.js","names":["DropdownMenu","DropdownMenuPrimitive","itemClasses"],"sources":["../../src/components/dropdown-menu.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { menuItemClasses as itemClasses, surfaceClasses } from './popover';\n\nfunction DropdownMenu(props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuTrigger(props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuGroup(props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n surfaceClasses,\n 'max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1',\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset || undefined}\n data-variant={variant}\n className={cn(\n itemClasses,\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(itemClasses, 'pl-8', className)}\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 <Check className=\"size-4 text-foreground\" aria-hidden />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <span className=\"block size-2 rounded-full bg-foreground\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset || undefined}\n className={cn(\n 'px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub(props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset || undefined}\n className={cn(itemClasses, 'data-[state=open]:bg-muted', className)}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto size-4\" aria-hidden />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n surfaceClasses,\n 'min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden p-1',\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 DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n};\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ export interface EditorTab {
3
+ /** Stable identity, usually the file path. */
4
+ id: string;
5
+ label: string;
6
+ /** Full path or context; the tooltip and the accessible description. */
7
+ description?: string;
8
+ icon?: React.ReactNode;
9
+ /** Unsaved changes: a dot replaces the close button until hover. */
10
+ dirty?: boolean;
11
+ /** Default true. */
12
+ closeable?: boolean;
13
+ /** A preview tab that the next opened file replaces; shown in italics. */
14
+ preview?: boolean;
15
+ /** The id of the panel this tab shows, for aria-controls. */
16
+ controls?: string;
17
+ }
18
+ export interface EditorTabsProps extends Omit<React.ComponentProps<'div'>, 'children' | 'aria-label'> {
19
+ tabs: EditorTab[];
20
+ activeId: string | null;
21
+ onActiveChange: (id: string) => void;
22
+ /**
23
+ * A request to close. The component never removes a tab itself: for a dirty
24
+ * tab, ask the person (save, discard, cancel) and then update `tabs`.
25
+ */
26
+ onClose?: (id: string) => void;
27
+ /** Reorder by drag or Ctrl+Shift+PageUp/PageDown. `toIndex` is the new position. */
28
+ onMove?: (id: string, toIndex: number) => void;
29
+ /** Required: e.g. "Open editors". */
30
+ 'aria-label': string;
31
+ /** Right-hand slot for split, more and similar buttons. */
32
+ actions?: React.ReactNode;
33
+ /** Right-click on a tab. */
34
+ onTabContextMenu?: (id: string, event: React.MouseEvent) => void;
35
+ }
36
+ /**
37
+ * The strip of open files above an editor. One tab stop; Left/Right/Home/End
38
+ * move focus, Enter or Space opens, Delete asks to close, Ctrl+Shift+PageUp
39
+ * and PageDown move the tab. Middle-click closes. The strip scrolls when the
40
+ * tabs overflow and keeps the active tab in view.
41
+ */
42
+ declare function EditorTabs({ tabs, activeId, onActiveChange, onClose, onMove, actions, onTabContextMenu, className, 'aria-label': ariaLabel, ...props }: EditorTabsProps): React.JSX.Element;
43
+ export { EditorTabs };
@@ -0,0 +1,178 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import * as React from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import X from "@burtson-labs/icons/react/x";
5
+ //#region src/components/editor-tabs.tsx
6
+ /**
7
+ * The strip of open files above an editor. One tab stop; Left/Right/Home/End
8
+ * move focus, Enter or Space opens, Delete asks to close, Ctrl+Shift+PageUp
9
+ * and PageDown move the tab. Middle-click closes. The strip scrolls when the
10
+ * tabs overflow and keeps the active tab in view.
11
+ */
12
+ function EditorTabs({ tabs, activeId, onActiveChange, onClose, onMove, actions, onTabContextMenu, className, "aria-label": ariaLabel, ...props }) {
13
+ const baseId = React.useId();
14
+ const tabRefs = React.useRef(/* @__PURE__ */ new Map());
15
+ const listRef = React.useRef(null);
16
+ const [focusedId, setFocusedId] = React.useState(null);
17
+ const [dragId, setDragId] = React.useState(null);
18
+ const lastIds = React.useRef([]);
19
+ const hadFocus = React.useRef(false);
20
+ const ids = tabs.map((t) => t.id);
21
+ const idsKey = ids.join("\0");
22
+ const tabStop = (focusedId && ids.includes(focusedId) ? focusedId : null) ?? (activeId && ids.includes(activeId) ? activeId : null) ?? ids[0] ?? null;
23
+ React.useEffect(() => {
24
+ if (activeId) tabRefs.current.get(activeId)?.scrollIntoView?.({
25
+ block: "nearest",
26
+ inline: "nearest"
27
+ });
28
+ }, [activeId]);
29
+ React.useLayoutEffect(() => {
30
+ if (focusedId && !ids.includes(focusedId)) {
31
+ const next = (activeId && ids.includes(activeId) ? activeId : null) ?? ids[Math.min(Math.max(0, lastIds.current.indexOf(focusedId)), ids.length - 1)] ?? null;
32
+ setFocusedId(next);
33
+ const active = document.activeElement;
34
+ if (next && hadFocus.current && (!active || active === document.body)) tabRefs.current.get(next)?.focus();
35
+ }
36
+ lastIds.current = ids;
37
+ }, [
38
+ focusedId,
39
+ idsKey,
40
+ activeId
41
+ ]);
42
+ const focusTab = (id) => {
43
+ if (!id) return;
44
+ setFocusedId(id);
45
+ tabRefs.current.get(id)?.focus();
46
+ };
47
+ const onKeyDown = (event, tab) => {
48
+ const i = ids.indexOf(tab.id);
49
+ const [prev, next] = (listRef.current ? getComputedStyle(listRef.current).direction === "rtl" : false) ? ["ArrowRight", "ArrowLeft"] : ["ArrowLeft", "ArrowRight"];
50
+ let handled = true;
51
+ if (event.ctrlKey && event.shiftKey && (event.key === "PageUp" || event.key === "PageDown")) {
52
+ const to = event.key === "PageUp" ? i - 1 : i + 1;
53
+ if (onMove && to >= 0 && to < ids.length) onMove(tab.id, to);
54
+ } else if (event.key === prev) focusTab(ids[(i - 1 + ids.length) % ids.length]);
55
+ else if (event.key === next) focusTab(ids[(i + 1) % ids.length]);
56
+ else if (event.key === "Home") focusTab(ids[0]);
57
+ else if (event.key === "End") focusTab(ids[ids.length - 1]);
58
+ else if (event.key === "Delete" && tab.closeable !== false && onClose) onClose(tab.id);
59
+ else handled = false;
60
+ if (handled) event.preventDefault();
61
+ };
62
+ return /* @__PURE__ */ jsxs("div", {
63
+ "data-slot": "editor-tabs",
64
+ className: cn("flex h-9 min-w-0 items-stretch border-b bg-surface-muted", className),
65
+ ...props,
66
+ children: [/* @__PURE__ */ jsx("div", {
67
+ ref: listRef,
68
+ role: "tablist",
69
+ "aria-label": ariaLabel,
70
+ "aria-orientation": "horizontal",
71
+ className: "flex min-w-0 flex-1 items-stretch overflow-x-auto [scrollbar-width:thin]",
72
+ onFocus: () => hadFocus.current = true,
73
+ onBlur: (event) => {
74
+ if (!listRef.current?.contains(event.relatedTarget)) hadFocus.current = false;
75
+ },
76
+ children: tabs.map((tab, i) => {
77
+ const active = tab.id === activeId;
78
+ const closeable = tab.closeable !== false && Boolean(onClose);
79
+ const tabId = `${baseId}-tab-${i}`;
80
+ return /* @__PURE__ */ jsxs("div", {
81
+ "data-slot": "editor-tab",
82
+ "data-state": active ? "active" : "inactive",
83
+ "data-dirty": tab.dirty || void 0,
84
+ "data-dragging": dragId === tab.id || void 0,
85
+ draggable: Boolean(onMove),
86
+ onDragStart: (event) => {
87
+ setDragId(tab.id);
88
+ event.dataTransfer.effectAllowed = "move";
89
+ event.dataTransfer.setData("text/plain", tab.id);
90
+ },
91
+ onDragEnd: () => setDragId(null),
92
+ onDragOver: (event) => {
93
+ if (dragId) event.preventDefault();
94
+ },
95
+ onDrop: (event) => {
96
+ event.preventDefault();
97
+ if (dragId && dragId !== tab.id) onMove?.(dragId, i);
98
+ setDragId(null);
99
+ },
100
+ onAuxClick: (event) => {
101
+ if (event.button === 1 && closeable) {
102
+ event.preventDefault();
103
+ onClose?.(tab.id);
104
+ }
105
+ },
106
+ onContextMenu: onTabContextMenu ? (event) => onTabContextMenu(tab.id, event) : void 0,
107
+ className: cn("group/tab relative flex max-w-60 shrink-0 items-center border-e text-[13px] text-muted-foreground", "hover:bg-muted/60 data-[state=active]:bg-background data-[state=active]:text-foreground", "data-[state=active]:before:absolute data-[state=active]:before:inset-x-0 data-[state=active]:before:top-0 data-[state=active]:before:h-0.5 data-[state=active]:before:bg-brand data-[state=active]:before:content-[\"\"]", "data-[dragging]:opacity-50"),
108
+ children: [
109
+ /* @__PURE__ */ jsxs("button", {
110
+ ref: (el) => {
111
+ if (el) tabRefs.current.set(tab.id, el);
112
+ else tabRefs.current.delete(tab.id);
113
+ },
114
+ type: "button",
115
+ role: "tab",
116
+ id: tabId,
117
+ "aria-selected": active,
118
+ "aria-controls": tab.controls,
119
+ "aria-describedby": tab.description ? `${tabId}-desc` : void 0,
120
+ title: tab.description,
121
+ tabIndex: tab.id === tabStop ? 0 : -1,
122
+ onFocus: () => setFocusedId(tab.id),
123
+ onClick: () => onActiveChange(tab.id),
124
+ onKeyDown: (event) => onKeyDown(event, tab),
125
+ className: cn("flex h-full min-w-0 items-center gap-1.5 ps-3 outline-none focus-visible:shadow-[inset_0_0_0_1px_var(--ring)]", closeable ? "pe-1" : "pe-3"),
126
+ children: [
127
+ tab.icon && /* @__PURE__ */ jsx("span", {
128
+ "aria-hidden": true,
129
+ className: "flex shrink-0 [&_svg]:size-4",
130
+ children: tab.icon
131
+ }),
132
+ /* @__PURE__ */ jsx("span", {
133
+ className: cn("truncate", tab.preview && "italic"),
134
+ children: tab.label
135
+ }),
136
+ tab.dirty && /* @__PURE__ */ jsx("span", {
137
+ className: "sr-only",
138
+ children: ", unsaved changes"
139
+ })
140
+ ]
141
+ }),
142
+ tab.description && /* @__PURE__ */ jsx("span", {
143
+ id: `${tabId}-desc`,
144
+ hidden: true,
145
+ children: tab.description
146
+ }),
147
+ closeable ? /* @__PURE__ */ jsxs("button", {
148
+ type: "button",
149
+ tabIndex: -1,
150
+ "aria-label": `Close ${tab.label}`,
151
+ title: "Close (Delete)",
152
+ onClick: () => onClose?.(tab.id),
153
+ className: "me-1 flex size-5 shrink-0 items-center justify-center rounded-xs text-muted-foreground outline-none hover:bg-muted hover:text-foreground",
154
+ children: [tab.dirty && /* @__PURE__ */ jsx("span", {
155
+ "aria-hidden": true,
156
+ className: "size-2 rounded-full bg-foreground/70 group-hover/tab:hidden"
157
+ }), /* @__PURE__ */ jsx(X, {
158
+ "aria-hidden": true,
159
+ className: cn("size-3.5", tab.dirty ? "hidden group-hover/tab:block" : "opacity-0 group-hover/tab:opacity-100 group-data-[state=active]/tab:opacity-100 group-focus-within/tab:opacity-100")
160
+ })]
161
+ }) : tab.dirty ? /* @__PURE__ */ jsx("span", {
162
+ "aria-hidden": true,
163
+ className: "me-3 size-2 shrink-0 rounded-full bg-foreground/70"
164
+ }) : null
165
+ ]
166
+ }, tab.id);
167
+ })
168
+ }), actions && /* @__PURE__ */ jsx("div", {
169
+ "data-slot": "editor-tabs-actions",
170
+ className: "flex shrink-0 items-center gap-0.5 px-1",
171
+ children: actions
172
+ })]
173
+ });
174
+ }
175
+ //#endregion
176
+ export { EditorTabs };
177
+
178
+ //# sourceMappingURL=editor-tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-tabs.js","names":[],"sources":["../../src/components/editor-tabs.tsx"],"sourcesContent":["import X from '@burtson-labs/icons/react/x';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface EditorTab {\n /** Stable identity, usually the file path. */\n id: string;\n label: string;\n /** Full path or context; the tooltip and the accessible description. */\n description?: string;\n icon?: React.ReactNode;\n /** Unsaved changes: a dot replaces the close button until hover. */\n dirty?: boolean;\n /** Default true. */\n closeable?: boolean;\n /** A preview tab that the next opened file replaces; shown in italics. */\n preview?: boolean;\n /** The id of the panel this tab shows, for aria-controls. */\n controls?: string;\n}\n\nexport interface EditorTabsProps extends Omit<\n React.ComponentProps<'div'>,\n 'children' | 'aria-label'\n> {\n tabs: EditorTab[];\n activeId: string | null;\n onActiveChange: (id: string) => void;\n /**\n * A request to close. The component never removes a tab itself: for a dirty\n * tab, ask the person (save, discard, cancel) and then update `tabs`.\n */\n onClose?: (id: string) => void;\n /** Reorder by drag or Ctrl+Shift+PageUp/PageDown. `toIndex` is the new position. */\n onMove?: (id: string, toIndex: number) => void;\n /** Required: e.g. \"Open editors\". */\n 'aria-label': string;\n /** Right-hand slot for split, more and similar buttons. */\n actions?: React.ReactNode;\n /** Right-click on a tab. */\n onTabContextMenu?: (id: string, event: React.MouseEvent) => void;\n}\n\n/**\n * The strip of open files above an editor. One tab stop; Left/Right/Home/End\n * move focus, Enter or Space opens, Delete asks to close, Ctrl+Shift+PageUp\n * and PageDown move the tab. Middle-click closes. The strip scrolls when the\n * tabs overflow and keeps the active tab in view.\n */\nfunction EditorTabs({\n tabs,\n activeId,\n onActiveChange,\n onClose,\n onMove,\n actions,\n onTabContextMenu,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: EditorTabsProps) {\n const baseId = React.useId();\n const tabRefs = React.useRef(new Map<string, HTMLButtonElement>());\n const listRef = React.useRef<HTMLDivElement>(null);\n const [focusedId, setFocusedId] = React.useState<string | null>(null);\n const [dragId, setDragId] = React.useState<string | null>(null);\n const lastIds = React.useRef<string[]>([]);\n const hadFocus = React.useRef(false);\n\n const ids = tabs.map((t) => t.id);\n const idsKey = ids.join('\\u0000');\n const tabStop =\n (focusedId && ids.includes(focusedId) ? focusedId : null) ??\n (activeId && ids.includes(activeId) ? activeId : null) ??\n ids[0] ??\n null;\n\n React.useEffect(() => {\n if (activeId)\n tabRefs.current.get(activeId)?.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });\n }, [activeId]);\n\n // After a close, keep keyboard focus in the strip: the active tab if the\n // app picked one, else the neighbour at the closed tab's position.\n React.useLayoutEffect(() => {\n if (focusedId && !ids.includes(focusedId)) {\n const next =\n (activeId && ids.includes(activeId) ? activeId : null) ??\n ids[Math.min(Math.max(0, lastIds.current.indexOf(focusedId)), ids.length - 1)] ??\n null;\n setFocusedId(next);\n const active = document.activeElement;\n if (next && hadFocus.current && (!active || active === document.body))\n tabRefs.current.get(next)?.focus();\n }\n lastIds.current = ids;\n // ids is derived from tabs each render; idsKey is its stable form.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [focusedId, idsKey, activeId]);\n\n const focusTab = (id: string | undefined) => {\n if (!id) return;\n setFocusedId(id);\n tabRefs.current.get(id)?.focus();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, tab: EditorTab) => {\n const i = ids.indexOf(tab.id);\n const rtl = listRef.current ? getComputedStyle(listRef.current).direction === 'rtl' : false;\n const [prev, next] = rtl ? ['ArrowRight', 'ArrowLeft'] : ['ArrowLeft', 'ArrowRight'];\n let handled = true;\n if (event.ctrlKey && event.shiftKey && (event.key === 'PageUp' || event.key === 'PageDown')) {\n const to = event.key === 'PageUp' ? i - 1 : i + 1;\n if (onMove && to >= 0 && to < ids.length) onMove(tab.id, to);\n } else if (event.key === prev) focusTab(ids[(i - 1 + ids.length) % ids.length]);\n else if (event.key === next) focusTab(ids[(i + 1) % ids.length]);\n else if (event.key === 'Home') focusTab(ids[0]);\n else if (event.key === 'End') focusTab(ids[ids.length - 1]);\n else if (event.key === 'Delete' && tab.closeable !== false && onClose) onClose(tab.id);\n else handled = false;\n if (handled) event.preventDefault();\n };\n\n return (\n <div\n data-slot=\"editor-tabs\"\n className={cn('flex h-9 min-w-0 items-stretch border-b bg-surface-muted', className)}\n {...props}\n >\n <div\n ref={listRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation=\"horizontal\"\n className=\"flex min-w-0 flex-1 items-stretch overflow-x-auto [scrollbar-width:thin]\"\n onFocus={() => (hadFocus.current = true)}\n onBlur={(event) => {\n if (!listRef.current?.contains(event.relatedTarget)) hadFocus.current = false;\n }}\n >\n {tabs.map((tab, i) => {\n const active = tab.id === activeId;\n const closeable = tab.closeable !== false && Boolean(onClose);\n const tabId = `${baseId}-tab-${i}`;\n return (\n <div\n key={tab.id}\n data-slot=\"editor-tab\"\n data-state={active ? 'active' : 'inactive'}\n data-dirty={tab.dirty || undefined}\n data-dragging={dragId === tab.id || undefined}\n draggable={Boolean(onMove)}\n onDragStart={(event) => {\n setDragId(tab.id);\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', tab.id);\n }}\n onDragEnd={() => setDragId(null)}\n onDragOver={(event) => {\n if (dragId) event.preventDefault();\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (dragId && dragId !== tab.id) onMove?.(dragId, i);\n setDragId(null);\n }}\n onAuxClick={(event) => {\n if (event.button === 1 && closeable) {\n event.preventDefault();\n onClose?.(tab.id);\n }\n }}\n onContextMenu={\n onTabContextMenu ? (event) => onTabContextMenu(tab.id, event) : undefined\n }\n className={cn(\n 'group/tab relative flex max-w-60 shrink-0 items-center border-e text-[13px] text-muted-foreground',\n 'hover:bg-muted/60 data-[state=active]:bg-background data-[state=active]:text-foreground',\n // The active tab's top edge carries the brand colour.\n 'data-[state=active]:before:absolute data-[state=active]:before:inset-x-0 data-[state=active]:before:top-0 data-[state=active]:before:h-0.5 data-[state=active]:before:bg-brand data-[state=active]:before:content-[\"\"]',\n 'data-[dragging]:opacity-50',\n )}\n >\n <button\n ref={(el) => {\n if (el) tabRefs.current.set(tab.id, el);\n else tabRefs.current.delete(tab.id);\n }}\n type=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={active}\n aria-controls={tab.controls}\n aria-describedby={tab.description ? `${tabId}-desc` : undefined}\n title={tab.description}\n tabIndex={tab.id === tabStop ? 0 : -1}\n onFocus={() => setFocusedId(tab.id)}\n onClick={() => onActiveChange(tab.id)}\n onKeyDown={(event) => onKeyDown(event, tab)}\n className={cn(\n 'flex h-full min-w-0 items-center gap-1.5 ps-3 outline-none focus-visible:shadow-[inset_0_0_0_1px_var(--ring)]',\n closeable ? 'pe-1' : 'pe-3',\n )}\n >\n {tab.icon && (\n <span aria-hidden className=\"flex shrink-0 [&_svg]:size-4\">\n {tab.icon}\n </span>\n )}\n <span className={cn('truncate', tab.preview && 'italic')}>{tab.label}</span>\n {tab.dirty && <span className=\"sr-only\">, unsaved changes</span>}\n </button>\n {tab.description && (\n <span id={`${tabId}-desc`} hidden>\n {tab.description}\n </span>\n )}\n {closeable ? (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={`Close ${tab.label}`}\n title=\"Close (Delete)\"\n onClick={() => onClose?.(tab.id)}\n className=\"me-1 flex size-5 shrink-0 items-center justify-center rounded-xs text-muted-foreground outline-none hover:bg-muted hover:text-foreground\"\n >\n {tab.dirty && (\n <span\n aria-hidden\n className=\"size-2 rounded-full bg-foreground/70 group-hover/tab:hidden\"\n />\n )}\n <X\n aria-hidden\n className={cn(\n 'size-3.5',\n tab.dirty\n ? 'hidden group-hover/tab:block'\n : 'opacity-0 group-hover/tab:opacity-100 group-data-[state=active]/tab:opacity-100 group-focus-within/tab:opacity-100',\n )}\n />\n </button>\n ) : tab.dirty ? (\n <span aria-hidden className=\"me-3 size-2 shrink-0 rounded-full bg-foreground/70\" />\n ) : null}\n </div>\n );\n })}\n </div>\n {actions && (\n <div data-slot=\"editor-tabs-actions\" className=\"flex shrink-0 items-center gap-0.5 px-1\">\n {actions}\n </div>\n )}\n </div>\n );\n}\n\nexport { EditorTabs };\n"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Menubar as MenubarPrimitive } from 'radix-ui';
2
+ import * as React from 'react';
3
+ /**
4
+ * An application menu bar (File, Edit, View). Left/Right move between menus,
5
+ * Down opens one, and an open menu follows the pointer across triggers. Rows
6
+ * match DropdownMenu and ContextMenu.
7
+ */
8
+ declare function Menubar({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Root>): React.JSX.Element;
9
+ declare function MenubarMenu(props: React.ComponentProps<typeof MenubarPrimitive.Menu>): React.JSX.Element;
10
+ declare function MenubarTrigger({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Trigger>): React.JSX.Element;
11
+ declare function MenubarGroup(props: React.ComponentProps<typeof MenubarPrimitive.Group>): React.JSX.Element;
12
+ declare function MenubarContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof MenubarPrimitive.Content>): React.JSX.Element;
13
+ declare function MenubarItem({ className, inset, variant, ...props }: React.ComponentProps<typeof MenubarPrimitive.Item> & {
14
+ inset?: boolean;
15
+ variant?: 'default' | 'destructive';
16
+ }): React.JSX.Element;
17
+ declare function MenubarCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>): React.JSX.Element;
18
+ declare function MenubarRadioGroup(props: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>): React.JSX.Element;
19
+ declare function MenubarRadioItem({ className, children, ...props }: React.ComponentProps<typeof MenubarPrimitive.RadioItem>): React.JSX.Element;
20
+ declare function MenubarLabel({ className, inset, ...props }: React.ComponentProps<typeof MenubarPrimitive.Label> & {
21
+ inset?: boolean;
22
+ }): React.JSX.Element;
23
+ declare function MenubarSeparator({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Separator>): React.JSX.Element;
24
+ declare function MenubarShortcut({ className, ...props }: React.ComponentProps<'span'>): React.JSX.Element;
25
+ declare function MenubarSub(props: React.ComponentProps<typeof MenubarPrimitive.Sub>): React.JSX.Element;
26
+ declare function MenubarSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {
27
+ inset?: boolean;
28
+ }): React.JSX.Element;
29
+ declare function MenubarSubContent({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.SubContent>): React.JSX.Element;
30
+ export { Menubar, MenubarMenu, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, };