@godxjp/ui 9.2.0 → 11.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 (137) 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-UTc4j4nj.d.ts → app.prop-Cy6dJnU8.d.ts} +18 -40
  5. package/dist/{checkbox-ChRsR7Nk.d.ts → checkbox-em-oFM5D.d.ts} +1 -1
  6. package/dist/{chunk-LJLGABFV.js → chunk-2HXZT2WJ.js} +17 -9
  7. package/dist/{chunk-QLMXEJSY.js → chunk-3Q4A4U2P.js} +24 -1
  8. package/dist/{chunk-26CPAKUP.js → chunk-44YRPSZ7.js} +1 -2
  9. package/dist/{chunk-HB2OHB5X.js → chunk-5NCFLCM7.js} +27 -16
  10. package/dist/{chunk-FXFJF4YA.js → chunk-6CSBMMZS.js} +262 -31
  11. package/dist/{chunk-457KVJTX.js → chunk-7Q45MBFW.js} +7 -5
  12. package/dist/{chunk-O24Z3ULJ.js → chunk-BE6GJGKJ.js} +1 -1
  13. package/dist/{chunk-FVPCVZL3.js → chunk-BG5RNXTH.js} +1 -1
  14. package/dist/{chunk-AINW5WYN.js → chunk-COD66MFF.js} +1 -2
  15. package/dist/{chunk-IOGU3ZWF.js → chunk-DNGJHWJZ.js} +3 -3
  16. package/dist/{chunk-3TS3G4U3.js → chunk-EE5DKOHX.js} +3 -1
  17. package/dist/{chunk-BHV2FUOA.js → chunk-EZHHJQWQ.js} +1 -1
  18. package/dist/{chunk-G6Q32VHO.js → chunk-FAB3LMTK.js} +33 -8
  19. package/dist/{chunk-N3JPLJ3B.js → chunk-GDDCSKCB.js} +12 -5
  20. package/dist/{chunk-RLGHEV4A.js → chunk-HTG5VHU7.js} +10 -1
  21. package/dist/{chunk-R2W2FX5Q.js → chunk-I7NQ2LIL.js} +1 -9
  22. package/dist/{chunk-XQMPK4GM.js → chunk-IHRMOJXD.js} +86 -39
  23. package/dist/{chunk-TILFZBTE.js → chunk-INIIF7F7.js} +1 -4
  24. package/dist/{chunk-UIYEAUWA.js → chunk-IY347EQA.js} +2 -2
  25. package/dist/{chunk-HCM4JAC2.js → chunk-JWGLJXQU.js} +39 -11
  26. package/dist/{chunk-TO33OY4L.js → chunk-LMKUKCTN.js} +1 -1
  27. package/dist/chunk-NXVCI6YB.js +453 -0
  28. package/dist/{chunk-O2OUNXV4.js → chunk-P5KPCT6R.js} +3 -3
  29. package/dist/{chunk-6HQMUUQW.js → chunk-PDXFQS7M.js} +14 -30
  30. package/dist/{chunk-26WDEDWL.js → chunk-PUGEOUWZ.js} +32 -23
  31. package/dist/{chunk-F7PG4OEV.js → chunk-QSGW3ZWK.js} +12 -4
  32. package/dist/{chunk-E7HBHUJY.js → chunk-QVLUCB47.js} +8 -6
  33. package/dist/{chunk-25RYBC5T.js → chunk-S2IJKT3D.js} +1 -1
  34. package/dist/{chunk-OJZ6C2HM.js → chunk-SARQRCKO.js} +54 -48
  35. package/dist/chunk-T2QO2S65.js +126 -0
  36. package/dist/{chunk-6J7GRCDA.js → chunk-UNVRNJCB.js} +71 -11
  37. package/dist/{chunk-S6TBIL7J.js → chunk-USNR424B.js} +63 -44
  38. package/dist/{chunk-6YBYAEXD.js → chunk-VSM44AYE.js} +94 -24
  39. package/dist/{chunk-QWLXN6CT.js → chunk-VSUYVT2Q.js} +3 -2
  40. package/dist/{chunk-4R7QL3MW.js → chunk-X2VY4MOW.js} +14 -29
  41. package/dist/{chunk-ETLAI3QU.js → chunk-Z46J47FY.js} +73 -77
  42. package/dist/components/admin/index.d.ts +22 -12
  43. package/dist/components/admin/index.js +29 -30
  44. package/dist/components/data-display/badge.js +3 -3
  45. package/dist/components/data-display/card.d.ts +3 -3
  46. package/dist/components/data-display/card.js +1 -1
  47. package/dist/components/data-display/carousel.js +3 -1
  48. package/dist/components/data-display/index.js +55 -33
  49. package/dist/components/data-entry/calendar.d.ts +1 -1
  50. package/dist/components/data-entry/calendar.js +1 -1
  51. package/dist/components/data-entry/cascader.d.ts +1 -1
  52. package/dist/components/data-entry/cascader.js +5 -5
  53. package/dist/components/data-entry/checkbox.d.ts +2 -2
  54. package/dist/components/data-entry/checkbox.js +2 -2
  55. package/dist/components/data-entry/color-picker.d.ts +1 -1
  56. package/dist/components/data-entry/color-picker.js +3 -3
  57. package/dist/components/data-entry/date-picker.d.ts +2 -2
  58. package/dist/components/data-entry/date-picker.js +4 -4
  59. package/dist/components/data-entry/date-range-picker.d.ts +2 -2
  60. package/dist/components/data-entry/date-range-picker.js +4 -4
  61. package/dist/components/data-entry/index.d.ts +9 -25
  62. package/dist/components/data-entry/index.js +22 -26
  63. package/dist/components/data-entry/radio.d.ts +1 -1
  64. package/dist/components/data-entry/radio.js +2 -2
  65. package/dist/components/data-entry/select.d.ts +2 -2
  66. package/dist/components/data-entry/select.js +3 -4
  67. package/dist/components/data-entry/slider.d.ts +1 -1
  68. package/dist/components/data-entry/switch.d.ts +2 -2
  69. package/dist/components/data-entry/switch.js +1 -1
  70. package/dist/components/data-entry/time-input.js +2 -2
  71. package/dist/components/data-entry/time-picker.d.ts +3 -1
  72. package/dist/components/data-entry/time-picker.js +3 -3
  73. package/dist/components/data-entry/transfer.d.ts +2 -2
  74. package/dist/components/data-entry/transfer.js +5 -5
  75. package/dist/components/data-entry/tree-select.d.ts +1 -1
  76. package/dist/components/data-entry/tree-select.js +5 -5
  77. package/dist/components/data-entry/upload.d.ts +2 -2
  78. package/dist/components/data-entry/upload.js +5 -5
  79. package/dist/components/feedback/alert.js +5 -5
  80. package/dist/components/feedback/dialog.js +3 -3
  81. package/dist/components/feedback/index.d.ts +4 -4
  82. package/dist/components/feedback/index.js +9 -9
  83. package/dist/components/feedback/sheet.js +1 -1
  84. package/dist/components/layout/index.d.ts +6 -9
  85. package/dist/components/layout/index.js +6 -4
  86. package/dist/components/navigation/dropdown-menu.js +1 -1
  87. package/dist/components/navigation/index.d.ts +14 -16
  88. package/dist/components/navigation/index.js +7 -8
  89. package/dist/components/navigation/pagination.d.ts +11 -8
  90. package/dist/components/navigation/pagination.js +4 -5
  91. package/dist/components/navigation/steps.d.ts +3 -3
  92. package/dist/components/navigation/steps.js +3 -1
  93. package/dist/components/query/index.d.ts +1 -5
  94. package/dist/components/query/index.js +6 -8
  95. package/dist/components/ui/index.d.ts +5 -7
  96. package/dist/components/ui/index.js +30 -33
  97. package/dist/{data-entry.prop-CDkOajPj.d.ts → data-entry.prop-BR4vNA1j.d.ts} +7 -35
  98. package/dist/filter-bar-BxjSJJnQ.d.ts +7 -0
  99. package/dist/{inline-CDSVAN54.d.ts → flex-D_EXRFSW.d.ts} +2 -8
  100. package/dist/form/index.js +1 -1
  101. package/dist/i18n/index.d.ts +82 -10
  102. package/dist/i18n/index.js +2 -2
  103. package/dist/index.d.ts +6 -6
  104. package/dist/index.js +41 -44
  105. package/dist/lib/datetime/index.js +1 -1
  106. package/dist/{navigation.prop-8DgElO0c.d.ts → navigation.prop-DMcXkR-J.d.ts} +9 -11
  107. package/dist/{password-strength-kQkloEeo.d.ts → password-strength-DVRvXEOK.d.ts} +2 -2
  108. package/dist/props/components/index.d.ts +3 -3
  109. package/dist/props/index.d.ts +3 -3
  110. package/dist/props/index.js +1 -1
  111. package/dist/props/registry.d.ts +84 -39
  112. package/dist/props/registry.js +1 -1
  113. package/dist/{search-input-cezAxpgb.d.ts → search-input-DpqDMXcn.d.ts} +2 -4
  114. package/dist/{skeleton-uWAjSacg.d.ts → skeleton-cj9kh5wo.d.ts} +1 -3
  115. package/dist/styles/control.css +176 -41
  116. package/dist/styles/data-display-layout.css +41 -15
  117. package/dist/styles/feedback-layout.css +44 -12
  118. package/dist/styles/index.css +45 -1
  119. package/dist/styles/layout.css +18 -17
  120. package/dist/styles/navigation-layout.css +3 -1
  121. package/dist/styles/shell-layout.css +3 -3
  122. package/dist/styles/table-layout.css +13 -0
  123. package/dist/tokens/foundation.css +12 -1
  124. package/dist/tokens/semantic/layout.css +2 -2
  125. package/package.json +6 -7
  126. package/scripts/ui-audit.mjs +35 -2
  127. package/dist/chunk-6MCI7W5G.js +0 -201
  128. package/dist/chunk-CAEL2ZD2.js +0 -222
  129. package/dist/chunk-GKXPALFT.js +0 -32
  130. package/dist/chunk-JKHWLPM5.js +0 -101
  131. package/dist/chunk-KDBGFJJI.js +0 -220
  132. package/dist/components/data-entry/autocomplete.d.ts +0 -24
  133. package/dist/components/data-entry/autocomplete.js +0 -10
  134. package/dist/components/data-entry/combobox.d.ts +0 -22
  135. package/dist/components/data-entry/combobox.js +0 -6
  136. package/dist/filter-bar-B5TPUqEO.d.ts +0 -14
  137. /package/dist/{chunk-LDSLS6HE.js → chunk-7CFO5FFE.js} +0 -0
@@ -1,8 +1,9 @@
1
- import { DropdownMenu, DropdownMenuTrigger } from './chunk-TO33OY4L.js';
2
1
  import { Tooltip, TooltipTrigger, TooltipContent } from './chunk-32WO3YLB.js';
2
+ import { DropdownMenu, DropdownMenuTrigger } from './chunk-LMKUKCTN.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
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -75,12 +76,6 @@ function PageContainerRoot({
75
76
  var PageContainer = Object.assign(PageContainerRoot, {
76
77
  Inset: PageContainerInset
77
78
  });
78
- function PageInset(props) {
79
- return /* @__PURE__ */ jsx(PageContainerInset, { ...props });
80
- }
81
- function Stack(props) {
82
- return /* @__PURE__ */ jsx(Flex, { direction: "col", ...props });
83
- }
84
79
  function AppShell({
85
80
  sidebar,
86
81
  topbar,
@@ -92,6 +87,7 @@ function AppShell({
92
87
  children,
93
88
  sidebarCollapsed = false
94
89
  }) {
90
+ const { t } = useTranslation();
95
91
  const resolvedTopbar = topbar !== void 0 ? topbar : /* @__PURE__ */ jsxs("div", { className: "app-topbar-rail", children: [
96
92
  logo !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-logo", children: logo }),
97
93
  topbarLeft !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-left", children: topbarLeft }),
@@ -99,17 +95,18 @@ function AppShell({
99
95
  topbarRight !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-right", children: topbarRight })
100
96
  ] });
101
97
  return /* @__PURE__ */ jsxs("div", { className: "app-root", "data-collapsed": sidebarCollapsed ? "true" : void 0, children: [
102
- /* @__PURE__ */ jsx("aside", { className: "app-sidebar", children: sidebar }),
103
- /* @__PURE__ */ jsx("header", { className: "app-topbar", children: resolvedTopbar }),
104
- /* @__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: [
105
101
  breadcrumb !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-breadcrumb", children: breadcrumb }),
106
102
  children
107
103
  ] }),
108
- 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 })
109
105
  ] });
110
106
  }
111
107
  function Breadcrumb({ items, linkComponent: LinkComponent = "a" }) {
112
- 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) => {
113
110
  const isLast = index === items.length - 1;
114
111
  return /* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
115
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 }),
@@ -298,6 +295,7 @@ function Sidebar({
298
295
  renderItem,
299
296
  footer
300
297
  }) {
298
+ const { t } = useTranslation();
301
299
  const resolvedSections = sections ?? [];
302
300
  return /* @__PURE__ */ jsxs("div", { className: "sb-root", "data-collapsed": collapsed ? "true" : void 0, children: [
303
301
  brand !== void 0 ? /* @__PURE__ */ jsx(SidebarHeader, { children: brand }) : product ? /* @__PURE__ */ jsxs(
@@ -324,7 +322,7 @@ function Sidebar({
324
322
  ]
325
323
  }
326
324
  ) : null,
327
- /* @__PURE__ */ jsx("div", { className: "sb-nav-scroll", children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
325
+ /* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
328
326
  SidebarSection,
329
327
  {
330
328
  label: section.label,
@@ -373,6 +371,7 @@ function Topbar({
373
371
  onNotificationsOpen,
374
372
  user
375
373
  }) {
374
+ const { t } = useTranslation();
376
375
  const productChip = /* @__PURE__ */ jsxs(
377
376
  "button",
378
377
  {
@@ -414,7 +413,7 @@ function Topbar({
414
413
  {
415
414
  type: "button",
416
415
  className: "tb-icon-btn",
417
- "aria-label": "Toggle sidebar",
416
+ "aria-label": t("layout.topbar.toggleSidebar"),
418
417
  "aria-pressed": collapsed,
419
418
  onClick: onToggleCollapsed,
420
419
  children: collapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(PanelLeftClose, { "aria-hidden": "true" })
@@ -431,18 +430,28 @@ function Topbar({
431
430
  projectMenu
432
431
  ] }) : projectChip : null
433
432
  ] }),
434
- /* @__PURE__ */ jsxs("button", { type: "button", className: "tb-search", onClick: onSearchOpen, children: [
435
- /* @__PURE__ */ jsx(Search, { "aria-hidden": "true" }),
436
- /* @__PURE__ */ jsx("span", { children: "Search..." }),
437
- /* @__PURE__ */ jsx("kbd", { className: "kbd", children: "\u2318K" })
438
- ] }),
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
+ ),
439
448
  rightSlot,
440
449
  onNotificationsOpen ? /* @__PURE__ */ jsxs(
441
450
  "button",
442
451
  {
443
452
  type: "button",
444
453
  className: "tb-icon-btn tb-bell",
445
- "aria-label": "Notifications",
454
+ "aria-label": t("layout.topbar.notifications"),
446
455
  onClick: onNotificationsOpen,
447
456
  children: [
448
457
  /* @__PURE__ */ jsx(Bell, { "aria-hidden": "true" }),
@@ -456,7 +465,7 @@ function Topbar({
456
465
  {
457
466
  type: "button",
458
467
  className: "tb-icon-btn",
459
- "aria-label": "Open tweaks",
468
+ "aria-label": t("layout.topbar.tweaks"),
460
469
  onClick: onTweaksOpen,
461
470
  children: /* @__PURE__ */ jsx(SlidersHorizontal, { "aria-hidden": "true" })
462
471
  }
@@ -487,4 +496,4 @@ function SplitPane({ children, aside, asideWidth = "md" }) {
487
496
  ] });
488
497
  }
489
498
 
490
- export { AppShell, Breadcrumb, PageContainer, PageInset, ResponsiveGrid, Sidebar, SidebarHeader, SidebarItem, SidebarSection, SplitPane, Stack, Topbar };
499
+ export { AppShell, Breadcrumb, PageContainer, ResponsiveGrid, Sidebar, SidebarHeader, SidebarItem, SidebarSection, SplitPane, Topbar };
@@ -13,11 +13,18 @@ function FormField({
13
13
  className,
14
14
  children
15
15
  }) {
16
- const helperId = helper && !error ? `${id}-helper` : void 0;
16
+ const helperId = helper ? `${id}-helper` : void 0;
17
17
  const errorId = error ? `${id}-error` : void 0;
18
- const describedBy = errorId ?? helperId;
18
+ if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production" && !React.isValidElement(children)) {
19
+ console.warn(
20
+ "FormField expects a single React element child to receive aria-describedby/aria-errormessage; the helper text and error message will not be associated with the control."
21
+ );
22
+ }
19
23
  const childWithA11y = React.isValidElement(children) ? React.cloneElement(children, {
20
- "aria-describedby": describedBy,
24
+ // Helper and error can coexist: helper stays on aria-describedby, the error on
25
+ // aria-errormessage (surfaced when aria-invalid is true).
26
+ "aria-describedby": helperId,
27
+ "aria-errormessage": errorId,
21
28
  "aria-required": required ? true : void 0,
22
29
  "aria-invalid": !!error || void 0
23
30
  }) : children;
@@ -30,7 +37,8 @@ function FormField({
30
37
  labelAddon
31
38
  ] }),
32
39
  childWithA11y,
33
- error ? /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: "text-destructive text-xs", children: error }) : helper ? /* @__PURE__ */ jsx("p", { id: helperId, className: "text-muted-foreground text-xs", children: helper }) : null
40
+ helper ? /* @__PURE__ */ jsx("p", { id: helperId, className: "text-muted-foreground text-xs", children: helper }) : null,
41
+ error ? /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: "text-destructive text-xs", children: error }) : null
34
42
  ] });
35
43
  }
36
44
 
@@ -1,13 +1,14 @@
1
- import { humanError } from './chunk-4R7QL3MW.js';
1
+ import { humanError } from './chunk-X2VY4MOW.js';
2
+ import { Flex } from './chunk-INIIF7F7.js';
2
3
  import { Button } from './chunk-M4PZNAMV.js';
3
- import { Inline } from './chunk-TILFZBTE.js';
4
- import { useTranslation } from './chunk-RLGHEV4A.js';
4
+ import { useTranslation } from './chunk-HTG5VHU7.js';
5
5
  import { cn } from './chunk-U7N2A7A3.js';
6
6
  import * as React from 'react';
7
7
  import { Info, CheckCircle2, TriangleAlert, AlertCircle, X, RefreshCw } from 'lucide-react';
8
8
  import { jsx, jsxs } from 'react/jsx-runtime';
9
9
 
10
10
  var AlertContext = React.createContext("default");
11
+ var ASSERTIVE_TONES = /* @__PURE__ */ new Set(["destructive", "warning"]);
11
12
  var DEFAULT_ICONS = {
12
13
  default: Info,
13
14
  destructive: AlertCircle,
@@ -19,12 +20,13 @@ var DEFAULT_ICONS = {
19
20
  };
20
21
  var AlertBase = React.forwardRef(
21
22
  ({ variant = "default", tone = "default", icon, onDismiss, className, children, ...props }, ref) => {
23
+ const { t } = useTranslation();
22
24
  const IconComponent = icon === false ? null : icon ?? DEFAULT_ICONS[tone];
23
25
  return /* @__PURE__ */ jsx(AlertContext.Provider, { value: tone, children: /* @__PURE__ */ jsxs(
24
26
  "div",
25
27
  {
26
28
  ref,
27
- role: "alert",
29
+ role: ASSERTIVE_TONES.has(tone) ? "alert" : "status",
28
30
  "data-slot": "alert",
29
31
  "data-variant": variant,
30
32
  "data-tone": tone,
@@ -43,7 +45,7 @@ var AlertBase = React.forwardRef(
43
45
  },
44
46
  "data-slot": "alert-dismiss",
45
47
  className: "ring-offset-background focus-visible:ring-ring transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
46
- "aria-label": "Dismiss",
48
+ "aria-label": t("feedback.alert.dismiss"),
47
49
  children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
48
50
  }
49
51
  )
@@ -93,7 +95,7 @@ function AlertQueryError({ error, onRetry, className }) {
93
95
  onClick: () => {
94
96
  void onRetry();
95
97
  },
96
- children: /* @__PURE__ */ jsxs(Inline, { gap: "xs", children: [
98
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "row", wrap: true, align: "center", gap: "xs", children: [
97
99
  /* @__PURE__ */ jsx(RefreshCw, { className: "size-4", "aria-hidden": "true" }),
98
100
  t("common.retry")
99
101
  ] })
@@ -1,4 +1,4 @@
1
- import { Field, choiceGroupClassName } from './chunk-26CPAKUP.js';
1
+ import { Field, choiceGroupClassName } from './chunk-44YRPSZ7.js';
2
2
  import { cn } from './chunk-U7N2A7A3.js';
3
3
  import * as React from 'react';
4
4
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
@@ -1,7 +1,8 @@
1
1
  import { controlIconClass } from './chunk-IBK5D2Q6.js';
2
+ import { useTranslation } from './chunk-HTG5VHU7.js';
2
3
  import { cn } from './chunk-U7N2A7A3.js';
3
4
  import { Check, Loader2, X, Circle } from 'lucide-react';
4
- import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
 
6
7
  function resolveStepStatus(index, current, itemStatus, currentStatus) {
7
8
  if (itemStatus) return itemStatus;
@@ -53,17 +54,18 @@ function StepIcon({
53
54
  }
54
55
  function Steps({
55
56
  items = [],
56
- current = 0,
57
- initial = 0,
57
+ value: current = 0,
58
+ defaultValue = 0,
58
59
  status: currentStatus = "process",
59
60
  orientation = "horizontal",
60
61
  type = "default",
61
- size = "default",
62
+ size = "md",
62
63
  titlePlacement = "horizontal",
63
- onChange,
64
+ onValueChange,
64
65
  className
65
66
  }) {
66
- const base = initial;
67
+ const { t } = useTranslation();
68
+ const base = defaultValue;
67
69
  const isVertical = orientation === "vertical";
68
70
  const compact = size === "sm";
69
71
  return /* @__PURE__ */ jsx(
@@ -74,65 +76,69 @@ function Steps({
74
76
  isVertical ? "flex-col gap-0" : "flex-row items-start",
75
77
  className
76
78
  ),
77
- "aria-label": "Progress",
79
+ "aria-label": t("navigation.steps.ariaLabel"),
78
80
  children: items.map((item, index) => {
79
81
  const absoluteIndex = base + index;
80
82
  const stepStatus = resolveStepStatus(absoluteIndex, current, item.status, currentStatus);
81
- const clickable = Boolean(onChange) && !item.disabled;
82
- const description = item.content ?? item.description;
83
+ const interactive = Boolean(onValueChange);
84
+ const clickable = interactive && !item.disabled;
85
+ const description = item.description;
86
+ const isCurrent = absoluteIndex === current;
87
+ const stepClassName = cn(
88
+ "group flex min-w-0",
89
+ isVertical ? "flex-row items-start gap-3" : "flex-col items-center",
90
+ clickable ? "cursor-pointer" : "cursor-default"
91
+ );
92
+ const stepInner = /* @__PURE__ */ jsxs(Fragment, { children: [
93
+ /* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type }),
94
+ /* @__PURE__ */ jsxs(
95
+ "div",
96
+ {
97
+ className: cn(
98
+ "min-w-0",
99
+ isVertical ? "pt-1 text-left" : "mt-2 px-2",
100
+ titlePlacement === "vertical" && !isVertical && "mt-1"
101
+ ),
102
+ children: [
103
+ /* @__PURE__ */ jsx(
104
+ "div",
105
+ {
106
+ className: cn(
107
+ "font-medium",
108
+ compact ? "text-xs" : "text-sm",
109
+ stepStatus === "process" && "text-foreground",
110
+ stepStatus === "wait" && "text-muted-foreground",
111
+ stepStatus === "error" && "text-destructive"
112
+ ),
113
+ children: item.title
114
+ }
115
+ ),
116
+ item.subtitle && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground text-xs", children: item.subtitle }),
117
+ description && /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground", compact ? "text-xs" : "text-sm"), children: description })
118
+ ]
119
+ }
120
+ )
121
+ ] });
83
122
  return /* @__PURE__ */ jsx(
84
123
  "li",
85
124
  {
125
+ "aria-current": isCurrent ? "step" : void 0,
86
126
  className: cn(
87
127
  "relative flex min-w-0 flex-1",
88
128
  isVertical ? "flex-row gap-3 pb-8 last:pb-0" : "flex-col items-center text-center",
89
129
  !isVertical && index < items.length - 1 && "after:bg-border after:absolute after:top-4 after:h-px",
90
130
  !isVertical && index < items.length - 1 && "after:left-[calc(50%+1.25rem)] after:w-[calc(100%-2.5rem)]"
91
131
  ),
92
- children: /* @__PURE__ */ jsxs(
132
+ children: interactive ? /* @__PURE__ */ jsx(
93
133
  "button",
94
134
  {
95
135
  type: "button",
96
136
  disabled: !clickable,
97
- onClick: clickable ? () => onChange?.(absoluteIndex) : void 0,
98
- className: cn(
99
- "group flex min-w-0",
100
- isVertical ? "flex-row items-start gap-3" : "flex-col items-center",
101
- clickable && "cursor-pointer",
102
- !clickable && "cursor-default"
103
- ),
104
- children: [
105
- /* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type }),
106
- /* @__PURE__ */ jsxs(
107
- "div",
108
- {
109
- className: cn(
110
- "min-w-0",
111
- isVertical ? "pt-1 text-left" : "mt-2 px-2",
112
- titlePlacement === "vertical" && !isVertical && "mt-1"
113
- ),
114
- children: [
115
- /* @__PURE__ */ jsx(
116
- "div",
117
- {
118
- className: cn(
119
- "font-medium",
120
- compact ? "text-xs" : "text-sm",
121
- stepStatus === "process" && "text-foreground",
122
- stepStatus === "wait" && "text-muted-foreground",
123
- stepStatus === "error" && "text-destructive"
124
- ),
125
- children: item.title
126
- }
127
- ),
128
- item.subTitle && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground text-xs", children: item.subTitle }),
129
- description && /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground", compact ? "text-xs" : "text-sm"), children: description })
130
- ]
131
- }
132
- )
133
- ]
137
+ onClick: clickable ? () => onValueChange?.(absoluteIndex) : void 0,
138
+ className: stepClassName,
139
+ children: stepInner
134
140
  }
135
- )
141
+ ) : /* @__PURE__ */ jsx("span", { className: stepClassName, children: stepInner })
136
142
  },
137
143
  index
138
144
  );
@@ -0,0 +1,126 @@
1
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-NXVCI6YB.js';
2
+ import { Button } from './chunk-M4PZNAMV.js';
3
+ import { useOptionalAppContext, useTranslation, APP_TIME_FORMAT_OPTIONS, getTimeFormatLabel, resolveTimezonePickerOptions, getTimezoneLabel, APP_LOCALES } from './chunk-HTG5VHU7.js';
4
+ import { APP_DATE_FORMAT_OPTIONS, getDateFormatLabel } from './chunk-6CSBMMZS.js';
5
+ import { cn } from './chunk-U7N2A7A3.js';
6
+ import * as React from 'react';
7
+ import { useId } from 'react';
8
+ import { Clock, CalendarDays, Globe, Languages, X } from 'lucide-react';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
10
+
11
+ function Toolbar({ onClear, hasActiveFilters = true, className, children }) {
12
+ const { t } = useTranslation();
13
+ return /* @__PURE__ */ jsxs(
14
+ "div",
15
+ {
16
+ role: "toolbar",
17
+ "aria-label": t("navigation.toolbar.ariaLabel"),
18
+ className: cn("ui-toolbar", className),
19
+ children: [
20
+ children,
21
+ onClear && hasActiveFilters && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: onClear, className: "ui-toolbar-clear", children: [
22
+ /* @__PURE__ */ jsx(X, { "aria-hidden": "true" }),
23
+ t("common.clearFilters")
24
+ ] })
25
+ ]
26
+ }
27
+ );
28
+ }
29
+ function ToolbarGroup({ label, className, children }) {
30
+ const labelId = useId();
31
+ return /* @__PURE__ */ jsxs(
32
+ "div",
33
+ {
34
+ role: "group",
35
+ "aria-labelledby": label ? labelId : void 0,
36
+ className: cn("ui-stack-xs ui-toolbar-group", className),
37
+ children: [
38
+ label ? /* @__PURE__ */ jsx("div", { id: labelId, className: "ui-toolbar-label", children: label }) : null,
39
+ children
40
+ ]
41
+ }
42
+ );
43
+ }
44
+ var ICON = {
45
+ locale: Languages,
46
+ timezone: Globe,
47
+ dateFormat: CalendarDays,
48
+ timeFormat: Clock
49
+ };
50
+ var TRIGGER_WIDTH = {
51
+ locale: "sm:w-40",
52
+ timezone: "sm:w-56",
53
+ dateFormat: "sm:w-44",
54
+ timeFormat: "sm:w-44"
55
+ };
56
+ var ARIA_KEY = {
57
+ locale: "navigation.localePicker.ariaLabel",
58
+ timezone: "navigation.timezonePicker.ariaLabel",
59
+ dateFormat: "navigation.dateFormatPicker.ariaLabel",
60
+ timeFormat: "navigation.timeFormatPicker.ariaLabel"
61
+ };
62
+ var AppSettingPicker = React.forwardRef(
63
+ function AppSettingPicker2({ kind, className, disabled, id, name, value, onValueChange }, ref) {
64
+ const ctx = useOptionalAppContext();
65
+ const { t, locale, fallbackLocale } = useTranslation();
66
+ const current = value ?? ctx?.[kind];
67
+ const setter = ctx ? {
68
+ locale: ctx.setLocale,
69
+ timezone: ctx.setTimezone,
70
+ dateFormat: ctx.setDateFormat,
71
+ timeFormat: ctx.setTimeFormat
72
+ }[kind] : void 0;
73
+ const handleChange = onValueChange ?? setter;
74
+ const items = React.useMemo(() => {
75
+ switch (kind) {
76
+ case "locale":
77
+ return APP_LOCALES.map((code) => ({ value: code, label: t(`locale.${code}`) }));
78
+ case "timezone":
79
+ return resolveTimezonePickerOptions(ctx?.timezoneOptions, current ?? "").map((tz) => ({
80
+ value: tz,
81
+ label: getTimezoneLabel(tz, locale, fallbackLocale)
82
+ }));
83
+ case "dateFormat":
84
+ return APP_DATE_FORMAT_OPTIONS.map((option) => ({
85
+ value: option.value,
86
+ label: getDateFormatLabel(option.value, locale, fallbackLocale)
87
+ }));
88
+ case "timeFormat":
89
+ return APP_TIME_FORMAT_OPTIONS.map((option) => ({
90
+ value: option.value,
91
+ label: getTimeFormatLabel(option.value, locale, fallbackLocale)
92
+ }));
93
+ }
94
+ }, [kind, ctx?.timezoneOptions, current, t, locale, fallbackLocale]);
95
+ const unbound = current === void 0 || !handleChange;
96
+ const Icon = ICON[kind];
97
+ return /* @__PURE__ */ jsxs(
98
+ Select,
99
+ {
100
+ value: current ?? "",
101
+ onValueChange: handleChange ?? (() => {
102
+ }),
103
+ disabled: disabled || unbound,
104
+ name,
105
+ children: [
106
+ /* @__PURE__ */ jsxs(
107
+ SelectTrigger,
108
+ {
109
+ ref,
110
+ id,
111
+ className: cn("w-full", TRIGGER_WIDTH[kind], className),
112
+ "aria-label": t(ARIA_KEY[kind]),
113
+ children: [
114
+ /* @__PURE__ */ jsx(Icon, { className: "me-2 size-4 shrink-0 opacity-70", "aria-hidden": "true" }),
115
+ /* @__PURE__ */ jsx(SelectValue, {})
116
+ ]
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsx(SelectContent, { children: items.map((item) => /* @__PURE__ */ jsx(SelectItem, { value: item.value, children: item.label }, item.value)) })
120
+ ]
121
+ }
122
+ );
123
+ }
124
+ );
125
+
126
+ export { AppSettingPicker, Toolbar, ToolbarGroup };
@@ -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