@yca-software/yca-react-core 0.0.22 → 0.0.24
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 +12 -1
- package/dist/api/index.d.ts +7 -2
- package/dist/api/index.js +1 -1
- package/dist/{chunk-WZ64FPVI.js → chunk-BL4GPQGY.js} +32 -23
- package/dist/chunk-BL4GPQGY.js.map +1 -0
- package/dist/{chunk-QHNZTXPJ.js → chunk-GDYI2I74.js} +391 -139
- package/dist/chunk-GDYI2I74.js.map +1 -0
- package/dist/{chunk-HJZNKZHZ.js → chunk-L4KNKLFW.js} +3 -3
- package/dist/{chunk-HJZNKZHZ.js.map → chunk-L4KNKLFW.js.map} +1 -1
- package/dist/{chunk-2HTQDFQJ.js → chunk-V6EYEN2F.js} +18 -5
- package/dist/chunk-V6EYEN2F.js.map +1 -0
- package/dist/components/forms/index.js +2 -2
- package/dist/components/spa/index.d.ts +7 -2
- package/dist/components/spa/index.js +2 -2
- package/dist/components/ui/index.d.ts +46 -17
- package/dist/components/ui/index.js +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/{types-CN73TWSY.d.ts → types-BYLBukHJ.d.ts} +5 -0
- package/package.json +1 -1
- package/dist/chunk-2HTQDFQJ.js.map +0 -1
- package/dist/chunk-QHNZTXPJ.js.map +0 -1
- package/dist/chunk-WZ64FPVI.js.map +0 -1
|
@@ -4,10 +4,10 @@ import { cn, surfaceOverlay, controlFocus, controlInvalid, controlBase, surfaceC
|
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
7
|
-
import * as
|
|
7
|
+
import * as React20 from 'react';
|
|
8
8
|
import { useRef, useId, useState, useEffect } from 'react';
|
|
9
9
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
10
|
-
import { Check, Calendar as Calendar$1, ChevronLeft, ChevronRight, Loader2, XIcon, ChevronUp, ChevronDown, X, CheckSquare, Search, FileText, ImagePlus, UploadCloud } from 'lucide-react';
|
|
10
|
+
import { Check, Calendar as Calendar$1, ChevronLeft, ChevronRight, Loader2, XIcon, ChevronUp, ChevronDown, Info, X, CheckSquare, Search, FileText, ImagePlus, UploadCloud } from 'lucide-react';
|
|
11
11
|
import { DayPicker } from 'react-day-picker';
|
|
12
12
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
13
13
|
import { format, isSameMonth, isSameDay, addDays, startOfMonth, startOfDay, endOfDay, isWithinInterval, addMonths, addWeeks, startOfWeek, endOfWeek, parse } from 'date-fns';
|
|
@@ -68,7 +68,7 @@ function AlertDescription({ className, ...props }) {
|
|
|
68
68
|
var AlertDialog = AlertDialogPrimitive.Root;
|
|
69
69
|
var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
70
70
|
var AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
71
|
-
var AlertDialogOverlay =
|
|
71
|
+
var AlertDialogOverlay = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
72
72
|
AlertDialogPrimitive.Overlay,
|
|
73
73
|
{
|
|
74
74
|
className: cn(
|
|
@@ -80,7 +80,7 @@ var AlertDialogOverlay = React8.forwardRef(({ className, ...props }, ref) => /*
|
|
|
80
80
|
}
|
|
81
81
|
));
|
|
82
82
|
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
83
|
-
var AlertDialogContent =
|
|
83
|
+
var AlertDialogContent = React20.forwardRef(({ className, onOverlayClick, overlayClassName, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
|
|
84
84
|
/* @__PURE__ */ jsx(AlertDialogOverlay, { onClick: onOverlayClick, className: overlayClassName }),
|
|
85
85
|
/* @__PURE__ */ jsx(
|
|
86
86
|
AlertDialogPrimitive.Content,
|
|
@@ -106,7 +106,7 @@ var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
|
106
106
|
}
|
|
107
107
|
);
|
|
108
108
|
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
109
|
-
var AlertDialogTitle =
|
|
109
|
+
var AlertDialogTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
110
110
|
AlertDialogPrimitive.Title,
|
|
111
111
|
{
|
|
112
112
|
ref,
|
|
@@ -115,7 +115,7 @@ var AlertDialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
115
115
|
}
|
|
116
116
|
));
|
|
117
117
|
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
118
|
-
var AlertDialogDescription =
|
|
118
|
+
var AlertDialogDescription = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
119
119
|
AlertDialogPrimitive.Description,
|
|
120
120
|
{
|
|
121
121
|
ref,
|
|
@@ -124,7 +124,7 @@ var AlertDialogDescription = React8.forwardRef(({ className, ...props }, ref) =>
|
|
|
124
124
|
}
|
|
125
125
|
));
|
|
126
126
|
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
127
|
-
var AlertDialogAction =
|
|
127
|
+
var AlertDialogAction = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
128
128
|
AlertDialogPrimitive.Action,
|
|
129
129
|
{
|
|
130
130
|
ref,
|
|
@@ -134,7 +134,7 @@ var AlertDialogAction = React8.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
134
134
|
}
|
|
135
135
|
));
|
|
136
136
|
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
137
|
-
var AlertDialogCancel =
|
|
137
|
+
var AlertDialogCancel = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
138
138
|
AlertDialogPrimitive.Cancel,
|
|
139
139
|
{
|
|
140
140
|
ref,
|
|
@@ -144,7 +144,7 @@ var AlertDialogCancel = React8.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
144
144
|
}
|
|
145
145
|
));
|
|
146
146
|
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
147
|
-
var Avatar =
|
|
147
|
+
var Avatar = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
148
148
|
AvatarPrimitive.Root,
|
|
149
149
|
{
|
|
150
150
|
ref,
|
|
@@ -153,7 +153,7 @@ var Avatar = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
153
153
|
}
|
|
154
154
|
));
|
|
155
155
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
156
|
-
var AvatarImage =
|
|
156
|
+
var AvatarImage = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
157
157
|
AvatarPrimitive.Image,
|
|
158
158
|
{
|
|
159
159
|
ref,
|
|
@@ -162,7 +162,7 @@ var AvatarImage = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
162
162
|
}
|
|
163
163
|
));
|
|
164
164
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
165
|
-
var AvatarFallback =
|
|
165
|
+
var AvatarFallback = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
166
166
|
AvatarPrimitive.Fallback,
|
|
167
167
|
{
|
|
168
168
|
ref,
|
|
@@ -254,7 +254,7 @@ function Calendar({
|
|
|
254
254
|
}
|
|
255
255
|
);
|
|
256
256
|
}
|
|
257
|
-
var Checkbox =
|
|
257
|
+
var Checkbox = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
258
258
|
CheckboxPrimitive.Root,
|
|
259
259
|
{
|
|
260
260
|
ref,
|
|
@@ -406,11 +406,11 @@ function DatePicker({
|
|
|
406
406
|
className,
|
|
407
407
|
"aria-label": ariaLabel
|
|
408
408
|
}) {
|
|
409
|
-
const [open, setOpen] =
|
|
409
|
+
const [open, setOpen] = React20.useState(false);
|
|
410
410
|
const normalizedMin = normalizeDate(minDate);
|
|
411
411
|
const normalizedMax = normalizeDate(maxDate);
|
|
412
|
-
const formatOpts =
|
|
413
|
-
const disabledMatchers =
|
|
412
|
+
const formatOpts = React20.useMemo(() => locale ? { locale } : void 0, [locale]);
|
|
413
|
+
const disabledMatchers = React20.useMemo(() => {
|
|
414
414
|
const toStartOfDay = (d) => {
|
|
415
415
|
const copy = new Date(d);
|
|
416
416
|
copy.setHours(0, 0, 0, 0);
|
|
@@ -481,7 +481,7 @@ function DatePicker({
|
|
|
481
481
|
) })
|
|
482
482
|
] });
|
|
483
483
|
}
|
|
484
|
-
var InsideModalScrollLockContext =
|
|
484
|
+
var InsideModalScrollLockContext = React20.createContext(false);
|
|
485
485
|
function InsideModalScrollLockProvider({
|
|
486
486
|
children,
|
|
487
487
|
active = true
|
|
@@ -489,7 +489,7 @@ function InsideModalScrollLockProvider({
|
|
|
489
489
|
return /* @__PURE__ */ jsx(InsideModalScrollLockContext.Provider, { value: active, children });
|
|
490
490
|
}
|
|
491
491
|
function useInsideModalScrollLock() {
|
|
492
|
-
return
|
|
492
|
+
return React20.useContext(InsideModalScrollLockContext);
|
|
493
493
|
}
|
|
494
494
|
function Dialog({ ...props }) {
|
|
495
495
|
return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
@@ -896,7 +896,7 @@ function DateRangePickerPresetList({
|
|
|
896
896
|
})
|
|
897
897
|
] }) });
|
|
898
898
|
}
|
|
899
|
-
var DateRangePickerTrigger =
|
|
899
|
+
var DateRangePickerTrigger = React20.forwardRef(
|
|
900
900
|
function DateRangePickerTrigger2({
|
|
901
901
|
className,
|
|
902
902
|
inputText,
|
|
@@ -1018,7 +1018,7 @@ function getPresetRange(presetId) {
|
|
|
1018
1018
|
}
|
|
1019
1019
|
}
|
|
1020
1020
|
function useMediaQuery(query, fallback = false) {
|
|
1021
|
-
const subscribe =
|
|
1021
|
+
const subscribe = React20.useCallback(
|
|
1022
1022
|
(onChange) => {
|
|
1023
1023
|
const mql = window.matchMedia(query);
|
|
1024
1024
|
mql.addEventListener("change", onChange);
|
|
@@ -1026,7 +1026,7 @@ function useMediaQuery(query, fallback = false) {
|
|
|
1026
1026
|
},
|
|
1027
1027
|
[query]
|
|
1028
1028
|
);
|
|
1029
|
-
return
|
|
1029
|
+
return React20.useSyncExternalStore(
|
|
1030
1030
|
subscribe,
|
|
1031
1031
|
() => window.matchMedia(query).matches,
|
|
1032
1032
|
() => fallback
|
|
@@ -1054,7 +1054,7 @@ function DateRangePicker({
|
|
|
1054
1054
|
}) {
|
|
1055
1055
|
const t = { ...DEFAULT_TRANSLATIONS, ...translations };
|
|
1056
1056
|
const effectivePlaceholder = placeholder ?? t.placeholder;
|
|
1057
|
-
const presetList =
|
|
1057
|
+
const presetList = React20.useMemo(() => {
|
|
1058
1058
|
if (customPresets?.length) return customPresets;
|
|
1059
1059
|
if (!showPresets) return [];
|
|
1060
1060
|
return DEFAULT_PRESET_IDS.map(({ id }) => ({
|
|
@@ -1068,16 +1068,16 @@ function DateRangePicker({
|
|
|
1068
1068
|
const isMobileLayout = useIsDatePickerMobileLayout();
|
|
1069
1069
|
const isWideLayout = useIsWideDatePickerLayout();
|
|
1070
1070
|
const calendarMonths = isMobileLayout ? 1 : isWideLayout ? 2 : 1;
|
|
1071
|
-
const [open, setOpen] =
|
|
1072
|
-
const [draft, setDraft] =
|
|
1073
|
-
const [displayedMonth, setDisplayedMonth] =
|
|
1074
|
-
const appliedRef =
|
|
1075
|
-
const wasOpenRef =
|
|
1071
|
+
const [open, setOpen] = React20.useState(false);
|
|
1072
|
+
const [draft, setDraft] = React20.useState(value);
|
|
1073
|
+
const [displayedMonth, setDisplayedMonth] = React20.useState(() => value?.from ?? /* @__PURE__ */ new Date());
|
|
1074
|
+
const appliedRef = React20.useRef(value);
|
|
1075
|
+
const wasOpenRef = React20.useRef(false);
|
|
1076
1076
|
const useApplyFlow = !!onApply;
|
|
1077
|
-
const idScope =
|
|
1077
|
+
const idScope = React20.useId();
|
|
1078
1078
|
const startInputId = `date-range-start-${idScope}`;
|
|
1079
1079
|
const endInputId = `date-range-end-${idScope}`;
|
|
1080
|
-
|
|
1080
|
+
React20.useEffect(() => {
|
|
1081
1081
|
const wasOpen = wasOpenRef.current;
|
|
1082
1082
|
wasOpenRef.current = open;
|
|
1083
1083
|
if (open && !wasOpen) {
|
|
@@ -1088,7 +1088,7 @@ function DateRangePicker({
|
|
|
1088
1088
|
setDraft(value);
|
|
1089
1089
|
}
|
|
1090
1090
|
}, [open, value]);
|
|
1091
|
-
const handleOpenChange =
|
|
1091
|
+
const handleOpenChange = React20.useCallback(
|
|
1092
1092
|
(next) => {
|
|
1093
1093
|
if (!next && open && !useApplyFlow) {
|
|
1094
1094
|
onChange(appliedRef.current);
|
|
@@ -1098,14 +1098,14 @@ function DateRangePicker({
|
|
|
1098
1098
|
},
|
|
1099
1099
|
[open, useApplyFlow, onChange]
|
|
1100
1100
|
);
|
|
1101
|
-
const formatOpts =
|
|
1102
|
-
const label =
|
|
1101
|
+
const formatOpts = React20.useMemo(() => locale ? { locale } : void 0, [locale]);
|
|
1102
|
+
const label = React20.useMemo(
|
|
1103
1103
|
() => formatRangeLabel(value, effectivePlaceholder, formatOpts),
|
|
1104
1104
|
[effectivePlaceholder, value, formatOpts]
|
|
1105
1105
|
);
|
|
1106
|
-
const [inputText, setInputText] =
|
|
1107
|
-
const inputFocusedRef =
|
|
1108
|
-
|
|
1106
|
+
const [inputText, setInputText] = React20.useState(label);
|
|
1107
|
+
const inputFocusedRef = React20.useRef(false);
|
|
1108
|
+
React20.useEffect(() => {
|
|
1109
1109
|
if (!inputFocusedRef.current) setInputText(label);
|
|
1110
1110
|
}, [label]);
|
|
1111
1111
|
const handleInputBlur = () => {
|
|
@@ -1124,7 +1124,7 @@ function DateRangePicker({
|
|
|
1124
1124
|
setInputText(label);
|
|
1125
1125
|
}
|
|
1126
1126
|
};
|
|
1127
|
-
const disabledMatchers =
|
|
1127
|
+
const disabledMatchers = React20.useMemo(() => {
|
|
1128
1128
|
const toStartOfDay = (d) => {
|
|
1129
1129
|
const copy = new Date(d);
|
|
1130
1130
|
copy.setHours(0, 0, 0, 0);
|
|
@@ -1182,9 +1182,9 @@ function DateRangePicker({
|
|
|
1182
1182
|
return nextRange;
|
|
1183
1183
|
});
|
|
1184
1184
|
};
|
|
1185
|
-
const [startInputText, setStartInputText] =
|
|
1186
|
-
const [endInputText, setEndInputText] =
|
|
1187
|
-
|
|
1185
|
+
const [startInputText, setStartInputText] = React20.useState("");
|
|
1186
|
+
const [endInputText, setEndInputText] = React20.useState("");
|
|
1187
|
+
React20.useEffect(() => {
|
|
1188
1188
|
if (open) {
|
|
1189
1189
|
setStartInputText(draft?.from ? format(draft.from, INPUT_FORMAT) : "");
|
|
1190
1190
|
setEndInputText(draft?.to ? format(draft.to, INPUT_FORMAT) : "");
|
|
@@ -1384,10 +1384,10 @@ function DropdownScrollableList({
|
|
|
1384
1384
|
scrollAreaClassName,
|
|
1385
1385
|
grow = true
|
|
1386
1386
|
}) {
|
|
1387
|
-
const scrollRef =
|
|
1388
|
-
const [showTop, setShowTop] =
|
|
1389
|
-
const [showBottom, setShowBottom] =
|
|
1390
|
-
const update =
|
|
1387
|
+
const scrollRef = React20.useRef(null);
|
|
1388
|
+
const [showTop, setShowTop] = React20.useState(false);
|
|
1389
|
+
const [showBottom, setShowBottom] = React20.useState(false);
|
|
1390
|
+
const update = React20.useCallback(() => {
|
|
1391
1391
|
const el = scrollRef.current;
|
|
1392
1392
|
if (!el) {
|
|
1393
1393
|
setShowTop(false);
|
|
@@ -1404,14 +1404,14 @@ function DropdownScrollableList({
|
|
|
1404
1404
|
setShowTop(scrollTop > 2);
|
|
1405
1405
|
setShowBottom(scrollTop + clientHeight < scrollHeight - 2);
|
|
1406
1406
|
}, []);
|
|
1407
|
-
|
|
1407
|
+
React20.useLayoutEffect(() => {
|
|
1408
1408
|
update();
|
|
1409
1409
|
const id = requestAnimationFrame(() => {
|
|
1410
1410
|
requestAnimationFrame(update);
|
|
1411
1411
|
});
|
|
1412
1412
|
return () => cancelAnimationFrame(id);
|
|
1413
1413
|
}, [update, scrollKey]);
|
|
1414
|
-
|
|
1414
|
+
React20.useEffect(() => {
|
|
1415
1415
|
const el = scrollRef.current;
|
|
1416
1416
|
if (!el) return;
|
|
1417
1417
|
if (typeof ResizeObserver === "undefined") {
|
|
@@ -1541,10 +1541,10 @@ function titleForView(anchor, view, weekStartsOnMonday) {
|
|
|
1541
1541
|
}
|
|
1542
1542
|
var MAX_MONTH_CHIPS = 3;
|
|
1543
1543
|
function useControlledDate(value, defaultValue, onChange) {
|
|
1544
|
-
const [internal, setInternal] =
|
|
1544
|
+
const [internal, setInternal] = React20.useState(defaultValue ?? /* @__PURE__ */ new Date());
|
|
1545
1545
|
const isControlled = value !== void 0;
|
|
1546
1546
|
const current = isControlled ? value : internal;
|
|
1547
|
-
const set =
|
|
1547
|
+
const set = React20.useCallback(
|
|
1548
1548
|
(next) => {
|
|
1549
1549
|
if (!isControlled) setInternal(next);
|
|
1550
1550
|
onChange?.(next);
|
|
@@ -1554,10 +1554,10 @@ function useControlledDate(value, defaultValue, onChange) {
|
|
|
1554
1554
|
return [current, set];
|
|
1555
1555
|
}
|
|
1556
1556
|
function useControlledView(value, defaultValue, onChange) {
|
|
1557
|
-
const [internal, setInternal] =
|
|
1557
|
+
const [internal, setInternal] = React20.useState(defaultValue);
|
|
1558
1558
|
const isControlled = value !== void 0;
|
|
1559
1559
|
const current = isControlled ? value : internal;
|
|
1560
|
-
const set =
|
|
1560
|
+
const set = React20.useCallback(
|
|
1561
1561
|
(next) => {
|
|
1562
1562
|
if (!isControlled) setInternal(next);
|
|
1563
1563
|
onChange?.(next);
|
|
@@ -1607,7 +1607,7 @@ function EventCalendar({
|
|
|
1607
1607
|
}) {
|
|
1608
1608
|
const [safeAnchor, setAnchor] = useControlledDate(value, defaultValue, onValueChange);
|
|
1609
1609
|
const [safeView, setViewSafe] = useControlledView(viewProp, defaultView, onViewChange);
|
|
1610
|
-
const weekdays =
|
|
1610
|
+
const weekdays = React20.useMemo(
|
|
1611
1611
|
() => weekdayLabels(weekStartsOnMonday, safeAnchor),
|
|
1612
1612
|
[weekStartsOnMonday, safeAnchor]
|
|
1613
1613
|
);
|
|
@@ -1819,15 +1819,15 @@ function Label({
|
|
|
1819
1819
|
return /* @__PURE__ */ jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn(labelVariants(), className), ...props });
|
|
1820
1820
|
}
|
|
1821
1821
|
var Form = FormProvider;
|
|
1822
|
-
var FormFieldContext =
|
|
1822
|
+
var FormFieldContext = React20.createContext(null);
|
|
1823
1823
|
var FormField = ({
|
|
1824
1824
|
...props
|
|
1825
1825
|
}) => {
|
|
1826
1826
|
return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
|
|
1827
1827
|
};
|
|
1828
1828
|
var useFormField = () => {
|
|
1829
|
-
const fieldContext =
|
|
1830
|
-
const itemContext =
|
|
1829
|
+
const fieldContext = React20.useContext(FormFieldContext);
|
|
1830
|
+
const itemContext = React20.useContext(FormItemContext);
|
|
1831
1831
|
if (fieldContext === null || fieldContext === void 0) {
|
|
1832
1832
|
throw new Error("useFormField should be used within <FormField>");
|
|
1833
1833
|
}
|
|
@@ -1844,9 +1844,9 @@ var useFormField = () => {
|
|
|
1844
1844
|
...fieldState
|
|
1845
1845
|
};
|
|
1846
1846
|
};
|
|
1847
|
-
var FormItemContext =
|
|
1847
|
+
var FormItemContext = React20.createContext({});
|
|
1848
1848
|
function FormItem({ className, ...props }) {
|
|
1849
|
-
const id =
|
|
1849
|
+
const id = React20.useId();
|
|
1850
1850
|
return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-3", className), ...props }) });
|
|
1851
1851
|
}
|
|
1852
1852
|
function FormLabel({
|
|
@@ -2025,29 +2025,66 @@ function FormDrawer({
|
|
|
2025
2025
|
onOpenChange,
|
|
2026
2026
|
title,
|
|
2027
2027
|
description,
|
|
2028
|
+
info,
|
|
2028
2029
|
children,
|
|
2029
2030
|
className,
|
|
2030
2031
|
contentClassName
|
|
2031
2032
|
}) {
|
|
2033
|
+
const bodyRef = React20.useRef(null);
|
|
2034
|
+
const [infoOpen, setInfoOpen] = React20.useState(false);
|
|
2035
|
+
React20.useEffect(() => {
|
|
2036
|
+
if (!open) setInfoOpen(false);
|
|
2037
|
+
}, [open]);
|
|
2032
2038
|
return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
2033
2039
|
SheetContent,
|
|
2034
2040
|
{
|
|
2035
2041
|
"data-slot": "form-drawer-content",
|
|
2042
|
+
onOpenAutoFocus: (event) => {
|
|
2043
|
+
event.preventDefault();
|
|
2044
|
+
bodyRef.current?.focus({ preventScroll: true });
|
|
2045
|
+
},
|
|
2046
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
2036
2047
|
className: cn(
|
|
2037
2048
|
"flex flex-col gap-4 w-[calc(100%-2rem)] max-w-[calc(100%-2rem)] sm:max-w-lg overflow-hidden",
|
|
2038
2049
|
contentClassName
|
|
2039
2050
|
),
|
|
2040
2051
|
children: [
|
|
2041
2052
|
/* @__PURE__ */ jsxs(SheetHeader, { className: "flex-shrink-0 gap-2 pb-2", children: [
|
|
2042
|
-
/* @__PURE__ */
|
|
2043
|
-
|
|
2053
|
+
/* @__PURE__ */ jsxs(SheetTitle, { className: "flex items-center gap-1.5 text-base sm:text-lg", children: [
|
|
2054
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0", children: title }),
|
|
2055
|
+
info ? /* @__PURE__ */ jsxs(Popover, { open: infoOpen, onOpenChange: setInfoOpen, children: [
|
|
2056
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2057
|
+
"button",
|
|
2058
|
+
{
|
|
2059
|
+
type: "button",
|
|
2060
|
+
className: "inline-flex shrink-0 cursor-help rounded-sm p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
2061
|
+
"aria-label": "More info",
|
|
2062
|
+
"aria-expanded": infoOpen,
|
|
2063
|
+
children: /* @__PURE__ */ jsx(Info, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
2064
|
+
}
|
|
2065
|
+
) }),
|
|
2066
|
+
/* @__PURE__ */ jsx(
|
|
2067
|
+
PopoverContent,
|
|
2068
|
+
{
|
|
2069
|
+
side: "bottom",
|
|
2070
|
+
align: "start",
|
|
2071
|
+
sideOffset: 6,
|
|
2072
|
+
className: "z-[120] max-w-xs p-3 text-sm leading-snug",
|
|
2073
|
+
children: info
|
|
2074
|
+
}
|
|
2075
|
+
)
|
|
2076
|
+
] }) : null
|
|
2077
|
+
] }),
|
|
2078
|
+
description ? /* @__PURE__ */ jsx(SheetDescription, { className: "text-sm", children: description }) : null
|
|
2044
2079
|
] }),
|
|
2045
2080
|
/* @__PURE__ */ jsx(InsideModalScrollLockProvider, { children: /* @__PURE__ */ jsx(
|
|
2046
2081
|
"div",
|
|
2047
2082
|
{
|
|
2083
|
+
ref: bodyRef,
|
|
2084
|
+
tabIndex: -1,
|
|
2048
2085
|
className: cn(
|
|
2049
2086
|
// Inset so focus rings / box-shadow on full-width inputs are not clipped by overflow-y-auto
|
|
2050
|
-
"flex flex-col flex-1 min-h-0 gap-4 overflow-y-auto px-2 py-1",
|
|
2087
|
+
"flex flex-col flex-1 min-h-0 gap-4 overflow-y-auto px-2 py-1 outline-none",
|
|
2051
2088
|
className
|
|
2052
2089
|
),
|
|
2053
2090
|
children
|
|
@@ -2106,14 +2143,14 @@ function MultiSelect({
|
|
|
2106
2143
|
}) {
|
|
2107
2144
|
const t = { ...DEFAULT_TRANSLATIONS2, ...translations };
|
|
2108
2145
|
const insideModalScrollLock = useInsideModalScrollLock();
|
|
2109
|
-
const [search, setSearch] =
|
|
2110
|
-
const selectedSet =
|
|
2111
|
-
const labelByValue =
|
|
2146
|
+
const [search, setSearch] = React20.useState("");
|
|
2147
|
+
const selectedSet = React20.useMemo(() => new Set(value), [value]);
|
|
2148
|
+
const labelByValue = React20.useMemo(() => {
|
|
2112
2149
|
const map = /* @__PURE__ */ new Map();
|
|
2113
2150
|
for (const opt of options) map.set(opt.value, opt.label);
|
|
2114
2151
|
return map;
|
|
2115
2152
|
}, [options]);
|
|
2116
|
-
const filteredOptions =
|
|
2153
|
+
const filteredOptions = React20.useMemo(() => {
|
|
2117
2154
|
const q = search.trim().toLowerCase();
|
|
2118
2155
|
if (!q) return options;
|
|
2119
2156
|
return options.filter((opt) => opt.label.toLowerCase().includes(q));
|
|
@@ -2209,7 +2246,7 @@ function MultiSelect({
|
|
|
2209
2246
|
] })
|
|
2210
2247
|
] });
|
|
2211
2248
|
}
|
|
2212
|
-
var ScrollArea =
|
|
2249
|
+
var ScrollArea = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2213
2250
|
ScrollAreaPrimitive.Root,
|
|
2214
2251
|
{
|
|
2215
2252
|
ref,
|
|
@@ -2223,7 +2260,7 @@ var ScrollArea = React8.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
2223
2260
|
}
|
|
2224
2261
|
));
|
|
2225
2262
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
2226
|
-
var ScrollBar =
|
|
2263
|
+
var ScrollBar = React20.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2227
2264
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
2228
2265
|
{
|
|
2229
2266
|
ref,
|
|
@@ -2361,10 +2398,10 @@ function Select({
|
|
|
2361
2398
|
}) {
|
|
2362
2399
|
const t = { ...DEFAULT_TRANSLATIONS3, ...translations };
|
|
2363
2400
|
const insideModalScrollLock = useInsideModalScrollLock();
|
|
2364
|
-
const [open, setOpen] =
|
|
2365
|
-
const [search, setSearch] =
|
|
2401
|
+
const [open, setOpen] = React20.useState(false);
|
|
2402
|
+
const [search, setSearch] = React20.useState("");
|
|
2366
2403
|
const showSearch = isSelectSearchable(options.length, searchable);
|
|
2367
|
-
const filteredOptions =
|
|
2404
|
+
const filteredOptions = React20.useMemo(
|
|
2368
2405
|
() => showSearch ? filterSelectOptions(options, search) : options,
|
|
2369
2406
|
[options, search, showSearch]
|
|
2370
2407
|
);
|
|
@@ -2389,7 +2426,7 @@ function Select({
|
|
|
2389
2426
|
controlFocus,
|
|
2390
2427
|
"flex h-9 w-full cursor-pointer items-center justify-between px-3 py-2 text-sm",
|
|
2391
2428
|
"hover:bg-accent/40 disabled:pointer-events-none disabled:opacity-50",
|
|
2392
|
-
!
|
|
2429
|
+
!selectedOption && "text-muted-foreground",
|
|
2393
2430
|
triggerClassName,
|
|
2394
2431
|
className
|
|
2395
2432
|
),
|
|
@@ -2429,10 +2466,8 @@ function Select({
|
|
|
2429
2466
|
children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-sm text-muted-foreground", children: t.noOptionsText }) : filteredOptions.map((opt) => /* @__PURE__ */ jsx(
|
|
2430
2467
|
DropdownMenuItem,
|
|
2431
2468
|
{
|
|
2432
|
-
|
|
2469
|
+
onSelect: () => {
|
|
2433
2470
|
onValueChange(opt.value);
|
|
2434
|
-
setOpen(false);
|
|
2435
|
-
setSearch("");
|
|
2436
2471
|
},
|
|
2437
2472
|
children: opt.label
|
|
2438
2473
|
},
|
|
@@ -2468,7 +2503,7 @@ function ChevronDownIcon({ className, ...props }) {
|
|
|
2468
2503
|
}
|
|
2469
2504
|
);
|
|
2470
2505
|
}
|
|
2471
|
-
var Separator =
|
|
2506
|
+
var Separator = React20.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2472
2507
|
SeparatorPrimitive.Root,
|
|
2473
2508
|
{
|
|
2474
2509
|
ref,
|
|
@@ -2483,7 +2518,7 @@ var Separator = React8.forwardRef(({ className, orientation = "horizontal", deco
|
|
|
2483
2518
|
}
|
|
2484
2519
|
));
|
|
2485
2520
|
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
2486
|
-
var Switch =
|
|
2521
|
+
var Switch = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2487
2522
|
SwitchPrimitive.Root,
|
|
2488
2523
|
{
|
|
2489
2524
|
ref,
|
|
@@ -2509,11 +2544,11 @@ var Switch = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
2509
2544
|
}
|
|
2510
2545
|
));
|
|
2511
2546
|
Switch.displayName = SwitchPrimitive.Root.displayName;
|
|
2512
|
-
var Table =
|
|
2547
|
+
var Table = React20.forwardRef(
|
|
2513
2548
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) })
|
|
2514
2549
|
);
|
|
2515
2550
|
Table.displayName = "Table";
|
|
2516
|
-
var TableHeader =
|
|
2551
|
+
var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2517
2552
|
"thead",
|
|
2518
2553
|
{
|
|
2519
2554
|
ref,
|
|
@@ -2522,9 +2557,9 @@ var TableHeader = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2522
2557
|
}
|
|
2523
2558
|
));
|
|
2524
2559
|
TableHeader.displayName = "TableHeader";
|
|
2525
|
-
var TableBody =
|
|
2560
|
+
var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
|
|
2526
2561
|
TableBody.displayName = "TableBody";
|
|
2527
|
-
var TableFooter =
|
|
2562
|
+
var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2528
2563
|
"tfoot",
|
|
2529
2564
|
{
|
|
2530
2565
|
ref,
|
|
@@ -2536,7 +2571,7 @@ var TableFooter = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2536
2571
|
}
|
|
2537
2572
|
));
|
|
2538
2573
|
TableFooter.displayName = "TableFooter";
|
|
2539
|
-
var TableRow =
|
|
2574
|
+
var TableRow = React20.forwardRef(
|
|
2540
2575
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2541
2576
|
"tr",
|
|
2542
2577
|
{
|
|
@@ -2550,7 +2585,7 @@ var TableRow = React8.forwardRef(
|
|
|
2550
2585
|
)
|
|
2551
2586
|
);
|
|
2552
2587
|
TableRow.displayName = "TableRow";
|
|
2553
|
-
var TableHead =
|
|
2588
|
+
var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2554
2589
|
"th",
|
|
2555
2590
|
{
|
|
2556
2591
|
ref,
|
|
@@ -2562,7 +2597,7 @@ var TableHead = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
2562
2597
|
}
|
|
2563
2598
|
));
|
|
2564
2599
|
TableHead.displayName = "TableHead";
|
|
2565
|
-
var TableCell =
|
|
2600
|
+
var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2566
2601
|
"td",
|
|
2567
2602
|
{
|
|
2568
2603
|
ref,
|
|
@@ -2571,7 +2606,7 @@ var TableCell = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
2571
2606
|
}
|
|
2572
2607
|
));
|
|
2573
2608
|
TableCell.displayName = "TableCell";
|
|
2574
|
-
var TableCaption =
|
|
2609
|
+
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
|
|
2575
2610
|
TableCaption.displayName = "TableCaption";
|
|
2576
2611
|
function Tabs({ className, ...props }) {
|
|
2577
2612
|
return /* @__PURE__ */ jsx(
|
|
@@ -2631,7 +2666,7 @@ function TabsContent({
|
|
|
2631
2666
|
}
|
|
2632
2667
|
);
|
|
2633
2668
|
}
|
|
2634
|
-
var Textarea =
|
|
2669
|
+
var Textarea = React20.forwardRef(
|
|
2635
2670
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2636
2671
|
"textarea",
|
|
2637
2672
|
{
|
|
@@ -2652,58 +2687,157 @@ var Textarea = React8.forwardRef(
|
|
|
2652
2687
|
);
|
|
2653
2688
|
Textarea.displayName = "Textarea";
|
|
2654
2689
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
2690
|
+
function prefersCoarsePointer() {
|
|
2691
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
2692
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
2693
|
+
}
|
|
2694
|
+
function isPointerOver(el, x, y) {
|
|
2695
|
+
if (!el || typeof document.elementFromPoint !== "function") return false;
|
|
2696
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return false;
|
|
2697
|
+
const under = document.elementFromPoint(x, y);
|
|
2698
|
+
return Boolean(under && (under === el || el.contains(under)));
|
|
2699
|
+
}
|
|
2655
2700
|
function Tooltip({
|
|
2656
2701
|
content,
|
|
2657
2702
|
children,
|
|
2658
2703
|
side = "top",
|
|
2659
2704
|
align = "center",
|
|
2660
|
-
delayDuration =
|
|
2661
|
-
closeDelay =
|
|
2705
|
+
delayDuration = 200,
|
|
2706
|
+
closeDelay = 280
|
|
2662
2707
|
}) {
|
|
2663
|
-
const [open, setOpen] =
|
|
2664
|
-
const
|
|
2665
|
-
const
|
|
2666
|
-
const
|
|
2708
|
+
const [open, setOpen] = React20.useState(false);
|
|
2709
|
+
const triggerRef = React20.useRef(null);
|
|
2710
|
+
const stickyRef = React20.useRef(false);
|
|
2711
|
+
const hoveringRef = React20.useRef(false);
|
|
2712
|
+
const openRef = React20.useRef(false);
|
|
2713
|
+
const hoverArmedRef = React20.useRef(false);
|
|
2714
|
+
const layoutReadyRef = React20.useRef(false);
|
|
2715
|
+
const lastPointerRef = React20.useRef({ x: Number.NaN, y: Number.NaN });
|
|
2716
|
+
const openTimeoutRef = React20.useRef(null);
|
|
2717
|
+
const closeTimeoutRef = React20.useRef(null);
|
|
2718
|
+
React20.useEffect(() => {
|
|
2719
|
+
openRef.current = open;
|
|
2720
|
+
}, [open]);
|
|
2721
|
+
React20.useLayoutEffect(() => {
|
|
2722
|
+
hoverArmedRef.current = false;
|
|
2723
|
+
stickyRef.current = false;
|
|
2724
|
+
hoveringRef.current = false;
|
|
2725
|
+
layoutReadyRef.current = false;
|
|
2726
|
+
setOpen(false);
|
|
2727
|
+
const markReady = () => {
|
|
2728
|
+
layoutReadyRef.current = true;
|
|
2729
|
+
const el = triggerRef.current;
|
|
2730
|
+
const { x, y } = lastPointerRef.current;
|
|
2731
|
+
if (isPointerOver(el, x, y)) {
|
|
2732
|
+
hoverArmedRef.current = false;
|
|
2733
|
+
return;
|
|
2734
|
+
}
|
|
2735
|
+
hoverArmedRef.current = true;
|
|
2736
|
+
};
|
|
2737
|
+
let raf2 = 0;
|
|
2738
|
+
const raf1 = window.requestAnimationFrame(() => {
|
|
2739
|
+
raf2 = window.requestAnimationFrame(markReady);
|
|
2740
|
+
});
|
|
2741
|
+
const onPointerMove = (event) => {
|
|
2742
|
+
lastPointerRef.current = { x: event.clientX, y: event.clientY };
|
|
2743
|
+
if (!layoutReadyRef.current) return;
|
|
2744
|
+
if (isPointerOver(triggerRef.current, event.clientX, event.clientY)) return;
|
|
2745
|
+
hoverArmedRef.current = true;
|
|
2746
|
+
};
|
|
2747
|
+
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
2748
|
+
return () => {
|
|
2749
|
+
window.cancelAnimationFrame(raf1);
|
|
2750
|
+
window.cancelAnimationFrame(raf2);
|
|
2751
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
2752
|
+
};
|
|
2753
|
+
}, []);
|
|
2754
|
+
const clearOpenTimeout = React20.useCallback(() => {
|
|
2667
2755
|
if (openTimeoutRef.current !== null) {
|
|
2668
2756
|
window.clearTimeout(openTimeoutRef.current);
|
|
2669
2757
|
openTimeoutRef.current = null;
|
|
2670
2758
|
}
|
|
2671
2759
|
}, []);
|
|
2672
|
-
const clearCloseTimeout =
|
|
2760
|
+
const clearCloseTimeout = React20.useCallback(() => {
|
|
2673
2761
|
if (closeTimeoutRef.current !== null) {
|
|
2674
2762
|
window.clearTimeout(closeTimeoutRef.current);
|
|
2675
2763
|
closeTimeoutRef.current = null;
|
|
2676
2764
|
}
|
|
2677
2765
|
}, []);
|
|
2678
|
-
const
|
|
2766
|
+
const scheduleClose = React20.useCallback(() => {
|
|
2767
|
+
if (stickyRef.current || hoveringRef.current) return;
|
|
2768
|
+
clearOpenTimeout();
|
|
2769
|
+
clearCloseTimeout();
|
|
2770
|
+
if (closeDelay === 0) {
|
|
2771
|
+
setOpen(false);
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
closeTimeoutRef.current = window.setTimeout(() => {
|
|
2775
|
+
if (stickyRef.current || hoveringRef.current) return;
|
|
2776
|
+
setOpen(false);
|
|
2777
|
+
}, closeDelay);
|
|
2778
|
+
}, [clearCloseTimeout, clearOpenTimeout, closeDelay]);
|
|
2779
|
+
const handleOpenChange = React20.useCallback(
|
|
2679
2780
|
(next) => {
|
|
2680
|
-
if (
|
|
2781
|
+
if (next) {
|
|
2782
|
+
if (!hoveringRef.current && !stickyRef.current) return;
|
|
2783
|
+
setOpen(true);
|
|
2784
|
+
return;
|
|
2785
|
+
}
|
|
2786
|
+
if (stickyRef.current) {
|
|
2787
|
+
stickyRef.current = false;
|
|
2788
|
+
hoveringRef.current = false;
|
|
2681
2789
|
clearOpenTimeout();
|
|
2682
2790
|
clearCloseTimeout();
|
|
2683
2791
|
setOpen(false);
|
|
2792
|
+
return;
|
|
2684
2793
|
}
|
|
2794
|
+
scheduleClose();
|
|
2685
2795
|
},
|
|
2686
|
-
[clearCloseTimeout, clearOpenTimeout]
|
|
2796
|
+
[clearCloseTimeout, clearOpenTimeout, scheduleClose]
|
|
2687
2797
|
);
|
|
2688
|
-
const handlePointerEnter =
|
|
2798
|
+
const handlePointerEnter = React20.useCallback(() => {
|
|
2799
|
+
if (!hoverArmedRef.current) return;
|
|
2800
|
+
hoveringRef.current = true;
|
|
2689
2801
|
clearCloseTimeout();
|
|
2690
2802
|
clearOpenTimeout();
|
|
2803
|
+
if (openRef.current || delayDuration <= 0) {
|
|
2804
|
+
setOpen(true);
|
|
2805
|
+
return;
|
|
2806
|
+
}
|
|
2691
2807
|
openTimeoutRef.current = window.setTimeout(() => {
|
|
2808
|
+
if (!hoveringRef.current || !hoverArmedRef.current) return;
|
|
2692
2809
|
setOpen(true);
|
|
2693
2810
|
}, delayDuration);
|
|
2694
2811
|
}, [clearCloseTimeout, clearOpenTimeout, delayDuration]);
|
|
2695
|
-
const handlePointerLeave =
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
}, [
|
|
2706
|
-
|
|
2812
|
+
const handlePointerLeave = React20.useCallback(() => {
|
|
2813
|
+
hoverArmedRef.current = true;
|
|
2814
|
+
hoveringRef.current = false;
|
|
2815
|
+
scheduleClose();
|
|
2816
|
+
}, [scheduleClose]);
|
|
2817
|
+
const blockRadixFocusOpen = React20.useCallback((e) => {
|
|
2818
|
+
e.preventDefault();
|
|
2819
|
+
}, []);
|
|
2820
|
+
const blockRadixPointerMoveOpen = React20.useCallback((e) => {
|
|
2821
|
+
e.preventDefault();
|
|
2822
|
+
}, []);
|
|
2823
|
+
const handleTriggerClick = React20.useCallback(
|
|
2824
|
+
(e) => {
|
|
2825
|
+
if (!prefersCoarsePointer()) {
|
|
2826
|
+
e.preventDefault();
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
clearOpenTimeout();
|
|
2830
|
+
clearCloseTimeout();
|
|
2831
|
+
const next = !open;
|
|
2832
|
+
stickyRef.current = next;
|
|
2833
|
+
hoveringRef.current = next;
|
|
2834
|
+
hoverArmedRef.current = true;
|
|
2835
|
+
setOpen(next);
|
|
2836
|
+
e.preventDefault();
|
|
2837
|
+
},
|
|
2838
|
+
[clearCloseTimeout, clearOpenTimeout, open]
|
|
2839
|
+
);
|
|
2840
|
+
React20.useEffect(
|
|
2707
2841
|
() => () => {
|
|
2708
2842
|
clearOpenTimeout();
|
|
2709
2843
|
clearCloseTimeout();
|
|
@@ -2714,9 +2848,13 @@ function Tooltip({
|
|
|
2714
2848
|
/* @__PURE__ */ jsx(
|
|
2715
2849
|
TooltipPrimitive.Trigger,
|
|
2716
2850
|
{
|
|
2851
|
+
ref: triggerRef,
|
|
2717
2852
|
asChild: true,
|
|
2853
|
+
onFocus: blockRadixFocusOpen,
|
|
2854
|
+
onPointerMove: blockRadixPointerMoveOpen,
|
|
2718
2855
|
onPointerEnter: handlePointerEnter,
|
|
2719
2856
|
onPointerLeave: handlePointerLeave,
|
|
2857
|
+
onClick: handleTriggerClick,
|
|
2720
2858
|
children
|
|
2721
2859
|
}
|
|
2722
2860
|
),
|
|
@@ -2764,7 +2902,7 @@ var paragraphVariants = cva("text-muted-foreground leading-relaxed", {
|
|
|
2764
2902
|
size: "default"
|
|
2765
2903
|
}
|
|
2766
2904
|
});
|
|
2767
|
-
var Heading =
|
|
2905
|
+
var Heading = React20.forwardRef(
|
|
2768
2906
|
({ className, level, as, ...props }, ref) => {
|
|
2769
2907
|
const Component = as || (level === "h1" ? "h1" : level === "h2" ? "h2" : level === "h3" ? "h3" : "h4");
|
|
2770
2908
|
return /* @__PURE__ */ jsx(
|
|
@@ -2778,13 +2916,13 @@ var Heading = React8.forwardRef(
|
|
|
2778
2916
|
}
|
|
2779
2917
|
);
|
|
2780
2918
|
Heading.displayName = "Heading";
|
|
2781
|
-
var Paragraph =
|
|
2919
|
+
var Paragraph = React20.forwardRef(
|
|
2782
2920
|
({ className, size, ...props }, ref) => {
|
|
2783
2921
|
return /* @__PURE__ */ jsx("p", { ref, className: cn(paragraphVariants({ size }), className), ...props });
|
|
2784
2922
|
}
|
|
2785
2923
|
);
|
|
2786
2924
|
Paragraph.displayName = "Paragraph";
|
|
2787
|
-
var H3 =
|
|
2925
|
+
var H3 = React20.forwardRef(
|
|
2788
2926
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(Heading, { ref, level: "h3", as: "h3", className, ...props })
|
|
2789
2927
|
);
|
|
2790
2928
|
H3.displayName = "H3";
|
|
@@ -2794,10 +2932,30 @@ var DEFAULT_TRANSLATIONS4 = {
|
|
|
2794
2932
|
chooseImageText: "Choose image",
|
|
2795
2933
|
chooseFileText: "Choose file",
|
|
2796
2934
|
removeText: "Remove",
|
|
2797
|
-
removeExistingImageText: "Remove existing image"
|
|
2935
|
+
removeExistingImageText: "Remove existing image",
|
|
2936
|
+
removeFileAriaLabel: "Remove file"
|
|
2798
2937
|
};
|
|
2938
|
+
function fileMatchesAccept(file, accept) {
|
|
2939
|
+
if (!accept?.trim()) return true;
|
|
2940
|
+
const tokens = accept.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
2941
|
+
if (!tokens.length) return true;
|
|
2942
|
+
const name = file.name.toLowerCase();
|
|
2943
|
+
const type = (file.type || "").toLowerCase();
|
|
2944
|
+
return tokens.some((token) => {
|
|
2945
|
+
if (token.startsWith(".")) return name.endsWith(token);
|
|
2946
|
+
if (token.endsWith("/*")) return type.startsWith(token.slice(0, -1));
|
|
2947
|
+
return type === token;
|
|
2948
|
+
});
|
|
2949
|
+
}
|
|
2950
|
+
function fileKey(file) {
|
|
2951
|
+
return `${file.name}:${file.size}:${file.lastModified}`;
|
|
2952
|
+
}
|
|
2953
|
+
function isFileLike(value) {
|
|
2954
|
+
return typeof value === "object" && value != null && typeof value.name === "string" && typeof value.size === "number";
|
|
2955
|
+
}
|
|
2799
2956
|
function UploadDropzone(props) {
|
|
2800
2957
|
const isFile = props.variant === "file";
|
|
2958
|
+
const isMultiple = isFile && (props.multiple === true || Array.isArray(props.value));
|
|
2801
2959
|
const inputId = useId();
|
|
2802
2960
|
const removeExistingLabelId = useId();
|
|
2803
2961
|
const pickerDisabled = isFile && props.disabled;
|
|
@@ -2805,40 +2963,83 @@ function UploadDropzone(props) {
|
|
|
2805
2963
|
const inputRef = useRef(null);
|
|
2806
2964
|
const [isDragging, setIsDragging] = useState(false);
|
|
2807
2965
|
const [previewUrl, setPreviewUrl] = useState(null);
|
|
2966
|
+
const singleFile = isFile && !isMultiple && isFileLike(props.value) ? props.value : null;
|
|
2967
|
+
const multiFiles = isMultiple && Array.isArray(props.value) ? props.value.filter(isFileLike) : [];
|
|
2968
|
+
const accept = isFile ? props.accept : "image/*";
|
|
2969
|
+
const setSingleFile = (file) => {
|
|
2970
|
+
if (isFile && !isMultiple) {
|
|
2971
|
+
props.onChange(file);
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
if (!isFile) {
|
|
2975
|
+
props.onChange(file);
|
|
2976
|
+
props.onRemoveExistingImageChange?.(false);
|
|
2977
|
+
}
|
|
2978
|
+
};
|
|
2979
|
+
const setMultiFiles = (next) => {
|
|
2980
|
+
if (isMultiple) props.onChange(next);
|
|
2981
|
+
};
|
|
2982
|
+
const imageFile = !isFile && isFileLike(props.value) ? props.value : null;
|
|
2808
2983
|
useEffect(() => {
|
|
2809
2984
|
if (isFile) {
|
|
2810
|
-
|
|
2985
|
+
const mime = singleFile?.type || "";
|
|
2986
|
+
if (!singleFile || !mime.startsWith("video/")) {
|
|
2811
2987
|
setPreviewUrl(null);
|
|
2812
2988
|
return;
|
|
2813
2989
|
}
|
|
2814
|
-
const nextUrl2 = URL.createObjectURL(
|
|
2990
|
+
const nextUrl2 = URL.createObjectURL(singleFile);
|
|
2815
2991
|
setPreviewUrl(nextUrl2);
|
|
2816
2992
|
return () => URL.revokeObjectURL(nextUrl2);
|
|
2817
2993
|
}
|
|
2818
|
-
if (!
|
|
2994
|
+
if (!imageFile) {
|
|
2819
2995
|
setPreviewUrl(null);
|
|
2820
2996
|
return;
|
|
2821
2997
|
}
|
|
2822
|
-
const nextUrl = URL.createObjectURL(
|
|
2998
|
+
const nextUrl = URL.createObjectURL(imageFile);
|
|
2823
2999
|
setPreviewUrl(nextUrl);
|
|
2824
3000
|
return () => URL.revokeObjectURL(nextUrl);
|
|
2825
|
-
}, [isFile,
|
|
2826
|
-
const
|
|
2827
|
-
if (!
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
3001
|
+
}, [imageFile, isFile, singleFile]);
|
|
3002
|
+
const acceptFiles = (incoming) => {
|
|
3003
|
+
if (!incoming || pickerDisabled) return;
|
|
3004
|
+
const list = Array.from(incoming).filter(isFileLike);
|
|
3005
|
+
if (!list.length) return;
|
|
3006
|
+
const accepted = [];
|
|
3007
|
+
for (const file of list) {
|
|
3008
|
+
if (props.maxSizeBytes != null && file.size > props.maxSizeBytes) {
|
|
3009
|
+
props.onFileTooLarge?.();
|
|
3010
|
+
continue;
|
|
3011
|
+
}
|
|
3012
|
+
if (isFile) {
|
|
3013
|
+
if (!fileMatchesAccept(file, accept)) {
|
|
3014
|
+
props.onInvalidFile?.();
|
|
3015
|
+
continue;
|
|
3016
|
+
}
|
|
3017
|
+
accepted.push(file);
|
|
3018
|
+
continue;
|
|
3019
|
+
}
|
|
3020
|
+
if (!(file.type || "").startsWith("image/")) {
|
|
3021
|
+
props.onInvalidFile?.();
|
|
3022
|
+
continue;
|
|
3023
|
+
}
|
|
3024
|
+
accepted.push(file);
|
|
3025
|
+
}
|
|
3026
|
+
if (!accepted.length) return;
|
|
3027
|
+
if (isMultiple) {
|
|
3028
|
+
const seen = new Set(multiFiles.map(fileKey));
|
|
3029
|
+
const next = [...multiFiles];
|
|
3030
|
+
for (const file of accepted) {
|
|
3031
|
+
const key = fileKey(file);
|
|
3032
|
+
if (seen.has(key)) continue;
|
|
3033
|
+
seen.add(key);
|
|
3034
|
+
next.push(file);
|
|
3035
|
+
}
|
|
3036
|
+
setMultiFiles(next);
|
|
2835
3037
|
return;
|
|
2836
3038
|
}
|
|
2837
|
-
|
|
2838
|
-
props.onChange(file);
|
|
2839
|
-
props.onRemoveExistingImageChange?.(false);
|
|
3039
|
+
setSingleFile(accepted[0] ?? null);
|
|
2840
3040
|
};
|
|
2841
|
-
const
|
|
3041
|
+
const imageProps = !isFile ? props : null;
|
|
3042
|
+
const displayedImage = imageProps && (previewUrl ?? (!imageProps.removeExistingImage ? imageProps.existingImageUrl : void 0));
|
|
2842
3043
|
const dashedClasses = cn(
|
|
2843
3044
|
"block rounded-xl border-2 border-dashed border-border/55 p-4 transition-colors",
|
|
2844
3045
|
pickerDisabled && "pointer-events-none opacity-50",
|
|
@@ -2862,8 +3063,7 @@ function UploadDropzone(props) {
|
|
|
2862
3063
|
event.preventDefault();
|
|
2863
3064
|
setIsDragging(false);
|
|
2864
3065
|
if (pickerDisabled) return;
|
|
2865
|
-
|
|
2866
|
-
handleFile(file);
|
|
3066
|
+
acceptFiles(event.dataTransfer.files);
|
|
2867
3067
|
},
|
|
2868
3068
|
children: [
|
|
2869
3069
|
/* @__PURE__ */ jsx(
|
|
@@ -2872,10 +3072,14 @@ function UploadDropzone(props) {
|
|
|
2872
3072
|
id: inputId,
|
|
2873
3073
|
ref: inputRef,
|
|
2874
3074
|
type: "file",
|
|
2875
|
-
accept
|
|
3075
|
+
accept,
|
|
3076
|
+
multiple: isMultiple || void 0,
|
|
2876
3077
|
disabled: pickerDisabled || void 0,
|
|
2877
3078
|
className: "sr-only",
|
|
2878
|
-
onChange: (event) =>
|
|
3079
|
+
onChange: (event) => {
|
|
3080
|
+
acceptFiles(event.target.files);
|
|
3081
|
+
event.target.value = "";
|
|
3082
|
+
}
|
|
2879
3083
|
}
|
|
2880
3084
|
),
|
|
2881
3085
|
isFile ? /* @__PURE__ */ jsxs("div", { className: "mb-3 flex min-h-28 flex-col items-center justify-center gap-2 rounded-lg border border-border/45 bg-muted/20 px-3 py-4 text-center", children: [
|
|
@@ -2887,7 +3091,40 @@ function UploadDropzone(props) {
|
|
|
2887
3091
|
className: "max-h-44 w-full rounded-lg border border-border/45 bg-foreground"
|
|
2888
3092
|
}
|
|
2889
3093
|
) : /* @__PURE__ */ jsx(FileText, { className: "h-8 w-8 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
2890
|
-
|
|
3094
|
+
isMultiple ? multiFiles.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "w-full space-y-1.5 text-left", children: multiFiles.map((file) => /* @__PURE__ */ jsxs(
|
|
3095
|
+
"li",
|
|
3096
|
+
{
|
|
3097
|
+
className: "flex items-center gap-2 rounded-md border border-border/40 bg-background/60 px-2 py-1.5",
|
|
3098
|
+
children: [
|
|
3099
|
+
/* @__PURE__ */ jsx(
|
|
3100
|
+
FileText,
|
|
3101
|
+
{
|
|
3102
|
+
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
3103
|
+
"aria-hidden": true
|
|
3104
|
+
}
|
|
3105
|
+
),
|
|
3106
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: file.name }),
|
|
3107
|
+
/* @__PURE__ */ jsx(
|
|
3108
|
+
Button,
|
|
3109
|
+
{
|
|
3110
|
+
type: "button",
|
|
3111
|
+
size: "sm",
|
|
3112
|
+
variant: "ghost",
|
|
3113
|
+
className: "h-7 w-7 shrink-0 p-0",
|
|
3114
|
+
disabled: pickerDisabled || void 0,
|
|
3115
|
+
"aria-label": `${t.removeFileAriaLabel} ${file.name}`,
|
|
3116
|
+
onClick: (event) => {
|
|
3117
|
+
event.preventDefault();
|
|
3118
|
+
event.stopPropagation();
|
|
3119
|
+
setMultiFiles(multiFiles.filter((f) => fileKey(f) !== fileKey(file)));
|
|
3120
|
+
},
|
|
3121
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
3122
|
+
}
|
|
3123
|
+
)
|
|
3124
|
+
]
|
|
3125
|
+
},
|
|
3126
|
+
fileKey(file)
|
|
3127
|
+
)) }) : null : singleFile ? /* @__PURE__ */ jsx("p", { className: "line-clamp-2 w-full break-all text-sm font-medium", children: singleFile.name }) : null
|
|
2891
3128
|
] }) : displayedImage ? /* @__PURE__ */ jsx(
|
|
2892
3129
|
"img",
|
|
2893
3130
|
{
|
|
@@ -2916,7 +3153,22 @@ function UploadDropzone(props) {
|
|
|
2916
3153
|
]
|
|
2917
3154
|
}
|
|
2918
3155
|
),
|
|
2919
|
-
|
|
3156
|
+
!isMultiple && isFile && singleFile ? /* @__PURE__ */ jsx(
|
|
3157
|
+
Button,
|
|
3158
|
+
{
|
|
3159
|
+
type: "button",
|
|
3160
|
+
size: "sm",
|
|
3161
|
+
variant: "outline",
|
|
3162
|
+
disabled: pickerDisabled || void 0,
|
|
3163
|
+
onClick: (event) => {
|
|
3164
|
+
event.preventDefault();
|
|
3165
|
+
event.stopPropagation();
|
|
3166
|
+
setSingleFile(null);
|
|
3167
|
+
},
|
|
3168
|
+
children: t.removeText
|
|
3169
|
+
}
|
|
3170
|
+
) : null,
|
|
3171
|
+
isMultiple && multiFiles.length > 0 ? /* @__PURE__ */ jsx(
|
|
2920
3172
|
Button,
|
|
2921
3173
|
{
|
|
2922
3174
|
type: "button",
|
|
@@ -2926,7 +3178,7 @@ function UploadDropzone(props) {
|
|
|
2926
3178
|
onClick: (event) => {
|
|
2927
3179
|
event.preventDefault();
|
|
2928
3180
|
event.stopPropagation();
|
|
2929
|
-
|
|
3181
|
+
setMultiFiles([]);
|
|
2930
3182
|
},
|
|
2931
3183
|
children: t.removeText
|
|
2932
3184
|
}
|
|
@@ -2936,20 +3188,20 @@ function UploadDropzone(props) {
|
|
|
2936
3188
|
]
|
|
2937
3189
|
}
|
|
2938
3190
|
),
|
|
2939
|
-
|
|
3191
|
+
imageProps?.existingImageUrl && imageProps.onRemoveExistingImageChange && t.removeExistingImageText ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg border border-border/45 bg-muted/15 px-3 py-2", children: [
|
|
2940
3192
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", id: removeExistingLabelId, children: t.removeExistingImageText }),
|
|
2941
3193
|
/* @__PURE__ */ jsx(
|
|
2942
3194
|
Checkbox,
|
|
2943
3195
|
{
|
|
2944
3196
|
"aria-labelledby": removeExistingLabelId,
|
|
2945
|
-
checked:
|
|
2946
|
-
onCheckedChange: (checked) =>
|
|
3197
|
+
checked: imageProps.removeExistingImage,
|
|
3198
|
+
onCheckedChange: (checked) => imageProps.onRemoveExistingImageChange?.(checked === true)
|
|
2947
3199
|
}
|
|
2948
3200
|
)
|
|
2949
3201
|
] }) : null
|
|
2950
3202
|
] });
|
|
2951
3203
|
}
|
|
2952
3204
|
|
|
2953
|
-
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarFallback, AvatarImage, Badge, Calendar, Checkbox, ConfirmDialog, DatePicker, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownScrollableList, DropdownSelectSearchInput, EventCalendar, Form, FormControl, FormDescription, FormDrawer, FormField, FormItem, FormLabel, FormMessage, H3, Heading, Label, Link, MultiSelect, Paragraph, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SEARCHABLE_SELECT_MIN_OPTIONS, ScrollArea, ScrollBar, SearchField, Select, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Tooltip, TooltipProvider, UploadDropzone, badgeVariants, dropdownMenuSelectOptionsMaxHeightClassName, filterSelectOptions, foldSearchText, headingVariants, isSelectSearchable, linkStyles, paragraphVariants, useFormField };
|
|
2954
|
-
//# sourceMappingURL=chunk-
|
|
2955
|
-
//# sourceMappingURL=chunk-
|
|
3205
|
+
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarFallback, AvatarImage, Badge, Calendar, Checkbox, ConfirmDialog, DatePicker, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownScrollableList, DropdownSelectSearchInput, EventCalendar, Form, FormControl, FormDescription, FormDrawer, FormField, FormItem, FormLabel, FormMessage, H3, Heading, Label, Link, MultiSelect, Paragraph, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SEARCHABLE_SELECT_MIN_OPTIONS, ScrollArea, ScrollBar, SearchField, Select, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Tooltip, TooltipProvider, UploadDropzone, badgeVariants, dropdownMenuSelectOptionsMaxHeightClassName, fileMatchesAccept, filterSelectOptions, foldSearchText, headingVariants, isSelectSearchable, linkStyles, paragraphVariants, useFormField };
|
|
3206
|
+
//# sourceMappingURL=chunk-GDYI2I74.js.map
|
|
3207
|
+
//# sourceMappingURL=chunk-GDYI2I74.js.map
|