@bizapps/design-system-testing 1.0.11 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor.cjs +1242 -0
- package/dist/editor.cjs.map +1 -0
- package/dist/editor.d.cts +318 -0
- package/dist/editor.d.ts +318 -0
- package/dist/editor.js +1231 -0
- package/dist/editor.js.map +1 -0
- package/dist/main.cjs +1663 -462
- package/dist/main.cjs.map +1 -1
- package/dist/main.css +1 -1
- package/dist/main.d.cts +283 -64
- package/dist/main.d.ts +283 -64
- package/dist/main.js +1628 -464
- package/dist/main.js.map +1 -1
- package/dist/phone.cjs +18 -0
- package/dist/phone.cjs.map +1 -0
- package/dist/phone.d.cts +28 -0
- package/dist/phone.d.ts +28 -0
- package/dist/phone.js +16 -0
- package/dist/phone.js.map +1 -0
- package/dist/policy-DPpMNLiO.d.cts +75 -0
- package/dist/policy-DPpMNLiO.d.ts +75 -0
- package/dist/policy.cjs +33 -0
- package/dist/policy.cjs.map +1 -0
- package/dist/policy.d.cts +1 -0
- package/dist/policy.d.ts +1 -0
- package/dist/policy.js +29 -0
- package/dist/policy.js.map +1 -0
- package/package.json +85 -15
package/dist/main.cjs
CHANGED
|
@@ -8,13 +8,15 @@ var tailwindMerge = require('tailwind-merge');
|
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
var react = require('react');
|
|
10
10
|
var radixUi = require('radix-ui');
|
|
11
|
-
var reactDayPicker = require('react-day-picker');
|
|
12
11
|
var dateFns = require('date-fns');
|
|
13
12
|
var useEmblaCarousel = require('embla-carousel-react');
|
|
14
|
-
var
|
|
13
|
+
var libphonenumberJs = require('libphonenumber-js');
|
|
15
14
|
var cmdk = require('cmdk');
|
|
15
|
+
var countryFlags = require('country-flag-icons/react/3x2');
|
|
16
|
+
var react$1 = require('motion/react');
|
|
16
17
|
var reactDropzone = require('react-dropzone');
|
|
17
18
|
var Color = require('color');
|
|
19
|
+
var reactDayPicker = require('react-day-picker');
|
|
18
20
|
var react$2 = require('@schedule-x/react');
|
|
19
21
|
var calendar = require('@schedule-x/calendar');
|
|
20
22
|
var eventsService = require('@schedule-x/events-service');
|
|
@@ -28,7 +30,26 @@ var reactTable = require('@tanstack/react-table');
|
|
|
28
30
|
|
|
29
31
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
32
|
|
|
33
|
+
function _interopNamespace(e) {
|
|
34
|
+
if (e && e.__esModule) return e;
|
|
35
|
+
var n = Object.create(null);
|
|
36
|
+
if (e) {
|
|
37
|
+
Object.keys(e).forEach(function (k) {
|
|
38
|
+
if (k !== 'default') {
|
|
39
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
40
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
get: function () { return e[k]; }
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
n.default = e;
|
|
48
|
+
return Object.freeze(n);
|
|
49
|
+
}
|
|
50
|
+
|
|
31
51
|
var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
|
|
52
|
+
var countryFlags__namespace = /*#__PURE__*/_interopNamespace(countryFlags);
|
|
32
53
|
var Color__default = /*#__PURE__*/_interopDefault(Color);
|
|
33
54
|
|
|
34
55
|
// src/components/ui/Alert/alert.tsx
|
|
@@ -457,174 +478,6 @@ function Button({
|
|
|
457
478
|
}
|
|
458
479
|
);
|
|
459
480
|
}
|
|
460
|
-
function Calendar({
|
|
461
|
-
className,
|
|
462
|
-
classNames,
|
|
463
|
-
showOutsideDays = true,
|
|
464
|
-
captionLayout = "dropdown",
|
|
465
|
-
buttonVariant = "ghost",
|
|
466
|
-
locale,
|
|
467
|
-
formatters,
|
|
468
|
-
components,
|
|
469
|
-
fromYear,
|
|
470
|
-
toYear,
|
|
471
|
-
...props
|
|
472
|
-
}) {
|
|
473
|
-
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
474
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
475
|
-
reactDayPicker.DayPicker,
|
|
476
|
-
{
|
|
477
|
-
showOutsideDays,
|
|
478
|
-
className: cn(
|
|
479
|
-
"group/calendar bg-background p-3 font-sans [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
|
|
480
|
-
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
481
|
-
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
482
|
-
className
|
|
483
|
-
),
|
|
484
|
-
captionLayout,
|
|
485
|
-
startMonth: new Date(fromYear ?? 1900, 0),
|
|
486
|
-
endMonth: new Date(toYear ?? 2100, 11),
|
|
487
|
-
locale,
|
|
488
|
-
formatters: {
|
|
489
|
-
formatMonthDropdown: (date) => date.toLocaleString(locale?.code, { month: "short" }),
|
|
490
|
-
...formatters
|
|
491
|
-
},
|
|
492
|
-
classNames: {
|
|
493
|
-
root: cn("w-fit", defaultClassNames.root),
|
|
494
|
-
months: cn("relative flex flex-col gap-3 md:flex-row", defaultClassNames.months),
|
|
495
|
-
month: cn("flex w-full flex-col gap-3", defaultClassNames.month),
|
|
496
|
-
nav: cn(
|
|
497
|
-
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-2",
|
|
498
|
-
defaultClassNames.nav
|
|
499
|
-
),
|
|
500
|
-
button_previous: cn(
|
|
501
|
-
buttonVariants({ variant: buttonVariant }),
|
|
502
|
-
"size-7 p-0 select-none opacity-50 aria-disabled:opacity-30 transition-opacity duration-150 hover:opacity-100",
|
|
503
|
-
defaultClassNames.button_previous
|
|
504
|
-
),
|
|
505
|
-
button_next: cn(
|
|
506
|
-
buttonVariants({ variant: buttonVariant }),
|
|
507
|
-
"size-7 p-0 select-none opacity-50 aria-disabled:opacity-30 transition-opacity duration-150 hover:opacity-100",
|
|
508
|
-
defaultClassNames.button_next
|
|
509
|
-
),
|
|
510
|
-
month_caption: cn(
|
|
511
|
-
"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size) tracking-tight",
|
|
512
|
-
defaultClassNames.month_caption
|
|
513
|
-
),
|
|
514
|
-
dropdowns: cn(
|
|
515
|
-
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-semibold",
|
|
516
|
-
defaultClassNames.dropdowns
|
|
517
|
-
),
|
|
518
|
-
dropdown_root: cn(
|
|
519
|
-
"relative rounded-(--cell-radius)",
|
|
520
|
-
defaultClassNames.dropdown_root
|
|
521
|
-
),
|
|
522
|
-
dropdown: cn("absolute inset-0 bg-popover opacity-0", defaultClassNames.dropdown),
|
|
523
|
-
caption_label: cn(
|
|
524
|
-
"font-semibold select-none",
|
|
525
|
-
captionLayout === "label" ? "text-sm" : "flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
|
|
526
|
-
defaultClassNames.caption_label
|
|
527
|
-
),
|
|
528
|
-
weekdays: cn("flex gap-1", defaultClassNames.weekdays),
|
|
529
|
-
weekday: cn(
|
|
530
|
-
"flex-1 rounded-(--cell-radius) text-[0.75rem] font-semibold text-muted-foreground/70 select-none tracking-wide",
|
|
531
|
-
defaultClassNames.weekday
|
|
532
|
-
),
|
|
533
|
-
week: cn("mt-2 flex w-full gap-1", defaultClassNames.week),
|
|
534
|
-
week_number_header: cn(
|
|
535
|
-
"w-(--cell-size) select-none",
|
|
536
|
-
defaultClassNames.week_number_header
|
|
537
|
-
),
|
|
538
|
-
week_number: cn(
|
|
539
|
-
"text-[0.75rem] text-muted-foreground/50 select-none",
|
|
540
|
-
defaultClassNames.week_number
|
|
541
|
-
),
|
|
542
|
-
day: cn(
|
|
543
|
-
"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
|
|
544
|
-
props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)" : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
|
|
545
|
-
defaultClassNames.day
|
|
546
|
-
),
|
|
547
|
-
range_start: cn(
|
|
548
|
-
"relative isolate z-0 rounded-l-md bg-primary/8 after:absolute after:inset-y-0 after:right-0 after:w-3 after:bg-primary/8",
|
|
549
|
-
defaultClassNames.range_start
|
|
550
|
-
),
|
|
551
|
-
range_middle: cn("rounded-none bg-primary/8", defaultClassNames.range_middle),
|
|
552
|
-
range_end: cn(
|
|
553
|
-
"relative isolate z-0 rounded-r-md bg-primary/8 after:absolute after:inset-y-0 after:left-0 after:w-3 after:bg-primary/8",
|
|
554
|
-
defaultClassNames.range_end
|
|
555
|
-
),
|
|
556
|
-
today: cn("rounded-md bg-accent text-accent-foreground", defaultClassNames.today),
|
|
557
|
-
outside: cn(
|
|
558
|
-
"text-muted-foreground/50 aria-selected:text-muted-foreground/50",
|
|
559
|
-
defaultClassNames.outside
|
|
560
|
-
),
|
|
561
|
-
disabled: cn("text-muted-foreground/40 opacity-50", defaultClassNames.disabled),
|
|
562
|
-
hidden: cn("invisible", defaultClassNames.hidden),
|
|
563
|
-
...classNames
|
|
564
|
-
},
|
|
565
|
-
components: {
|
|
566
|
-
Root: ({ className: className2, rootRef, ...props2 }) => {
|
|
567
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
568
|
-
"div",
|
|
569
|
-
{
|
|
570
|
-
"data-slot": "calendar",
|
|
571
|
-
ref: rootRef,
|
|
572
|
-
className: cn(className2),
|
|
573
|
-
...props2
|
|
574
|
-
}
|
|
575
|
-
);
|
|
576
|
-
},
|
|
577
|
-
Chevron: ({ className: className2, orientation, ...props2 }) => {
|
|
578
|
-
if (orientation === "left") {
|
|
579
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
|
|
580
|
-
}
|
|
581
|
-
if (orientation === "right") {
|
|
582
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: cn("size-4", className2), ...props2 });
|
|
583
|
-
}
|
|
584
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
|
|
585
|
-
},
|
|
586
|
-
DayButton: ({ ...props2 }) => /* @__PURE__ */ jsxRuntime.jsx(CalendarDayButton, { locale, ...props2 }),
|
|
587
|
-
WeekNumber: ({ children, ...props2 }) => {
|
|
588
|
-
return /* @__PURE__ */ jsxRuntime.jsx("td", { ...props2, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
|
|
589
|
-
},
|
|
590
|
-
...components
|
|
591
|
-
},
|
|
592
|
-
...props
|
|
593
|
-
}
|
|
594
|
-
);
|
|
595
|
-
}
|
|
596
|
-
function CalendarDayButton({
|
|
597
|
-
className,
|
|
598
|
-
day,
|
|
599
|
-
modifiers,
|
|
600
|
-
locale,
|
|
601
|
-
...props
|
|
602
|
-
}) {
|
|
603
|
-
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
604
|
-
const ref = react.useRef(null);
|
|
605
|
-
react.useEffect(() => {
|
|
606
|
-
if (modifiers.focused) ref.current?.focus();
|
|
607
|
-
}, [modifiers.focused]);
|
|
608
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
609
|
-
Button,
|
|
610
|
-
{
|
|
611
|
-
ref,
|
|
612
|
-
variant: "ghost",
|
|
613
|
-
size: "icon-sm",
|
|
614
|
-
"data-day": day.date.toLocaleDateString(locale?.code),
|
|
615
|
-
"data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
|
|
616
|
-
"data-range-start": modifiers.range_start,
|
|
617
|
-
"data-range-end": modifiers.range_end,
|
|
618
|
-
"data-range-middle": modifiers.range_middle,
|
|
619
|
-
className: cn(
|
|
620
|
-
"group-data-[focused=true]/day:ring-primary/40 data-[range-end=true]:!bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:!bg-primary/8 data-[range-middle=true]:text-foreground data-[range-start=true]:!bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:!bg-primary data-[selected-single=true]:text-primary-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 !rounded-md border-0 !bg-transparent leading-none font-normal transition-colors duration-150 group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:rounded-md group-data-[focused=true]/day:ring-[2px] hover:!bg-transparent data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[selected-single=true]:rounded-md [&>span]:text-xs [&>span]:font-medium [&>span]:opacity-75",
|
|
621
|
-
defaultClassNames.day,
|
|
622
|
-
className
|
|
623
|
-
),
|
|
624
|
-
...props
|
|
625
|
-
}
|
|
626
|
-
);
|
|
627
|
-
}
|
|
628
481
|
function useControllableState({
|
|
629
482
|
prop,
|
|
630
483
|
defaultProp,
|
|
@@ -1110,6 +963,22 @@ function Input({ className, type, ...props }) {
|
|
|
1110
963
|
}
|
|
1111
964
|
);
|
|
1112
965
|
}
|
|
966
|
+
function Label({ className, ...props }) {
|
|
967
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
968
|
+
radixUi.Label.Root,
|
|
969
|
+
{
|
|
970
|
+
"data-slot": "label",
|
|
971
|
+
className: cn(
|
|
972
|
+
"text-foreground text-sm leading-6 font-medium transition-colors select-none",
|
|
973
|
+
"group-has-disabled/field:cursor-not-allowed group-has-disabled/field:opacity-50",
|
|
974
|
+
"peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
975
|
+
"aria-invalid:text-destructive dark:aria-invalid:text-destructive/90",
|
|
976
|
+
className
|
|
977
|
+
),
|
|
978
|
+
...props
|
|
979
|
+
}
|
|
980
|
+
);
|
|
981
|
+
}
|
|
1113
982
|
|
|
1114
983
|
// src/utils/urlSecurity.ts
|
|
1115
984
|
var SAFE_HREF_PROTOCOLS = /* @__PURE__ */ new Set(["https:", "http:", "mailto:", "tel:"]);
|
|
@@ -1191,15 +1060,412 @@ function Link({
|
|
|
1191
1060
|
truncate ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap", children }) : children,
|
|
1192
1061
|
isExternal && !disabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1193
1062
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1194
|
-
lucideReact.ExternalLinkIcon,
|
|
1063
|
+
lucideReact.ExternalLinkIcon,
|
|
1064
|
+
{
|
|
1065
|
+
"aria-hidden": "true",
|
|
1066
|
+
size: externalIconSize,
|
|
1067
|
+
className: "shrink-0"
|
|
1068
|
+
}
|
|
1069
|
+
),
|
|
1070
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "(opens in new tab)" })
|
|
1071
|
+
] })
|
|
1072
|
+
]
|
|
1073
|
+
}
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
function validatePhone(value) {
|
|
1077
|
+
if (!value) {
|
|
1078
|
+
return { isValid: false };
|
|
1079
|
+
}
|
|
1080
|
+
if (libphonenumberJs.isValidPhoneNumber(value)) {
|
|
1081
|
+
return { isValid: true };
|
|
1082
|
+
}
|
|
1083
|
+
return { isValid: false, problem: libphonenumberJs.validatePhoneNumberLength(value) ?? "INVALID" };
|
|
1084
|
+
}
|
|
1085
|
+
function Popover({ ...props }) {
|
|
1086
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Root, { "data-slot": "popover", ...props });
|
|
1087
|
+
}
|
|
1088
|
+
function PopoverTrigger({ ...props }) {
|
|
1089
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
1090
|
+
}
|
|
1091
|
+
function PopoverContent({
|
|
1092
|
+
className,
|
|
1093
|
+
align = "center",
|
|
1094
|
+
sideOffset = 4,
|
|
1095
|
+
container,
|
|
1096
|
+
...props
|
|
1097
|
+
}) {
|
|
1098
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { container, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1099
|
+
radixUi.Popover.Content,
|
|
1100
|
+
{
|
|
1101
|
+
"data-slot": "popover-content",
|
|
1102
|
+
align,
|
|
1103
|
+
sideOffset,
|
|
1104
|
+
className: cn(
|
|
1105
|
+
"bg-popover text-popover-foreground ring-foreground/5 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 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-1 rounded-3xl p-4 text-sm shadow-lg ring-1 outline-hidden duration-100",
|
|
1106
|
+
className
|
|
1107
|
+
),
|
|
1108
|
+
...props
|
|
1109
|
+
}
|
|
1110
|
+
) });
|
|
1111
|
+
}
|
|
1112
|
+
function PopoverAnchor({ ...props }) {
|
|
1113
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
1114
|
+
}
|
|
1115
|
+
function PopoverHeader({ className, ...props }) {
|
|
1116
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1117
|
+
"div",
|
|
1118
|
+
{
|
|
1119
|
+
"data-slot": "popover-header",
|
|
1120
|
+
className: cn("flex flex-col gap-1 text-sm", className),
|
|
1121
|
+
...props
|
|
1122
|
+
}
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1125
|
+
function PopoverTitle({ className, ...props }) {
|
|
1126
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1127
|
+
"div",
|
|
1128
|
+
{
|
|
1129
|
+
"data-slot": "popover-title",
|
|
1130
|
+
className: cn("text-base font-medium", className),
|
|
1131
|
+
...props
|
|
1132
|
+
}
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
function PopoverDescription({ className, ...props }) {
|
|
1136
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1137
|
+
"p",
|
|
1138
|
+
{
|
|
1139
|
+
"data-slot": "popover-description",
|
|
1140
|
+
className: cn("text-muted-foreground", className),
|
|
1141
|
+
...props
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
function stripLeadingDialCode(raw, dialCode) {
|
|
1146
|
+
if (!raw.startsWith("+")) {
|
|
1147
|
+
return raw.replace(/\D/g, "");
|
|
1148
|
+
}
|
|
1149
|
+
const parsed = libphonenumberJs.parsePhoneNumberFromString(raw);
|
|
1150
|
+
if (parsed) {
|
|
1151
|
+
return parsed.nationalNumber;
|
|
1152
|
+
}
|
|
1153
|
+
const digits = raw.replace(/\D/g, "");
|
|
1154
|
+
const code = dialCode.replace(/\D/g, "");
|
|
1155
|
+
return code && digits.startsWith(code) ? digits.length > code.length ? digits.slice(code.length) : "" : digits;
|
|
1156
|
+
}
|
|
1157
|
+
var flagByCode = countryFlags__namespace;
|
|
1158
|
+
function CountryFlag({
|
|
1159
|
+
code,
|
|
1160
|
+
flagUrl,
|
|
1161
|
+
className
|
|
1162
|
+
}) {
|
|
1163
|
+
const isoCode = (code || "").toUpperCase();
|
|
1164
|
+
const FlagComponent = flagByCode[isoCode];
|
|
1165
|
+
const flag = flagUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: flagUrl, alt: "", "aria-hidden": "true", className: "size-full object-cover" }) : FlagComponent ? /* @__PURE__ */ jsxRuntime.jsx(FlagComponent, { "aria-hidden": "true", className: "size-full" }) : null;
|
|
1166
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1167
|
+
"span",
|
|
1168
|
+
{
|
|
1169
|
+
"data-slot": "phone-field-country-flag",
|
|
1170
|
+
"data-country": isoCode || void 0,
|
|
1171
|
+
"data-fallback": flag ? void 0 : "true",
|
|
1172
|
+
"aria-hidden": "true",
|
|
1173
|
+
className: cn(
|
|
1174
|
+
"size-4 shrink-0 overflow-hidden rounded-[2px]",
|
|
1175
|
+
!flag && "bg-muted rounded-full",
|
|
1176
|
+
className
|
|
1177
|
+
),
|
|
1178
|
+
children: flag
|
|
1179
|
+
}
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
function PhoneField({
|
|
1183
|
+
countries,
|
|
1184
|
+
value,
|
|
1185
|
+
onValueChange,
|
|
1186
|
+
onValidityChange,
|
|
1187
|
+
defaultCountry,
|
|
1188
|
+
placeholder = "Phone number",
|
|
1189
|
+
disabled = false,
|
|
1190
|
+
className,
|
|
1191
|
+
container,
|
|
1192
|
+
name,
|
|
1193
|
+
...inputProps
|
|
1194
|
+
}) {
|
|
1195
|
+
const [open, setOpen] = react.useState(false);
|
|
1196
|
+
const [pickedCode, setPickedCode] = react.useState(
|
|
1197
|
+
(defaultCountry ?? countries[0]?.code)?.toUpperCase()
|
|
1198
|
+
);
|
|
1199
|
+
const [internalValue, setInternalValue] = react.useState("");
|
|
1200
|
+
const listRef = react.useRef(null);
|
|
1201
|
+
const inputRef = react.useRef(null);
|
|
1202
|
+
const caretRef = react.useRef(null);
|
|
1203
|
+
const lastValidityRef = react.useRef(null);
|
|
1204
|
+
const listId = `${react.useId()}-countries-list`;
|
|
1205
|
+
const isControlled = value !== void 0;
|
|
1206
|
+
const currentValue = isControlled ? value : internalValue;
|
|
1207
|
+
const parsed = currentValue ? libphonenumberJs.parsePhoneNumberFromString(currentValue) : void 0;
|
|
1208
|
+
const parsedCountry = parsed?.country;
|
|
1209
|
+
const parsedCallingCode = parsed?.countryCallingCode;
|
|
1210
|
+
const countryInList = parsedCountry !== void 0 && countries.some((country) => country.code.toUpperCase() === parsedCountry);
|
|
1211
|
+
const callingCodeInList = parsedCallingCode !== void 0 && countries.some(
|
|
1212
|
+
(country) => country.dialCode.replace(/\D/g, "") === parsedCallingCode
|
|
1213
|
+
);
|
|
1214
|
+
const pickedCountry = pickedCode ? countries.find((country) => country.code.toUpperCase() === pickedCode.toUpperCase()) : void 0;
|
|
1215
|
+
const pickMatchesValue = pickedCountry !== void 0 && pickedCountry.dialCode.replace(/\D/g, "") === parsedCallingCode;
|
|
1216
|
+
const representedCode = countryInList ? parsedCountry : pickMatchesValue ? pickedCountry.code : callingCodeInList ? countries.find(
|
|
1217
|
+
(country) => country.dialCode.replace(/\D/g, "") === parsedCallingCode
|
|
1218
|
+
)?.code : void 0;
|
|
1219
|
+
const selectedCode = representedCode ?? pickedCode ?? defaultCountry ?? countries[0]?.code;
|
|
1220
|
+
const selectedCountry = countries.find(
|
|
1221
|
+
(country) => country.code.toUpperCase() === selectedCode?.toUpperCase()
|
|
1222
|
+
) ?? countries[0];
|
|
1223
|
+
const dialCode = selectedCountry ? selectedCountry.dialCode.replace(/\D/g, "") : "";
|
|
1224
|
+
const emitDialCode = parsedCallingCode ?? dialCode;
|
|
1225
|
+
const nationalDigits = parsed ? parsed.nationalNumber : currentValue ? stripLeadingDialCode(currentValue, dialCode) : "";
|
|
1226
|
+
const canFormat = selectedCountry !== void 0 && (!parsed || countryInList || callingCodeInList);
|
|
1227
|
+
const inputValue = selectedCountry && canFormat && nationalDigits ? new libphonenumberJs.AsYouType((selectedCountry.code || "").toUpperCase()).input(
|
|
1228
|
+
nationalDigits
|
|
1229
|
+
) : nationalDigits;
|
|
1230
|
+
const isInvalid = inputProps["aria-invalid"] === true || inputProps["aria-invalid"] === "true";
|
|
1231
|
+
const { isValid, problem } = validatePhone(currentValue);
|
|
1232
|
+
react.useEffect(() => {
|
|
1233
|
+
const last = lastValidityRef.current;
|
|
1234
|
+
if (last && last.isValid === isValid && last.problem === problem) {
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
lastValidityRef.current = { isValid, problem };
|
|
1238
|
+
onValidityChange?.({ isValid, problem });
|
|
1239
|
+
}, [isValid, problem, onValidityChange]);
|
|
1240
|
+
react.useLayoutEffect(() => {
|
|
1241
|
+
const input = inputRef.current;
|
|
1242
|
+
const caret = caretRef.current;
|
|
1243
|
+
if (!input || !caret || document.activeElement !== input) {
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
const digitsBefore = caret.raw.slice(0, caret.start).replace(/\D/g, "").length;
|
|
1247
|
+
let position = 0;
|
|
1248
|
+
if (digitsBefore > 0) {
|
|
1249
|
+
let digitsSeen = 0;
|
|
1250
|
+
for (let i = 0; i < inputValue.length; i++) {
|
|
1251
|
+
if (/\d/.test(inputValue[i])) {
|
|
1252
|
+
digitsSeen += 1;
|
|
1253
|
+
}
|
|
1254
|
+
position = i + 1;
|
|
1255
|
+
if (digitsSeen >= digitsBefore) {
|
|
1256
|
+
break;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
input.setSelectionRange(position, position + (caret.end - caret.start));
|
|
1261
|
+
caretRef.current = null;
|
|
1262
|
+
}, [inputValue]);
|
|
1263
|
+
const handleSearchChange = () => {
|
|
1264
|
+
requestAnimationFrame(() => listRef.current?.scrollTo({ top: 0 }));
|
|
1265
|
+
};
|
|
1266
|
+
function handleCountrySelect(code) {
|
|
1267
|
+
setPickedCode(code);
|
|
1268
|
+
setOpen(false);
|
|
1269
|
+
const nextCountry = countries.find(
|
|
1270
|
+
(country) => country.code.toUpperCase() === code.toUpperCase()
|
|
1271
|
+
);
|
|
1272
|
+
if (nextCountry && nationalDigits) {
|
|
1273
|
+
const next = `+${nextCountry.dialCode.replace(/\D/g, "")}${nationalDigits}`;
|
|
1274
|
+
onValueChange?.(next);
|
|
1275
|
+
if (!isControlled) {
|
|
1276
|
+
setInternalValue(next);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
function deriveFromE164(e164) {
|
|
1281
|
+
const parsed2 = libphonenumberJs.parsePhoneNumberFromString(e164);
|
|
1282
|
+
if (!parsed2?.nationalNumber) {
|
|
1283
|
+
return void 0;
|
|
1284
|
+
}
|
|
1285
|
+
const countryMatch = parsed2.country ? countries.find((country) => country.code.toUpperCase() === parsed2.country) : void 0;
|
|
1286
|
+
const nextPickedCode = countryMatch ? countryMatch.code : parsed2.countryCallingCode ? countries.find(
|
|
1287
|
+
(country) => country.dialCode.replace(/\D/g, "") === parsed2.countryCallingCode
|
|
1288
|
+
)?.code : void 0;
|
|
1289
|
+
return {
|
|
1290
|
+
nationalNumber: parsed2.nationalNumber,
|
|
1291
|
+
emitCode: parsed2.countryCallingCode,
|
|
1292
|
+
nextPickedCode
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
function handleInputChange(raw, nativeEvent) {
|
|
1296
|
+
const input = inputRef.current;
|
|
1297
|
+
if (input) {
|
|
1298
|
+
caretRef.current = {
|
|
1299
|
+
raw,
|
|
1300
|
+
start: input.selectionStart ?? raw.length,
|
|
1301
|
+
end: input.selectionEnd ?? raw.length
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
if (!selectedCountry) return;
|
|
1305
|
+
let national = stripLeadingDialCode(raw, dialCode);
|
|
1306
|
+
let emitCode = emitDialCode;
|
|
1307
|
+
let nextPickedCode;
|
|
1308
|
+
const plusIndex = raw.indexOf("+");
|
|
1309
|
+
if (plusIndex === 0) {
|
|
1310
|
+
const derived = deriveFromE164(raw);
|
|
1311
|
+
if (derived) {
|
|
1312
|
+
emitCode = derived.emitCode || emitDialCode;
|
|
1313
|
+
nextPickedCode = derived.nextPickedCode;
|
|
1314
|
+
} else if (nativeEvent?.inputType === "insertFromPaste") {
|
|
1315
|
+
national = "";
|
|
1316
|
+
}
|
|
1317
|
+
} else if (plusIndex > 0) {
|
|
1318
|
+
const pasted = nativeEvent?.inputType === "insertFromPaste" && nativeEvent.data?.startsWith("+") ? nativeEvent.data : void 0;
|
|
1319
|
+
if (pasted) {
|
|
1320
|
+
const derived = deriveFromE164(pasted);
|
|
1321
|
+
const prefixDigits = raw.slice(0, plusIndex).replace(/\D/g, "");
|
|
1322
|
+
const suffixDigits = raw.slice(plusIndex + pasted.length).replace(/\D/g, "");
|
|
1323
|
+
if (derived) {
|
|
1324
|
+
national = prefixDigits + derived.nationalNumber + suffixDigits;
|
|
1325
|
+
emitCode = derived.emitCode || emitDialCode;
|
|
1326
|
+
nextPickedCode = derived.nextPickedCode;
|
|
1327
|
+
} else {
|
|
1328
|
+
national = prefixDigits + suffixDigits;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
const next = national ? `+${emitCode}${national}` : "";
|
|
1333
|
+
const grew = national.replace(/\D/g, "").length > nationalDigits.length;
|
|
1334
|
+
const isPaste = nativeEvent?.inputType === "insertFromPaste";
|
|
1335
|
+
if (grew && !isPaste && libphonenumberJs.validatePhoneNumberLength(next) === "TOO_LONG") {
|
|
1336
|
+
if (input) {
|
|
1337
|
+
const caret = Math.max(0, (input.selectionStart ?? inputValue.length) - 1);
|
|
1338
|
+
input.value = inputValue;
|
|
1339
|
+
input.setSelectionRange(caret, caret);
|
|
1340
|
+
}
|
|
1341
|
+
caretRef.current = null;
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
if (nextPickedCode) {
|
|
1345
|
+
setPickedCode(nextPickedCode);
|
|
1346
|
+
}
|
|
1347
|
+
onValueChange?.(next);
|
|
1348
|
+
if (!isControlled) {
|
|
1349
|
+
setInternalValue(next);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1353
|
+
"div",
|
|
1354
|
+
{
|
|
1355
|
+
"data-slot": "phone-field",
|
|
1356
|
+
"data-invalid": isInvalid || void 0,
|
|
1357
|
+
className: cn(
|
|
1358
|
+
"border-input flex h-9 w-full min-w-0 items-center overflow-hidden rounded-md border bg-transparent shadow-xs transition-[color,box-shadow]",
|
|
1359
|
+
"focus-within:border-ring focus-within:ring-ring/30 focus-within:ring-3",
|
|
1360
|
+
"data-[invalid=true]:border-destructive data-[invalid=true]:ring-destructive/20 data-[invalid=true]:ring-3",
|
|
1361
|
+
"dark:data-[invalid=true]:border-destructive/50 dark:data-[invalid=true]:ring-destructive/40",
|
|
1362
|
+
className
|
|
1363
|
+
),
|
|
1364
|
+
children: [
|
|
1365
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
1366
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1367
|
+
"button",
|
|
1368
|
+
{
|
|
1369
|
+
type: "button",
|
|
1370
|
+
"data-slot": "phone-field-country-select",
|
|
1371
|
+
disabled,
|
|
1372
|
+
"aria-expanded": open,
|
|
1373
|
+
"aria-haspopup": "listbox",
|
|
1374
|
+
"aria-controls": open ? listId : void 0,
|
|
1375
|
+
"aria-label": selectedCountry ? `${selectedCountry.name} ${selectedCountry.dialCode}` : void 0,
|
|
1376
|
+
className: cn(
|
|
1377
|
+
"flex h-full shrink-0 cursor-pointer items-center gap-1.5 border-r border-input px-2.5 text-sm font-medium outline-none select-none",
|
|
1378
|
+
"hover:bg-muted",
|
|
1379
|
+
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
1380
|
+
),
|
|
1381
|
+
children: selectedCountry && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1382
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1383
|
+
CountryFlag,
|
|
1384
|
+
{
|
|
1385
|
+
code: selectedCountry.code,
|
|
1386
|
+
flagUrl: selectedCountry.flagUrl
|
|
1387
|
+
}
|
|
1388
|
+
),
|
|
1389
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: selectedCountry.dialCode }),
|
|
1390
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDownIcon, { size: 14, className: "text-muted-foreground shrink-0" })
|
|
1391
|
+
] })
|
|
1392
|
+
}
|
|
1393
|
+
) }),
|
|
1394
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1395
|
+
PopoverContent,
|
|
1195
1396
|
{
|
|
1196
|
-
"
|
|
1197
|
-
|
|
1198
|
-
|
|
1397
|
+
className: "w-72 rounded-xl p-0",
|
|
1398
|
+
align: "start",
|
|
1399
|
+
container,
|
|
1400
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command, { className: "rounded-xl", label: "Search countries", children: [
|
|
1401
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-border flex items-center gap-2 border-b px-3", children: [
|
|
1402
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { size: 14, className: "text-muted-foreground shrink-0" }),
|
|
1403
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1404
|
+
cmdk.Command.Input,
|
|
1405
|
+
{
|
|
1406
|
+
placeholder: "Search country...",
|
|
1407
|
+
onValueChange: handleSearchChange,
|
|
1408
|
+
className: "placeholder:text-muted-foreground flex h-9 w-full bg-transparent py-2 text-sm outline-none"
|
|
1409
|
+
}
|
|
1410
|
+
)
|
|
1411
|
+
] }),
|
|
1412
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: listId, children: /* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command.List, { ref: listRef, className: "max-h-56 overflow-y-auto p-1", children: [
|
|
1413
|
+
/* @__PURE__ */ jsxRuntime.jsx(cmdk.Command.Empty, { className: "text-muted-foreground py-4 text-center text-sm", children: "No country found." }),
|
|
1414
|
+
countries.map((country) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1415
|
+
cmdk.Command.Item,
|
|
1416
|
+
{
|
|
1417
|
+
value: country.code,
|
|
1418
|
+
keywords: [country.name, country.dialCode],
|
|
1419
|
+
"data-slot": "phone-field-country-item",
|
|
1420
|
+
onSelect: () => handleCountrySelect(country.code),
|
|
1421
|
+
className: cn(
|
|
1422
|
+
"flex cursor-pointer items-center justify-between gap-2 rounded-md px-2 py-1.5 text-sm outline-none select-none",
|
|
1423
|
+
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground",
|
|
1424
|
+
"hover:bg-accent hover:text-accent-foreground"
|
|
1425
|
+
),
|
|
1426
|
+
children: [
|
|
1427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1428
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountryFlag, { code: country.code, flagUrl: country.flagUrl }),
|
|
1429
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: country.name })
|
|
1430
|
+
] }),
|
|
1431
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
|
|
1432
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground tabular-nums", children: country.dialCode }),
|
|
1433
|
+
selectedCode?.toUpperCase() === country.code.toUpperCase() && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1434
|
+
lucideReact.CheckIcon,
|
|
1435
|
+
{
|
|
1436
|
+
size: 14,
|
|
1437
|
+
className: "text-[var(--color-main-blue-primary)] shrink-0"
|
|
1438
|
+
}
|
|
1439
|
+
)
|
|
1440
|
+
] })
|
|
1441
|
+
]
|
|
1442
|
+
},
|
|
1443
|
+
country.code
|
|
1444
|
+
))
|
|
1445
|
+
] }) })
|
|
1446
|
+
] })
|
|
1199
1447
|
}
|
|
1200
|
-
)
|
|
1201
|
-
|
|
1202
|
-
|
|
1448
|
+
)
|
|
1449
|
+
] }),
|
|
1450
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1451
|
+
Input,
|
|
1452
|
+
{
|
|
1453
|
+
ref: inputRef,
|
|
1454
|
+
...inputProps,
|
|
1455
|
+
"data-slot": "phone-field-input",
|
|
1456
|
+
type: "tel",
|
|
1457
|
+
value: inputValue,
|
|
1458
|
+
onChange: (event) => handleInputChange(event.target.value, event.nativeEvent),
|
|
1459
|
+
placeholder,
|
|
1460
|
+
disabled,
|
|
1461
|
+
autoComplete: inputProps.autoComplete ?? "tel",
|
|
1462
|
+
className: cn(
|
|
1463
|
+
"h-full flex-1 rounded-none border-0 bg-transparent shadow-none",
|
|
1464
|
+
"px-3 focus-visible:border-transparent focus-visible:ring-0"
|
|
1465
|
+
)
|
|
1466
|
+
}
|
|
1467
|
+
),
|
|
1468
|
+
name !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: currentValue, "data-slot": "phone-field-hidden-input" })
|
|
1203
1469
|
]
|
|
1204
1470
|
}
|
|
1205
1471
|
);
|
|
@@ -1434,31 +1700,37 @@ function SelectContent({
|
|
|
1434
1700
|
className,
|
|
1435
1701
|
children,
|
|
1436
1702
|
position = "popper",
|
|
1703
|
+
maxHeight,
|
|
1704
|
+
style,
|
|
1437
1705
|
...props
|
|
1438
1706
|
}) {
|
|
1707
|
+
const resolvedMaxHeight = typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight;
|
|
1439
1708
|
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Select.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1440
1709
|
radixUi.Select.Content,
|
|
1441
1710
|
{
|
|
1442
1711
|
"data-slot": "select-content",
|
|
1443
1712
|
className: cn(
|
|
1444
|
-
"border-border bg-popover text-popover-foreground relative z-50 max-h-
|
|
1713
|
+
"border-border bg-popover text-popover-foreground relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-hidden rounded-md border shadow-md",
|
|
1445
1714
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
1446
1715
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
1447
1716
|
"data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1",
|
|
1448
|
-
position === "popper" && "w-
|
|
1717
|
+
position === "popper" && "w-(--radix-select-trigger-width)",
|
|
1449
1718
|
className
|
|
1450
1719
|
),
|
|
1451
1720
|
position,
|
|
1721
|
+
style: {
|
|
1722
|
+
...resolvedMaxHeight ? {
|
|
1723
|
+
maxHeight: `min(${resolvedMaxHeight}, var(--radix-select-content-available-height))`
|
|
1724
|
+
} : null,
|
|
1725
|
+
...style
|
|
1726
|
+
},
|
|
1452
1727
|
...props,
|
|
1453
1728
|
children: [
|
|
1454
1729
|
/* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
|
|
1455
1730
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1456
1731
|
radixUi.Select.Viewport,
|
|
1457
1732
|
{
|
|
1458
|
-
className: cn(
|
|
1459
|
-
"p-1",
|
|
1460
|
-
position === "popper" && "h-[--radix-select-trigger-height]"
|
|
1461
|
-
),
|
|
1733
|
+
className: cn("scroll-my-1 p-1", position === "popper" && "w-full"),
|
|
1462
1734
|
children
|
|
1463
1735
|
}
|
|
1464
1736
|
),
|
|
@@ -1585,7 +1857,7 @@ var progressVariants = classVarianceAuthority.cva("relative flex w-full items-ce
|
|
|
1585
1857
|
size: "md"
|
|
1586
1858
|
}
|
|
1587
1859
|
});
|
|
1588
|
-
var progressIndicatorVariants = classVarianceAuthority.cva("size-full flex-1 transition-all", {
|
|
1860
|
+
var progressIndicatorVariants = classVarianceAuthority.cva("size-full flex-1 transition-all rounded-[5px]", {
|
|
1589
1861
|
variants: {
|
|
1590
1862
|
variant: {
|
|
1591
1863
|
default: "bg-[var(--color-main-blue-primary)]",
|
|
@@ -1750,7 +2022,8 @@ var ease = {
|
|
|
1750
2022
|
smooth: [0.4, 0, 0.2, 1],
|
|
1751
2023
|
enter: [0, 0, 0.2, 1],
|
|
1752
2024
|
exit: [0.4, 0, 1, 1],
|
|
1753
|
-
linear: [0, 0, 1, 1]
|
|
2025
|
+
linear: [0, 0, 1, 1],
|
|
2026
|
+
drawer: [0.22, 1, 0.36, 1]
|
|
1754
2027
|
};
|
|
1755
2028
|
var spring = {
|
|
1756
2029
|
gentle: { type: "spring", stiffness: 260, damping: 28 },
|
|
@@ -1794,6 +2067,15 @@ var transition = {
|
|
|
1794
2067
|
card: {
|
|
1795
2068
|
duration: duration.fast,
|
|
1796
2069
|
ease: ease.smooth
|
|
2070
|
+
},
|
|
2071
|
+
// Drawer / slide panel — smooth enter, fast exit
|
|
2072
|
+
drawer: {
|
|
2073
|
+
duration: 0.3,
|
|
2074
|
+
ease: ease.drawer
|
|
2075
|
+
},
|
|
2076
|
+
drawerExit: {
|
|
2077
|
+
duration: 0.2,
|
|
2078
|
+
ease: ease.exit
|
|
1797
2079
|
}
|
|
1798
2080
|
};
|
|
1799
2081
|
var fadeIn = {
|
|
@@ -2258,65 +2540,6 @@ function TooltipContent({
|
|
|
2258
2540
|
}
|
|
2259
2541
|
) });
|
|
2260
2542
|
}
|
|
2261
|
-
function Popover({ ...props }) {
|
|
2262
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Root, { "data-slot": "popover", ...props });
|
|
2263
|
-
}
|
|
2264
|
-
function PopoverTrigger({ ...props }) {
|
|
2265
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
2266
|
-
}
|
|
2267
|
-
function PopoverContent({
|
|
2268
|
-
className,
|
|
2269
|
-
align = "center",
|
|
2270
|
-
sideOffset = 4,
|
|
2271
|
-
...props
|
|
2272
|
-
}) {
|
|
2273
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2274
|
-
radixUi.Popover.Content,
|
|
2275
|
-
{
|
|
2276
|
-
"data-slot": "popover-content",
|
|
2277
|
-
align,
|
|
2278
|
-
sideOffset,
|
|
2279
|
-
className: cn(
|
|
2280
|
-
"bg-popover text-popover-foreground ring-foreground/5 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 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-1 rounded-3xl p-4 text-sm shadow-lg ring-1 outline-hidden duration-100",
|
|
2281
|
-
className
|
|
2282
|
-
),
|
|
2283
|
-
...props
|
|
2284
|
-
}
|
|
2285
|
-
) });
|
|
2286
|
-
}
|
|
2287
|
-
function PopoverAnchor({ ...props }) {
|
|
2288
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
2289
|
-
}
|
|
2290
|
-
function PopoverHeader({ className, ...props }) {
|
|
2291
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2292
|
-
"div",
|
|
2293
|
-
{
|
|
2294
|
-
"data-slot": "popover-header",
|
|
2295
|
-
className: cn("flex flex-col gap-1 text-sm", className),
|
|
2296
|
-
...props
|
|
2297
|
-
}
|
|
2298
|
-
);
|
|
2299
|
-
}
|
|
2300
|
-
function PopoverTitle({ className, ...props }) {
|
|
2301
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2302
|
-
"div",
|
|
2303
|
-
{
|
|
2304
|
-
"data-slot": "popover-title",
|
|
2305
|
-
className: cn("text-base font-medium", className),
|
|
2306
|
-
...props
|
|
2307
|
-
}
|
|
2308
|
-
);
|
|
2309
|
-
}
|
|
2310
|
-
function PopoverDescription({ className, ...props }) {
|
|
2311
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2312
|
-
"p",
|
|
2313
|
-
{
|
|
2314
|
-
"data-slot": "popover-description",
|
|
2315
|
-
className: cn("text-muted-foreground", className),
|
|
2316
|
-
...props
|
|
2317
|
-
}
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
2543
|
var TEXT_SIZES = [12, 14, 16, 18, 20, 24, 28, 32, 40, 48];
|
|
2321
2544
|
var TEXT_WEIGHTS = [100, 200, 300, 400, 500, 700, 800, 900];
|
|
2322
2545
|
function Text({
|
|
@@ -2371,7 +2594,7 @@ function DialogTrigger({ ...props }) {
|
|
|
2371
2594
|
}
|
|
2372
2595
|
function DialogPortal({ children, ...props }) {
|
|
2373
2596
|
const isOpen = react.useContext(DialogContext);
|
|
2374
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Portal, { "data-slot": "dialog-portal", forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "
|
|
2597
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Portal, { "data-slot": "dialog-portal", forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "sync", children: isOpen && children }) });
|
|
2375
2598
|
}
|
|
2376
2599
|
function DialogClose({ ...props }) {
|
|
2377
2600
|
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "dialog-close", ...props });
|
|
@@ -2398,7 +2621,7 @@ function DialogContent({
|
|
|
2398
2621
|
...props
|
|
2399
2622
|
}) {
|
|
2400
2623
|
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
2401
|
-
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
2624
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}, "dialog-overlay"),
|
|
2402
2625
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2403
2626
|
radixUi.Dialog.Content,
|
|
2404
2627
|
{
|
|
@@ -2435,7 +2658,8 @@ function DialogContent({
|
|
|
2435
2658
|
]
|
|
2436
2659
|
}
|
|
2437
2660
|
)
|
|
2438
|
-
}
|
|
2661
|
+
},
|
|
2662
|
+
"dialog-content"
|
|
2439
2663
|
)
|
|
2440
2664
|
] });
|
|
2441
2665
|
}
|
|
@@ -2538,7 +2762,7 @@ function AlertDialogPortal({
|
|
|
2538
2762
|
...props
|
|
2539
2763
|
}) {
|
|
2540
2764
|
const isOpen = react.useContext(AlertDialogContext);
|
|
2541
|
-
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.AlertDialog.Portal, { "data-slot": "alert-dialog-portal", forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "
|
|
2765
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.AlertDialog.Portal, { "data-slot": "alert-dialog-portal", forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "sync", children: isOpen && children }) });
|
|
2542
2766
|
}
|
|
2543
2767
|
function AlertDialogOverlay({
|
|
2544
2768
|
className,
|
|
@@ -2580,7 +2804,8 @@ function AlertDialogContent({
|
|
|
2580
2804
|
AlertDialogOverlay,
|
|
2581
2805
|
{
|
|
2582
2806
|
className: cn(variant === "dark-glass" && "bg-primary/60 backdrop-blur-md")
|
|
2583
|
-
}
|
|
2807
|
+
},
|
|
2808
|
+
"alert-dialog-overlay"
|
|
2584
2809
|
),
|
|
2585
2810
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2586
2811
|
radixUi.AlertDialog.Content,
|
|
@@ -2614,7 +2839,8 @@ function AlertDialogContent({
|
|
|
2614
2839
|
]
|
|
2615
2840
|
}
|
|
2616
2841
|
)
|
|
2617
|
-
}
|
|
2842
|
+
},
|
|
2843
|
+
"alert-dialog-content"
|
|
2618
2844
|
)
|
|
2619
2845
|
] });
|
|
2620
2846
|
}
|
|
@@ -2775,6 +3001,17 @@ function AccordionContent({
|
|
|
2775
3001
|
}
|
|
2776
3002
|
);
|
|
2777
3003
|
}
|
|
3004
|
+
function createMatchFilter(mode) {
|
|
3005
|
+
return (value, search, keywords = []) => {
|
|
3006
|
+
const query = search.toLowerCase().trim();
|
|
3007
|
+
if (!query) return 1;
|
|
3008
|
+
const haystacks = [value, ...keywords].map((s) => s.toLowerCase());
|
|
3009
|
+
const matched = mode === "substring" ? haystacks.some((h) => h.includes(query)) : haystacks.some(
|
|
3010
|
+
(h) => h.startsWith(query) || h.split(/\s+/).some((word) => word.startsWith(query))
|
|
3011
|
+
);
|
|
3012
|
+
return matched ? 1 : 0;
|
|
3013
|
+
};
|
|
3014
|
+
}
|
|
2778
3015
|
function Combobox({
|
|
2779
3016
|
options,
|
|
2780
3017
|
value,
|
|
@@ -2783,10 +3020,17 @@ function Combobox({
|
|
|
2783
3020
|
searchPlaceholder = "Search...",
|
|
2784
3021
|
emptyMessage = "No results found.",
|
|
2785
3022
|
disabled = false,
|
|
2786
|
-
className
|
|
3023
|
+
className,
|
|
3024
|
+
container,
|
|
3025
|
+
matchMode = "fuzzy"
|
|
2787
3026
|
}) {
|
|
2788
3027
|
const [open, setOpen] = react.useState(false);
|
|
3028
|
+
const listRef = react.useRef(null);
|
|
2789
3029
|
const selected = options.find((opt) => opt.value === value);
|
|
3030
|
+
const filter = matchMode === "fuzzy" ? void 0 : createMatchFilter(matchMode);
|
|
3031
|
+
const handleSearchChange = () => {
|
|
3032
|
+
requestAnimationFrame(() => listRef.current?.scrollTo({ top: 0 }));
|
|
3033
|
+
};
|
|
2790
3034
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
2791
3035
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2792
3036
|
Button,
|
|
@@ -2806,18 +3050,19 @@ function Combobox({
|
|
|
2806
3050
|
]
|
|
2807
3051
|
}
|
|
2808
3052
|
) }),
|
|
2809
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 rounded-lg p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command, { className: "rounded-lg", children: [
|
|
3053
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 rounded-lg p-0", align: "start", container, children: /* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command, { className: "rounded-lg", filter, children: [
|
|
2810
3054
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-border flex items-center gap-2 border-b px-3", children: [
|
|
2811
3055
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { size: 14, className: "text-muted-foreground shrink-0" }),
|
|
2812
3056
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2813
3057
|
cmdk.Command.Input,
|
|
2814
3058
|
{
|
|
2815
3059
|
placeholder: searchPlaceholder,
|
|
3060
|
+
onValueChange: handleSearchChange,
|
|
2816
3061
|
className: "placeholder:text-muted-foreground flex h-9 w-full bg-transparent py-2 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
2817
3062
|
}
|
|
2818
3063
|
)
|
|
2819
3064
|
] }),
|
|
2820
|
-
/* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command.List, { className: "max-h-56 overflow-y-auto p-1", children: [
|
|
3065
|
+
/* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command.List, { ref: listRef, className: "max-h-56 overflow-y-auto p-1", children: [
|
|
2821
3066
|
/* @__PURE__ */ jsxRuntime.jsx(cmdk.Command.Empty, { className: "text-muted-foreground py-4 text-center text-sm", children: emptyMessage }),
|
|
2822
3067
|
options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2823
3068
|
cmdk.Command.Item,
|
|
@@ -4082,92 +4327,325 @@ var ColorPickerFormat = ({ className, ...props }) => {
|
|
|
4082
4327
|
"relative flex w-full items-center gap-1 -space-x-px rounded-md",
|
|
4083
4328
|
className
|
|
4084
4329
|
),
|
|
4085
|
-
...props,
|
|
4086
|
-
children: [
|
|
4087
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4088
|
-
Input2,
|
|
4089
|
-
{
|
|
4090
|
-
className: "bg-muted h-8 w-[5rem] rounded-md px-2 text-xs",
|
|
4091
|
-
readOnly: true,
|
|
4092
|
-
type: "text",
|
|
4093
|
-
value: displayHex
|
|
4094
|
-
}
|
|
4095
|
-
),
|
|
4096
|
-
/* @__PURE__ */ jsxRuntime.jsx(PercentageInput, { value: alpha, onChange: setAlpha })
|
|
4097
|
-
]
|
|
4098
|
-
}
|
|
4099
|
-
);
|
|
4100
|
-
}
|
|
4101
|
-
if (mode === "css") {
|
|
4102
|
-
const rgb = color.rgb().array().map((value) => Math.round(value));
|
|
4103
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full rounded-md", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4104
|
-
Input2,
|
|
4105
|
-
{
|
|
4106
|
-
className: "bg-muted h-8 w-full rounded-md px-2 text-xs shadow-none",
|
|
4107
|
-
readOnly: true,
|
|
4108
|
-
type: "text",
|
|
4109
|
-
value: `rgba(${rgb.join(", ")}, ${alpha}%)`,
|
|
4110
|
-
...props
|
|
4111
|
-
}
|
|
4112
|
-
) });
|
|
4113
|
-
}
|
|
4114
|
-
return null;
|
|
4115
|
-
};
|
|
4116
|
-
var ColorPickerPresets = ({ colors, className, ...props }) => {
|
|
4117
|
-
const { hue, saturation, lightness, alpha, setHue, setSaturation, setLightness, setAlpha } = useColorPicker();
|
|
4118
|
-
const currentHex = Color__default.default.hsl(hue, saturation, lightness, alpha / 100).hex();
|
|
4119
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-1.5", className), ...props, children: colors.map((hex) => {
|
|
4120
|
-
const isActive = Color__default.default(hex).hex().toUpperCase() === currentHex.toUpperCase();
|
|
4121
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4122
|
-
"button",
|
|
4123
|
-
{
|
|
4124
|
-
type: "button",
|
|
4125
|
-
className: cn(
|
|
4126
|
-
"size-5 cursor-pointer rounded-[3px] border transition-all",
|
|
4127
|
-
"hover:scale-110 hover:shadow-md",
|
|
4128
|
-
isActive && "ring-ring ring-offset-background ring-2 ring-offset-1"
|
|
4330
|
+
...props,
|
|
4331
|
+
children: [
|
|
4332
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4333
|
+
Input2,
|
|
4334
|
+
{
|
|
4335
|
+
className: "bg-muted h-8 w-[5rem] rounded-md px-2 text-xs",
|
|
4336
|
+
readOnly: true,
|
|
4337
|
+
type: "text",
|
|
4338
|
+
value: displayHex
|
|
4339
|
+
}
|
|
4340
|
+
),
|
|
4341
|
+
/* @__PURE__ */ jsxRuntime.jsx(PercentageInput, { value: alpha, onChange: setAlpha })
|
|
4342
|
+
]
|
|
4343
|
+
}
|
|
4344
|
+
);
|
|
4345
|
+
}
|
|
4346
|
+
if (mode === "css") {
|
|
4347
|
+
const rgb = color.rgb().array().map((value) => Math.round(value));
|
|
4348
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full rounded-md", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4349
|
+
Input2,
|
|
4350
|
+
{
|
|
4351
|
+
className: "bg-muted h-8 w-full rounded-md px-2 text-xs shadow-none",
|
|
4352
|
+
readOnly: true,
|
|
4353
|
+
type: "text",
|
|
4354
|
+
value: `rgba(${rgb.join(", ")}, ${alpha}%)`,
|
|
4355
|
+
...props
|
|
4356
|
+
}
|
|
4357
|
+
) });
|
|
4358
|
+
}
|
|
4359
|
+
return null;
|
|
4360
|
+
};
|
|
4361
|
+
var ColorPickerPresets = ({ colors, className, ...props }) => {
|
|
4362
|
+
const { hue, saturation, lightness, alpha, setHue, setSaturation, setLightness, setAlpha } = useColorPicker();
|
|
4363
|
+
const currentHex = Color__default.default.hsl(hue, saturation, lightness, alpha / 100).hex();
|
|
4364
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-1.5", className), ...props, children: colors.map((hex) => {
|
|
4365
|
+
const isActive = Color__default.default(hex).hex().toUpperCase() === currentHex.toUpperCase();
|
|
4366
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4367
|
+
"button",
|
|
4368
|
+
{
|
|
4369
|
+
type: "button",
|
|
4370
|
+
className: cn(
|
|
4371
|
+
"size-5 cursor-pointer rounded-[3px] border transition-all",
|
|
4372
|
+
"hover:scale-110 hover:shadow-md",
|
|
4373
|
+
isActive && "ring-ring ring-offset-background ring-2 ring-offset-1"
|
|
4374
|
+
),
|
|
4375
|
+
style: { backgroundColor: hex },
|
|
4376
|
+
onClick: () => {
|
|
4377
|
+
const color = Color__default.default(hex);
|
|
4378
|
+
const [h, s, l] = color.hsl().array();
|
|
4379
|
+
setHue(h);
|
|
4380
|
+
setSaturation(s);
|
|
4381
|
+
setLightness(l);
|
|
4382
|
+
setAlpha(100);
|
|
4383
|
+
},
|
|
4384
|
+
"aria-label": hex,
|
|
4385
|
+
title: hex
|
|
4386
|
+
},
|
|
4387
|
+
hex
|
|
4388
|
+
);
|
|
4389
|
+
}) });
|
|
4390
|
+
};
|
|
4391
|
+
ColorPickerPresets.displayName = "ColorPickerPresets";
|
|
4392
|
+
function Calendar({
|
|
4393
|
+
className,
|
|
4394
|
+
classNames,
|
|
4395
|
+
modifiersClassNames,
|
|
4396
|
+
showOutsideDays = true,
|
|
4397
|
+
captionLayout = "dropdown",
|
|
4398
|
+
buttonVariant = "ghost",
|
|
4399
|
+
locale,
|
|
4400
|
+
formatters,
|
|
4401
|
+
components,
|
|
4402
|
+
fromYear,
|
|
4403
|
+
toYear,
|
|
4404
|
+
...props
|
|
4405
|
+
}) {
|
|
4406
|
+
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
4407
|
+
const resolvedComponents = react.useMemo(
|
|
4408
|
+
() => ({
|
|
4409
|
+
Root: ({ className: className2, rootRef, ...rootProps }) => {
|
|
4410
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4411
|
+
"div",
|
|
4412
|
+
{
|
|
4413
|
+
"data-slot": "calendar",
|
|
4414
|
+
ref: rootRef,
|
|
4415
|
+
className: cn(className2),
|
|
4416
|
+
...rootProps
|
|
4417
|
+
}
|
|
4418
|
+
);
|
|
4419
|
+
},
|
|
4420
|
+
Chevron: ({ className: className2, orientation, ...chevronProps }) => {
|
|
4421
|
+
if (orientation === "left") {
|
|
4422
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: cn("size-4", className2), ...chevronProps });
|
|
4423
|
+
}
|
|
4424
|
+
if (orientation === "right") {
|
|
4425
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: cn("size-4", className2), ...chevronProps });
|
|
4426
|
+
}
|
|
4427
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("size-4", className2), ...chevronProps });
|
|
4428
|
+
},
|
|
4429
|
+
DayButton: (dayButtonProps) => /* @__PURE__ */ jsxRuntime.jsx(CalendarDayButton, { locale, ...dayButtonProps }),
|
|
4430
|
+
WeekNumber: ({ children, ...weekNumberProps }) => {
|
|
4431
|
+
return /* @__PURE__ */ jsxRuntime.jsx("td", { ...weekNumberProps, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
|
|
4432
|
+
},
|
|
4433
|
+
...components
|
|
4434
|
+
}),
|
|
4435
|
+
[locale, components]
|
|
4436
|
+
);
|
|
4437
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4438
|
+
reactDayPicker.DayPicker,
|
|
4439
|
+
{
|
|
4440
|
+
showOutsideDays,
|
|
4441
|
+
className: cn(
|
|
4442
|
+
"group/calendar bg-background p-3 font-sans [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
|
|
4443
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
4444
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
4445
|
+
className
|
|
4446
|
+
),
|
|
4447
|
+
captionLayout,
|
|
4448
|
+
startMonth: new Date(fromYear ?? 1900, 0),
|
|
4449
|
+
endMonth: new Date(toYear ?? 2100, 11),
|
|
4450
|
+
locale,
|
|
4451
|
+
formatters: {
|
|
4452
|
+
formatMonthDropdown: (date) => date.toLocaleString(locale?.code, { month: "short" }),
|
|
4453
|
+
...formatters
|
|
4454
|
+
},
|
|
4455
|
+
classNames: {
|
|
4456
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
4457
|
+
months: cn("relative flex flex-col gap-3 md:flex-row", defaultClassNames.months),
|
|
4458
|
+
month: cn("flex w-full flex-col gap-3", defaultClassNames.month),
|
|
4459
|
+
nav: cn(
|
|
4460
|
+
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-2",
|
|
4461
|
+
defaultClassNames.nav
|
|
4462
|
+
),
|
|
4463
|
+
button_previous: cn(
|
|
4464
|
+
buttonVariants({ variant: buttonVariant }),
|
|
4465
|
+
"size-7 p-0 select-none opacity-50 aria-disabled:opacity-30 transition-opacity duration-150 hover:opacity-100",
|
|
4466
|
+
defaultClassNames.button_previous
|
|
4467
|
+
),
|
|
4468
|
+
button_next: cn(
|
|
4469
|
+
buttonVariants({ variant: buttonVariant }),
|
|
4470
|
+
"size-7 p-0 select-none opacity-50 aria-disabled:opacity-30 transition-opacity duration-150 hover:opacity-100",
|
|
4471
|
+
defaultClassNames.button_next
|
|
4472
|
+
),
|
|
4473
|
+
month_caption: cn(
|
|
4474
|
+
"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size) tracking-tight",
|
|
4475
|
+
defaultClassNames.month_caption
|
|
4476
|
+
),
|
|
4477
|
+
dropdowns: cn(
|
|
4478
|
+
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-semibold",
|
|
4479
|
+
defaultClassNames.dropdowns
|
|
4480
|
+
),
|
|
4481
|
+
dropdown_root: cn(
|
|
4482
|
+
"relative rounded-(--cell-radius)",
|
|
4483
|
+
defaultClassNames.dropdown_root
|
|
4484
|
+
),
|
|
4485
|
+
dropdown: cn("absolute inset-0 bg-popover opacity-0", defaultClassNames.dropdown),
|
|
4486
|
+
caption_label: cn(
|
|
4487
|
+
"font-semibold select-none",
|
|
4488
|
+
captionLayout === "label" ? "text-sm" : "flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
|
|
4489
|
+
defaultClassNames.caption_label
|
|
4490
|
+
),
|
|
4491
|
+
weekdays: cn("flex gap-1", defaultClassNames.weekdays),
|
|
4492
|
+
weekday: cn(
|
|
4493
|
+
"flex-1 rounded-(--cell-radius) text-[0.75rem] font-semibold text-muted-foreground/70 select-none tracking-wide",
|
|
4494
|
+
defaultClassNames.weekday
|
|
4495
|
+
),
|
|
4496
|
+
week: cn("mt-2 flex w-full gap-1", defaultClassNames.week),
|
|
4497
|
+
week_number_header: cn(
|
|
4498
|
+
"w-(--cell-size) select-none",
|
|
4499
|
+
defaultClassNames.week_number_header
|
|
4500
|
+
),
|
|
4501
|
+
week_number: cn(
|
|
4502
|
+
"text-[0.75rem] text-muted-foreground/50 select-none",
|
|
4503
|
+
defaultClassNames.week_number
|
|
4504
|
+
),
|
|
4505
|
+
day: cn(
|
|
4506
|
+
"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
|
|
4507
|
+
props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)" : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
|
|
4508
|
+
defaultClassNames.day
|
|
4509
|
+
),
|
|
4510
|
+
range_start: cn(
|
|
4511
|
+
"relative isolate z-0 rounded-l-md bg-primary/8 after:absolute after:inset-y-0 after:right-0 after:w-3 after:bg-primary/8",
|
|
4512
|
+
defaultClassNames.range_start
|
|
4129
4513
|
),
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4514
|
+
range_middle: cn("rounded-none bg-primary/8", defaultClassNames.range_middle),
|
|
4515
|
+
range_end: cn(
|
|
4516
|
+
"relative isolate z-0 rounded-r-md bg-primary/8 after:absolute after:inset-y-0 after:left-0 after:w-3 after:bg-primary/8",
|
|
4517
|
+
defaultClassNames.range_end
|
|
4518
|
+
),
|
|
4519
|
+
today: cn("rounded-md bg-accent text-accent-foreground", defaultClassNames.today),
|
|
4520
|
+
outside: cn(
|
|
4521
|
+
"text-muted-foreground/50 aria-selected:text-muted-foreground/50",
|
|
4522
|
+
defaultClassNames.outside
|
|
4523
|
+
),
|
|
4524
|
+
disabled: cn("text-muted-foreground/40 opacity-50", defaultClassNames.disabled),
|
|
4525
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
4526
|
+
...classNames
|
|
4141
4527
|
},
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4528
|
+
modifiersClassNames: {
|
|
4529
|
+
preview_start: "relative isolate z-0 rounded-l-md bg-primary/8 after:absolute after:inset-y-0 after:right-0 after:w-3 after:bg-primary/8",
|
|
4530
|
+
preview_middle: "rounded-none bg-primary/8",
|
|
4531
|
+
preview_end: "relative isolate z-0 rounded-r-md bg-primary/8 after:absolute after:inset-y-0 after:left-0 after:w-3 after:bg-primary/8",
|
|
4532
|
+
...modifiersClassNames
|
|
4533
|
+
},
|
|
4534
|
+
components: resolvedComponents,
|
|
4535
|
+
...props
|
|
4536
|
+
}
|
|
4537
|
+
);
|
|
4538
|
+
}
|
|
4539
|
+
function CalendarDayButton({
|
|
4153
4540
|
className,
|
|
4154
|
-
|
|
4155
|
-
|
|
4541
|
+
day,
|
|
4542
|
+
modifiers,
|
|
4543
|
+
locale,
|
|
4544
|
+
...props
|
|
4156
4545
|
}) {
|
|
4546
|
+
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
4547
|
+
const ref = react.useRef(null);
|
|
4548
|
+
react.useEffect(() => {
|
|
4549
|
+
if (modifiers.focused) ref.current?.focus();
|
|
4550
|
+
}, [modifiers.focused]);
|
|
4551
|
+
const isPreviewEdge = Boolean(
|
|
4552
|
+
(modifiers.preview_start || modifiers.preview_end) && !modifiers.selected
|
|
4553
|
+
);
|
|
4554
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4555
|
+
Button,
|
|
4556
|
+
{
|
|
4557
|
+
ref,
|
|
4558
|
+
variant: "ghost",
|
|
4559
|
+
size: "icon-sm",
|
|
4560
|
+
"data-day": day.date.toLocaleDateString(locale?.code),
|
|
4561
|
+
"data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
|
|
4562
|
+
"data-range-start": modifiers.range_start,
|
|
4563
|
+
"data-range-end": modifiers.range_end,
|
|
4564
|
+
"data-range-middle": modifiers.range_middle,
|
|
4565
|
+
"data-preview-middle": Boolean(modifiers.preview_middle),
|
|
4566
|
+
"data-preview-edge": isPreviewEdge,
|
|
4567
|
+
className: cn(
|
|
4568
|
+
"group-data-[focused=true]/day:ring-primary/40 data-[preview-edge=true]:ring-primary/50 data-[preview-edge=true]:text-primary data-[preview-middle=true]:text-primary data-[range-end=true]:!bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:!bg-primary/8 data-[range-middle=true]:text-foreground data-[range-start=true]:!bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:!bg-primary data-[selected-single=true]:text-primary-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 !rounded-md border-0 !bg-transparent leading-none font-normal transition-colors duration-150 group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:rounded-md group-data-[focused=true]/day:ring-[2px] hover:!bg-transparent data-[preview-edge=true]:rounded-md data-[preview-edge=true]:font-medium data-[preview-edge=true]:ring-[2px] data-[preview-middle=true]:font-medium data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[selected-single=true]:rounded-md [&>span]:text-xs [&>span]:font-medium [&>span]:opacity-75",
|
|
4569
|
+
defaultClassNames.day,
|
|
4570
|
+
className
|
|
4571
|
+
),
|
|
4572
|
+
...props
|
|
4573
|
+
}
|
|
4574
|
+
);
|
|
4575
|
+
}
|
|
4576
|
+
function DatePicker(props) {
|
|
4577
|
+
const {
|
|
4578
|
+
placeholder = "Pick a date",
|
|
4579
|
+
disabled = false,
|
|
4580
|
+
className,
|
|
4581
|
+
fromDate,
|
|
4582
|
+
toDate,
|
|
4583
|
+
numberOfMonths = 1
|
|
4584
|
+
} = props;
|
|
4157
4585
|
const [open, setOpen] = react.useState(false);
|
|
4586
|
+
const [awaitingRangeEnd, setAwaitingRangeEnd] = react.useState(false);
|
|
4587
|
+
const [previewDate, setPreviewDate] = react.useState(void 0);
|
|
4158
4588
|
const label = react.useMemo(() => {
|
|
4159
|
-
if (mode === "range") {
|
|
4160
|
-
const range = selected;
|
|
4161
|
-
if (range?.from
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4589
|
+
if (props.mode === "range") {
|
|
4590
|
+
const range = props.selected;
|
|
4591
|
+
if (!range?.from) return placeholder;
|
|
4592
|
+
if (!range.to) return `${dateFns.format(range.from, "MMM d, yyyy")} \u2013 \u2026`;
|
|
4593
|
+
return `${dateFns.format(range.from, "MMM d, yyyy")} \u2013 ${dateFns.format(range.to, "MMM d, yyyy")}`;
|
|
4594
|
+
}
|
|
4595
|
+
return props.selected ? dateFns.format(props.selected, "MMM d, yyyy") : placeholder;
|
|
4596
|
+
}, [props.mode, props.selected, placeholder]);
|
|
4597
|
+
const handleOpenChange = (nextOpen) => {
|
|
4598
|
+
setOpen(nextOpen);
|
|
4599
|
+
if (!nextOpen) {
|
|
4600
|
+
setAwaitingRangeEnd(false);
|
|
4601
|
+
setPreviewDate(void 0);
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4604
|
+
const handleRangeSelect = (range, triggerDate) => {
|
|
4605
|
+
if (props.mode !== "range") return;
|
|
4606
|
+
const emit = props.onSelect;
|
|
4607
|
+
if (!awaitingRangeEnd) {
|
|
4608
|
+
setAwaitingRangeEnd(true);
|
|
4609
|
+
emit?.({ from: triggerDate, to: void 0 });
|
|
4610
|
+
return;
|
|
4611
|
+
}
|
|
4612
|
+
emit?.(range);
|
|
4613
|
+
if (!range?.from || !range.to) {
|
|
4614
|
+
setAwaitingRangeEnd(!!range?.from);
|
|
4615
|
+
return;
|
|
4616
|
+
}
|
|
4617
|
+
setAwaitingRangeEnd(false);
|
|
4618
|
+
setPreviewDate(void 0);
|
|
4619
|
+
setOpen(false);
|
|
4620
|
+
};
|
|
4621
|
+
const rangeFrom = props.mode === "range" ? props.selected?.from : void 0;
|
|
4622
|
+
const previewModifiers = react.useMemo(() => {
|
|
4623
|
+
if (!awaitingRangeEnd || !rangeFrom || !previewDate) return void 0;
|
|
4624
|
+
if (dateFns.isSameDay(rangeFrom, previewDate)) return void 0;
|
|
4625
|
+
const [start, end] = previewDate < rangeFrom ? [previewDate, rangeFrom] : [rangeFrom, previewDate];
|
|
4626
|
+
return {
|
|
4627
|
+
preview_start: start,
|
|
4628
|
+
preview_middle: { after: start, before: end },
|
|
4629
|
+
preview_end: end
|
|
4630
|
+
};
|
|
4631
|
+
}, [awaitingRangeEnd, rangeFrom, previewDate]);
|
|
4632
|
+
const handleDayPreview = (day, dayModifiers) => {
|
|
4633
|
+
if (!awaitingRangeEnd) return;
|
|
4634
|
+
if (dayModifiers.disabled || dayModifiers.hidden) return;
|
|
4635
|
+
setPreviewDate((current) => current && dateFns.isSameDay(current, day) ? current : day);
|
|
4636
|
+
};
|
|
4637
|
+
const dateConstraints = react.useMemo(() => {
|
|
4638
|
+
const disabledMatchers = [];
|
|
4639
|
+
if (fromDate) disabledMatchers.push({ before: fromDate });
|
|
4640
|
+
if (toDate) disabledMatchers.push({ after: toDate });
|
|
4641
|
+
return {
|
|
4642
|
+
...disabledMatchers.length > 0 && { disabled: disabledMatchers },
|
|
4643
|
+
...fromDate && { startMonth: fromDate },
|
|
4644
|
+
...toDate && { endMonth: toDate }
|
|
4645
|
+
};
|
|
4646
|
+
}, [fromDate, toDate]);
|
|
4647
|
+
const hasValue = props.mode === "range" ? !!props.selected?.from : !!props.selected;
|
|
4648
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
4171
4649
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4172
4650
|
Button,
|
|
4173
4651
|
{
|
|
@@ -4185,36 +4663,36 @@ function DatePicker({
|
|
|
4185
4663
|
]
|
|
4186
4664
|
}
|
|
4187
4665
|
) }),
|
|
4188
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { "data-slot": "date-picker-content", className: "w-auto p-0", align: "start", children: mode === "range" ?
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4666
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { "data-slot": "date-picker-content", className: "w-auto p-0", align: "start", children: props.mode === "range" ? (
|
|
4667
|
+
// Clearing the preview on the wrapper instead of per day
|
|
4668
|
+
// avoids the blank frame `onDayMouseLeave` would cause when
|
|
4669
|
+
// the pointer travels from one day to the next.
|
|
4670
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { onMouseLeave: () => setPreviewDate(void 0), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4671
|
+
Calendar,
|
|
4672
|
+
{
|
|
4192
4673
|
mode: "range",
|
|
4193
|
-
selected,
|
|
4194
|
-
onSelect:
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
initialFocus: true
|
|
4674
|
+
selected: props.selected,
|
|
4675
|
+
onSelect: handleRangeSelect,
|
|
4676
|
+
modifiers: previewModifiers,
|
|
4677
|
+
onDayMouseEnter: handleDayPreview,
|
|
4678
|
+
onDayFocus: handleDayPreview,
|
|
4679
|
+
numberOfMonths,
|
|
4680
|
+
autoFocus: true,
|
|
4681
|
+
...dateConstraints
|
|
4202
4682
|
}
|
|
4203
|
-
}
|
|
4683
|
+
) })
|
|
4204
4684
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4205
4685
|
Calendar,
|
|
4206
4686
|
{
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
onSelect
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
initialFocus: true
|
|
4217
|
-
}
|
|
4687
|
+
mode: "single",
|
|
4688
|
+
selected: props.selected,
|
|
4689
|
+
onSelect: (date) => {
|
|
4690
|
+
props.onSelect?.(date);
|
|
4691
|
+
setOpen(false);
|
|
4692
|
+
},
|
|
4693
|
+
numberOfMonths,
|
|
4694
|
+
autoFocus: true,
|
|
4695
|
+
...dateConstraints
|
|
4218
4696
|
}
|
|
4219
4697
|
) })
|
|
4220
4698
|
] });
|
|
@@ -4339,6 +4817,7 @@ var Navbar = react.forwardRef(
|
|
|
4339
4817
|
notifications,
|
|
4340
4818
|
avatarSrc,
|
|
4341
4819
|
avatarFallback,
|
|
4820
|
+
showUtilityBar = true,
|
|
4342
4821
|
onNavLinkClick,
|
|
4343
4822
|
onSearchClick,
|
|
4344
4823
|
onHelpClick,
|
|
@@ -4410,7 +4889,7 @@ var Navbar = react.forwardRef(
|
|
|
4410
4889
|
] }),
|
|
4411
4890
|
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "ml-auto flex h-full items-center", children: navigationLinks.map((link, i) => /* @__PURE__ */ jsxRuntime.jsx(NavLinkItem, { link, onNavLinkClick }, i)) })
|
|
4412
4891
|
] }) }),
|
|
4413
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-background border-border border-b px-4 md:px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex h-9 max-w-screen-2xl items-center justify-between", children: [
|
|
4892
|
+
showUtilityBar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-background border-border border-b px-4 md:px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex h-9 max-w-screen-2xl items-center justify-between", children: [
|
|
4414
4893
|
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex items-center", children: utilityLinks.map((link, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
4415
4894
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-border mx-3 select-none", children: "|" }),
|
|
4416
4895
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4655,6 +5134,8 @@ function NavigationMenuIndicator({
|
|
|
4655
5134
|
}
|
|
4656
5135
|
);
|
|
4657
5136
|
}
|
|
5137
|
+
|
|
5138
|
+
// src/components/authorization/policy.ts
|
|
4658
5139
|
function matchPermission(pattern, permission) {
|
|
4659
5140
|
if (pattern === "*") return true;
|
|
4660
5141
|
if (pattern === permission) return true;
|
|
@@ -4670,41 +5151,46 @@ function matchesAny(permissionSet, permission) {
|
|
|
4670
5151
|
}
|
|
4671
5152
|
return false;
|
|
4672
5153
|
}
|
|
5154
|
+
function can(permissionSet, perms, mode = "any") {
|
|
5155
|
+
const list = Array.isArray(perms) ? perms : [perms];
|
|
5156
|
+
if (list.length === 0) return false;
|
|
5157
|
+
if (permissionSet.has("*")) return true;
|
|
5158
|
+
if (mode === "all") {
|
|
5159
|
+
return list.every((p) => matchesAny(permissionSet, p));
|
|
5160
|
+
}
|
|
5161
|
+
return list.some((p) => matchesAny(permissionSet, p));
|
|
5162
|
+
}
|
|
4673
5163
|
var AbilityContext = react.createContext(void 0);
|
|
4674
5164
|
AbilityContext.displayName = "AbilityContext";
|
|
4675
5165
|
function AbilityProvider({ children, permissions }) {
|
|
4676
5166
|
const [permissionSet, setPermissionSet] = react.useState(
|
|
4677
5167
|
() => new Set(permissions ?? [])
|
|
4678
5168
|
);
|
|
4679
|
-
const
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
if (permissionSet.has("*")) return true;
|
|
4684
|
-
if (mode === "all") {
|
|
4685
|
-
return list.every((p) => matchesAny(permissionSet, p));
|
|
4686
|
-
}
|
|
4687
|
-
return list.some((p) => matchesAny(permissionSet, p));
|
|
4688
|
-
},
|
|
5169
|
+
const [imperativelyResolved, setImperativelyResolved] = react.useState(false);
|
|
5170
|
+
const status = permissions !== void 0 || imperativelyResolved ? "ready" : "loading";
|
|
5171
|
+
const can2 = react.useCallback(
|
|
5172
|
+
(perms, mode = "any") => can(permissionSet, perms, mode),
|
|
4689
5173
|
[permissionSet]
|
|
4690
5174
|
);
|
|
4691
5175
|
const setAbilities = react.useCallback((perms) => {
|
|
4692
5176
|
setPermissionSet(new Set(perms));
|
|
5177
|
+
setImperativelyResolved(true);
|
|
4693
5178
|
}, []);
|
|
4694
5179
|
const clearAbilities = react.useCallback(() => {
|
|
4695
5180
|
setPermissionSet(/* @__PURE__ */ new Set());
|
|
5181
|
+
setImperativelyResolved(true);
|
|
4696
5182
|
}, []);
|
|
4697
|
-
const
|
|
5183
|
+
const permissionKey = permissions === void 0 ? null : [...permissions].sort().join("|");
|
|
5184
|
+
const syncedKey = react.useRef(permissionKey);
|
|
4698
5185
|
react.useEffect(() => {
|
|
4699
|
-
if (
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
syncedKey.current = key;
|
|
5186
|
+
if (permissionKey === null) return;
|
|
5187
|
+
if (permissionKey === syncedKey.current) return;
|
|
5188
|
+
syncedKey.current = permissionKey;
|
|
4703
5189
|
setPermissionSet(new Set(permissions));
|
|
4704
|
-
}, [permissions]);
|
|
5190
|
+
}, [permissionKey, permissions]);
|
|
4705
5191
|
const value = react.useMemo(
|
|
4706
|
-
() => ({ can, setAbilities, clearAbilities }),
|
|
4707
|
-
[
|
|
5192
|
+
() => ({ can: can2, setAbilities, clearAbilities, status }),
|
|
5193
|
+
[can2, setAbilities, clearAbilities, status]
|
|
4708
5194
|
);
|
|
4709
5195
|
return /* @__PURE__ */ jsxRuntime.jsx(AbilityContext.Provider, { value, children });
|
|
4710
5196
|
}
|
|
@@ -4716,36 +5202,194 @@ function useAbility() {
|
|
|
4716
5202
|
return context;
|
|
4717
5203
|
}
|
|
4718
5204
|
function useCan(permissions, mode = "any") {
|
|
4719
|
-
const { can } = useAbility();
|
|
4720
|
-
return
|
|
5205
|
+
const { can: can2 } = useAbility();
|
|
5206
|
+
return can2(permissions, mode);
|
|
5207
|
+
}
|
|
5208
|
+
function useAbilityStatus() {
|
|
5209
|
+
return useAbility().status;
|
|
5210
|
+
}
|
|
5211
|
+
|
|
5212
|
+
// src/components/authorization/permissions.generated.ts
|
|
5213
|
+
var KNOWN_PERMISSIONS = [];
|
|
5214
|
+
|
|
5215
|
+
// src/components/authorization/permission-catalog.ts
|
|
5216
|
+
var CATALOG = new Set(KNOWN_PERMISSIONS);
|
|
5217
|
+
var warned = /* @__PURE__ */ new Set();
|
|
5218
|
+
function warnUnknownPermission(permission) {
|
|
5219
|
+
if (process.env.NODE_ENV === "production") return;
|
|
5220
|
+
if (CATALOG.size === 0) return;
|
|
5221
|
+
const requested = Array.isArray(permission) ? permission : [permission];
|
|
5222
|
+
for (const entry of requested) {
|
|
5223
|
+
if (entry.includes("*")) continue;
|
|
5224
|
+
if (CATALOG.has(entry) || warned.has(entry)) continue;
|
|
5225
|
+
warned.add(entry);
|
|
5226
|
+
console.warn(
|
|
5227
|
+
`[Can] Unknown permission "${entry}". It is not in the generated permission catalog. Check for a typo, or regenerate the catalog with \`pnpm generate-permissions\`.`
|
|
5228
|
+
);
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
var FOCUS_TRAVERSAL_KEYS = /* @__PURE__ */ new Set(["Tab", "Escape"]);
|
|
5232
|
+
function blockInteraction(event) {
|
|
5233
|
+
event.preventDefault();
|
|
5234
|
+
event.stopPropagation();
|
|
5235
|
+
}
|
|
5236
|
+
function blockNonTraversalKey(event) {
|
|
5237
|
+
if (!FOCUS_TRAVERSAL_KEYS.has(event.key)) blockInteraction(event);
|
|
5238
|
+
}
|
|
5239
|
+
var warnedRenderPropMisuse = /* @__PURE__ */ new Set();
|
|
5240
|
+
function warnRenderPropVoidsProps(voided) {
|
|
5241
|
+
if (process.env.NODE_ENV === "production") return;
|
|
5242
|
+
if (voided.length === 0) return;
|
|
5243
|
+
const key = voided.join(",");
|
|
5244
|
+
if (warnedRenderPropMisuse.has(key)) return;
|
|
5245
|
+
warnedRenderPropMisuse.add(key);
|
|
5246
|
+
console.warn(
|
|
5247
|
+
`[Can] \`children\` is a function, so ${voided.map((prop) => `\`${prop}\``).join(", ")} ${voided.length === 1 ? "is" : "are"} ignored. A render prop owns every state: read \`allowed\` and \`status\` and render the disabled, loading and denied cases yourself, or pass an element instead of a function.`
|
|
5248
|
+
);
|
|
5249
|
+
}
|
|
5250
|
+
function disableElement(child) {
|
|
5251
|
+
return react.cloneElement(child, {
|
|
5252
|
+
"aria-disabled": "true",
|
|
5253
|
+
className: cn(child.props.className, "cursor-not-allowed opacity-50"),
|
|
5254
|
+
onClickCapture: blockInteraction,
|
|
5255
|
+
onKeyDownCapture: blockNonTraversalKey,
|
|
5256
|
+
onKeyUpCapture: blockNonTraversalKey,
|
|
5257
|
+
onPointerDownCapture: blockInteraction,
|
|
5258
|
+
onMouseDownCapture: blockInteraction
|
|
5259
|
+
});
|
|
5260
|
+
}
|
|
5261
|
+
function InteractionFirewall({ children }) {
|
|
5262
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5263
|
+
"span",
|
|
5264
|
+
{
|
|
5265
|
+
"data-slot": "can-blocked",
|
|
5266
|
+
className: "contents",
|
|
5267
|
+
onClickCapture: blockInteraction,
|
|
5268
|
+
onPointerDownCapture: blockInteraction,
|
|
5269
|
+
onMouseDownCapture: blockInteraction,
|
|
5270
|
+
onKeyDownCapture: blockNonTraversalKey,
|
|
5271
|
+
onKeyUpCapture: blockNonTraversalKey,
|
|
5272
|
+
children
|
|
5273
|
+
}
|
|
5274
|
+
);
|
|
5275
|
+
}
|
|
5276
|
+
function DisabledSubtree({
|
|
5277
|
+
children,
|
|
5278
|
+
className,
|
|
5279
|
+
...props
|
|
5280
|
+
}) {
|
|
5281
|
+
const { "data-slot": _incomingDataSlot, ...restProps } = props;
|
|
5282
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5283
|
+
"span",
|
|
5284
|
+
{
|
|
5285
|
+
"data-slot": "can-disabled",
|
|
5286
|
+
"aria-disabled": "true",
|
|
5287
|
+
className: cn(
|
|
5288
|
+
"inline-flex cursor-not-allowed opacity-50",
|
|
5289
|
+
"*:pointer-events-none",
|
|
5290
|
+
className
|
|
5291
|
+
),
|
|
5292
|
+
onClickCapture: blockInteraction,
|
|
5293
|
+
onPointerDownCapture: blockInteraction,
|
|
5294
|
+
onMouseDownCapture: blockInteraction,
|
|
5295
|
+
onKeyDownCapture: blockNonTraversalKey,
|
|
5296
|
+
onKeyUpCapture: blockNonTraversalKey,
|
|
5297
|
+
...restProps,
|
|
5298
|
+
children
|
|
5299
|
+
}
|
|
5300
|
+
);
|
|
4721
5301
|
}
|
|
4722
|
-
function Can({
|
|
4723
|
-
|
|
4724
|
-
|
|
5302
|
+
function Can({
|
|
5303
|
+
permission,
|
|
5304
|
+
mode = "any",
|
|
5305
|
+
negate = false,
|
|
5306
|
+
behavior = "hide",
|
|
5307
|
+
reason = null,
|
|
5308
|
+
fallback = null,
|
|
5309
|
+
loading,
|
|
5310
|
+
children
|
|
5311
|
+
}) {
|
|
5312
|
+
warnUnknownPermission(permission);
|
|
5313
|
+
const { can: can2, status } = useAbility();
|
|
5314
|
+
const hasPermission = status === "ready" && can2(permission, mode);
|
|
4725
5315
|
const show = negate ? !hasPermission : hasPermission;
|
|
4726
5316
|
if (typeof children === "function") {
|
|
4727
|
-
|
|
5317
|
+
warnRenderPropVoidsProps([
|
|
5318
|
+
...behavior === "disable" ? ["behavior='disable'"] : [],
|
|
5319
|
+
...reason !== null ? ["reason"] : [],
|
|
5320
|
+
...fallback !== null ? ["fallback"] : [],
|
|
5321
|
+
...loading !== void 0 ? ["loading"] : []
|
|
5322
|
+
]);
|
|
5323
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children({ allowed: show, status }) });
|
|
5324
|
+
}
|
|
5325
|
+
if (status === "loading" && loading !== void 0) {
|
|
5326
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loading });
|
|
4728
5327
|
}
|
|
4729
|
-
|
|
5328
|
+
if (show) {
|
|
5329
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
5330
|
+
}
|
|
5331
|
+
if (behavior === "disable") {
|
|
5332
|
+
if (react.isValidElement(children) && children.type !== react.Fragment) {
|
|
5333
|
+
const disabledChild = disableElement(children);
|
|
5334
|
+
if (reason === null) {
|
|
5335
|
+
return /* @__PURE__ */ jsxRuntime.jsx(InteractionFirewall, { children: disabledChild });
|
|
5336
|
+
}
|
|
5337
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
5338
|
+
/* @__PURE__ */ jsxRuntime.jsx(InteractionFirewall, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: disabledChild }) }),
|
|
5339
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: reason })
|
|
5340
|
+
] });
|
|
5341
|
+
}
|
|
5342
|
+
if (reason === null) {
|
|
5343
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DisabledSubtree, { children });
|
|
5344
|
+
}
|
|
5345
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
5346
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DisabledSubtree, { children }) }),
|
|
5347
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: reason })
|
|
5348
|
+
] });
|
|
5349
|
+
}
|
|
5350
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
|
|
4730
5351
|
}
|
|
4731
5352
|
Can.displayName = "Can";
|
|
4732
|
-
function CanNot({
|
|
4733
|
-
|
|
5353
|
+
function CanNot({
|
|
5354
|
+
permission,
|
|
5355
|
+
mode = "any",
|
|
5356
|
+
behavior = "hide",
|
|
5357
|
+
reason = null,
|
|
5358
|
+
fallback = null,
|
|
5359
|
+
loading,
|
|
5360
|
+
children
|
|
5361
|
+
}) {
|
|
5362
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5363
|
+
Can,
|
|
5364
|
+
{
|
|
5365
|
+
permission,
|
|
5366
|
+
mode,
|
|
5367
|
+
negate: true,
|
|
5368
|
+
behavior,
|
|
5369
|
+
reason,
|
|
5370
|
+
fallback,
|
|
5371
|
+
loading,
|
|
5372
|
+
children
|
|
5373
|
+
}
|
|
5374
|
+
);
|
|
4734
5375
|
}
|
|
4735
5376
|
CanNot.displayName = "CanNot";
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
const [isMobile, setIsMobile] = react.useState(void 0);
|
|
5377
|
+
function useMediaQuery(query) {
|
|
5378
|
+
const [matches, setMatches] = react.useState(false);
|
|
4739
5379
|
react.useEffect(() => {
|
|
4740
|
-
|
|
4741
|
-
const
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
mql.addEventListener("change",
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
5380
|
+
if (typeof window === "undefined") return;
|
|
5381
|
+
const mql = window.matchMedia(query);
|
|
5382
|
+
setMatches(mql.matches);
|
|
5383
|
+
const handler = (e) => setMatches(e.matches);
|
|
5384
|
+
mql.addEventListener("change", handler);
|
|
5385
|
+
return () => mql.removeEventListener("change", handler);
|
|
5386
|
+
}, [query]);
|
|
5387
|
+
return matches;
|
|
5388
|
+
}
|
|
5389
|
+
|
|
5390
|
+
// src/hooks/use-mobile.ts
|
|
5391
|
+
function useIsMobile() {
|
|
5392
|
+
return useMediaQuery("(max-width: 767px)");
|
|
4749
5393
|
}
|
|
4750
5394
|
function Sheet({ ...props }) {
|
|
4751
5395
|
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Root, { "data-slot": "sheet", ...props });
|
|
@@ -4938,6 +5582,39 @@ function SidebarProvider({
|
|
|
4938
5582
|
}
|
|
4939
5583
|
) });
|
|
4940
5584
|
}
|
|
5585
|
+
function SidebarResizeHandle() {
|
|
5586
|
+
const dragRef = react.useRef(null);
|
|
5587
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5588
|
+
"div",
|
|
5589
|
+
{
|
|
5590
|
+
"data-slot": "sidebar-resize-handle",
|
|
5591
|
+
className: "absolute inset-y-0 right-0 w-1 cursor-col-resize opacity-0 transition-opacity hover:opacity-100 hover:bg-sidebar-border group-data-[state=collapsed]:hidden",
|
|
5592
|
+
onPointerDown: (e) => {
|
|
5593
|
+
e.preventDefault();
|
|
5594
|
+
const wrapper = e.currentTarget.closest('[data-slot="sidebar-wrapper"]');
|
|
5595
|
+
if (!wrapper) return;
|
|
5596
|
+
const container = e.currentTarget.closest('[data-slot="sidebar-container"]');
|
|
5597
|
+
const gap = container?.parentElement?.querySelector('[data-slot="sidebar-gap"]') ?? null;
|
|
5598
|
+
const currentWidth = container ? parseFloat(getComputedStyle(container).width) : 256;
|
|
5599
|
+
if (container) container.style.transition = "none";
|
|
5600
|
+
if (gap) gap.style.transition = "none";
|
|
5601
|
+
dragRef.current = { startX: e.clientX, startWidth: currentWidth, wrapper, container: container ?? null, gap };
|
|
5602
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
5603
|
+
},
|
|
5604
|
+
onPointerMove: (e) => {
|
|
5605
|
+
if (!dragRef.current) return;
|
|
5606
|
+
const { startX, startWidth, wrapper } = dragRef.current;
|
|
5607
|
+
const newWidth = Math.max(160, Math.min(480, startWidth + (e.clientX - startX)));
|
|
5608
|
+
wrapper.style.setProperty("--sidebar-width", `${newWidth}px`);
|
|
5609
|
+
},
|
|
5610
|
+
onPointerUp: () => {
|
|
5611
|
+
if (dragRef.current?.container) dragRef.current.container.style.transition = "";
|
|
5612
|
+
if (dragRef.current?.gap) dragRef.current.gap.style.transition = "";
|
|
5613
|
+
dragRef.current = null;
|
|
5614
|
+
}
|
|
5615
|
+
}
|
|
5616
|
+
);
|
|
5617
|
+
}
|
|
4941
5618
|
function Sidebar({
|
|
4942
5619
|
side = "left",
|
|
4943
5620
|
variant = "sidebar",
|
|
@@ -5008,7 +5685,7 @@ function Sidebar({
|
|
|
5008
5685
|
)
|
|
5009
5686
|
}
|
|
5010
5687
|
),
|
|
5011
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5688
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5012
5689
|
"div",
|
|
5013
5690
|
{
|
|
5014
5691
|
"data-slot": "sidebar-container",
|
|
@@ -5020,15 +5697,18 @@ function Sidebar({
|
|
|
5020
5697
|
className
|
|
5021
5698
|
),
|
|
5022
5699
|
...props,
|
|
5023
|
-
children:
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5700
|
+
children: [
|
|
5701
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5702
|
+
"div",
|
|
5703
|
+
{
|
|
5704
|
+
"data-sidebar": "sidebar",
|
|
5705
|
+
"data-slot": "sidebar-inner",
|
|
5706
|
+
className: "bg-sidebar group-data-[variant=floating]:ring-sidebar-border flex size-full flex-col group-data-[variant=floating]:rounded-2xl group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1",
|
|
5707
|
+
children
|
|
5708
|
+
}
|
|
5709
|
+
),
|
|
5710
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarResizeHandle, {})
|
|
5711
|
+
]
|
|
5032
5712
|
}
|
|
5033
5713
|
)
|
|
5034
5714
|
]
|
|
@@ -5145,7 +5825,7 @@ function SidebarContent({ className, ...props }) {
|
|
|
5145
5825
|
"data-slot": "sidebar-content",
|
|
5146
5826
|
"data-sidebar": "content",
|
|
5147
5827
|
className: cn(
|
|
5148
|
-
"no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto [--radius:var(--radius-xl)] group-data-[collapsible=icon]:overflow-hidden",
|
|
5828
|
+
"no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden [--radius:var(--radius-xl)] group-data-[collapsible=icon]:overflow-hidden",
|
|
5149
5829
|
className
|
|
5150
5830
|
),
|
|
5151
5831
|
...props
|
|
@@ -5440,6 +6120,7 @@ function AppShell({
|
|
|
5440
6120
|
onItemClick,
|
|
5441
6121
|
brandName = "Total Portal",
|
|
5442
6122
|
showHeader = true,
|
|
6123
|
+
header,
|
|
5443
6124
|
open,
|
|
5444
6125
|
onOpenChange,
|
|
5445
6126
|
defaultOpen,
|
|
@@ -5460,7 +6141,7 @@ function AppShell({
|
|
|
5460
6141
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarTrigger, { variant: "ghost", className: "size-8 shrink-0" }),
|
|
5461
6142
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarBrand, { brandName })
|
|
5462
6143
|
] }),
|
|
5463
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarContent, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => {
|
|
6144
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarContent, { className: "overflow-x:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => {
|
|
5464
6145
|
const menuItem = /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5465
6146
|
SidebarMenuButton,
|
|
5466
6147
|
{
|
|
@@ -5489,7 +6170,7 @@ function AppShell({
|
|
|
5489
6170
|
}) }) }) }) })
|
|
5490
6171
|
] }),
|
|
5491
6172
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
5492
|
-
showHeader ? /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex h-14 items-center gap-2 border-b px-4", children: [
|
|
6173
|
+
header ? header : showHeader ? /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex h-14 items-center gap-2 border-b px-4", children: [
|
|
5493
6174
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarTrigger, { variant: "ghost", className: "size-8 shrink-0 md:hidden" }),
|
|
5494
6175
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: brandName })
|
|
5495
6176
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(SidebarTrigger, { variant: "ghost", className: "size-8 shrink-0 md:hidden" }),
|
|
@@ -6103,14 +6784,9 @@ var eventCalendarStyles = `
|
|
|
6103
6784
|
font-weight: 600;
|
|
6104
6785
|
}
|
|
6105
6786
|
|
|
6106
|
-
/* \u2500\u2500 Event modal \
|
|
6787
|
+
/* \u2500\u2500 Event modal \u2014 hidden; replaced by TCCE Popover in event-calendar.tsx \u2500\u2500 */
|
|
6107
6788
|
.sx-tcce .sx__event-modal {
|
|
6108
|
-
|
|
6109
|
-
border: 1px solid var(--color-border);
|
|
6110
|
-
font-size: 13px;
|
|
6111
|
-
min-width: 220px;
|
|
6112
|
-
max-width: 300px;
|
|
6113
|
-
background: var(--color-background);
|
|
6789
|
+
display: none !important;
|
|
6114
6790
|
}
|
|
6115
6791
|
.sx-tcce .sx__event-modal__title {
|
|
6116
6792
|
font-size: 14px;
|
|
@@ -6255,8 +6931,43 @@ function useEventCalendar({
|
|
|
6255
6931
|
return () => unsubscribe?.();
|
|
6256
6932
|
}, []);
|
|
6257
6933
|
return {
|
|
6258
|
-
calendarApp: calendarApp.current
|
|
6934
|
+
calendarApp: calendarApp.current,
|
|
6935
|
+
eventModal: eventModal$1.current
|
|
6936
|
+
};
|
|
6937
|
+
}
|
|
6938
|
+
var EVENT_COLOR = {
|
|
6939
|
+
default: "#22205f",
|
|
6940
|
+
primary: "#22205f",
|
|
6941
|
+
success: "#00a824",
|
|
6942
|
+
warning: "#c8a23b",
|
|
6943
|
+
danger: "#ea3a3d"
|
|
6944
|
+
};
|
|
6945
|
+
function getFixedAnchorRect(el) {
|
|
6946
|
+
const rect = el.getBoundingClientRect();
|
|
6947
|
+
let ancestor = el.parentElement;
|
|
6948
|
+
while (ancestor && ancestor !== document.documentElement) {
|
|
6949
|
+
if (window.getComputedStyle(ancestor).transform !== "none") {
|
|
6950
|
+
const cb = ancestor.getBoundingClientRect();
|
|
6951
|
+
return new DOMRect(rect.left - cb.left, rect.top - cb.top, rect.width, rect.height);
|
|
6952
|
+
}
|
|
6953
|
+
ancestor = ancestor.parentElement;
|
|
6954
|
+
}
|
|
6955
|
+
return rect;
|
|
6956
|
+
}
|
|
6957
|
+
function formatEventTime(start, end) {
|
|
6958
|
+
const isAllDay = start.length === 10;
|
|
6959
|
+
if (isAllDay) {
|
|
6960
|
+
const date = /* @__PURE__ */ new Date(`${start}T00:00:00`);
|
|
6961
|
+
return date.toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
|
|
6962
|
+
}
|
|
6963
|
+
const fmt = (s) => {
|
|
6964
|
+
const [, time] = s.split(" ");
|
|
6965
|
+
const [h, m] = time.split(":").map(Number);
|
|
6966
|
+
const ampm = h >= 12 ? "PM" : "AM";
|
|
6967
|
+
const hour = h % 12 || 12;
|
|
6968
|
+
return `${hour}:${m.toString().padStart(2, "0")} ${ampm}`;
|
|
6259
6969
|
};
|
|
6970
|
+
return `${fmt(start)} \u2013 ${fmt(end)}`;
|
|
6260
6971
|
}
|
|
6261
6972
|
function EventCalendar({
|
|
6262
6973
|
events,
|
|
@@ -6269,26 +6980,116 @@ function EventCalendar({
|
|
|
6269
6980
|
className
|
|
6270
6981
|
}) {
|
|
6271
6982
|
const [currentView, setCurrentView] = react.useState(defaultView);
|
|
6983
|
+
const [selectedEvent, setSelectedEvent] = react.useState(null);
|
|
6984
|
+
const [anchorRect, setAnchorRect] = react.useState(null);
|
|
6985
|
+
const clickedEventElRef = react.useRef(false);
|
|
6272
6986
|
const handleViewChange = react.useCallback(
|
|
6273
6987
|
(view) => {
|
|
6274
6988
|
setCurrentView(view);
|
|
6275
6989
|
onViewChange?.(view);
|
|
6276
6990
|
},
|
|
6277
|
-
[onViewChange]
|
|
6991
|
+
[onViewChange]
|
|
6992
|
+
);
|
|
6993
|
+
const handleEventClick = react.useCallback(
|
|
6994
|
+
(event) => {
|
|
6995
|
+
setSelectedEvent(event);
|
|
6996
|
+
onEventClick?.(event);
|
|
6997
|
+
},
|
|
6998
|
+
[onEventClick]
|
|
6999
|
+
);
|
|
7000
|
+
const { calendarApp, eventModal } = useEventCalendar({
|
|
7001
|
+
events,
|
|
7002
|
+
defaultView,
|
|
7003
|
+
defaultDate,
|
|
7004
|
+
locale,
|
|
7005
|
+
onEventClick: handleEventClick,
|
|
7006
|
+
onEventCreate,
|
|
7007
|
+
onViewChange: handleViewChange
|
|
7008
|
+
});
|
|
7009
|
+
react.useEffect(() => {
|
|
7010
|
+
const unsub = eventModal.calendarEventElement.subscribe((el) => {
|
|
7011
|
+
if (!el) {
|
|
7012
|
+
if (clickedEventElRef.current) {
|
|
7013
|
+
clickedEventElRef.current = false;
|
|
7014
|
+
} else {
|
|
7015
|
+
setSelectedEvent(null);
|
|
7016
|
+
setAnchorRect(null);
|
|
7017
|
+
}
|
|
7018
|
+
} else {
|
|
7019
|
+
setAnchorRect(getFixedAnchorRect(el));
|
|
7020
|
+
}
|
|
7021
|
+
});
|
|
7022
|
+
return unsub;
|
|
7023
|
+
}, [eventModal]);
|
|
7024
|
+
const handlePopoverOpenChange = react.useCallback(
|
|
7025
|
+
(open) => {
|
|
7026
|
+
if (!open) {
|
|
7027
|
+
eventModal.close();
|
|
7028
|
+
setSelectedEvent(null);
|
|
7029
|
+
setAnchorRect(null);
|
|
7030
|
+
}
|
|
7031
|
+
},
|
|
7032
|
+
[eventModal]
|
|
6278
7033
|
);
|
|
6279
|
-
const { calendarApp } = useEventCalendar({
|
|
6280
|
-
events,
|
|
6281
|
-
defaultView,
|
|
6282
|
-
defaultDate,
|
|
6283
|
-
locale,
|
|
6284
|
-
onEventClick,
|
|
6285
|
-
onEventCreate,
|
|
6286
|
-
onViewChange: handleViewChange
|
|
6287
|
-
});
|
|
6288
7034
|
const contextValue = react.useMemo(() => ({ currentView }), [currentView]);
|
|
6289
7035
|
return /* @__PURE__ */ jsxRuntime.jsxs(EventCalendarContext.Provider, { value: contextValue, children: [
|
|
6290
7036
|
/* @__PURE__ */ jsxRuntime.jsx("style", { href: "tcce-event-calendar", precedence: "default", children: eventCalendarStyles }),
|
|
6291
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7037
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: !!selectedEvent && !!anchorRect, onOpenChange: handlePopoverOpenChange, children: [
|
|
7038
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "event-calendar", className: cn("sx-tcce w-full", className), children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ScheduleXCalendar, { calendarApp: calendarApp ?? null }) }),
|
|
7039
|
+
anchorRect && /* @__PURE__ */ jsxRuntime.jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7040
|
+
"span",
|
|
7041
|
+
{
|
|
7042
|
+
style: {
|
|
7043
|
+
position: "fixed",
|
|
7044
|
+
top: anchorRect.top,
|
|
7045
|
+
left: anchorRect.left,
|
|
7046
|
+
width: anchorRect.width,
|
|
7047
|
+
height: anchorRect.height,
|
|
7048
|
+
pointerEvents: "none"
|
|
7049
|
+
}
|
|
7050
|
+
}
|
|
7051
|
+
) }),
|
|
7052
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7053
|
+
PopoverContent,
|
|
7054
|
+
{
|
|
7055
|
+
side: "right",
|
|
7056
|
+
align: "start",
|
|
7057
|
+
className: "w-65 gap-2",
|
|
7058
|
+
onPointerDownOutside: (e) => {
|
|
7059
|
+
const target = e.target;
|
|
7060
|
+
const isEventEl = target.closest(
|
|
7061
|
+
".sx__month-grid-event, .sx__time-grid-event, .sx__month-agenda-event"
|
|
7062
|
+
);
|
|
7063
|
+
if (isEventEl) {
|
|
7064
|
+
e.preventDefault();
|
|
7065
|
+
clickedEventElRef.current = true;
|
|
7066
|
+
}
|
|
7067
|
+
},
|
|
7068
|
+
children: selectedEvent && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7069
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
7070
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7071
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7072
|
+
"span",
|
|
7073
|
+
{
|
|
7074
|
+
className: "size-2 shrink-0 rounded-full",
|
|
7075
|
+
style: {
|
|
7076
|
+
backgroundColor: EVENT_COLOR[selectedEvent.color ?? "default"]
|
|
7077
|
+
}
|
|
7078
|
+
}
|
|
7079
|
+
),
|
|
7080
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-heading text-sm font-semibold leading-tight", children: selectedEvent.title })
|
|
7081
|
+
] }),
|
|
7082
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Edit event", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { size: 14 }) })
|
|
7083
|
+
] }),
|
|
7084
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
7085
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { size: 13, className: "shrink-0" }),
|
|
7086
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatEventTime(selectedEvent.start, selectedEvent.end) })
|
|
7087
|
+
] }),
|
|
7088
|
+
selectedEvent.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: selectedEvent.description })
|
|
7089
|
+
] })
|
|
7090
|
+
}
|
|
7091
|
+
)
|
|
7092
|
+
] })
|
|
6292
7093
|
] });
|
|
6293
7094
|
}
|
|
6294
7095
|
function useAppForm(schema, options) {
|
|
@@ -6367,7 +7168,7 @@ function TableHead({ className, ...props }) {
|
|
|
6367
7168
|
{
|
|
6368
7169
|
"data-slot": "table-head",
|
|
6369
7170
|
className: cn(
|
|
6370
|
-
"text-foreground has
|
|
7171
|
+
"text-foreground has-[[role=checkbox]]:pr-0 h-12 px-3 text-left align-middle font-medium whitespace-nowrap",
|
|
6371
7172
|
className
|
|
6372
7173
|
),
|
|
6373
7174
|
...props
|
|
@@ -6380,7 +7181,7 @@ function TableCell({ className, ...props }) {
|
|
|
6380
7181
|
{
|
|
6381
7182
|
"data-slot": "table-cell",
|
|
6382
7183
|
className: cn(
|
|
6383
|
-
"has
|
|
7184
|
+
"has-[[role=checkbox]]:pr-0 p-3 align-middle whitespace-nowrap",
|
|
6384
7185
|
className
|
|
6385
7186
|
),
|
|
6386
7187
|
...props
|
|
@@ -6630,18 +7431,6 @@ function TablePaginationBase({
|
|
|
6630
7431
|
);
|
|
6631
7432
|
}
|
|
6632
7433
|
var TablePagination = react.memo(TablePaginationBase);
|
|
6633
|
-
function useMediaQuery(query) {
|
|
6634
|
-
const [matches, setMatches] = react.useState(false);
|
|
6635
|
-
react.useEffect(() => {
|
|
6636
|
-
if (typeof window === "undefined") return;
|
|
6637
|
-
const mql = window.matchMedia(query);
|
|
6638
|
-
setMatches(mql.matches);
|
|
6639
|
-
const handler = (e) => setMatches(e.matches);
|
|
6640
|
-
mql.addEventListener("change", handler);
|
|
6641
|
-
return () => mql.removeEventListener("change", handler);
|
|
6642
|
-
}, [query]);
|
|
6643
|
-
return matches;
|
|
6644
|
-
}
|
|
6645
7434
|
var TableContext = react.createContext(null);
|
|
6646
7435
|
function useTableContext() {
|
|
6647
7436
|
const ctx = react.useContext(TableContext);
|
|
@@ -6653,6 +7442,13 @@ function useTableContext() {
|
|
|
6653
7442
|
function useTableContextSafe() {
|
|
6654
7443
|
return react.useContext(TableContext);
|
|
6655
7444
|
}
|
|
7445
|
+
|
|
7446
|
+
// src/components/compounds/Table/cell-size-class.ts
|
|
7447
|
+
var cellSizeClass = {
|
|
7448
|
+
sm: "px-3 py-1.5 text-xs",
|
|
7449
|
+
md: "px-5 py-2.5 text-sm",
|
|
7450
|
+
lg: "px-6 py-3 text-sm"
|
|
7451
|
+
};
|
|
6656
7452
|
var cardPadding = {
|
|
6657
7453
|
sm: "p-3",
|
|
6658
7454
|
md: "p-4",
|
|
@@ -6990,6 +7786,9 @@ function DataTableHeaderCell({ header }) {
|
|
|
6990
7786
|
},
|
|
6991
7787
|
className: cn(
|
|
6992
7788
|
"bg-primary text-primary-foreground",
|
|
7789
|
+
// Same density padding as the body cells: without it the header
|
|
7790
|
+
// label and the cell value below it sit at different offsets.
|
|
7791
|
+
cellSizeClass[meta.size ?? tableSize],
|
|
6993
7792
|
canResize && "relative",
|
|
6994
7793
|
meta.align === "center" && "text-center",
|
|
6995
7794
|
meta.align === "right" && "text-right",
|
|
@@ -7379,11 +8178,6 @@ function useTablePersistence({
|
|
|
7379
8178
|
persistDensity
|
|
7380
8179
|
};
|
|
7381
8180
|
}
|
|
7382
|
-
var cellSizeClass = {
|
|
7383
|
-
sm: "px-1 py-0 text-xs",
|
|
7384
|
-
md: "px-5 py-2.5 text-sm",
|
|
7385
|
-
lg: "px-6 py-3 text-sm"
|
|
7386
|
-
};
|
|
7387
8181
|
function resolveClassName(value, row) {
|
|
7388
8182
|
return typeof value === "function" ? value(row) : value;
|
|
7389
8183
|
}
|
|
@@ -7424,6 +8218,13 @@ function DataTableCell({
|
|
|
7424
8218
|
}
|
|
7425
8219
|
);
|
|
7426
8220
|
}
|
|
8221
|
+
var INTERACTIVE_CELL_CONTENT = 'button, a, input, select, textarea, [role="button"], [role="checkbox"], [role="menuitem"], [role="link"]';
|
|
8222
|
+
function isInteractiveCellEvent(event) {
|
|
8223
|
+
const target = event.target;
|
|
8224
|
+
if (!(target instanceof Element)) return false;
|
|
8225
|
+
const match = target.closest(INTERACTIVE_CELL_CONTENT);
|
|
8226
|
+
return match !== null && match !== event.currentTarget;
|
|
8227
|
+
}
|
|
7427
8228
|
function DataTableRow({ row, classNames }) {
|
|
7428
8229
|
const { onRowClick, variant } = useTableContext();
|
|
7429
8230
|
const clickable = Boolean(onRowClick);
|
|
@@ -7436,12 +8237,15 @@ function DataTableRow({ row, classNames }) {
|
|
|
7436
8237
|
"data-clickable": clickable || void 0,
|
|
7437
8238
|
role: clickable ? "button" : void 0,
|
|
7438
8239
|
tabIndex: clickable ? 0 : void 0,
|
|
7439
|
-
onClick: clickable ? () =>
|
|
8240
|
+
onClick: clickable ? (e) => {
|
|
8241
|
+
if (isInteractiveCellEvent(e)) return;
|
|
8242
|
+
onRowClick?.(row.original);
|
|
8243
|
+
} : void 0,
|
|
7440
8244
|
onKeyDown: clickable ? (e) => {
|
|
7441
|
-
if (e.key
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
8245
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
8246
|
+
if (isInteractiveCellEvent(e)) return;
|
|
8247
|
+
e.preventDefault();
|
|
8248
|
+
onRowClick?.(row.original);
|
|
7445
8249
|
} : void 0,
|
|
7446
8250
|
className: cn("hover:bg-muted", clickable && "cursor-pointer", rowClassName),
|
|
7447
8251
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(DataTableCell, { cell, cellClassName }, cell.id))
|
|
@@ -8042,7 +8846,7 @@ function DataTableFooter({ pagination, selectedCount, className }) {
|
|
|
8042
8846
|
className: cn("flex items-center justify-between border-t px-4 py-2", className),
|
|
8043
8847
|
children: [
|
|
8044
8848
|
selectedCount != null && selectedCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "text-muted-foreground text-xs", children: `${selectedCount} row${selectedCount > 1 ? "s" : ""} selected` }),
|
|
8045
|
-
/* @__PURE__ */ jsxRuntime.jsx(TablePagination, { ...pagination })
|
|
8849
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(TablePagination, { ...pagination }) })
|
|
8046
8850
|
]
|
|
8047
8851
|
}
|
|
8048
8852
|
);
|
|
@@ -8151,18 +8955,21 @@ function DataTableSearch({
|
|
|
8151
8955
|
debounce = 300
|
|
8152
8956
|
}) {
|
|
8153
8957
|
const ctx = useTableContextSafe();
|
|
8154
|
-
const [inputValue, setInputValue] = react.useState("");
|
|
8155
8958
|
const globalFilter = ctx?.globalFilter;
|
|
8156
8959
|
const setGlobalFilter = ctx?.setGlobalFilter;
|
|
8960
|
+
const committedValue = globalFilter ?? "";
|
|
8961
|
+
const [inputValue, setInputValue] = react.useState(committedValue);
|
|
8157
8962
|
react.useEffect(() => {
|
|
8158
|
-
if (globalFilter ===
|
|
8963
|
+
if (globalFilter === void 0) return;
|
|
8964
|
+
setInputValue(globalFilter);
|
|
8159
8965
|
}, [globalFilter]);
|
|
8160
8966
|
react.useEffect(() => {
|
|
8967
|
+
if (inputValue === committedValue) return;
|
|
8161
8968
|
const timer = setTimeout(() => {
|
|
8162
8969
|
setGlobalFilter?.(inputValue);
|
|
8163
8970
|
}, debounce);
|
|
8164
8971
|
return () => clearTimeout(timer);
|
|
8165
|
-
}, [inputValue, debounce, setGlobalFilter]);
|
|
8972
|
+
}, [inputValue, committedValue, debounce, setGlobalFilter]);
|
|
8166
8973
|
const handleClear = () => {
|
|
8167
8974
|
setInputValue("");
|
|
8168
8975
|
setGlobalFilter?.("");
|
|
@@ -8183,7 +8990,13 @@ function DataTableSearch({
|
|
|
8183
8990
|
onChange: (e) => setInputValue(e.target.value),
|
|
8184
8991
|
placeholder,
|
|
8185
8992
|
"aria-label": placeholder,
|
|
8186
|
-
className:
|
|
8993
|
+
className: cn(
|
|
8994
|
+
"h-8 w-48 pr-9 pl-9 text-sm",
|
|
8995
|
+
"[&::-webkit-search-cancel-button]:appearance-none",
|
|
8996
|
+
"[&::-webkit-search-decoration]:appearance-none",
|
|
8997
|
+
"[&::-webkit-search-results-button]:appearance-none",
|
|
8998
|
+
"[&::-webkit-search-results-decoration]:appearance-none"
|
|
8999
|
+
)
|
|
8187
9000
|
}
|
|
8188
9001
|
),
|
|
8189
9002
|
inputValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8193,12 +9006,382 @@ function DataTableSearch({
|
|
|
8193
9006
|
size: "icon-sm",
|
|
8194
9007
|
onClick: handleClear,
|
|
8195
9008
|
"aria-label": "Clear search",
|
|
8196
|
-
className: "text-muted-foreground hover:text-foreground absolute right-
|
|
9009
|
+
className: "text-muted-foreground hover:text-foreground absolute top-1/2 right-1.5 size-6 -translate-y-1/2",
|
|
8197
9010
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5", "aria-hidden": "true" })
|
|
8198
9011
|
}
|
|
8199
9012
|
)
|
|
8200
9013
|
] });
|
|
8201
9014
|
}
|
|
9015
|
+
function BottomNav({ items, className }) {
|
|
9016
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9017
|
+
"nav",
|
|
9018
|
+
{
|
|
9019
|
+
"data-slot": "bottom-nav",
|
|
9020
|
+
className: cn(
|
|
9021
|
+
"fixed bottom-0 left-0 right-0 z-50 mx-4 mb-4 rounded-2xl bg-background shadow-[0_-4px_20px_rgba(0,0,0,0.08)]",
|
|
9022
|
+
className
|
|
9023
|
+
),
|
|
9024
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-20 items-center justify-around px-4", children: items.map(({ label, href, icon, isActive, onClick }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9025
|
+
"a",
|
|
9026
|
+
{
|
|
9027
|
+
href,
|
|
9028
|
+
onClick,
|
|
9029
|
+
"data-slot": "bottom-nav-item",
|
|
9030
|
+
className: cn(
|
|
9031
|
+
"group flex flex-col items-center gap-0 transition-colors",
|
|
9032
|
+
isActive ? "text-primary" : "text-muted-foreground"
|
|
9033
|
+
),
|
|
9034
|
+
children: [
|
|
9035
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9036
|
+
"span",
|
|
9037
|
+
{
|
|
9038
|
+
className: cn(
|
|
9039
|
+
"flex h-12 items-center justify-center rounded-2xl transition-all",
|
|
9040
|
+
isActive ? "flex-col gap-0.5 bg-primary/10 px-4" : "w-12 group-hover:bg-muted group-active:bg-primary/10"
|
|
9041
|
+
),
|
|
9042
|
+
children: [
|
|
9043
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-6 w-6 shrink-0", children: icon }),
|
|
9044
|
+
isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold leading-none", children: label })
|
|
9045
|
+
]
|
|
9046
|
+
}
|
|
9047
|
+
),
|
|
9048
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9049
|
+
"span",
|
|
9050
|
+
{
|
|
9051
|
+
className: cn(
|
|
9052
|
+
"text-[10px] font-medium",
|
|
9053
|
+
isActive ? "invisible" : "visible"
|
|
9054
|
+
),
|
|
9055
|
+
children: label
|
|
9056
|
+
}
|
|
9057
|
+
),
|
|
9058
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9059
|
+
"span",
|
|
9060
|
+
{
|
|
9061
|
+
className: cn(
|
|
9062
|
+
"h-1 w-5 rounded-full transition-all",
|
|
9063
|
+
isActive ? "bg-primary" : "bg-transparent"
|
|
9064
|
+
)
|
|
9065
|
+
}
|
|
9066
|
+
)
|
|
9067
|
+
]
|
|
9068
|
+
},
|
|
9069
|
+
href
|
|
9070
|
+
)) })
|
|
9071
|
+
}
|
|
9072
|
+
);
|
|
9073
|
+
}
|
|
9074
|
+
var BottomNavTabsContext = react.createContext(null);
|
|
9075
|
+
function useBottomNavTabsContext() {
|
|
9076
|
+
const ctx = react.useContext(BottomNavTabsContext);
|
|
9077
|
+
if (!ctx) throw new Error("BottomNavTabsList must be inside BottomNavTabs");
|
|
9078
|
+
return ctx;
|
|
9079
|
+
}
|
|
9080
|
+
function BottomNavTabs({
|
|
9081
|
+
defaultValue,
|
|
9082
|
+
value: controlledValue,
|
|
9083
|
+
onValueChange,
|
|
9084
|
+
...props
|
|
9085
|
+
}) {
|
|
9086
|
+
const [internalValue, setInternalValue] = react.useState(controlledValue ?? defaultValue ?? "");
|
|
9087
|
+
const activeValue = controlledValue ?? internalValue;
|
|
9088
|
+
const listId = react.useId();
|
|
9089
|
+
const handleValueChange = (v) => {
|
|
9090
|
+
if (controlledValue === void 0) setInternalValue(v);
|
|
9091
|
+
onValueChange?.(v);
|
|
9092
|
+
};
|
|
9093
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BottomNavTabsContext.Provider, { value: { activeValue, listId }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9094
|
+
radixUi.Tabs.Root,
|
|
9095
|
+
{
|
|
9096
|
+
"data-slot": "bottom-nav-tabs",
|
|
9097
|
+
value: activeValue,
|
|
9098
|
+
onValueChange: handleValueChange,
|
|
9099
|
+
...props
|
|
9100
|
+
}
|
|
9101
|
+
) });
|
|
9102
|
+
}
|
|
9103
|
+
function BottomNavTabsContent({
|
|
9104
|
+
className,
|
|
9105
|
+
...props
|
|
9106
|
+
}) {
|
|
9107
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { className: cn("pb-28", className), ...props });
|
|
9108
|
+
}
|
|
9109
|
+
function BottomNavTabsList({ items, className }) {
|
|
9110
|
+
const { activeValue, listId } = useBottomNavTabsContext();
|
|
9111
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9112
|
+
"nav",
|
|
9113
|
+
{
|
|
9114
|
+
"data-slot": "bottom-nav-tabs-list",
|
|
9115
|
+
className: cn(
|
|
9116
|
+
"fixed bottom-0 left-0 right-0 z-50 mx-6 max-w- mb-4 rounded-2xl bg-background shadow-[0_-4px_20px_rgba(0,0,0,0.08)]",
|
|
9117
|
+
className
|
|
9118
|
+
),
|
|
9119
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(radixUi.Tabs.List, { className: "flex h-20 items-center justify-around px-4", children: items.map(({ value, label, icon, activeIcon }) => {
|
|
9120
|
+
const isActive = value === activeValue;
|
|
9121
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9122
|
+
radixUi.Tabs.Trigger,
|
|
9123
|
+
{
|
|
9124
|
+
value,
|
|
9125
|
+
"data-slot": "bottom-nav-tabs-trigger",
|
|
9126
|
+
className: cn(
|
|
9127
|
+
"group flex flex-col items-center transition-colors",
|
|
9128
|
+
"data-[state=active]:text-primary data-[state=inactive]:text-muted-foreground",
|
|
9129
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-2xl"
|
|
9130
|
+
),
|
|
9131
|
+
children: [
|
|
9132
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-15 w-16 flex-col items-center justify-center gap-1.5", children: [
|
|
9133
|
+
/* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { initial: false, children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9134
|
+
react$1.motion.span,
|
|
9135
|
+
{
|
|
9136
|
+
layoutId: `${listId}-pill`,
|
|
9137
|
+
className: "absolute inset-0 rounded-2xl bg-primary/10",
|
|
9138
|
+
transition: spring.snappy
|
|
9139
|
+
}
|
|
9140
|
+
) }),
|
|
9141
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10 h-6 w-6", children: isActive ? activeIcon ?? icon : icon }),
|
|
9142
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10 text-[10px] font-medium leading-none", children: label })
|
|
9143
|
+
] }),
|
|
9144
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9145
|
+
"span",
|
|
9146
|
+
{
|
|
9147
|
+
className: cn(
|
|
9148
|
+
"mt-1 h-1 w-6 rounded-full transition-colors",
|
|
9149
|
+
isActive ? "bg-primary" : "bg-transparent"
|
|
9150
|
+
)
|
|
9151
|
+
}
|
|
9152
|
+
)
|
|
9153
|
+
]
|
|
9154
|
+
},
|
|
9155
|
+
value
|
|
9156
|
+
);
|
|
9157
|
+
}) })
|
|
9158
|
+
}
|
|
9159
|
+
);
|
|
9160
|
+
}
|
|
9161
|
+
var DrawerContext = react.createContext({ isOpen: false, modal: true });
|
|
9162
|
+
function Drawer({ children, open, onOpenChange, modal = true, ...props }) {
|
|
9163
|
+
const [internalOpen, setInternalOpen] = react.useState(props.defaultOpen ?? false);
|
|
9164
|
+
const isOpen = open !== void 0 ? open : internalOpen;
|
|
9165
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DrawerContext.Provider, { value: { isOpen, modal }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9166
|
+
radixUi.Dialog.Root,
|
|
9167
|
+
{
|
|
9168
|
+
"data-slot": "drawer",
|
|
9169
|
+
modal,
|
|
9170
|
+
...props,
|
|
9171
|
+
open: isOpen,
|
|
9172
|
+
onOpenChange: (v) => {
|
|
9173
|
+
setInternalOpen(v);
|
|
9174
|
+
onOpenChange?.(v);
|
|
9175
|
+
},
|
|
9176
|
+
children
|
|
9177
|
+
}
|
|
9178
|
+
) });
|
|
9179
|
+
}
|
|
9180
|
+
function DrawerTrigger({ ...props }) {
|
|
9181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Trigger, { "data-slot": "drawer-trigger", ...props });
|
|
9182
|
+
}
|
|
9183
|
+
function DrawerClose({ ...props }) {
|
|
9184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "drawer-close", ...props });
|
|
9185
|
+
}
|
|
9186
|
+
function DrawerPortal({ children, ...props }) {
|
|
9187
|
+
const { isOpen } = react.useContext(DrawerContext);
|
|
9188
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Portal, { forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "sync", children: isOpen && children }) });
|
|
9189
|
+
}
|
|
9190
|
+
function DrawerOverlay({ className, ...props }) {
|
|
9191
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Overlay, { "data-slot": "drawer-overlay", asChild: true, forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9192
|
+
react$1.motion.div,
|
|
9193
|
+
{
|
|
9194
|
+
className: cn(
|
|
9195
|
+
"fixed inset-0 isolate z-50 bg-black/30 supports-backdrop-filter:backdrop-blur-sm",
|
|
9196
|
+
className
|
|
9197
|
+
),
|
|
9198
|
+
initial: { opacity: 0 },
|
|
9199
|
+
animate: { opacity: 1 },
|
|
9200
|
+
exit: { opacity: 0 },
|
|
9201
|
+
transition: { duration: duration.normal, ease: ease.smooth }
|
|
9202
|
+
}
|
|
9203
|
+
) });
|
|
9204
|
+
}
|
|
9205
|
+
var sizeClasses = {
|
|
9206
|
+
sm: "w-64",
|
|
9207
|
+
md: "w-80",
|
|
9208
|
+
lg: "w-96",
|
|
9209
|
+
xl: "w-[30rem]",
|
|
9210
|
+
full: "w-screen"
|
|
9211
|
+
};
|
|
9212
|
+
function DrawerContent({
|
|
9213
|
+
className,
|
|
9214
|
+
children,
|
|
9215
|
+
side = "right",
|
|
9216
|
+
size = "md",
|
|
9217
|
+
showCloseButton = true,
|
|
9218
|
+
resizable = false,
|
|
9219
|
+
...props
|
|
9220
|
+
}) {
|
|
9221
|
+
const isHorizontal = side === "left" || side === "right";
|
|
9222
|
+
const xInitial = side === "right" ? "100%" : side === "left" ? "-100%" : 0;
|
|
9223
|
+
const yInitial = side === "bottom" ? "100%" : side === "top" ? "-100%" : 0;
|
|
9224
|
+
const dragRef = react.useRef(null);
|
|
9225
|
+
const { modal } = react.useContext(DrawerContext);
|
|
9226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DrawerPortal, { children: [
|
|
9227
|
+
modal && /* @__PURE__ */ jsxRuntime.jsx(DrawerOverlay, {}, "drawer-overlay"),
|
|
9228
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9229
|
+
radixUi.Dialog.Content,
|
|
9230
|
+
{
|
|
9231
|
+
"data-slot": "drawer-content",
|
|
9232
|
+
"data-side": side,
|
|
9233
|
+
asChild: true,
|
|
9234
|
+
forceMount: true,
|
|
9235
|
+
className: cn(
|
|
9236
|
+
"fixed z-50 flex flex-col bg-popover text-popover-foreground shadow-xl outline-none",
|
|
9237
|
+
side === "left" && "inset-y-0 left-0",
|
|
9238
|
+
side === "right" && "inset-y-0 right-0",
|
|
9239
|
+
side === "top" && "inset-x-0 top-0",
|
|
9240
|
+
side === "bottom" && "inset-x-0 bottom-0",
|
|
9241
|
+
isHorizontal && sizeClasses[size],
|
|
9242
|
+
!isHorizontal && "h-auto min-h-40",
|
|
9243
|
+
className
|
|
9244
|
+
),
|
|
9245
|
+
...props,
|
|
9246
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9247
|
+
react$1.motion.div,
|
|
9248
|
+
{
|
|
9249
|
+
className: cn("flex flex-col", isHorizontal && "h-full"),
|
|
9250
|
+
initial: { x: xInitial, y: yInitial, opacity: 0 },
|
|
9251
|
+
animate: { x: 0, y: 0, opacity: 1, transition: transition.drawer },
|
|
9252
|
+
exit: { x: xInitial, y: yInitial, opacity: 0, transition: transition.drawerExit },
|
|
9253
|
+
children: [
|
|
9254
|
+
children,
|
|
9255
|
+
showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "drawer-close", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9256
|
+
Button,
|
|
9257
|
+
{
|
|
9258
|
+
variant: "ghost",
|
|
9259
|
+
className: "absolute top-4 right-4",
|
|
9260
|
+
size: "icon-sm",
|
|
9261
|
+
children: [
|
|
9262
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
|
|
9263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
9264
|
+
]
|
|
9265
|
+
}
|
|
9266
|
+
) }),
|
|
9267
|
+
resizable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9268
|
+
"div",
|
|
9269
|
+
{
|
|
9270
|
+
"data-slot": "drawer-resize-handle",
|
|
9271
|
+
className: cn(
|
|
9272
|
+
"absolute opacity-0 transition-opacity hover:opacity-100 hover:bg-border",
|
|
9273
|
+
side === "right" && "inset-y-0 left-0 w-1 cursor-col-resize",
|
|
9274
|
+
side === "left" && "inset-y-0 right-0 w-1 cursor-col-resize",
|
|
9275
|
+
side === "top" && "inset-x-0 bottom-0 h-1 cursor-row-resize",
|
|
9276
|
+
side === "bottom" && "inset-x-0 top-0 h-1 cursor-row-resize"
|
|
9277
|
+
),
|
|
9278
|
+
onPointerDown: (e) => {
|
|
9279
|
+
e.preventDefault();
|
|
9280
|
+
const content = e.currentTarget.parentElement;
|
|
9281
|
+
if (!content) return;
|
|
9282
|
+
const startSize = isHorizontal ? parseFloat(getComputedStyle(content).width) : parseFloat(getComputedStyle(content).height);
|
|
9283
|
+
content.style.transition = "none";
|
|
9284
|
+
dragRef.current = {
|
|
9285
|
+
startPos: isHorizontal ? e.clientX : e.clientY,
|
|
9286
|
+
startSize,
|
|
9287
|
+
content
|
|
9288
|
+
};
|
|
9289
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
9290
|
+
},
|
|
9291
|
+
onPointerMove: (e) => {
|
|
9292
|
+
if (!dragRef.current) return;
|
|
9293
|
+
const { startPos, startSize, content } = dragRef.current;
|
|
9294
|
+
const delta = (isHorizontal ? e.clientX : e.clientY) - startPos;
|
|
9295
|
+
let newSize;
|
|
9296
|
+
if (side === "right") {
|
|
9297
|
+
newSize = Math.max(160, Math.min(window.innerWidth * 0.9, startSize - delta));
|
|
9298
|
+
} else if (side === "left") {
|
|
9299
|
+
newSize = Math.max(160, Math.min(window.innerWidth * 0.9, startSize + delta));
|
|
9300
|
+
} else if (side === "bottom") {
|
|
9301
|
+
newSize = Math.max(80, Math.min(window.innerHeight * 0.9, startSize - delta));
|
|
9302
|
+
} else {
|
|
9303
|
+
newSize = Math.max(80, Math.min(window.innerHeight * 0.9, startSize + delta));
|
|
9304
|
+
}
|
|
9305
|
+
content.style[isHorizontal ? "width" : "height"] = `${newSize}px`;
|
|
9306
|
+
},
|
|
9307
|
+
onPointerUp: () => {
|
|
9308
|
+
if (dragRef.current?.content) {
|
|
9309
|
+
dragRef.current.content.style.transition = "";
|
|
9310
|
+
}
|
|
9311
|
+
dragRef.current = null;
|
|
9312
|
+
},
|
|
9313
|
+
onPointerCancel: () => {
|
|
9314
|
+
if (dragRef.current?.content) {
|
|
9315
|
+
dragRef.current.content.style.transition = "";
|
|
9316
|
+
}
|
|
9317
|
+
dragRef.current = null;
|
|
9318
|
+
}
|
|
9319
|
+
}
|
|
9320
|
+
)
|
|
9321
|
+
]
|
|
9322
|
+
}
|
|
9323
|
+
)
|
|
9324
|
+
},
|
|
9325
|
+
"drawer-content"
|
|
9326
|
+
)
|
|
9327
|
+
] });
|
|
9328
|
+
}
|
|
9329
|
+
function DrawerHeader({ className, ...props }) {
|
|
9330
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9331
|
+
"div",
|
|
9332
|
+
{
|
|
9333
|
+
"data-slot": "drawer-header",
|
|
9334
|
+
className: cn("flex shrink-0 flex-col gap-1.5 p-6", className),
|
|
9335
|
+
...props
|
|
9336
|
+
}
|
|
9337
|
+
);
|
|
9338
|
+
}
|
|
9339
|
+
function DrawerBody({ className, ...props }) {
|
|
9340
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9341
|
+
"div",
|
|
9342
|
+
{
|
|
9343
|
+
"data-slot": "drawer-body",
|
|
9344
|
+
className: cn("flex-1 overflow-y-auto px-6 pb-6", className),
|
|
9345
|
+
...props
|
|
9346
|
+
}
|
|
9347
|
+
);
|
|
9348
|
+
}
|
|
9349
|
+
function DrawerFooter({ className, ...props }) {
|
|
9350
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9351
|
+
"div",
|
|
9352
|
+
{
|
|
9353
|
+
"data-slot": "drawer-footer",
|
|
9354
|
+
className: cn(
|
|
9355
|
+
"border-border mt-auto flex shrink-0 flex-wrap items-center justify-end gap-2 border-t px-6 py-4",
|
|
9356
|
+
className
|
|
9357
|
+
),
|
|
9358
|
+
...props
|
|
9359
|
+
}
|
|
9360
|
+
);
|
|
9361
|
+
}
|
|
9362
|
+
function DrawerTitle({ className, ...props }) {
|
|
9363
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9364
|
+
radixUi.Dialog.Title,
|
|
9365
|
+
{
|
|
9366
|
+
"data-slot": "drawer-title",
|
|
9367
|
+
className: cn("font-heading text-base leading-none font-semibold", className),
|
|
9368
|
+
...props
|
|
9369
|
+
}
|
|
9370
|
+
);
|
|
9371
|
+
}
|
|
9372
|
+
function DrawerDescription({
|
|
9373
|
+
className,
|
|
9374
|
+
...props
|
|
9375
|
+
}) {
|
|
9376
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9377
|
+
radixUi.Dialog.Description,
|
|
9378
|
+
{
|
|
9379
|
+
"data-slot": "drawer-description",
|
|
9380
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
9381
|
+
...props
|
|
9382
|
+
}
|
|
9383
|
+
);
|
|
9384
|
+
}
|
|
8202
9385
|
function TCCEProvider({
|
|
8203
9386
|
children,
|
|
8204
9387
|
permissions,
|
|
@@ -8248,6 +9431,10 @@ exports.AvatarGroup = AvatarGroup;
|
|
|
8248
9431
|
exports.AvatarGroupCount = AvatarGroupCount;
|
|
8249
9432
|
exports.AvatarImage = AvatarImage;
|
|
8250
9433
|
exports.Badge = Badge2;
|
|
9434
|
+
exports.BottomNav = BottomNav;
|
|
9435
|
+
exports.BottomNavTabs = BottomNavTabs;
|
|
9436
|
+
exports.BottomNavTabsContent = BottomNavTabsContent;
|
|
9437
|
+
exports.BottomNavTabsList = BottomNavTabsList;
|
|
8251
9438
|
exports.Breadcrumb = Breadcrumb;
|
|
8252
9439
|
exports.BreadcrumbEllipsis = BreadcrumbEllipsis;
|
|
8253
9440
|
exports.BreadcrumbItem = BreadcrumbItem;
|
|
@@ -8256,8 +9443,6 @@ exports.BreadcrumbList = BreadcrumbList;
|
|
|
8256
9443
|
exports.BreadcrumbPage = BreadcrumbPage;
|
|
8257
9444
|
exports.BreadcrumbSeparator = BreadcrumbSeparator;
|
|
8258
9445
|
exports.Button = Button;
|
|
8259
|
-
exports.Calendar = Calendar;
|
|
8260
|
-
exports.CalendarDayButton = CalendarDayButton;
|
|
8261
9446
|
exports.Can = Can;
|
|
8262
9447
|
exports.CanNot = CanNot;
|
|
8263
9448
|
exports.Card = Card;
|
|
@@ -8303,6 +9488,17 @@ exports.DialogOverlay = DialogOverlay;
|
|
|
8303
9488
|
exports.DialogPortal = DialogPortal;
|
|
8304
9489
|
exports.DialogTitle = DialogTitle;
|
|
8305
9490
|
exports.DialogTrigger = DialogTrigger;
|
|
9491
|
+
exports.Drawer = Drawer;
|
|
9492
|
+
exports.DrawerBody = DrawerBody;
|
|
9493
|
+
exports.DrawerClose = DrawerClose;
|
|
9494
|
+
exports.DrawerContent = DrawerContent;
|
|
9495
|
+
exports.DrawerDescription = DrawerDescription;
|
|
9496
|
+
exports.DrawerFooter = DrawerFooter;
|
|
9497
|
+
exports.DrawerHeader = DrawerHeader;
|
|
9498
|
+
exports.DrawerOverlay = DrawerOverlay;
|
|
9499
|
+
exports.DrawerPortal = DrawerPortal;
|
|
9500
|
+
exports.DrawerTitle = DrawerTitle;
|
|
9501
|
+
exports.DrawerTrigger = DrawerTrigger;
|
|
8306
9502
|
exports.DropdownMenu = DropdownMenu;
|
|
8307
9503
|
exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem;
|
|
8308
9504
|
exports.DropdownMenuContent = DropdownMenuContent;
|
|
@@ -8345,6 +9541,8 @@ exports.ItemHeader = ItemHeader;
|
|
|
8345
9541
|
exports.ItemMedia = ItemMedia;
|
|
8346
9542
|
exports.ItemSeparator = ItemSeparator;
|
|
8347
9543
|
exports.ItemTitle = ItemTitle;
|
|
9544
|
+
exports.KNOWN_PERMISSIONS = KNOWN_PERMISSIONS;
|
|
9545
|
+
exports.Label = Label;
|
|
8348
9546
|
exports.Link = Link;
|
|
8349
9547
|
exports.Logo = Logo;
|
|
8350
9548
|
exports.MiniCalendar = MiniCalendar;
|
|
@@ -8367,6 +9565,7 @@ exports.PaginationItem = PaginationItem;
|
|
|
8367
9565
|
exports.PaginationLink = PaginationLink;
|
|
8368
9566
|
exports.PaginationNext = PaginationNext;
|
|
8369
9567
|
exports.PaginationPrevious = PaginationPrevious;
|
|
9568
|
+
exports.PhoneField = PhoneField;
|
|
8370
9569
|
exports.PinInput = PinInput;
|
|
8371
9570
|
exports.Popover = Popover;
|
|
8372
9571
|
exports.PopoverAnchor = PopoverAnchor;
|
|
@@ -8503,6 +9702,7 @@ exports.toggleVariants = toggleVariants;
|
|
|
8503
9702
|
exports.tooltipContentVariants = tooltipContentVariants;
|
|
8504
9703
|
exports.transition = transition;
|
|
8505
9704
|
exports.useAbility = useAbility;
|
|
9705
|
+
exports.useAbilityStatus = useAbilityStatus;
|
|
8506
9706
|
exports.useAppForm = useAppForm;
|
|
8507
9707
|
exports.useCan = useCan;
|
|
8508
9708
|
exports.useCarousel = useCarousel;
|
|
@@ -8517,5 +9717,6 @@ exports.useTableSizing = useTableSizing;
|
|
|
8517
9717
|
exports.useTableSorting = useTableSorting;
|
|
8518
9718
|
exports.useTableVisibility = useTableVisibility;
|
|
8519
9719
|
exports.useToast = useToast;
|
|
9720
|
+
exports.validatePhone = validatePhone;
|
|
8520
9721
|
//# sourceMappingURL=main.cjs.map
|
|
8521
9722
|
//# sourceMappingURL=main.cjs.map
|