@komensal/ui 0.14.1 → 0.16.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.
package/dist/index.js CHANGED
@@ -1,134 +1,43 @@
1
- // src/components/add-tile.tsx
2
- import * as React from "react";
3
-
4
- // src/utils/cn.ts
5
- import { clsx } from "clsx";
6
- import { twMerge } from "tailwind-merge";
7
- function cn(...inputs) {
8
- return twMerge(clsx(inputs));
9
- }
10
-
11
- // src/utils/color.ts
12
- function isLightColor(hex) {
13
- const normalized = hex.replace("#", "");
14
- const r = parseInt(normalized.slice(0, 2), 16);
15
- const g = parseInt(normalized.slice(2, 4), 16);
16
- const b = parseInt(normalized.slice(4, 6), 16);
17
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
18
- return luminance > 0.6;
19
- }
20
-
21
- // src/utils/format.ts
22
- var DEFAULT_CURRENCY = "COP";
23
- var DEFAULT_LOCALE = "es-CO";
24
- function capitalize(value) {
25
- if (!value) return "";
26
- const trimmed = value.trimStart();
27
- if (trimmed.length === 0) return value;
28
- return trimmed.charAt(0).toLocaleUpperCase("es") + trimmed.slice(1);
29
- }
30
- function formatNumber(value, locale = DEFAULT_LOCALE) {
31
- return new Intl.NumberFormat(locale, { style: "decimal" }).format(value);
32
- }
33
- function formatPrice(value, locale = DEFAULT_LOCALE, currency = DEFAULT_CURRENCY) {
34
- return new Intl.NumberFormat(locale, {
35
- currency,
36
- maximumFractionDigits: 0,
37
- style: "currency"
38
- }).format(value);
39
- }
40
-
41
- // src/utils/styles.ts
42
- var inputSurface = cn(
43
- "w-full rounded-[10px] px-3 text-base font-normal",
44
- "border-border bg-surface text-foreground border",
45
- "transition-all duration-200 ease-in-out",
46
- "placeholder:text-icon-muted placeholder:text-sm placeholder:leading-none placeholder:font-normal",
47
- "disabled:bg-inactive disabled:text-inactive-text disabled:border-inactive disabled:placeholder:text-inactive-text disabled:cursor-not-allowed"
48
- );
49
- var inputBase = cn("flex !h-[50px] items-center justify-between gap-[10px]", inputSurface);
50
- var inputPlaceholder = cn("text-icon-muted text-sm leading-none font-normal");
51
- var inputDisabled = cn("cursor-not-allowed opacity-50");
52
- var inputCompact = cn(
53
- "border-border bg-surface text-foreground focus:border-primary focus:ring-ring h-9 w-full rounded-lg border px-2.5 text-sm focus:ring-2 focus:outline-none"
54
- );
55
- var inputFocus = cn(
56
- "focus:outline-none focus-visible:outline-none",
57
- "focus-visible:ring-ring focus-visible:border-primary focus-visible:ring-2",
58
- "data-[state=open]:ring-ring data-[state=open]:border-primary data-[state=open]:ring-2"
59
- );
60
-
61
- // src/utils/tag-emoji.ts
62
- var TAG_EMOJI_RULES = [
63
- { emoji: "\u{1F336}\uFE0F", keywords: ["picante", "picoso", "spicy"] },
64
- { emoji: "\u{1F95C}", keywords: ["nuez", "nueces", "mani", "cacahuate", "frutos secos"] },
65
- { emoji: "\u{1F331}", keywords: ["vegano", "vegetariano", "vegan"] },
66
- { emoji: "\u{1F33E}", keywords: ["sin gluten", "gluten free"] },
67
- { emoji: "\u{1F95B}", keywords: ["lacteos", "leche", "lactosa"] },
68
- { emoji: "\u{1F990}", keywords: ["marisco", "camaron"] },
69
- { emoji: "\u{1F525}", keywords: ["popular", "top ventas"] },
70
- { emoji: "\u{1F195}", keywords: ["nuevo", "new"] },
71
- { emoji: "\u{1F36C}", keywords: ["dulce"] },
72
- { emoji: "\u{1F9CA}", keywords: ["frio", "helado"] }
73
- ];
74
- function getTagEmoji(tag) {
75
- const normalized = normalize(tag);
76
- const match = TAG_EMOJI_RULES.find((rule) => rule.keywords.some((keyword) => normalized.includes(keyword)));
77
- return match?.emoji ?? null;
78
- }
79
- function normalize(text) {
80
- return text.toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, "");
81
- }
82
-
83
- // src/utils/toast-emitter.ts
84
- var emitToast = null;
85
- var toast = {
86
- error(options) {
87
- emit("destructive", options);
88
- },
89
- info(options) {
90
- emit("info", options);
91
- },
92
- success(options) {
93
- emit("success", options);
94
- },
95
- wait(options) {
96
- emit("wait", options);
97
- },
98
- warning(options) {
99
- emit("warning", options);
100
- }
101
- };
102
- function registerToastEmitter(fn) {
103
- emitToast = fn;
104
- }
105
- function emit(type, options) {
106
- if (!emitToast) return;
107
- if (typeof options === "string") {
108
- emitToast(type, { title: options });
109
- } else {
110
- emitToast(type, options);
111
- }
112
- }
113
-
114
- // src/utils/url.ts
115
- function isSafeUrl(url) {
116
- try {
117
- const parsed = new URL(url, "https://placeholder.invalid");
118
- return parsed.protocol === "http:" || parsed.protocol === "https:";
119
- } catch {
120
- return false;
121
- }
122
- }
123
-
124
- // src/utils/z-index.ts
125
- var zPopover = "z-50";
126
- var zDialogOverlay = "z-60";
127
- var zDialogContent = "z-70";
128
- var zPopoverAboveDialog = "z-100";
129
- var zToast = "z-4000";
1
+ import {
2
+ Form,
3
+ FormControl,
4
+ FormField,
5
+ FormFieldShell,
6
+ FormItem,
7
+ FormMessage,
8
+ GoogleMapPicker,
9
+ Label,
10
+ LabelField,
11
+ MapPickerField,
12
+ capitalize,
13
+ cn,
14
+ focusRing,
15
+ formatNumber,
16
+ formatPrice,
17
+ getTagEmoji,
18
+ inputBase,
19
+ inputCompact,
20
+ inputDisabled,
21
+ inputFocus,
22
+ inputPlaceholder,
23
+ inputSurface,
24
+ isLightColor,
25
+ isSafeUrl,
26
+ registerToastEmitter,
27
+ toast,
28
+ useFormField,
29
+ zDialogContent,
30
+ zDialogOverlay,
31
+ zPopover,
32
+ zPopoverAboveDialog,
33
+ zToast
34
+ } from "./chunk-5VBG6IKL.js";
35
+ import {
36
+ ui_default
37
+ } from "./chunk-FDVY36KS.js";
130
38
 
131
39
  // src/components/add-tile.tsx
40
+ import * as React from "react";
132
41
  import { jsx, jsxs } from "react/jsx-runtime";
133
42
  var AddTile = React.forwardRef(
134
43
  ({ className, icon, label, labelClassName, ...props }, ref) => /* @__PURE__ */ jsxs(
@@ -165,22 +74,27 @@ var variantIcons = {
165
74
  success: CheckCircleIcon,
166
75
  warning: WarningIcon
167
76
  };
77
+ var variantRoles = {
78
+ destructive: "alert",
79
+ info: "status",
80
+ success: "status",
81
+ warning: "alert"
82
+ };
168
83
  var Alert = ({ children, className, variant = "destructive", ...props }) => {
169
84
  const styles = variantStyles[variant];
170
85
  const Icon = variantIcons[variant];
171
86
  return /* @__PURE__ */ jsxs2(
172
87
  "div",
173
88
  {
174
- "aria-live": "polite",
175
89
  className: cn(
176
90
  "flex items-center justify-center gap-2 rounded-[10px] px-4 py-3 text-sm",
177
91
  styles.container,
178
92
  className
179
93
  ),
180
- role: "alert",
94
+ role: variantRoles[variant],
181
95
  ...props,
182
96
  children: [
183
- /* @__PURE__ */ jsx2(Icon, { className: cn("h-5 w-5 shrink-0", styles.icon) }),
97
+ /* @__PURE__ */ jsx2(Icon, { "aria-hidden": true, className: cn("h-5 w-5 shrink-0", styles.icon) }),
184
98
  /* @__PURE__ */ jsx2("span", { children })
185
99
  ]
186
100
  }
@@ -208,64 +122,9 @@ var AuthHeader = ({
208
122
  // src/components/breadcrumb.tsx
209
123
  import * as React3 from "react";
210
124
 
211
- // src/components/skeleton.tsx
212
- import * as React2 from "react";
213
- import { jsx as jsx4 } from "react/jsx-runtime";
214
- var Skeleton = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4("div", { className: cn("bg-inactive animate-pulse rounded-md", className), ref, ...props }));
215
- Skeleton.displayName = "Skeleton";
216
-
217
- // src/components/breadcrumb.tsx
218
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
219
- var Breadcrumb = React3.forwardRef(({ className, items, ...props }, ref) => /* @__PURE__ */ jsx5("div", { className: cn("flex items-center gap-1 text-sm", className), ref, ...props, children: items.map((item, index) => {
220
- const isLast = index === items.length - 1;
221
- return /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1", children: [
222
- index > 0 && /* @__PURE__ */ jsx5("span", { className: "text-muted", children: "\u203A" }),
223
- item.loading ? /* @__PURE__ */ jsx5(Skeleton, { className: "h-4 w-20" }) : item.onClick && !isLast ? /* @__PURE__ */ jsx5("button", { className: "text-muted hover:text-foreground transition-colors", onClick: item.onClick, type: "button", children: item.label }) : /* @__PURE__ */ jsx5("span", { className: isLast ? "text-foreground font-semibold" : "text-muted font-normal", children: item.label })
224
- ] }, `${item.label}-${index}`);
225
- }) }));
226
- Breadcrumb.displayName = "Breadcrumb";
227
-
228
- // src/components/button.tsx
229
- import { Slot } from "@radix-ui/react-slot";
230
- import { cva } from "class-variance-authority";
231
- import * as React5 from "react";
232
-
233
- // src/components/spinner.tsx
234
- import clsx2 from "clsx";
235
-
236
125
  // src/lib/i18n.ts
237
126
  import i18n from "i18next";
238
127
  import { initReactI18next, useTranslation } from "react-i18next";
239
-
240
- // src/locales/es/ui.json
241
- var ui_default = {
242
- inputField: {
243
- showPassword: "Mostrar contrase\xF1a",
244
- hidePassword: "Ocultar contrase\xF1a",
245
- clear: "Limpiar"
246
- },
247
- dialog: {
248
- close: "Cerrar"
249
- },
250
- selectInput: {
251
- placeholder: "Selecciona...",
252
- loading: "Cargando...",
253
- search: "Buscar...",
254
- noResults: "Sin resultados.",
255
- clear: "Limpiar selecci\xF3n"
256
- },
257
- passwordChecklist: {
258
- minLength: "M\xEDnimo {{min}} caracteres",
259
- hasUpperAndLower: "Una may\xFAscula y min\xFAscula",
260
- hasNumber: "Un n\xFAmero",
261
- hasSpecialChar: "Un car\xE1cter especial"
262
- },
263
- spinner: {
264
- loading: "Cargando..."
265
- }
266
- };
267
-
268
- // src/lib/i18n.ts
269
128
  var uiI18n = i18n.createInstance();
270
129
  void uiI18n.use(initReactI18next).init({
271
130
  defaultNS: "ui",
@@ -278,7 +137,48 @@ void uiI18n.use(initReactI18next).init({
278
137
  var setUiLanguage = (lng) => uiI18n.changeLanguage(lng);
279
138
  var useUiT = () => useTranslation("ui", { i18n: uiI18n }).t;
280
139
 
140
+ // src/components/skeleton.tsx
141
+ import * as React2 from "react";
142
+ import { jsx as jsx4 } from "react/jsx-runtime";
143
+ var Skeleton = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4("div", { className: cn("bg-inactive animate-pulse rounded-md", className), ref, ...props }));
144
+ Skeleton.displayName = "Skeleton";
145
+
146
+ // src/components/breadcrumb.tsx
147
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
148
+ var Breadcrumb = React3.forwardRef(({ className, items, ...props }, ref) => {
149
+ const t = useUiT();
150
+ return /* @__PURE__ */ jsx5("nav", { "aria-label": t("breadcrumb.label"), ref, ...props, children: /* @__PURE__ */ jsx5("ol", { className: cn("flex items-center gap-1 text-sm", className), children: items.map((item, index) => {
151
+ const isLast = index === items.length - 1;
152
+ return /* @__PURE__ */ jsxs4("li", { className: "flex items-center gap-1", children: [
153
+ index > 0 && /* @__PURE__ */ jsx5("span", { "aria-hidden": true, className: "text-muted", children: "\u203A" }),
154
+ item.loading ? /* @__PURE__ */ jsx5(Skeleton, { className: "h-4 w-20" }) : item.onClick && !isLast ? /* @__PURE__ */ jsx5(
155
+ "button",
156
+ {
157
+ className: cn("text-muted hover:text-foreground rounded-sm transition-colors", focusRing),
158
+ onClick: item.onClick,
159
+ type: "button",
160
+ children: item.label
161
+ }
162
+ ) : /* @__PURE__ */ jsx5(
163
+ "span",
164
+ {
165
+ "aria-current": isLast ? "page" : void 0,
166
+ className: isLast ? "text-foreground font-semibold" : "text-muted font-normal",
167
+ children: item.label
168
+ }
169
+ )
170
+ ] }, `${item.label}-${index}`);
171
+ }) }) });
172
+ });
173
+ Breadcrumb.displayName = "Breadcrumb";
174
+
175
+ // src/components/button.tsx
176
+ import { Slot } from "@radix-ui/react-slot";
177
+ import { cva } from "class-variance-authority";
178
+ import * as React5 from "react";
179
+
281
180
  // src/components/spinner.tsx
181
+ import clsx from "clsx";
282
182
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
283
183
  var sizes = {
284
184
  lg: "70",
@@ -298,13 +198,15 @@ var Spinner = ({ className = "", loadingLabel, size = "md", variant = "primary"
298
198
  /* @__PURE__ */ jsx6(
299
199
  "svg",
300
200
  {
201
+ "aria-hidden": true,
301
202
  fill: "currentColor",
203
+ focusable: "false",
302
204
  height: sizes[size],
303
205
  stroke: variants[variant],
304
206
  viewBox: "0 0 100 100",
305
207
  width: sizes[size],
306
208
  xmlns: "http://www.w3.org/2000/svg",
307
- children: /* @__PURE__ */ jsxs5("g", { className: clsx2("spinner_V8m1", className), children: [
209
+ children: /* @__PURE__ */ jsxs5("g", { className: clsx(className), children: [
308
210
  /* @__PURE__ */ jsx6("circle", { cx: "50", cy: "50", fill: "none", opacity: "0.25", r: "35", stroke: "currentColor", strokeWidth: "10" }),
309
211
  /* @__PURE__ */ jsx6(
310
212
  "circle",
@@ -332,7 +234,7 @@ var Spinner = ({ className = "", loadingLabel, size = "md", variant = "primary"
332
234
  ] })
333
235
  }
334
236
  ),
335
- /* @__PURE__ */ jsx6("span", { className: "sr-only", children: loadingLabel ?? t("spinner.loading") })
237
+ /* @__PURE__ */ jsx6("span", { className: "sr-only", role: "status", children: loadingLabel ?? t("spinner.loading") })
336
238
  ] });
337
239
  };
338
240
 
@@ -357,10 +259,10 @@ var TooltipContent = React4.forwardRef(({ className, sideOffset = 4, ...props },
357
259
  ) }));
358
260
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
359
261
  var Tooltip = React4.forwardRef(
360
- ({ children, childrenClassName, className, message, sideTooltip = "top" }, ref) => {
262
+ ({ asChild = false, children, childrenClassName, className, message, sideTooltip = "top" }, ref) => {
361
263
  return /* @__PURE__ */ jsx7(TooltipProvider, { children: /* @__PURE__ */ jsxs6(TooltipRoot, { children: [
362
- /* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx7("div", { className: cn("", childrenClassName), ref, children }) }),
363
- /* @__PURE__ */ jsx7(TooltipContent, { className: cn("", className), side: sideTooltip, children: /* @__PURE__ */ jsx7("p", { children: message }) })
264
+ /* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: asChild ? children : /* @__PURE__ */ jsx7("div", { className: childrenClassName, ref, children }) }),
265
+ /* @__PURE__ */ jsx7(TooltipContent, { className, side: sideTooltip, children: /* @__PURE__ */ jsx7("p", { children: message }) })
364
266
  ] }) });
365
267
  }
366
268
  );
@@ -369,7 +271,10 @@ Tooltip.displayName = "Tooltip";
369
271
  // src/components/button.tsx
370
272
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
371
273
  var buttonVariants = cva(
372
- "w-full inline-flex items-center justify-center gap-[10px] whitespace-nowrap rounded-[10px] border border-transparent text-base font-semibold transition-all duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:bg-inactive disabled:text-inactive-text disabled:border-transparent cursor-pointer",
274
+ [
275
+ "w-full inline-flex items-center justify-center gap-[10px] whitespace-nowrap rounded-[10px] border border-transparent text-base font-semibold transition-all duration-300 ease-in-out focus-visible:ring-offset-2 disabled:pointer-events-none disabled:bg-inactive disabled:text-inactive-text disabled:border-transparent cursor-pointer",
276
+ focusRing
277
+ ],
373
278
  {
374
279
  defaultVariants: {
375
280
  hoverStyle: "none",
@@ -387,15 +292,17 @@ var buttonVariants = cva(
387
292
  hover:-translate-y-[1px] hover:shadow-lg
388
293
  before:content-[''] before:absolute before:top-0 before:left-[-100%]
389
294
  before:w-full before:h-full
390
- before:bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.15),transparent)]
295
+ before:bg-linear-to-r before:from-transparent before:via-inverse/15 before:to-transparent
391
296
  before:transition-all before:duration-300
392
297
  hover:before:left-[100%]
393
298
  `
394
299
  },
395
300
  size: {
301
+ compact: "h-9 rounded-lg px-3 text-sm font-medium",
396
302
  default: "h-10 px-4",
397
303
  icon: "h-12 w-12 p-0",
398
304
  lg: "h-14 px-12",
305
+ md: "h-10 rounded-[10px] px-5 text-sm font-medium",
399
306
  sm: "h-9 px-3 text-sm",
400
307
  xs: "h-9 px-3 rounded-[5px] text-xs font-normal"
401
308
  },
@@ -445,7 +352,7 @@ var Button = React5.forwardRef(
445
352
  icon,
446
353
  /* @__PURE__ */ jsx8("span", { className: cn("flex w-full items-center justify-center gap-2", childrenClassName), children }),
447
354
  iconRight,
448
- isLoading && /* @__PURE__ */ jsx8("div", { className: "absolute inset-0 flex items-center justify-center bg-black/10 backdrop-blur-sm", children: /* @__PURE__ */ jsx8(Spinner, { size: "sm" }) })
355
+ isLoading && /* @__PURE__ */ jsx8("div", { className: "bg-foreground/10 absolute inset-0 flex items-center justify-center backdrop-blur-sm", children: /* @__PURE__ */ jsx8(Spinner, { size: "sm" }) })
449
356
  ]
450
357
  }
451
358
  );
@@ -459,7 +366,10 @@ import { cva as cva2 } from "class-variance-authority";
459
366
  import * as React6 from "react";
460
367
  import { jsx as jsx9 } from "react/jsx-runtime";
461
368
  var chipVariants = cva2(
462
- "focus-visible:ring-ring inline-flex cursor-pointer items-center justify-center rounded-full px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-2 focus-visible:outline-none",
369
+ [
370
+ "inline-flex cursor-pointer items-center justify-center rounded-full px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-colors",
371
+ focusRing
372
+ ],
463
373
  {
464
374
  defaultVariants: {
465
375
  active: false
@@ -472,7 +382,16 @@ var chipVariants = cva2(
472
382
  }
473
383
  }
474
384
  );
475
- var Chip = React6.forwardRef(({ active, className, ...props }, ref) => /* @__PURE__ */ jsx9("button", { className: cn(chipVariants({ active }), className), ref, type: "button", ...props }));
385
+ var Chip = React6.forwardRef(({ active, className, ...props }, ref) => /* @__PURE__ */ jsx9(
386
+ "button",
387
+ {
388
+ "aria-pressed": active ?? void 0,
389
+ className: cn(chipVariants({ active }), className),
390
+ ref,
391
+ type: "button",
392
+ ...props
393
+ }
394
+ ));
476
395
  Chip.displayName = "Chip";
477
396
 
478
397
  // src/components/command.tsx
@@ -511,7 +430,7 @@ var DialogContent = React7.forwardRef(
511
430
  DialogPrimitive.Content,
512
431
  {
513
432
  className: cn(
514
- `bg-surface data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] ${zDialogContent} grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-2xl p-6 shadow-lg duration-200 outline-none`,
433
+ `bg-surface data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 ${zDialogContent} grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-2xl p-6 shadow-lg duration-200 outline-none`,
515
434
  isAbsolute ? "absolute top-[50%] left-[50%]" : "fixed top-[50%] left-[50%]",
516
435
  className
517
436
  ),
@@ -519,10 +438,19 @@ var DialogContent = React7.forwardRef(
519
438
  ...props,
520
439
  children: [
521
440
  children,
522
- isCloseIcon && /* @__PURE__ */ jsxs8(DialogPrimitive.Close, { className: "data-[state=open]:text-muted ring-offset-surface focus:ring-ring data-[state=open]:bg-hover hover:bg-hover absolute top-5 right-5 flex h-8 w-8 min-w-8 cursor-pointer items-center justify-center rounded-full bg-transparent opacity-70 transition-all hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none", children: [
523
- /* @__PURE__ */ jsx10(XIcon, { className: "text-body h-4 w-4" }),
524
- /* @__PURE__ */ jsx10("span", { className: "sr-only", children: closeLabel ?? t("dialog.close") })
525
- ] })
441
+ isCloseIcon && /* @__PURE__ */ jsxs8(
442
+ DialogPrimitive.Close,
443
+ {
444
+ className: cn(
445
+ "data-[state=open]:text-muted ring-offset-surface data-[state=open]:bg-hover hover:bg-hover absolute top-5 right-5 flex h-8 w-8 min-w-8 cursor-pointer items-center justify-center rounded-full bg-transparent opacity-70 transition-all hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-offset-2 disabled:pointer-events-none",
446
+ focusRing
447
+ ),
448
+ children: [
449
+ /* @__PURE__ */ jsx10(XIcon, { "aria-hidden": true, className: "text-body h-4 w-4" }),
450
+ /* @__PURE__ */ jsx10("span", { className: "sr-only", children: closeLabel ?? t("dialog.close") })
451
+ ]
452
+ }
453
+ )
526
454
  ]
527
455
  }
528
456
  )
@@ -539,12 +467,11 @@ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
539
467
  {
540
468
  className: cn("text-lg leading-none font-semibold tracking-tight", className),
541
469
  ref,
542
- ...props,
543
- children: /* @__PURE__ */ jsx10("span", { children: props.children })
470
+ ...props
544
471
  }
545
472
  ));
546
473
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
547
- var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(DialogPrimitive.Description, { className: cn("text-muted text-sm", className), ref, ...props, children: /* @__PURE__ */ jsx10("span", { children: props.children }) }));
474
+ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(DialogPrimitive.Description, { className: cn("text-muted text-sm", className), ref, ...props }));
548
475
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
549
476
 
550
477
  // src/components/command.tsx
@@ -561,8 +488,8 @@ Command.displayName = CommandPrimitive.displayName;
561
488
  var CommandDialog = ({ children, ...props }) => {
562
489
  return /* @__PURE__ */ jsx11(Dialog, { ...props, children: /* @__PURE__ */ jsx11(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx11(Command, { className: "**:[[cmdk-group-heading]]:text-muted [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5 **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group]]:px-2 **:[[cmdk-input]]:h-12 **:[[cmdk-item]]:px-2 **:[[cmdk-item]]:py-3", children }) }) });
563
490
  };
564
- var CommandInput = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs9("div", { className: "flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
565
- /* @__PURE__ */ jsx11(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
491
+ var CommandInput = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs9("div", { className: "border-border flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
492
+ /* @__PURE__ */ jsx11(MagnifyingGlassIcon, { "aria-hidden": true, className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
566
493
  /* @__PURE__ */ jsx11(
567
494
  CommandPrimitive.Input,
568
495
  {
@@ -611,93 +538,29 @@ var CommandShortcut = ({ className, ...props }) => {
611
538
  };
612
539
  CommandShortcut.displayName = "CommandShortcut";
613
540
 
614
- // src/components/form.tsx
615
- import { Slot as Slot2 } from "@radix-ui/react-slot";
616
- import * as React9 from "react";
617
- import { Controller, FormProvider, useFormContext } from "react-hook-form";
618
- import { jsx as jsx12 } from "react/jsx-runtime";
619
- var Form = FormProvider;
620
- var FormFieldContext = React9.createContext(null);
621
- var FormField = ({
622
- ...props
623
- }) => {
624
- return /* @__PURE__ */ jsx12(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx12(Controller, { ...props }) });
625
- };
626
- var useFormField = () => {
627
- const fieldContext = React9.useContext(FormFieldContext);
628
- const itemContext = React9.useContext(FormItemContext);
629
- const { formState, getFieldState } = useFormContext();
630
- if (!fieldContext) {
631
- throw new Error("useFormField must be used within <FormField>");
632
- }
633
- if (!itemContext) {
634
- throw new Error("useFormField must be used within <FormItem>");
635
- }
636
- const fieldState = getFieldState(fieldContext.name, formState);
637
- const { id } = itemContext;
638
- return {
639
- formDescriptionId: `${id}-form-item-description`,
640
- formItemId: `${id}-form-item`,
641
- formMessageId: `${id}-form-item-message`,
642
- id,
643
- name: fieldContext.name,
644
- ...fieldState
645
- };
646
- };
647
- var FormItemContext = React9.createContext(null);
648
- var FormItem = React9.forwardRef(
649
- ({ className, ...props }, ref) => {
650
- const id = React9.useId();
651
- return /* @__PURE__ */ jsx12(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx12("div", { className: cn("space-y-1", className), ref, ...props }) });
652
- }
653
- );
654
- FormItem.displayName = "FormItem";
655
- var FormControl = React9.forwardRef(
656
- ({ ...props }, ref) => {
657
- const { error, formDescriptionId, formItemId, formMessageId } = useFormField();
658
- return /* @__PURE__ */ jsx12(
659
- Slot2,
660
- {
661
- "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
662
- "aria-invalid": !!error,
663
- id: formItemId,
664
- ref,
665
- ...props
666
- }
667
- );
668
- }
669
- );
670
- FormControl.displayName = "FormControl";
671
- var FormMessage = React9.forwardRef(
672
- ({ children, className, ...props }, ref) => {
673
- const { error, formMessageId } = useFormField();
674
- const body = error?.message ? String(error.message) : children;
675
- if (!body) {
676
- return null;
677
- }
678
- return /* @__PURE__ */ jsx12(
679
- "p",
680
- {
681
- className: cn("text-destructive text-[0.8rem] font-medium", className),
682
- id: formMessageId,
683
- ref,
684
- ...props,
685
- children: body
686
- }
687
- );
688
- }
689
- );
690
- FormMessage.displayName = "FormMessage";
691
-
692
541
  // src/components/form-fields/input-field.tsx
693
542
  import { EyeIcon, EyeSlashIcon, XIcon as XIcon2 } from "@phosphor-icons/react";
694
543
  import { useState } from "react";
695
544
 
696
545
  // src/components/input.tsx
697
- import * as React10 from "react";
698
- import { jsx as jsx13 } from "react/jsx-runtime";
699
- var Input = React10.forwardRef(({ className, onKeyDown, type, ...props }, ref) => {
700
- return /* @__PURE__ */ jsx13(
546
+ import * as React9 from "react";
547
+ import { jsx as jsx12 } from "react/jsx-runtime";
548
+ var NUMBER_ALLOWED_KEYS = /* @__PURE__ */ new Set([
549
+ "ArrowDown",
550
+ "ArrowLeft",
551
+ "ArrowRight",
552
+ "ArrowUp",
553
+ "Backspace",
554
+ "Delete",
555
+ "End",
556
+ "Enter",
557
+ "Escape",
558
+ "Home",
559
+ "Tab"
560
+ ]);
561
+ var isAllowedNumberKey = (event) => event.ctrlKey || event.metaKey || event.altKey || NUMBER_ALLOWED_KEYS.has(event.key) || /^[0-9]$/.test(event.key);
562
+ var Input = React9.forwardRef(({ className, onKeyDown, type, ...props }, ref) => {
563
+ return /* @__PURE__ */ jsx12(
701
564
  "input",
702
565
  {
703
566
  className: cn(
@@ -708,15 +571,8 @@ var Input = React10.forwardRef(({ className, onKeyDown, type, ...props }, ref) =
708
571
  ),
709
572
  onKeyDown: (e) => {
710
573
  onKeyDown?.(e);
711
- if (e.defaultPrevented) return;
712
- const key = e.key;
713
- const allowedKeys = ["Backspace", "Tab", "Enter", "Escape", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"];
714
- if (allowedKeys.includes(key)) {
715
- return;
716
- }
717
- if (!(key >= "0" && key <= "9") && type === "number") {
718
- e.preventDefault();
719
- }
574
+ if (e.defaultPrevented || type !== "number") return;
575
+ if (!isAllowedNumberKey(e)) e.preventDefault();
720
576
  },
721
577
  ref,
722
578
  type,
@@ -726,69 +582,24 @@ var Input = React10.forwardRef(({ className, onKeyDown, type, ...props }, ref) =
726
582
  });
727
583
  Input.displayName = "Input";
728
584
 
729
- // src/components/label.tsx
730
- import * as LabelPrimitive from "@radix-ui/react-label";
731
- import { cva as cva3 } from "class-variance-authority";
732
- import * as React11 from "react";
733
- import { jsx as jsx14 } from "react/jsx-runtime";
734
- var labelVariants = cva3("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
735
- var Label = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(LabelPrimitive.Root, { className: cn(labelVariants(), className), ref, ...props }));
736
- Label.displayName = LabelPrimitive.Root.displayName;
737
-
738
- // src/components/form-fields/label-field.tsx
739
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
740
- var LabelField = ({ label, labelClassName, name, visualRequired }) => {
741
- return /* @__PURE__ */ jsxs10(
742
- Label,
743
- {
744
- className: cn("text-body mb-2 text-start text-sm leading-none font-normal tracking-normal", labelClassName),
745
- htmlFor: name,
746
- children: [
747
- /* @__PURE__ */ jsx15("span", { children: label }),
748
- " ",
749
- visualRequired && /* @__PURE__ */ jsx15("span", { className: "text-destructive", children: " *" })
750
- ]
751
- }
752
- );
753
- };
754
-
755
- // src/components/form-fields/form-field-shell.tsx
756
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
757
- var FormFieldShell = ({
758
- children,
759
- hasError,
760
- label,
761
- labelClassName,
762
- mainClassName,
763
- name,
764
- visualRequired
765
- }) => /* @__PURE__ */ jsxs11(FormItem, { className: cn("flex flex-col", mainClassName), children: [
766
- /* @__PURE__ */ jsx16(
767
- LabelField,
768
- {
769
- label,
770
- labelClassName: cn(labelClassName, hasError && "text-destructive"),
771
- name,
772
- visualRequired
773
- }
774
- ),
775
- /* @__PURE__ */ jsx16(FormControl, { children }),
776
- /* @__PURE__ */ jsx16(FormMessage, {})
777
- ] });
778
-
779
585
  // src/components/form-fields/input-field.tsx
780
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
586
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
587
+ var iconButtonClassName = cn("flex items-center justify-center rounded-sm", focusRing);
781
588
  var InputField = ({
589
+ autoComplete,
782
590
  clearLabel,
783
591
  control,
784
592
  disabled,
785
593
  hidePasswordLabel,
786
594
  inputClassName,
595
+ inputMode,
787
596
  isClearable,
788
597
  label,
789
598
  labelClassName,
790
599
  mainClassName,
600
+ maxLength,
791
601
  name,
602
+ onBlur,
792
603
  onClear,
793
604
  placeholder,
794
605
  showPasswordLabel,
@@ -802,14 +613,16 @@ var InputField = ({
802
613
  };
803
614
  const isPassword = type === "password";
804
615
  const inputType = isPassword ? isPasswordVisible ? "text" : "password" : type;
805
- return /* @__PURE__ */ jsx17(
616
+ const resolvedClearLabel = clearLabel ?? t("inputField.clear");
617
+ const passwordToggleLabel = isPasswordVisible ? hidePasswordLabel ?? t("inputField.hidePassword") : showPasswordLabel ?? t("inputField.showPassword");
618
+ return /* @__PURE__ */ jsx13(
806
619
  FormField,
807
620
  {
808
621
  control,
809
622
  name,
810
623
  render: ({ field, fieldState }) => {
811
624
  const hasError = !!fieldState.error;
812
- return /* @__PURE__ */ jsx17(
625
+ return /* @__PURE__ */ jsx13(
813
626
  FormFieldShell,
814
627
  {
815
628
  hasError,
@@ -818,12 +631,13 @@ var InputField = ({
818
631
  mainClassName,
819
632
  name,
820
633
  visualRequired,
821
- children: /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
822
- /* @__PURE__ */ jsx17(
634
+ children: (controlProps) => /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
635
+ /* @__PURE__ */ jsx13(
823
636
  Input,
824
637
  {
825
638
  ...field,
826
- autoComplete: isPassword ? "current-password" : void 0,
639
+ ...controlProps,
640
+ autoComplete: autoComplete ?? (isPassword ? "current-password" : void 0),
827
641
  className: cn(
828
642
  inputClassName,
829
643
  hasError && "border-destructive",
@@ -833,31 +647,39 @@ var InputField = ({
833
647
  "data-bwignore": isPassword || void 0,
834
648
  "data-lpignore": isPassword || void 0,
835
649
  disabled,
650
+ inputMode,
651
+ maxLength,
836
652
  min: type === "number" ? 0 : void 0,
653
+ onBlur: (event) => {
654
+ field.onBlur();
655
+ onBlur?.(event);
656
+ },
837
657
  placeholder,
838
658
  type: inputType,
839
659
  value: field.value ?? ""
840
660
  }
841
661
  ),
842
- /* @__PURE__ */ jsxs12("div", { className: "absolute inset-y-0 right-0 flex items-center space-x-2 pr-2", children: [
843
- field.value && isClearable && /* @__PURE__ */ jsx17(
662
+ /* @__PURE__ */ jsxs10("div", { className: "absolute inset-y-0 right-0 flex items-center space-x-2 pr-2", children: [
663
+ field.value && isClearable && /* @__PURE__ */ jsx13(
844
664
  "button",
845
665
  {
846
- className: "focus:outline-none",
666
+ "aria-label": resolvedClearLabel,
667
+ className: iconButtonClassName,
847
668
  onClick: onClear,
848
- title: clearLabel ?? t("inputField.clear"),
669
+ title: resolvedClearLabel,
849
670
  type: "button",
850
- children: /* @__PURE__ */ jsx17(XIcon2, { size: 18 })
671
+ children: /* @__PURE__ */ jsx13(XIcon2, { "aria-hidden": true, size: 18 })
851
672
  }
852
673
  ),
853
- type === "password" && /* @__PURE__ */ jsx17(
674
+ isPassword && /* @__PURE__ */ jsx13(
854
675
  "button",
855
676
  {
856
- className: "focus:outline-none",
677
+ "aria-label": passwordToggleLabel,
678
+ className: iconButtonClassName,
857
679
  onClick: togglePasswordVisibility,
858
- title: isPasswordVisible ? hidePasswordLabel ?? t("inputField.hidePassword") : showPasswordLabel ?? t("inputField.showPassword"),
680
+ title: passwordToggleLabel,
859
681
  type: "button",
860
- children: isPasswordVisible ? /* @__PURE__ */ jsx17(EyeIcon, { size: 18 }) : /* @__PURE__ */ jsx17(EyeSlashIcon, { size: 20 })
682
+ children: isPasswordVisible ? /* @__PURE__ */ jsx13(EyeIcon, { "aria-hidden": true, size: 18 }) : /* @__PURE__ */ jsx13(EyeSlashIcon, { "aria-hidden": true, size: 20 })
861
683
  }
862
684
  )
863
685
  ] })
@@ -869,340 +691,16 @@ var InputField = ({
869
691
  );
870
692
  };
871
693
 
872
- // src/components/google-map-picker.tsx
873
- import { AdvancedMarker, APIProvider, Map as Map2 } from "@vis.gl/react-google-maps";
874
-
875
- // src/components/use-google-map-picker.ts
876
- import { useMap, useMapsLibrary } from "@vis.gl/react-google-maps";
877
- import { useCallback, useEffect, useMemo, useRef, useState as useState2 } from "react";
878
- var PICKER_MAP_ID = "komensal-restaurant-map";
879
- var SELECTED_ZOOM = 15;
880
- var CITY_ZOOM = 12;
881
- var DEBOUNCE_MS = 300;
882
- var BLUR_CLOSE_DELAY_MS = 150;
883
- var parseComponents = (components) => {
884
- const find = (type) => components.find((c) => c.types.includes(type));
885
- const country = find("country");
886
- const department = find("administrative_area_level_1");
887
- const city = find("locality") ?? find("administrative_area_level_2");
888
- return {
889
- city: city?.long ?? null,
890
- country: country?.short ?? null,
891
- countryName: country?.long ?? null,
892
- department: department?.long ?? null
893
- };
894
- };
895
- function useGoogleMapPicker({
896
- centerOn,
897
- countryCode,
898
- disabled,
899
- initialPosition,
900
- locationQuery,
901
- locationZoom,
902
- onAddressResolved,
903
- onChange,
904
- onError,
905
- value
906
- }) {
907
- const placesLib = useMapsLibrary("places");
908
- const geocodingLib = useMapsLibrary("geocoding");
909
- const map = useMap(PICKER_MAP_ID);
910
- const onChangeRef = useRef(onChange);
911
- const onResolvedRef = useRef(onAddressResolved);
912
- const onErrorRef = useRef(onError);
913
- const geocoder = useMemo(
914
- () => geocodingLib ? new geocodingLib.Geocoder() : null,
915
- [geocodingLib]
916
- );
917
- const debounceRef = useRef(null);
918
- const blurTimeoutRef = useRef(null);
919
- const [inputValue, setInputValue] = useState2(value);
920
- const [suggestions, setSuggestions] = useState2([]);
921
- const [showDropdown, setShowDropdown] = useState2(false);
922
- const [sessionToken, setSessionToken] = useState2();
923
- const [position, setPosition] = useState2(initialPosition ?? null);
924
- useEffect(() => {
925
- onChangeRef.current = onChange;
926
- onResolvedRef.current = onAddressResolved;
927
- onErrorRef.current = onError;
928
- });
929
- useEffect(
930
- () => () => {
931
- if (debounceRef.current) clearTimeout(debounceRef.current);
932
- if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
933
- },
934
- []
935
- );
936
- const [prevValue, setPrevValue] = useState2(value);
937
- if (prevValue !== value) {
938
- setPrevValue(value);
939
- setInputValue(value);
940
- }
941
- useEffect(() => {
942
- if (map && centerOn) {
943
- map.panTo(centerOn);
944
- map.setZoom(CITY_ZOOM);
945
- }
946
- }, [map, centerOn]);
947
- useEffect(() => {
948
- if (map && position) {
949
- map.panTo(position);
950
- map.setZoom(SELECTED_ZOOM);
951
- }
952
- }, [map, position]);
953
- const [prevPlacesLib, setPrevPlacesLib] = useState2(placesLib);
954
- if (prevPlacesLib !== placesLib) {
955
- setPrevPlacesLib(placesLib);
956
- if (placesLib) setSessionToken(new placesLib.AutocompleteSessionToken());
957
- }
958
- useEffect(() => {
959
- if (!geocoder || !locationQuery || !map || position) return;
960
- const g = geocoder;
961
- const ctrl = { cancelled: false };
962
- void (async () => {
963
- try {
964
- const { results } = await g.geocode({ address: locationQuery });
965
- if (ctrl.cancelled || results.length === 0) return;
966
- const loc = results[0].geometry.location;
967
- map.panTo({ lat: loc.lat(), lng: loc.lng() });
968
- map.setZoom(locationZoom ?? CITY_ZOOM);
969
- } catch (error) {
970
- if (!ctrl.cancelled) {
971
- console.error("[GoogleMapPicker] geocode by query failed", error);
972
- onErrorRef.current?.(error);
973
- }
974
- }
975
- })();
976
- return () => {
977
- ctrl.cancelled = true;
978
- };
979
- }, [geocoder, locationQuery, locationZoom, map, position]);
980
- const fetchSuggestions = useCallback(
981
- async (input) => {
982
- if (!placesLib || input.length < 2) {
983
- setSuggestions([]);
984
- return;
985
- }
986
- try {
987
- const result = await placesLib.AutocompleteSuggestion.fetchAutocompleteSuggestions({
988
- includedRegionCodes: countryCode ? [countryCode.trim().toLowerCase()] : void 0,
989
- input,
990
- sessionToken
991
- });
992
- setSuggestions(result.suggestions);
993
- setShowDropdown(true);
994
- } catch (error) {
995
- console.error("[GoogleMapPicker] fetchAutocompleteSuggestions failed", error);
996
- onErrorRef.current?.(error);
997
- setSuggestions([]);
998
- }
999
- },
1000
- [placesLib, sessionToken, countryCode]
1001
- );
1002
- const reverseGeocode = useCallback(
1003
- async (latLng) => {
1004
- if (!geocoder) return;
1005
- try {
1006
- const { results } = await geocoder.geocode({ location: latLng });
1007
- if (results.length > 0) {
1008
- const result = results[0];
1009
- const address = result.formatted_address;
1010
- setInputValue(address);
1011
- onChangeRef.current(address);
1012
- const parts = parseComponents(
1013
- result.address_components.map((c) => ({ long: c.long_name, short: c.short_name, types: c.types }))
1014
- );
1015
- onResolvedRef.current?.({ address, lat: latLng.lat, lng: latLng.lng, ...parts });
1016
- }
1017
- } catch (error) {
1018
- console.error("[GoogleMapPicker] reverse geocode failed", error);
1019
- onErrorRef.current?.(error);
1020
- }
1021
- },
1022
- [geocoder]
1023
- );
1024
- const handleInputChange = (e) => {
1025
- const val = e.target.value;
1026
- setInputValue(val);
1027
- onChangeRef.current(val);
1028
- if (debounceRef.current) clearTimeout(debounceRef.current);
1029
- debounceRef.current = setTimeout(() => void fetchSuggestions(val), DEBOUNCE_MS);
1030
- };
1031
- const handleSelect = async (suggestion) => {
1032
- const prediction = suggestion.placePrediction;
1033
- if (!prediction) return;
1034
- const place = prediction.toPlace();
1035
- await place.fetchFields({ fields: ["formattedAddress", "location", "addressComponents"] });
1036
- const address = place.formattedAddress ?? prediction.text.text;
1037
- setInputValue(address);
1038
- onChangeRef.current(address);
1039
- setSuggestions([]);
1040
- setShowDropdown(false);
1041
- const lat = place.location?.lat() ?? null;
1042
- const lng = place.location?.lng() ?? null;
1043
- if (place.location) {
1044
- setPosition({ lat: place.location.lat(), lng: place.location.lng() });
1045
- }
1046
- const parts = parseComponents(
1047
- (place.addressComponents ?? []).map((c) => ({ long: c.longText, short: c.shortText, types: c.types }))
1048
- );
1049
- onResolvedRef.current?.({ address, lat, lng, ...parts });
1050
- if (placesLib) setSessionToken(new placesLib.AutocompleteSessionToken());
1051
- };
1052
- const handleBlur = () => {
1053
- if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
1054
- blurTimeoutRef.current = setTimeout(() => setShowDropdown(false), BLUR_CLOSE_DELAY_MS);
1055
- };
1056
- const handleMapClick = useCallback(
1057
- (e) => {
1058
- if (disabled || !e.detail.latLng) return;
1059
- const latLng = e.detail.latLng;
1060
- setPosition(latLng);
1061
- void reverseGeocode(latLng);
1062
- },
1063
- [disabled, reverseGeocode]
1064
- );
1065
- const handleMarkerDragEnd = useCallback(
1066
- (e) => {
1067
- const latLng = e.latLng;
1068
- if (!latLng) return;
1069
- const pos = { lat: latLng.lat(), lng: latLng.lng() };
1070
- setPosition(pos);
1071
- void reverseGeocode(pos);
1072
- },
1073
- [reverseGeocode]
1074
- );
1075
- return {
1076
- handleBlur,
1077
- handleInputChange,
1078
- handleMapClick,
1079
- handleMarkerDragEnd,
1080
- handleSelect,
1081
- inputValue,
1082
- position,
1083
- setShowDropdown,
1084
- showDropdown,
1085
- suggestions
1086
- };
1087
- }
1088
-
1089
- // src/components/google-map-picker.tsx
1090
- import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
1091
- var DEFAULT_CENTER = { lat: 4.711, lng: -74.0721 };
1092
- var MapPickerContent = (props) => {
1093
- const { disabled, hasError, mapId, placeholder } = props;
1094
- const {
1095
- handleBlur,
1096
- handleInputChange,
1097
- handleMapClick,
1098
- handleMarkerDragEnd,
1099
- handleSelect,
1100
- inputValue,
1101
- position,
1102
- setShowDropdown,
1103
- showDropdown,
1104
- suggestions
1105
- } = useGoogleMapPicker(props);
1106
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3", children: [
1107
- /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
1108
- /* @__PURE__ */ jsx18(
1109
- "input",
1110
- {
1111
- className: cn(inputBase, inputFocus, hasError && "border-destructive"),
1112
- disabled,
1113
- onBlur: handleBlur,
1114
- onChange: handleInputChange,
1115
- onFocus: () => suggestions.length > 0 && setShowDropdown(true),
1116
- placeholder,
1117
- type: "text",
1118
- value: inputValue
1119
- }
1120
- ),
1121
- showDropdown && suggestions.length > 0 && /* @__PURE__ */ jsx18(
1122
- "ul",
1123
- {
1124
- className: cn(
1125
- "border-border bg-surface absolute mt-1 w-full overflow-hidden rounded-[10px] border shadow-md",
1126
- zPopover
1127
- ),
1128
- children: suggestions.map((suggestion) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
1129
- "button",
1130
- {
1131
- className: "text-foreground hover:bg-hover w-full px-4 py-3 text-left text-sm transition-colors",
1132
- onClick: () => void handleSelect(suggestion),
1133
- type: "button",
1134
- children: suggestion.placePrediction?.text.text ?? ""
1135
- }
1136
- ) }, suggestion.placePrediction?.placeId ?? suggestion.placePrediction?.text.text))
1137
- }
1138
- )
1139
- ] }),
1140
- /* @__PURE__ */ jsx18("div", { className: "border-border h-59 overflow-hidden rounded-[10px] border md:h-87.5", children: /* @__PURE__ */ jsx18(
1141
- Map2,
1142
- {
1143
- defaultCenter: DEFAULT_CENTER,
1144
- defaultZoom: 5,
1145
- disableDefaultUI: true,
1146
- gestureHandling: "cooperative",
1147
- id: PICKER_MAP_ID,
1148
- mapId: mapId ?? import.meta.env.VITE_GOOGLE_MAPS_MAP_ID ?? "DEMO_MAP_ID",
1149
- onClick: handleMapClick,
1150
- style: { height: "100%", width: "100%" },
1151
- children: position && /* @__PURE__ */ jsx18(AdvancedMarker, { draggable: !disabled, onDragEnd: handleMarkerDragEnd, position })
1152
- }
1153
- ) })
1154
- ] });
1155
- };
1156
- var GoogleMapPicker = (props) => /* @__PURE__ */ jsx18(APIProvider, { apiKey: props.apiKey ?? import.meta.env.VITE_GOOGLE_MAPS_API_KEY ?? "", language: "es", region: "CO", children: /* @__PURE__ */ jsx18(MapPickerContent, { ...props }) });
1157
-
1158
- // src/components/form-fields/map-picker-field.tsx
1159
- import { jsx as jsx19 } from "react/jsx-runtime";
1160
- var MapPickerField = ({
1161
- control,
1162
- label,
1163
- labelClassName,
1164
- mainClassName,
1165
- name,
1166
- visualRequired,
1167
- ...pickerProps
1168
- }) => /* @__PURE__ */ jsx19(
1169
- FormField,
1170
- {
1171
- control,
1172
- name,
1173
- render: ({ field, fieldState }) => /* @__PURE__ */ jsx19(
1174
- FormFieldShell,
1175
- {
1176
- hasError: !!fieldState.error,
1177
- label,
1178
- labelClassName,
1179
- mainClassName,
1180
- name,
1181
- visualRequired,
1182
- children: /* @__PURE__ */ jsx19(
1183
- GoogleMapPicker,
1184
- {
1185
- ...pickerProps,
1186
- hasError: !!fieldState.error,
1187
- onChange: field.onChange,
1188
- value: field.value ?? ""
1189
- }
1190
- )
1191
- }
1192
- )
1193
- }
1194
- );
1195
-
1196
694
  // src/components/otp-input.tsx
1197
695
  import { OTPInput, OTPInputContext } from "input-otp";
1198
- import React12 from "react";
1199
- import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
696
+ import React10 from "react";
697
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1200
698
  function InputOTP({
1201
699
  className,
1202
700
  containerClassName,
1203
701
  ...props
1204
702
  }) {
1205
- return /* @__PURE__ */ jsx20(
703
+ return /* @__PURE__ */ jsx14(
1206
704
  OTPInput,
1207
705
  {
1208
706
  className: cn("disabled:cursor-not-allowed", className),
@@ -1213,16 +711,16 @@ function InputOTP({
1213
711
  );
1214
712
  }
1215
713
  function InputOTPGroup({ className, ...props }) {
1216
- return /* @__PURE__ */ jsx20("div", { className: cn("flex items-center gap-2", className), "data-slot": "input-otp-group", ...props });
714
+ return /* @__PURE__ */ jsx14("div", { className: cn("flex items-center gap-2", className), "data-slot": "input-otp-group", ...props });
1217
715
  }
1218
716
  function InputOTPSlot({
1219
717
  className,
1220
718
  index,
1221
719
  ...props
1222
720
  }) {
1223
- const inputOTPContext = React12.useContext(OTPInputContext);
721
+ const inputOTPContext = React10.useContext(OTPInputContext);
1224
722
  const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {};
1225
- return /* @__PURE__ */ jsxs14(
723
+ return /* @__PURE__ */ jsxs11(
1226
724
  "div",
1227
725
  {
1228
726
  className: cn(
@@ -1237,14 +735,14 @@ function InputOTPSlot({
1237
735
  ...props,
1238
736
  children: [
1239
737
  char,
1240
- hasFakeCaret && /* @__PURE__ */ jsx20("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx20("div", { className: "animate-caret-blink bg-foreground h-6 w-px duration-1000" }) })
738
+ hasFakeCaret && /* @__PURE__ */ jsx14("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx14("div", { className: "animate-caret-blink bg-foreground h-6 w-px duration-1000" }) })
1241
739
  ]
1242
740
  }
1243
741
  );
1244
742
  }
1245
743
 
1246
744
  // src/components/form-fields/otp-field.tsx
1247
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
745
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1248
746
  function OTPField({
1249
747
  autoFocus,
1250
748
  className,
@@ -1257,13 +755,13 @@ function OTPField({
1257
755
  otpLength = 6,
1258
756
  visualRequired
1259
757
  }) {
1260
- return /* @__PURE__ */ jsx21(
758
+ return /* @__PURE__ */ jsx15(
1261
759
  FormField,
1262
760
  {
1263
761
  control,
1264
762
  name,
1265
- render: ({ field, fieldState }) => /* @__PURE__ */ jsxs15(FormItem, { className: cn("flex flex-col", className), children: [
1266
- label ? /* @__PURE__ */ jsx21(
763
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs12(FormItem, { className: cn("flex flex-col", className), children: [
764
+ label ? /* @__PURE__ */ jsx15(
1267
765
  LabelField,
1268
766
  {
1269
767
  label,
@@ -1272,7 +770,7 @@ function OTPField({
1272
770
  visualRequired
1273
771
  }
1274
772
  ) : null,
1275
- /* @__PURE__ */ jsx21(FormControl, { children: /* @__PURE__ */ jsx21(
773
+ /* @__PURE__ */ jsx15(FormControl, { children: /* @__PURE__ */ jsx15(
1276
774
  InputOTP,
1277
775
  {
1278
776
  "aria-invalid": fieldState.invalid || void 0,
@@ -1280,17 +778,16 @@ function OTPField({
1280
778
  autoFocus,
1281
779
  containerClassName: cn("justify-center", containerClassName),
1282
780
  disabled,
1283
- id: name,
1284
781
  inputMode: "numeric",
1285
782
  maxLength: otpLength,
1286
783
  onChange: (val) => field.onChange(val),
1287
784
  onPaste: (e) => field.onChange(e.clipboardData.getData("text")),
1288
785
  pattern: "[0-9]*",
1289
786
  value: field.value ?? "",
1290
- children: /* @__PURE__ */ jsx21(InputOTPGroup, { children: Array.from({ length: otpLength }).map((_, i) => /* @__PURE__ */ jsx21(InputOTPSlot, { "aria-invalid": fieldState.invalid || void 0, index: i }, i)) })
787
+ children: /* @__PURE__ */ jsx15(InputOTPGroup, { children: Array.from({ length: otpLength }).map((_, i) => /* @__PURE__ */ jsx15(InputOTPSlot, { "aria-invalid": fieldState.invalid || void 0, index: i }, i)) })
1291
788
  }
1292
789
  ) }),
1293
- /* @__PURE__ */ jsx21(FormMessage, {})
790
+ /* @__PURE__ */ jsx15(FormMessage, {})
1294
791
  ] })
1295
792
  }
1296
793
  );
@@ -1298,15 +795,15 @@ function OTPField({
1298
795
 
1299
796
  // src/components/select-input.tsx
1300
797
  import { CaretDownIcon, CaretUpIcon, ClockIcon, XIcon as XIcon3 } from "@phosphor-icons/react";
1301
- import { cloneElement, useCallback as useCallback2, useId as useId2, useMemo as useMemo3, useState as useState4 } from "react";
798
+ import { cloneElement, useCallback, useEffect as useEffect3, useId, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
1302
799
 
1303
800
  // src/components/popover.tsx
1304
801
  import * as PopoverPrimitive from "@radix-ui/react-popover";
1305
- import * as React13 from "react";
1306
- import { jsx as jsx22 } from "react/jsx-runtime";
802
+ import * as React11 from "react";
803
+ import { jsx as jsx16 } from "react/jsx-runtime";
1307
804
  var Popover = PopoverPrimitive.Root;
1308
805
  var PopoverTrigger = PopoverPrimitive.Trigger;
1309
- var PopoverContent = React13.forwardRef(({ align = "center", className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx22(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx22(
806
+ var PopoverContent = React11.forwardRef(({ align = "center", className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx16(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx16(
1310
807
  PopoverPrimitive.Content,
1311
808
  {
1312
809
  align,
@@ -1322,67 +819,90 @@ var PopoverContent = React13.forwardRef(({ align = "center", className, sideOffs
1322
819
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
1323
820
 
1324
821
  // src/components/time-columns.tsx
1325
- import * as React14 from "react";
1326
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
822
+ import * as React12 from "react";
823
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
824
+ var optionClassName = cn(
825
+ "hover:bg-hover w-full cursor-pointer rounded-sm px-2 py-1.5 text-sm focus-visible:ring-inset",
826
+ focusRing
827
+ );
1327
828
  var TimeColumns = ({ hours, minutes, onSelectHour, onSelectMinute, value }) => {
829
+ const t = useUiT();
1328
830
  const [selectedHour, selectedMinute] = value ? value.split(":") : ["", ""];
1329
- const hourListRef = React14.useRef(null);
1330
- const minuteListRef = React14.useRef(null);
1331
- React14.useEffect(() => {
831
+ const hourListRef = React12.useRef(null);
832
+ const minuteListRef = React12.useRef(null);
833
+ React12.useEffect(() => {
1332
834
  hourListRef.current?.querySelector('[data-selected="true"]')?.scrollIntoView({ block: "center" });
1333
835
  minuteListRef.current?.querySelector('[data-selected="true"]')?.scrollIntoView({ block: "center" });
1334
836
  }, []);
1335
- return /* @__PURE__ */ jsxs16("div", { className: "divide-border flex divide-x", children: [
1336
- /* @__PURE__ */ jsx23("div", { className: "max-h-60 flex-1 overflow-y-auto", ref: hourListRef, children: hours.map((hour) => {
1337
- const isSelected = hour === selectedHour;
1338
- return /* @__PURE__ */ jsx23(
1339
- "button",
1340
- {
1341
- className: cn(
1342
- "hover:bg-hover flex w-full cursor-pointer items-center justify-center rounded-sm px-2 py-1.5 text-sm",
1343
- isSelected && "bg-inactive font-medium"
1344
- ),
1345
- "data-selected": isSelected,
1346
- onClick: () => onSelectHour(hour),
1347
- type: "button",
1348
- children: formatHour12(hour)
1349
- },
1350
- hour
1351
- );
1352
- }) }),
1353
- /* @__PURE__ */ jsx23("div", { className: "max-h-60 flex-1 overflow-y-auto", ref: minuteListRef, children: minutes.map((minute) => {
1354
- const isSelected = minute === selectedMinute;
1355
- return /* @__PURE__ */ jsx23(
1356
- "button",
1357
- {
1358
- className: cn(
1359
- "hover:bg-hover w-full cursor-pointer rounded-sm px-2 py-1.5 text-center text-sm",
1360
- isSelected && "bg-inactive font-medium"
1361
- ),
1362
- "data-selected": isSelected,
1363
- onClick: () => onSelectMinute(minute),
1364
- type: "button",
1365
- children: minute
1366
- },
1367
- minute
1368
- );
1369
- }) })
837
+ const formatHour12 = (hour) => {
838
+ const hourNum = Number(hour);
839
+ const period = hourNum >= 12 ? t("timeColumns.pm") : t("timeColumns.am");
840
+ const hour12 = hourNum % 12 === 0 ? 12 : hourNum % 12;
841
+ return `${hour12} ${period}`;
842
+ };
843
+ return /* @__PURE__ */ jsxs13("div", { className: "divide-border flex divide-x", children: [
844
+ /* @__PURE__ */ jsx17(
845
+ "div",
846
+ {
847
+ "aria-label": t("timeColumns.hours"),
848
+ className: "max-h-60 flex-1 overflow-y-auto",
849
+ ref: hourListRef,
850
+ role: "group",
851
+ children: hours.map((hour) => {
852
+ const isSelected = hour === selectedHour;
853
+ return /* @__PURE__ */ jsx17(
854
+ "button",
855
+ {
856
+ "aria-pressed": isSelected,
857
+ className: cn(
858
+ optionClassName,
859
+ "flex items-center justify-center",
860
+ isSelected && "bg-inactive font-medium"
861
+ ),
862
+ "data-selected": isSelected,
863
+ onClick: () => onSelectHour(hour),
864
+ type: "button",
865
+ children: formatHour12(hour)
866
+ },
867
+ hour
868
+ );
869
+ })
870
+ }
871
+ ),
872
+ /* @__PURE__ */ jsx17(
873
+ "div",
874
+ {
875
+ "aria-label": t("timeColumns.minutes"),
876
+ className: "max-h-60 flex-1 overflow-y-auto",
877
+ ref: minuteListRef,
878
+ role: "group",
879
+ children: minutes.map((minute) => {
880
+ const isSelected = minute === selectedMinute;
881
+ return /* @__PURE__ */ jsx17(
882
+ "button",
883
+ {
884
+ "aria-pressed": isSelected,
885
+ className: cn(optionClassName, "text-center", isSelected && "bg-inactive font-medium"),
886
+ "data-selected": isSelected,
887
+ onClick: () => onSelectMinute(minute),
888
+ type: "button",
889
+ children: minute
890
+ },
891
+ minute
892
+ );
893
+ })
894
+ }
895
+ )
1370
896
  ] });
1371
897
  };
1372
- function formatHour12(hour) {
1373
- const hourNum = Number(hour);
1374
- const period = hourNum >= 12 ? "PM" : "AM";
1375
- const hour12 = hourNum % 12 === 0 ? 12 : hourNum % 12;
1376
- return `${hour12} ${period}`;
1377
- }
1378
898
 
1379
899
  // src/components/use-select-input.ts
1380
- import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
900
+ import { useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
1381
901
  var normalizeString = (str) => str.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
1382
902
  function usePopoverWidth() {
1383
- const ref = useRef3(null);
1384
- const [width, setWidth] = useState3(0);
1385
- useEffect3(() => {
903
+ const ref = useRef2(null);
904
+ const [width, setWidth] = useState2(0);
905
+ useEffect2(() => {
1386
906
  const el = ref.current;
1387
907
  if (!el) return;
1388
908
  const updateWidth = () => setWidth(el.getBoundingClientRect().width);
@@ -1394,8 +914,8 @@ function usePopoverWidth() {
1394
914
  return { ref, width };
1395
915
  }
1396
916
  function useSelectFilter(items, labelKey, valueKey) {
1397
- const [query, setQuery] = useState3("");
1398
- const normalizedItems = useMemo2(() => {
917
+ const [query, setQuery] = useState2("");
918
+ const normalizedItems = useMemo(() => {
1399
919
  if (!items) return [];
1400
920
  return items.map((it) => ({
1401
921
  ...it,
@@ -1403,7 +923,7 @@ function useSelectFilter(items, labelKey, valueKey) {
1403
923
  [valueKey]: String(it[valueKey])
1404
924
  }));
1405
925
  }, [items, labelKey, valueKey]);
1406
- const filteredOptions = useMemo2(() => {
926
+ const filteredOptions = useMemo(() => {
1407
927
  if (!query) return normalizedItems;
1408
928
  return normalizedItems.filter((el) => normalizeString(el[labelKey]).includes(normalizeString(query)));
1409
929
  }, [normalizedItems, labelKey, query]);
@@ -1411,15 +931,20 @@ function useSelectFilter(items, labelKey, valueKey) {
1411
931
  }
1412
932
 
1413
933
  // src/components/select-input.tsx
1414
- import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
934
+ import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
1415
935
  var QUERY_RESET_DELAY_MS = 100;
1416
936
  var SelectInput = (props) => {
1417
937
  const t = useUiT();
1418
938
  const {
1419
939
  ableDeleteOption,
940
+ "aria-describedby": ariaDescribedBy,
941
+ "aria-invalid": ariaInvalid,
942
+ "aria-label": ariaLabel,
943
+ "aria-labelledby": ariaLabelledBy,
1420
944
  className,
1421
945
  disabled = false,
1422
946
  error,
947
+ id,
1423
948
  items,
1424
949
  labelKey = "label",
1425
950
  leftIcon,
@@ -1438,12 +963,19 @@ var SelectInput = (props) => {
1438
963
  valueKey = "value"
1439
964
  } = props;
1440
965
  const resolvedPlaceholder = placeholder ?? t("selectInput.placeholder");
1441
- const listboxId = useId2();
1442
- const [open, setOpen] = useState4(false);
1443
- const [valueItem, setValueItem] = useState4(value);
966
+ const listboxId = useId();
967
+ const [open, setOpen] = useState3(false);
968
+ const [valueItem, setValueItem] = useState3(value);
969
+ const queryResetRef = useRef3(null);
970
+ useEffect3(
971
+ () => () => {
972
+ if (queryResetRef.current) clearTimeout(queryResetRef.current);
973
+ },
974
+ []
975
+ );
1444
976
  const { ref: divRef, width } = usePopoverWidth();
1445
977
  const { filteredOptions, normalizedItems, query, setQuery } = useSelectFilter(items, labelKey, valueKey);
1446
- const onValueChange = useCallback2(
978
+ const onValueChange = useCallback(
1447
979
  (val) => {
1448
980
  if (!normalizedItems.length) return;
1449
981
  const item = normalizedItems.find((i) => i[valueKey] === val);
@@ -1457,13 +989,13 @@ var SelectInput = (props) => {
1457
989
  },
1458
990
  [normalizedItems, labelKey, valueKey, onValueChangeCallBack]
1459
991
  );
1460
- const timeHours = useMemo3(
992
+ const timeHours = useMemo2(
1461
993
  () => Array.from(new Set(normalizedItems.map((i) => i[valueKey].split(":")[0]))).sort(
1462
994
  (a, b) => a.localeCompare(b)
1463
995
  ),
1464
996
  [normalizedItems, valueKey]
1465
997
  );
1466
- const timeMinutes = useMemo3(
998
+ const timeMinutes = useMemo2(
1467
999
  () => Array.from(new Set(normalizedItems.map((i) => i[valueKey].split(":")[1]))).sort(
1468
1000
  (a, b) => a.localeCompare(b)
1469
1001
  ),
@@ -1482,7 +1014,7 @@ var SelectInput = (props) => {
1482
1014
  onValueChange(newValue);
1483
1015
  setOpen(false);
1484
1016
  };
1485
- const buttonClassName = useMemo3(
1017
+ const buttonClassName = useMemo2(
1486
1018
  () => cn(
1487
1019
  inputBase,
1488
1020
  inputFocus,
@@ -1493,53 +1025,58 @@ var SelectInput = (props) => {
1493
1025
  ),
1494
1026
  [disabled, error, className]
1495
1027
  );
1496
- const [prevValue, setPrevValue] = useState4(value);
1028
+ const [prevValue, setPrevValue] = useState3(value);
1497
1029
  if (prevValue !== value) {
1498
1030
  setPrevValue(value);
1499
1031
  setValueItem(value);
1500
1032
  }
1501
- return /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs17("div", { className: "relative flex flex-col justify-center", children: [
1502
- /* @__PURE__ */ jsxs17(Popover, { onOpenChange: setOpen, open, children: [
1503
- /* @__PURE__ */ jsx24(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx24(
1033
+ return /* @__PURE__ */ jsx18("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs14("div", { className: "relative flex flex-col justify-center", children: [
1034
+ /* @__PURE__ */ jsxs14(Popover, { onOpenChange: setOpen, open, children: [
1035
+ /* @__PURE__ */ jsx18(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx18(
1504
1036
  Button,
1505
1037
  {
1038
+ "aria-busy": loading || void 0,
1506
1039
  "aria-controls": listboxId,
1040
+ "aria-describedby": ariaDescribedBy,
1507
1041
  "aria-expanded": open,
1508
1042
  "aria-haspopup": "listbox",
1043
+ "aria-invalid": ariaInvalid ?? (error ? true : void 0),
1044
+ "aria-label": ariaLabel,
1045
+ "aria-labelledby": ariaLabelledBy,
1509
1046
  className: buttonClassName,
1510
- disabled,
1511
- isLoading: loading,
1047
+ disabled: disabled || loading,
1048
+ id,
1512
1049
  onBlur,
1513
1050
  ref: divRef,
1514
1051
  role: "combobox",
1515
1052
  variant: "primary",
1516
- children: loading ? /* @__PURE__ */ jsxs17(Fragment3, { children: [
1053
+ children: loading ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1517
1054
  loadingLabel ?? t("selectInput.loading"),
1518
1055
  " ",
1519
- /* @__PURE__ */ jsx24(Spinner, {})
1520
- ] }) : /* @__PURE__ */ jsx24("div", { className: "relative flex h-5 w-full items-center", children: timeField ? /* @__PURE__ */ jsxs17("div", { className: "text-title flex w-full items-center justify-center gap-2 truncate text-sm", children: [
1521
- valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */ jsx24("span", { className: cn(inputPlaceholder, placeholderClassName), children: resolvedPlaceholder }),
1522
- /* @__PURE__ */ jsx24(ClockIcon, { className: "text-border h-3.5 w-3.5 shrink-0" })
1523
- ] }) : /* @__PURE__ */ jsxs17(Fragment3, { children: [
1524
- /* @__PURE__ */ jsxs17("div", { className: "flex w-full max-w-[90%] items-center truncate", children: [
1525
- leftIcon && /* @__PURE__ */ jsx24("span", { className: "mr-2 shrink-0", children: cloneElement(leftIcon, { size: 20, strokeWidth: 1 }) }),
1526
- valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */ jsx24("span", { className: cn(inputPlaceholder, placeholderClassName), children: resolvedPlaceholder })
1056
+ /* @__PURE__ */ jsx18(Spinner, { size: "sm" })
1057
+ ] }) : /* @__PURE__ */ jsx18("div", { className: "relative flex h-5 w-full items-center", children: timeField ? /* @__PURE__ */ jsxs14("div", { className: "text-title flex w-full items-center justify-center gap-2 truncate text-sm", children: [
1058
+ valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */ jsx18("span", { className: cn(inputPlaceholder, placeholderClassName), children: resolvedPlaceholder }),
1059
+ /* @__PURE__ */ jsx18(ClockIcon, { "aria-hidden": true, className: "text-border h-3.5 w-3.5 shrink-0" })
1060
+ ] }) : /* @__PURE__ */ jsxs14(Fragment3, { children: [
1061
+ /* @__PURE__ */ jsxs14("div", { className: "flex w-full max-w-[90%] items-center truncate", children: [
1062
+ leftIcon && /* @__PURE__ */ jsx18("span", { className: "mr-2 shrink-0", children: cloneElement(leftIcon, { size: 20, strokeWidth: 1 }) }),
1063
+ valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */ jsx18("span", { className: cn(inputPlaceholder, placeholderClassName), children: resolvedPlaceholder })
1527
1064
  ] }),
1528
- /* @__PURE__ */ jsxs17("div", { className: "absolute top-0.5 right-0 flex gap-2", children: [
1529
- ableDeleteOption && /* @__PURE__ */ jsx24("div", { "aria-hidden": true, className: "h-4 w-4 shrink-0" }),
1530
- !open ? /* @__PURE__ */ jsx24(CaretDownIcon, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }) : /* @__PURE__ */ jsx24(CaretUpIcon, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
1065
+ /* @__PURE__ */ jsxs14("div", { className: "absolute top-0.5 right-0 flex gap-2", children: [
1066
+ ableDeleteOption && /* @__PURE__ */ jsx18("div", { "aria-hidden": true, className: "h-4 w-4 shrink-0" }),
1067
+ !open ? /* @__PURE__ */ jsx18(CaretDownIcon, { "aria-hidden": true, className: "ml-2 h-4 w-4 shrink-0 opacity-50" }) : /* @__PURE__ */ jsx18(CaretUpIcon, { "aria-hidden": true, className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
1531
1068
  ] })
1532
1069
  ] }) })
1533
1070
  }
1534
1071
  ) }),
1535
- /* @__PURE__ */ jsx24(
1072
+ /* @__PURE__ */ jsx18(
1536
1073
  PopoverContent,
1537
1074
  {
1538
1075
  className: cn("bg-surface border-border rounded-sm p-1", zPopoverAboveDialog),
1539
1076
  id: listboxId,
1540
1077
  onOpenAutoFocus: (e) => e.preventDefault(),
1541
1078
  style: timeField ? { maxWidth: "auto", width: "180px" } : width > 0 ? { maxWidth: "auto", minWidth: `${width}px`, width: `${width}px` } : void 0,
1542
- children: timeField ? /* @__PURE__ */ jsx24(
1079
+ children: timeField ? /* @__PURE__ */ jsx18(
1543
1080
  TimeColumns,
1544
1081
  {
1545
1082
  hours: timeHours,
@@ -1548,8 +1085,8 @@ var SelectInput = (props) => {
1548
1085
  onSelectMinute: handleSelectMinute,
1549
1086
  value: valueItem
1550
1087
  }
1551
- ) : /* @__PURE__ */ jsxs17(Command, { className: "flex w-full flex-col gap-2", children: [
1552
- search && /* @__PURE__ */ jsx24(
1088
+ ) : /* @__PURE__ */ jsxs14(Command, { className: "flex w-full flex-col gap-2", children: [
1089
+ search && /* @__PURE__ */ jsx18(
1553
1090
  Input,
1554
1091
  {
1555
1092
  className: "mb-1 rounded-sm",
@@ -1558,11 +1095,11 @@ var SelectInput = (props) => {
1558
1095
  value: query
1559
1096
  }
1560
1097
  ),
1561
- /* @__PURE__ */ jsx24(CommandEmpty, { className: "text-center", children: noResultsLabel ?? t("selectInput.noResults") }),
1562
- /* @__PURE__ */ jsx24(CommandList, { children: /* @__PURE__ */ jsx24(CommandGroup, { className: "p-0", children: filteredOptions.map((item) => {
1098
+ /* @__PURE__ */ jsx18(CommandEmpty, { className: "text-center", children: noResultsLabel ?? t("selectInput.noResults") }),
1099
+ /* @__PURE__ */ jsx18(CommandList, { children: /* @__PURE__ */ jsx18(CommandGroup, { className: "p-0", children: filteredOptions.map((item) => {
1563
1100
  const labelValue = item[labelKey];
1564
1101
  const valueValue = item[valueKey];
1565
- return /* @__PURE__ */ jsx24(
1102
+ return /* @__PURE__ */ jsx18(
1566
1103
  CommandItem,
1567
1104
  {
1568
1105
  className: cn(
@@ -1573,7 +1110,8 @@ var SelectInput = (props) => {
1573
1110
  onChange?.(currentValue);
1574
1111
  onValueChange(currentValue);
1575
1112
  setOpen(false);
1576
- setTimeout(() => setQuery(""), QUERY_RESET_DELAY_MS);
1113
+ if (queryResetRef.current) clearTimeout(queryResetRef.current);
1114
+ queryResetRef.current = setTimeout(() => setQuery(""), QUERY_RESET_DELAY_MS);
1577
1115
  },
1578
1116
  value: valueValue,
1579
1117
  children: labelValue.trim()
@@ -1585,11 +1123,14 @@ var SelectInput = (props) => {
1585
1123
  }
1586
1124
  )
1587
1125
  ] }),
1588
- ableDeleteOption && !loading && !timeField && /* @__PURE__ */ jsx24(
1126
+ ableDeleteOption && !loading && !timeField && /* @__PURE__ */ jsx18(
1589
1127
  "button",
1590
1128
  {
1591
1129
  "aria-label": t("selectInput.clear"),
1592
- className: "absolute top-1/2 right-9 z-10 flex h-4 w-4 -translate-y-1/2 items-center justify-center",
1130
+ className: cn(
1131
+ "absolute top-1/2 right-7 z-10 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full",
1132
+ focusRing
1133
+ ),
1593
1134
  onClick: () => {
1594
1135
  onChange?.("");
1595
1136
  onValueChange("");
@@ -1598,14 +1139,14 @@ var SelectInput = (props) => {
1598
1139
  setOpen(false);
1599
1140
  },
1600
1141
  type: "button",
1601
- children: /* @__PURE__ */ jsx24(XIcon3, { className: "h-4 w-4 shrink-0 opacity-50" })
1142
+ children: /* @__PURE__ */ jsx18(XIcon3, { "aria-hidden": true, className: "h-4 w-4 shrink-0 opacity-50" })
1602
1143
  }
1603
1144
  )
1604
1145
  ] }) });
1605
1146
  };
1606
1147
 
1607
1148
  // src/components/form-fields/select-field.tsx
1608
- import { jsx as jsx25 } from "react/jsx-runtime";
1149
+ import { jsx as jsx19 } from "react/jsx-runtime";
1609
1150
  var SelectField = ({
1610
1151
  ableDeleteOption,
1611
1152
  className,
@@ -1621,14 +1162,14 @@ var SelectField = ({
1621
1162
  search,
1622
1163
  visualRequired
1623
1164
  }) => {
1624
- return /* @__PURE__ */ jsx25(
1165
+ return /* @__PURE__ */ jsx19(
1625
1166
  FormField,
1626
1167
  {
1627
1168
  control,
1628
1169
  name,
1629
1170
  render: ({ field, fieldState }) => {
1630
1171
  const hasError = !!fieldState.error;
1631
- return /* @__PURE__ */ jsx25(
1172
+ return /* @__PURE__ */ jsx19(
1632
1173
  FormFieldShell,
1633
1174
  {
1634
1175
  hasError,
@@ -1637,9 +1178,10 @@ var SelectField = ({
1637
1178
  mainClassName,
1638
1179
  name,
1639
1180
  visualRequired,
1640
- children: /* @__PURE__ */ jsx25(
1181
+ children: (controlProps) => /* @__PURE__ */ jsx19(
1641
1182
  SelectInput,
1642
1183
  {
1184
+ ...controlProps,
1643
1185
  ableDeleteOption,
1644
1186
  className,
1645
1187
  disabled,
@@ -1663,13 +1205,13 @@ var SelectField = ({
1663
1205
 
1664
1206
  // src/components/password-checklist.tsx
1665
1207
  import { CheckCircleIcon as CheckCircleIcon2, XCircleIcon } from "@phosphor-icons/react";
1666
- import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
1208
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
1667
1209
  var PasswordChecklist = ({ className, rules, value }) => {
1668
1210
  if (rules.length === 0) return null;
1669
- return /* @__PURE__ */ jsx26("ul", { className: cn("flex flex-col gap-1", className), children: rules.map((rule) => {
1211
+ return /* @__PURE__ */ jsx20("ul", { className: cn("flex flex-col gap-1", className), children: rules.map((rule) => {
1670
1212
  const isMet = rule.test(value);
1671
1213
  const Icon = isMet ? CheckCircleIcon2 : XCircleIcon;
1672
- return /* @__PURE__ */ jsxs18(
1214
+ return /* @__PURE__ */ jsxs15(
1673
1215
  "li",
1674
1216
  {
1675
1217
  className: cn(
@@ -1677,8 +1219,8 @@ var PasswordChecklist = ({ className, rules, value }) => {
1677
1219
  isMet ? "text-success" : "text-inactive-text"
1678
1220
  ),
1679
1221
  children: [
1680
- /* @__PURE__ */ jsx26(Icon, { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }),
1681
- /* @__PURE__ */ jsx26("span", { children: rule.label })
1222
+ /* @__PURE__ */ jsx20(Icon, { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }),
1223
+ /* @__PURE__ */ jsx20("span", { children: rule.label })
1682
1224
  ]
1683
1225
  },
1684
1226
  rule.key
@@ -1687,22 +1229,22 @@ var PasswordChecklist = ({ className, rules, value }) => {
1687
1229
  };
1688
1230
 
1689
1231
  // src/components/step-header.tsx
1690
- import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
1691
- var StepHeader = ({ subtitle, subtitleClassName, title }) => /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
1692
- /* @__PURE__ */ jsx27("h1", { className: "text-title text-2xl font-bold", children: title }),
1693
- subtitle !== void 0 && /* @__PURE__ */ jsx27("p", { className: cn("text-subtitle text-sm", subtitleClassName), children: subtitle })
1232
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
1233
+ var StepHeader = ({ subtitle, subtitleClassName, title }) => /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
1234
+ /* @__PURE__ */ jsx21("h1", { className: "text-title text-2xl font-bold", children: title }),
1235
+ subtitle !== void 0 && /* @__PURE__ */ jsx21("p", { className: cn("text-subtitle text-sm", subtitleClassName), children: subtitle })
1694
1236
  ] });
1695
1237
 
1696
1238
  // src/components/stepper.tsx
1697
1239
  import { CheckIcon } from "@phosphor-icons/react";
1698
- import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
1240
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
1699
1241
  var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
1700
- return /* @__PURE__ */ jsx28("div", { className: cn("flex w-full items-start", className), children: steps.map((step, index) => {
1242
+ return /* @__PURE__ */ jsx22("div", { className: cn("flex w-full items-start", className), children: steps.map((step, index) => {
1701
1243
  const isCompleted = intermediate ? index <= activeIndex : index < activeIndex;
1702
1244
  const isActive = !intermediate && index === activeIndex;
1703
- return /* @__PURE__ */ jsxs20("div", { className: "flex flex-1 flex-col items-center", children: [
1704
- /* @__PURE__ */ jsxs20("div", { className: "flex w-full items-center", children: [
1705
- /* @__PURE__ */ jsx28(
1245
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 flex-col items-center", children: [
1246
+ /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center", children: [
1247
+ /* @__PURE__ */ jsx22(
1706
1248
  "div",
1707
1249
  {
1708
1250
  className: cn(
@@ -1712,7 +1254,7 @@ var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
1712
1254
  )
1713
1255
  }
1714
1256
  ),
1715
- /* @__PURE__ */ jsx28(
1257
+ /* @__PURE__ */ jsx22(
1716
1258
  "div",
1717
1259
  {
1718
1260
  "aria-current": isActive ? "step" : void 0,
@@ -1720,12 +1262,12 @@ var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
1720
1262
  "flex h-5.5 w-5.5 shrink-0 items-center justify-center rounded-full border text-xs font-semibold transition-colors md:h-6.5 md:w-6.5",
1721
1263
  isCompleted && "bg-primary border-primary text-inverse",
1722
1264
  isActive && "bg-primary border-primary text-inverse",
1723
- !isCompleted && !isActive && "bg-inactive border-inactive text-surface"
1265
+ !isCompleted && !isActive && "bg-inactive border-inactive text-inverse"
1724
1266
  ),
1725
- children: isCompleted ? /* @__PURE__ */ jsx28(CheckIcon, { className: "h-4 w-4" }) : index + 1
1267
+ children: isCompleted ? /* @__PURE__ */ jsx22(CheckIcon, { "aria-hidden": true, className: "h-4 w-4" }) : index + 1
1726
1268
  }
1727
1269
  ),
1728
- /* @__PURE__ */ jsx28(
1270
+ /* @__PURE__ */ jsx22(
1729
1271
  "div",
1730
1272
  {
1731
1273
  className: cn(
@@ -1733,7 +1275,7 @@ var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
1733
1275
  isCompleted ? "bg-primary" : "bg-inactive",
1734
1276
  index === steps.length - 1 && "rounded-r-full"
1735
1277
  ),
1736
- children: index === 0 && /* @__PURE__ */ jsx28(
1278
+ children: index === 0 && /* @__PURE__ */ jsx22(
1737
1279
  "div",
1738
1280
  {
1739
1281
  className: cn(
@@ -1745,39 +1287,40 @@ var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
1745
1287
  }
1746
1288
  )
1747
1289
  ] }),
1748
- /* @__PURE__ */ jsx28("span", { className: cn("mt-1 text-xs font-normal", isCompleted || isActive ? "text-primary" : "text-muted"), children: step.label })
1290
+ /* @__PURE__ */ jsx22("span", { className: cn("mt-1 text-xs font-normal", isCompleted || isActive ? "text-primary" : "text-muted"), children: step.label })
1749
1291
  ] }, step.label);
1750
1292
  }) });
1751
1293
  };
1752
1294
 
1753
1295
  // src/components/switch.tsx
1754
1296
  import * as SwitchPrimitive from "@radix-ui/react-switch";
1755
- import * as React15 from "react";
1756
- import { jsx as jsx29 } from "react/jsx-runtime";
1757
- var Switch = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx29(
1297
+ import * as React13 from "react";
1298
+ import { jsx as jsx23 } from "react/jsx-runtime";
1299
+ var Switch = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
1758
1300
  SwitchPrimitive.Root,
1759
1301
  {
1760
1302
  className: cn(
1761
- "border-border focus-visible:ring-ring data-[state=checked]:bg-success data-[state=unchecked]:bg-inactive relative inline-flex h-[26px] w-[50px] shrink-0 cursor-pointer items-center rounded-full border transition-colors focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
1303
+ "border-border data-[state=checked]:bg-success data-[state=unchecked]:bg-inactive relative inline-flex h-[26px] w-[50px] shrink-0 cursor-pointer items-center rounded-full border transition-colors disabled:cursor-not-allowed disabled:opacity-50",
1304
+ focusRing,
1762
1305
  className
1763
1306
  ),
1764
1307
  ref,
1765
1308
  ...props,
1766
- children: /* @__PURE__ */ jsx29(SwitchPrimitive.Thumb, { className: "bg-surface pointer-events-none absolute top-[3px] left-[3px] block h-[18px] w-[18px] rounded-full shadow-lg transition-transform data-[state=checked]:translate-x-6" })
1309
+ children: /* @__PURE__ */ jsx23(SwitchPrimitive.Thumb, { className: "bg-surface pointer-events-none absolute top-[3px] left-[3px] block h-[18px] w-[18px] rounded-full shadow-lg transition-transform data-[state=checked]:translate-x-6" })
1767
1310
  }
1768
1311
  ));
1769
1312
  Switch.displayName = SwitchPrimitive.Root.displayName;
1770
1313
 
1771
1314
  // src/components/textarea.tsx
1772
- import * as React16 from "react";
1773
- import { jsx as jsx30 } from "react/jsx-runtime";
1774
- var Textarea = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx30("textarea", { className: cn(inputSurface, inputFocus, "block h-28 resize-none py-3", className), ref, ...props }));
1315
+ import * as React14 from "react";
1316
+ import { jsx as jsx24 } from "react/jsx-runtime";
1317
+ var Textarea = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24("textarea", { className: cn(inputSurface, inputFocus, "block h-28 resize-none py-3", className), ref, ...props }));
1775
1318
  Textarea.displayName = "Textarea";
1776
1319
 
1777
1320
  // src/components/toast/toast.tsx
1778
1321
  import { CheckIcon as CheckIcon2, FileLockIcon, InfoIcon as InfoIcon2, WarningIcon as WarningIcon2, XIcon as XIcon4 } from "@phosphor-icons/react";
1779
- import { useEffect as useEffect4, useRef as useRef4, useState as useState5 } from "react";
1780
- import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
1322
+ import { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
1323
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1781
1324
  var EXIT_ANIMATION_MS = 200;
1782
1325
  var typeIcons = {
1783
1326
  destructive: XIcon4,
@@ -1794,7 +1337,7 @@ var typeStyles = {
1794
1337
  warning: { border: "border-warning", icon: "text-warning", iconBorder: "border-warning" }
1795
1338
  };
1796
1339
  function Toast({ duration = 2500, id, onClose, subtitle, title, type }) {
1797
- const [leaving, setLeaving] = useState5(false);
1340
+ const [leaving, setLeaving] = useState4(false);
1798
1341
  const startedAtRef = useRef4(Date.now());
1799
1342
  const timeoutRef = useRef4(null);
1800
1343
  const exitRef = useRef4(null);
@@ -1814,10 +1357,9 @@ function Toast({ duration = 2500, id, onClose, subtitle, title, type }) {
1814
1357
  if (exitRef.current) clearTimeout(exitRef.current);
1815
1358
  };
1816
1359
  }, [id, duration, onClose]);
1817
- return /* @__PURE__ */ jsxs21(
1360
+ return /* @__PURE__ */ jsxs18(
1818
1361
  "div",
1819
1362
  {
1820
- "aria-live": "polite",
1821
1363
  className: cn(
1822
1364
  "relative",
1823
1365
  leaving ? "absolute top-0 right-0 left-0" : "",
@@ -1830,19 +1372,19 @@ function Toast({ duration = 2500, id, onClose, subtitle, title, type }) {
1830
1372
  styles.border,
1831
1373
  leaving ? "translate-y-2 opacity-0" : "translate-y-0 opacity-100"
1832
1374
  ),
1833
- role: "status",
1375
+ role: type === "destructive" ? "alert" : "status",
1834
1376
  children: [
1835
- /* @__PURE__ */ jsx31("div", { className: "min-w-0 pr-4", children: /* @__PURE__ */ jsx31("h4", { className: cn("text-[16px] leading-normal font-semibold", "text-foreground", "line-clamp-2"), children: title }) }),
1836
- subtitle ? /* @__PURE__ */ jsx31("div", { className: "shrink-0 pr-4 text-left", children: /* @__PURE__ */ jsx31("div", { className: cn("max-w-28 text-[14px] leading-[19.5px] font-normal", "text-body"), children: subtitle }) }) : null,
1837
- /* @__PURE__ */ jsx31(
1377
+ /* @__PURE__ */ jsx25("div", { className: "min-w-0 pr-4", children: /* @__PURE__ */ jsx25("h4", { className: cn("text-base leading-normal font-semibold", "text-foreground", "line-clamp-2"), children: title }) }),
1378
+ subtitle ? /* @__PURE__ */ jsx25("div", { className: "shrink-0 pr-4 text-left", children: /* @__PURE__ */ jsx25("div", { className: cn("max-w-28 text-sm font-normal", "text-body"), children: subtitle }) }) : null,
1379
+ /* @__PURE__ */ jsx25(
1838
1380
  "div",
1839
1381
  {
1840
1382
  className: cn(
1841
1383
  "shrink-0",
1842
- "flex h-8 w-8 min-w-8 items-center justify-center rounded-full border-2",
1384
+ "flex size-8 min-w-8 items-center justify-center rounded-full border-2",
1843
1385
  styles.iconBorder
1844
1386
  ),
1845
- children: /* @__PURE__ */ jsx31(Icon, { className: cn("h-5 w-5", styles.icon) })
1387
+ children: /* @__PURE__ */ jsx25(Icon, { "aria-hidden": true, className: cn("h-5 w-5", styles.icon) })
1846
1388
  }
1847
1389
  )
1848
1390
  ]
@@ -1851,13 +1393,13 @@ function Toast({ duration = 2500, id, onClose, subtitle, title, type }) {
1851
1393
  }
1852
1394
 
1853
1395
  // src/components/toast/toast-provider.tsx
1854
- import { useCallback as useCallback3, useEffect as useEffect5, useLayoutEffect, useMemo as useMemo4, useRef as useRef5, useState as useState6 } from "react";
1855
- import { Fragment as Fragment4, jsx as jsx32 } from "react/jsx-runtime";
1396
+ import { useCallback as useCallback2, useEffect as useEffect5, useLayoutEffect, useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
1397
+ import { Fragment as Fragment4, jsx as jsx26 } from "react/jsx-runtime";
1856
1398
  function ToastProvider() {
1857
- const [toasts, setToasts] = useState6([]);
1399
+ const [toasts, setToasts] = useState5([]);
1858
1400
  const itemRefs = useRef5(/* @__PURE__ */ new Map());
1859
1401
  const prevRects = useRef5(/* @__PURE__ */ new Map());
1860
- const showToast = useCallback3((type, options) => {
1402
+ const showToast = useCallback2((type, options) => {
1861
1403
  setToasts((prev) => [
1862
1404
  ...prev,
1863
1405
  {
@@ -1869,14 +1411,14 @@ function ToastProvider() {
1869
1411
  }
1870
1412
  ]);
1871
1413
  }, []);
1872
- const removeToast = useCallback3((id) => {
1414
+ const removeToast = useCallback2((id) => {
1873
1415
  setToasts((prev) => prev.filter((t) => t.id !== id));
1874
1416
  }, []);
1875
1417
  useEffect5(() => {
1876
1418
  registerToastEmitter(showToast);
1877
1419
  return () => registerToastEmitter(null);
1878
1420
  }, [showToast]);
1879
- const grouped = useMemo4(() => {
1421
+ const grouped = useMemo3(() => {
1880
1422
  return toasts.reduce((acc, toast2) => {
1881
1423
  const pos = toast2.position ?? "top";
1882
1424
  acc[pos] = [...acc[pos] ?? [], toast2];
@@ -1903,7 +1445,7 @@ function ToastProvider() {
1903
1445
  });
1904
1446
  prevRects.current = newRects;
1905
1447
  }, [toasts]);
1906
- const setItemRef = useCallback3((id) => {
1448
+ const setItemRef = useCallback2((id) => {
1907
1449
  return (el) => {
1908
1450
  if (!el) {
1909
1451
  itemRefs.current.delete(id);
@@ -1913,7 +1455,7 @@ function ToastProvider() {
1913
1455
  itemRefs.current.set(id, el);
1914
1456
  };
1915
1457
  }, []);
1916
- return /* @__PURE__ */ jsx32(Fragment4, { children: Object.entries(grouped).map(([position, list]) => /* @__PURE__ */ jsx32("div", { className: `fixed ${zToast} ${getPositionClass(position)}`, children: /* @__PURE__ */ jsx32("div", { className: "relative flex flex-col gap-3", children: list.map((toast2) => /* @__PURE__ */ jsx32("div", { ref: setItemRef(toast2.id), children: /* @__PURE__ */ jsx32(
1458
+ return /* @__PURE__ */ jsx26(Fragment4, { children: Object.entries(grouped).map(([position, list]) => /* @__PURE__ */ jsx26("div", { className: `fixed ${zToast} ${getPositionClass(position)}`, children: /* @__PURE__ */ jsx26("div", { className: "relative flex flex-col gap-3", children: list.map((toast2) => /* @__PURE__ */ jsx26("div", { ref: setItemRef(toast2.id), children: /* @__PURE__ */ jsx26(
1917
1459
  Toast,
1918
1460
  {
1919
1461
  duration: toast2.duration,
@@ -1941,9 +1483,9 @@ function getPositionClass(position) {
1941
1483
  }
1942
1484
 
1943
1485
  // src/components/wrapper.tsx
1944
- import { jsx as jsx33 } from "react/jsx-runtime";
1486
+ import { jsx as jsx27 } from "react/jsx-runtime";
1945
1487
  var Wrapper = ({ children, className }) => {
1946
- return /* @__PURE__ */ jsx33("div", { className: cn("mx-auto h-full w-full", className), children });
1488
+ return /* @__PURE__ */ jsx27("div", { className: cn("mx-auto h-full w-full", className), children });
1947
1489
  };
1948
1490
  export {
1949
1491
  AddTile,
@@ -2001,11 +1543,16 @@ export {
2001
1543
  Toast,
2002
1544
  ToastProvider,
2003
1545
  Tooltip,
1546
+ TooltipContent,
1547
+ TooltipProvider,
1548
+ TooltipRoot,
1549
+ TooltipTrigger,
2004
1550
  Wrapper,
2005
1551
  buttonVariants,
2006
1552
  capitalize,
2007
1553
  chipVariants,
2008
1554
  cn,
1555
+ focusRing,
2009
1556
  formatNumber,
2010
1557
  formatPrice,
2011
1558
  getTagEmoji,