@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,8 +1,8 @@
1
1
  import { Input } from './chunk-VOHTRR5X.js';
2
2
  import { Button } from './chunk-M4PZNAMV.js';
3
3
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
4
- import { useTranslation } from './chunk-RLGHEV4A.js';
5
- import { normalizeHhmm, isValidHhmm } from './chunk-FXFJF4YA.js';
4
+ import { useTranslation, usePickerLocales } from './chunk-HTG5VHU7.js';
5
+ import { normalizeHhmm, isValidHhmm } from './chunk-6CSBMMZS.js';
6
6
  import { cn } from './chunk-U7N2A7A3.js';
7
7
  import * as React from 'react';
8
8
  import { Clock } from 'lucide-react';
@@ -23,49 +23,97 @@ function parseHhmm(value) {
23
23
  const [h, m] = normalized.split(":").map(Number);
24
24
  return { hour: h, minute: m };
25
25
  }
26
+ function to12h(hour24) {
27
+ const h = hour24 % 12;
28
+ return h === 0 ? 12 : h;
29
+ }
30
+ function from12h(hour12, meridiem) {
31
+ const base = hour12 % 12;
32
+ return meridiem === "pm" ? base + 12 : base;
33
+ }
26
34
  function TimeColumn({
27
35
  label,
28
36
  items,
29
37
  selected,
38
+ formatItem,
30
39
  onSelect
31
40
  }) {
32
41
  const listRef = React.useRef(null);
33
42
  React.useEffect(() => {
34
43
  listRef.current?.querySelector('[data-selected="true"]')?.scrollIntoView({ block: "center" });
35
44
  }, [selected]);
45
+ const moveFocus = (index) => {
46
+ const options = listRef.current?.querySelectorAll('[role="option"]');
47
+ options?.[index]?.focus();
48
+ };
49
+ const onKeyDown = (e, index) => {
50
+ switch (e.key) {
51
+ case "ArrowDown":
52
+ e.preventDefault();
53
+ moveFocus(Math.min(items.length - 1, index + 1));
54
+ break;
55
+ case "ArrowUp":
56
+ e.preventDefault();
57
+ moveFocus(Math.max(0, index - 1));
58
+ break;
59
+ case "Home":
60
+ e.preventDefault();
61
+ moveFocus(0);
62
+ break;
63
+ case "End":
64
+ e.preventDefault();
65
+ moveFocus(items.length - 1);
66
+ break;
67
+ case "Enter":
68
+ case " ":
69
+ e.preventDefault();
70
+ onSelect(items[index]);
71
+ break;
72
+ }
73
+ };
36
74
  return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
37
75
  /* @__PURE__ */ jsx("div", { className: "text-muted-foreground border-b px-1 py-1.5 text-center text-xs font-medium", children: label }),
38
76
  /* @__PURE__ */ jsx(
39
77
  "div",
40
78
  {
41
79
  ref: listRef,
80
+ role: "listbox",
81
+ "aria-label": label,
42
82
  className: "h-52 [scrollbar-width:thin] [scrollbar-gutter:stable] overflow-y-scroll overscroll-contain p-1",
43
- children: items.map((item) => /* @__PURE__ */ jsx(
44
- "button",
45
- {
46
- type: "button",
47
- "data-selected": item === selected,
48
- className: cn(
49
- "hover:bg-accent flex w-full items-center justify-center rounded-md py-1.5 text-sm tabular-nums transition-colors",
50
- item === selected && "bg-primary text-primary-foreground hover:bg-primary/90"
51
- ),
52
- onClick: () => {
53
- onSelect(item);
83
+ children: items.map((item, index) => {
84
+ const isSelected = item === selected;
85
+ return /* @__PURE__ */ jsx(
86
+ "button",
87
+ {
88
+ type: "button",
89
+ role: "option",
90
+ "aria-selected": isSelected,
91
+ "data-selected": isSelected,
92
+ tabIndex: isSelected ? 0 : -1,
93
+ className: cn(
94
+ "hover:bg-accent flex w-full items-center justify-center rounded-md py-1.5 text-sm tabular-nums transition-colors",
95
+ isSelected && "bg-primary text-primary-foreground hover:bg-primary/90"
96
+ ),
97
+ onClick: () => {
98
+ onSelect(item);
99
+ },
100
+ onKeyDown: (e) => onKeyDown(e, index),
101
+ children: formatItem(item)
54
102
  },
55
- children: pad2(item)
56
- },
57
- item
58
- ))
103
+ item
104
+ );
105
+ })
59
106
  }
60
107
  )
61
108
  ] });
62
109
  }
63
- function TimePickerPanel({ value, minuteStep, onChange, onDone }) {
110
+ function TimePickerPanel({ value, minuteStep, use12h, onChange, onDone }) {
64
111
  const { t } = useTranslation();
65
112
  const { hour, minute } = parseHhmm(value);
66
113
  const minutes = buildMinutes(minuteStep);
67
114
  const snappedMinute = minutes.includes(minute) ? minute : minutes[0];
68
115
  const [draft, setDraft] = React.useState(value);
116
+ const meridiem = hour >= 12 ? "pm" : "am";
69
117
  React.useEffect(() => {
70
118
  setDraft(value);
71
119
  }, [value]);
@@ -79,16 +127,20 @@ function TimePickerPanel({ value, minuteStep, onChange, onDone }) {
79
127
  onChange(next);
80
128
  onDone?.();
81
129
  };
82
- return /* @__PURE__ */ jsxs("div", { className: "w-36", children: [
130
+ const hourItems = use12h ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 24 }, (_, i) => i);
131
+ const selectedHourItem = use12h ? to12h(hour) : hour;
132
+ return /* @__PURE__ */ jsxs("div", { className: use12h ? "w-52" : "w-36", children: [
83
133
  /* @__PURE__ */ jsxs("div", { className: "divide-border flex divide-x", children: [
84
134
  /* @__PURE__ */ jsx(
85
135
  TimeColumn,
86
136
  {
87
137
  label: t("dataEntry.timePicker.hour"),
88
- items: Array.from({ length: 24 }, (_, i) => i),
89
- selected: hour,
138
+ items: hourItems,
139
+ selected: selectedHourItem,
140
+ formatItem: (h) => use12h ? String(h) : pad2(h),
90
141
  onSelect: (h) => {
91
- onChange(`${pad2(h)}:${pad2(snappedMinute)}`);
142
+ const hour24 = use12h ? from12h(h, meridiem) : h;
143
+ onChange(`${pad2(hour24)}:${pad2(snappedMinute)}`);
92
144
  }
93
145
  }
94
146
  ),
@@ -98,10 +150,25 @@ function TimePickerPanel({ value, minuteStep, onChange, onDone }) {
98
150
  label: t("dataEntry.timePicker.minute"),
99
151
  items: minutes,
100
152
  selected: snappedMinute,
153
+ formatItem: (m) => pad2(m),
101
154
  onSelect: (m) => {
102
155
  commit(`${pad2(hour)}:${pad2(m)}`);
103
156
  }
104
157
  }
158
+ ),
159
+ use12h && /* @__PURE__ */ jsx(
160
+ TimeColumn,
161
+ {
162
+ label: t("dataEntry.timePicker.meridiem"),
163
+ items: [0, 1],
164
+ selected: meridiem === "pm" ? 1 : 0,
165
+ formatItem: (m) => m === 1 ? t("dataEntry.timePicker.pm") : t("dataEntry.timePicker.am"),
166
+ onSelect: (m) => {
167
+ const nextMeridiem = m === 1 ? "pm" : "am";
168
+ const hour24 = from12h(to12h(hour), nextMeridiem);
169
+ onChange(`${pad2(hour24)}:${pad2(snappedMinute)}`);
170
+ }
171
+ }
105
172
  )
106
173
  ] }),
107
174
  /* @__PURE__ */ jsx("div", { className: "border-t p-2", children: /* @__PURE__ */ jsx(
@@ -142,6 +209,8 @@ function TimePicker({
142
209
  minuteStep = 5
143
210
  }) {
144
211
  const { t } = useTranslation();
212
+ const { timeFormat } = usePickerLocales();
213
+ const use12h = timeFormat === "12h";
145
214
  const [open, setOpen] = React.useState(false);
146
215
  const [internal, setInternal] = React.useState(defaultValue ?? "");
147
216
  const isControlled = controlledValue !== void 0;
@@ -169,7 +238,7 @@ function TimePicker({
169
238
  role: "combobox",
170
239
  "aria-expanded": open,
171
240
  "aria-haspopup": "dialog",
172
- className: "pr-10 tabular-nums",
241
+ className: "pe-10 tabular-nums",
173
242
  onChange: (event) => {
174
243
  setText(event.target.value);
175
244
  const normalized = normalizeHhmm(event.target.value);
@@ -191,7 +260,7 @@ function TimePicker({
191
260
  disabled,
192
261
  tabIndex: -1,
193
262
  "aria-label": t("dataEntry.timePicker.openPicker") ?? "Open time picker",
194
- className: "text-muted-foreground absolute inset-y-0 right-0 h-full px-2 hover:bg-transparent",
263
+ className: "text-muted-foreground absolute inset-y-0 end-0 h-full px-2 hover:bg-transparent",
195
264
  children: /* @__PURE__ */ jsx(Clock, { className: "size-4 shrink-0", "aria-hidden": "true" })
196
265
  }
197
266
  ) }),
@@ -200,6 +269,7 @@ function TimePicker({
200
269
  {
201
270
  value: value || "09:00",
202
271
  minuteStep,
272
+ use12h,
203
273
  onChange: (next) => {
204
274
  setValue(next);
205
275
  setText(next);
@@ -0,0 +1,163 @@
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, jsxs } from 'react/jsx-runtime';
6
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
7
+ import { Check, X } from 'lucide-react';
8
+
9
+ var toggleVariants = cva("ui-toggle", {
10
+ variants: {
11
+ variant: {
12
+ default: "ui-toggle-default",
13
+ outline: "ui-toggle-outline"
14
+ },
15
+ size: {
16
+ sm: "ui-toggle-sm",
17
+ md: "ui-toggle-default-size",
18
+ lg: "ui-toggle-lg"
19
+ }
20
+ },
21
+ defaultVariants: {
22
+ variant: "default",
23
+ size: "md"
24
+ }
25
+ });
26
+ var Toggle = React2.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
27
+ TogglePrimitive.Root,
28
+ {
29
+ ref,
30
+ "data-slot": "toggle",
31
+ className: cn(toggleVariants({ variant, size }), className),
32
+ ...props
33
+ }
34
+ ));
35
+ Toggle.displayName = TogglePrimitive.Root.displayName;
36
+ var ToggleGroup = React2.forwardRef(({ className, variant = "default", size = "default", children, ...props }, ref) => /* @__PURE__ */ jsx(
37
+ ToggleGroupPrimitive.Root,
38
+ {
39
+ ref,
40
+ "data-slot": "toggle-group",
41
+ "data-variant": variant,
42
+ "data-size": size,
43
+ className: cn("ui-toggle-group", className),
44
+ ...props,
45
+ children
46
+ }
47
+ ));
48
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
49
+ var ToggleGroupItem = React2.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
50
+ ToggleGroupPrimitive.Item,
51
+ {
52
+ ref,
53
+ "data-slot": "toggle-group-item",
54
+ className: cn(toggleVariants({ variant, size }), className),
55
+ ...props
56
+ }
57
+ ));
58
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
59
+ var DEFAULT_PASSWORD_RULES = ["length", "upper", "lower", "number", "symbol"];
60
+ var DEFAULT_LABELS = {
61
+ weak: "Weak",
62
+ fair: "Fair",
63
+ strong: "Strong"
64
+ };
65
+ function usePasswordStrength(value, rules = [...DEFAULT_PASSWORD_RULES]) {
66
+ const uniqueRules = [...new Set(rules)];
67
+ const checks = {
68
+ length: value.length >= 8,
69
+ upper: /[A-Z]/.test(value),
70
+ lower: /[a-z]/.test(value),
71
+ number: /\d/.test(value),
72
+ symbol: /[^A-Za-z0-9]/.test(value)
73
+ };
74
+ const passed = uniqueRules.filter((rule) => checks[rule]).length;
75
+ const score = Math.max(0, Math.min(4, passed));
76
+ return { score, checks };
77
+ }
78
+ function scoreTone(score) {
79
+ if (score <= 1) return "destructive";
80
+ if (score <= 3) return "warning";
81
+ return "success";
82
+ }
83
+ function scoreLabel(score, labels) {
84
+ if (score <= 1) return labels.weak;
85
+ if (score <= 3) return labels.fair;
86
+ return labels.strong;
87
+ }
88
+ function PasswordStrength({
89
+ value,
90
+ rules = [...DEFAULT_PASSWORD_RULES],
91
+ showChecklist = true,
92
+ labels = DEFAULT_LABELS
93
+ }) {
94
+ const normalizedRules = [...new Set(rules)];
95
+ const { score, checks } = usePasswordStrength(value, normalizedRules);
96
+ const tone = scoreTone(score);
97
+ const segments = Array.from({ length: 5 });
98
+ return /* @__PURE__ */ jsxs("div", { className: "ui-password-strength", children: [
99
+ /* @__PURE__ */ jsx(
100
+ "div",
101
+ {
102
+ className: "ui-password-strength-track",
103
+ role: "img",
104
+ "aria-label": `Password strength ${score}/4`,
105
+ children: segments.map((_, index) => {
106
+ const filled = index < score + 1;
107
+ return /* @__PURE__ */ jsx(
108
+ "span",
109
+ {
110
+ className: "ui-password-strength-segment",
111
+ "data-tone": filled ? tone : void 0,
112
+ "data-state": filled ? "filled" : "empty",
113
+ "aria-hidden": "true"
114
+ },
115
+ index
116
+ );
117
+ })
118
+ }
119
+ ),
120
+ /* @__PURE__ */ jsxs("div", { className: "ui-password-strength-meta", children: [
121
+ /* @__PURE__ */ jsx("span", { className: "ui-password-strength-label", children: scoreLabel(score, labels) }),
122
+ /* @__PURE__ */ jsxs("span", { className: "ui-password-strength-score", "aria-hidden": "true", children: [
123
+ score,
124
+ "/4"
125
+ ] })
126
+ ] }),
127
+ showChecklist ? /* @__PURE__ */ jsx("ul", { className: "ui-password-strength-checklist", children: normalizedRules.map((rule) => /* @__PURE__ */ jsxs(
128
+ "li",
129
+ {
130
+ className: "ui-password-strength-checklist-item",
131
+ "data-state": checks[rule] ? "passed" : "failed",
132
+ children: [
133
+ checks[rule] ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(X, { "aria-hidden": "true" }),
134
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: checks[rule] ? "Passed: " : "Failed: " }),
135
+ /* @__PURE__ */ jsx("span", { children: labelForRule(rule) })
136
+ ]
137
+ },
138
+ rule
139
+ )) }) : null,
140
+ /* @__PURE__ */ jsxs("span", { className: "sr-only", "aria-live": "polite", children: [
141
+ scoreLabel(score, labels),
142
+ " password strength"
143
+ ] })
144
+ ] });
145
+ }
146
+ function labelForRule(rule) {
147
+ switch (rule) {
148
+ case "length":
149
+ return "8+ characters";
150
+ case "upper":
151
+ return "Contains uppercase letter";
152
+ case "lower":
153
+ return "Contains lowercase letter";
154
+ case "number":
155
+ return "Contains number";
156
+ case "symbol":
157
+ return "Contains symbol";
158
+ default:
159
+ return rule;
160
+ }
161
+ }
162
+
163
+ export { PasswordStrength, Toggle, ToggleGroup, ToggleGroupItem, toggleVariants, usePasswordStrength };
@@ -1,4 +1,4 @@
1
- import { formatDate, translateCurrent } from './chunk-FXFJF4YA.js';
1
+ import { formatDate, getSyncedLocale, translateCurrent } from './chunk-6CSBMMZS.js';
2
2
 
3
3
  // src/lib/format.ts
4
4
  function formatDateTime(value, options) {
@@ -10,38 +10,23 @@ function formatDateLong(value, options) {
10
10
  function formatRelative(value, options) {
11
11
  return formatDate(value, { ...options, kind: "relative" });
12
12
  }
13
- function formatBytes(n) {
13
+ function formatBytes(n, locale = getSyncedLocale()) {
14
14
  if (n == null) return "\u2014";
15
- if (n < 1024) return `${n} B`;
16
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
17
- if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
18
- return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
15
+ const num = (digits, scaled) => new Intl.NumberFormat(locale, {
16
+ minimumFractionDigits: digits,
17
+ maximumFractionDigits: digits
18
+ }).format(scaled);
19
+ if (n < 1024) return `${num(0, n)} B`;
20
+ if (n < 1024 * 1024) return `${num(1, n / 1024)} KB`;
21
+ if (n < 1024 * 1024 * 1024) return `${num(1, n / 1024 / 1024)} MB`;
22
+ return `${num(2, n / 1024 / 1024 / 1024)} GB`;
19
23
  }
20
- function formatCurrency(amountMinor, currency) {
24
+ function formatCurrency(amountMinor, currency, locale = getSyncedLocale()) {
21
25
  if (amountMinor == null || !currency) return "\u2014";
22
- const zeroDecimal = [
23
- "JPY",
24
- "VND",
25
- "KRW",
26
- "CLP",
27
- "ISK",
28
- "BIF",
29
- "DJF",
30
- "GNF",
31
- "KMF",
32
- "RWF",
33
- "XAF",
34
- "XOF",
35
- "XPF"
36
- ];
37
- const minorUnitDigits = zeroDecimal.includes(currency.toUpperCase()) ? 0 : 2;
26
+ const formatter = new Intl.NumberFormat(locale, { style: "currency", currency });
27
+ const minorUnitDigits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
38
28
  const major = amountMinor / Math.pow(10, minorUnitDigits);
39
- return new Intl.NumberFormat("en-US", {
40
- style: "currency",
41
- currency,
42
- minimumFractionDigits: minorUnitDigits,
43
- maximumFractionDigits: minorUnitDigits
44
- }).format(major);
29
+ return formatter.format(major);
45
30
  }
46
31
  function shortId(id) {
47
32
  if (!id) return "\u2014";
@@ -1,8 +1,22 @@
1
1
  import { cn } from './chunk-U7N2A7A3.js';
2
2
  import * as React from 'react';
3
- import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
3
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
4
4
  import { jsx } from 'react/jsx-runtime';
5
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
5
6
 
7
+ var Separator = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
8
+ SeparatorPrimitive.Root,
9
+ {
10
+ ref,
11
+ "data-slot": "separator",
12
+ "data-orientation": orientation,
13
+ orientation,
14
+ decorative,
15
+ className: cn("ui-separator", className),
16
+ ...props
17
+ }
18
+ ));
19
+ Separator.displayName = SeparatorPrimitive.Root.displayName;
6
20
  var AspectRatio = React.forwardRef(({ className, ratio = 16 / 9, ...props }, ref) => /* @__PURE__ */ jsx(
7
21
  AspectRatioPrimitive.Root,
8
22
  {
@@ -15,4 +29,4 @@ var AspectRatio = React.forwardRef(({ className, ratio = 16 / 9, ...props }, ref
15
29
  ));
16
30
  AspectRatio.displayName = AspectRatioPrimitive.Root.displayName;
17
31
 
18
- export { AspectRatio };
32
+ export { AspectRatio, Separator };