@godxjp/ui 9.1.0 → 10.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 (145) hide show
  1. package/README.md +58 -29
  2. package/dist/app/index.d.ts +1 -1
  3. package/dist/app/index.js +4 -4
  4. package/dist/{app.prop-DnIXFzLi.d.ts → app.prop-Cy6dJnU8.d.ts} +18 -35
  5. package/dist/aspect-ratio-CZZJd9Km.d.ts +9 -0
  6. package/dist/{checkbox-ChRsR7Nk.d.ts → checkbox-em-oFM5D.d.ts} +1 -1
  7. package/dist/{chunk-LJLGABFV.js → chunk-2HXZT2WJ.js} +17 -9
  8. package/dist/{chunk-QLMXEJSY.js → chunk-3Q4A4U2P.js} +24 -1
  9. package/dist/{chunk-26CPAKUP.js → chunk-44YRPSZ7.js} +1 -2
  10. package/dist/{chunk-HB2OHB5X.js → chunk-5NCFLCM7.js} +27 -16
  11. package/dist/{chunk-FXFJF4YA.js → chunk-6CSBMMZS.js} +262 -31
  12. package/dist/{chunk-ZRRLOOBX.js → chunk-6HHSU6RG.js} +8 -6
  13. package/dist/{chunk-INSF6K3Y.js → chunk-7Q45MBFW.js} +7 -5
  14. package/dist/{chunk-O24Z3ULJ.js → chunk-BE6GJGKJ.js} +1 -1
  15. package/dist/{chunk-5D42MFB4.js → chunk-BG5RNXTH.js} +71 -2
  16. package/dist/{chunk-AINW5WYN.js → chunk-COD66MFF.js} +1 -2
  17. package/dist/{chunk-IOGU3ZWF.js → chunk-DNGJHWJZ.js} +3 -3
  18. package/dist/{chunk-3TS3G4U3.js → chunk-EE5DKOHX.js} +3 -1
  19. package/dist/{chunk-KXOAZGPA.js → chunk-EQZP53KI.js} +33 -8
  20. package/dist/{chunk-BHV2FUOA.js → chunk-EZHHJQWQ.js} +1 -1
  21. package/dist/{chunk-N3JPLJ3B.js → chunk-GDDCSKCB.js} +12 -5
  22. package/dist/{chunk-RLGHEV4A.js → chunk-HTG5VHU7.js} +10 -1
  23. package/dist/{chunk-R2W2FX5Q.js → chunk-I7NQ2LIL.js} +1 -9
  24. package/dist/{chunk-XQMPK4GM.js → chunk-IHRMOJXD.js} +86 -39
  25. package/dist/{chunk-TILFZBTE.js → chunk-INIIF7F7.js} +1 -4
  26. package/dist/{chunk-UIYEAUWA.js → chunk-IY347EQA.js} +2 -2
  27. package/dist/{chunk-HCM4JAC2.js → chunk-JWGLJXQU.js} +39 -11
  28. package/dist/{chunk-TO33OY4L.js → chunk-LMKUKCTN.js} +1 -1
  29. package/dist/chunk-NXVCI6YB.js +453 -0
  30. package/dist/{chunk-JBHXILI4.js → chunk-O6DQZYNI.js} +63 -44
  31. package/dist/{chunk-O2OUNXV4.js → chunk-P5KPCT6R.js} +3 -3
  32. package/dist/{chunk-56NYZNVY.js → chunk-PDXFQS7M.js} +112 -49
  33. package/dist/{chunk-F7PG4OEV.js → chunk-QSGW3ZWK.js} +12 -4
  34. package/dist/{chunk-25RYBC5T.js → chunk-S2IJKT3D.js} +1 -1
  35. package/dist/{chunk-OJZ6C2HM.js → chunk-SARQRCKO.js} +54 -48
  36. package/dist/chunk-T2QO2S65.js +126 -0
  37. package/dist/{chunk-442ULAA6.js → chunk-TGNBXS7H.js} +142 -62
  38. package/dist/{chunk-6J7GRCDA.js → chunk-UNVRNJCB.js} +71 -11
  39. package/dist/{chunk-6YBYAEXD.js → chunk-VSM44AYE.js} +94 -24
  40. package/dist/chunk-VSUYVT2Q.js +163 -0
  41. package/dist/{chunk-4R7QL3MW.js → chunk-X2VY4MOW.js} +14 -29
  42. package/dist/{chunk-FRU44GA2.js → chunk-XK3M3VRR.js} +16 -2
  43. package/dist/{chunk-6YK3IJXW.js → chunk-Z46J47FY.js} +73 -77
  44. package/dist/components/admin/index.d.ts +23 -13
  45. package/dist/components/admin/index.js +29 -30
  46. package/dist/components/data-display/badge.js +3 -3
  47. package/dist/components/data-display/card.d.ts +3 -3
  48. package/dist/components/data-display/card.js +1 -1
  49. package/dist/components/data-display/carousel.js +3 -1
  50. package/dist/components/data-display/index.js +55 -33
  51. package/dist/components/data-entry/calendar.d.ts +1 -1
  52. package/dist/components/data-entry/calendar.js +1 -1
  53. package/dist/components/data-entry/cascader.d.ts +1 -1
  54. package/dist/components/data-entry/cascader.js +5 -5
  55. package/dist/components/data-entry/checkbox.d.ts +2 -2
  56. package/dist/components/data-entry/checkbox.js +2 -2
  57. package/dist/components/data-entry/color-picker.d.ts +1 -1
  58. package/dist/components/data-entry/color-picker.js +3 -3
  59. package/dist/components/data-entry/date-picker.d.ts +2 -2
  60. package/dist/components/data-entry/date-picker.js +4 -4
  61. package/dist/components/data-entry/date-range-picker.d.ts +2 -2
  62. package/dist/components/data-entry/date-range-picker.js +4 -4
  63. package/dist/components/data-entry/index.d.ts +9 -25
  64. package/dist/components/data-entry/index.js +22 -26
  65. package/dist/components/data-entry/radio.d.ts +1 -1
  66. package/dist/components/data-entry/radio.js +2 -2
  67. package/dist/components/data-entry/select.d.ts +2 -2
  68. package/dist/components/data-entry/select.js +3 -4
  69. package/dist/components/data-entry/slider.d.ts +1 -1
  70. package/dist/components/data-entry/switch.d.ts +2 -2
  71. package/dist/components/data-entry/switch.js +1 -1
  72. package/dist/components/data-entry/time-input.js +2 -2
  73. package/dist/components/data-entry/time-picker.d.ts +3 -1
  74. package/dist/components/data-entry/time-picker.js +3 -3
  75. package/dist/components/data-entry/transfer.d.ts +2 -2
  76. package/dist/components/data-entry/transfer.js +5 -5
  77. package/dist/components/data-entry/tree-select.d.ts +1 -1
  78. package/dist/components/data-entry/tree-select.js +5 -5
  79. package/dist/components/data-entry/upload.d.ts +2 -2
  80. package/dist/components/data-entry/upload.js +5 -5
  81. package/dist/components/feedback/alert.js +5 -5
  82. package/dist/components/feedback/dialog.d.ts +20 -1
  83. package/dist/components/feedback/dialog.js +3 -3
  84. package/dist/components/feedback/index.d.ts +10 -18
  85. package/dist/components/feedback/index.js +9 -9
  86. package/dist/components/feedback/sheet.js +1 -1
  87. package/dist/components/layout/index.d.ts +27 -15
  88. package/dist/components/layout/index.js +7 -5
  89. package/dist/components/navigation/dropdown-menu.js +1 -1
  90. package/dist/components/navigation/index.d.ts +15 -17
  91. package/dist/components/navigation/index.js +7 -8
  92. package/dist/components/navigation/pagination.d.ts +25 -4
  93. package/dist/components/navigation/pagination.js +4 -5
  94. package/dist/components/navigation/steps.d.ts +3 -3
  95. package/dist/components/navigation/steps.js +3 -1
  96. package/dist/components/query/index.d.ts +1 -5
  97. package/dist/components/query/index.js +6 -8
  98. package/dist/components/ui/index.d.ts +13 -12
  99. package/dist/components/ui/index.js +30 -32
  100. package/dist/{data-entry.prop-CDkOajPj.d.ts → data-entry.prop-BR4vNA1j.d.ts} +7 -35
  101. package/dist/filter-bar-BxjSJJnQ.d.ts +7 -0
  102. package/dist/{inline-DCqn4O29.d.ts → flex-D_EXRFSW.d.ts} +2 -8
  103. package/dist/form/index.js +1 -1
  104. package/dist/i18n/index.d.ts +82 -10
  105. package/dist/i18n/index.js +2 -2
  106. package/dist/index.d.ts +7 -7
  107. package/dist/index.js +41 -44
  108. package/dist/{layout.prop-DwJKI6ka.d.ts → layout.prop-JE2TcRyL.d.ts} +8 -2
  109. package/dist/lib/datetime/index.js +1 -1
  110. package/dist/{navigation.prop-8DgElO0c.d.ts → navigation.prop-DMcXkR-J.d.ts} +9 -11
  111. package/dist/{toggle-group-BulJgKh3.d.ts → password-strength-DVRvXEOK.d.ts} +24 -3
  112. package/dist/props/components/index.d.ts +4 -4
  113. package/dist/props/index.d.ts +4 -4
  114. package/dist/props/index.js +1 -1
  115. package/dist/props/registry.d.ts +84 -39
  116. package/dist/props/registry.js +1 -1
  117. package/dist/{search-input-cezAxpgb.d.ts → search-input-DpqDMXcn.d.ts} +2 -4
  118. package/dist/{skeleton-uWAjSacg.d.ts → skeleton-cj9kh5wo.d.ts} +1 -3
  119. package/dist/styles/control.css +176 -41
  120. package/dist/styles/data-display-layout.css +41 -15
  121. package/dist/styles/data-entry-layout.css +71 -0
  122. package/dist/styles/feedback-layout.css +44 -12
  123. package/dist/styles/index.css +45 -1
  124. package/dist/styles/layout.css +66 -17
  125. package/dist/styles/navigation-layout.css +3 -1
  126. package/dist/styles/shell-layout.css +3 -3
  127. package/dist/styles/table-layout.css +13 -0
  128. package/dist/tokens/foundation.css +12 -1
  129. package/dist/tokens/semantic/layout.css +2 -2
  130. package/dist/tooltip-Bf2KjRy8.d.ts +14 -0
  131. package/package.json +7 -7
  132. package/scripts/ui-audit.mjs +31 -2
  133. package/dist/aspect-ratio-DGoYrOry.d.ts +0 -6
  134. package/dist/chunk-CAEL2ZD2.js +0 -222
  135. package/dist/chunk-FYM3MJSK.js +0 -59
  136. package/dist/chunk-GKXPALFT.js +0 -32
  137. package/dist/chunk-JKHWLPM5.js +0 -101
  138. package/dist/chunk-KDBGFJJI.js +0 -220
  139. package/dist/chunk-VN72SWHX.js +0 -189
  140. package/dist/components/data-entry/autocomplete.d.ts +0 -24
  141. package/dist/components/data-entry/autocomplete.js +0 -10
  142. package/dist/components/data-entry/combobox.d.ts +0 -22
  143. package/dist/components/data-entry/combobox.js +0 -6
  144. package/dist/filter-bar-BycYH10i.d.ts +0 -14
  145. /package/dist/{chunk-LDSLS6HE.js → chunk-7CFO5FFE.js} +0 -0
@@ -1,13 +1,13 @@
1
- import { DropdownMenu, DropdownMenuTrigger } from './chunk-TO33OY4L.js';
1
+ import { DropdownMenu, DropdownMenuTrigger } from './chunk-LMKUKCTN.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, Flex } from './chunk-TILFZBTE.js';
4
+ import { densityClass, pageContainerVariantClass } from './chunk-INIIF7F7.js';
5
5
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
6
+ import { useTranslation } from './chunk-HTG5VHU7.js';
6
7
  import { cn } from './chunk-U7N2A7A3.js';
7
8
  import { ChevronRight, ChevronDown, PanelLeftOpen, PanelLeftClose, Search, Bell, SlidersHorizontal } from 'lucide-react';
8
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
10
  import * as React from 'react';
10
- import * as SeparatorPrimitive from '@radix-ui/react-separator';
11
11
 
12
12
  function PageContainerInset({ className, children, ...props }) {
13
13
  return /* @__PURE__ */ jsx("div", { className: cn("ui-page-container-inset", className), ...props, children });
@@ -76,12 +76,6 @@ function PageContainerRoot({
76
76
  var PageContainer = Object.assign(PageContainerRoot, {
77
77
  Inset: PageContainerInset
78
78
  });
79
- function PageInset(props) {
80
- return /* @__PURE__ */ jsx(PageContainerInset, { ...props });
81
- }
82
- function Stack(props) {
83
- return /* @__PURE__ */ jsx(Flex, { direction: "col", ...props });
84
- }
85
79
  function AppShell({
86
80
  sidebar,
87
81
  topbar,
@@ -93,6 +87,7 @@ function AppShell({
93
87
  children,
94
88
  sidebarCollapsed = false
95
89
  }) {
90
+ const { t } = useTranslation();
96
91
  const resolvedTopbar = topbar !== void 0 ? topbar : /* @__PURE__ */ jsxs("div", { className: "app-topbar-rail", children: [
97
92
  logo !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-logo", children: logo }),
98
93
  topbarLeft !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-left", children: topbarLeft }),
@@ -100,17 +95,18 @@ function AppShell({
100
95
  topbarRight !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-right", children: topbarRight })
101
96
  ] });
102
97
  return /* @__PURE__ */ jsxs("div", { className: "app-root", "data-collapsed": sidebarCollapsed ? "true" : void 0, children: [
103
- /* @__PURE__ */ jsx("aside", { className: "app-sidebar", children: sidebar }),
104
- /* @__PURE__ */ jsx("header", { className: "app-topbar", children: resolvedTopbar }),
105
- /* @__PURE__ */ jsxs("main", { className: "app-main", children: [
98
+ /* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar }),
99
+ /* @__PURE__ */ jsx("header", { className: "app-topbar", "aria-label": t("layout.appShell.headerLabel"), children: resolvedTopbar }),
100
+ /* @__PURE__ */ jsxs("main", { className: "app-main", "aria-label": t("layout.appShell.mainLabel"), children: [
106
101
  breadcrumb !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-breadcrumb", children: breadcrumb }),
107
102
  children
108
103
  ] }),
109
- footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "app-footer", children: footer })
104
+ footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "app-footer", "aria-label": t("layout.appShell.footerLabel"), children: footer })
110
105
  ] });
111
106
  }
112
107
  function Breadcrumb({ items, linkComponent: LinkComponent = "a" }) {
113
- return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
108
+ const { t } = useTranslation();
109
+ return /* @__PURE__ */ jsx("nav", { "aria-label": t("navigation.breadcrumb.ariaLabel"), className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
114
110
  const isLast = index === items.length - 1;
115
111
  return /* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
116
112
  item.to && !isLast ? /* @__PURE__ */ jsx(LinkComponent, { href: item.to, 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 }),
@@ -118,33 +114,91 @@ function Breadcrumb({ items, linkComponent: LinkComponent = "a" }) {
118
114
  ] }, item.to ?? index);
119
115
  }) }) });
120
116
  }
121
- function isItemActive(item, activeId) {
122
- if (item.id === activeId) return true;
123
- return (item.children ?? []).some((child) => isItemActive(child, activeId));
117
+ function SidebarHeader({ children, className, ...props }) {
118
+ return /* @__PURE__ */ jsx("div", { className: cn("sb-brand", className), ...props, children });
124
119
  }
125
- function NavLeaf({ item, activeId, onSelect, sub = false }) {
120
+ function SidebarSection({
121
+ label,
122
+ collapsed = false,
123
+ children,
124
+ className,
125
+ ...props
126
+ }) {
127
+ return /* @__PURE__ */ jsxs("div", { className: cn("sb-section", className), ...props, children: [
128
+ label && !collapsed ? /* @__PURE__ */ jsx("div", { className: "sb-section-label", children: label }) : null,
129
+ /* @__PURE__ */ jsx("div", { className: "sb-nav", children })
130
+ ] });
131
+ }
132
+ function SidebarItem({
133
+ item,
134
+ active = false,
135
+ sub = false,
136
+ onActivate,
137
+ renderItem,
138
+ children,
139
+ ...props
140
+ }) {
126
141
  const Icon = item.icon;
127
- const active = item.id === activeId;
128
- return /* @__PURE__ */ jsxs(
142
+ const showBadge = item.badge !== void 0 && item.badge !== "";
143
+ const disabled = item.disabled || props.disabled;
144
+ const content = children ?? (renderItem ? renderItem(item) : void 0);
145
+ return /* @__PURE__ */ jsx(
129
146
  "button",
130
147
  {
131
148
  type: "button",
132
149
  className: cn("sb-nav-item", sub && "sb-nav-item--sub"),
133
150
  "data-active": active ? "true" : void 0,
134
151
  "aria-current": active ? "page" : void 0,
135
- "aria-disabled": item.disabled,
152
+ "aria-disabled": disabled,
153
+ ...props,
136
154
  onClick: () => {
137
- if (!item.disabled) onSelect?.(item.id);
155
+ if (disabled) return;
156
+ onActivate?.(item.id);
138
157
  },
139
- children: [
158
+ children: content ? content : /* @__PURE__ */ jsxs(Fragment, { children: [
140
159
  !sub ? /* @__PURE__ */ jsx("span", { className: "sb-icon", children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) }) : null,
141
160
  /* @__PURE__ */ jsx("span", { className: "sb-label", children: item.label }),
142
- item.badge !== void 0 && item.badge !== "" ? /* @__PURE__ */ jsx("span", { className: "sb-badge", children: item.badge }) : null
143
- ]
161
+ showBadge ? /* @__PURE__ */ jsx("span", { className: "sb-badge", children: item.badge }) : null
162
+ ] })
144
163
  }
145
164
  );
146
165
  }
147
- function NavGroup({ item, activeId, onSelect }) {
166
+ function isItemActive(item, activeId) {
167
+ if (item.id === activeId) return true;
168
+ return (item.children ?? []).some((child) => isItemActive(child, activeId));
169
+ }
170
+ function NavLeaf({ item, activeId, onSelect, sub = false, renderItem }) {
171
+ const active = item.id === activeId;
172
+ return /* @__PURE__ */ jsx(
173
+ SidebarItem,
174
+ {
175
+ item,
176
+ active,
177
+ onActivate: onSelect,
178
+ sub,
179
+ renderItem
180
+ }
181
+ );
182
+ }
183
+ function NavLeafsInGroup({
184
+ children,
185
+ activeId,
186
+ onSelect,
187
+ renderItem
188
+ }) {
189
+ return children.map((child) => /* @__PURE__ */ jsx(
190
+ NavLeaf,
191
+ {
192
+ item: child,
193
+ activeId,
194
+ onSelect,
195
+ sub: true,
196
+ renderItem
197
+ },
198
+ child.id
199
+ ));
200
+ }
201
+ function NavGroup({ item, activeId, onSelect, renderItem }) {
148
202
  const Icon = item.icon;
149
203
  const active = isItemActive(item, activeId);
150
204
  const children = item.children ?? [];
@@ -161,7 +215,7 @@ function NavGroup({ item, activeId, onSelect }) {
161
215
  ]
162
216
  }
163
217
  ),
164
- /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "sb-nav-sub", children: children.map((child) => /* @__PURE__ */ jsx(NavLeaf, { item: child, activeId, onSelect, sub: true }, child.id)) }) })
218
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "sb-nav-sub", children: children.length > 0 ? /* @__PURE__ */ jsx(NavLeafsInGroup, { activeId, onSelect, renderItem, children }) : null }) })
165
219
  ] });
166
220
  }
167
221
  function CollapsedRow({ item, activeId, onSelect }) {
@@ -237,10 +291,14 @@ function Sidebar({
237
291
  onProductClick,
238
292
  brand,
239
293
  collapsed = false,
294
+ children,
295
+ renderItem,
240
296
  footer
241
297
  }) {
298
+ const { t } = useTranslation();
299
+ const resolvedSections = sections ?? [];
242
300
  return /* @__PURE__ */ jsxs("div", { className: "sb-root", "data-collapsed": collapsed ? "true" : void 0, children: [
243
- brand !== void 0 ? /* @__PURE__ */ jsx("div", { className: "sb-brand", children: brand }) : product ? /* @__PURE__ */ jsxs(
301
+ brand !== void 0 ? /* @__PURE__ */ jsx(SidebarHeader, { children: brand }) : product ? /* @__PURE__ */ jsxs(
244
302
  "button",
245
303
  {
246
304
  type: "button",
@@ -256,20 +314,43 @@ function Sidebar({
256
314
  children: product.name[0]?.toUpperCase() ?? "?"
257
315
  }
258
316
  ),
259
- !collapsed && /* @__PURE__ */ jsxs("span", { className: "sb-product-meta", children: [
317
+ !collapsed ? /* @__PURE__ */ jsxs("span", { className: "sb-product-meta", children: [
260
318
  /* @__PURE__ */ jsx("span", { className: "sb-product-name", children: product.name }),
261
319
  product.role ? /* @__PURE__ */ jsx("span", { className: "sb-product-tenant", children: product.role }) : null
262
- ] }),
263
- !collapsed && /* @__PURE__ */ jsx("span", { className: "sb-product-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
320
+ ] }) : null,
321
+ !collapsed ? /* @__PURE__ */ jsx("span", { className: "sb-product-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) }) : null
264
322
  ]
265
323
  }
266
324
  ) : null,
267
- /* @__PURE__ */ jsx("div", { className: "sb-nav-scroll", children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs("div", { className: "sb-section", children: [
268
- section.label && !collapsed ? /* @__PURE__ */ jsx("div", { className: "sb-section-label", children: section.label }) : null,
269
- /* @__PURE__ */ jsx("div", { className: "sb-nav", role: "navigation", children: section.items.map(
270
- (item) => collapsed ? /* @__PURE__ */ jsx(CollapsedRow, { item, activeId, onSelect }, item.id) : item.children && item.children.length > 0 ? /* @__PURE__ */ jsx(NavGroup, { item, activeId, onSelect }, item.id) : /* @__PURE__ */ jsx(NavLeaf, { item, activeId, onSelect }, item.id)
271
- ) })
272
- ] }, section.label ?? sectionIndex)) }),
325
+ /* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
326
+ SidebarSection,
327
+ {
328
+ label: section.label,
329
+ collapsed,
330
+ children: section.items.map(
331
+ (item) => collapsed ? /* @__PURE__ */ jsx(CollapsedRow, { item, activeId, onSelect }, item.id) : item.children && item.children.length > 0 ? /* @__PURE__ */ jsx(
332
+ NavGroup,
333
+ {
334
+ item,
335
+ activeId,
336
+ onSelect,
337
+ renderItem
338
+ },
339
+ item.id
340
+ ) : /* @__PURE__ */ jsx(
341
+ NavLeaf,
342
+ {
343
+ item,
344
+ activeId,
345
+ onSelect,
346
+ renderItem
347
+ },
348
+ item.id
349
+ )
350
+ )
351
+ },
352
+ section.label ?? sectionIndex
353
+ )) }),
273
354
  footer ? /* @__PURE__ */ jsx("div", { className: "sb-footer", children: footer }) : null
274
355
  ] });
275
356
  }
@@ -278,6 +359,7 @@ function Topbar({
278
359
  project,
279
360
  productMenu,
280
361
  projectMenu,
362
+ projectPlaceholder,
281
363
  onProductOpen,
282
364
  onProjectOpen,
283
365
  onSearchOpen,
@@ -289,6 +371,7 @@ function Topbar({
289
371
  onNotificationsOpen,
290
372
  user
291
373
  }) {
374
+ const { t } = useTranslation();
292
375
  const productChip = /* @__PURE__ */ jsxs(
293
376
  "button",
294
377
  {
@@ -316,10 +399,10 @@ function Topbar({
316
399
  {
317
400
  type: "button",
318
401
  className: `tb-chip ${project ? "" : "tb-chip-empty"}`,
319
- "aria-label": project ? project.name : "Pick project",
402
+ "aria-label": project ? project.name : projectPlaceholder ?? "",
320
403
  onClick: projectMenu ? void 0 : onProjectOpen,
321
404
  children: [
322
- /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: project ? project.name : "Pick project" }),
405
+ /* @__PURE__ */ jsx("span", { className: "tb-chip-label", children: project ? project.name : projectPlaceholder ?? "\u2014" }),
323
406
  /* @__PURE__ */ jsx("span", { className: "tb-chip-caret", children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
324
407
  ]
325
408
  }
@@ -330,7 +413,7 @@ function Topbar({
330
413
  {
331
414
  type: "button",
332
415
  className: "tb-icon-btn",
333
- "aria-label": "Toggle sidebar",
416
+ "aria-label": t("layout.topbar.toggleSidebar"),
334
417
  "aria-pressed": collapsed,
335
418
  onClick: onToggleCollapsed,
336
419
  children: collapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(PanelLeftClose, { "aria-hidden": "true" })
@@ -347,18 +430,28 @@ function Topbar({
347
430
  projectMenu
348
431
  ] }) : projectChip : null
349
432
  ] }),
350
- /* @__PURE__ */ jsxs("button", { type: "button", className: "tb-search", onClick: onSearchOpen, children: [
351
- /* @__PURE__ */ jsx(Search, { "aria-hidden": "true" }),
352
- /* @__PURE__ */ jsx("span", { children: "Search..." }),
353
- /* @__PURE__ */ jsx("kbd", { className: "kbd", children: "\u2318K" })
354
- ] }),
433
+ /* @__PURE__ */ jsxs(
434
+ "button",
435
+ {
436
+ type: "button",
437
+ className: "tb-search",
438
+ "aria-label": t("layout.topbar.search"),
439
+ "aria-keyshortcuts": "Meta+K",
440
+ onClick: onSearchOpen,
441
+ children: [
442
+ /* @__PURE__ */ jsx(Search, { "aria-hidden": "true" }),
443
+ /* @__PURE__ */ jsx("span", { children: t("layout.topbar.searchPlaceholder") }),
444
+ /* @__PURE__ */ jsx("kbd", { className: "kbd", children: "\u2318K" })
445
+ ]
446
+ }
447
+ ),
355
448
  rightSlot,
356
449
  onNotificationsOpen ? /* @__PURE__ */ jsxs(
357
450
  "button",
358
451
  {
359
452
  type: "button",
360
453
  className: "tb-icon-btn tb-bell",
361
- "aria-label": "Notifications",
454
+ "aria-label": t("layout.topbar.notifications"),
362
455
  onClick: onNotificationsOpen,
363
456
  children: [
364
457
  /* @__PURE__ */ jsx(Bell, { "aria-hidden": "true" }),
@@ -372,7 +465,7 @@ function Topbar({
372
465
  {
373
466
  type: "button",
374
467
  className: "tb-icon-btn",
375
- "aria-label": "Open tweaks",
468
+ "aria-label": t("layout.topbar.tweaks"),
376
469
  onClick: onTweaksOpen,
377
470
  children: /* @__PURE__ */ jsx(SlidersHorizontal, { "aria-hidden": "true" })
378
471
  }
@@ -402,18 +495,5 @@ function SplitPane({ children, aside, asideWidth = "md" }) {
402
495
  /* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", children: aside })
403
496
  ] });
404
497
  }
405
- var Separator = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
406
- SeparatorPrimitive.Root,
407
- {
408
- ref,
409
- "data-slot": "separator",
410
- "data-orientation": orientation,
411
- orientation,
412
- decorative,
413
- className: cn("ui-separator", className),
414
- ...props
415
- }
416
- ));
417
- Separator.displayName = SeparatorPrimitive.Root.displayName;
418
498
 
419
- export { AppShell, Breadcrumb, PageContainer, PageInset, ResponsiveGrid, Separator, Sidebar, SplitPane, Stack, Topbar };
499
+ export { AppShell, Breadcrumb, PageContainer, ResponsiveGrid, Sidebar, SidebarHeader, SidebarItem, SidebarSection, SplitPane, Topbar };
@@ -1,10 +1,10 @@
1
1
  import { normalizeTreeOptions, collectAllExpandableKeys, filterVisibleTree, flattenVisibleTree, findNodeByValue, reactNodeText, getDescendantValues } from './chunk-SMLKNECP.js';
2
- import { Checkbox } from './chunk-O24Z3ULJ.js';
3
2
  import { Command, CommandInput } from './chunk-HTEL5DQI.js';
3
+ import { Checkbox } from './chunk-BE6GJGKJ.js';
4
4
  import { Button } from './chunk-M4PZNAMV.js';
5
5
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
6
6
  import { ScrollArea } from './chunk-3KPEZ5CF.js';
7
- import { useTranslation } from './chunk-RLGHEV4A.js';
7
+ import { useTranslation } from './chunk-HTG5VHU7.js';
8
8
  import { cn } from './chunk-U7N2A7A3.js';
9
9
  import * as React from 'react';
10
10
  import { X, ChevronsUpDown, ChevronDown, ChevronRight } from 'lucide-react';
@@ -65,6 +65,8 @@ function TreeSelectRoot({
65
65
  );
66
66
  const isControlled = value !== void 0;
67
67
  const [internal, setInternal] = React.useState(() => toArray(defaultValue));
68
+ const [activeKey, setActiveKey] = React.useState(null);
69
+ const treeItemRefs = React.useRef(/* @__PURE__ */ new Map());
68
70
  const selected = isControlled ? toArray(value) : internal;
69
71
  const resolvedPlaceholder = placeholder ?? t("dataEntry.treeSelect.placeholder");
70
72
  const visible = React.useMemo(() => {
@@ -110,6 +112,53 @@ function TreeSelectRoot({
110
112
  e.stopPropagation();
111
113
  commit([]);
112
114
  };
115
+ const rovingKey = (activeKey && visible.some(({ node }) => node.value === activeKey) ? activeKey : null) ?? visible[0]?.node.value ?? null;
116
+ React.useEffect(() => {
117
+ if (!open || !activeKey) return;
118
+ treeItemRefs.current.get(activeKey)?.focus();
119
+ }, [activeKey, open, visible]);
120
+ const focusByOffset = (currentValue, delta) => {
121
+ const index = visible.findIndex(({ node }) => node.value === currentValue);
122
+ if (index === -1) return;
123
+ const next = visible[index + delta];
124
+ if (next) setActiveKey(next.node.value);
125
+ };
126
+ const onTreeItemKeyDown = (event, node, hasChildren, expanded) => {
127
+ switch (event.key) {
128
+ case "ArrowDown": {
129
+ event.preventDefault();
130
+ focusByOffset(node.value, 1);
131
+ break;
132
+ }
133
+ case "ArrowUp": {
134
+ event.preventDefault();
135
+ focusByOffset(node.value, -1);
136
+ break;
137
+ }
138
+ case "ArrowRight": {
139
+ event.preventDefault();
140
+ if (hasChildren && !expanded) {
141
+ toggleExpand(node.value);
142
+ } else if (hasChildren && expanded) {
143
+ focusByOffset(node.value, 1);
144
+ }
145
+ break;
146
+ }
147
+ case "ArrowLeft": {
148
+ event.preventDefault();
149
+ if (hasChildren && expanded) {
150
+ toggleExpand(node.value);
151
+ }
152
+ break;
153
+ }
154
+ case "Enter":
155
+ case " ": {
156
+ event.preventDefault();
157
+ toggleSelect(node);
158
+ break;
159
+ }
160
+ }
161
+ };
113
162
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
114
163
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
115
164
  Button,
@@ -127,13 +176,15 @@ function TreeSelectRoot({
127
176
  ),
128
177
  children: [
129
178
  /* @__PURE__ */ jsx("span", { className: "truncate", children: displayKeys.length ? displayLabel : resolvedPlaceholder }),
130
- /* @__PURE__ */ jsxs("span", { className: "ml-2 flex shrink-0 items-center gap-1", children: [
179
+ /* @__PURE__ */ jsxs("span", { className: "ms-2 flex shrink-0 items-center gap-1", children: [
131
180
  allowClear && displayKeys.length > 0 && !disabled && /* @__PURE__ */ jsx(
132
- X,
181
+ "button",
133
182
  {
134
- className: "size-4 opacity-50 hover:opacity-100",
135
- "aria-hidden": "true",
136
- onClick: clearValue
183
+ type: "button",
184
+ "aria-label": t("dataEntry.treeSelect.clear"),
185
+ className: "flex size-4 items-center justify-center rounded-sm opacity-50 hover:opacity-100 focus-visible:opacity-100",
186
+ onClick: clearValue,
187
+ children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
137
188
  }
138
189
  ),
139
190
  /* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-4 opacity-50", "aria-hidden": "true" })
@@ -162,16 +213,23 @@ function TreeSelectRoot({
162
213
  return /* @__PURE__ */ jsxs(
163
214
  "div",
164
215
  {
216
+ ref: (el) => {
217
+ treeItemRefs.current.set(node.value, el);
218
+ },
165
219
  role: "treeitem",
220
+ tabIndex: node.disabled ? -1 : rovingKey === node.value ? 0 : -1,
166
221
  "aria-expanded": hasChildren ? expanded : void 0,
167
222
  "aria-selected": isSelected,
223
+ onFocus: () => setActiveKey(node.value),
224
+ onKeyDown: (event) => onTreeItemKeyDown(event, node, hasChildren, expanded),
168
225
  className: cn(
169
- "flex items-center rounded-sm py-1.5 pr-2 text-sm outline-none",
226
+ "flex items-center rounded-sm py-1.5 pe-2 text-sm outline-none",
170
227
  "hover:bg-accent hover:text-accent-foreground",
228
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-1",
171
229
  isSelected && "bg-accent/60",
172
230
  node.disabled && "pointer-events-none opacity-50"
173
231
  ),
174
- style: { paddingLeft: `${depth * 1.25 + 0.5}rem` },
232
+ style: { paddingInlineStart: `${depth * 1.25 + 0.5}rem` },
175
233
  children: [
176
234
  /* @__PURE__ */ jsx(
177
235
  "button",
@@ -180,7 +238,7 @@ function TreeSelectRoot({
180
238
  tabIndex: -1,
181
239
  "aria-label": expanded ? t("dataEntry.treeSelect.collapse") : t("dataEntry.treeSelect.expand"),
182
240
  className: cn(
183
- "mr-1 flex size-5 shrink-0 items-center justify-center rounded-sm",
241
+ "me-1 flex size-5 shrink-0 items-center justify-center rounded-sm",
184
242
  !hasChildren && "invisible"
185
243
  ),
186
244
  onClick: () => toggleExpand(node.value),
@@ -192,6 +250,7 @@ function TreeSelectRoot({
192
250
  Checkbox,
193
251
  {
194
252
  checked: isSelected,
253
+ tabIndex: -1,
195
254
  disabled: Boolean(node.disabled) || Boolean(node.disableCheckbox),
196
255
  onCheckedChange: () => toggleSelect(node)
197
256
  }
@@ -201,7 +260,8 @@ function TreeSelectRoot({
201
260
  "button",
202
261
  {
203
262
  type: "button",
204
- className: "flex-1 truncate text-left",
263
+ tabIndex: -1,
264
+ className: "flex-1 truncate text-start",
205
265
  disabled: node.disabled,
206
266
  onClick: () => toggleSelect(node),
207
267
  children: node.label