@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/chunk-5VBG6IKL.js +649 -0
- package/dist/chunk-5VBG6IKL.js.map +1 -0
- package/dist/chunk-FDVY36KS.js +41 -0
- package/dist/chunk-FDVY36KS.js.map +1 -0
- package/dist/index.d.ts +28 -46
- package/dist/index.js +396 -849
- package/dist/index.js.map +1 -1
- package/dist/locales/index.d.ts +9 -0
- package/dist/locales/index.js +3 -27
- package/dist/locales/index.js.map +1 -1
- package/dist/maps.d.ts +46 -0
- package/dist/maps.js +9 -0
- package/dist/maps.js.map +1 -0
- package/dist/styles/index.css +1 -0
- package/dist/styles/theme.css +16 -0
- package/package.json +22 -6
package/dist/index.js
CHANGED
|
@@ -1,134 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
363
|
-
/* @__PURE__ */ jsx7(TooltipContent, { className
|
|
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
|
-
|
|
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-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
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(
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
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
|
|
698
|
-
import { jsx as
|
|
699
|
-
var
|
|
700
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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__ */
|
|
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__ */
|
|
822
|
-
/* @__PURE__ */
|
|
634
|
+
children: (controlProps) => /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
|
|
635
|
+
/* @__PURE__ */ jsx13(
|
|
823
636
|
Input,
|
|
824
637
|
{
|
|
825
638
|
...field,
|
|
826
|
-
|
|
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__ */
|
|
843
|
-
field.value && isClearable && /* @__PURE__ */
|
|
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
|
-
|
|
666
|
+
"aria-label": resolvedClearLabel,
|
|
667
|
+
className: iconButtonClassName,
|
|
847
668
|
onClick: onClear,
|
|
848
|
-
title:
|
|
669
|
+
title: resolvedClearLabel,
|
|
849
670
|
type: "button",
|
|
850
|
-
children: /* @__PURE__ */
|
|
671
|
+
children: /* @__PURE__ */ jsx13(XIcon2, { "aria-hidden": true, size: 18 })
|
|
851
672
|
}
|
|
852
673
|
),
|
|
853
|
-
|
|
674
|
+
isPassword && /* @__PURE__ */ jsx13(
|
|
854
675
|
"button",
|
|
855
676
|
{
|
|
856
|
-
|
|
677
|
+
"aria-label": passwordToggleLabel,
|
|
678
|
+
className: iconButtonClassName,
|
|
857
679
|
onClick: togglePasswordVisibility,
|
|
858
|
-
title:
|
|
680
|
+
title: passwordToggleLabel,
|
|
859
681
|
type: "button",
|
|
860
|
-
children: isPasswordVisible ? /* @__PURE__ */
|
|
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
|
|
1199
|
-
import { jsx as
|
|
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__ */
|
|
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__ */
|
|
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 =
|
|
721
|
+
const inputOTPContext = React10.useContext(OTPInputContext);
|
|
1224
722
|
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {};
|
|
1225
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
758
|
+
return /* @__PURE__ */ jsx15(
|
|
1261
759
|
FormField,
|
|
1262
760
|
{
|
|
1263
761
|
control,
|
|
1264
762
|
name,
|
|
1265
|
-
render: ({ field, fieldState }) => /* @__PURE__ */
|
|
1266
|
-
label ? /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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
|
|
1306
|
-
import { jsx as
|
|
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 =
|
|
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
|
|
1326
|
-
import { jsx as
|
|
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 =
|
|
1330
|
-
const minuteListRef =
|
|
1331
|
-
|
|
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
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
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
|
|
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 =
|
|
1384
|
-
const [width, setWidth] =
|
|
1385
|
-
|
|
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] =
|
|
1398
|
-
const normalizedItems =
|
|
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 =
|
|
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
|
|
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 =
|
|
1442
|
-
const [open, setOpen] =
|
|
1443
|
-
const [valueItem, setValueItem] =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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] =
|
|
1028
|
+
const [prevValue, setPrevValue] = useState3(value);
|
|
1497
1029
|
if (prevValue !== value) {
|
|
1498
1030
|
setPrevValue(value);
|
|
1499
1031
|
setValueItem(value);
|
|
1500
1032
|
}
|
|
1501
|
-
return /* @__PURE__ */
|
|
1502
|
-
/* @__PURE__ */
|
|
1503
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
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__ */
|
|
1053
|
+
children: loading ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
1517
1054
|
loadingLabel ?? t("selectInput.loading"),
|
|
1518
1055
|
" ",
|
|
1519
|
-
/* @__PURE__ */
|
|
1520
|
-
] }) : /* @__PURE__ */
|
|
1521
|
-
valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
1523
|
-
] }) : /* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
1525
|
-
leftIcon && /* @__PURE__ */
|
|
1526
|
-
valueItem ? filteredOptions.find((i) => i[valueKey] === valueItem)?.[labelKey] : /* @__PURE__ */
|
|
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__ */
|
|
1529
|
-
ableDeleteOption && /* @__PURE__ */
|
|
1530
|
-
!open ? /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1552
|
-
search && /* @__PURE__ */
|
|
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__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
-
|
|
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__ */
|
|
1126
|
+
ableDeleteOption && !loading && !timeField && /* @__PURE__ */ jsx18(
|
|
1589
1127
|
"button",
|
|
1590
1128
|
{
|
|
1591
1129
|
"aria-label": t("selectInput.clear"),
|
|
1592
|
-
className:
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1681
|
-
/* @__PURE__ */
|
|
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
|
|
1691
|
-
var StepHeader = ({ subtitle, subtitleClassName, title }) => /* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1693
|
-
subtitle !== void 0 && /* @__PURE__ */
|
|
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
|
|
1240
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1699
1241
|
var Stepper = ({ activeIndex, className, intermediate = false, steps }) => {
|
|
1700
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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-
|
|
1265
|
+
!isCompleted && !isActive && "bg-inactive border-inactive text-inverse"
|
|
1724
1266
|
),
|
|
1725
|
-
children: isCompleted ? /* @__PURE__ */
|
|
1267
|
+
children: isCompleted ? /* @__PURE__ */ jsx22(CheckIcon, { "aria-hidden": true, className: "h-4 w-4" }) : index + 1
|
|
1726
1268
|
}
|
|
1727
1269
|
),
|
|
1728
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
1756
|
-
import { jsx as
|
|
1757
|
-
var Switch =
|
|
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
|
|
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__ */
|
|
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
|
|
1773
|
-
import { jsx as
|
|
1774
|
-
var Textarea =
|
|
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
|
|
1780
|
-
import { jsx as
|
|
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] =
|
|
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__ */
|
|
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__ */
|
|
1836
|
-
subtitle ? /* @__PURE__ */
|
|
1837
|
-
/* @__PURE__ */
|
|
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
|
|
1384
|
+
"flex size-8 min-w-8 items-center justify-center rounded-full border-2",
|
|
1843
1385
|
styles.iconBorder
|
|
1844
1386
|
),
|
|
1845
|
-
children: /* @__PURE__ */
|
|
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
|
|
1855
|
-
import { Fragment as Fragment4, jsx as
|
|
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] =
|
|
1399
|
+
const [toasts, setToasts] = useState5([]);
|
|
1858
1400
|
const itemRefs = useRef5(/* @__PURE__ */ new Map());
|
|
1859
1401
|
const prevRects = useRef5(/* @__PURE__ */ new Map());
|
|
1860
|
-
const showToast =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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__ */
|
|
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
|
|
1486
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1945
1487
|
var Wrapper = ({ children, className }) => {
|
|
1946
|
-
return /* @__PURE__ */
|
|
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,
|