@godxjp/ui 6.12.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +5 -0
  2. package/dist/aspect-ratio-DGoYrOry.d.ts +6 -0
  3. package/dist/avatar-D9MdXzfF.d.ts +8 -0
  4. package/dist/{checkbox-9w-eF8sM.d.ts → checkbox-CK2mYEpD.d.ts} +1 -1
  5. package/dist/{chunk-T2S3IGZG.js → chunk-6TSU4IHV.js} +1 -1
  6. package/dist/chunk-7AMHT5Z5.js +61 -0
  7. package/dist/{chunk-EE3B3TEQ.js → chunk-ARDVPIF4.js} +1 -1
  8. package/dist/chunk-B3WX53JQ.js +40 -0
  9. package/dist/{chunk-T4UT3B3K.js → chunk-EQRQM6RF.js} +127 -182
  10. package/dist/{chunk-JBEIL3VD.js → chunk-FBHN6OO4.js} +1 -1
  11. package/dist/chunk-FRU44GA2.js +18 -0
  12. package/dist/chunk-FYM3MJSK.js +59 -0
  13. package/dist/{chunk-M64MVRLS.js → chunk-HKQITNB3.js} +12 -48
  14. package/dist/{chunk-GXHZAJUA.js → chunk-O2OUNXV4.js} +10 -10
  15. package/dist/{chunk-BM5LIDCS.js → chunk-OGFWIXRO.js} +7 -16
  16. package/dist/chunk-R2W2FX5Q.js +48 -0
  17. package/dist/chunk-SEG2YBXF.js +29 -0
  18. package/dist/{chunk-XG7XDYIM.js → chunk-V3N266PT.js} +48 -2
  19. package/dist/{chunk-TW4IRRAX.js → chunk-VXXKR5U4.js} +6 -47
  20. package/dist/{chunk-SWGQX3AP.js → chunk-Y3XBNUTD.js} +1 -1
  21. package/dist/components/admin/index.d.ts +12 -10
  22. package/dist/components/admin/index.js +18 -17
  23. package/dist/components/data-display/badge.d.ts +12 -4
  24. package/dist/components/data-display/badge.js +3 -1
  25. package/dist/components/data-display/card.d.ts +5 -5
  26. package/dist/components/data-display/card.js +1 -1
  27. package/dist/components/data-display/index.d.ts +10 -22
  28. package/dist/components/data-display/index.js +24 -33
  29. package/dist/components/data-entry/autocomplete.d.ts +1 -1
  30. package/dist/components/data-entry/autocomplete.js +3 -3
  31. package/dist/components/data-entry/calendar.d.ts +1 -1
  32. package/dist/components/data-entry/cascader.d.ts +1 -1
  33. package/dist/components/data-entry/checkbox.d.ts +2 -2
  34. package/dist/components/data-entry/color-picker.d.ts +1 -1
  35. package/dist/components/data-entry/color-picker.js +2 -2
  36. package/dist/components/data-entry/command.d.ts +5 -5
  37. package/dist/components/data-entry/date-picker.d.ts +1 -1
  38. package/dist/components/data-entry/date-picker.js +2 -2
  39. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  40. package/dist/components/data-entry/date-range-picker.js +2 -2
  41. package/dist/components/data-entry/index.d.ts +18 -14
  42. package/dist/components/data-entry/index.js +18 -78
  43. package/dist/components/data-entry/radio.d.ts +1 -1
  44. package/dist/components/data-entry/select.d.ts +1 -1
  45. package/dist/components/data-entry/select.js +3 -3
  46. package/dist/components/data-entry/slider.d.ts +1 -1
  47. package/dist/components/data-entry/switch.d.ts +1 -1
  48. package/dist/components/data-entry/switch.js +1 -1
  49. package/dist/components/data-entry/time-picker.d.ts +1 -1
  50. package/dist/components/data-entry/time-picker.js +2 -2
  51. package/dist/components/data-entry/transfer.d.ts +2 -2
  52. package/dist/components/data-entry/transfer.js +2 -2
  53. package/dist/components/data-entry/tree-select.d.ts +1 -1
  54. package/dist/components/data-entry/upload.d.ts +2 -2
  55. package/dist/components/data-entry/upload.js +2 -2
  56. package/dist/components/feedback/index.d.ts +2 -1
  57. package/dist/components/feedback/index.js +6 -5
  58. package/dist/components/layout/index.d.ts +11 -38
  59. package/dist/components/layout/index.js +3 -4
  60. package/dist/components/navigation/index.d.ts +2 -3
  61. package/dist/components/navigation/index.js +6 -7
  62. package/dist/components/navigation/pagination.d.ts +1 -1
  63. package/dist/components/navigation/pagination.js +4 -4
  64. package/dist/components/navigation/steps.d.ts +2 -2
  65. package/dist/components/navigation/tabs.d.ts +14 -2
  66. package/dist/components/navigation/tabs.js +1 -1
  67. package/dist/components/ui/index.d.ts +14 -7
  68. package/dist/components/ui/index.js +22 -19
  69. package/dist/{data-display.prop-i0iaSwMV.d.ts → data-display.prop-CXP9Jfdn.d.ts} +14 -14
  70. package/dist/{data-entry.prop-Cjidhei7.d.ts → data-entry.prop-CpSx5dX6.d.ts} +1 -17
  71. package/dist/{data-table-Bg7fPpXy.d.ts → data-table-C5lcmAwE.d.ts} +7 -30
  72. package/dist/{filter-bar-BpUvE_yO.d.ts → filter-bar-zSKz7YCR.d.ts} +1 -1
  73. package/dist/index.d.ts +12 -10
  74. package/dist/index.js +18 -17
  75. package/dist/{navigation.prop-Ck5_gSfs.d.ts → navigation.prop-DAH4ysXj.d.ts} +6 -7
  76. package/dist/props/components/index.d.ts +3 -3
  77. package/dist/props/index.d.ts +3 -3
  78. package/dist/props/index.js +1 -1
  79. package/dist/props/registry.d.ts +7 -12
  80. package/dist/props/registry.js +1 -1
  81. package/dist/{search-input-mAZy3Den.d.ts → search-input-rR2XDrjv.d.ts} +1 -1
  82. package/dist/skeleton-CqFO4dRc.d.ts +20 -0
  83. package/dist/styles/badge-layout.css +2 -2
  84. package/dist/styles/card-layout.css +19 -19
  85. package/dist/styles/control.css +68 -0
  86. package/dist/styles/data-display-layout.css +23 -81
  87. package/dist/styles/layout.css +19 -71
  88. package/dist/toggle-group-BulJgKh3.d.ts +26 -0
  89. package/dist/tokens/primitives/card.css +9 -9
  90. package/dist/use-toast-Dsw3yE2S.d.ts +19 -0
  91. package/package.json +11 -7
  92. package/dist/chunk-BPSKQUL2.js +0 -68
  93. package/dist/chunk-PIIRNAXA.js +0 -26
  94. package/dist/chunk-WXW43RK5.js +0 -24
  95. package/dist/components/navigation/tabs-items.d.ts +0 -12
  96. package/dist/components/navigation/tabs-items.js +0 -3
  97. package/dist/use-toast-Dol5bdY3.d.ts +0 -34
  98. package/dist/{chunk-I3272Y2C.js → chunk-25ZZ2W3M.js} +1 -1
  99. package/dist/{chunk-AZS7553U.js → chunk-EXBWDW5E.js} +1 -1
  100. package/dist/{chunk-K27I23OA.js → chunk-NTUHJ37K.js} +1 -1
  101. package/dist/{chunk-Y7AV7QJO.js → chunk-OXKY5QMK.js} +1 -1
  102. package/dist/{chunk-ZTYEH3UW.js → chunk-TT2L7JM6.js} +1 -1
  103. package/dist/{chunk-GH7E5N6F.js → chunk-ZKIAZDVU.js} +1 -1
  104. package/dist/{chunk-YVBZ37ZE.js → chunk-ZR2TIBPG.js} +1 -1
package/README.md CHANGED
@@ -126,8 +126,13 @@ pnpm preview # preview app → http://localhost:6008 (fixed port, kills
126
126
  pnpm preview:build # static build — the integration test for examples + docs
127
127
  pnpm docs:sync-primitives # regenerate docs/primitives/**/*.md from source
128
128
  pnpm typecheck && pnpm audit && pnpm test
129
+ pnpm check:mcp-sync # MCP registry ↔ library export drift guard (also in verify)
130
+ pnpm release --ui <patch|minor|major> --mcp <…|skip> # publish lib + MCP in lockstep
129
131
  ```
130
132
 
133
+ This repo ships two packages — `@godxjp/ui` (this dir) and `@godxjp/ui-mcp` (`mcp/`). They keep
134
+ separate version lines but release together via `pnpm release`; see DEVELOPMENT.md §6.
135
+
131
136
  → **[docs/DEVELOPMENT.md](./docs/DEVELOPMENT.md)** is the contributor guideline (the
132
137
  boundary, the layers, how to add/extend a component, verification).
133
138
 
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
3
+
4
+ declare const AspectRatio: React.ForwardRefExoticComponent<Omit<AspectRatioPrimitive.AspectRatioProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+
6
+ export { AspectRatio as A };
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
3
+
4
+ declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
5
+ declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
6
+ declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
7
+
8
+ export { Avatar as A, AvatarFallback as a, AvatarImage as b };
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import { c as CheckboxGroupProp } from './data-entry.prop-Cjidhei7.js';
4
+ import { c as CheckboxGroupProp } from './data-entry.prop-CpSx5dX6.js';
5
5
 
6
6
  declare function CheckboxGroup({ value: controlledValue, defaultValue, onChange, options, orientation, disabled, name, className, children, }: CheckboxGroupProp): react_jsx_runtime.JSX.Element;
7
7
 
@@ -1,4 +1,4 @@
1
- import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-EE3B3TEQ.js';
1
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-ARDVPIF4.js';
2
2
  import { Button } from './chunk-HJEBRCXL.js';
3
3
  import { useTranslation, useOptionalAppContext, APP_LOCALES, resolveTimezonePickerOptions, getTimezoneLabel, APP_TIME_FORMAT_OPTIONS, getTimeFormatLabel } from './chunk-RLGHEV4A.js';
4
4
  import { APP_DATE_FORMAT_OPTIONS, getDateFormatLabel } from './chunk-FXFJF4YA.js';
@@ -0,0 +1,61 @@
1
+ import { toneNeutralClass, toneInfoClass, toneWarningClass, toneSuccessClass, toneDestructiveClass } from './chunk-ICM6XBST.js';
2
+ import { useTranslation } from './chunk-RLGHEV4A.js';
3
+ import { cn } from './chunk-U7N2A7A3.js';
4
+ import { cva } from 'class-variance-authority';
5
+ import { XCircle, Pause, CheckCircle2, Circle, Trash2, AlertCircle, Clock, Play } from 'lucide-react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var STATUS_MAP = {
9
+ active: { tone: "success", icon: CheckCircle2 },
10
+ completed: { tone: "success", icon: CheckCircle2 },
11
+ delivered: { tone: "success", icon: CheckCircle2 },
12
+ done: { tone: "success", icon: CheckCircle2 },
13
+ permanent: { tone: "success", icon: CheckCircle2 },
14
+ succeeded: { tone: "success", icon: CheckCircle2 },
15
+ draft: { tone: "neutral", icon: Circle },
16
+ pending: { tone: "warning", icon: Clock },
17
+ scheduled: { tone: "info", icon: Clock },
18
+ sending: { tone: "info", icon: Play },
19
+ temporary: { tone: "warning", icon: Clock },
20
+ bounced: { tone: "destructive", icon: AlertCircle },
21
+ cancelled: { tone: "neutral", icon: Pause },
22
+ deleted: { tone: "destructive", icon: Trash2 },
23
+ failed: { tone: "destructive", icon: XCircle },
24
+ private: { tone: "neutral", icon: Circle },
25
+ internal: { tone: "info", icon: Circle },
26
+ public: { tone: "info", icon: Circle },
27
+ ASSIGNMENT_STATUS_ACTIVE: { tone: "success", icon: CheckCircle2 },
28
+ ASSIGNMENT_STATUS_SUSPENDED: { tone: "warning", icon: Pause },
29
+ ASSIGNMENT_STATUS_TERMINATED: { tone: "destructive", icon: XCircle }
30
+ };
31
+ var badgeVariants = cva(
32
+ "inline-flex items-center border text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
33
+ {
34
+ variants: {
35
+ variant: {
36
+ default: "border-transparent bg-primary text-primary-foreground",
37
+ secondary: "border-transparent bg-secondary text-secondary-foreground",
38
+ destructive: cn("border-transparent", toneDestructiveClass),
39
+ outline: "text-foreground",
40
+ success: cn("border-transparent", toneSuccessClass),
41
+ warning: cn("border-transparent", toneWarningClass),
42
+ info: cn("border-transparent", toneInfoClass),
43
+ neutral: cn("border-transparent", toneNeutralClass)
44
+ }
45
+ },
46
+ defaultVariants: { variant: "default" }
47
+ }
48
+ );
49
+ function Badge({ className, variant, icon, status, children, ...props }) {
50
+ const { t } = useTranslation();
51
+ const statusDef = status ? STATUS_MAP[status] ?? { tone: "neutral", icon: Circle } : null;
52
+ const resolvedVariant = variant ?? statusDef?.tone ?? "default";
53
+ const ResolvedIcon = icon === void 0 ? statusDef?.icon : icon;
54
+ const resolvedChildren = children ?? (status ? status in STATUS_MAP ? t(`status.${status}`) : status : void 0);
55
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "badge", className: cn(badgeVariants({ variant: resolvedVariant }), className), ...props, children: [
56
+ ResolvedIcon ? /* @__PURE__ */ jsx(ResolvedIcon, { "data-slot": "badge-icon", "aria-hidden": "true" }) : null,
57
+ resolvedChildren
58
+ ] });
59
+ }
60
+
61
+ export { Badge };
@@ -1,4 +1,4 @@
1
- import { SearchSelect } from './chunk-Y7AV7QJO.js';
1
+ import { SearchSelect } from './chunk-OXKY5QMK.js';
2
2
  import { controlTriggerClass } from './chunk-ICM6XBST.js';
3
3
  import { cn } from './chunk-U7N2A7A3.js';
4
4
  import * as React from 'react';
@@ -0,0 +1,40 @@
1
+ import { toast as toast$1 } from 'sonner';
2
+
3
+ // src/components/feedback/use-toast.ts
4
+ function nodeText(value) {
5
+ if (value == null) return "";
6
+ if (typeof value === "string") return value;
7
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
8
+ return "";
9
+ }
10
+ function legacyToast(options) {
11
+ const { title, description, variant, ...rest } = options;
12
+ const titleText = nodeText(title);
13
+ const descText = nodeText(description);
14
+ const message = titleText || descText;
15
+ const desc = titleText && descText ? descText : void 0;
16
+ const sonnerOptions = { ...rest, description: desc };
17
+ switch (variant) {
18
+ case "destructive":
19
+ return toast$1.error(message, sonnerOptions);
20
+ case "success":
21
+ return toast$1.success(message, sonnerOptions);
22
+ default:
23
+ return toast$1(message, sonnerOptions);
24
+ }
25
+ }
26
+ var toast = Object.assign((messageOrOptions) => {
27
+ if (typeof messageOrOptions === "string") {
28
+ return toast$1(messageOrOptions);
29
+ }
30
+ return legacyToast(messageOrOptions);
31
+ }, toast$1);
32
+ function useToast() {
33
+ return {
34
+ toast: (options) => legacyToast(options),
35
+ dismiss: toast$1.dismiss,
36
+ toasts: []
37
+ };
38
+ }
39
+
40
+ export { toast, useToast };
@@ -1,14 +1,14 @@
1
1
  import { DropdownMenu, DropdownMenuTrigger } from './chunk-TO33OY4L.js';
2
2
  import { Tooltip, TooltipTrigger, TooltipContent } from './chunk-32WO3YLB.js';
3
3
  import { Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-DV52WNXO.js';
4
- import { densityClass, pageContainerVariantClass, stackGapClass } from './chunk-S66TJXJU.js';
5
- import { Badge } from './chunk-PIIRNAXA.js';
6
4
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
5
+ import { densityClass, pageContainerVariantClass, stackGapClass } from './chunk-S66TJXJU.js';
7
6
  import { cn } from './chunk-U7N2A7A3.js';
8
7
  import { Link } from 'react-router-dom';
9
8
  import { ChevronRight, ChevronDown, PanelLeftOpen, PanelLeftClose, Search, Bell, SlidersHorizontal } from 'lucide-react';
10
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
11
10
  import * as React from 'react';
11
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
12
12
 
13
13
  function PageContainer({
14
14
  title,
@@ -95,131 +95,14 @@ function AppShell({
95
95
  footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "app-footer", children: footer })
96
96
  ] });
97
97
  }
98
- function Topbar({
99
- product,
100
- project,
101
- productMenu,
102
- projectMenu,
103
- onProductOpen,
104
- onProjectOpen,
105
- onSearchOpen,
106
- onTweaksOpen,
107
- collapsed = false,
108
- onToggleCollapsed,
109
- rightSlot,
110
- unread = false,
111
- onNotificationsOpen,
112
- user
113
- }) {
114
- const productChip = /* @__PURE__ */ jsxs(
115
- "button",
116
- {
117
- type: "button",
118
- className: "tb-chip",
119
- "aria-label": product.name,
120
- onClick: productMenu ? void 0 : onProductOpen,
121
- children: [
122
- /* @__PURE__ */ jsx(
123
- "span",
124
- {
125
- className: "tb-chip-icon",
126
- style: { background: product.color ?? "hsl(var(--attention))" },
127
- children: product.name[0]?.toUpperCase() ?? "?"
128
- }
129
- ),
130
- /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: product.name }),
131
- /* @__PURE__ */ jsx("span", { className: "tb-chip-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
132
- ]
133
- }
134
- );
135
- const showProject = project != null || projectMenu != null;
136
- const projectChip = /* @__PURE__ */ jsxs(
137
- "button",
138
- {
139
- type: "button",
140
- className: `tb-chip ${project ? "" : "tb-chip-empty"}`,
141
- "aria-label": project ? project.name : "Pick project",
142
- onClick: projectMenu ? void 0 : onProjectOpen,
143
- children: [
144
- /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: project ? project.name : "Pick project" }),
145
- /* @__PURE__ */ jsx("span", { className: "tb-chip-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
146
- ]
147
- }
148
- );
149
- return /* @__PURE__ */ jsxs(Fragment, { children: [
150
- onToggleCollapsed ? /* @__PURE__ */ jsx(
151
- "button",
152
- {
153
- type: "button",
154
- className: "tb-icon-btn",
155
- "aria-label": "Toggle sidebar",
156
- "aria-pressed": collapsed,
157
- onClick: onToggleCollapsed,
158
- children: collapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(PanelLeftClose, { "aria-hidden": "true" })
159
- }
160
- ) : null,
161
- /* @__PURE__ */ jsxs("div", { className: "tb-switcher", children: [
162
- productMenu ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
163
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: productChip }),
164
- productMenu
165
- ] }) : productChip,
166
- showProject ? /* @__PURE__ */ jsx("span", { className: "tb-chip-sep", children: "/" }) : null,
167
- showProject ? projectMenu ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
168
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: projectChip }),
169
- projectMenu
170
- ] }) : projectChip : null
171
- ] }),
172
- /* @__PURE__ */ jsxs("button", { type: "button", className: "tb-search", onClick: onSearchOpen, children: [
173
- /* @__PURE__ */ jsx(Search, { "aria-hidden": "true" }),
174
- /* @__PURE__ */ jsx("span", { children: "Search..." }),
175
- /* @__PURE__ */ jsx("kbd", { className: "kbd", children: "\u2318K" })
176
- ] }),
177
- rightSlot,
178
- onNotificationsOpen ? /* @__PURE__ */ jsxs(
179
- "button",
180
- {
181
- type: "button",
182
- className: "tb-icon-btn tb-bell",
183
- "aria-label": "Notifications",
184
- onClick: onNotificationsOpen,
185
- children: [
186
- /* @__PURE__ */ jsx(Bell, { "aria-hidden": "true" }),
187
- unread ? /* @__PURE__ */ jsx("span", { className: "tb-bell-dot", "aria-hidden": "true" }) : null
188
- ]
189
- }
190
- ) : null,
191
- user,
192
- onTweaksOpen ? /* @__PURE__ */ jsx(
193
- "button",
194
- {
195
- type: "button",
196
- className: "tb-icon-btn",
197
- "aria-label": "Open tweaks",
198
- onClick: onTweaksOpen,
199
- children: /* @__PURE__ */ jsx(SlidersHorizontal, { "aria-hidden": "true" })
200
- }
201
- ) : null
202
- ] });
203
- }
204
- function ShellApp({ menu, breadcrumb, children }) {
205
- return /* @__PURE__ */ jsx(
206
- AppShell,
207
- {
208
- sidebar: menu,
209
- breadcrumb,
210
- topbar: /* @__PURE__ */ jsx(
211
- Topbar,
212
- {
213
- product: { name: "GodX", color: "hsl(var(--attention))" },
214
- project: { name: "Japan to SEA lanes" },
215
- onSearchOpen: () => void 0,
216
- onNotificationsOpen: () => void 0,
217
- unread: true
218
- }
219
- ),
220
- children
221
- }
222
- );
98
+ function Breadcrumb({ items }) {
99
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
100
+ const isLast = index === items.length - 1;
101
+ return /* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
102
+ item.to && !isLast ? /* @__PURE__ */ jsx(Link, { to: item.to, className: "ui-breadcrumb-link", children: item.label }) : /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-current", "aria-current": isLast ? "page" : void 0, children: item.label }),
103
+ !isLast ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }) : null
104
+ ] }, item.to ?? index);
105
+ }) }) });
223
106
  }
224
107
  function isItemActive(item, activeId) {
225
108
  if (item.id === activeId) return true;
@@ -376,29 +259,111 @@ function Sidebar({
376
259
  footer ? /* @__PURE__ */ jsx("div", { className: "sb-footer", children: footer }) : null
377
260
  ] });
378
261
  }
379
- function Menu({ items }) {
380
- const sections = items.map((section) => ({
381
- label: section.label,
382
- items: section.items.map(({ active: _active, ...item }) => item)
383
- }));
384
- const activeId = items.flatMap((section) => section.items).find((item) => item.active)?.id ?? items[0]?.items[0]?.id ?? "";
385
- return /* @__PURE__ */ jsx(
386
- Sidebar,
262
+ function Topbar({
263
+ product,
264
+ project,
265
+ productMenu,
266
+ projectMenu,
267
+ onProductOpen,
268
+ onProjectOpen,
269
+ onSearchOpen,
270
+ onTweaksOpen,
271
+ collapsed = false,
272
+ onToggleCollapsed,
273
+ rightSlot,
274
+ unread = false,
275
+ onNotificationsOpen,
276
+ user
277
+ }) {
278
+ const productChip = /* @__PURE__ */ jsxs(
279
+ "button",
280
+ {
281
+ type: "button",
282
+ className: "tb-chip",
283
+ "aria-label": product.name,
284
+ onClick: productMenu ? void 0 : onProductOpen,
285
+ children: [
286
+ /* @__PURE__ */ jsx(
287
+ "span",
288
+ {
289
+ className: "tb-chip-icon",
290
+ style: { background: product.color ?? "hsl(var(--attention))" },
291
+ children: product.name[0]?.toUpperCase() ?? "?"
292
+ }
293
+ ),
294
+ /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: product.name }),
295
+ /* @__PURE__ */ jsx("span", { className: "tb-chip-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
296
+ ]
297
+ }
298
+ );
299
+ const showProject = project != null || projectMenu != null;
300
+ const projectChip = /* @__PURE__ */ jsxs(
301
+ "button",
387
302
  {
388
- activeId,
389
- sections,
390
- product: { name: "Acme Console", role: "Workspace", color: "hsl(var(--attention))" }
303
+ type: "button",
304
+ className: `tb-chip ${project ? "" : "tb-chip-empty"}`,
305
+ "aria-label": project ? project.name : "Pick project",
306
+ onClick: projectMenu ? void 0 : onProjectOpen,
307
+ children: [
308
+ /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: project ? project.name : "Pick project" }),
309
+ /* @__PURE__ */ jsx("span", { className: "tb-chip-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
310
+ ]
391
311
  }
392
312
  );
393
- }
394
- function Breadcrumb({ items }) {
395
- return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
396
- const isLast = index === items.length - 1;
397
- return /* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
398
- item.to && !isLast ? /* @__PURE__ */ jsx(Link, { to: item.to, className: "ui-breadcrumb-link", children: item.label }) : /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-current", "aria-current": isLast ? "page" : void 0, children: item.label }),
399
- !isLast ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }) : null
400
- ] }, item.to ?? index);
401
- }) }) });
313
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
314
+ onToggleCollapsed ? /* @__PURE__ */ jsx(
315
+ "button",
316
+ {
317
+ type: "button",
318
+ className: "tb-icon-btn",
319
+ "aria-label": "Toggle sidebar",
320
+ "aria-pressed": collapsed,
321
+ onClick: onToggleCollapsed,
322
+ children: collapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(PanelLeftClose, { "aria-hidden": "true" })
323
+ }
324
+ ) : null,
325
+ /* @__PURE__ */ jsxs("div", { className: "tb-switcher", children: [
326
+ productMenu ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
327
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: productChip }),
328
+ productMenu
329
+ ] }) : productChip,
330
+ showProject ? /* @__PURE__ */ jsx("span", { className: "tb-chip-sep", children: "/" }) : null,
331
+ showProject ? projectMenu ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
332
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: projectChip }),
333
+ projectMenu
334
+ ] }) : projectChip : null
335
+ ] }),
336
+ /* @__PURE__ */ jsxs("button", { type: "button", className: "tb-search", onClick: onSearchOpen, children: [
337
+ /* @__PURE__ */ jsx(Search, { "aria-hidden": "true" }),
338
+ /* @__PURE__ */ jsx("span", { children: "Search..." }),
339
+ /* @__PURE__ */ jsx("kbd", { className: "kbd", children: "\u2318K" })
340
+ ] }),
341
+ rightSlot,
342
+ onNotificationsOpen ? /* @__PURE__ */ jsxs(
343
+ "button",
344
+ {
345
+ type: "button",
346
+ className: "tb-icon-btn tb-bell",
347
+ "aria-label": "Notifications",
348
+ onClick: onNotificationsOpen,
349
+ children: [
350
+ /* @__PURE__ */ jsx(Bell, { "aria-hidden": "true" }),
351
+ unread ? /* @__PURE__ */ jsx("span", { className: "tb-bell-dot", "aria-hidden": "true" }) : null
352
+ ]
353
+ }
354
+ ) : null,
355
+ user,
356
+ onTweaksOpen ? /* @__PURE__ */ jsx(
357
+ "button",
358
+ {
359
+ type: "button",
360
+ className: "tb-icon-btn",
361
+ "aria-label": "Open tweaks",
362
+ onClick: onTweaksOpen,
363
+ children: /* @__PURE__ */ jsx(SlidersHorizontal, { "aria-hidden": "true" })
364
+ }
365
+ ) : null
366
+ ] });
402
367
  }
403
368
  function ResponsiveGrid({ columns = 4, children }) {
404
369
  return /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid", "data-columns": columns, children });
@@ -409,38 +374,18 @@ function SplitPane({ children, aside, asideWidth = "md" }) {
409
374
  /* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", children: aside })
410
375
  ] });
411
376
  }
412
- function MobileFrame({
413
- title,
414
- subtitle,
415
- status,
416
- children,
417
- navItems = []
418
- }) {
419
- return /* @__PURE__ */ jsx("div", { className: "ui-mobile-stage", children: /* @__PURE__ */ jsxs("div", { className: "ui-mobile-frame", children: [
420
- /* @__PURE__ */ jsxs("header", { className: "ui-mobile-header", children: [
421
- /* @__PURE__ */ jsxs("div", { children: [
422
- /* @__PURE__ */ jsx("div", { className: "ui-mobile-title", children: title }),
423
- subtitle ? /* @__PURE__ */ jsx("div", { className: "ui-mobile-subtitle", children: subtitle }) : null
424
- ] }),
425
- status ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: status }) : null
426
- ] }),
427
- /* @__PURE__ */ jsx("main", { className: "ui-mobile-main", children }),
428
- navItems.length > 0 ? /* @__PURE__ */ jsx("footer", { className: "ui-mobile-nav", children: navItems.map((item) => {
429
- const Icon = item.icon;
430
- return /* @__PURE__ */ jsxs(
431
- "div",
432
- {
433
- className: "ui-mobile-nav-item",
434
- "data-active": item.active ? "true" : void 0,
435
- children: [
436
- /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }),
437
- /* @__PURE__ */ jsx("span", { children: item.label })
438
- ]
439
- },
440
- item.label
441
- );
442
- }) }) : null
443
- ] }) });
444
- }
377
+ var Separator = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
378
+ SeparatorPrimitive.Root,
379
+ {
380
+ ref,
381
+ "data-slot": "separator",
382
+ "data-orientation": orientation,
383
+ orientation,
384
+ decorative,
385
+ className: cn("ui-separator", className),
386
+ ...props
387
+ }
388
+ ));
389
+ Separator.displayName = SeparatorPrimitive.Root.displayName;
445
390
 
446
- export { AppShell, Breadcrumb, Menu, MobileFrame, PageContainer, PageInset, ResponsiveGrid, ShellApp, Sidebar, SplitPane, Stack, Topbar };
391
+ export { AppShell, Breadcrumb, PageContainer, PageInset, ResponsiveGrid, Separator, Sidebar, SplitPane, Stack, Topbar };
@@ -1,4 +1,4 @@
1
- import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-EE3B3TEQ.js';
1
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-ARDVPIF4.js';
2
2
  import { Button } from './chunk-HJEBRCXL.js';
3
3
  import { useTranslation } from './chunk-RLGHEV4A.js';
4
4
  import { cn } from './chunk-U7N2A7A3.js';
@@ -0,0 +1,18 @@
1
+ import { cn } from './chunk-U7N2A7A3.js';
2
+ import * as React from 'react';
3
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var AspectRatio = React.forwardRef(({ className, ratio = 16 / 9, ...props }, ref) => /* @__PURE__ */ jsx(
7
+ AspectRatioPrimitive.Root,
8
+ {
9
+ ref,
10
+ "data-slot": "aspect-ratio",
11
+ ratio,
12
+ className: cn("ui-aspect-ratio", className),
13
+ ...props
14
+ }
15
+ ));
16
+ AspectRatio.displayName = AspectRatioPrimitive.Root.displayName;
17
+
18
+ export { AspectRatio };
@@ -0,0 +1,59 @@
1
+ import { cn } from './chunk-U7N2A7A3.js';
2
+ import * as React2 from 'react';
3
+ import * as TogglePrimitive from '@radix-ui/react-toggle';
4
+ import { cva } from 'class-variance-authority';
5
+ import { jsx } from 'react/jsx-runtime';
6
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
7
+
8
+ var toggleVariants = cva("ui-toggle", {
9
+ variants: {
10
+ variant: {
11
+ default: "ui-toggle-default",
12
+ outline: "ui-toggle-outline"
13
+ },
14
+ size: {
15
+ sm: "ui-toggle-sm",
16
+ default: "ui-toggle-default-size",
17
+ lg: "ui-toggle-lg"
18
+ }
19
+ },
20
+ defaultVariants: {
21
+ variant: "default",
22
+ size: "default"
23
+ }
24
+ });
25
+ var Toggle = React2.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
26
+ TogglePrimitive.Root,
27
+ {
28
+ ref,
29
+ "data-slot": "toggle",
30
+ className: cn(toggleVariants({ variant, size }), className),
31
+ ...props
32
+ }
33
+ ));
34
+ Toggle.displayName = TogglePrimitive.Root.displayName;
35
+ var ToggleGroup = React2.forwardRef(({ className, variant = "default", size = "default", children, ...props }, ref) => /* @__PURE__ */ jsx(
36
+ ToggleGroupPrimitive.Root,
37
+ {
38
+ ref,
39
+ "data-slot": "toggle-group",
40
+ "data-variant": variant,
41
+ "data-size": size,
42
+ className: cn("ui-toggle-group", className),
43
+ ...props,
44
+ children
45
+ }
46
+ ));
47
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
48
+ var ToggleGroupItem = React2.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
49
+ ToggleGroupPrimitive.Item,
50
+ {
51
+ ref,
52
+ "data-slot": "toggle-group-item",
53
+ className: cn(toggleVariants({ variant, size }), className),
54
+ ...props
55
+ }
56
+ ));
57
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
58
+
59
+ export { Toggle, ToggleGroup, ToggleGroupItem, toggleVariants };