@godxjp/ui 6.11.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 (90) 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-7AMHT5Z5.js +61 -0
  6. package/dist/chunk-B3WX53JQ.js +40 -0
  7. package/dist/{chunk-X3OSXYAB.js → chunk-EQRQM6RF.js} +126 -181
  8. package/dist/chunk-FRU44GA2.js +18 -0
  9. package/dist/chunk-FYM3MJSK.js +59 -0
  10. package/dist/{chunk-M64MVRLS.js → chunk-HKQITNB3.js} +12 -48
  11. package/dist/{chunk-GXHZAJUA.js → chunk-O2OUNXV4.js} +10 -10
  12. package/dist/{chunk-BM5LIDCS.js → chunk-OGFWIXRO.js} +7 -16
  13. package/dist/chunk-R2W2FX5Q.js +48 -0
  14. package/dist/chunk-SEG2YBXF.js +29 -0
  15. package/dist/{chunk-XG7XDYIM.js → chunk-V3N266PT.js} +48 -2
  16. package/dist/{chunk-OI7TDPEJ.js → chunk-VXXKR5U4.js} +5 -46
  17. package/dist/components/admin/index.d.ts +12 -10
  18. package/dist/components/admin/index.js +18 -17
  19. package/dist/components/data-display/badge.d.ts +12 -4
  20. package/dist/components/data-display/badge.js +3 -1
  21. package/dist/components/data-display/card.d.ts +5 -5
  22. package/dist/components/data-display/card.js +1 -1
  23. package/dist/components/data-display/index.d.ts +10 -22
  24. package/dist/components/data-display/index.js +23 -32
  25. package/dist/components/data-entry/autocomplete.d.ts +1 -1
  26. package/dist/components/data-entry/calendar.d.ts +1 -1
  27. package/dist/components/data-entry/cascader.d.ts +1 -1
  28. package/dist/components/data-entry/cascader.js +2 -2
  29. package/dist/components/data-entry/checkbox.d.ts +2 -2
  30. package/dist/components/data-entry/color-picker.d.ts +1 -1
  31. package/dist/components/data-entry/command.d.ts +5 -5
  32. package/dist/components/data-entry/date-picker.d.ts +1 -1
  33. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  34. package/dist/components/data-entry/index.d.ts +18 -14
  35. package/dist/components/data-entry/index.js +12 -72
  36. package/dist/components/data-entry/radio.d.ts +1 -1
  37. package/dist/components/data-entry/select.d.ts +1 -1
  38. package/dist/components/data-entry/slider.d.ts +1 -1
  39. package/dist/components/data-entry/switch.d.ts +1 -1
  40. package/dist/components/data-entry/switch.js +1 -1
  41. package/dist/components/data-entry/time-picker.d.ts +1 -1
  42. package/dist/components/data-entry/transfer.d.ts +2 -2
  43. package/dist/components/data-entry/tree-select.d.ts +1 -1
  44. package/dist/components/data-entry/tree-select.js +2 -2
  45. package/dist/components/data-entry/upload.d.ts +2 -2
  46. package/dist/components/feedback/index.d.ts +2 -1
  47. package/dist/components/feedback/index.js +3 -2
  48. package/dist/components/layout/index.d.ts +11 -38
  49. package/dist/components/layout/index.js +2 -3
  50. package/dist/components/navigation/index.d.ts +2 -3
  51. package/dist/components/navigation/index.js +3 -4
  52. package/dist/components/navigation/pagination.d.ts +1 -1
  53. package/dist/components/navigation/steps.d.ts +2 -2
  54. package/dist/components/navigation/tabs.d.ts +14 -2
  55. package/dist/components/navigation/tabs.js +1 -1
  56. package/dist/components/ui/index.d.ts +14 -7
  57. package/dist/components/ui/index.js +14 -11
  58. package/dist/{data-display.prop-i0iaSwMV.d.ts → data-display.prop-CXP9Jfdn.d.ts} +14 -14
  59. package/dist/{data-entry.prop-Cjidhei7.d.ts → data-entry.prop-CpSx5dX6.d.ts} +1 -17
  60. package/dist/{data-table-Bg7fPpXy.d.ts → data-table-C5lcmAwE.d.ts} +7 -30
  61. package/dist/{filter-bar-BpUvE_yO.d.ts → filter-bar-zSKz7YCR.d.ts} +1 -1
  62. package/dist/index.d.ts +12 -10
  63. package/dist/index.js +18 -17
  64. package/dist/{navigation.prop-Ck5_gSfs.d.ts → navigation.prop-DAH4ysXj.d.ts} +6 -7
  65. package/dist/props/components/index.d.ts +3 -3
  66. package/dist/props/index.d.ts +3 -3
  67. package/dist/props/index.js +1 -1
  68. package/dist/props/registry.d.ts +7 -12
  69. package/dist/props/registry.js +1 -1
  70. package/dist/{search-input-mAZy3Den.d.ts → search-input-rR2XDrjv.d.ts} +1 -1
  71. package/dist/skeleton-CqFO4dRc.d.ts +20 -0
  72. package/dist/styles/badge-layout.css +2 -2
  73. package/dist/styles/card-layout.css +19 -19
  74. package/dist/styles/control.css +68 -0
  75. package/dist/styles/data-display-layout.css +23 -81
  76. package/dist/styles/layout.css +19 -71
  77. package/dist/toggle-group-BulJgKh3.d.ts +26 -0
  78. package/dist/tokens/primitives/card.css +9 -9
  79. package/dist/use-toast-Dsw3yE2S.d.ts +19 -0
  80. package/package.json +11 -7
  81. package/scripts/ui-audit.mjs +38 -1
  82. package/dist/chunk-BPSKQUL2.js +0 -68
  83. package/dist/chunk-PIIRNAXA.js +0 -26
  84. package/dist/chunk-WXW43RK5.js +0 -24
  85. package/dist/components/navigation/tabs-items.d.ts +0 -12
  86. package/dist/components/navigation/tabs-items.js +0 -3
  87. package/dist/use-toast-Dol5bdY3.d.ts +0 -34
  88. package/dist/{chunk-PFOBVLF3.js → chunk-6TSU4IHV.js} +0 -0
  89. package/dist/{chunk-V7RC4PBY.js → chunk-JJCGMCTL.js} +1 -1
  90. package/dist/{chunk-VRSHUKDF.js → chunk-RVY4F7LK.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
 
@@ -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 };
@@ -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 { Badge } from './chunk-PIIRNAXA.js';
5
4
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
6
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",
387
280
  {
388
- activeId,
389
- sections,
390
- product: { name: "Acme Console", role: "Workspace", color: "hsl(var(--attention))" }
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
+ ]
391
297
  }
392
298
  );
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
- }) }) });
299
+ const showProject = project != null || projectMenu != null;
300
+ const projectChip = /* @__PURE__ */ jsxs(
301
+ "button",
302
+ {
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
+ ]
311
+ }
312
+ );
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 };
@@ -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 };
@@ -1,9 +1,8 @@
1
1
  import { tableCellPaddingClass, tableRowHeightClass } from './chunk-ICM6XBST.js';
2
2
  import { cn } from './chunk-U7N2A7A3.js';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
- import { toast as toast$1 } from 'sonner';
5
4
 
6
- function SkeletonBlock({ className, ...props }) {
5
+ function Skeleton({ className, ...props }) {
7
6
  return /* @__PURE__ */ jsx(
8
7
  "div",
9
8
  {
@@ -16,7 +15,7 @@ function SkeletonBlock({ className, ...props }) {
16
15
  }
17
16
  function SkeletonRows({ rows = 6, columns = 4, className }) {
18
17
  return /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-rows", className), "aria-busy": "true", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "ui-skeleton-row", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(
19
- SkeletonBlock,
18
+ Skeleton,
20
19
  {
21
20
  className: cn("h-4", j === 0 ? "w-1/4" : j === columns - 1 ? "w-1/6" : "flex-1")
22
21
  },
@@ -25,12 +24,12 @@ function SkeletonRows({ rows = 6, columns = 4, className }) {
25
24
  }
26
25
  function SkeletonTable({ rows = 8, columns = 5 }) {
27
26
  return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-table", "aria-busy": "true", children: [
28
- /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-table-head", tableCellPaddingClass, tableRowHeightClass), children: Array.from({ length: columns }).map((_, j) => /* @__PURE__ */ jsx(SkeletonBlock, { className: cn("h-3", j === 0 ? "w-1/5" : "flex-1") }, j)) }),
27
+ /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-table-head", tableCellPaddingClass, tableRowHeightClass), children: Array.from({ length: columns }).map((_, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("h-3", j === 0 ? "w-1/5" : "flex-1") }, j)) }),
29
28
  /* @__PURE__ */ jsx("div", { className: "ui-skeleton-table-body", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx(
30
29
  "div",
31
30
  {
32
31
  className: cn("ui-skeleton-table-row", tableCellPaddingClass, tableRowHeightClass),
33
- children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(SkeletonBlock, { className: cn("h-4", j === 0 ? "w-1/5" : "flex-1") }, j))
32
+ children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("h-4", j === 0 ? "w-1/5" : "flex-1") }, j))
34
33
  },
35
34
  i
36
35
  )) })
@@ -38,55 +37,20 @@ function SkeletonTable({ rows = 8, columns = 5 }) {
38
37
  }
39
38
  function SkeletonDetail() {
40
39
  return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-detail ui-skeleton-detail-stack", "aria-busy": "true", children: [
41
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-7 w-1/3" }),
42
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 w-1/2" }),
40
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-1/3" }),
41
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }),
43
42
  /* @__PURE__ */ jsx("div", { className: "ui-skeleton-detail-box ui-skeleton-detail-stack", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-detail-stack", children: [
44
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-3 w-24" }),
45
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 w-full max-w-md" })
43
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" }),
44
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full max-w-md" })
46
45
  ] }, i)) })
47
46
  ] });
48
47
  }
49
48
  function SkeletonCard() {
50
49
  return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-card", "aria-busy": "true", children: [
51
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-3 w-24" }),
52
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-[length:var(--control-height)] w-32" }),
53
- /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-3 w-20" })
50
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" }),
51
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-[length:var(--control-height)] w-32" }),
52
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-20" })
54
53
  ] });
55
54
  }
56
- function nodeText(value) {
57
- if (value == null) return "";
58
- if (typeof value === "string") return value;
59
- if (typeof value === "number" || typeof value === "boolean") return String(value);
60
- return "";
61
- }
62
- function legacyToast(options) {
63
- const { title, description, variant, ...rest } = options;
64
- const titleText = nodeText(title);
65
- const descText = nodeText(description);
66
- const message = titleText || descText;
67
- const desc = titleText && descText ? descText : void 0;
68
- const sonnerOptions = { ...rest, description: desc };
69
- switch (variant) {
70
- case "destructive":
71
- return toast$1.error(message, sonnerOptions);
72
- case "success":
73
- return toast$1.success(message, sonnerOptions);
74
- default:
75
- return toast$1(message, sonnerOptions);
76
- }
77
- }
78
- var toast = Object.assign((messageOrOptions) => {
79
- if (typeof messageOrOptions === "string") {
80
- return toast$1(messageOrOptions);
81
- }
82
- return legacyToast(messageOrOptions);
83
- }, toast$1);
84
- function useToast() {
85
- return {
86
- toast: (options) => legacyToast(options),
87
- dismiss: toast$1.dismiss,
88
- toasts: []
89
- };
90
- }
91
55
 
92
- export { SkeletonCard, SkeletonDetail, SkeletonRows, SkeletonTable, toast, useToast };
56
+ export { Skeleton, SkeletonCard, SkeletonDetail, SkeletonRows, SkeletonTable };