@page-speed/forms 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +551 -330
- package/dist/inputs.cjs.map +1 -1
- package/dist/inputs.d.cts +5 -1
- package/dist/inputs.d.ts +5 -1
- package/dist/inputs.js +551 -330
- package/dist/inputs.js.map +1 -1
- package/package.json +4 -2
package/dist/inputs.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React7 = require('react');
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
4
6
|
|
|
5
7
|
function _interopNamespace(e) {
|
|
6
8
|
if (e && e.__esModule) return e;
|
|
@@ -43,7 +45,7 @@ function TextInput({
|
|
|
43
45
|
const handleBlur = () => {
|
|
44
46
|
onBlur?.();
|
|
45
47
|
};
|
|
46
|
-
const baseClassName = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors
|
|
48
|
+
const baseClassName = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
|
|
47
49
|
const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
|
|
48
50
|
const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
|
|
49
51
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
@@ -90,7 +92,7 @@ function TextArea({
|
|
|
90
92
|
const handleBlur = () => {
|
|
91
93
|
onBlur?.();
|
|
92
94
|
};
|
|
93
|
-
const baseClassName = "flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors
|
|
95
|
+
const baseClassName = "flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
|
|
94
96
|
const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
|
|
95
97
|
const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
|
|
96
98
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
@@ -117,6 +119,11 @@ function TextArea({
|
|
|
117
119
|
);
|
|
118
120
|
}
|
|
119
121
|
TextArea.displayName = "TextArea";
|
|
122
|
+
function cn(...inputs) {
|
|
123
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/inputs/Checkbox.tsx
|
|
120
127
|
function Checkbox({
|
|
121
128
|
name,
|
|
122
129
|
value,
|
|
@@ -129,6 +136,7 @@ function Checkbox({
|
|
|
129
136
|
indeterminate = false,
|
|
130
137
|
label,
|
|
131
138
|
description,
|
|
139
|
+
checkboxVariant = "boxed",
|
|
132
140
|
...props
|
|
133
141
|
}) {
|
|
134
142
|
const inputRef = React7__namespace.useRef(null);
|
|
@@ -144,36 +152,92 @@ function Checkbox({
|
|
|
144
152
|
const handleBlur = () => {
|
|
145
153
|
onBlur?.();
|
|
146
154
|
};
|
|
147
|
-
const
|
|
148
|
-
|
|
155
|
+
const isActive = value || indeterminate && !value;
|
|
156
|
+
const checkbox = /* @__PURE__ */ React7__namespace.createElement(
|
|
157
|
+
"div",
|
|
149
158
|
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
159
|
+
className: cn(
|
|
160
|
+
"relative inline-flex items-center justify-center",
|
|
161
|
+
!label && className
|
|
162
|
+
)
|
|
163
|
+
},
|
|
164
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
165
|
+
"input",
|
|
166
|
+
{
|
|
167
|
+
ref: inputRef,
|
|
168
|
+
type: "checkbox",
|
|
169
|
+
id: checkboxId,
|
|
170
|
+
name,
|
|
171
|
+
checked: value,
|
|
172
|
+
onChange: handleChange,
|
|
173
|
+
onBlur: handleBlur,
|
|
174
|
+
disabled,
|
|
175
|
+
required,
|
|
176
|
+
className: "peer sr-only",
|
|
177
|
+
"aria-invalid": error || props["aria-invalid"],
|
|
178
|
+
"aria-describedby": description ? `${checkboxId}-description` : props["aria-describedby"],
|
|
179
|
+
"aria-required": required || props["aria-required"],
|
|
180
|
+
...props
|
|
181
|
+
}
|
|
182
|
+
),
|
|
183
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
184
|
+
"div",
|
|
185
|
+
{
|
|
186
|
+
className: cn(
|
|
187
|
+
"flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
|
|
188
|
+
!error && isActive && "border-primary bg-primary text-primary-foreground",
|
|
189
|
+
!error && !isActive && "border-input bg-transparent",
|
|
190
|
+
error && isActive && "border-destructive bg-destructive text-destructive-foreground",
|
|
191
|
+
error && !isActive && "border-destructive bg-transparent",
|
|
192
|
+
disabled && "opacity-50",
|
|
193
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
194
|
+
)
|
|
195
|
+
},
|
|
196
|
+
value && /* @__PURE__ */ React7__namespace.createElement(
|
|
197
|
+
"svg",
|
|
198
|
+
{
|
|
199
|
+
className: "size-3.5",
|
|
200
|
+
viewBox: "0 0 24 24",
|
|
201
|
+
fill: "none",
|
|
202
|
+
stroke: "currentColor",
|
|
203
|
+
strokeWidth: "3",
|
|
204
|
+
strokeLinecap: "round",
|
|
205
|
+
strokeLinejoin: "round"
|
|
206
|
+
},
|
|
207
|
+
/* @__PURE__ */ React7__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
208
|
+
),
|
|
209
|
+
indeterminate && !value && /* @__PURE__ */ React7__namespace.createElement(
|
|
210
|
+
"svg",
|
|
211
|
+
{
|
|
212
|
+
className: "size-3.5",
|
|
213
|
+
viewBox: "0 0 24 24",
|
|
214
|
+
fill: "none",
|
|
215
|
+
stroke: "currentColor",
|
|
216
|
+
strokeWidth: "3",
|
|
217
|
+
strokeLinecap: "round",
|
|
218
|
+
strokeLinejoin: "round"
|
|
219
|
+
},
|
|
220
|
+
/* @__PURE__ */ React7__namespace.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
);
|
|
166
224
|
if (label) {
|
|
167
225
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
168
226
|
"label",
|
|
169
227
|
{
|
|
170
|
-
className:
|
|
228
|
+
className: cn(
|
|
229
|
+
"w-full h-full flex gap-3 p-3 duration-200",
|
|
230
|
+
checkboxVariant === "boxed" && "border rounded-lg hover:ring-2",
|
|
231
|
+
checkboxVariant === "boxed" && value && "ring-2",
|
|
232
|
+
disabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer",
|
|
233
|
+
className
|
|
234
|
+
),
|
|
171
235
|
htmlFor: checkboxId
|
|
172
236
|
},
|
|
173
|
-
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row
|
|
237
|
+
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row gap-2" }, checkbox, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, label), description && /* @__PURE__ */ React7__namespace.createElement(
|
|
174
238
|
"p",
|
|
175
239
|
{
|
|
176
|
-
className: "text-
|
|
240
|
+
className: "text-xs opacity-75",
|
|
177
241
|
id: `${checkboxId}-description`
|
|
178
242
|
},
|
|
179
243
|
description
|
|
@@ -211,6 +275,18 @@ function CheckboxGroup({
|
|
|
211
275
|
).length;
|
|
212
276
|
const allSelected = selectedEnabledCount === enabledOptions.length;
|
|
213
277
|
const someSelected = selectedEnabledCount > 0 && !allSelected;
|
|
278
|
+
const checkboxVariant = React7__namespace.useMemo(() => {
|
|
279
|
+
if (options.some((opt) => opt.description)) {
|
|
280
|
+
return "boxed";
|
|
281
|
+
}
|
|
282
|
+
return "inline";
|
|
283
|
+
}, [options]);
|
|
284
|
+
const countableValue = React7__namespace.useMemo(() => {
|
|
285
|
+
if (value?.length > 0) {
|
|
286
|
+
return value.length;
|
|
287
|
+
}
|
|
288
|
+
return 0;
|
|
289
|
+
}, [value]);
|
|
214
290
|
const handleChange = (optionValue, checked) => {
|
|
215
291
|
const newValues = checked ? [...value, optionValue] : value.filter((v) => v !== optionValue);
|
|
216
292
|
if (maxSelections && checked && newValues.length > maxSelections) {
|
|
@@ -229,9 +305,14 @@ function CheckboxGroup({
|
|
|
229
305
|
const handleBlur = () => {
|
|
230
306
|
onBlur?.();
|
|
231
307
|
};
|
|
232
|
-
const
|
|
233
|
-
const containerClass =
|
|
234
|
-
|
|
308
|
+
const maxReached = Boolean(maxSelections && countableValue >= maxSelections);
|
|
309
|
+
const containerClass = cn(
|
|
310
|
+
"w-full gap-3",
|
|
311
|
+
layout === "stacked" && "flex flex-col",
|
|
312
|
+
layout === "inline" && "flex flex-row flex-wrap",
|
|
313
|
+
layout === "grid" && "grid",
|
|
314
|
+
className
|
|
315
|
+
);
|
|
235
316
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
236
317
|
"div",
|
|
237
318
|
{
|
|
@@ -245,68 +326,56 @@ function CheckboxGroup({
|
|
|
245
326
|
gridTemplateColumns: `repeat(${gridColumns}, 1fr)`
|
|
246
327
|
} : void 0
|
|
247
328
|
},
|
|
248
|
-
label
|
|
249
|
-
description
|
|
329
|
+
label ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, label) : null,
|
|
330
|
+
description ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs opacity-70" }, description) : null,
|
|
250
331
|
showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React7__namespace.createElement(
|
|
251
|
-
|
|
332
|
+
Checkbox,
|
|
252
333
|
{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
},
|
|
265
|
-
onChange: (e) => handleSelectAll(e.target.checked),
|
|
266
|
-
onBlur: handleBlur,
|
|
267
|
-
disabled,
|
|
268
|
-
className: "peer relative flex size-4 shrink-0 appearance-none items-center justify-center rounded-lg border border-input bg-transparent outline-none transition-colors focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50",
|
|
269
|
-
"aria-label": selectAllLabel
|
|
270
|
-
}
|
|
271
|
-
), allSelected && /* @__PURE__ */ React7__namespace.createElement("span", { className: "pointer-events-none absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center justify-center text-primary-foreground" }, /* @__PURE__ */ React7__namespace.createElement("svg", { className: "size-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3" }, /* @__PURE__ */ React7__namespace.createElement("polyline", { points: "20 6 9 17 4 12" }))), someSelected && !allSelected && /* @__PURE__ */ React7__namespace.createElement("span", { className: "pointer-events-none absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center justify-center text-primary" }, /* @__PURE__ */ React7__namespace.createElement("svg", { className: "size-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3" }, /* @__PURE__ */ React7__namespace.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })))), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium" }, selectAllLabel))
|
|
334
|
+
name: `${name}-select-all`,
|
|
335
|
+
id: `${name}-select-all`,
|
|
336
|
+
value: allSelected,
|
|
337
|
+
onChange: handleSelectAll,
|
|
338
|
+
onBlur: handleBlur,
|
|
339
|
+
indeterminate: someSelected,
|
|
340
|
+
label: selectAllLabel,
|
|
341
|
+
checkboxVariant: "inline",
|
|
342
|
+
disabled,
|
|
343
|
+
"aria-label": selectAllLabel
|
|
344
|
+
}
|
|
272
345
|
),
|
|
273
346
|
options.map((option) => {
|
|
274
347
|
const isChecked = value.includes(option.value);
|
|
275
348
|
const isDisabled = disabled || option.disabled || maxReached && !isChecked;
|
|
276
|
-
const checkboxId = `${name}-${option.value}`;
|
|
277
349
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
278
|
-
|
|
350
|
+
Checkbox,
|
|
279
351
|
{
|
|
280
352
|
key: option.value,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
onBlur: handleBlur,
|
|
294
|
-
disabled: isDisabled,
|
|
295
|
-
required: required && minSelections ? value.length < minSelections : false,
|
|
296
|
-
className: `peer relative flex size-4 shrink-0 appearance-none items-center justify-center rounded-lg border border-input bg-transparent outline-none transition-colors focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 ${error ? "border-destructive ring-3 ring-destructive/20" : ""} ${isChecked ? "bg-primary border-primary" : ""}`,
|
|
297
|
-
"aria-describedby": option.description ? `${checkboxId}-description` : props["aria-describedby"]
|
|
298
|
-
}
|
|
299
|
-
), isChecked && /* @__PURE__ */ React7__namespace.createElement("span", { className: "pointer-events-none absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center justify-center text-primary-foreground" }, /* @__PURE__ */ React7__namespace.createElement("svg", { className: "size-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3" }, /* @__PURE__ */ React7__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, renderOption ? renderOption(option) : /* @__PURE__ */ React7__namespace.createElement(React7__namespace.Fragment, null, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-2 text-sm font-medium" }, option.label), option.description && /* @__PURE__ */ React7__namespace.createElement(
|
|
300
|
-
"p",
|
|
301
|
-
{
|
|
302
|
-
className: "text-muted-foreground text-sm",
|
|
303
|
-
id: `${checkboxId}-description`
|
|
304
|
-
},
|
|
305
|
-
option.description
|
|
306
|
-
))))
|
|
353
|
+
name,
|
|
354
|
+
id: `${name}-${option.value}`,
|
|
355
|
+
value: isChecked,
|
|
356
|
+
onChange: (checked) => handleChange(option.value, checked),
|
|
357
|
+
onBlur: handleBlur,
|
|
358
|
+
disabled: isDisabled,
|
|
359
|
+
required: required && minSelections ? value.length < minSelections : false,
|
|
360
|
+
error,
|
|
361
|
+
label: renderOption ? renderOption(option) : option.label,
|
|
362
|
+
description: renderOption ? void 0 : option.description,
|
|
363
|
+
checkboxVariant
|
|
364
|
+
}
|
|
307
365
|
);
|
|
308
366
|
}),
|
|
309
|
-
(minSelections || maxSelections) && /* @__PURE__ */ React7__namespace.createElement(
|
|
367
|
+
(minSelections || maxSelections) && /* @__PURE__ */ React7__namespace.createElement(
|
|
368
|
+
"div",
|
|
369
|
+
{
|
|
370
|
+
className: cn(
|
|
371
|
+
"text-sm p-2 rounded-lg border font-semibold mt-2",
|
|
372
|
+
minSelections && countableValue < minSelections ? "border-destructive bg-destructive/80 text-destructive-foreground" : "border-border bg-card text-card-foreground"
|
|
373
|
+
),
|
|
374
|
+
"aria-live": "polite"
|
|
375
|
+
},
|
|
376
|
+
minSelections && countableValue < minSelections && /* @__PURE__ */ React7__namespace.createElement("span", null, "Select at least ", minSelections, " option", minSelections !== 1 ? "s" : ""),
|
|
377
|
+
maxSelections && /* @__PURE__ */ React7__namespace.createElement("span", null, countableValue, "/", maxSelections, " selected")
|
|
378
|
+
)
|
|
310
379
|
);
|
|
311
380
|
}
|
|
312
381
|
CheckboxGroup.displayName = "CheckboxGroup";
|
|
@@ -355,8 +424,16 @@ function Radio({
|
|
|
355
424
|
const handleBlur = () => {
|
|
356
425
|
onBlur?.();
|
|
357
426
|
};
|
|
358
|
-
const
|
|
359
|
-
|
|
427
|
+
const useChoiceCard = React7__namespace.useMemo(() => {
|
|
428
|
+
return options.some((option) => option.description);
|
|
429
|
+
}, [options]);
|
|
430
|
+
const containerClass = React7__namespace.useMemo(() => {
|
|
431
|
+
return cn(
|
|
432
|
+
"w-full gap-3 grid grid-cols-1",
|
|
433
|
+
layout === "inline" && "md:grid-cols-2",
|
|
434
|
+
className
|
|
435
|
+
);
|
|
436
|
+
}, [layout, className]);
|
|
360
437
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
361
438
|
"div",
|
|
362
439
|
{
|
|
@@ -372,38 +449,53 @@ function Radio({
|
|
|
372
449
|
const isChecked = value === option.value;
|
|
373
450
|
const isDisabled = disabled || option.disabled;
|
|
374
451
|
const radioId = `${name}-${option.value}`;
|
|
452
|
+
const hasDescription = option.description != null && option.description !== "";
|
|
453
|
+
const radioIndicator = /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative inline-flex items-center justify-center" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
454
|
+
"input",
|
|
455
|
+
{
|
|
456
|
+
type: "radio",
|
|
457
|
+
id: radioId,
|
|
458
|
+
name,
|
|
459
|
+
value: option.value,
|
|
460
|
+
checked: isChecked,
|
|
461
|
+
onChange: (e) => handleChange(e.target.value),
|
|
462
|
+
onBlur: handleBlur,
|
|
463
|
+
disabled: isDisabled,
|
|
464
|
+
required,
|
|
465
|
+
className: "peer sr-only",
|
|
466
|
+
"aria-describedby": hasDescription ? `${radioId}-description` : props["aria-describedby"]
|
|
467
|
+
}
|
|
468
|
+
), /* @__PURE__ */ React7__namespace.createElement(
|
|
469
|
+
"div",
|
|
470
|
+
{
|
|
471
|
+
className: cn(
|
|
472
|
+
"flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
|
|
473
|
+
!error && isChecked && "border-primary bg-transparent",
|
|
474
|
+
!error && !isChecked && "border-input bg-transparent",
|
|
475
|
+
error && isChecked && "border-destructive bg-transparent",
|
|
476
|
+
error && !isChecked && "border-destructive bg-transparent",
|
|
477
|
+
isDisabled && "opacity-50",
|
|
478
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
479
|
+
)
|
|
480
|
+
},
|
|
481
|
+
isChecked && /* @__PURE__ */ React7__namespace.createElement("div", { className: "size-3 rounded-full bg-primary" })
|
|
482
|
+
));
|
|
483
|
+
const labelContent = /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, option.label), hasDescription && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs opacity-75", id: `${radioId}-description` }, option.description));
|
|
375
484
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
376
485
|
"label",
|
|
377
486
|
{
|
|
378
487
|
key: option.value,
|
|
379
|
-
className:
|
|
488
|
+
className: cn(
|
|
489
|
+
"w-full h-full flex gap-3 p-3 duration-200",
|
|
490
|
+
useChoiceCard && "border rounded-lg hover:ring-2",
|
|
491
|
+
useChoiceCard && isChecked && "ring-2",
|
|
492
|
+
isDisabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer"
|
|
493
|
+
),
|
|
380
494
|
htmlFor: radioId,
|
|
381
495
|
onKeyDown: (e) => handleKeyDown(e, index),
|
|
382
496
|
tabIndex: isDisabled ? -1 : 0
|
|
383
497
|
},
|
|
384
|
-
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" },
|
|
385
|
-
"p",
|
|
386
|
-
{
|
|
387
|
-
className: "text-muted-foreground text-sm",
|
|
388
|
-
id: `${radioId}-description`
|
|
389
|
-
},
|
|
390
|
-
option.description
|
|
391
|
-
)) : /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium" }, option.label)), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
392
|
-
"input",
|
|
393
|
-
{
|
|
394
|
-
type: "radio",
|
|
395
|
-
id: radioId,
|
|
396
|
-
name,
|
|
397
|
-
value: option.value,
|
|
398
|
-
checked: isChecked,
|
|
399
|
-
onChange: (e) => handleChange(e.target.value),
|
|
400
|
-
onBlur: handleBlur,
|
|
401
|
-
disabled: isDisabled,
|
|
402
|
-
required,
|
|
403
|
-
className: `peer relative flex aspect-square size-4 shrink-0 appearance-none rounded-full border border-input outline-none transition-colors focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 ${error ? "border-destructive" : ""} ${isChecked ? "border-primary bg-primary" : "bg-transparent"}`,
|
|
404
|
-
"aria-describedby": option.description ? `${radioId}-description` : props["aria-describedby"]
|
|
405
|
-
}
|
|
406
|
-
), isChecked && /* @__PURE__ */ React7__namespace.createElement("span", { className: "pointer-events-none absolute top-1/2 left-1/2 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center text-primary-foreground" }, /* @__PURE__ */ React7__namespace.createElement("svg", { className: "size-2 fill-current", viewBox: "0 0 24 24" }, /* @__PURE__ */ React7__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" })))))
|
|
498
|
+
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, !useChoiceCard && radioIndicator, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent), useChoiceCard && radioIndicator)
|
|
407
499
|
);
|
|
408
500
|
})
|
|
409
501
|
);
|
|
@@ -493,9 +585,7 @@ function Select({
|
|
|
493
585
|
if (enabledOptions.length > 0) {
|
|
494
586
|
const currentIndexInFiltered = focusedIndex;
|
|
495
587
|
const nextIndex = (currentIndexInFiltered + 1) % enabledOptions.length;
|
|
496
|
-
setFocusedIndex(
|
|
497
|
-
filteredOptions.indexOf(enabledOptions[nextIndex])
|
|
498
|
-
);
|
|
588
|
+
setFocusedIndex(filteredOptions.indexOf(enabledOptions[nextIndex]));
|
|
499
589
|
}
|
|
500
590
|
}
|
|
501
591
|
break;
|
|
@@ -506,9 +596,7 @@ function Select({
|
|
|
506
596
|
if (enabledOptions.length > 0) {
|
|
507
597
|
const currentIndexInFiltered = focusedIndex;
|
|
508
598
|
const prevIndex = (currentIndexInFiltered - 1 + enabledOptions.length) % enabledOptions.length;
|
|
509
|
-
setFocusedIndex(
|
|
510
|
-
filteredOptions.indexOf(enabledOptions[prevIndex])
|
|
511
|
-
);
|
|
599
|
+
setFocusedIndex(filteredOptions.indexOf(enabledOptions[prevIndex]));
|
|
512
600
|
}
|
|
513
601
|
}
|
|
514
602
|
break;
|
|
@@ -598,7 +686,7 @@ function Select({
|
|
|
598
686
|
/* @__PURE__ */ React7__namespace.createElement(
|
|
599
687
|
"div",
|
|
600
688
|
{
|
|
601
|
-
className: `flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm cursor-pointer transition-colors hover:bg-
|
|
689
|
+
className: `flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm cursor-pointer transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring ${disabled ? "cursor-not-allowed opacity-50 pointer-events-none" : ""} ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
|
|
602
690
|
onClick: handleToggle,
|
|
603
691
|
role: "combobox",
|
|
604
692
|
"aria-expanded": isOpen,
|
|
@@ -609,48 +697,76 @@ function Select({
|
|
|
609
697
|
"aria-disabled": disabled,
|
|
610
698
|
tabIndex: disabled ? -1 : 0
|
|
611
699
|
},
|
|
612
|
-
/* @__PURE__ */ React7__namespace.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7__namespace.createElement("span", { className: "
|
|
700
|
+
/* @__PURE__ */ React7__namespace.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7__namespace.createElement("span", { className: "relative" }, placeholder)),
|
|
613
701
|
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value && !disabled && !loading && /* @__PURE__ */ React7__namespace.createElement(
|
|
614
702
|
"button",
|
|
615
703
|
{
|
|
616
704
|
type: "button",
|
|
617
|
-
className: "flex items-center justify-center h-4 w-4 rounded-sm border-none bg-transparent
|
|
705
|
+
className: "flex items-center justify-center h-4 w-4 rounded-sm border-none bg-transparent cursor-pointer text-xs p-0 transition-opacity hover:opacity-70",
|
|
618
706
|
onClick: handleClear,
|
|
619
707
|
"aria-label": "Clear selection",
|
|
620
708
|
tabIndex: -1
|
|
621
709
|
},
|
|
622
710
|
"\u2715"
|
|
623
|
-
), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-
|
|
711
|
+
), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
|
|
624
712
|
),
|
|
625
|
-
isOpen && /* @__PURE__ */ React7__namespace.createElement(
|
|
626
|
-
"
|
|
713
|
+
isOpen && /* @__PURE__ */ React7__namespace.createElement(
|
|
714
|
+
"div",
|
|
627
715
|
{
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
(
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
716
|
+
id: dropdownId,
|
|
717
|
+
className: "absolute z-50 top-full mt-1 min-w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
|
|
718
|
+
role: "listbox"
|
|
719
|
+
},
|
|
720
|
+
searchable && /* @__PURE__ */ React7__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
721
|
+
"input",
|
|
722
|
+
{
|
|
723
|
+
ref: searchInputRef,
|
|
724
|
+
type: "text",
|
|
725
|
+
className: "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
|
|
726
|
+
placeholder: "Search...",
|
|
727
|
+
value: searchQuery,
|
|
728
|
+
onChange: handleSearchChange,
|
|
729
|
+
onClick: (e) => e.stopPropagation(),
|
|
730
|
+
"aria-label": "Search options"
|
|
731
|
+
}
|
|
732
|
+
)),
|
|
733
|
+
/* @__PURE__ */ React7__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
|
|
734
|
+
// Render grouped options
|
|
735
|
+
optionGroups.map((group, groupIndex) => {
|
|
736
|
+
const groupOptions = group.options.filter(
|
|
737
|
+
(opt) => filteredOptions.includes(opt)
|
|
738
|
+
);
|
|
739
|
+
if (groupOptions.length === 0) return null;
|
|
740
|
+
return /* @__PURE__ */ React7__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
|
|
741
|
+
const globalIndex = filteredOptions.indexOf(option);
|
|
742
|
+
const isSelected = value === option.value;
|
|
743
|
+
const isFocused = globalIndex === focusedIndex;
|
|
744
|
+
const isDisabled = option.disabled;
|
|
745
|
+
return /* @__PURE__ */ React7__namespace.createElement(
|
|
746
|
+
"div",
|
|
747
|
+
{
|
|
748
|
+
key: option.value,
|
|
749
|
+
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
|
|
750
|
+
onClick: () => !isDisabled && handleSelect(option.value),
|
|
751
|
+
role: "option",
|
|
752
|
+
"aria-selected": isSelected,
|
|
753
|
+
"aria-disabled": isDisabled
|
|
754
|
+
},
|
|
755
|
+
renderOption ? renderOption(option) : option.label
|
|
756
|
+
);
|
|
757
|
+
}));
|
|
758
|
+
})
|
|
759
|
+
) : (
|
|
760
|
+
// Render flat options
|
|
761
|
+
filteredOptions.map((option, index) => {
|
|
646
762
|
const isSelected = value === option.value;
|
|
647
|
-
const isFocused =
|
|
763
|
+
const isFocused = index === focusedIndex;
|
|
648
764
|
const isDisabled = option.disabled;
|
|
649
765
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
650
766
|
"div",
|
|
651
767
|
{
|
|
652
768
|
key: option.value,
|
|
653
|
-
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-
|
|
769
|
+
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
|
|
654
770
|
onClick: () => !isDisabled && handleSelect(option.value),
|
|
655
771
|
role: "option",
|
|
656
772
|
"aria-selected": isSelected,
|
|
@@ -658,28 +774,9 @@ function Select({
|
|
|
658
774
|
},
|
|
659
775
|
renderOption ? renderOption(option) : option.label
|
|
660
776
|
);
|
|
661
|
-
})
|
|
662
|
-
|
|
663
|
-
)
|
|
664
|
-
// Render flat options
|
|
665
|
-
filteredOptions.map((option, index) => {
|
|
666
|
-
const isSelected = value === option.value;
|
|
667
|
-
const isFocused = index === focusedIndex;
|
|
668
|
-
const isDisabled = option.disabled;
|
|
669
|
-
return /* @__PURE__ */ React7__namespace.createElement(
|
|
670
|
-
"div",
|
|
671
|
-
{
|
|
672
|
-
key: option.value,
|
|
673
|
-
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground ${isFocused ? "bg-accent text-accent-foreground" : ""} ${isSelected ? "font-medium bg-accent" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
|
|
674
|
-
onClick: () => !isDisabled && handleSelect(option.value),
|
|
675
|
-
role: "option",
|
|
676
|
-
"aria-selected": isSelected,
|
|
677
|
-
"aria-disabled": isDisabled
|
|
678
|
-
},
|
|
679
|
-
renderOption ? renderOption(option) : option.label
|
|
680
|
-
);
|
|
681
|
-
})
|
|
682
|
-
)))
|
|
777
|
+
})
|
|
778
|
+
))
|
|
779
|
+
)
|
|
683
780
|
);
|
|
684
781
|
}
|
|
685
782
|
Select.displayName = "Select";
|
|
@@ -688,7 +785,7 @@ function FileInput({
|
|
|
688
785
|
value = [],
|
|
689
786
|
onChange,
|
|
690
787
|
onBlur,
|
|
691
|
-
placeholder = "Choose file
|
|
788
|
+
placeholder = "Choose file...",
|
|
692
789
|
disabled = false,
|
|
693
790
|
required = false,
|
|
694
791
|
error = false,
|
|
@@ -791,7 +888,15 @@ function FileInput({
|
|
|
791
888
|
inputRef.current.value = "";
|
|
792
889
|
}
|
|
793
890
|
},
|
|
794
|
-
[
|
|
891
|
+
[
|
|
892
|
+
value,
|
|
893
|
+
onChange,
|
|
894
|
+
validateFile,
|
|
895
|
+
maxFiles,
|
|
896
|
+
multiple,
|
|
897
|
+
enableCropping,
|
|
898
|
+
onValidationError
|
|
899
|
+
]
|
|
795
900
|
);
|
|
796
901
|
const createCroppedImage = React7__namespace.useCallback(
|
|
797
902
|
async (imageUrl, cropArea) => {
|
|
@@ -817,13 +922,17 @@ function FileInput({
|
|
|
817
922
|
cropArea.width,
|
|
818
923
|
cropArea.height
|
|
819
924
|
);
|
|
820
|
-
canvas.toBlob(
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
925
|
+
canvas.toBlob(
|
|
926
|
+
(blob) => {
|
|
927
|
+
if (blob) {
|
|
928
|
+
resolve(blob);
|
|
929
|
+
} else {
|
|
930
|
+
reject(new Error("Failed to create blob from canvas"));
|
|
931
|
+
}
|
|
932
|
+
},
|
|
933
|
+
"image/jpeg",
|
|
934
|
+
0.95
|
|
935
|
+
);
|
|
827
936
|
};
|
|
828
937
|
image.onerror = () => {
|
|
829
938
|
reject(new Error("Failed to load image"));
|
|
@@ -843,11 +952,9 @@ function FileInput({
|
|
|
843
952
|
if (onCropComplete) {
|
|
844
953
|
onCropComplete(croppedBlob, imageToCrop.file);
|
|
845
954
|
}
|
|
846
|
-
const croppedFile = new File(
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
{ type: "image/jpeg" }
|
|
850
|
-
);
|
|
955
|
+
const croppedFile = new File([croppedBlob], imageToCrop.file.name, {
|
|
956
|
+
type: "image/jpeg"
|
|
957
|
+
});
|
|
851
958
|
const updatedFiles = multiple ? [...value, croppedFile] : [croppedFile];
|
|
852
959
|
onChange(updatedFiles);
|
|
853
960
|
setCropperOpen(false);
|
|
@@ -859,7 +966,15 @@ function FileInput({
|
|
|
859
966
|
} catch (error2) {
|
|
860
967
|
console.error("Failed to crop image:", error2);
|
|
861
968
|
}
|
|
862
|
-
}, [
|
|
969
|
+
}, [
|
|
970
|
+
imageToCrop,
|
|
971
|
+
croppedAreaPixels,
|
|
972
|
+
createCroppedImage,
|
|
973
|
+
onCropComplete,
|
|
974
|
+
value,
|
|
975
|
+
onChange,
|
|
976
|
+
multiple
|
|
977
|
+
]);
|
|
863
978
|
const handleCropCancel = React7__namespace.useCallback(() => {
|
|
864
979
|
if (imageToCrop) {
|
|
865
980
|
URL.revokeObjectURL(imageToCrop.url);
|
|
@@ -971,7 +1086,7 @@ function FileInput({
|
|
|
971
1086
|
), /* @__PURE__ */ React7__namespace.createElement(
|
|
972
1087
|
"div",
|
|
973
1088
|
{
|
|
974
|
-
className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-
|
|
1089
|
+
className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-primary/50 hover:border-ring ${dragActive ? "bg-primary text-primary-foreground border-ring" : ""} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${error ? "border-red-500" : ""}`,
|
|
975
1090
|
onDragEnter: handleDrag,
|
|
976
1091
|
onDragLeave: handleDrag,
|
|
977
1092
|
onDragOver: handleDrag,
|
|
@@ -986,7 +1101,6 @@ function FileInput({
|
|
|
986
1101
|
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
987
1102
|
"svg",
|
|
988
1103
|
{
|
|
989
|
-
className: "text-muted-foreground",
|
|
990
1104
|
width: "48",
|
|
991
1105
|
height: "48",
|
|
992
1106
|
viewBox: "0 0 24 24",
|
|
@@ -1000,92 +1114,102 @@ function FileInput({
|
|
|
1000
1114
|
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
1001
1115
|
/* @__PURE__ */ React7__namespace.createElement("polyline", { points: "17 8 12 3 7 8" }),
|
|
1002
1116
|
/* @__PURE__ */ React7__namespace.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
1003
|
-
), /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs
|
|
1117
|
+
), /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
|
|
1004
1118
|
), value.length > 0 && /* @__PURE__ */ React7__namespace.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
|
|
1005
1119
|
const previewUrl = showPreview ? getPreviewUrl(file) : null;
|
|
1006
|
-
return /* @__PURE__ */ React7__namespace.createElement(
|
|
1007
|
-
"
|
|
1008
|
-
{
|
|
1009
|
-
src: previewUrl,
|
|
1010
|
-
alt: file.name,
|
|
1011
|
-
className: "w-12 h-12 rounded object-cover",
|
|
1012
|
-
width: "48",
|
|
1013
|
-
height: "48"
|
|
1014
|
-
}
|
|
1015
|
-
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs text-muted-foreground" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1016
|
-
"div",
|
|
1120
|
+
return /* @__PURE__ */ React7__namespace.createElement(
|
|
1121
|
+
"li",
|
|
1017
1122
|
{
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
"aria-valuenow": uploadProgress[file.name],
|
|
1021
|
-
"aria-valuemin": 0,
|
|
1022
|
-
"aria-valuemax": 100,
|
|
1023
|
-
"aria-label": `Upload progress: ${uploadProgress[file.name]}%`
|
|
1123
|
+
key: `${file.name}-${index}`,
|
|
1124
|
+
className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
|
|
1024
1125
|
},
|
|
1025
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1026
|
-
"
|
|
1126
|
+
previewUrl && /* @__PURE__ */ React7__namespace.createElement(
|
|
1127
|
+
"img",
|
|
1027
1128
|
{
|
|
1028
|
-
|
|
1029
|
-
|
|
1129
|
+
src: previewUrl,
|
|
1130
|
+
alt: file.name,
|
|
1131
|
+
className: "w-12 h-12 rounded object-cover",
|
|
1132
|
+
width: "48",
|
|
1133
|
+
height: "48"
|
|
1030
1134
|
}
|
|
1031
|
-
)
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
{
|
|
1035
|
-
type: "button",
|
|
1036
|
-
onClick: (e) => {
|
|
1037
|
-
e.stopPropagation();
|
|
1038
|
-
handleCrop(file);
|
|
1039
|
-
},
|
|
1040
|
-
disabled,
|
|
1041
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
1042
|
-
"aria-label": `Crop ${file.name}`
|
|
1043
|
-
},
|
|
1044
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1045
|
-
"svg",
|
|
1135
|
+
),
|
|
1136
|
+
/* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1137
|
+
"div",
|
|
1046
1138
|
{
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
strokeLinecap: "round",
|
|
1054
|
-
strokeLinejoin: "round",
|
|
1055
|
-
"aria-hidden": "true"
|
|
1139
|
+
className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
|
|
1140
|
+
role: "progressbar",
|
|
1141
|
+
"aria-valuenow": uploadProgress[file.name],
|
|
1142
|
+
"aria-valuemin": 0,
|
|
1143
|
+
"aria-valuemax": 100,
|
|
1144
|
+
"aria-label": `Upload progress: ${uploadProgress[file.name]}%`
|
|
1056
1145
|
},
|
|
1057
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1146
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
1147
|
+
"div",
|
|
1148
|
+
{
|
|
1149
|
+
className: "h-full bg-primary transition-all",
|
|
1150
|
+
style: { width: `${uploadProgress[file.name]}%` }
|
|
1151
|
+
}
|
|
1152
|
+
)
|
|
1153
|
+
), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
|
|
1154
|
+
enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React7__namespace.createElement(
|
|
1155
|
+
"button",
|
|
1156
|
+
{
|
|
1157
|
+
type: "button",
|
|
1158
|
+
onClick: (e) => {
|
|
1159
|
+
e.stopPropagation();
|
|
1160
|
+
handleCrop(file);
|
|
1161
|
+
},
|
|
1162
|
+
disabled,
|
|
1163
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1164
|
+
"aria-label": `Crop ${file.name}`
|
|
1067
1165
|
},
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1166
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
1167
|
+
"svg",
|
|
1168
|
+
{
|
|
1169
|
+
width: "20",
|
|
1170
|
+
height: "20",
|
|
1171
|
+
viewBox: "0 0 24 24",
|
|
1172
|
+
fill: "none",
|
|
1173
|
+
stroke: "currentColor",
|
|
1174
|
+
strokeWidth: "2",
|
|
1175
|
+
strokeLinecap: "round",
|
|
1176
|
+
strokeLinejoin: "round",
|
|
1177
|
+
"aria-hidden": "true"
|
|
1178
|
+
},
|
|
1179
|
+
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
|
|
1180
|
+
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
|
|
1181
|
+
)
|
|
1182
|
+
),
|
|
1072
1183
|
/* @__PURE__ */ React7__namespace.createElement(
|
|
1073
|
-
"
|
|
1184
|
+
"button",
|
|
1074
1185
|
{
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
"aria-hidden": "true"
|
|
1186
|
+
type: "button",
|
|
1187
|
+
onClick: (e) => {
|
|
1188
|
+
e.stopPropagation();
|
|
1189
|
+
handleRemove(index);
|
|
1190
|
+
},
|
|
1191
|
+
disabled,
|
|
1192
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1193
|
+
"aria-label": `Remove ${file.name}`
|
|
1084
1194
|
},
|
|
1085
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1086
|
-
|
|
1195
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
1196
|
+
"svg",
|
|
1197
|
+
{
|
|
1198
|
+
width: "20",
|
|
1199
|
+
height: "20",
|
|
1200
|
+
viewBox: "0 0 24 24",
|
|
1201
|
+
fill: "none",
|
|
1202
|
+
stroke: "currentColor",
|
|
1203
|
+
strokeWidth: "2",
|
|
1204
|
+
strokeLinecap: "round",
|
|
1205
|
+
strokeLinejoin: "round",
|
|
1206
|
+
"aria-hidden": "true"
|
|
1207
|
+
},
|
|
1208
|
+
/* @__PURE__ */ React7__namespace.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1209
|
+
/* @__PURE__ */ React7__namespace.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1210
|
+
)
|
|
1087
1211
|
)
|
|
1088
|
-
)
|
|
1212
|
+
);
|
|
1089
1213
|
})), cropperOpen && imageToCrop && /* @__PURE__ */ React7__namespace.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1090
1214
|
"div",
|
|
1091
1215
|
{
|
|
@@ -1097,7 +1221,7 @@ function FileInput({
|
|
|
1097
1221
|
"button",
|
|
1098
1222
|
{
|
|
1099
1223
|
type: "button",
|
|
1100
|
-
className: "flex items-center justify-center h-8 w-8 rounded hover:bg-
|
|
1224
|
+
className: "flex items-center justify-center h-8 w-8 rounded hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1101
1225
|
onClick: handleCropCancel,
|
|
1102
1226
|
"aria-label": "Close"
|
|
1103
1227
|
},
|
|
@@ -1138,7 +1262,10 @@ function FileInput({
|
|
|
1138
1262
|
const img = e.currentTarget;
|
|
1139
1263
|
const containerWidth = 600;
|
|
1140
1264
|
const containerHeight = 400;
|
|
1141
|
-
const cropWidth = cropAspectRatio ? Math.min(
|
|
1265
|
+
const cropWidth = cropAspectRatio ? Math.min(
|
|
1266
|
+
containerWidth * 0.8,
|
|
1267
|
+
containerHeight * 0.8 * cropAspectRatio
|
|
1268
|
+
) : containerWidth * 0.8;
|
|
1142
1269
|
const cropHeight = cropAspectRatio ? cropWidth / cropAspectRatio : containerHeight * 0.8;
|
|
1143
1270
|
const scale = zoom;
|
|
1144
1271
|
const imgWidth = img.naturalWidth;
|
|
@@ -1167,7 +1294,16 @@ function FileInput({
|
|
|
1167
1294
|
},
|
|
1168
1295
|
/* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", null))
|
|
1169
1296
|
)
|
|
1170
|
-
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1297
|
+
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1298
|
+
"label",
|
|
1299
|
+
{
|
|
1300
|
+
htmlFor: "zoom-slider",
|
|
1301
|
+
className: "text-sm font-medium whitespace-nowrap"
|
|
1302
|
+
},
|
|
1303
|
+
"Zoom: ",
|
|
1304
|
+
zoom.toFixed(1),
|
|
1305
|
+
"x"
|
|
1306
|
+
), /* @__PURE__ */ React7__namespace.createElement(
|
|
1171
1307
|
"input",
|
|
1172
1308
|
{
|
|
1173
1309
|
id: "zoom-slider",
|
|
@@ -1184,7 +1320,7 @@ function FileInput({
|
|
|
1184
1320
|
"button",
|
|
1185
1321
|
{
|
|
1186
1322
|
type: "button",
|
|
1187
|
-
className: "inline-flex items-center justify-center h-9 rounded-md px-4 text-sm font-medium border border-input bg-transparent hover:bg-
|
|
1323
|
+
className: "inline-flex items-center justify-center h-9 rounded-md px-4 text-sm font-medium border border-input bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1188
1324
|
onClick: handleCropCancel
|
|
1189
1325
|
},
|
|
1190
1326
|
"Cancel"
|
|
@@ -1253,7 +1389,9 @@ function DatePicker({
|
|
|
1253
1389
|
}) {
|
|
1254
1390
|
const [isOpen, setIsOpen] = React7__namespace.useState(false);
|
|
1255
1391
|
const [inputValue, setInputValue] = React7__namespace.useState("");
|
|
1256
|
-
const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
|
|
1392
|
+
const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
|
|
1393
|
+
value || /* @__PURE__ */ new Date()
|
|
1394
|
+
);
|
|
1257
1395
|
const containerRef = React7__namespace.useRef(null);
|
|
1258
1396
|
const inputRef = React7__namespace.useRef(null);
|
|
1259
1397
|
React7__namespace.useEffect(() => {
|
|
@@ -1344,7 +1482,7 @@ function DatePicker({
|
|
|
1344
1482
|
"button",
|
|
1345
1483
|
{
|
|
1346
1484
|
type: "button",
|
|
1347
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1485
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
|
|
1348
1486
|
onClick: handlePrevMonth,
|
|
1349
1487
|
"aria-label": "Previous month"
|
|
1350
1488
|
},
|
|
@@ -1353,12 +1491,19 @@ function DatePicker({
|
|
|
1353
1491
|
"button",
|
|
1354
1492
|
{
|
|
1355
1493
|
type: "button",
|
|
1356
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1494
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
|
|
1357
1495
|
onClick: handleNextMonth,
|
|
1358
1496
|
"aria-label": "Next month"
|
|
1359
1497
|
},
|
|
1360
1498
|
"\u2192"
|
|
1361
|
-
)), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement(
|
|
1499
|
+
)), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement(
|
|
1500
|
+
"div",
|
|
1501
|
+
{
|
|
1502
|
+
key: day,
|
|
1503
|
+
className: "flex items-center justify-center h-8 w-full text-xs font-medium"
|
|
1504
|
+
},
|
|
1505
|
+
day
|
|
1506
|
+
))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
|
|
1362
1507
|
if (!date) {
|
|
1363
1508
|
return /* @__PURE__ */ React7__namespace.createElement("div", { key: `empty-${index}` });
|
|
1364
1509
|
}
|
|
@@ -1370,7 +1515,7 @@ function DatePicker({
|
|
|
1370
1515
|
{
|
|
1371
1516
|
key: date.toISOString(),
|
|
1372
1517
|
type: "button",
|
|
1373
|
-
className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-
|
|
1518
|
+
className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-primary hover:text-primary-foreground ${isSelected ? "bg-primary text-primary-foreground font-semibold" : ""} ${isToday ? "border border-primary" : ""} ${disabled2 ? "cursor-not-allowed opacity-50 pointer-events-none" : ""}`,
|
|
1374
1519
|
onClick: () => !disabled2 && handleDateSelect(date),
|
|
1375
1520
|
disabled: disabled2,
|
|
1376
1521
|
"aria-label": formatDate(date, format)
|
|
@@ -1387,26 +1532,33 @@ function DatePicker({
|
|
|
1387
1532
|
name,
|
|
1388
1533
|
value: value ? value.toISOString() : ""
|
|
1389
1534
|
}
|
|
1390
|
-
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
1391
|
-
"
|
|
1535
|
+
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
1536
|
+
"span",
|
|
1392
1537
|
{
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
height: "18",
|
|
1396
|
-
viewBox: "0 0 24 24",
|
|
1397
|
-
fill: "none",
|
|
1398
|
-
stroke: "currentColor",
|
|
1399
|
-
strokeLinecap: "round",
|
|
1400
|
-
strokeLinejoin: "round",
|
|
1401
|
-
strokeWidth: "2"
|
|
1538
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1539
|
+
"aria-hidden": "true"
|
|
1402
1540
|
},
|
|
1403
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1404
|
-
|
|
1541
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
1542
|
+
"svg",
|
|
1543
|
+
{
|
|
1544
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1545
|
+
width: "18",
|
|
1546
|
+
height: "18",
|
|
1547
|
+
viewBox: "0 0 24 24",
|
|
1548
|
+
fill: "none",
|
|
1549
|
+
stroke: "currentColor",
|
|
1550
|
+
strokeLinecap: "round",
|
|
1551
|
+
strokeLinejoin: "round",
|
|
1552
|
+
strokeWidth: "2"
|
|
1553
|
+
},
|
|
1554
|
+
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
|
|
1555
|
+
)
|
|
1556
|
+
), /* @__PURE__ */ React7__namespace.createElement(
|
|
1405
1557
|
"input",
|
|
1406
1558
|
{
|
|
1407
1559
|
ref: inputRef,
|
|
1408
1560
|
type: "text",
|
|
1409
|
-
className: `flex h-9 w-full rounded-md border border-input bg-transparent ${showIcon ? "pl-10" : "pl-3"} ${clearable && value ? "pr-10" : "pr-3"} py-1 text-base shadow-sm transition-colors
|
|
1561
|
+
className: `flex h-9 w-full rounded-md border border-input bg-transparent ${showIcon ? "pl-10" : "pl-3"} ${clearable && value ? "pr-10" : "pr-3"} py-1 text-base shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
|
|
1410
1562
|
value: inputValue,
|
|
1411
1563
|
onChange: handleInputChange,
|
|
1412
1564
|
onClick: handleToggle,
|
|
@@ -1423,7 +1575,7 @@ function DatePicker({
|
|
|
1423
1575
|
"button",
|
|
1424
1576
|
{
|
|
1425
1577
|
type: "button",
|
|
1426
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2
|
|
1578
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
|
|
1427
1579
|
onClick: handleClear,
|
|
1428
1580
|
"aria-label": "Clear date",
|
|
1429
1581
|
tabIndex: -1
|
|
@@ -1562,36 +1714,43 @@ function TimePicker({
|
|
|
1562
1714
|
}
|
|
1563
1715
|
return mins;
|
|
1564
1716
|
}, [minuteStep]);
|
|
1565
|
-
const combinedClassName =
|
|
1717
|
+
const combinedClassName = cn("relative", className);
|
|
1566
1718
|
const displayValue = formatTimeValue(timeValue, use24Hour);
|
|
1567
|
-
return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1568
|
-
"
|
|
1719
|
+
return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
1720
|
+
"span",
|
|
1569
1721
|
{
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
value
|
|
1573
|
-
}
|
|
1574
|
-
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none", "aria-hidden": "true" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1575
|
-
"svg",
|
|
1576
|
-
{
|
|
1577
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1578
|
-
width: "18",
|
|
1579
|
-
height: "18",
|
|
1580
|
-
viewBox: "0 0 24 24",
|
|
1581
|
-
fill: "none",
|
|
1582
|
-
stroke: "currentColor",
|
|
1583
|
-
strokeLinecap: "round",
|
|
1584
|
-
strokeLinejoin: "round",
|
|
1585
|
-
strokeWidth: "2"
|
|
1722
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1723
|
+
"aria-hidden": "true"
|
|
1586
1724
|
},
|
|
1587
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1588
|
-
|
|
1589
|
-
|
|
1725
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
1726
|
+
"svg",
|
|
1727
|
+
{
|
|
1728
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1729
|
+
width: "18",
|
|
1730
|
+
height: "18",
|
|
1731
|
+
viewBox: "0 0 24 24",
|
|
1732
|
+
fill: "none",
|
|
1733
|
+
stroke: "currentColor",
|
|
1734
|
+
strokeLinecap: "round",
|
|
1735
|
+
strokeLinejoin: "round",
|
|
1736
|
+
strokeWidth: "2"
|
|
1737
|
+
},
|
|
1738
|
+
/* @__PURE__ */ React7__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1739
|
+
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M12 6v6l4 2" })
|
|
1740
|
+
)
|
|
1741
|
+
), /* @__PURE__ */ React7__namespace.createElement(
|
|
1590
1742
|
"input",
|
|
1591
1743
|
{
|
|
1592
1744
|
ref: inputRef,
|
|
1593
1745
|
type: "text",
|
|
1594
|
-
className:
|
|
1746
|
+
className: cn(
|
|
1747
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
|
|
1748
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1749
|
+
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1750
|
+
showIcon ? "pl-10" : "pl-3",
|
|
1751
|
+
clearable && value ? "pr-10" : "pr-3",
|
|
1752
|
+
error && "border-red-500 ring-1 ring-red-500"
|
|
1753
|
+
),
|
|
1595
1754
|
value: displayValue,
|
|
1596
1755
|
onClick: handleToggle,
|
|
1597
1756
|
onBlur,
|
|
@@ -1607,13 +1766,13 @@ function TimePicker({
|
|
|
1607
1766
|
"button",
|
|
1608
1767
|
{
|
|
1609
1768
|
type: "button",
|
|
1610
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2
|
|
1769
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
|
|
1611
1770
|
onClick: handleClear,
|
|
1612
1771
|
"aria-label": "Clear time",
|
|
1613
1772
|
tabIndex: -1
|
|
1614
1773
|
},
|
|
1615
1774
|
"\u2715"
|
|
1616
|
-
)), isOpen && !disabled && /* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium
|
|
1775
|
+
)), isOpen && !disabled && /* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, use24Hour ? "Hour" : "Hour"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, hours.map((hour) => {
|
|
1617
1776
|
const displayHour = use24Hour ? hour : hour;
|
|
1618
1777
|
const isSelected = use24Hour ? timeValue?.hour === (hour === 0 ? 12 : hour > 12 ? hour - 12 : hour) && timeValue?.period === (hour >= 12 ? "PM" : "AM") : timeValue?.hour === hour;
|
|
1619
1778
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
@@ -1621,7 +1780,12 @@ function TimePicker({
|
|
|
1621
1780
|
{
|
|
1622
1781
|
key: hour,
|
|
1623
1782
|
type: "button",
|
|
1624
|
-
className:
|
|
1783
|
+
className: cn(
|
|
1784
|
+
"flex items-center justify-center h-8 w-full rounded",
|
|
1785
|
+
"border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
1786
|
+
"hover:bg-primary hover:text-primary-foreground",
|
|
1787
|
+
isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
|
|
1788
|
+
),
|
|
1625
1789
|
onClick: () => {
|
|
1626
1790
|
if (use24Hour) {
|
|
1627
1791
|
const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
|
|
@@ -1641,24 +1805,34 @@ function TimePicker({
|
|
|
1641
1805
|
},
|
|
1642
1806
|
String(displayHour).padStart(2, "0")
|
|
1643
1807
|
);
|
|
1644
|
-
}))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium
|
|
1808
|
+
}))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
|
|
1645
1809
|
const isSelected = timeValue?.minute === minute;
|
|
1646
1810
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
1647
1811
|
"button",
|
|
1648
1812
|
{
|
|
1649
1813
|
key: minute,
|
|
1650
1814
|
type: "button",
|
|
1651
|
-
className:
|
|
1815
|
+
className: cn(
|
|
1816
|
+
"flex items-center justify-center h-8 w-full",
|
|
1817
|
+
"rounded border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
1818
|
+
"hover:bg-primary hover:text-primary-foreground",
|
|
1819
|
+
isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
|
|
1820
|
+
),
|
|
1652
1821
|
onClick: () => handleMinuteChange(minute),
|
|
1653
1822
|
"aria-label": `${String(minute).padStart(2, "0")} minutes`
|
|
1654
1823
|
},
|
|
1655
1824
|
String(minute).padStart(2, "0")
|
|
1656
1825
|
);
|
|
1657
|
-
}))), !use24Hour && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium
|
|
1826
|
+
}))), !use24Hour && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Period"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1658
1827
|
"button",
|
|
1659
1828
|
{
|
|
1660
1829
|
type: "button",
|
|
1661
|
-
className:
|
|
1830
|
+
className: cn(
|
|
1831
|
+
"flex items-center justify-center h-8 w-full",
|
|
1832
|
+
"rounded border-none bg-transparent cursor-pointer text-sm",
|
|
1833
|
+
"transition-colors hover:bg-primary hover:text-primary-foreground",
|
|
1834
|
+
timeValue?.period === "AM" ? "bg-muted font-semibold" : ""
|
|
1835
|
+
),
|
|
1662
1836
|
onClick: () => handlePeriodChange("AM")
|
|
1663
1837
|
},
|
|
1664
1838
|
"AM"
|
|
@@ -1666,7 +1840,12 @@ function TimePicker({
|
|
|
1666
1840
|
"button",
|
|
1667
1841
|
{
|
|
1668
1842
|
type: "button",
|
|
1669
|
-
className:
|
|
1843
|
+
className: cn(
|
|
1844
|
+
"flex items-center justify-center h-8 w-full",
|
|
1845
|
+
"rounded border-none bg-transparent cursor-pointer text-sm",
|
|
1846
|
+
"transition-colors hover:bg-primary hover:text-primary-foreground",
|
|
1847
|
+
timeValue?.period === "PM" ? "bg-muted font-semibold" : ""
|
|
1848
|
+
),
|
|
1670
1849
|
onClick: () => handlePeriodChange("PM")
|
|
1671
1850
|
},
|
|
1672
1851
|
"PM"
|
|
@@ -1711,7 +1890,9 @@ function DateRangePicker({
|
|
|
1711
1890
|
...props
|
|
1712
1891
|
}) {
|
|
1713
1892
|
const [isOpen, setIsOpen] = React7__namespace.useState(false);
|
|
1714
|
-
const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
|
|
1893
|
+
const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
|
|
1894
|
+
value.start || /* @__PURE__ */ new Date()
|
|
1895
|
+
);
|
|
1715
1896
|
const [rangeStart, setRangeStart] = React7__namespace.useState(value.start);
|
|
1716
1897
|
const [rangeEnd, setRangeEnd] = React7__namespace.useState(value.end);
|
|
1717
1898
|
const [hoverDate, setHoverDate] = React7__namespace.useState(null);
|
|
@@ -1809,7 +1990,7 @@ function DateRangePicker({
|
|
|
1809
1990
|
"button",
|
|
1810
1991
|
{
|
|
1811
1992
|
type: "button",
|
|
1812
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1993
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
|
|
1813
1994
|
onClick: handlePrevMonth,
|
|
1814
1995
|
"aria-label": "Previous month"
|
|
1815
1996
|
},
|
|
@@ -1818,19 +1999,30 @@ function DateRangePicker({
|
|
|
1818
1999
|
"button",
|
|
1819
2000
|
{
|
|
1820
2001
|
type: "button",
|
|
1821
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
2002
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
|
|
1822
2003
|
onClick: handleNextMonth,
|
|
1823
2004
|
"aria-label": "Next month"
|
|
1824
2005
|
},
|
|
1825
2006
|
"\u2192"
|
|
1826
|
-
)), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement(
|
|
2007
|
+
)), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement(
|
|
2008
|
+
"div",
|
|
2009
|
+
{
|
|
2010
|
+
key: day,
|
|
2011
|
+
className: "flex items-center justify-center h-8 w-full text-xs font-medium"
|
|
2012
|
+
},
|
|
2013
|
+
day
|
|
2014
|
+
))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
|
|
1827
2015
|
if (!date) {
|
|
1828
2016
|
return /* @__PURE__ */ React7__namespace.createElement("div", { key: `empty-${index}` });
|
|
1829
2017
|
}
|
|
1830
2018
|
const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
|
|
1831
2019
|
const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
|
|
2020
|
+
const isRangeEndpoint = Boolean(isStart || isEnd);
|
|
1832
2021
|
const isInRange = rangeStart && rangeEnd && isDateInRange(date, rangeStart, rangeEnd);
|
|
1833
2022
|
const isInHoverRange = rangeStart && !rangeEnd && hoverDate && (date >= rangeStart && date <= hoverDate || date <= rangeStart && date >= hoverDate);
|
|
2023
|
+
const isRangeHighlight = Boolean(
|
|
2024
|
+
(isInRange || isInHoverRange) && !isRangeEndpoint
|
|
2025
|
+
);
|
|
1834
2026
|
const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
1835
2027
|
const disabled2 = isDisabled(date);
|
|
1836
2028
|
return /* @__PURE__ */ React7__namespace.createElement(
|
|
@@ -1838,7 +2030,14 @@ function DateRangePicker({
|
|
|
1838
2030
|
{
|
|
1839
2031
|
key: date.toISOString(),
|
|
1840
2032
|
type: "button",
|
|
1841
|
-
className:
|
|
2033
|
+
className: cn(
|
|
2034
|
+
"flex items-center justify-center h-8 w-full rounded border-none bg-transparent",
|
|
2035
|
+
"cursor-pointer text-sm transition-colors hover:bg-muted",
|
|
2036
|
+
isRangeEndpoint && "bg-muted font-semibold",
|
|
2037
|
+
isRangeHighlight && "bg-muted/70",
|
|
2038
|
+
isToday && "border border-primary",
|
|
2039
|
+
disabled2 && "cursor-not-allowed opacity-50 pointer-events-none"
|
|
2040
|
+
),
|
|
1842
2041
|
onClick: () => !disabled2 && handleDateSelect(date),
|
|
1843
2042
|
onMouseEnter: () => setHoverDate(date),
|
|
1844
2043
|
onMouseLeave: () => setHoverDate(null),
|
|
@@ -1849,7 +2048,7 @@ function DateRangePicker({
|
|
|
1849
2048
|
);
|
|
1850
2049
|
})));
|
|
1851
2050
|
};
|
|
1852
|
-
const combinedClassName =
|
|
2051
|
+
const combinedClassName = cn("relative", className);
|
|
1853
2052
|
const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
|
|
1854
2053
|
return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1855
2054
|
"input",
|
|
@@ -1865,25 +2064,39 @@ function DateRangePicker({
|
|
|
1865
2064
|
name: `${name}[end]`,
|
|
1866
2065
|
value: rangeEnd ? rangeEnd.toISOString() : ""
|
|
1867
2066
|
}
|
|
1868
|
-
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
1869
|
-
"
|
|
2067
|
+
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
2068
|
+
"span",
|
|
1870
2069
|
{
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
height: "18",
|
|
1874
|
-
viewBox: "0 0 24 24",
|
|
1875
|
-
fill: "none",
|
|
1876
|
-
stroke: "currentColor",
|
|
1877
|
-
strokeLinecap: "round",
|
|
1878
|
-
strokeLinejoin: "round",
|
|
1879
|
-
strokeWidth: "2"
|
|
2070
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
2071
|
+
"aria-hidden": "true"
|
|
1880
2072
|
},
|
|
1881
|
-
/* @__PURE__ */ React7__namespace.createElement(
|
|
1882
|
-
|
|
2073
|
+
/* @__PURE__ */ React7__namespace.createElement(
|
|
2074
|
+
"svg",
|
|
2075
|
+
{
|
|
2076
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2077
|
+
width: "18",
|
|
2078
|
+
height: "18",
|
|
2079
|
+
viewBox: "0 0 24 24",
|
|
2080
|
+
fill: "none",
|
|
2081
|
+
stroke: "currentColor",
|
|
2082
|
+
strokeLinecap: "round",
|
|
2083
|
+
strokeLinejoin: "round",
|
|
2084
|
+
strokeWidth: "2"
|
|
2085
|
+
},
|
|
2086
|
+
/* @__PURE__ */ React7__namespace.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
|
|
2087
|
+
)
|
|
2088
|
+
), /* @__PURE__ */ React7__namespace.createElement(
|
|
1883
2089
|
"input",
|
|
1884
2090
|
{
|
|
1885
2091
|
type: "text",
|
|
1886
|
-
className:
|
|
2092
|
+
className: cn(
|
|
2093
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
|
|
2094
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2095
|
+
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
2096
|
+
showIcon ? "pl-10" : "pl-3",
|
|
2097
|
+
clearable && (rangeStart || rangeEnd) ? "pr-10" : "pr-3",
|
|
2098
|
+
error && "border-red-500 ring-1 ring-red-500"
|
|
2099
|
+
),
|
|
1887
2100
|
value: displayValue,
|
|
1888
2101
|
onClick: handleToggle,
|
|
1889
2102
|
onBlur,
|
|
@@ -1899,13 +2112,13 @@ function DateRangePicker({
|
|
|
1899
2112
|
"button",
|
|
1900
2113
|
{
|
|
1901
2114
|
type: "button",
|
|
1902
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2
|
|
2115
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
|
|
1903
2116
|
onClick: handleClear,
|
|
1904
2117
|
"aria-label": "Clear date range",
|
|
1905
2118
|
tabIndex: -1
|
|
1906
2119
|
},
|
|
1907
2120
|
"\u2715"
|
|
1908
|
-
)), isOpen && !disabled && /* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, renderCalendar(), rangeStart && !rangeEnd && /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs text-
|
|
2121
|
+
)), isOpen && !disabled && /* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, renderCalendar(), rangeStart && !rangeEnd && /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")));
|
|
1909
2122
|
}
|
|
1910
2123
|
DateRangePicker.displayName = "DateRangePicker";
|
|
1911
2124
|
function htmlToMarkdown(html) {
|
|
@@ -1961,11 +2174,19 @@ function RichTextEditor({
|
|
|
1961
2174
|
className = "",
|
|
1962
2175
|
mode = "wysiwyg",
|
|
1963
2176
|
allowModeSwitch = false,
|
|
1964
|
-
placeholder = "
|
|
2177
|
+
placeholder = "Your message...",
|
|
1965
2178
|
minHeight = "200px",
|
|
1966
2179
|
maxHeight,
|
|
1967
2180
|
showToolbar = true,
|
|
1968
|
-
toolbarButtons = [
|
|
2181
|
+
toolbarButtons = [
|
|
2182
|
+
"bold",
|
|
2183
|
+
"italic",
|
|
2184
|
+
"underline",
|
|
2185
|
+
"heading",
|
|
2186
|
+
"bulletList",
|
|
2187
|
+
"orderedList",
|
|
2188
|
+
"link"
|
|
2189
|
+
],
|
|
1969
2190
|
...props
|
|
1970
2191
|
}) {
|
|
1971
2192
|
const [currentMode, setCurrentMode] = React7__namespace.useState(mode);
|
|
@@ -2074,7 +2295,7 @@ function RichTextEditor({
|
|
|
2074
2295
|
{
|
|
2075
2296
|
key: buttonName,
|
|
2076
2297
|
type: "button",
|
|
2077
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
2298
|
+
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-muted cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
2078
2299
|
onClick: () => editorRef.current && button.action(editorRef.current),
|
|
2079
2300
|
title: button.title,
|
|
2080
2301
|
disabled: disabled || currentMode === "markdown",
|
|
@@ -2086,7 +2307,7 @@ function RichTextEditor({
|
|
|
2086
2307
|
"button",
|
|
2087
2308
|
{
|
|
2088
2309
|
type: "button",
|
|
2089
|
-
className: "flex items-center justify-center h-8 px-3 rounded border-none bg-transparent hover:bg-
|
|
2310
|
+
className: "flex items-center justify-center h-8 px-3 rounded border-none bg-transparent hover:bg-muted text-xs font-medium cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
2090
2311
|
onClick: handleModeToggle,
|
|
2091
2312
|
disabled,
|
|
2092
2313
|
title: `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`,
|
|
@@ -2097,7 +2318,7 @@ function RichTextEditor({
|
|
|
2097
2318
|
"div",
|
|
2098
2319
|
{
|
|
2099
2320
|
ref: editorRef,
|
|
2100
|
-
className: "w-full p-3 text-base md:text-sm outline-none bg-transparent focus-visible:outline-none [&:empty:before]:content-[attr(data-placeholder)]
|
|
2321
|
+
className: "w-full p-3 text-base md:text-sm outline-none bg-transparent focus-visible:outline-none [&:empty:before]:content-[attr(data-placeholder)]",
|
|
2101
2322
|
role: "textbox",
|
|
2102
2323
|
contentEditable: !disabled,
|
|
2103
2324
|
onInput: handleWysiwygChange,
|
|
@@ -2112,7 +2333,7 @@ function RichTextEditor({
|
|
|
2112
2333
|
"textarea",
|
|
2113
2334
|
{
|
|
2114
2335
|
ref: textareaRef,
|
|
2115
|
-
className: "w-full p-3 text-base md:text-sm outline-none bg-transparent resize-none focus-visible:outline-none
|
|
2336
|
+
className: "w-full p-3 text-base md:text-sm outline-none bg-transparent resize-none focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
2116
2337
|
value: content,
|
|
2117
2338
|
onChange: handleMarkdownChange,
|
|
2118
2339
|
onBlur,
|