@arkcit/react-ui 0.3.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/README.md +59 -0
- package/dist/ApiDocLayout-6hYQvst0.d.ts +19 -0
- package/dist/ComponentGuidelines-h1MjGBuJ.d.ts +1293 -0
- package/dist/FileUploadField-DLwEPn_A.d.ts +32 -0
- package/dist/contracts.d.ts +10 -0
- package/dist/contracts.js +36 -0
- package/dist/form-fields-9C7CmVGn.d.ts +88 -0
- package/dist/form-fields.d.ts +5 -0
- package/dist/form-fields.js +2113 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +16112 -0
- package/dist/orchestrator-contracts.d.ts +1 -0
- package/dist/orchestrator-contracts.js +0 -0
- package/dist/orchestrator-registry.d.ts +25 -0
- package/dist/orchestrator-registry.js +9405 -0
- package/dist/orchestrator.d.ts +29 -0
- package/dist/orchestrator.js +9602 -0
- package/dist/registry.d.ts +30 -0
- package/dist/registry.js +15786 -0
- package/dist/ui-contracts.d.ts +123 -0
- package/dist/ui-contracts.js +36 -0
- package/dist/ui-registry.d.ts +127 -0
- package/dist/ui-registry.js +15611 -0
- package/dist/ui.d.ts +119 -0
- package/dist/ui.js +9618 -0
- package/package.json +121 -0
|
@@ -0,0 +1,2113 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/components/shared/patterns/forms/engine/syntheticEvents.ts
|
|
34
|
+
var createFormFieldChangeEvent = (name, value) => ({
|
|
35
|
+
target: {
|
|
36
|
+
name,
|
|
37
|
+
value
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// src/components/shared/primitives/data-entry/Checkbox/Checkbox.tsx
|
|
42
|
+
import { forwardRef } from "react";
|
|
43
|
+
import { jsx } from "react/jsx-runtime";
|
|
44
|
+
var Checkbox = forwardRef(
|
|
45
|
+
(_a, ref) => {
|
|
46
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
"input",
|
|
49
|
+
__spreadValues({
|
|
50
|
+
ref,
|
|
51
|
+
type: "checkbox",
|
|
52
|
+
className: `h-4 w-4 rounded border border-border-strong text-primary focus-visible:ring-2 focus-visible:ring-primary/30 disabled:opacity-50 disabled:cursor-not-allowed ${className != null ? className : ""}`
|
|
53
|
+
}, props)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
Checkbox.displayName = "Checkbox";
|
|
58
|
+
var Checkbox_default = Checkbox;
|
|
59
|
+
|
|
60
|
+
// src/components/shared/patterns/forms/FormField/fields/CheckboxField/CheckboxField.tsx
|
|
61
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
62
|
+
var CheckboxField = ({
|
|
63
|
+
field,
|
|
64
|
+
value,
|
|
65
|
+
error,
|
|
66
|
+
errorId,
|
|
67
|
+
onChange
|
|
68
|
+
}) => {
|
|
69
|
+
const checked = Boolean(value);
|
|
70
|
+
const emit = (next) => {
|
|
71
|
+
onChange(createFormFieldChangeEvent(field.name, next));
|
|
72
|
+
};
|
|
73
|
+
return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer select-none py-1", children: [
|
|
74
|
+
/* @__PURE__ */ jsx2(
|
|
75
|
+
Checkbox_default,
|
|
76
|
+
{
|
|
77
|
+
id: field.name,
|
|
78
|
+
name: field.name,
|
|
79
|
+
checked,
|
|
80
|
+
onChange: (e) => emit(e.target.checked),
|
|
81
|
+
"aria-invalid": Boolean(error),
|
|
82
|
+
"aria-describedby": errorId,
|
|
83
|
+
className: `cursor-pointer ${error ? "border-danger" : "border-border-strong"}`
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsxs("span", { className: "text-foreground", children: [
|
|
87
|
+
field.label,
|
|
88
|
+
" ",
|
|
89
|
+
field.required && "*"
|
|
90
|
+
] }),
|
|
91
|
+
error && !errorId && /* @__PURE__ */ jsx2("p", { className: "text-sm text-danger", children: error })
|
|
92
|
+
] });
|
|
93
|
+
};
|
|
94
|
+
var CheckboxField_default = CheckboxField;
|
|
95
|
+
|
|
96
|
+
// src/components/shared/patterns/forms/FormField/fields/CheckboxField/index.tsx
|
|
97
|
+
var CheckboxField_default2 = CheckboxField_default;
|
|
98
|
+
|
|
99
|
+
// src/components/shared/patterns/forms/FormField/fields/CheckboxSearchField/CheckboxSearchField.tsx
|
|
100
|
+
import React4 from "react";
|
|
101
|
+
import { ChevronDown } from "lucide-react";
|
|
102
|
+
|
|
103
|
+
// src/components/shared/primitives/data-entry/Input/Input.tsx
|
|
104
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
105
|
+
|
|
106
|
+
// src/components/shared/utils/cx.ts
|
|
107
|
+
var cx = (...classes) => classes.filter(Boolean).join(" ");
|
|
108
|
+
|
|
109
|
+
// src/components/shared/primitives/data-entry/Input/Input.tsx
|
|
110
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
111
|
+
var SIZE_CLASSES = {
|
|
112
|
+
xs: "h-7 px-2 text-xs",
|
|
113
|
+
sm: "h-8 px-3 text-sm",
|
|
114
|
+
md: "h-10 px-3 text-sm",
|
|
115
|
+
lg: "h-11 px-4 text-base"
|
|
116
|
+
};
|
|
117
|
+
var INTENT_CLASSES = {
|
|
118
|
+
primary: "focus-visible:border-primary",
|
|
119
|
+
secondary: "focus-visible:border-secondary",
|
|
120
|
+
success: "focus-visible:border-success",
|
|
121
|
+
warning: "focus-visible:border-warning",
|
|
122
|
+
danger: "focus-visible:border-danger",
|
|
123
|
+
info: "focus-visible:border-info",
|
|
124
|
+
neutral: "focus-visible:border-primary"
|
|
125
|
+
};
|
|
126
|
+
var Input = forwardRef2(
|
|
127
|
+
(_a, ref) => {
|
|
128
|
+
var _b = _a, {
|
|
129
|
+
className,
|
|
130
|
+
type = "text",
|
|
131
|
+
intent = "neutral",
|
|
132
|
+
size = "md",
|
|
133
|
+
rightIcon: RightIcon,
|
|
134
|
+
rightIconClassName
|
|
135
|
+
} = _b, props = __objRest(_b, [
|
|
136
|
+
"className",
|
|
137
|
+
"type",
|
|
138
|
+
"intent",
|
|
139
|
+
"size",
|
|
140
|
+
"rightIcon",
|
|
141
|
+
"rightIconClassName"
|
|
142
|
+
]);
|
|
143
|
+
const isInvalid = props["aria-invalid"] === true || props["aria-invalid"] === "true";
|
|
144
|
+
return /* @__PURE__ */ jsxs2("div", { className: "relative w-full", children: [
|
|
145
|
+
/* @__PURE__ */ jsx3(
|
|
146
|
+
"input",
|
|
147
|
+
__spreadValues({
|
|
148
|
+
ref,
|
|
149
|
+
type,
|
|
150
|
+
className: cx(
|
|
151
|
+
"w-full rounded-md border bg-background text-foreground outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed",
|
|
152
|
+
SIZE_CLASSES[size],
|
|
153
|
+
isInvalid ? "border-danger focus-visible:border-danger" : "border-border-strong",
|
|
154
|
+
!isInvalid && INTENT_CLASSES[intent],
|
|
155
|
+
RightIcon && "pr-10",
|
|
156
|
+
className
|
|
157
|
+
)
|
|
158
|
+
}, props)
|
|
159
|
+
),
|
|
160
|
+
RightIcon ? /* @__PURE__ */ jsx3("span", { className: "pointer-events-none absolute inset-y-0 right-3 flex items-center text-muted-foreground", children: /* @__PURE__ */ jsx3(
|
|
161
|
+
RightIcon,
|
|
162
|
+
{
|
|
163
|
+
"aria-hidden": "true",
|
|
164
|
+
className: cx("h-4 w-4", rightIconClassName)
|
|
165
|
+
}
|
|
166
|
+
) }) : null
|
|
167
|
+
] });
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
Input.displayName = "Input";
|
|
171
|
+
var Input_default = Input;
|
|
172
|
+
|
|
173
|
+
// src/components/shared/primitives/misc/Tag/Tag.tsx
|
|
174
|
+
import { X } from "lucide-react";
|
|
175
|
+
|
|
176
|
+
// src/components/shared/utils/renderBindableNode.tsx
|
|
177
|
+
import React3 from "react";
|
|
178
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
179
|
+
var MISSING_TRANSLATION_FALLBACK = "Lorem ipsum dolor sit amet. (fallback)";
|
|
180
|
+
var MISSING_REF_FALLBACK = "Lorem ipsum dolor sit amet. (fallback)";
|
|
181
|
+
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
182
|
+
var renderBindableNode = (value) => {
|
|
183
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value == null) {
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
if (Array.isArray(value)) {
|
|
187
|
+
return value.map((item, index) => /* @__PURE__ */ jsx4(React3.Fragment, { children: renderBindableNode(item) }, `bindable-node-${index}`));
|
|
188
|
+
}
|
|
189
|
+
if (React3.isValidElement(value)) return value;
|
|
190
|
+
if (isPlainObject(value)) {
|
|
191
|
+
if (typeof value.$t === "string") return MISSING_TRANSLATION_FALLBACK;
|
|
192
|
+
if (typeof value.$ref === "string") return MISSING_REF_FALLBACK;
|
|
193
|
+
if ("children" in value) {
|
|
194
|
+
return renderBindableNode(value.children);
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
return JSON.stringify(value);
|
|
198
|
+
} catch (e) {
|
|
199
|
+
return String(value);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return String(value);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/components/shared/primitives/misc/Tag/Tag.tsx
|
|
206
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
207
|
+
var SIZE_CLASSES2 = {
|
|
208
|
+
sm: "h-6 px-2 text-xs",
|
|
209
|
+
md: "h-7 px-2.5 text-sm"
|
|
210
|
+
};
|
|
211
|
+
var VARIANT_CLASSES = {
|
|
212
|
+
solid: {
|
|
213
|
+
primary: "bg-primary text-primary-foreground border border-primary",
|
|
214
|
+
secondary: "bg-secondary text-secondary-foreground border border-secondary",
|
|
215
|
+
success: "bg-success text-success-foreground border border-success",
|
|
216
|
+
warning: "bg-warning text-warning-foreground border border-warning",
|
|
217
|
+
danger: "bg-danger text-danger-foreground border border-danger",
|
|
218
|
+
info: "bg-info text-info-foreground border border-info",
|
|
219
|
+
neutral: "bg-foreground text-background border border-foreground"
|
|
220
|
+
},
|
|
221
|
+
soft: {
|
|
222
|
+
primary: "bg-primary-soft text-primary-soft-foreground border border-transparent",
|
|
223
|
+
secondary: "bg-secondary-soft text-secondary-soft-foreground border border-transparent",
|
|
224
|
+
success: "bg-success-soft text-success-soft-foreground border border-transparent",
|
|
225
|
+
warning: "bg-warning-soft text-warning-soft-foreground border border-transparent",
|
|
226
|
+
danger: "bg-danger-soft text-danger-soft-foreground border border-transparent",
|
|
227
|
+
info: "bg-info-soft text-info-soft-foreground border border-transparent",
|
|
228
|
+
neutral: "bg-surface text-foreground border border-transparent"
|
|
229
|
+
},
|
|
230
|
+
outline: {
|
|
231
|
+
primary: "bg-background text-primary border border-primary",
|
|
232
|
+
secondary: "bg-background text-secondary border border-secondary",
|
|
233
|
+
success: "bg-background text-success border border-success",
|
|
234
|
+
warning: "bg-background text-warning border border-warning",
|
|
235
|
+
danger: "bg-background text-danger border border-danger",
|
|
236
|
+
info: "bg-background text-info border border-info",
|
|
237
|
+
neutral: "bg-background text-foreground border border-border-strong"
|
|
238
|
+
},
|
|
239
|
+
ghost: {
|
|
240
|
+
primary: "bg-transparent text-ghost-primary-foreground border border-transparent hover:bg-ghost-primary-hover",
|
|
241
|
+
secondary: "bg-transparent text-ghost-secondary-foreground border border-transparent hover:bg-ghost-secondary-hover",
|
|
242
|
+
success: "bg-transparent text-ghost-success-foreground border border-transparent hover:bg-ghost-success-hover",
|
|
243
|
+
warning: "bg-transparent text-ghost-warning-foreground border border-transparent hover:bg-ghost-warning-hover",
|
|
244
|
+
danger: "bg-transparent text-ghost-danger-foreground border border-transparent hover:bg-ghost-danger-hover",
|
|
245
|
+
info: "bg-transparent text-ghost-info-foreground border border-transparent hover:bg-ghost-info-hover",
|
|
246
|
+
neutral: "bg-transparent text-ghost-foreground border border-transparent hover:bg-ghost-hover"
|
|
247
|
+
},
|
|
248
|
+
glass: {
|
|
249
|
+
primary: "bg-primary/20 text-primary-soft-foreground border border-glass-border shadow-glass",
|
|
250
|
+
secondary: "bg-secondary/20 text-secondary-soft-foreground border border-glass-border shadow-glass",
|
|
251
|
+
success: "bg-success/20 text-success-soft-foreground border border-glass-border shadow-glass",
|
|
252
|
+
warning: "bg-warning/20 text-warning-soft-foreground border border-glass-border shadow-glass",
|
|
253
|
+
danger: "bg-danger/20 text-danger-soft-foreground border border-glass-border shadow-glass",
|
|
254
|
+
info: "bg-info/20 text-info-soft-foreground border border-glass-border shadow-glass",
|
|
255
|
+
neutral: "bg-glass-bg text-foreground border border-glass-border shadow-glass"
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
var Tag = (_a) => {
|
|
259
|
+
var _b = _a, {
|
|
260
|
+
children,
|
|
261
|
+
onRemove,
|
|
262
|
+
intent = "neutral",
|
|
263
|
+
variant = "soft",
|
|
264
|
+
size = "sm",
|
|
265
|
+
disabled = false,
|
|
266
|
+
className
|
|
267
|
+
} = _b, props = __objRest(_b, [
|
|
268
|
+
"children",
|
|
269
|
+
"onRemove",
|
|
270
|
+
"intent",
|
|
271
|
+
"variant",
|
|
272
|
+
"size",
|
|
273
|
+
"disabled",
|
|
274
|
+
"className"
|
|
275
|
+
]);
|
|
276
|
+
return /* @__PURE__ */ jsxs3(
|
|
277
|
+
"span",
|
|
278
|
+
__spreadProps(__spreadValues({
|
|
279
|
+
className: cx(
|
|
280
|
+
"inline-flex items-center gap-1 rounded-md font-medium transition-colors",
|
|
281
|
+
SIZE_CLASSES2[size],
|
|
282
|
+
VARIANT_CLASSES[variant][intent],
|
|
283
|
+
disabled && "opacity-50",
|
|
284
|
+
className
|
|
285
|
+
)
|
|
286
|
+
}, props), {
|
|
287
|
+
children: [
|
|
288
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: renderBindableNode(children) }),
|
|
289
|
+
onRemove ? /* @__PURE__ */ jsx5(
|
|
290
|
+
"button",
|
|
291
|
+
{
|
|
292
|
+
type: "button",
|
|
293
|
+
onClick: onRemove,
|
|
294
|
+
disabled,
|
|
295
|
+
"aria-label": "Remove tag",
|
|
296
|
+
className: "inline-flex h-4 w-4 items-center justify-center rounded-sm hover:bg-black/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed",
|
|
297
|
+
children: /* @__PURE__ */ jsx5(X, { className: "h-3 w-3", "aria-hidden": "true" })
|
|
298
|
+
}
|
|
299
|
+
) : null
|
|
300
|
+
]
|
|
301
|
+
})
|
|
302
|
+
);
|
|
303
|
+
};
|
|
304
|
+
var Tag_default = Tag;
|
|
305
|
+
|
|
306
|
+
// src/components/shared/hooks/events/useEventListener.ts
|
|
307
|
+
import { useEffect, useRef } from "react";
|
|
308
|
+
function useEventListener(event, handler, options) {
|
|
309
|
+
const handlerRef = useRef(handler);
|
|
310
|
+
useEffect(() => {
|
|
311
|
+
handlerRef.current = handler;
|
|
312
|
+
}, [handler]);
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (typeof window === "undefined") return;
|
|
315
|
+
const listener = (e) => handlerRef.current(e);
|
|
316
|
+
window.addEventListener(event, listener, options);
|
|
317
|
+
return () => {
|
|
318
|
+
window.removeEventListener(event, listener, options);
|
|
319
|
+
};
|
|
320
|
+
}, [event, options]);
|
|
321
|
+
}
|
|
322
|
+
var useEventListener_default = useEventListener;
|
|
323
|
+
|
|
324
|
+
// src/components/shared/hooks/events/useOnClickOutside.ts
|
|
325
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
326
|
+
function useOnClickOutside(ref, handler) {
|
|
327
|
+
const handlerRef = useRef2(handler);
|
|
328
|
+
useEffect2(() => {
|
|
329
|
+
handlerRef.current = handler;
|
|
330
|
+
}, [handler]);
|
|
331
|
+
useEffect2(() => {
|
|
332
|
+
if (typeof document === "undefined") return;
|
|
333
|
+
const listener = (event) => {
|
|
334
|
+
const el = ref.current;
|
|
335
|
+
if (!el || el.contains(event.target)) return;
|
|
336
|
+
handlerRef.current(event);
|
|
337
|
+
};
|
|
338
|
+
document.addEventListener("mousedown", listener);
|
|
339
|
+
document.addEventListener("touchstart", listener);
|
|
340
|
+
return () => {
|
|
341
|
+
document.removeEventListener("mousedown", listener);
|
|
342
|
+
document.removeEventListener("touchstart", listener);
|
|
343
|
+
};
|
|
344
|
+
}, [ref]);
|
|
345
|
+
}
|
|
346
|
+
var useOnClickOutside_default = useOnClickOutside;
|
|
347
|
+
|
|
348
|
+
// src/components/shared/patterns/forms/FormField/fields/CheckboxSearchField/CheckboxSearchField.tsx
|
|
349
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
350
|
+
var CheckboxSearchField = ({
|
|
351
|
+
field,
|
|
352
|
+
value,
|
|
353
|
+
error,
|
|
354
|
+
errorId,
|
|
355
|
+
onChange,
|
|
356
|
+
dict
|
|
357
|
+
}) => {
|
|
358
|
+
var _a, _b;
|
|
359
|
+
const selected = Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
360
|
+
const [search, setSearch] = React4.useState("");
|
|
361
|
+
const [open, setOpen] = React4.useState(false);
|
|
362
|
+
const containerRef = React4.useRef(null);
|
|
363
|
+
const filtered = (_b = (_a = field.options) == null ? void 0 : _a.filter(
|
|
364
|
+
(opt) => opt.label.toLowerCase().includes(search.toLowerCase())
|
|
365
|
+
)) != null ? _b : [];
|
|
366
|
+
const emit = (next) => {
|
|
367
|
+
onChange(createFormFieldChangeEvent(field.name, next));
|
|
368
|
+
};
|
|
369
|
+
const toggle = (val) => {
|
|
370
|
+
const next = selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val];
|
|
371
|
+
emit(next);
|
|
372
|
+
};
|
|
373
|
+
const removeTag = (tag) => {
|
|
374
|
+
const next = selected.filter((t) => t !== tag);
|
|
375
|
+
emit(next);
|
|
376
|
+
};
|
|
377
|
+
useOnClickOutside_default(containerRef, () => {
|
|
378
|
+
setOpen(false);
|
|
379
|
+
});
|
|
380
|
+
return /* @__PURE__ */ jsxs4("div", { ref: containerRef, className: "flex flex-col gap-2 relative", children: [
|
|
381
|
+
/* @__PURE__ */ jsx6(
|
|
382
|
+
Input_default,
|
|
383
|
+
{
|
|
384
|
+
id: field.name,
|
|
385
|
+
type: "text",
|
|
386
|
+
className: "cursor-pointer placeholder:text-muted-foreground",
|
|
387
|
+
rightIcon: ChevronDown,
|
|
388
|
+
rightIconClassName: cx(
|
|
389
|
+
"h-5 w-5 [stroke-width:2.5] transition-transform duration-200 ease-out",
|
|
390
|
+
open && "rotate-180"
|
|
391
|
+
),
|
|
392
|
+
placeholder: dict.search,
|
|
393
|
+
value: search,
|
|
394
|
+
onChange: (e) => setSearch(e.target.value),
|
|
395
|
+
onFocus: () => setOpen(true),
|
|
396
|
+
onClick: () => setOpen(true),
|
|
397
|
+
"aria-invalid": Boolean(error),
|
|
398
|
+
"aria-describedby": errorId,
|
|
399
|
+
"aria-expanded": open
|
|
400
|
+
}
|
|
401
|
+
),
|
|
402
|
+
open && /* @__PURE__ */ jsxs4(
|
|
403
|
+
"div",
|
|
404
|
+
{
|
|
405
|
+
role: "listbox",
|
|
406
|
+
"aria-label": field.label,
|
|
407
|
+
className: "absolute left-0 right-0 top-full z-10 mt-1 max-h-60 overflow-y-auto rounded-lg border border-border bg-background p-2 shadow-lg",
|
|
408
|
+
children: [
|
|
409
|
+
filtered.length === 0 && /* @__PURE__ */ jsx6("div", { className: "px-2 py-1 text-sm text-muted-foreground", children: dict.noResultToShow }),
|
|
410
|
+
filtered.map((opt) => {
|
|
411
|
+
const val = opt.value.toString();
|
|
412
|
+
const checked = selected.includes(val);
|
|
413
|
+
return /* @__PURE__ */ jsxs4(
|
|
414
|
+
"label",
|
|
415
|
+
{
|
|
416
|
+
className: "flex cursor-pointer select-none items-center gap-2 rounded px-2 py-1 hover:bg-surface-hover",
|
|
417
|
+
children: [
|
|
418
|
+
/* @__PURE__ */ jsx6(
|
|
419
|
+
Checkbox_default,
|
|
420
|
+
{
|
|
421
|
+
checked,
|
|
422
|
+
onChange: () => toggle(val),
|
|
423
|
+
className: "cursor-pointer"
|
|
424
|
+
}
|
|
425
|
+
),
|
|
426
|
+
/* @__PURE__ */ jsx6("span", { children: opt.label })
|
|
427
|
+
]
|
|
428
|
+
},
|
|
429
|
+
val
|
|
430
|
+
);
|
|
431
|
+
})
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
),
|
|
435
|
+
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap gap-2 mt-1", children: selected.map((tag) => {
|
|
436
|
+
var _a2, _b2;
|
|
437
|
+
const opt = (_a2 = field.options) == null ? void 0 : _a2.find((o) => o.value.toString() === tag);
|
|
438
|
+
return /* @__PURE__ */ jsx6(
|
|
439
|
+
Tag_default,
|
|
440
|
+
{
|
|
441
|
+
intent: "primary",
|
|
442
|
+
variant: "soft",
|
|
443
|
+
onRemove: () => removeTag(tag),
|
|
444
|
+
children: (_b2 = opt == null ? void 0 : opt.label) != null ? _b2 : tag
|
|
445
|
+
},
|
|
446
|
+
tag
|
|
447
|
+
);
|
|
448
|
+
}) })
|
|
449
|
+
] });
|
|
450
|
+
};
|
|
451
|
+
var CheckboxSearchField_default = CheckboxSearchField;
|
|
452
|
+
|
|
453
|
+
// src/components/shared/patterns/forms/FormField/fields/CheckboxSearchField/index.tsx
|
|
454
|
+
var CheckboxSearchField_default2 = CheckboxSearchField_default;
|
|
455
|
+
|
|
456
|
+
// src/helpers/forms/index.ts
|
|
457
|
+
var getSafeValue = (value) => {
|
|
458
|
+
if (value === null || value === void 0) return "";
|
|
459
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
460
|
+
if (Array.isArray(value)) {
|
|
461
|
+
return value.every((item) => typeof item === "string") ? value : void 0;
|
|
462
|
+
}
|
|
463
|
+
return value;
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// src/components/shared/patterns/forms/FormField/fields/ColorField/ColorField.tsx
|
|
467
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
468
|
+
var ColorField = ({
|
|
469
|
+
field,
|
|
470
|
+
value,
|
|
471
|
+
error,
|
|
472
|
+
errorId,
|
|
473
|
+
onChange
|
|
474
|
+
}) => {
|
|
475
|
+
var _a;
|
|
476
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-4", children: [
|
|
477
|
+
/* @__PURE__ */ jsx7(
|
|
478
|
+
"input",
|
|
479
|
+
{
|
|
480
|
+
id: field.name,
|
|
481
|
+
type: "color",
|
|
482
|
+
name: field.name,
|
|
483
|
+
value: getSafeValue(value) || "#000000",
|
|
484
|
+
onChange,
|
|
485
|
+
"aria-invalid": Boolean(error),
|
|
486
|
+
"aria-describedby": errorId,
|
|
487
|
+
className: `h-10 w-12 cursor-pointer rounded-md border p-1 ${error ? "border-danger" : "border-border-strong"}`
|
|
488
|
+
}
|
|
489
|
+
),
|
|
490
|
+
/* @__PURE__ */ jsx7(
|
|
491
|
+
"input",
|
|
492
|
+
{
|
|
493
|
+
type: "text",
|
|
494
|
+
name: field.name,
|
|
495
|
+
value: getSafeValue(value),
|
|
496
|
+
onChange,
|
|
497
|
+
placeholder: (_a = field.placeholder) != null ? _a : "#rrggbb",
|
|
498
|
+
"aria-invalid": Boolean(error),
|
|
499
|
+
"aria-describedby": errorId,
|
|
500
|
+
className: `w-full flex-1 rounded-lg border px-3 py-2 focus:outline-none focus:ring-2 ${error ? "border-danger focus:ring-danger/40" : "border-border-strong focus:ring-ring"}`
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
] });
|
|
504
|
+
};
|
|
505
|
+
var ColorField_default = ColorField;
|
|
506
|
+
|
|
507
|
+
// src/components/shared/patterns/forms/FormField/fields/ColorField/index.tsx
|
|
508
|
+
var ColorField_default2 = ColorField_default;
|
|
509
|
+
|
|
510
|
+
// src/components/shared/patterns/forms/selection/Combobox/Combobox.tsx
|
|
511
|
+
import { useEffect as useEffect3, useId, useMemo, useRef as useRef3, useState } from "react";
|
|
512
|
+
import { Check, ChevronDown as ChevronDown2, Loader2 } from "lucide-react";
|
|
513
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
514
|
+
var sizeClasses = {
|
|
515
|
+
sm: "min-h-9 px-3 text-sm",
|
|
516
|
+
md: "min-h-10 px-3 text-sm",
|
|
517
|
+
lg: "min-h-11 px-4 text-base"
|
|
518
|
+
};
|
|
519
|
+
var variantClasses = {
|
|
520
|
+
solid: "bg-surface border-border text-foreground",
|
|
521
|
+
outline: "bg-background border-border-strong text-foreground",
|
|
522
|
+
ghost: "bg-transparent border-transparent text-foreground hover:bg-surface",
|
|
523
|
+
soft: "bg-surface border-transparent text-foreground",
|
|
524
|
+
glass: "bg-glass-bg border-glass-border text-foreground shadow-glass backdrop-blur-md"
|
|
525
|
+
};
|
|
526
|
+
var intentClasses = {
|
|
527
|
+
primary: "focus-within:border-primary",
|
|
528
|
+
secondary: "focus-within:border-secondary",
|
|
529
|
+
success: "focus-within:border-success",
|
|
530
|
+
warning: "focus-within:border-warning",
|
|
531
|
+
danger: "focus-within:border-danger",
|
|
532
|
+
info: "focus-within:border-info"
|
|
533
|
+
};
|
|
534
|
+
var defaultFilter = (option, query) => option.label.toLowerCase().includes(query.toLowerCase());
|
|
535
|
+
var valuesEqual = (a, b) => Object.is(a, b);
|
|
536
|
+
var Combobox = ({
|
|
537
|
+
options,
|
|
538
|
+
value = null,
|
|
539
|
+
onChange,
|
|
540
|
+
values = [],
|
|
541
|
+
onChangeMany,
|
|
542
|
+
multiple = false,
|
|
543
|
+
placeholder = "Select...",
|
|
544
|
+
disabled = false,
|
|
545
|
+
loading = false,
|
|
546
|
+
search = true,
|
|
547
|
+
query,
|
|
548
|
+
onQueryChange,
|
|
549
|
+
filterFn = defaultFilter,
|
|
550
|
+
closeOnSelect,
|
|
551
|
+
maxSelected,
|
|
552
|
+
size = "md",
|
|
553
|
+
intent = "primary",
|
|
554
|
+
variant = "outline",
|
|
555
|
+
label,
|
|
556
|
+
hint,
|
|
557
|
+
error,
|
|
558
|
+
className,
|
|
559
|
+
inputClassName,
|
|
560
|
+
menuClassName,
|
|
561
|
+
renderOption,
|
|
562
|
+
renderValue,
|
|
563
|
+
"aria-label": ariaLabel,
|
|
564
|
+
id,
|
|
565
|
+
name
|
|
566
|
+
}) => {
|
|
567
|
+
const internalId = useId();
|
|
568
|
+
const inputId = id != null ? id : `combobox-${internalId}`;
|
|
569
|
+
const listboxId = `${inputId}-listbox`;
|
|
570
|
+
const wrapperRef = useRef3(null);
|
|
571
|
+
const inputRef = useRef3(null);
|
|
572
|
+
const [open, setOpen] = useState(false);
|
|
573
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
574
|
+
const [internalQuery, setInternalQuery] = useState("");
|
|
575
|
+
const isControlledQuery = typeof query === "string";
|
|
576
|
+
const currentQuery = isControlledQuery ? query : internalQuery;
|
|
577
|
+
const isInvalid = Boolean(error);
|
|
578
|
+
const shouldCloseOnSelect = closeOnSelect != null ? closeOnSelect : multiple ? false : true;
|
|
579
|
+
const selectedValues = multiple ? values : value == null ? [] : [value];
|
|
580
|
+
const filteredOptions = useMemo(
|
|
581
|
+
() => options.filter(
|
|
582
|
+
(option) => currentQuery.trim() ? filterFn(option, currentQuery) : true
|
|
583
|
+
),
|
|
584
|
+
[currentQuery, filterFn, options]
|
|
585
|
+
);
|
|
586
|
+
const currentSingleLabel = useMemo(() => {
|
|
587
|
+
if (multiple || value == null) return "";
|
|
588
|
+
const option = options.find((item) => valuesEqual(item.value, value));
|
|
589
|
+
if (!option) return "";
|
|
590
|
+
return renderValue ? renderValue(option.value) : option.label;
|
|
591
|
+
}, [multiple, options, renderValue, value]);
|
|
592
|
+
const inputValue = useMemo(() => {
|
|
593
|
+
if (multiple) return currentQuery;
|
|
594
|
+
if (!search) return currentSingleLabel;
|
|
595
|
+
return open ? currentQuery : currentQuery || currentSingleLabel;
|
|
596
|
+
}, [currentQuery, currentSingleLabel, multiple, open, search]);
|
|
597
|
+
useEffect3(() => {
|
|
598
|
+
if (!open) return;
|
|
599
|
+
const onClickOutside = (event) => {
|
|
600
|
+
var _a;
|
|
601
|
+
if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(event.target))) {
|
|
602
|
+
setOpen(false);
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
document.addEventListener("mousedown", onClickOutside);
|
|
606
|
+
return () => document.removeEventListener("mousedown", onClickOutside);
|
|
607
|
+
}, [open]);
|
|
608
|
+
const updateQuery = (nextQuery) => {
|
|
609
|
+
if (!isControlledQuery) setInternalQuery(nextQuery);
|
|
610
|
+
onQueryChange == null ? void 0 : onQueryChange(nextQuery);
|
|
611
|
+
};
|
|
612
|
+
const isSelected = (option) => selectedValues.some((item) => valuesEqual(item, option.value));
|
|
613
|
+
const commitSingle = (next) => {
|
|
614
|
+
onChange == null ? void 0 : onChange(next);
|
|
615
|
+
};
|
|
616
|
+
const commitMany = (next) => {
|
|
617
|
+
onChangeMany == null ? void 0 : onChangeMany(next);
|
|
618
|
+
};
|
|
619
|
+
const selectOption = (option) => {
|
|
620
|
+
if (option.disabled) return;
|
|
621
|
+
if (multiple) {
|
|
622
|
+
const exists = isSelected(option);
|
|
623
|
+
if (exists) {
|
|
624
|
+
commitMany(values.filter((item) => !valuesEqual(item, option.value)));
|
|
625
|
+
} else {
|
|
626
|
+
if (typeof maxSelected === "number" && values.length >= maxSelected)
|
|
627
|
+
return;
|
|
628
|
+
commitMany([...values, option.value]);
|
|
629
|
+
}
|
|
630
|
+
} else {
|
|
631
|
+
commitSingle(option.value);
|
|
632
|
+
if (search) updateQuery("");
|
|
633
|
+
}
|
|
634
|
+
if (shouldCloseOnSelect) {
|
|
635
|
+
setOpen(false);
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
return /* @__PURE__ */ jsxs6("div", { className: cx("relative w-full", className), ref: wrapperRef, children: [
|
|
639
|
+
label ? /* @__PURE__ */ jsx8(
|
|
640
|
+
"label",
|
|
641
|
+
{
|
|
642
|
+
htmlFor: inputId,
|
|
643
|
+
className: "mb-1 block text-sm font-medium text-foreground",
|
|
644
|
+
children: label
|
|
645
|
+
}
|
|
646
|
+
) : null,
|
|
647
|
+
/* @__PURE__ */ jsxs6(
|
|
648
|
+
"div",
|
|
649
|
+
{
|
|
650
|
+
className: cx(
|
|
651
|
+
"rounded-md border transition-colors focus-within:ring-2 focus-within:ring-ring",
|
|
652
|
+
sizeClasses[size],
|
|
653
|
+
variantClasses[variant],
|
|
654
|
+
intentClasses[intent],
|
|
655
|
+
isInvalid && "border-danger focus-within:border-danger",
|
|
656
|
+
disabled && "cursor-not-allowed opacity-60"
|
|
657
|
+
),
|
|
658
|
+
children: [
|
|
659
|
+
multiple && values.length > 0 ? /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-1 px-2 pb-1 pt-2", children: values.map((selected, index) => {
|
|
660
|
+
var _a;
|
|
661
|
+
const option = options.find(
|
|
662
|
+
(item) => valuesEqual(item.value, selected)
|
|
663
|
+
);
|
|
664
|
+
return /* @__PURE__ */ jsx8(
|
|
665
|
+
Tag_default,
|
|
666
|
+
{
|
|
667
|
+
size: "sm",
|
|
668
|
+
onRemove: () => commitMany(
|
|
669
|
+
values.filter((item) => !valuesEqual(item, selected))
|
|
670
|
+
),
|
|
671
|
+
children: (_a = option == null ? void 0 : option.label) != null ? _a : String(selected)
|
|
672
|
+
},
|
|
673
|
+
`${String(selected)}-${index}`
|
|
674
|
+
);
|
|
675
|
+
}) }) : null,
|
|
676
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 py-0.5", children: [
|
|
677
|
+
/* @__PURE__ */ jsx8(
|
|
678
|
+
"input",
|
|
679
|
+
{
|
|
680
|
+
ref: inputRef,
|
|
681
|
+
id: inputId,
|
|
682
|
+
name,
|
|
683
|
+
value: inputValue,
|
|
684
|
+
onFocus: () => {
|
|
685
|
+
if (!disabled) setOpen(true);
|
|
686
|
+
},
|
|
687
|
+
onClick: () => {
|
|
688
|
+
if (!disabled) setOpen(true);
|
|
689
|
+
},
|
|
690
|
+
onChange: (event) => {
|
|
691
|
+
if (!search && !multiple) return;
|
|
692
|
+
updateQuery(event.target.value);
|
|
693
|
+
setOpen(true);
|
|
694
|
+
setActiveIndex(0);
|
|
695
|
+
},
|
|
696
|
+
onKeyDown: (event) => {
|
|
697
|
+
if (disabled) return;
|
|
698
|
+
if (event.key === "ArrowDown") {
|
|
699
|
+
event.preventDefault();
|
|
700
|
+
setOpen(true);
|
|
701
|
+
setActiveIndex(
|
|
702
|
+
(prev) => Math.min(filteredOptions.length - 1, prev + 1)
|
|
703
|
+
);
|
|
704
|
+
} else if (event.key === "ArrowUp") {
|
|
705
|
+
event.preventDefault();
|
|
706
|
+
setOpen(true);
|
|
707
|
+
setActiveIndex((prev) => Math.max(0, prev - 1));
|
|
708
|
+
} else if (event.key === "Enter") {
|
|
709
|
+
event.preventDefault();
|
|
710
|
+
if (!open) {
|
|
711
|
+
setOpen(true);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
const option = filteredOptions[activeIndex];
|
|
715
|
+
if (option) selectOption(option);
|
|
716
|
+
} else if (event.key === "Escape") {
|
|
717
|
+
setOpen(false);
|
|
718
|
+
} else if (event.key === "Backspace" && multiple && !currentQuery && values.length > 0) {
|
|
719
|
+
commitMany(values.slice(0, -1));
|
|
720
|
+
} else if (event.key === "Tab") {
|
|
721
|
+
setOpen(false);
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
placeholder: multiple && values.length > 0 ? "" : placeholder,
|
|
725
|
+
role: "combobox",
|
|
726
|
+
"aria-expanded": open,
|
|
727
|
+
"aria-controls": listboxId,
|
|
728
|
+
"aria-autocomplete": "list",
|
|
729
|
+
"aria-label": ariaLabel,
|
|
730
|
+
"aria-invalid": isInvalid,
|
|
731
|
+
disabled,
|
|
732
|
+
className: cx(
|
|
733
|
+
"h-8 w-full bg-transparent py-0 text-foreground outline-none placeholder:text-muted-foreground",
|
|
734
|
+
inputClassName
|
|
735
|
+
)
|
|
736
|
+
}
|
|
737
|
+
),
|
|
738
|
+
loading ? /* @__PURE__ */ jsx8(
|
|
739
|
+
Loader2,
|
|
740
|
+
{
|
|
741
|
+
className: "h-4 w-4 animate-spin text-muted-foreground",
|
|
742
|
+
"aria-hidden": "true"
|
|
743
|
+
}
|
|
744
|
+
) : null,
|
|
745
|
+
/* @__PURE__ */ jsx8("span", { className: "inline-flex h-8 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx8(
|
|
746
|
+
ChevronDown2,
|
|
747
|
+
{
|
|
748
|
+
strokeWidth: 2.5,
|
|
749
|
+
className: cx(
|
|
750
|
+
"h-5 w-5 text-muted-foreground transition-transform duration-200 ease-out",
|
|
751
|
+
open && "rotate-180"
|
|
752
|
+
),
|
|
753
|
+
"aria-hidden": "true"
|
|
754
|
+
}
|
|
755
|
+
) })
|
|
756
|
+
] })
|
|
757
|
+
]
|
|
758
|
+
}
|
|
759
|
+
),
|
|
760
|
+
open ? /* @__PURE__ */ jsx8(
|
|
761
|
+
"ul",
|
|
762
|
+
{
|
|
763
|
+
id: listboxId,
|
|
764
|
+
role: "listbox",
|
|
765
|
+
"aria-multiselectable": multiple || void 0,
|
|
766
|
+
className: cx(
|
|
767
|
+
"absolute left-0 right-0 top-full z-20 mt-1 max-h-60 overflow-y-auto rounded-md border border-border bg-background p-1 shadow-md",
|
|
768
|
+
menuClassName
|
|
769
|
+
),
|
|
770
|
+
children: loading ? /* @__PURE__ */ jsx8("li", { className: "px-3 py-2 text-sm text-muted-foreground", children: "Loading..." }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx8("li", { className: "px-3 py-2 text-sm text-muted-foreground", children: "No results" }) : filteredOptions.map((option, index) => {
|
|
771
|
+
const selected = isSelected(option);
|
|
772
|
+
const active = index === activeIndex;
|
|
773
|
+
return /* @__PURE__ */ jsx8(
|
|
774
|
+
"li",
|
|
775
|
+
{
|
|
776
|
+
role: "option",
|
|
777
|
+
"aria-selected": selected,
|
|
778
|
+
children: /* @__PURE__ */ jsxs6(
|
|
779
|
+
"button",
|
|
780
|
+
{
|
|
781
|
+
type: "button",
|
|
782
|
+
disabled: option.disabled,
|
|
783
|
+
onMouseEnter: () => setActiveIndex(index),
|
|
784
|
+
onClick: () => selectOption(option),
|
|
785
|
+
className: cx(
|
|
786
|
+
"flex w-full items-center justify-between rounded px-3 py-2 text-sm",
|
|
787
|
+
active ? "bg-surface" : "hover:bg-surface",
|
|
788
|
+
option.disabled && "cursor-not-allowed opacity-50"
|
|
789
|
+
),
|
|
790
|
+
children: [
|
|
791
|
+
renderOption ? renderOption(option, { selected, active }) : /* @__PURE__ */ jsx8("span", { className: "text-foreground", children: option.label }),
|
|
792
|
+
selected ? /* @__PURE__ */ jsx8(
|
|
793
|
+
Check,
|
|
794
|
+
{
|
|
795
|
+
className: "h-4 w-4 text-primary",
|
|
796
|
+
"aria-hidden": "true"
|
|
797
|
+
}
|
|
798
|
+
) : null
|
|
799
|
+
]
|
|
800
|
+
}
|
|
801
|
+
)
|
|
802
|
+
},
|
|
803
|
+
`${String(option.value)}-${index}`
|
|
804
|
+
);
|
|
805
|
+
})
|
|
806
|
+
}
|
|
807
|
+
) : null,
|
|
808
|
+
hint && !error ? /* @__PURE__ */ jsx8("p", { className: "mt-1 text-xs text-muted-foreground", children: hint }) : null,
|
|
809
|
+
error ? /* @__PURE__ */ jsx8("p", { className: "mt-1 text-xs text-danger", children: error }) : null
|
|
810
|
+
] });
|
|
811
|
+
};
|
|
812
|
+
var Combobox_default = Combobox;
|
|
813
|
+
|
|
814
|
+
// src/components/shared/patterns/forms/FormField/fields/ComboboxField/ComboboxField.tsx
|
|
815
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
816
|
+
var ComboboxField = ({
|
|
817
|
+
field,
|
|
818
|
+
value,
|
|
819
|
+
error,
|
|
820
|
+
onChange
|
|
821
|
+
}) => {
|
|
822
|
+
var _a, _b;
|
|
823
|
+
const isMultiple = Boolean(field.multiple);
|
|
824
|
+
const options = ((_a = field.options) != null ? _a : []).map((option) => ({
|
|
825
|
+
value: String(option.value),
|
|
826
|
+
label: option.label
|
|
827
|
+
}));
|
|
828
|
+
const emitChange = (nextValue) => {
|
|
829
|
+
const normalizedValue = nextValue == null ? "" : Array.isArray(nextValue) ? nextValue : String(nextValue);
|
|
830
|
+
onChange(createFormFieldChangeEvent(field.name, normalizedValue));
|
|
831
|
+
};
|
|
832
|
+
return /* @__PURE__ */ jsx9(
|
|
833
|
+
Combobox_default,
|
|
834
|
+
{
|
|
835
|
+
id: field.name,
|
|
836
|
+
name: field.name,
|
|
837
|
+
options,
|
|
838
|
+
multiple: isMultiple,
|
|
839
|
+
values: isMultiple ? value != null ? value : [] : [],
|
|
840
|
+
value: !isMultiple ? value != null ? value : null : null,
|
|
841
|
+
onChange: (next) => emitChange(next),
|
|
842
|
+
onChangeMany: (next) => emitChange(next),
|
|
843
|
+
placeholder: (_b = field.placeholder) != null ? _b : "Select...",
|
|
844
|
+
intent: error ? "danger" : "primary",
|
|
845
|
+
error,
|
|
846
|
+
inputClassName: "cursor-pointer",
|
|
847
|
+
"aria-label": field.label
|
|
848
|
+
}
|
|
849
|
+
);
|
|
850
|
+
};
|
|
851
|
+
var ComboboxField_default = ComboboxField;
|
|
852
|
+
|
|
853
|
+
// src/components/shared/patterns/forms/FormField/fields/DatePickerField/DatePickerField.tsx
|
|
854
|
+
import React7, { useEffect as useEffect5, useMemo as useMemo2, useState as useState3 } from "react";
|
|
855
|
+
|
|
856
|
+
// src/components/shared/primitives/actions/Button/Button.tsx
|
|
857
|
+
import { forwardRef as forwardRef3 } from "react";
|
|
858
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
859
|
+
var BASE_CLASSES = "relative inline-flex items-center justify-center overflow-hidden rounded-lg font-semibold cursor-pointer transition-all focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
|
860
|
+
var SIZE_CLASSES3 = {
|
|
861
|
+
xs: "h-7 px-2 text-xs",
|
|
862
|
+
sm: "h-8 px-3 text-sm",
|
|
863
|
+
md: "h-10 px-4 text-sm",
|
|
864
|
+
lg: "h-11 px-5 text-base"
|
|
865
|
+
};
|
|
866
|
+
var SOLID_INTENT_CLASSES = {
|
|
867
|
+
primary: "bg-primary text-primary-foreground border border-primary hover:bg-primary-hover hover:border-primary-hover",
|
|
868
|
+
secondary: "bg-secondary text-secondary-foreground border border-secondary hover:bg-secondary-hover hover:border-secondary-hover",
|
|
869
|
+
success: "bg-success text-success-foreground border border-success hover:bg-success-hover hover:border-success-hover",
|
|
870
|
+
warning: "bg-warning text-warning-foreground border border-warning hover:bg-warning-hover hover:border-warning-hover",
|
|
871
|
+
danger: "bg-danger text-danger-foreground border border-danger hover:bg-danger-hover hover:border-danger-hover",
|
|
872
|
+
info: "bg-info text-info-foreground border border-info hover:bg-info-hover hover:border-info-hover",
|
|
873
|
+
neutral: "bg-foreground text-background border border-foreground hover:opacity-90"
|
|
874
|
+
};
|
|
875
|
+
var OUTLINE_INTENT_CLASSES = {
|
|
876
|
+
primary: "bg-background text-primary border border-primary hover:bg-primary hover:text-primary-foreground",
|
|
877
|
+
secondary: "bg-background text-secondary border border-secondary hover:bg-secondary hover:text-secondary-foreground",
|
|
878
|
+
success: "bg-background text-success border border-success hover:bg-success hover:text-success-foreground",
|
|
879
|
+
warning: "bg-background text-warning border border-warning hover:bg-warning hover:text-warning-foreground",
|
|
880
|
+
danger: "bg-background text-danger border border-danger hover:bg-danger hover:text-danger-foreground",
|
|
881
|
+
info: "bg-background text-info border border-info hover:bg-info hover:text-info-foreground",
|
|
882
|
+
neutral: "bg-background text-foreground border border-border-strong hover:bg-surface"
|
|
883
|
+
};
|
|
884
|
+
var SOFT_INTENT_CLASSES = {
|
|
885
|
+
primary: "bg-primary-soft text-primary-soft-foreground border border-transparent hover:bg-primary-soft",
|
|
886
|
+
secondary: "bg-secondary-soft text-secondary-soft-foreground border border-transparent hover:bg-secondary-soft",
|
|
887
|
+
success: "bg-success-soft text-success-soft-foreground border border-transparent hover:bg-success-soft",
|
|
888
|
+
warning: "bg-warning-soft text-warning-soft-foreground border border-transparent hover:bg-warning-soft",
|
|
889
|
+
danger: "bg-danger-soft text-danger-soft-foreground border border-transparent hover:bg-danger-soft",
|
|
890
|
+
info: "bg-info-soft text-info-soft-foreground border border-transparent hover:bg-info-soft",
|
|
891
|
+
neutral: "bg-surface text-foreground border border-transparent hover:bg-surface-hover"
|
|
892
|
+
};
|
|
893
|
+
var GHOST_INTENT_CLASSES = {
|
|
894
|
+
primary: "bg-transparent text-ghost-primary-foreground border border-transparent hover:bg-ghost-primary-hover",
|
|
895
|
+
secondary: "bg-transparent text-ghost-secondary-foreground border border-transparent hover:bg-ghost-secondary-hover",
|
|
896
|
+
success: "bg-transparent text-ghost-success-foreground border border-transparent hover:bg-ghost-success-hover",
|
|
897
|
+
warning: "bg-transparent text-ghost-warning-foreground border border-transparent hover:bg-ghost-warning-hover",
|
|
898
|
+
danger: "bg-transparent text-ghost-danger-foreground border border-transparent hover:bg-ghost-danger-hover",
|
|
899
|
+
info: "bg-transparent text-ghost-info-foreground border border-transparent hover:bg-ghost-info-hover",
|
|
900
|
+
neutral: "bg-ghost text-ghost-foreground border border-ghost hover:bg-ghost-hover"
|
|
901
|
+
};
|
|
902
|
+
var GLASS_INTENT_CLASSES = {
|
|
903
|
+
primary: "bg-primary/20 text-primary-soft-foreground border border-glass-border hover:bg-primary/30",
|
|
904
|
+
secondary: "bg-secondary/20 text-secondary-soft-foreground border border-glass-border hover:bg-secondary/30",
|
|
905
|
+
success: "bg-success/20 text-success-soft-foreground border border-glass-border hover:bg-success/30",
|
|
906
|
+
warning: "bg-warning/20 text-warning-soft-foreground border border-glass-border hover:bg-warning/30",
|
|
907
|
+
danger: "bg-danger/20 text-danger-soft-foreground border border-glass-border hover:bg-danger/30",
|
|
908
|
+
info: "bg-info/20 text-info-soft-foreground border border-glass-border hover:bg-info/30",
|
|
909
|
+
neutral: "bg-glass-bg text-foreground border border-glass-border hover:border-glass-highlight"
|
|
910
|
+
};
|
|
911
|
+
var GLASS_LAYER_CLASSES = "before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:bg-glass-highlight before:opacity-25";
|
|
912
|
+
var VARIANT_BY_KIND = {
|
|
913
|
+
solid: SOLID_INTENT_CLASSES,
|
|
914
|
+
outline: OUTLINE_INTENT_CLASSES,
|
|
915
|
+
ghost: GHOST_INTENT_CLASSES,
|
|
916
|
+
soft: SOFT_INTENT_CLASSES,
|
|
917
|
+
glass: GLASS_INTENT_CLASSES,
|
|
918
|
+
"reverse-primary": OUTLINE_INTENT_CLASSES,
|
|
919
|
+
"reverse-secondary": OUTLINE_INTENT_CLASSES
|
|
920
|
+
};
|
|
921
|
+
var resolveVariant = (intent, variant) => {
|
|
922
|
+
const safeVariant = variant != null ? variant : "solid";
|
|
923
|
+
if (safeVariant === "reverse-primary") {
|
|
924
|
+
return { intent: "primary", variant: "outline" };
|
|
925
|
+
}
|
|
926
|
+
if (safeVariant === "reverse-secondary") {
|
|
927
|
+
return { intent: "secondary", variant: "outline" };
|
|
928
|
+
}
|
|
929
|
+
return { intent, variant: safeVariant };
|
|
930
|
+
};
|
|
931
|
+
var Button = forwardRef3(
|
|
932
|
+
(_a, ref) => {
|
|
933
|
+
var _b = _a, {
|
|
934
|
+
type = "button",
|
|
935
|
+
intent = "primary",
|
|
936
|
+
variant = "solid",
|
|
937
|
+
size = "md",
|
|
938
|
+
loading = false,
|
|
939
|
+
disabled,
|
|
940
|
+
className,
|
|
941
|
+
children
|
|
942
|
+
} = _b, props = __objRest(_b, [
|
|
943
|
+
"type",
|
|
944
|
+
"intent",
|
|
945
|
+
"variant",
|
|
946
|
+
"size",
|
|
947
|
+
"loading",
|
|
948
|
+
"disabled",
|
|
949
|
+
"className",
|
|
950
|
+
"children"
|
|
951
|
+
]);
|
|
952
|
+
const resolved = resolveVariant(intent, variant);
|
|
953
|
+
const isDisabled = disabled || loading;
|
|
954
|
+
return /* @__PURE__ */ jsx10(
|
|
955
|
+
"button",
|
|
956
|
+
__spreadProps(__spreadValues({
|
|
957
|
+
ref,
|
|
958
|
+
type,
|
|
959
|
+
className: cx(
|
|
960
|
+
BASE_CLASSES,
|
|
961
|
+
SIZE_CLASSES3[size],
|
|
962
|
+
VARIANT_BY_KIND[resolved.variant][resolved.intent],
|
|
963
|
+
resolved.variant === "glass" && GLASS_LAYER_CLASSES,
|
|
964
|
+
className
|
|
965
|
+
),
|
|
966
|
+
disabled: isDisabled,
|
|
967
|
+
"aria-busy": loading || void 0
|
|
968
|
+
}, props), {
|
|
969
|
+
children: /* @__PURE__ */ jsxs7("span", { className: "relative inline-flex items-center gap-2 leading-none", children: [
|
|
970
|
+
loading && /* @__PURE__ */ jsx10(
|
|
971
|
+
"span",
|
|
972
|
+
{
|
|
973
|
+
className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-current border-r-transparent",
|
|
974
|
+
"aria-hidden": "true"
|
|
975
|
+
}
|
|
976
|
+
),
|
|
977
|
+
renderBindableNode(children)
|
|
978
|
+
] })
|
|
979
|
+
})
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
);
|
|
983
|
+
Button.displayName = "Button";
|
|
984
|
+
var Button_default = Button;
|
|
985
|
+
|
|
986
|
+
// src/components/shared/primitives/actions/Button/index.tsx
|
|
987
|
+
var Button_default2 = Button_default;
|
|
988
|
+
|
|
989
|
+
// src/components/shared/overlays/modals/Popin/Popin.tsx
|
|
990
|
+
import { X as X2 } from "lucide-react";
|
|
991
|
+
import {
|
|
992
|
+
useEffect as useEffect4,
|
|
993
|
+
useId as useId2,
|
|
994
|
+
useRef as useRef4,
|
|
995
|
+
useState as useState2
|
|
996
|
+
} from "react";
|
|
997
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
998
|
+
var MAX_SIZE_MAP = {
|
|
999
|
+
sm: "24rem",
|
|
1000
|
+
md: "28rem",
|
|
1001
|
+
lg: "32rem",
|
|
1002
|
+
xl: "36rem",
|
|
1003
|
+
"2xl": "42rem",
|
|
1004
|
+
full: "100vw"
|
|
1005
|
+
};
|
|
1006
|
+
var Popin = ({
|
|
1007
|
+
displayedPopin,
|
|
1008
|
+
children,
|
|
1009
|
+
setDisplayedPopin,
|
|
1010
|
+
title,
|
|
1011
|
+
closeText,
|
|
1012
|
+
hasCloseAvailability = true,
|
|
1013
|
+
closeOnOutsideClick = true,
|
|
1014
|
+
maxSize = "2xl",
|
|
1015
|
+
actionText,
|
|
1016
|
+
onAction,
|
|
1017
|
+
requireScrollToEnableAction = false
|
|
1018
|
+
}) => {
|
|
1019
|
+
const rawCloseOnOutsideClick = closeOnOutsideClick;
|
|
1020
|
+
const normalizedCloseOnOutsideClick = typeof rawCloseOnOutsideClick === "string" ? rawCloseOnOutsideClick.toLowerCase() !== "false" : Boolean(rawCloseOnOutsideClick);
|
|
1021
|
+
const titleId = useId2();
|
|
1022
|
+
const scrollRef = useRef4(null);
|
|
1023
|
+
const [hasScrolledToBottom, setHasScrolledToBottom] = useState2(
|
|
1024
|
+
!requireScrollToEnableAction
|
|
1025
|
+
);
|
|
1026
|
+
useEventListener_default("keydown", (event) => {
|
|
1027
|
+
if (!displayedPopin || !hasCloseAvailability) return;
|
|
1028
|
+
if (event.key === "Escape") {
|
|
1029
|
+
event.preventDefault();
|
|
1030
|
+
setDisplayedPopin(false);
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
useEffect4(() => {
|
|
1034
|
+
var _a;
|
|
1035
|
+
if (!displayedPopin) return;
|
|
1036
|
+
setHasScrolledToBottom(!requireScrollToEnableAction);
|
|
1037
|
+
(_a = scrollRef.current) == null ? void 0 : _a.scrollTo({ top: 0 });
|
|
1038
|
+
if (requireScrollToEnableAction) {
|
|
1039
|
+
queueMicrotask(() => {
|
|
1040
|
+
const el = scrollRef.current;
|
|
1041
|
+
if (!el) return;
|
|
1042
|
+
const noScrollNeeded = el.scrollHeight <= el.clientHeight + 1;
|
|
1043
|
+
if (noScrollNeeded) {
|
|
1044
|
+
setHasScrolledToBottom(true);
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
}, [displayedPopin, requireScrollToEnableAction]);
|
|
1049
|
+
const handleScroll = () => {
|
|
1050
|
+
if (!requireScrollToEnableAction) return;
|
|
1051
|
+
const el = scrollRef.current;
|
|
1052
|
+
if (!el) return;
|
|
1053
|
+
const isBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 4;
|
|
1054
|
+
if (isBottom) setHasScrolledToBottom(true);
|
|
1055
|
+
};
|
|
1056
|
+
if (!displayedPopin) return null;
|
|
1057
|
+
const dialogStyle = {
|
|
1058
|
+
maxWidth: maxSize === "full" ? "calc(100vw - 2rem)" : `min(${MAX_SIZE_MAP[maxSize]}, calc(100vw - 2rem))`
|
|
1059
|
+
};
|
|
1060
|
+
return /* @__PURE__ */ jsxs8("div", { className: "fixed inset-0 z-[9999] flex items-center justify-center px-4", children: [
|
|
1061
|
+
/* @__PURE__ */ jsx11(
|
|
1062
|
+
"div",
|
|
1063
|
+
{
|
|
1064
|
+
className: "absolute inset-0 bg-foreground/40 opacity-50",
|
|
1065
|
+
onMouseDown: (event) => {
|
|
1066
|
+
event.preventDefault();
|
|
1067
|
+
event.stopPropagation();
|
|
1068
|
+
},
|
|
1069
|
+
onClick: (event) => {
|
|
1070
|
+
event.preventDefault();
|
|
1071
|
+
event.stopPropagation();
|
|
1072
|
+
if (hasCloseAvailability && normalizedCloseOnOutsideClick) {
|
|
1073
|
+
setDisplayedPopin(false);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
),
|
|
1078
|
+
/* @__PURE__ */ jsxs8(
|
|
1079
|
+
"div",
|
|
1080
|
+
{
|
|
1081
|
+
role: "dialog",
|
|
1082
|
+
"aria-modal": "true",
|
|
1083
|
+
"aria-labelledby": titleId,
|
|
1084
|
+
className: "relative z-10 flex w-fit max-h-[72vh] max-w-full min-w-0 flex-col rounded border-2 border-border bg-surface-hover sm:max-h-[85vh]",
|
|
1085
|
+
style: dialogStyle,
|
|
1086
|
+
onClick: (event) => event.stopPropagation(),
|
|
1087
|
+
children: [
|
|
1088
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-3 border-b border-border px-6 py-4", children: [
|
|
1089
|
+
/* @__PURE__ */ jsx11(
|
|
1090
|
+
"h3",
|
|
1091
|
+
{
|
|
1092
|
+
id: titleId,
|
|
1093
|
+
className: "min-w-0 flex-1 break-words text-lg font-semibold text-primary",
|
|
1094
|
+
children: title
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
hasCloseAvailability && /* @__PURE__ */ jsx11(
|
|
1098
|
+
Button_default2,
|
|
1099
|
+
{
|
|
1100
|
+
type: "button",
|
|
1101
|
+
variant: "reverse-primary",
|
|
1102
|
+
onClick: () => setDisplayedPopin(false),
|
|
1103
|
+
"aria-label": typeof closeText === "string" ? closeText : "Close",
|
|
1104
|
+
className: "bg-transparent border-0 p-0 focus-visible:ring-offset-0",
|
|
1105
|
+
children: /* @__PURE__ */ jsx11(X2, { size: 20, "aria-hidden": "true" })
|
|
1106
|
+
}
|
|
1107
|
+
)
|
|
1108
|
+
] }),
|
|
1109
|
+
/* @__PURE__ */ jsx11(
|
|
1110
|
+
"div",
|
|
1111
|
+
{
|
|
1112
|
+
ref: scrollRef,
|
|
1113
|
+
onScroll: handleScroll,
|
|
1114
|
+
className: "min-h-0 overflow-x-auto overflow-y-auto break-words px-6 py-4",
|
|
1115
|
+
children
|
|
1116
|
+
}
|
|
1117
|
+
),
|
|
1118
|
+
actionText && /* @__PURE__ */ jsx11("div", { className: "flex justify-end px-6 py-4 border-t border-border bg-surface-hover", children: /* @__PURE__ */ jsx11(
|
|
1119
|
+
Button_default2,
|
|
1120
|
+
{
|
|
1121
|
+
onClick: onAction,
|
|
1122
|
+
disabled: requireScrollToEnableAction && !hasScrolledToBottom || !onAction,
|
|
1123
|
+
children: actionText
|
|
1124
|
+
}
|
|
1125
|
+
) })
|
|
1126
|
+
]
|
|
1127
|
+
}
|
|
1128
|
+
)
|
|
1129
|
+
] });
|
|
1130
|
+
};
|
|
1131
|
+
var Popin_default = Popin;
|
|
1132
|
+
|
|
1133
|
+
// src/components/shared/overlays/modals/Popin/index.ts
|
|
1134
|
+
var Popin_default2 = Popin_default;
|
|
1135
|
+
|
|
1136
|
+
// src/components/shared/patterns/forms/FormField/fields/DatePickerField/DatePickerField.tsx
|
|
1137
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1138
|
+
var ITEM_HEIGHT = 42;
|
|
1139
|
+
var WheelPickerColumn = ({
|
|
1140
|
+
label,
|
|
1141
|
+
items,
|
|
1142
|
+
selectedValue,
|
|
1143
|
+
onChange
|
|
1144
|
+
}) => {
|
|
1145
|
+
const wheelRef = React7.useRef(null);
|
|
1146
|
+
useEffect5(() => {
|
|
1147
|
+
const index = items.findIndex((item) => item.value === selectedValue);
|
|
1148
|
+
if (index < 0 || !wheelRef.current) return;
|
|
1149
|
+
wheelRef.current.scrollTo({
|
|
1150
|
+
top: index * ITEM_HEIGHT,
|
|
1151
|
+
behavior: "smooth"
|
|
1152
|
+
});
|
|
1153
|
+
}, [items, selectedValue]);
|
|
1154
|
+
return /* @__PURE__ */ jsxs9("div", { className: "min-w-20 flex flex-col gap-1", children: [
|
|
1155
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-semibold text-foreground", children: label }),
|
|
1156
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative", children: [
|
|
1157
|
+
/* @__PURE__ */ jsx12("div", { className: "pointer-events-none absolute left-0 right-0 top-1/2 z-10 h-10 -translate-y-1/2 rounded border border-primary/30 bg-primary/5" }),
|
|
1158
|
+
/* @__PURE__ */ jsx12(
|
|
1159
|
+
"div",
|
|
1160
|
+
{
|
|
1161
|
+
ref: wheelRef,
|
|
1162
|
+
role: "listbox",
|
|
1163
|
+
"aria-label": `${label} wheel picker`,
|
|
1164
|
+
className: "h-52 overflow-y-auto rounded border border-border bg-background snap-y snap-mandatory",
|
|
1165
|
+
onScroll: (event) => {
|
|
1166
|
+
const target = event.currentTarget;
|
|
1167
|
+
const index = Math.round(target.scrollTop / ITEM_HEIGHT);
|
|
1168
|
+
const clampedIndex = Math.max(0, Math.min(items.length - 1, index));
|
|
1169
|
+
const next = items[clampedIndex];
|
|
1170
|
+
if (next && next.value !== selectedValue) {
|
|
1171
|
+
onChange(next.value);
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
children: items.map((item) => /* @__PURE__ */ jsx12(
|
|
1175
|
+
"button",
|
|
1176
|
+
{
|
|
1177
|
+
type: "button",
|
|
1178
|
+
role: "option",
|
|
1179
|
+
"aria-selected": item.value === selectedValue,
|
|
1180
|
+
className: `flex h-10 w-full snap-start items-center justify-center text-sm ${item.value === selectedValue ? "font-semibold text-primary" : "text-muted-foreground"}`,
|
|
1181
|
+
onClick: () => onChange(item.value),
|
|
1182
|
+
children: item.label
|
|
1183
|
+
},
|
|
1184
|
+
`${label}-${item.value}`
|
|
1185
|
+
))
|
|
1186
|
+
}
|
|
1187
|
+
)
|
|
1188
|
+
] })
|
|
1189
|
+
] });
|
|
1190
|
+
};
|
|
1191
|
+
var DatePickerField = ({
|
|
1192
|
+
field,
|
|
1193
|
+
value,
|
|
1194
|
+
error,
|
|
1195
|
+
errorId,
|
|
1196
|
+
onChange
|
|
1197
|
+
}) => {
|
|
1198
|
+
var _a;
|
|
1199
|
+
const safeValue = String((_a = getSafeValue(value)) != null ? _a : "");
|
|
1200
|
+
const [isMobilePicker, setIsMobilePicker] = useState3(false);
|
|
1201
|
+
const [isPopinOpen, setIsPopinOpen] = useState3(false);
|
|
1202
|
+
const today = useMemo2(() => /* @__PURE__ */ new Date(), []);
|
|
1203
|
+
const defaultYear = today.getFullYear();
|
|
1204
|
+
const [selectedYear, setSelectedYear] = useState3(defaultYear);
|
|
1205
|
+
const [selectedMonth, setSelectedMonth] = useState3(today.getMonth() + 1);
|
|
1206
|
+
const [selectedDay, setSelectedDay] = useState3(today.getDate());
|
|
1207
|
+
useEffect5(() => {
|
|
1208
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
const media = window.matchMedia("(max-width: 768px), (pointer: coarse)");
|
|
1212
|
+
const update = () => setIsMobilePicker(media.matches);
|
|
1213
|
+
update();
|
|
1214
|
+
media.addEventListener("change", update);
|
|
1215
|
+
return () => media.removeEventListener("change", update);
|
|
1216
|
+
}, []);
|
|
1217
|
+
const parseDate = (dateString) => {
|
|
1218
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
|
|
1219
|
+
if (!match) return null;
|
|
1220
|
+
return {
|
|
1221
|
+
year: Number(match[1]),
|
|
1222
|
+
month: Number(match[2]),
|
|
1223
|
+
day: Number(match[3])
|
|
1224
|
+
};
|
|
1225
|
+
};
|
|
1226
|
+
const daysInSelectedMonth = new Date(
|
|
1227
|
+
selectedYear,
|
|
1228
|
+
selectedMonth,
|
|
1229
|
+
0
|
|
1230
|
+
).getDate();
|
|
1231
|
+
const years = useMemo2(() => {
|
|
1232
|
+
const start = defaultYear - 100;
|
|
1233
|
+
const end = defaultYear + 20;
|
|
1234
|
+
return Array.from({ length: end - start + 1 }, (_, index) => start + index);
|
|
1235
|
+
}, [defaultYear]);
|
|
1236
|
+
const days = useMemo2(
|
|
1237
|
+
() => Array.from({ length: daysInSelectedMonth }, (_, index) => index + 1),
|
|
1238
|
+
[daysInSelectedMonth]
|
|
1239
|
+
);
|
|
1240
|
+
const formattedValue = useMemo2(() => {
|
|
1241
|
+
const parsed = parseDate(safeValue);
|
|
1242
|
+
if (!parsed) return safeValue;
|
|
1243
|
+
return `${String(parsed.day).padStart(2, "0")}/${String(parsed.month).padStart(2, "0")}/${parsed.year}`;
|
|
1244
|
+
}, [safeValue]);
|
|
1245
|
+
const openMobilePicker = () => {
|
|
1246
|
+
const parsed = parseDate(safeValue);
|
|
1247
|
+
if (parsed) {
|
|
1248
|
+
setSelectedYear(parsed.year);
|
|
1249
|
+
setSelectedMonth(parsed.month);
|
|
1250
|
+
setSelectedDay(parsed.day);
|
|
1251
|
+
}
|
|
1252
|
+
setIsPopinOpen(true);
|
|
1253
|
+
};
|
|
1254
|
+
const emitDate = (nextValue) => {
|
|
1255
|
+
onChange(createFormFieldChangeEvent(field.name, nextValue));
|
|
1256
|
+
};
|
|
1257
|
+
const applyMobilePicker = () => {
|
|
1258
|
+
const safeDay = Math.min(selectedDay, daysInSelectedMonth);
|
|
1259
|
+
const isoDate = `${selectedYear}-${String(selectedMonth).padStart(2, "0")}-${String(safeDay).padStart(2, "0")}`;
|
|
1260
|
+
emitDate(isoDate);
|
|
1261
|
+
setIsPopinOpen(false);
|
|
1262
|
+
};
|
|
1263
|
+
if (isMobilePicker) {
|
|
1264
|
+
return /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
1265
|
+
/* @__PURE__ */ jsx12(
|
|
1266
|
+
"button",
|
|
1267
|
+
{
|
|
1268
|
+
type: "button",
|
|
1269
|
+
onClick: openMobilePicker,
|
|
1270
|
+
className: `mt-1 w-full rounded-md border bg-background px-3 py-2 text-left text-sm outline-none focus-visible:ring-2 ${error ? "border-danger focus-visible:ring-danger/40" : "border-border-strong focus-visible:ring-ring"}`,
|
|
1271
|
+
"aria-invalid": Boolean(error),
|
|
1272
|
+
"aria-describedby": errorId,
|
|
1273
|
+
children: formattedValue || field.placeholder || "Select a date"
|
|
1274
|
+
}
|
|
1275
|
+
),
|
|
1276
|
+
/* @__PURE__ */ jsx12(
|
|
1277
|
+
Popin_default2,
|
|
1278
|
+
{
|
|
1279
|
+
displayedPopin: isPopinOpen,
|
|
1280
|
+
setDisplayedPopin: setIsPopinOpen,
|
|
1281
|
+
title: field.label,
|
|
1282
|
+
closeText: "Close date picker",
|
|
1283
|
+
actionText: "Apply",
|
|
1284
|
+
onAction: applyMobilePicker,
|
|
1285
|
+
maxSize: "full",
|
|
1286
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex gap-3 overflow-x-auto", children: [
|
|
1287
|
+
/* @__PURE__ */ jsx12(
|
|
1288
|
+
WheelPickerColumn,
|
|
1289
|
+
{
|
|
1290
|
+
label: "Day",
|
|
1291
|
+
items: days.map((day) => ({
|
|
1292
|
+
value: day,
|
|
1293
|
+
label: String(day).padStart(2, "0")
|
|
1294
|
+
})),
|
|
1295
|
+
selectedValue: selectedDay,
|
|
1296
|
+
onChange: setSelectedDay
|
|
1297
|
+
}
|
|
1298
|
+
),
|
|
1299
|
+
/* @__PURE__ */ jsx12(
|
|
1300
|
+
WheelPickerColumn,
|
|
1301
|
+
{
|
|
1302
|
+
label: "Month",
|
|
1303
|
+
items: Array.from({ length: 12 }, (_, index) => ({
|
|
1304
|
+
value: index + 1,
|
|
1305
|
+
label: String(index + 1).padStart(2, "0")
|
|
1306
|
+
})),
|
|
1307
|
+
selectedValue: selectedMonth,
|
|
1308
|
+
onChange: setSelectedMonth
|
|
1309
|
+
}
|
|
1310
|
+
),
|
|
1311
|
+
/* @__PURE__ */ jsx12(
|
|
1312
|
+
WheelPickerColumn,
|
|
1313
|
+
{
|
|
1314
|
+
label: "Year",
|
|
1315
|
+
items: years.map((year) => ({
|
|
1316
|
+
value: year,
|
|
1317
|
+
label: String(year)
|
|
1318
|
+
})),
|
|
1319
|
+
selectedValue: selectedYear,
|
|
1320
|
+
onChange: setSelectedYear
|
|
1321
|
+
}
|
|
1322
|
+
)
|
|
1323
|
+
] })
|
|
1324
|
+
}
|
|
1325
|
+
)
|
|
1326
|
+
] });
|
|
1327
|
+
}
|
|
1328
|
+
return /* @__PURE__ */ jsx12(
|
|
1329
|
+
Input_default,
|
|
1330
|
+
{
|
|
1331
|
+
id: field.name,
|
|
1332
|
+
type: "date",
|
|
1333
|
+
name: field.name,
|
|
1334
|
+
value: safeValue,
|
|
1335
|
+
onChange,
|
|
1336
|
+
"aria-invalid": Boolean(error),
|
|
1337
|
+
"aria-describedby": errorId,
|
|
1338
|
+
intent: error ? "danger" : "neutral",
|
|
1339
|
+
className: "mt-1"
|
|
1340
|
+
}
|
|
1341
|
+
);
|
|
1342
|
+
};
|
|
1343
|
+
var DatePickerField_default = DatePickerField;
|
|
1344
|
+
|
|
1345
|
+
// src/components/shared/patterns/forms/FormField/fields/DatePickerField/index.tsx
|
|
1346
|
+
var DatePickerField_default2 = DatePickerField_default;
|
|
1347
|
+
|
|
1348
|
+
// src/components/shared/media/upload/fields/FileUpload/FileUpload.tsx
|
|
1349
|
+
import { useEffect as useEffect6, useId as useId3, useMemo as useMemo3, useState as useState4 } from "react";
|
|
1350
|
+
import { Upload, X as X3 } from "lucide-react";
|
|
1351
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1352
|
+
var VARIANT_CLASSES2 = {
|
|
1353
|
+
solid: {
|
|
1354
|
+
primary: "bg-primary-soft border-primary text-primary-soft-foreground",
|
|
1355
|
+
secondary: "bg-secondary-soft border-secondary text-secondary-soft-foreground",
|
|
1356
|
+
success: "bg-success-soft border-success text-success-soft-foreground",
|
|
1357
|
+
warning: "bg-warning-soft border-warning text-warning-soft-foreground",
|
|
1358
|
+
danger: "bg-danger-soft border-danger text-danger-soft-foreground",
|
|
1359
|
+
info: "bg-info-soft border-info text-info-soft-foreground",
|
|
1360
|
+
neutral: "bg-surface border-border text-foreground"
|
|
1361
|
+
},
|
|
1362
|
+
outline: {
|
|
1363
|
+
primary: "bg-background border-primary text-primary",
|
|
1364
|
+
secondary: "bg-background border-secondary text-secondary",
|
|
1365
|
+
success: "bg-background border-success text-success",
|
|
1366
|
+
warning: "bg-background border-warning text-warning",
|
|
1367
|
+
danger: "bg-background border-danger text-danger",
|
|
1368
|
+
info: "bg-background border-info text-info",
|
|
1369
|
+
neutral: "bg-background border-border text-foreground"
|
|
1370
|
+
},
|
|
1371
|
+
ghost: {
|
|
1372
|
+
primary: "bg-transparent border-transparent text-ghost-primary-foreground hover:bg-ghost-primary-hover",
|
|
1373
|
+
secondary: "bg-transparent border-transparent text-ghost-secondary-foreground hover:bg-ghost-secondary-hover",
|
|
1374
|
+
success: "bg-transparent border-transparent text-ghost-success-foreground hover:bg-ghost-success-hover",
|
|
1375
|
+
warning: "bg-transparent border-transparent text-ghost-warning-foreground hover:bg-ghost-warning-hover",
|
|
1376
|
+
danger: "bg-transparent border-transparent text-ghost-danger-foreground hover:bg-ghost-danger-hover",
|
|
1377
|
+
info: "bg-transparent border-transparent text-ghost-info-foreground hover:bg-ghost-info-hover",
|
|
1378
|
+
neutral: "bg-transparent border-transparent text-ghost-foreground hover:bg-ghost-hover"
|
|
1379
|
+
},
|
|
1380
|
+
soft: {
|
|
1381
|
+
primary: "bg-primary-soft border-transparent text-primary-soft-foreground",
|
|
1382
|
+
secondary: "bg-secondary-soft border-transparent text-secondary-soft-foreground",
|
|
1383
|
+
success: "bg-success-soft border-transparent text-success-soft-foreground",
|
|
1384
|
+
warning: "bg-warning-soft border-transparent text-warning-soft-foreground",
|
|
1385
|
+
danger: "bg-danger-soft border-transparent text-danger-soft-foreground",
|
|
1386
|
+
info: "bg-info-soft border-transparent text-info-soft-foreground",
|
|
1387
|
+
neutral: "bg-surface border-transparent text-foreground"
|
|
1388
|
+
},
|
|
1389
|
+
glass: {
|
|
1390
|
+
primary: "bg-primary/20 border-glass-border text-primary-soft-foreground shadow-glass",
|
|
1391
|
+
secondary: "bg-secondary/20 border-glass-border text-secondary-soft-foreground shadow-glass",
|
|
1392
|
+
success: "bg-success/20 border-glass-border text-success-soft-foreground shadow-glass",
|
|
1393
|
+
warning: "bg-warning/20 border-glass-border text-warning-soft-foreground shadow-glass",
|
|
1394
|
+
danger: "bg-danger/20 border-glass-border text-danger-soft-foreground shadow-glass",
|
|
1395
|
+
info: "bg-info/20 border-glass-border text-info-soft-foreground shadow-glass",
|
|
1396
|
+
neutral: "bg-glass-bg border-glass-border text-foreground shadow-glass"
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
var matchesAccept = (file, accept) => {
|
|
1400
|
+
if (!accept) return true;
|
|
1401
|
+
const accepted = accept.split(",").map((item) => item.trim().toLowerCase());
|
|
1402
|
+
const fileType = file.type.toLowerCase();
|
|
1403
|
+
const fileName = file.name.toLowerCase();
|
|
1404
|
+
return accepted.some((rule) => {
|
|
1405
|
+
if (rule.startsWith(".")) return fileName.endsWith(rule);
|
|
1406
|
+
if (rule.endsWith("/*")) return fileType.startsWith(rule.slice(0, -1));
|
|
1407
|
+
return fileType === rule;
|
|
1408
|
+
});
|
|
1409
|
+
};
|
|
1410
|
+
var getPreviewKind = (file) => {
|
|
1411
|
+
if (file.type.startsWith("image/")) return "image";
|
|
1412
|
+
if (file.type.startsWith("video/")) return "video";
|
|
1413
|
+
return null;
|
|
1414
|
+
};
|
|
1415
|
+
var createPreviewUrl = (file) => {
|
|
1416
|
+
if (typeof URL === "undefined" || typeof URL.createObjectURL !== "function") return null;
|
|
1417
|
+
return URL.createObjectURL(file);
|
|
1418
|
+
};
|
|
1419
|
+
var revokePreviewUrl = (url) => {
|
|
1420
|
+
if (!url) return;
|
|
1421
|
+
if (typeof URL === "undefined" || typeof URL.revokeObjectURL !== "function") return;
|
|
1422
|
+
URL.revokeObjectURL(url);
|
|
1423
|
+
};
|
|
1424
|
+
var FileUpload = ({
|
|
1425
|
+
value,
|
|
1426
|
+
onChange,
|
|
1427
|
+
multiple = true,
|
|
1428
|
+
accept,
|
|
1429
|
+
maxFiles,
|
|
1430
|
+
maxSizeBytes,
|
|
1431
|
+
disabled = false,
|
|
1432
|
+
renderFile,
|
|
1433
|
+
onReject,
|
|
1434
|
+
intent = "neutral",
|
|
1435
|
+
variant = "outline",
|
|
1436
|
+
className
|
|
1437
|
+
}) => {
|
|
1438
|
+
var _a;
|
|
1439
|
+
const inputId = useId3();
|
|
1440
|
+
const files = useMemo3(() => value != null ? value : [], [value]);
|
|
1441
|
+
const [dragActive, setDragActive] = useState4(false);
|
|
1442
|
+
const [previewOpen, setPreviewOpen] = useState4(false);
|
|
1443
|
+
const [activePreview, setActivePreview] = useState4(null);
|
|
1444
|
+
const previews = useMemo3(
|
|
1445
|
+
() => files.map((file) => {
|
|
1446
|
+
const kind = getPreviewKind(file);
|
|
1447
|
+
return {
|
|
1448
|
+
file,
|
|
1449
|
+
kind,
|
|
1450
|
+
url: kind ? createPreviewUrl(file) : null
|
|
1451
|
+
};
|
|
1452
|
+
}),
|
|
1453
|
+
[files]
|
|
1454
|
+
);
|
|
1455
|
+
useEffect6(
|
|
1456
|
+
() => () => {
|
|
1457
|
+
previews.forEach((preview) => {
|
|
1458
|
+
revokePreviewUrl(preview.url);
|
|
1459
|
+
});
|
|
1460
|
+
},
|
|
1461
|
+
[previews]
|
|
1462
|
+
);
|
|
1463
|
+
const normalizeFiles = (incomingFiles) => {
|
|
1464
|
+
const next = [];
|
|
1465
|
+
for (const file of incomingFiles) {
|
|
1466
|
+
if (!matchesAccept(file, accept)) {
|
|
1467
|
+
onReject == null ? void 0 : onReject({ type: "accept", file });
|
|
1468
|
+
continue;
|
|
1469
|
+
}
|
|
1470
|
+
if (typeof maxSizeBytes === "number" && file.size > maxSizeBytes) {
|
|
1471
|
+
onReject == null ? void 0 : onReject({ type: "maxSize", file });
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
next.push(file);
|
|
1475
|
+
}
|
|
1476
|
+
const merged = multiple ? [...files, ...next] : next.slice(0, 1);
|
|
1477
|
+
if (typeof maxFiles === "number" && merged.length > maxFiles) {
|
|
1478
|
+
onReject == null ? void 0 : onReject({ type: "maxFiles" });
|
|
1479
|
+
return merged.slice(0, maxFiles);
|
|
1480
|
+
}
|
|
1481
|
+
return merged;
|
|
1482
|
+
};
|
|
1483
|
+
const commitFiles = (incomingFiles) => {
|
|
1484
|
+
const normalized = normalizeFiles(incomingFiles);
|
|
1485
|
+
onChange(normalized);
|
|
1486
|
+
};
|
|
1487
|
+
return /* @__PURE__ */ jsxs10("div", { className: cx("space-y-3", className), children: [
|
|
1488
|
+
/* @__PURE__ */ jsxs10(
|
|
1489
|
+
"label",
|
|
1490
|
+
{
|
|
1491
|
+
htmlFor: inputId,
|
|
1492
|
+
onDragOver: (event) => {
|
|
1493
|
+
event.preventDefault();
|
|
1494
|
+
if (!disabled) setDragActive(true);
|
|
1495
|
+
},
|
|
1496
|
+
onDragLeave: () => setDragActive(false),
|
|
1497
|
+
onDrop: (event) => {
|
|
1498
|
+
event.preventDefault();
|
|
1499
|
+
setDragActive(false);
|
|
1500
|
+
if (disabled) return;
|
|
1501
|
+
const dropped = Array.from(event.dataTransfer.files);
|
|
1502
|
+
if (dropped.length) commitFiles(dropped);
|
|
1503
|
+
},
|
|
1504
|
+
className: cx(
|
|
1505
|
+
"flex min-h-28 cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-4 text-center transition-colors",
|
|
1506
|
+
VARIANT_CLASSES2[variant][intent],
|
|
1507
|
+
dragActive && "border-primary bg-primary-soft",
|
|
1508
|
+
disabled && "cursor-not-allowed opacity-60"
|
|
1509
|
+
),
|
|
1510
|
+
children: [
|
|
1511
|
+
/* @__PURE__ */ jsx13(Upload, { className: "h-5 w-5", "aria-hidden": "true" }),
|
|
1512
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium text-foreground", children: "Drop files here or click to upload" }),
|
|
1513
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-xs text-muted-foreground", children: [
|
|
1514
|
+
accept ? `Accepted: ${accept}` : "All file types",
|
|
1515
|
+
"."
|
|
1516
|
+
] })
|
|
1517
|
+
]
|
|
1518
|
+
}
|
|
1519
|
+
),
|
|
1520
|
+
/* @__PURE__ */ jsx13(
|
|
1521
|
+
"input",
|
|
1522
|
+
{
|
|
1523
|
+
id: inputId,
|
|
1524
|
+
type: "file",
|
|
1525
|
+
accept,
|
|
1526
|
+
multiple,
|
|
1527
|
+
disabled,
|
|
1528
|
+
className: "sr-only",
|
|
1529
|
+
onChange: (event) => {
|
|
1530
|
+
var _a2;
|
|
1531
|
+
const selected = Array.from((_a2 = event.target.files) != null ? _a2 : []);
|
|
1532
|
+
if (selected.length) commitFiles(selected);
|
|
1533
|
+
event.currentTarget.value = "";
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
),
|
|
1537
|
+
files.length > 0 ? /* @__PURE__ */ jsx13("div", { className: "flex flex-wrap justify-center gap-3", children: previews.map(({ file, kind, url }, index) => /* @__PURE__ */ jsxs10(
|
|
1538
|
+
"div",
|
|
1539
|
+
{
|
|
1540
|
+
className: "w-full max-w-64 rounded-lg border border-border bg-surface p-3",
|
|
1541
|
+
children: [
|
|
1542
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex justify-center", children: [
|
|
1543
|
+
kind === "image" && url ? /* @__PURE__ */ jsx13(
|
|
1544
|
+
"button",
|
|
1545
|
+
{
|
|
1546
|
+
type: "button",
|
|
1547
|
+
className: "w-full cursor-pointer rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1548
|
+
"aria-label": `Open preview ${file.name}`,
|
|
1549
|
+
onClick: () => {
|
|
1550
|
+
setActivePreview({ name: file.name, kind: "image", url });
|
|
1551
|
+
setPreviewOpen(true);
|
|
1552
|
+
},
|
|
1553
|
+
children: /* @__PURE__ */ jsx13(
|
|
1554
|
+
"img",
|
|
1555
|
+
{
|
|
1556
|
+
src: url,
|
|
1557
|
+
alt: file.name,
|
|
1558
|
+
className: "h-28 w-full rounded object-cover"
|
|
1559
|
+
}
|
|
1560
|
+
)
|
|
1561
|
+
}
|
|
1562
|
+
) : null,
|
|
1563
|
+
kind === "video" && url ? /* @__PURE__ */ jsx13(
|
|
1564
|
+
"button",
|
|
1565
|
+
{
|
|
1566
|
+
type: "button",
|
|
1567
|
+
className: "w-full cursor-pointer rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1568
|
+
"aria-label": `Open preview ${file.name}`,
|
|
1569
|
+
onClick: () => {
|
|
1570
|
+
setActivePreview({ name: file.name, kind: "video", url });
|
|
1571
|
+
setPreviewOpen(true);
|
|
1572
|
+
},
|
|
1573
|
+
children: /* @__PURE__ */ jsx13(
|
|
1574
|
+
"video",
|
|
1575
|
+
{
|
|
1576
|
+
src: url,
|
|
1577
|
+
className: "h-28 w-full rounded object-cover",
|
|
1578
|
+
muted: true,
|
|
1579
|
+
preload: "metadata",
|
|
1580
|
+
"aria-label": `Preview ${file.name}`
|
|
1581
|
+
}
|
|
1582
|
+
)
|
|
1583
|
+
}
|
|
1584
|
+
) : null,
|
|
1585
|
+
!kind ? /* @__PURE__ */ jsx13("div", { className: "flex h-28 w-full items-center justify-center rounded bg-muted text-xs text-muted-foreground", children: "No preview" }) : null
|
|
1586
|
+
] }),
|
|
1587
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-2 flex items-center gap-2", children: [
|
|
1588
|
+
/* @__PURE__ */ jsx13("div", { className: "min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-center text-sm", children: /* @__PURE__ */ jsx13("span", { className: "block truncate", children: renderFile ? renderFile(file) : file.name }) }),
|
|
1589
|
+
/* @__PURE__ */ jsx13(
|
|
1590
|
+
"button",
|
|
1591
|
+
{
|
|
1592
|
+
type: "button",
|
|
1593
|
+
"aria-label": `Remove ${file.name}`,
|
|
1594
|
+
onClick: () => onChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
1595
|
+
className: "shrink-0 rounded p-1 text-muted-foreground hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1596
|
+
children: /* @__PURE__ */ jsx13(X3, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
1597
|
+
}
|
|
1598
|
+
)
|
|
1599
|
+
] })
|
|
1600
|
+
]
|
|
1601
|
+
},
|
|
1602
|
+
`${file.name}-${file.size}-${index}`
|
|
1603
|
+
)) }) : null,
|
|
1604
|
+
/* @__PURE__ */ jsx13(
|
|
1605
|
+
Popin_default2,
|
|
1606
|
+
{
|
|
1607
|
+
displayedPopin: previewOpen,
|
|
1608
|
+
setDisplayedPopin: setPreviewOpen,
|
|
1609
|
+
title: (_a = activePreview == null ? void 0 : activePreview.name) != null ? _a : "Media preview",
|
|
1610
|
+
closeText: "Close preview",
|
|
1611
|
+
maxSize: "xl",
|
|
1612
|
+
children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-center", children: [
|
|
1613
|
+
(activePreview == null ? void 0 : activePreview.kind) === "image" ? /* @__PURE__ */ jsx13(
|
|
1614
|
+
"img",
|
|
1615
|
+
{
|
|
1616
|
+
src: activePreview.url,
|
|
1617
|
+
alt: activePreview.name,
|
|
1618
|
+
className: "max-h-[70vh] w-auto max-w-full rounded object-contain"
|
|
1619
|
+
}
|
|
1620
|
+
) : null,
|
|
1621
|
+
(activePreview == null ? void 0 : activePreview.kind) === "video" ? /* @__PURE__ */ jsx13(
|
|
1622
|
+
"video",
|
|
1623
|
+
{
|
|
1624
|
+
src: activePreview.url,
|
|
1625
|
+
className: "max-h-[70vh] w-auto max-w-full rounded",
|
|
1626
|
+
controls: true,
|
|
1627
|
+
autoPlay: true,
|
|
1628
|
+
muted: true
|
|
1629
|
+
}
|
|
1630
|
+
) : null
|
|
1631
|
+
] })
|
|
1632
|
+
}
|
|
1633
|
+
)
|
|
1634
|
+
] });
|
|
1635
|
+
};
|
|
1636
|
+
var FileUpload_default = FileUpload;
|
|
1637
|
+
|
|
1638
|
+
// src/components/shared/patterns/forms/FormField/fields/FileUploadField/FileUploadField.tsx
|
|
1639
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1640
|
+
var FileUploadField = ({
|
|
1641
|
+
field,
|
|
1642
|
+
value,
|
|
1643
|
+
onChange
|
|
1644
|
+
}) => {
|
|
1645
|
+
var _a;
|
|
1646
|
+
const safeField = field != null ? field : {};
|
|
1647
|
+
const fieldName = typeof safeField.name === "string" && safeField.name.trim() ? safeField.name : "fileUpload";
|
|
1648
|
+
const files = Array.isArray(value) ? value : [];
|
|
1649
|
+
return /* @__PURE__ */ jsx14(
|
|
1650
|
+
FileUpload_default,
|
|
1651
|
+
{
|
|
1652
|
+
value: files,
|
|
1653
|
+
onChange: (nextFiles) => onChange(createFormFieldChangeEvent(fieldName, nextFiles)),
|
|
1654
|
+
multiple: (_a = safeField.multiple) != null ? _a : true,
|
|
1655
|
+
accept: safeField.accept,
|
|
1656
|
+
maxFiles: safeField.maxFiles,
|
|
1657
|
+
maxSizeBytes: safeField.maxSizeBytes
|
|
1658
|
+
}
|
|
1659
|
+
);
|
|
1660
|
+
};
|
|
1661
|
+
var FileUploadField_default = FileUploadField;
|
|
1662
|
+
|
|
1663
|
+
// src/components/shared/primitives/data-entry/Select/Select.tsx
|
|
1664
|
+
import { forwardRef as forwardRef4, useState as useState5 } from "react";
|
|
1665
|
+
import { ChevronDown as ChevronDown3 } from "lucide-react";
|
|
1666
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1667
|
+
var SIZE_CLASSES4 = {
|
|
1668
|
+
xs: "h-7 px-2 text-xs",
|
|
1669
|
+
sm: "h-8 px-3 text-sm",
|
|
1670
|
+
md: "h-10 px-3 text-sm",
|
|
1671
|
+
lg: "h-11 px-4 text-base"
|
|
1672
|
+
};
|
|
1673
|
+
var INTENT_CLASSES2 = {
|
|
1674
|
+
primary: "focus-visible:border-primary",
|
|
1675
|
+
secondary: "focus-visible:border-secondary",
|
|
1676
|
+
success: "focus-visible:border-success",
|
|
1677
|
+
warning: "focus-visible:border-warning",
|
|
1678
|
+
danger: "focus-visible:border-danger",
|
|
1679
|
+
info: "focus-visible:border-info",
|
|
1680
|
+
neutral: "focus-visible:border-primary"
|
|
1681
|
+
};
|
|
1682
|
+
var Select = forwardRef4(
|
|
1683
|
+
(_a, ref) => {
|
|
1684
|
+
var _b = _a, { className, children, intent = "neutral", size = "md" } = _b, props = __objRest(_b, ["className", "children", "intent", "size"]);
|
|
1685
|
+
const isInvalid = props["aria-invalid"] === true || props["aria-invalid"] === "true";
|
|
1686
|
+
const [isFocused, setIsFocused] = useState5(false);
|
|
1687
|
+
return /* @__PURE__ */ jsxs11("div", { className: "relative w-full", children: [
|
|
1688
|
+
/* @__PURE__ */ jsx15(
|
|
1689
|
+
"select",
|
|
1690
|
+
__spreadProps(__spreadValues({
|
|
1691
|
+
ref,
|
|
1692
|
+
className: cx(
|
|
1693
|
+
"w-full appearance-none rounded-md border bg-background pr-10 text-foreground outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
1694
|
+
SIZE_CLASSES4[size],
|
|
1695
|
+
isInvalid ? "border-danger focus-visible:border-danger" : "border-border-strong",
|
|
1696
|
+
!isInvalid && INTENT_CLASSES2[intent],
|
|
1697
|
+
className
|
|
1698
|
+
),
|
|
1699
|
+
onFocus: (event) => {
|
|
1700
|
+
var _a2;
|
|
1701
|
+
setIsFocused(true);
|
|
1702
|
+
(_a2 = props.onFocus) == null ? void 0 : _a2.call(props, event);
|
|
1703
|
+
},
|
|
1704
|
+
onBlur: (event) => {
|
|
1705
|
+
var _a2;
|
|
1706
|
+
setIsFocused(false);
|
|
1707
|
+
(_a2 = props.onBlur) == null ? void 0 : _a2.call(props, event);
|
|
1708
|
+
}
|
|
1709
|
+
}, props), {
|
|
1710
|
+
children
|
|
1711
|
+
})
|
|
1712
|
+
),
|
|
1713
|
+
/* @__PURE__ */ jsx15("span", { className: "pointer-events-none absolute inset-y-0 right-3 flex items-center text-muted-foreground", children: /* @__PURE__ */ jsx15(
|
|
1714
|
+
ChevronDown3,
|
|
1715
|
+
{
|
|
1716
|
+
"aria-hidden": "true",
|
|
1717
|
+
strokeWidth: 2.5,
|
|
1718
|
+
className: cx(
|
|
1719
|
+
"h-5 w-5 transition-transform duration-200 ease-out",
|
|
1720
|
+
isFocused && "rotate-180"
|
|
1721
|
+
)
|
|
1722
|
+
}
|
|
1723
|
+
) })
|
|
1724
|
+
] });
|
|
1725
|
+
}
|
|
1726
|
+
);
|
|
1727
|
+
Select.displayName = "Select";
|
|
1728
|
+
var Select_default = Select;
|
|
1729
|
+
|
|
1730
|
+
// src/components/shared/patterns/forms/FormField/fields/SelectField/SelectField.tsx
|
|
1731
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1732
|
+
var SelectField = ({ field, value, error, errorId, onChange }) => {
|
|
1733
|
+
var _a;
|
|
1734
|
+
return /* @__PURE__ */ jsx16(
|
|
1735
|
+
Select_default,
|
|
1736
|
+
{
|
|
1737
|
+
id: field.name,
|
|
1738
|
+
name: field.name,
|
|
1739
|
+
value,
|
|
1740
|
+
onChange,
|
|
1741
|
+
"aria-invalid": Boolean(error),
|
|
1742
|
+
"aria-describedby": errorId,
|
|
1743
|
+
intent: error ? "danger" : "neutral",
|
|
1744
|
+
className: "mt-1 cursor-pointer",
|
|
1745
|
+
children: (_a = field.options) == null ? void 0 : _a.map((opt) => /* @__PURE__ */ jsx16("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1746
|
+
}
|
|
1747
|
+
);
|
|
1748
|
+
};
|
|
1749
|
+
var SelectField_default = SelectField;
|
|
1750
|
+
|
|
1751
|
+
// src/components/shared/patterns/forms/FormField/fields/SelectField/index.tsx
|
|
1752
|
+
var SelectField_default2 = SelectField_default;
|
|
1753
|
+
|
|
1754
|
+
// src/components/shared/primitives/data-entry/Slider/Slider.tsx
|
|
1755
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1756
|
+
var SIZE_CLASSES5 = {
|
|
1757
|
+
sm: "h-1.5",
|
|
1758
|
+
md: "h-2",
|
|
1759
|
+
lg: "h-2.5"
|
|
1760
|
+
};
|
|
1761
|
+
var INTENT_CLASSES3 = {
|
|
1762
|
+
primary: "accent-primary",
|
|
1763
|
+
secondary: "accent-secondary",
|
|
1764
|
+
success: "accent-success",
|
|
1765
|
+
warning: "accent-warning",
|
|
1766
|
+
danger: "accent-danger",
|
|
1767
|
+
info: "accent-info",
|
|
1768
|
+
neutral: "accent-primary"
|
|
1769
|
+
};
|
|
1770
|
+
var Slider = (_a) => {
|
|
1771
|
+
var _b = _a, {
|
|
1772
|
+
value,
|
|
1773
|
+
onChange,
|
|
1774
|
+
min = 0,
|
|
1775
|
+
max = 100,
|
|
1776
|
+
step = 1,
|
|
1777
|
+
disabled = false,
|
|
1778
|
+
showValue = false,
|
|
1779
|
+
formatValue,
|
|
1780
|
+
intent = "primary",
|
|
1781
|
+
size = "md",
|
|
1782
|
+
className
|
|
1783
|
+
} = _b, props = __objRest(_b, [
|
|
1784
|
+
"value",
|
|
1785
|
+
"onChange",
|
|
1786
|
+
"min",
|
|
1787
|
+
"max",
|
|
1788
|
+
"step",
|
|
1789
|
+
"disabled",
|
|
1790
|
+
"showValue",
|
|
1791
|
+
"formatValue",
|
|
1792
|
+
"intent",
|
|
1793
|
+
"size",
|
|
1794
|
+
"className"
|
|
1795
|
+
]);
|
|
1796
|
+
return /* @__PURE__ */ jsxs12("div", { className: cx("flex items-center gap-3", className), children: [
|
|
1797
|
+
/* @__PURE__ */ jsx17(
|
|
1798
|
+
"input",
|
|
1799
|
+
__spreadValues({
|
|
1800
|
+
type: "range",
|
|
1801
|
+
value,
|
|
1802
|
+
min,
|
|
1803
|
+
max,
|
|
1804
|
+
step,
|
|
1805
|
+
disabled,
|
|
1806
|
+
onChange: (event) => onChange(Number(event.target.value)),
|
|
1807
|
+
className: cx(
|
|
1808
|
+
"w-full cursor-pointer rounded-lg bg-surface shadow-none disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1809
|
+
SIZE_CLASSES5[size],
|
|
1810
|
+
INTENT_CLASSES3[intent]
|
|
1811
|
+
)
|
|
1812
|
+
}, props)
|
|
1813
|
+
),
|
|
1814
|
+
showValue ? /* @__PURE__ */ jsx17("span", { className: "min-w-10 text-right text-xs font-medium text-muted-foreground", children: formatValue ? formatValue(value) : value }) : null
|
|
1815
|
+
] });
|
|
1816
|
+
};
|
|
1817
|
+
var Slider_default = Slider;
|
|
1818
|
+
|
|
1819
|
+
// src/components/shared/patterns/forms/FormField/fields/SliderField/SliderField.tsx
|
|
1820
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1821
|
+
var SliderField = ({ field, value, onChange }) => {
|
|
1822
|
+
var _a, _b, _c, _d, _e;
|
|
1823
|
+
const numericValue = typeof value === "number" ? value : typeof value === "string" && value !== "" ? Number(value) : (_a = field.min) != null ? _a : 0;
|
|
1824
|
+
return /* @__PURE__ */ jsx18(
|
|
1825
|
+
Slider_default,
|
|
1826
|
+
{
|
|
1827
|
+
id: field.name,
|
|
1828
|
+
name: field.name,
|
|
1829
|
+
value: Number.isFinite(numericValue) ? numericValue : (_b = field.min) != null ? _b : 0,
|
|
1830
|
+
min: (_c = field.min) != null ? _c : 0,
|
|
1831
|
+
max: (_d = field.max) != null ? _d : 100,
|
|
1832
|
+
step: (_e = field.step) != null ? _e : 1,
|
|
1833
|
+
showValue: true,
|
|
1834
|
+
onChange: (next) => onChange(createFormFieldChangeEvent(field.name, next)),
|
|
1835
|
+
"aria-label": field.label
|
|
1836
|
+
}
|
|
1837
|
+
);
|
|
1838
|
+
};
|
|
1839
|
+
var SliderField_default = SliderField;
|
|
1840
|
+
|
|
1841
|
+
// src/components/shared/primitives/data-entry/Switch/Switch.tsx
|
|
1842
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1843
|
+
var Switch = (_a) => {
|
|
1844
|
+
var _b = _a, {
|
|
1845
|
+
checked,
|
|
1846
|
+
onChange,
|
|
1847
|
+
disabled = false,
|
|
1848
|
+
label,
|
|
1849
|
+
className,
|
|
1850
|
+
onKeyDown,
|
|
1851
|
+
"aria-label": ariaLabel
|
|
1852
|
+
} = _b, props = __objRest(_b, [
|
|
1853
|
+
"checked",
|
|
1854
|
+
"onChange",
|
|
1855
|
+
"disabled",
|
|
1856
|
+
"label",
|
|
1857
|
+
"className",
|
|
1858
|
+
"onKeyDown",
|
|
1859
|
+
"aria-label"
|
|
1860
|
+
]);
|
|
1861
|
+
const handleToggle = () => {
|
|
1862
|
+
if (disabled) return;
|
|
1863
|
+
onChange(!checked);
|
|
1864
|
+
};
|
|
1865
|
+
const handleKeyDown = (event) => {
|
|
1866
|
+
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
1867
|
+
if (event.defaultPrevented || disabled) return;
|
|
1868
|
+
if (event.key === " " || event.key === "Enter") {
|
|
1869
|
+
event.preventDefault();
|
|
1870
|
+
onChange(!checked);
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
return /* @__PURE__ */ jsx19(
|
|
1874
|
+
"button",
|
|
1875
|
+
__spreadProps(__spreadValues({
|
|
1876
|
+
type: "button",
|
|
1877
|
+
role: "switch",
|
|
1878
|
+
"aria-checked": checked,
|
|
1879
|
+
"aria-label": ariaLabel != null ? ariaLabel : label,
|
|
1880
|
+
disabled,
|
|
1881
|
+
onClick: handleToggle,
|
|
1882
|
+
onKeyDown: handleKeyDown,
|
|
1883
|
+
className: `relative inline-flex h-6 w-11 cursor-pointer items-center rounded-full border transition-colors shadow-sm disabled:opacity-50 disabled:cursor-not-allowed ${checked ? "border-primary-foreground/40 bg-primary-hover" : "border-border-strong bg-border-strong"} ${className != null ? className : ""}`
|
|
1884
|
+
}, props), {
|
|
1885
|
+
children: /* @__PURE__ */ jsx19(
|
|
1886
|
+
"span",
|
|
1887
|
+
{
|
|
1888
|
+
className: `inline-block h-4 w-4 transform rounded-full transition-transform ${checked ? "translate-x-6 bg-primary-foreground" : "translate-x-1 bg-background"}`
|
|
1889
|
+
}
|
|
1890
|
+
)
|
|
1891
|
+
})
|
|
1892
|
+
);
|
|
1893
|
+
};
|
|
1894
|
+
var Switch_default = Switch;
|
|
1895
|
+
|
|
1896
|
+
// src/components/shared/patterns/forms/FormField/fields/SwitchField/SwitchField.tsx
|
|
1897
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1898
|
+
var SwitchField = ({
|
|
1899
|
+
field,
|
|
1900
|
+
value,
|
|
1901
|
+
error,
|
|
1902
|
+
errorId,
|
|
1903
|
+
onChange
|
|
1904
|
+
}) => {
|
|
1905
|
+
const checked = Boolean(value);
|
|
1906
|
+
const emit = (next) => {
|
|
1907
|
+
onChange(createFormFieldChangeEvent(field.name, next));
|
|
1908
|
+
};
|
|
1909
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3 py-1", children: [
|
|
1910
|
+
/* @__PURE__ */ jsx20(
|
|
1911
|
+
Switch_default,
|
|
1912
|
+
{
|
|
1913
|
+
checked,
|
|
1914
|
+
onChange: emit,
|
|
1915
|
+
label: field.label,
|
|
1916
|
+
"aria-describedby": errorId,
|
|
1917
|
+
"aria-invalid": Boolean(error)
|
|
1918
|
+
}
|
|
1919
|
+
),
|
|
1920
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-foreground", children: [
|
|
1921
|
+
field.label,
|
|
1922
|
+
" ",
|
|
1923
|
+
field.required && "*"
|
|
1924
|
+
] }),
|
|
1925
|
+
error && !errorId && /* @__PURE__ */ jsx20("p", { className: "text-sm text-danger", children: error })
|
|
1926
|
+
] });
|
|
1927
|
+
};
|
|
1928
|
+
var SwitchField_default = SwitchField;
|
|
1929
|
+
|
|
1930
|
+
// src/components/shared/patterns/forms/FormField/fields/SwitchField/index.tsx
|
|
1931
|
+
var SwitchField_default2 = SwitchField_default;
|
|
1932
|
+
|
|
1933
|
+
// src/components/shared/patterns/forms/FormField/fields/TagsField/TagsField.tsx
|
|
1934
|
+
import React10 from "react";
|
|
1935
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1936
|
+
var TagsField = ({ field, value, error, errorId, onChange }) => {
|
|
1937
|
+
var _a;
|
|
1938
|
+
const [tagToAdd, setTagToAdd] = React10.useState("");
|
|
1939
|
+
const tags = Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
1940
|
+
const addTag = () => {
|
|
1941
|
+
if (!tagToAdd || tags.includes(tagToAdd)) return;
|
|
1942
|
+
onChange(createFormFieldChangeEvent(field.name, [...tags, tagToAdd]));
|
|
1943
|
+
setTagToAdd("");
|
|
1944
|
+
};
|
|
1945
|
+
const removeTag = (tag) => {
|
|
1946
|
+
onChange(createFormFieldChangeEvent(field.name, tags.filter((t) => t !== tag)));
|
|
1947
|
+
};
|
|
1948
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-2", children: [
|
|
1949
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
|
|
1950
|
+
/* @__PURE__ */ jsxs14(
|
|
1951
|
+
Select_default,
|
|
1952
|
+
{
|
|
1953
|
+
id: field.name,
|
|
1954
|
+
className: "flex-1 cursor-pointer placeholder:text-muted-foreground",
|
|
1955
|
+
value: tagToAdd,
|
|
1956
|
+
onChange: (e) => setTagToAdd(e.target.value),
|
|
1957
|
+
"aria-invalid": Boolean(error),
|
|
1958
|
+
"aria-describedby": errorId,
|
|
1959
|
+
intent: error ? "danger" : "neutral",
|
|
1960
|
+
children: [
|
|
1961
|
+
/* @__PURE__ */ jsx21("option", { value: "", children: "\u2014" }),
|
|
1962
|
+
(_a = field.options) == null ? void 0 : _a.map((opt) => /* @__PURE__ */ jsx21("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1963
|
+
]
|
|
1964
|
+
}
|
|
1965
|
+
),
|
|
1966
|
+
/* @__PURE__ */ jsx21(
|
|
1967
|
+
Button_default2,
|
|
1968
|
+
{
|
|
1969
|
+
intent: "primary",
|
|
1970
|
+
variant: "solid",
|
|
1971
|
+
type: "button",
|
|
1972
|
+
onClick: addTag,
|
|
1973
|
+
className: "px-3 py-2",
|
|
1974
|
+
children: "+"
|
|
1975
|
+
}
|
|
1976
|
+
)
|
|
1977
|
+
] }),
|
|
1978
|
+
/* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-2 mt-1", children: tags.map((tag) => {
|
|
1979
|
+
var _a2, _b, _c;
|
|
1980
|
+
return /* @__PURE__ */ jsx21(
|
|
1981
|
+
Tag_default,
|
|
1982
|
+
{
|
|
1983
|
+
intent: "primary",
|
|
1984
|
+
variant: "soft",
|
|
1985
|
+
onRemove: () => removeTag(tag),
|
|
1986
|
+
children: (_c = (_b = (_a2 = field.options) == null ? void 0 : _a2.find((option) => String(option.value) === tag)) == null ? void 0 : _b.label) != null ? _c : tag
|
|
1987
|
+
},
|
|
1988
|
+
tag
|
|
1989
|
+
);
|
|
1990
|
+
}) })
|
|
1991
|
+
] });
|
|
1992
|
+
};
|
|
1993
|
+
var TagsField_default = TagsField;
|
|
1994
|
+
|
|
1995
|
+
// src/components/shared/patterns/forms/FormField/fields/TagsField/index.tsx
|
|
1996
|
+
var TagsField_default2 = TagsField_default;
|
|
1997
|
+
|
|
1998
|
+
// src/components/shared/primitives/data-entry/Textarea/Textarea.tsx
|
|
1999
|
+
import { forwardRef as forwardRef5 } from "react";
|
|
2000
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2001
|
+
var SIZE_CLASSES6 = {
|
|
2002
|
+
xs: "px-2 py-1 text-xs",
|
|
2003
|
+
sm: "px-3 py-1.5 text-sm",
|
|
2004
|
+
md: "px-3 py-2 text-sm",
|
|
2005
|
+
lg: "px-4 py-2.5 text-base"
|
|
2006
|
+
};
|
|
2007
|
+
var INTENT_CLASSES4 = {
|
|
2008
|
+
primary: "focus-visible:border-primary",
|
|
2009
|
+
secondary: "focus-visible:border-secondary",
|
|
2010
|
+
success: "focus-visible:border-success",
|
|
2011
|
+
warning: "focus-visible:border-warning",
|
|
2012
|
+
danger: "focus-visible:border-danger",
|
|
2013
|
+
info: "focus-visible:border-info",
|
|
2014
|
+
neutral: "focus-visible:border-primary"
|
|
2015
|
+
};
|
|
2016
|
+
var Textarea = forwardRef5(
|
|
2017
|
+
(_a, ref) => {
|
|
2018
|
+
var _b = _a, { className, intent = "neutral", size = "md" } = _b, props = __objRest(_b, ["className", "intent", "size"]);
|
|
2019
|
+
const isInvalid = props["aria-invalid"] === true || props["aria-invalid"] === "true";
|
|
2020
|
+
return /* @__PURE__ */ jsx22(
|
|
2021
|
+
"textarea",
|
|
2022
|
+
__spreadValues({
|
|
2023
|
+
ref,
|
|
2024
|
+
className: cx(
|
|
2025
|
+
"w-full rounded-md border bg-background text-foreground outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed",
|
|
2026
|
+
SIZE_CLASSES6[size],
|
|
2027
|
+
isInvalid ? "border-danger focus-visible:border-danger" : "border-border-strong",
|
|
2028
|
+
!isInvalid && INTENT_CLASSES4[intent],
|
|
2029
|
+
className
|
|
2030
|
+
)
|
|
2031
|
+
}, props)
|
|
2032
|
+
);
|
|
2033
|
+
}
|
|
2034
|
+
);
|
|
2035
|
+
Textarea.displayName = "Textarea";
|
|
2036
|
+
var Textarea_default = Textarea;
|
|
2037
|
+
|
|
2038
|
+
// src/components/shared/patterns/forms/FormField/fields/TextAreaField/TextAreaField.tsx
|
|
2039
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2040
|
+
var TextareaField = ({
|
|
2041
|
+
field,
|
|
2042
|
+
value,
|
|
2043
|
+
error,
|
|
2044
|
+
errorId,
|
|
2045
|
+
onChange
|
|
2046
|
+
}) => {
|
|
2047
|
+
return /* @__PURE__ */ jsx23(
|
|
2048
|
+
Textarea_default,
|
|
2049
|
+
{
|
|
2050
|
+
id: field.name,
|
|
2051
|
+
name: field.name,
|
|
2052
|
+
value: getSafeValue(value),
|
|
2053
|
+
placeholder: field.placeholder,
|
|
2054
|
+
rows: 3,
|
|
2055
|
+
onChange,
|
|
2056
|
+
"aria-invalid": Boolean(error),
|
|
2057
|
+
"aria-describedby": errorId,
|
|
2058
|
+
intent: error ? "danger" : "neutral",
|
|
2059
|
+
className: "mt-1"
|
|
2060
|
+
}
|
|
2061
|
+
);
|
|
2062
|
+
};
|
|
2063
|
+
var TextAreaField_default = TextareaField;
|
|
2064
|
+
|
|
2065
|
+
// src/components/shared/patterns/forms/FormField/fields/TextAreaField/index.tsx
|
|
2066
|
+
var TextAreaField_default2 = TextAreaField_default;
|
|
2067
|
+
|
|
2068
|
+
// src/components/shared/patterns/forms/FormField/fields/TextField/TextField.tsx
|
|
2069
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
2070
|
+
var TextField = ({
|
|
2071
|
+
field,
|
|
2072
|
+
value,
|
|
2073
|
+
error,
|
|
2074
|
+
errorId,
|
|
2075
|
+
onChange
|
|
2076
|
+
}) => {
|
|
2077
|
+
return /* @__PURE__ */ jsx24(
|
|
2078
|
+
Input_default,
|
|
2079
|
+
{
|
|
2080
|
+
id: field.name,
|
|
2081
|
+
type: field.type === "number" /* NUMBER */ ? "number" : "text",
|
|
2082
|
+
name: field.name,
|
|
2083
|
+
value: getSafeValue(value),
|
|
2084
|
+
placeholder: field.placeholder,
|
|
2085
|
+
required: field.required,
|
|
2086
|
+
pattern: field.pattern,
|
|
2087
|
+
onChange,
|
|
2088
|
+
"aria-invalid": Boolean(error),
|
|
2089
|
+
"aria-describedby": errorId,
|
|
2090
|
+
intent: error ? "danger" : "neutral",
|
|
2091
|
+
className: "mt-1"
|
|
2092
|
+
}
|
|
2093
|
+
);
|
|
2094
|
+
};
|
|
2095
|
+
var TextField_default = TextField;
|
|
2096
|
+
|
|
2097
|
+
// src/components/shared/patterns/forms/FormField/fields/TextField/index.tsx
|
|
2098
|
+
var TextField_default2 = TextField_default;
|
|
2099
|
+
export {
|
|
2100
|
+
CheckboxField_default2 as CheckboxField,
|
|
2101
|
+
CheckboxSearchField_default2 as CheckboxSearchField,
|
|
2102
|
+
ColorField_default2 as ColorField,
|
|
2103
|
+
ComboboxField_default as ComboboxField,
|
|
2104
|
+
DatePickerField_default2 as DatePickerField,
|
|
2105
|
+
FileUploadField_default as FileUploadField,
|
|
2106
|
+
SelectField_default2 as SelectField,
|
|
2107
|
+
SliderField_default as SliderField,
|
|
2108
|
+
SwitchField_default2 as SwitchField,
|
|
2109
|
+
TagsField_default2 as TagField,
|
|
2110
|
+
TagsField_default2 as TagsField,
|
|
2111
|
+
TextAreaField_default2 as TextAreaField,
|
|
2112
|
+
TextField_default2 as TextField
|
|
2113
|
+
};
|