@yca-software/yca-react-core 0.0.23 → 0.0.25
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 +3 -1
- package/dist/{chunk-HJZNKZHZ.js → chunk-CTFLNTPC.js} +3 -3
- package/dist/{chunk-HJZNKZHZ.js.map → chunk-CTFLNTPC.js.map} +1 -1
- package/dist/{chunk-QHNZTXPJ.js → chunk-FJUWTB3A.js} +395 -140
- package/dist/chunk-FJUWTB3A.js.map +1 -0
- package/dist/{chunk-WZ64FPVI.js → chunk-VUWBN4CZ.js} +32 -23
- package/dist/chunk-VUWBN4CZ.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 +49 -18
- package/dist/components/ui/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/package.json +1 -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) : "");
|
|
@@ -1339,6 +1339,7 @@ function DropdownMenuTrigger({
|
|
|
1339
1339
|
}
|
|
1340
1340
|
function DropdownMenuContent({
|
|
1341
1341
|
className,
|
|
1342
|
+
animated = true,
|
|
1342
1343
|
sideOffset = 4,
|
|
1343
1344
|
portalled = true,
|
|
1344
1345
|
...props
|
|
@@ -1350,7 +1351,8 @@ function DropdownMenuContent({
|
|
|
1350
1351
|
sideOffset,
|
|
1351
1352
|
className: cn(
|
|
1352
1353
|
surfaceOverlay,
|
|
1353
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
1354
|
+
animated && "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
1355
|
+
"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1",
|
|
1354
1356
|
className
|
|
1355
1357
|
),
|
|
1356
1358
|
...props
|
|
@@ -1384,10 +1386,10 @@ function DropdownScrollableList({
|
|
|
1384
1386
|
scrollAreaClassName,
|
|
1385
1387
|
grow = true
|
|
1386
1388
|
}) {
|
|
1387
|
-
const scrollRef =
|
|
1388
|
-
const [showTop, setShowTop] =
|
|
1389
|
-
const [showBottom, setShowBottom] =
|
|
1390
|
-
const update =
|
|
1389
|
+
const scrollRef = React20.useRef(null);
|
|
1390
|
+
const [showTop, setShowTop] = React20.useState(false);
|
|
1391
|
+
const [showBottom, setShowBottom] = React20.useState(false);
|
|
1392
|
+
const update = React20.useCallback(() => {
|
|
1391
1393
|
const el = scrollRef.current;
|
|
1392
1394
|
if (!el) {
|
|
1393
1395
|
setShowTop(false);
|
|
@@ -1404,14 +1406,14 @@ function DropdownScrollableList({
|
|
|
1404
1406
|
setShowTop(scrollTop > 2);
|
|
1405
1407
|
setShowBottom(scrollTop + clientHeight < scrollHeight - 2);
|
|
1406
1408
|
}, []);
|
|
1407
|
-
|
|
1409
|
+
React20.useLayoutEffect(() => {
|
|
1408
1410
|
update();
|
|
1409
1411
|
const id = requestAnimationFrame(() => {
|
|
1410
1412
|
requestAnimationFrame(update);
|
|
1411
1413
|
});
|
|
1412
1414
|
return () => cancelAnimationFrame(id);
|
|
1413
1415
|
}, [update, scrollKey]);
|
|
1414
|
-
|
|
1416
|
+
React20.useEffect(() => {
|
|
1415
1417
|
const el = scrollRef.current;
|
|
1416
1418
|
if (!el) return;
|
|
1417
1419
|
if (typeof ResizeObserver === "undefined") {
|
|
@@ -1541,10 +1543,10 @@ function titleForView(anchor, view, weekStartsOnMonday) {
|
|
|
1541
1543
|
}
|
|
1542
1544
|
var MAX_MONTH_CHIPS = 3;
|
|
1543
1545
|
function useControlledDate(value, defaultValue, onChange) {
|
|
1544
|
-
const [internal, setInternal] =
|
|
1546
|
+
const [internal, setInternal] = React20.useState(defaultValue ?? /* @__PURE__ */ new Date());
|
|
1545
1547
|
const isControlled = value !== void 0;
|
|
1546
1548
|
const current = isControlled ? value : internal;
|
|
1547
|
-
const set =
|
|
1549
|
+
const set = React20.useCallback(
|
|
1548
1550
|
(next) => {
|
|
1549
1551
|
if (!isControlled) setInternal(next);
|
|
1550
1552
|
onChange?.(next);
|
|
@@ -1554,10 +1556,10 @@ function useControlledDate(value, defaultValue, onChange) {
|
|
|
1554
1556
|
return [current, set];
|
|
1555
1557
|
}
|
|
1556
1558
|
function useControlledView(value, defaultValue, onChange) {
|
|
1557
|
-
const [internal, setInternal] =
|
|
1559
|
+
const [internal, setInternal] = React20.useState(defaultValue);
|
|
1558
1560
|
const isControlled = value !== void 0;
|
|
1559
1561
|
const current = isControlled ? value : internal;
|
|
1560
|
-
const set =
|
|
1562
|
+
const set = React20.useCallback(
|
|
1561
1563
|
(next) => {
|
|
1562
1564
|
if (!isControlled) setInternal(next);
|
|
1563
1565
|
onChange?.(next);
|
|
@@ -1607,7 +1609,7 @@ function EventCalendar({
|
|
|
1607
1609
|
}) {
|
|
1608
1610
|
const [safeAnchor, setAnchor] = useControlledDate(value, defaultValue, onValueChange);
|
|
1609
1611
|
const [safeView, setViewSafe] = useControlledView(viewProp, defaultView, onViewChange);
|
|
1610
|
-
const weekdays =
|
|
1612
|
+
const weekdays = React20.useMemo(
|
|
1611
1613
|
() => weekdayLabels(weekStartsOnMonday, safeAnchor),
|
|
1612
1614
|
[weekStartsOnMonday, safeAnchor]
|
|
1613
1615
|
);
|
|
@@ -1819,15 +1821,15 @@ function Label({
|
|
|
1819
1821
|
return /* @__PURE__ */ jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn(labelVariants(), className), ...props });
|
|
1820
1822
|
}
|
|
1821
1823
|
var Form = FormProvider;
|
|
1822
|
-
var FormFieldContext =
|
|
1824
|
+
var FormFieldContext = React20.createContext(null);
|
|
1823
1825
|
var FormField = ({
|
|
1824
1826
|
...props
|
|
1825
1827
|
}) => {
|
|
1826
1828
|
return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
|
|
1827
1829
|
};
|
|
1828
1830
|
var useFormField = () => {
|
|
1829
|
-
const fieldContext =
|
|
1830
|
-
const itemContext =
|
|
1831
|
+
const fieldContext = React20.useContext(FormFieldContext);
|
|
1832
|
+
const itemContext = React20.useContext(FormItemContext);
|
|
1831
1833
|
if (fieldContext === null || fieldContext === void 0) {
|
|
1832
1834
|
throw new Error("useFormField should be used within <FormField>");
|
|
1833
1835
|
}
|
|
@@ -1844,9 +1846,9 @@ var useFormField = () => {
|
|
|
1844
1846
|
...fieldState
|
|
1845
1847
|
};
|
|
1846
1848
|
};
|
|
1847
|
-
var FormItemContext =
|
|
1849
|
+
var FormItemContext = React20.createContext({});
|
|
1848
1850
|
function FormItem({ className, ...props }) {
|
|
1849
|
-
const id =
|
|
1851
|
+
const id = React20.useId();
|
|
1850
1852
|
return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-3", className), ...props }) });
|
|
1851
1853
|
}
|
|
1852
1854
|
function FormLabel({
|
|
@@ -2025,29 +2027,66 @@ function FormDrawer({
|
|
|
2025
2027
|
onOpenChange,
|
|
2026
2028
|
title,
|
|
2027
2029
|
description,
|
|
2030
|
+
info,
|
|
2028
2031
|
children,
|
|
2029
2032
|
className,
|
|
2030
2033
|
contentClassName
|
|
2031
2034
|
}) {
|
|
2035
|
+
const bodyRef = React20.useRef(null);
|
|
2036
|
+
const [infoOpen, setInfoOpen] = React20.useState(false);
|
|
2037
|
+
React20.useEffect(() => {
|
|
2038
|
+
if (!open) setInfoOpen(false);
|
|
2039
|
+
}, [open]);
|
|
2032
2040
|
return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
2033
2041
|
SheetContent,
|
|
2034
2042
|
{
|
|
2035
2043
|
"data-slot": "form-drawer-content",
|
|
2044
|
+
onOpenAutoFocus: (event) => {
|
|
2045
|
+
event.preventDefault();
|
|
2046
|
+
bodyRef.current?.focus({ preventScroll: true });
|
|
2047
|
+
},
|
|
2048
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
2036
2049
|
className: cn(
|
|
2037
2050
|
"flex flex-col gap-4 w-[calc(100%-2rem)] max-w-[calc(100%-2rem)] sm:max-w-lg overflow-hidden",
|
|
2038
2051
|
contentClassName
|
|
2039
2052
|
),
|
|
2040
2053
|
children: [
|
|
2041
2054
|
/* @__PURE__ */ jsxs(SheetHeader, { className: "flex-shrink-0 gap-2 pb-2", children: [
|
|
2042
|
-
/* @__PURE__ */
|
|
2043
|
-
|
|
2055
|
+
/* @__PURE__ */ jsxs(SheetTitle, { className: "flex items-center gap-1.5 text-base sm:text-lg", children: [
|
|
2056
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0", children: title }),
|
|
2057
|
+
info ? /* @__PURE__ */ jsxs(Popover, { open: infoOpen, onOpenChange: setInfoOpen, children: [
|
|
2058
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2059
|
+
"button",
|
|
2060
|
+
{
|
|
2061
|
+
type: "button",
|
|
2062
|
+
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",
|
|
2063
|
+
"aria-label": "More info",
|
|
2064
|
+
"aria-expanded": infoOpen,
|
|
2065
|
+
children: /* @__PURE__ */ jsx(Info, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
2066
|
+
}
|
|
2067
|
+
) }),
|
|
2068
|
+
/* @__PURE__ */ jsx(
|
|
2069
|
+
PopoverContent,
|
|
2070
|
+
{
|
|
2071
|
+
side: "bottom",
|
|
2072
|
+
align: "start",
|
|
2073
|
+
sideOffset: 6,
|
|
2074
|
+
className: "z-[120] max-w-xs p-3 text-sm leading-snug",
|
|
2075
|
+
children: info
|
|
2076
|
+
}
|
|
2077
|
+
)
|
|
2078
|
+
] }) : null
|
|
2079
|
+
] }),
|
|
2080
|
+
description ? /* @__PURE__ */ jsx(SheetDescription, { className: "text-sm", children: description }) : null
|
|
2044
2081
|
] }),
|
|
2045
2082
|
/* @__PURE__ */ jsx(InsideModalScrollLockProvider, { children: /* @__PURE__ */ jsx(
|
|
2046
2083
|
"div",
|
|
2047
2084
|
{
|
|
2085
|
+
ref: bodyRef,
|
|
2086
|
+
tabIndex: -1,
|
|
2048
2087
|
className: cn(
|
|
2049
2088
|
// 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",
|
|
2089
|
+
"flex flex-col flex-1 min-h-0 gap-4 overflow-y-auto px-2 py-1 outline-none",
|
|
2051
2090
|
className
|
|
2052
2091
|
),
|
|
2053
2092
|
children
|
|
@@ -2106,14 +2145,14 @@ function MultiSelect({
|
|
|
2106
2145
|
}) {
|
|
2107
2146
|
const t = { ...DEFAULT_TRANSLATIONS2, ...translations };
|
|
2108
2147
|
const insideModalScrollLock = useInsideModalScrollLock();
|
|
2109
|
-
const [search, setSearch] =
|
|
2110
|
-
const selectedSet =
|
|
2111
|
-
const labelByValue =
|
|
2148
|
+
const [search, setSearch] = React20.useState("");
|
|
2149
|
+
const selectedSet = React20.useMemo(() => new Set(value), [value]);
|
|
2150
|
+
const labelByValue = React20.useMemo(() => {
|
|
2112
2151
|
const map = /* @__PURE__ */ new Map();
|
|
2113
2152
|
for (const opt of options) map.set(opt.value, opt.label);
|
|
2114
2153
|
return map;
|
|
2115
2154
|
}, [options]);
|
|
2116
|
-
const filteredOptions =
|
|
2155
|
+
const filteredOptions = React20.useMemo(() => {
|
|
2117
2156
|
const q = search.trim().toLowerCase();
|
|
2118
2157
|
if (!q) return options;
|
|
2119
2158
|
return options.filter((opt) => opt.label.toLowerCase().includes(q));
|
|
@@ -2209,7 +2248,7 @@ function MultiSelect({
|
|
|
2209
2248
|
] })
|
|
2210
2249
|
] });
|
|
2211
2250
|
}
|
|
2212
|
-
var ScrollArea =
|
|
2251
|
+
var ScrollArea = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2213
2252
|
ScrollAreaPrimitive.Root,
|
|
2214
2253
|
{
|
|
2215
2254
|
ref,
|
|
@@ -2223,7 +2262,7 @@ var ScrollArea = React8.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
2223
2262
|
}
|
|
2224
2263
|
));
|
|
2225
2264
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
2226
|
-
var ScrollBar =
|
|
2265
|
+
var ScrollBar = React20.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2227
2266
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
2228
2267
|
{
|
|
2229
2268
|
ref,
|
|
@@ -2361,10 +2400,10 @@ function Select({
|
|
|
2361
2400
|
}) {
|
|
2362
2401
|
const t = { ...DEFAULT_TRANSLATIONS3, ...translations };
|
|
2363
2402
|
const insideModalScrollLock = useInsideModalScrollLock();
|
|
2364
|
-
const [open, setOpen] =
|
|
2365
|
-
const [search, setSearch] =
|
|
2403
|
+
const [open, setOpen] = React20.useState(false);
|
|
2404
|
+
const [search, setSearch] = React20.useState("");
|
|
2366
2405
|
const showSearch = isSelectSearchable(options.length, searchable);
|
|
2367
|
-
const filteredOptions =
|
|
2406
|
+
const filteredOptions = React20.useMemo(
|
|
2368
2407
|
() => showSearch ? filterSelectOptions(options, search) : options,
|
|
2369
2408
|
[options, search, showSearch]
|
|
2370
2409
|
);
|
|
@@ -2389,7 +2428,7 @@ function Select({
|
|
|
2389
2428
|
controlFocus,
|
|
2390
2429
|
"flex h-9 w-full cursor-pointer items-center justify-between px-3 py-2 text-sm",
|
|
2391
2430
|
"hover:bg-accent/40 disabled:pointer-events-none disabled:opacity-50",
|
|
2392
|
-
!
|
|
2431
|
+
!selectedOption && "text-muted-foreground",
|
|
2393
2432
|
triggerClassName,
|
|
2394
2433
|
className
|
|
2395
2434
|
),
|
|
@@ -2402,6 +2441,7 @@ function Select({
|
|
|
2402
2441
|
/* @__PURE__ */ jsxs(
|
|
2403
2442
|
DropdownMenuContent,
|
|
2404
2443
|
{
|
|
2444
|
+
animated: false,
|
|
2405
2445
|
align: "start",
|
|
2406
2446
|
sideOffset: 0,
|
|
2407
2447
|
portalled: !insideModalScrollLock,
|
|
@@ -2429,10 +2469,8 @@ function Select({
|
|
|
2429
2469
|
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
2470
|
DropdownMenuItem,
|
|
2431
2471
|
{
|
|
2432
|
-
|
|
2472
|
+
onSelect: () => {
|
|
2433
2473
|
onValueChange(opt.value);
|
|
2434
|
-
setOpen(false);
|
|
2435
|
-
setSearch("");
|
|
2436
2474
|
},
|
|
2437
2475
|
children: opt.label
|
|
2438
2476
|
},
|
|
@@ -2468,7 +2506,7 @@ function ChevronDownIcon({ className, ...props }) {
|
|
|
2468
2506
|
}
|
|
2469
2507
|
);
|
|
2470
2508
|
}
|
|
2471
|
-
var Separator =
|
|
2509
|
+
var Separator = React20.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2472
2510
|
SeparatorPrimitive.Root,
|
|
2473
2511
|
{
|
|
2474
2512
|
ref,
|
|
@@ -2483,7 +2521,7 @@ var Separator = React8.forwardRef(({ className, orientation = "horizontal", deco
|
|
|
2483
2521
|
}
|
|
2484
2522
|
));
|
|
2485
2523
|
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
2486
|
-
var Switch =
|
|
2524
|
+
var Switch = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2487
2525
|
SwitchPrimitive.Root,
|
|
2488
2526
|
{
|
|
2489
2527
|
ref,
|
|
@@ -2509,11 +2547,11 @@ var Switch = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
2509
2547
|
}
|
|
2510
2548
|
));
|
|
2511
2549
|
Switch.displayName = SwitchPrimitive.Root.displayName;
|
|
2512
|
-
var Table =
|
|
2550
|
+
var Table = React20.forwardRef(
|
|
2513
2551
|
({ 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
2552
|
);
|
|
2515
2553
|
Table.displayName = "Table";
|
|
2516
|
-
var TableHeader =
|
|
2554
|
+
var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2517
2555
|
"thead",
|
|
2518
2556
|
{
|
|
2519
2557
|
ref,
|
|
@@ -2522,9 +2560,9 @@ var TableHeader = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2522
2560
|
}
|
|
2523
2561
|
));
|
|
2524
2562
|
TableHeader.displayName = "TableHeader";
|
|
2525
|
-
var TableBody =
|
|
2563
|
+
var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
|
|
2526
2564
|
TableBody.displayName = "TableBody";
|
|
2527
|
-
var TableFooter =
|
|
2565
|
+
var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2528
2566
|
"tfoot",
|
|
2529
2567
|
{
|
|
2530
2568
|
ref,
|
|
@@ -2536,7 +2574,7 @@ var TableFooter = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2536
2574
|
}
|
|
2537
2575
|
));
|
|
2538
2576
|
TableFooter.displayName = "TableFooter";
|
|
2539
|
-
var TableRow =
|
|
2577
|
+
var TableRow = React20.forwardRef(
|
|
2540
2578
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2541
2579
|
"tr",
|
|
2542
2580
|
{
|
|
@@ -2550,7 +2588,7 @@ var TableRow = React8.forwardRef(
|
|
|
2550
2588
|
)
|
|
2551
2589
|
);
|
|
2552
2590
|
TableRow.displayName = "TableRow";
|
|
2553
|
-
var TableHead =
|
|
2591
|
+
var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2554
2592
|
"th",
|
|
2555
2593
|
{
|
|
2556
2594
|
ref,
|
|
@@ -2562,7 +2600,7 @@ var TableHead = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
2562
2600
|
}
|
|
2563
2601
|
));
|
|
2564
2602
|
TableHead.displayName = "TableHead";
|
|
2565
|
-
var TableCell =
|
|
2603
|
+
var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2566
2604
|
"td",
|
|
2567
2605
|
{
|
|
2568
2606
|
ref,
|
|
@@ -2571,7 +2609,7 @@ var TableCell = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
2571
2609
|
}
|
|
2572
2610
|
));
|
|
2573
2611
|
TableCell.displayName = "TableCell";
|
|
2574
|
-
var TableCaption =
|
|
2612
|
+
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
|
|
2575
2613
|
TableCaption.displayName = "TableCaption";
|
|
2576
2614
|
function Tabs({ className, ...props }) {
|
|
2577
2615
|
return /* @__PURE__ */ jsx(
|
|
@@ -2631,7 +2669,7 @@ function TabsContent({
|
|
|
2631
2669
|
}
|
|
2632
2670
|
);
|
|
2633
2671
|
}
|
|
2634
|
-
var Textarea =
|
|
2672
|
+
var Textarea = React20.forwardRef(
|
|
2635
2673
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2636
2674
|
"textarea",
|
|
2637
2675
|
{
|
|
@@ -2652,58 +2690,157 @@ var Textarea = React8.forwardRef(
|
|
|
2652
2690
|
);
|
|
2653
2691
|
Textarea.displayName = "Textarea";
|
|
2654
2692
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
2693
|
+
function prefersCoarsePointer() {
|
|
2694
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
2695
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
2696
|
+
}
|
|
2697
|
+
function isPointerOver(el, x, y) {
|
|
2698
|
+
if (!el || typeof document.elementFromPoint !== "function") return false;
|
|
2699
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return false;
|
|
2700
|
+
const under = document.elementFromPoint(x, y);
|
|
2701
|
+
return Boolean(under && (under === el || el.contains(under)));
|
|
2702
|
+
}
|
|
2655
2703
|
function Tooltip({
|
|
2656
2704
|
content,
|
|
2657
2705
|
children,
|
|
2658
2706
|
side = "top",
|
|
2659
2707
|
align = "center",
|
|
2660
|
-
delayDuration =
|
|
2661
|
-
closeDelay =
|
|
2708
|
+
delayDuration = 200,
|
|
2709
|
+
closeDelay = 280
|
|
2662
2710
|
}) {
|
|
2663
|
-
const [open, setOpen] =
|
|
2664
|
-
const
|
|
2665
|
-
const
|
|
2666
|
-
const
|
|
2711
|
+
const [open, setOpen] = React20.useState(false);
|
|
2712
|
+
const triggerRef = React20.useRef(null);
|
|
2713
|
+
const stickyRef = React20.useRef(false);
|
|
2714
|
+
const hoveringRef = React20.useRef(false);
|
|
2715
|
+
const openRef = React20.useRef(false);
|
|
2716
|
+
const hoverArmedRef = React20.useRef(false);
|
|
2717
|
+
const layoutReadyRef = React20.useRef(false);
|
|
2718
|
+
const lastPointerRef = React20.useRef({ x: Number.NaN, y: Number.NaN });
|
|
2719
|
+
const openTimeoutRef = React20.useRef(null);
|
|
2720
|
+
const closeTimeoutRef = React20.useRef(null);
|
|
2721
|
+
React20.useEffect(() => {
|
|
2722
|
+
openRef.current = open;
|
|
2723
|
+
}, [open]);
|
|
2724
|
+
React20.useLayoutEffect(() => {
|
|
2725
|
+
hoverArmedRef.current = false;
|
|
2726
|
+
stickyRef.current = false;
|
|
2727
|
+
hoveringRef.current = false;
|
|
2728
|
+
layoutReadyRef.current = false;
|
|
2729
|
+
setOpen(false);
|
|
2730
|
+
const markReady = () => {
|
|
2731
|
+
layoutReadyRef.current = true;
|
|
2732
|
+
const el = triggerRef.current;
|
|
2733
|
+
const { x, y } = lastPointerRef.current;
|
|
2734
|
+
if (isPointerOver(el, x, y)) {
|
|
2735
|
+
hoverArmedRef.current = false;
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
hoverArmedRef.current = true;
|
|
2739
|
+
};
|
|
2740
|
+
let raf2 = 0;
|
|
2741
|
+
const raf1 = window.requestAnimationFrame(() => {
|
|
2742
|
+
raf2 = window.requestAnimationFrame(markReady);
|
|
2743
|
+
});
|
|
2744
|
+
const onPointerMove = (event) => {
|
|
2745
|
+
lastPointerRef.current = { x: event.clientX, y: event.clientY };
|
|
2746
|
+
if (!layoutReadyRef.current) return;
|
|
2747
|
+
if (isPointerOver(triggerRef.current, event.clientX, event.clientY)) return;
|
|
2748
|
+
hoverArmedRef.current = true;
|
|
2749
|
+
};
|
|
2750
|
+
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
2751
|
+
return () => {
|
|
2752
|
+
window.cancelAnimationFrame(raf1);
|
|
2753
|
+
window.cancelAnimationFrame(raf2);
|
|
2754
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
2755
|
+
};
|
|
2756
|
+
}, []);
|
|
2757
|
+
const clearOpenTimeout = React20.useCallback(() => {
|
|
2667
2758
|
if (openTimeoutRef.current !== null) {
|
|
2668
2759
|
window.clearTimeout(openTimeoutRef.current);
|
|
2669
2760
|
openTimeoutRef.current = null;
|
|
2670
2761
|
}
|
|
2671
2762
|
}, []);
|
|
2672
|
-
const clearCloseTimeout =
|
|
2763
|
+
const clearCloseTimeout = React20.useCallback(() => {
|
|
2673
2764
|
if (closeTimeoutRef.current !== null) {
|
|
2674
2765
|
window.clearTimeout(closeTimeoutRef.current);
|
|
2675
2766
|
closeTimeoutRef.current = null;
|
|
2676
2767
|
}
|
|
2677
2768
|
}, []);
|
|
2678
|
-
const
|
|
2769
|
+
const scheduleClose = React20.useCallback(() => {
|
|
2770
|
+
if (stickyRef.current || hoveringRef.current) return;
|
|
2771
|
+
clearOpenTimeout();
|
|
2772
|
+
clearCloseTimeout();
|
|
2773
|
+
if (closeDelay === 0) {
|
|
2774
|
+
setOpen(false);
|
|
2775
|
+
return;
|
|
2776
|
+
}
|
|
2777
|
+
closeTimeoutRef.current = window.setTimeout(() => {
|
|
2778
|
+
if (stickyRef.current || hoveringRef.current) return;
|
|
2779
|
+
setOpen(false);
|
|
2780
|
+
}, closeDelay);
|
|
2781
|
+
}, [clearCloseTimeout, clearOpenTimeout, closeDelay]);
|
|
2782
|
+
const handleOpenChange = React20.useCallback(
|
|
2679
2783
|
(next) => {
|
|
2680
|
-
if (
|
|
2784
|
+
if (next) {
|
|
2785
|
+
if (!hoveringRef.current && !stickyRef.current) return;
|
|
2786
|
+
setOpen(true);
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
if (stickyRef.current) {
|
|
2790
|
+
stickyRef.current = false;
|
|
2791
|
+
hoveringRef.current = false;
|
|
2681
2792
|
clearOpenTimeout();
|
|
2682
2793
|
clearCloseTimeout();
|
|
2683
2794
|
setOpen(false);
|
|
2795
|
+
return;
|
|
2684
2796
|
}
|
|
2797
|
+
scheduleClose();
|
|
2685
2798
|
},
|
|
2686
|
-
[clearCloseTimeout, clearOpenTimeout]
|
|
2799
|
+
[clearCloseTimeout, clearOpenTimeout, scheduleClose]
|
|
2687
2800
|
);
|
|
2688
|
-
const handlePointerEnter =
|
|
2801
|
+
const handlePointerEnter = React20.useCallback(() => {
|
|
2802
|
+
if (!hoverArmedRef.current) return;
|
|
2803
|
+
hoveringRef.current = true;
|
|
2689
2804
|
clearCloseTimeout();
|
|
2690
2805
|
clearOpenTimeout();
|
|
2806
|
+
if (openRef.current || delayDuration <= 0) {
|
|
2807
|
+
setOpen(true);
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2691
2810
|
openTimeoutRef.current = window.setTimeout(() => {
|
|
2811
|
+
if (!hoveringRef.current || !hoverArmedRef.current) return;
|
|
2692
2812
|
setOpen(true);
|
|
2693
2813
|
}, delayDuration);
|
|
2694
2814
|
}, [clearCloseTimeout, clearOpenTimeout, delayDuration]);
|
|
2695
|
-
const handlePointerLeave =
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
}, [
|
|
2706
|
-
|
|
2815
|
+
const handlePointerLeave = React20.useCallback(() => {
|
|
2816
|
+
hoverArmedRef.current = true;
|
|
2817
|
+
hoveringRef.current = false;
|
|
2818
|
+
scheduleClose();
|
|
2819
|
+
}, [scheduleClose]);
|
|
2820
|
+
const blockRadixFocusOpen = React20.useCallback((e) => {
|
|
2821
|
+
e.preventDefault();
|
|
2822
|
+
}, []);
|
|
2823
|
+
const blockRadixPointerMoveOpen = React20.useCallback((e) => {
|
|
2824
|
+
e.preventDefault();
|
|
2825
|
+
}, []);
|
|
2826
|
+
const handleTriggerClick = React20.useCallback(
|
|
2827
|
+
(e) => {
|
|
2828
|
+
if (!prefersCoarsePointer()) {
|
|
2829
|
+
e.preventDefault();
|
|
2830
|
+
return;
|
|
2831
|
+
}
|
|
2832
|
+
clearOpenTimeout();
|
|
2833
|
+
clearCloseTimeout();
|
|
2834
|
+
const next = !open;
|
|
2835
|
+
stickyRef.current = next;
|
|
2836
|
+
hoveringRef.current = next;
|
|
2837
|
+
hoverArmedRef.current = true;
|
|
2838
|
+
setOpen(next);
|
|
2839
|
+
e.preventDefault();
|
|
2840
|
+
},
|
|
2841
|
+
[clearCloseTimeout, clearOpenTimeout, open]
|
|
2842
|
+
);
|
|
2843
|
+
React20.useEffect(
|
|
2707
2844
|
() => () => {
|
|
2708
2845
|
clearOpenTimeout();
|
|
2709
2846
|
clearCloseTimeout();
|
|
@@ -2714,9 +2851,13 @@ function Tooltip({
|
|
|
2714
2851
|
/* @__PURE__ */ jsx(
|
|
2715
2852
|
TooltipPrimitive.Trigger,
|
|
2716
2853
|
{
|
|
2854
|
+
ref: triggerRef,
|
|
2717
2855
|
asChild: true,
|
|
2856
|
+
onFocus: blockRadixFocusOpen,
|
|
2857
|
+
onPointerMove: blockRadixPointerMoveOpen,
|
|
2718
2858
|
onPointerEnter: handlePointerEnter,
|
|
2719
2859
|
onPointerLeave: handlePointerLeave,
|
|
2860
|
+
onClick: handleTriggerClick,
|
|
2720
2861
|
children
|
|
2721
2862
|
}
|
|
2722
2863
|
),
|
|
@@ -2764,7 +2905,7 @@ var paragraphVariants = cva("text-muted-foreground leading-relaxed", {
|
|
|
2764
2905
|
size: "default"
|
|
2765
2906
|
}
|
|
2766
2907
|
});
|
|
2767
|
-
var Heading =
|
|
2908
|
+
var Heading = React20.forwardRef(
|
|
2768
2909
|
({ className, level, as, ...props }, ref) => {
|
|
2769
2910
|
const Component = as || (level === "h1" ? "h1" : level === "h2" ? "h2" : level === "h3" ? "h3" : "h4");
|
|
2770
2911
|
return /* @__PURE__ */ jsx(
|
|
@@ -2778,13 +2919,13 @@ var Heading = React8.forwardRef(
|
|
|
2778
2919
|
}
|
|
2779
2920
|
);
|
|
2780
2921
|
Heading.displayName = "Heading";
|
|
2781
|
-
var Paragraph =
|
|
2922
|
+
var Paragraph = React20.forwardRef(
|
|
2782
2923
|
({ className, size, ...props }, ref) => {
|
|
2783
2924
|
return /* @__PURE__ */ jsx("p", { ref, className: cn(paragraphVariants({ size }), className), ...props });
|
|
2784
2925
|
}
|
|
2785
2926
|
);
|
|
2786
2927
|
Paragraph.displayName = "Paragraph";
|
|
2787
|
-
var H3 =
|
|
2928
|
+
var H3 = React20.forwardRef(
|
|
2788
2929
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(Heading, { ref, level: "h3", as: "h3", className, ...props })
|
|
2789
2930
|
);
|
|
2790
2931
|
H3.displayName = "H3";
|
|
@@ -2794,10 +2935,30 @@ var DEFAULT_TRANSLATIONS4 = {
|
|
|
2794
2935
|
chooseImageText: "Choose image",
|
|
2795
2936
|
chooseFileText: "Choose file",
|
|
2796
2937
|
removeText: "Remove",
|
|
2797
|
-
removeExistingImageText: "Remove existing image"
|
|
2938
|
+
removeExistingImageText: "Remove existing image",
|
|
2939
|
+
removeFileAriaLabel: "Remove file"
|
|
2798
2940
|
};
|
|
2941
|
+
function fileMatchesAccept(file, accept) {
|
|
2942
|
+
if (!accept?.trim()) return true;
|
|
2943
|
+
const tokens = accept.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
2944
|
+
if (!tokens.length) return true;
|
|
2945
|
+
const name = file.name.toLowerCase();
|
|
2946
|
+
const type = (file.type || "").toLowerCase();
|
|
2947
|
+
return tokens.some((token) => {
|
|
2948
|
+
if (token.startsWith(".")) return name.endsWith(token);
|
|
2949
|
+
if (token.endsWith("/*")) return type.startsWith(token.slice(0, -1));
|
|
2950
|
+
return type === token;
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
function fileKey(file) {
|
|
2954
|
+
return `${file.name}:${file.size}:${file.lastModified}`;
|
|
2955
|
+
}
|
|
2956
|
+
function isFileLike(value) {
|
|
2957
|
+
return typeof value === "object" && value != null && typeof value.name === "string" && typeof value.size === "number";
|
|
2958
|
+
}
|
|
2799
2959
|
function UploadDropzone(props) {
|
|
2800
2960
|
const isFile = props.variant === "file";
|
|
2961
|
+
const isMultiple = isFile && (props.multiple === true || Array.isArray(props.value));
|
|
2801
2962
|
const inputId = useId();
|
|
2802
2963
|
const removeExistingLabelId = useId();
|
|
2803
2964
|
const pickerDisabled = isFile && props.disabled;
|
|
@@ -2805,40 +2966,83 @@ function UploadDropzone(props) {
|
|
|
2805
2966
|
const inputRef = useRef(null);
|
|
2806
2967
|
const [isDragging, setIsDragging] = useState(false);
|
|
2807
2968
|
const [previewUrl, setPreviewUrl] = useState(null);
|
|
2969
|
+
const singleFile = isFile && !isMultiple && isFileLike(props.value) ? props.value : null;
|
|
2970
|
+
const multiFiles = isMultiple && Array.isArray(props.value) ? props.value.filter(isFileLike) : [];
|
|
2971
|
+
const accept = isFile ? props.accept : "image/*";
|
|
2972
|
+
const setSingleFile = (file) => {
|
|
2973
|
+
if (isFile && !isMultiple) {
|
|
2974
|
+
props.onChange(file);
|
|
2975
|
+
return;
|
|
2976
|
+
}
|
|
2977
|
+
if (!isFile) {
|
|
2978
|
+
props.onChange(file);
|
|
2979
|
+
props.onRemoveExistingImageChange?.(false);
|
|
2980
|
+
}
|
|
2981
|
+
};
|
|
2982
|
+
const setMultiFiles = (next) => {
|
|
2983
|
+
if (isMultiple) props.onChange(next);
|
|
2984
|
+
};
|
|
2985
|
+
const imageFile = !isFile && isFileLike(props.value) ? props.value : null;
|
|
2808
2986
|
useEffect(() => {
|
|
2809
2987
|
if (isFile) {
|
|
2810
|
-
|
|
2988
|
+
const mime = singleFile?.type || "";
|
|
2989
|
+
if (!singleFile || !mime.startsWith("video/")) {
|
|
2811
2990
|
setPreviewUrl(null);
|
|
2812
2991
|
return;
|
|
2813
2992
|
}
|
|
2814
|
-
const nextUrl2 = URL.createObjectURL(
|
|
2993
|
+
const nextUrl2 = URL.createObjectURL(singleFile);
|
|
2815
2994
|
setPreviewUrl(nextUrl2);
|
|
2816
2995
|
return () => URL.revokeObjectURL(nextUrl2);
|
|
2817
2996
|
}
|
|
2818
|
-
if (!
|
|
2997
|
+
if (!imageFile) {
|
|
2819
2998
|
setPreviewUrl(null);
|
|
2820
2999
|
return;
|
|
2821
3000
|
}
|
|
2822
|
-
const nextUrl = URL.createObjectURL(
|
|
3001
|
+
const nextUrl = URL.createObjectURL(imageFile);
|
|
2823
3002
|
setPreviewUrl(nextUrl);
|
|
2824
3003
|
return () => URL.revokeObjectURL(nextUrl);
|
|
2825
|
-
}, [isFile,
|
|
2826
|
-
const
|
|
2827
|
-
if (!
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
3004
|
+
}, [imageFile, isFile, singleFile]);
|
|
3005
|
+
const acceptFiles = (incoming) => {
|
|
3006
|
+
if (!incoming || pickerDisabled) return;
|
|
3007
|
+
const list = Array.from(incoming).filter(isFileLike);
|
|
3008
|
+
if (!list.length) return;
|
|
3009
|
+
const accepted = [];
|
|
3010
|
+
for (const file of list) {
|
|
3011
|
+
if (props.maxSizeBytes != null && file.size > props.maxSizeBytes) {
|
|
3012
|
+
props.onFileTooLarge?.();
|
|
3013
|
+
continue;
|
|
3014
|
+
}
|
|
3015
|
+
if (isFile) {
|
|
3016
|
+
if (!fileMatchesAccept(file, accept)) {
|
|
3017
|
+
props.onInvalidFile?.();
|
|
3018
|
+
continue;
|
|
3019
|
+
}
|
|
3020
|
+
accepted.push(file);
|
|
3021
|
+
continue;
|
|
3022
|
+
}
|
|
3023
|
+
if (!(file.type || "").startsWith("image/")) {
|
|
3024
|
+
props.onInvalidFile?.();
|
|
3025
|
+
continue;
|
|
3026
|
+
}
|
|
3027
|
+
accepted.push(file);
|
|
3028
|
+
}
|
|
3029
|
+
if (!accepted.length) return;
|
|
3030
|
+
if (isMultiple) {
|
|
3031
|
+
const seen = new Set(multiFiles.map(fileKey));
|
|
3032
|
+
const next = [...multiFiles];
|
|
3033
|
+
for (const file of accepted) {
|
|
3034
|
+
const key = fileKey(file);
|
|
3035
|
+
if (seen.has(key)) continue;
|
|
3036
|
+
seen.add(key);
|
|
3037
|
+
next.push(file);
|
|
3038
|
+
}
|
|
3039
|
+
setMultiFiles(next);
|
|
2835
3040
|
return;
|
|
2836
3041
|
}
|
|
2837
|
-
|
|
2838
|
-
props.onChange(file);
|
|
2839
|
-
props.onRemoveExistingImageChange?.(false);
|
|
3042
|
+
setSingleFile(accepted[0] ?? null);
|
|
2840
3043
|
};
|
|
2841
|
-
const
|
|
3044
|
+
const imageProps = !isFile ? props : null;
|
|
3045
|
+
const displayedImage = imageProps && (previewUrl ?? (!imageProps.removeExistingImage ? imageProps.existingImageUrl : void 0));
|
|
2842
3046
|
const dashedClasses = cn(
|
|
2843
3047
|
"block rounded-xl border-2 border-dashed border-border/55 p-4 transition-colors",
|
|
2844
3048
|
pickerDisabled && "pointer-events-none opacity-50",
|
|
@@ -2862,8 +3066,7 @@ function UploadDropzone(props) {
|
|
|
2862
3066
|
event.preventDefault();
|
|
2863
3067
|
setIsDragging(false);
|
|
2864
3068
|
if (pickerDisabled) return;
|
|
2865
|
-
|
|
2866
|
-
handleFile(file);
|
|
3069
|
+
acceptFiles(event.dataTransfer.files);
|
|
2867
3070
|
},
|
|
2868
3071
|
children: [
|
|
2869
3072
|
/* @__PURE__ */ jsx(
|
|
@@ -2872,10 +3075,14 @@ function UploadDropzone(props) {
|
|
|
2872
3075
|
id: inputId,
|
|
2873
3076
|
ref: inputRef,
|
|
2874
3077
|
type: "file",
|
|
2875
|
-
accept
|
|
3078
|
+
accept,
|
|
3079
|
+
multiple: isMultiple || void 0,
|
|
2876
3080
|
disabled: pickerDisabled || void 0,
|
|
2877
3081
|
className: "sr-only",
|
|
2878
|
-
onChange: (event) =>
|
|
3082
|
+
onChange: (event) => {
|
|
3083
|
+
acceptFiles(event.target.files);
|
|
3084
|
+
event.target.value = "";
|
|
3085
|
+
}
|
|
2879
3086
|
}
|
|
2880
3087
|
),
|
|
2881
3088
|
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 +3094,40 @@ function UploadDropzone(props) {
|
|
|
2887
3094
|
className: "max-h-44 w-full rounded-lg border border-border/45 bg-foreground"
|
|
2888
3095
|
}
|
|
2889
3096
|
) : /* @__PURE__ */ jsx(FileText, { className: "h-8 w-8 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
2890
|
-
|
|
3097
|
+
isMultiple ? multiFiles.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "w-full space-y-1.5 text-left", children: multiFiles.map((file) => /* @__PURE__ */ jsxs(
|
|
3098
|
+
"li",
|
|
3099
|
+
{
|
|
3100
|
+
className: "flex items-center gap-2 rounded-md border border-border/40 bg-background/60 px-2 py-1.5",
|
|
3101
|
+
children: [
|
|
3102
|
+
/* @__PURE__ */ jsx(
|
|
3103
|
+
FileText,
|
|
3104
|
+
{
|
|
3105
|
+
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
3106
|
+
"aria-hidden": true
|
|
3107
|
+
}
|
|
3108
|
+
),
|
|
3109
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: file.name }),
|
|
3110
|
+
/* @__PURE__ */ jsx(
|
|
3111
|
+
Button,
|
|
3112
|
+
{
|
|
3113
|
+
type: "button",
|
|
3114
|
+
size: "sm",
|
|
3115
|
+
variant: "ghost",
|
|
3116
|
+
className: "h-7 w-7 shrink-0 p-0",
|
|
3117
|
+
disabled: pickerDisabled || void 0,
|
|
3118
|
+
"aria-label": `${t.removeFileAriaLabel} ${file.name}`,
|
|
3119
|
+
onClick: (event) => {
|
|
3120
|
+
event.preventDefault();
|
|
3121
|
+
event.stopPropagation();
|
|
3122
|
+
setMultiFiles(multiFiles.filter((f) => fileKey(f) !== fileKey(file)));
|
|
3123
|
+
},
|
|
3124
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
3125
|
+
}
|
|
3126
|
+
)
|
|
3127
|
+
]
|
|
3128
|
+
},
|
|
3129
|
+
fileKey(file)
|
|
3130
|
+
)) }) : null : singleFile ? /* @__PURE__ */ jsx("p", { className: "line-clamp-2 w-full break-all text-sm font-medium", children: singleFile.name }) : null
|
|
2891
3131
|
] }) : displayedImage ? /* @__PURE__ */ jsx(
|
|
2892
3132
|
"img",
|
|
2893
3133
|
{
|
|
@@ -2916,7 +3156,22 @@ function UploadDropzone(props) {
|
|
|
2916
3156
|
]
|
|
2917
3157
|
}
|
|
2918
3158
|
),
|
|
2919
|
-
|
|
3159
|
+
!isMultiple && isFile && singleFile ? /* @__PURE__ */ jsx(
|
|
3160
|
+
Button,
|
|
3161
|
+
{
|
|
3162
|
+
type: "button",
|
|
3163
|
+
size: "sm",
|
|
3164
|
+
variant: "outline",
|
|
3165
|
+
disabled: pickerDisabled || void 0,
|
|
3166
|
+
onClick: (event) => {
|
|
3167
|
+
event.preventDefault();
|
|
3168
|
+
event.stopPropagation();
|
|
3169
|
+
setSingleFile(null);
|
|
3170
|
+
},
|
|
3171
|
+
children: t.removeText
|
|
3172
|
+
}
|
|
3173
|
+
) : null,
|
|
3174
|
+
isMultiple && multiFiles.length > 0 ? /* @__PURE__ */ jsx(
|
|
2920
3175
|
Button,
|
|
2921
3176
|
{
|
|
2922
3177
|
type: "button",
|
|
@@ -2926,7 +3181,7 @@ function UploadDropzone(props) {
|
|
|
2926
3181
|
onClick: (event) => {
|
|
2927
3182
|
event.preventDefault();
|
|
2928
3183
|
event.stopPropagation();
|
|
2929
|
-
|
|
3184
|
+
setMultiFiles([]);
|
|
2930
3185
|
},
|
|
2931
3186
|
children: t.removeText
|
|
2932
3187
|
}
|
|
@@ -2936,20 +3191,20 @@ function UploadDropzone(props) {
|
|
|
2936
3191
|
]
|
|
2937
3192
|
}
|
|
2938
3193
|
),
|
|
2939
|
-
|
|
3194
|
+
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
3195
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", id: removeExistingLabelId, children: t.removeExistingImageText }),
|
|
2941
3196
|
/* @__PURE__ */ jsx(
|
|
2942
3197
|
Checkbox,
|
|
2943
3198
|
{
|
|
2944
3199
|
"aria-labelledby": removeExistingLabelId,
|
|
2945
|
-
checked:
|
|
2946
|
-
onCheckedChange: (checked) =>
|
|
3200
|
+
checked: imageProps.removeExistingImage,
|
|
3201
|
+
onCheckedChange: (checked) => imageProps.onRemoveExistingImageChange?.(checked === true)
|
|
2947
3202
|
}
|
|
2948
3203
|
)
|
|
2949
3204
|
] }) : null
|
|
2950
3205
|
] });
|
|
2951
3206
|
}
|
|
2952
3207
|
|
|
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-
|
|
3208
|
+
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 };
|
|
3209
|
+
//# sourceMappingURL=chunk-FJUWTB3A.js.map
|
|
3210
|
+
//# sourceMappingURL=chunk-FJUWTB3A.js.map
|