@payglocal_ui/flux-ui 0.3.0 → 0.3.2
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/index.cjs +456 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -3
- package/dist/index.d.ts +62 -3
- package/dist/index.js +483 -250
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/copyable-cell-tooltip.test.tsx +81 -0
- package/src/__tests__/data-table-column-width.test.tsx +77 -0
- package/src/__tests__/date-picker-show-time.test.tsx +189 -0
- package/src/__tests__/picker-in-dialog.test.tsx +140 -0
- package/src/copyable-cell.tsx +65 -26
- package/src/data-table.tsx +65 -9
- package/src/date-picker.tsx +459 -126
- package/src/index.ts +1 -1
- package/src/time-picker.tsx +95 -66
package/dist/index.js
CHANGED
|
@@ -2568,7 +2568,7 @@ function useSpotlight(steps, initialStep = 0) {
|
|
|
2568
2568
|
else setCurrentStep((s) => s + 1);
|
|
2569
2569
|
},
|
|
2570
2570
|
goBack: () => setCurrentStep((s) => Math.max(0, s - 1)),
|
|
2571
|
-
goTo: (
|
|
2571
|
+
goTo: (step2) => setCurrentStep(Math.max(0, Math.min(step2, steps.length - 1)))
|
|
2572
2572
|
};
|
|
2573
2573
|
}
|
|
2574
2574
|
|
|
@@ -3613,20 +3613,20 @@ var Progress = React36.forwardRef(({ className, value, variant = "default", size
|
|
|
3613
3613
|
] }));
|
|
3614
3614
|
Progress.displayName = "Progress";
|
|
3615
3615
|
var ProgressTracker = React36.forwardRef(
|
|
3616
|
-
({ className, steps, ...props }, ref) => /* @__PURE__ */ jsx47("div", { ref, className: cn("flex items-start", className), ...props, children: steps.map((
|
|
3616
|
+
({ className, steps, ...props }, ref) => /* @__PURE__ */ jsx47("div", { ref, className: cn("flex items-start", className), ...props, children: steps.map((step2, i) => /* @__PURE__ */ jsxs28(React36.Fragment, { children: [
|
|
3617
3617
|
/* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-1.5 min-w-0", children: [
|
|
3618
3618
|
/* @__PURE__ */ jsx47("div", { className: cn(
|
|
3619
3619
|
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold transition-colors",
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
), children:
|
|
3620
|
+
step2.status === "complete" && "bg-primary border-primary text-primary-foreground",
|
|
3621
|
+
step2.status === "current" && "bg-primary/10 border-primary text-primary",
|
|
3622
|
+
step2.status === "upcoming" && "bg-card border-border text-muted-foreground"
|
|
3623
|
+
), children: step2.status === "complete" ? /* @__PURE__ */ jsx47(Check7, { className: "size-4", strokeWidth: 2.5 }) : i + 1 }),
|
|
3624
3624
|
/* @__PURE__ */ jsxs28("div", { className: "text-center px-1", children: [
|
|
3625
|
-
/* @__PURE__ */ jsx47("p", { className: cn("text-xs font-medium",
|
|
3626
|
-
|
|
3625
|
+
/* @__PURE__ */ jsx47("p", { className: cn("text-xs font-medium", step2.status === "upcoming" ? "text-muted-foreground" : "text-foreground"), children: step2.label }),
|
|
3626
|
+
step2.description && /* @__PURE__ */ jsx47("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: step2.description })
|
|
3627
3627
|
] })
|
|
3628
3628
|
] }),
|
|
3629
|
-
i < steps.length - 1 && /* @__PURE__ */ jsx47("div", { className: "flex-1 mt-4 mx-1", children: /* @__PURE__ */ jsx47("div", { className: cn("h-0.5 w-full rounded-full transition-colors",
|
|
3629
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx47("div", { className: "flex-1 mt-4 mx-1", children: /* @__PURE__ */ jsx47("div", { className: cn("h-0.5 w-full rounded-full transition-colors", step2.status === "complete" ? "bg-primary" : "bg-border") }) })
|
|
3630
3630
|
] }, i)) })
|
|
3631
3631
|
);
|
|
3632
3632
|
ProgressTracker.displayName = "ProgressTracker";
|
|
@@ -3786,6 +3786,32 @@ function SortIndicator({ order }) {
|
|
|
3786
3786
|
}
|
|
3787
3787
|
);
|
|
3788
3788
|
}
|
|
3789
|
+
function parseMinMaxWidth(width) {
|
|
3790
|
+
if (!width) return null;
|
|
3791
|
+
const match = /^minmax\(\s*([^,]+?)\s*,\s*([^)]+?)\s*\)$/.exec(width.trim());
|
|
3792
|
+
return match ? { min: match[1], max: match[2] } : null;
|
|
3793
|
+
}
|
|
3794
|
+
function isFlexUnit(value) {
|
|
3795
|
+
return /^[\d.]*fr$/.test(value.trim());
|
|
3796
|
+
}
|
|
3797
|
+
function colWidthStyle(col) {
|
|
3798
|
+
const parsed = parseMinMaxWidth(col.width);
|
|
3799
|
+
if (!parsed) {
|
|
3800
|
+
return {
|
|
3801
|
+
width: col.width ?? (col.minWidth != null ? `${col.minWidth}px` : void 0),
|
|
3802
|
+
minWidth: col.minWidth,
|
|
3803
|
+
maxWidth: col.maxWidth
|
|
3804
|
+
};
|
|
3805
|
+
}
|
|
3806
|
+
return {
|
|
3807
|
+
width: isFlexUnit(parsed.max) ? void 0 : parsed.max,
|
|
3808
|
+
// An explicit numeric `minWidth`/`maxWidth` alongside a `minmax()` string
|
|
3809
|
+
// is not a combination any caller uses today; the string wins because it
|
|
3810
|
+
// is the more specific of the two.
|
|
3811
|
+
minWidth: parsed.min,
|
|
3812
|
+
maxWidth: isFlexUnit(parsed.max) ? col.maxWidth : void 0
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3789
3815
|
function DataTable({
|
|
3790
3816
|
columns,
|
|
3791
3817
|
data,
|
|
@@ -3932,17 +3958,7 @@ function DataTable({
|
|
|
3932
3958
|
children: [
|
|
3933
3959
|
tableLayout === "fixed" && !isEmpty && /* @__PURE__ */ jsxs31("colgroup", { children: [
|
|
3934
3960
|
hasExpand ? /* @__PURE__ */ jsx50("col", { style: { width: 40 } }) : null,
|
|
3935
|
-
columns.map((col) => /* @__PURE__ */ jsx50(
|
|
3936
|
-
"col",
|
|
3937
|
-
{
|
|
3938
|
-
style: {
|
|
3939
|
-
width: col.width ?? (col.minWidth != null ? `${col.minWidth}px` : void 0),
|
|
3940
|
-
minWidth: col.minWidth,
|
|
3941
|
-
maxWidth: col.maxWidth
|
|
3942
|
-
}
|
|
3943
|
-
},
|
|
3944
|
-
col.key
|
|
3945
|
-
)),
|
|
3961
|
+
columns.map((col) => /* @__PURE__ */ jsx50("col", { style: colWidthStyle(col) }, col.key)),
|
|
3946
3962
|
hasAction ? /* @__PURE__ */ jsx50("col", { style: { width: 0 } }) : null
|
|
3947
3963
|
] }),
|
|
3948
3964
|
/* @__PURE__ */ jsx50(
|
|
@@ -4247,7 +4263,7 @@ var PAGE_BUTTON = "w-7 h-7 rounded-md flex items-center justify-center text-[12p
|
|
|
4247
4263
|
var PAGE_BUTTON_IDLE = "text-muted-foreground hover:text-foreground hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed";
|
|
4248
4264
|
var PAGE_BUTTON_ACTIVE = "bg-primary text-primary-foreground shadow-sm";
|
|
4249
4265
|
function DataTableFooter({
|
|
4250
|
-
pad:
|
|
4266
|
+
pad: pad3,
|
|
4251
4267
|
summary,
|
|
4252
4268
|
countLabels,
|
|
4253
4269
|
leading,
|
|
@@ -4288,7 +4304,7 @@ function DataTableFooter({
|
|
|
4288
4304
|
{
|
|
4289
4305
|
className: cn(
|
|
4290
4306
|
"flex items-center gap-4 flex-wrap border-t border-border",
|
|
4291
|
-
|
|
4307
|
+
pad3,
|
|
4292
4308
|
summary === "none" && !showRowsPerPage && !leading ? "justify-end" : "justify-between"
|
|
4293
4309
|
),
|
|
4294
4310
|
children: [
|
|
@@ -4636,7 +4652,7 @@ function CopyableCell({
|
|
|
4636
4652
|
valueClassName
|
|
4637
4653
|
);
|
|
4638
4654
|
const elided = display !== void 0 && display !== value;
|
|
4639
|
-
const copyHint = copied ? "Copied" :
|
|
4655
|
+
const copyHint = copied ? "Copied" : `Copy ${label}`;
|
|
4640
4656
|
if (variant === "cell") {
|
|
4641
4657
|
return /* @__PURE__ */ jsx53(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs34(Tooltip, { children: [
|
|
4642
4658
|
/* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs34(
|
|
@@ -4674,31 +4690,45 @@ function CopyableCell({
|
|
|
4674
4690
|
/* @__PURE__ */ jsx53(TooltipContent, { side: "top", className: "text-xs", children: copied ? "Copied" : "Copy" })
|
|
4675
4691
|
] }) });
|
|
4676
4692
|
}
|
|
4693
|
+
const valueNode = onClick ? (
|
|
4694
|
+
// A bare <button>, deliberately, where the rest of flux would reach for
|
|
4695
|
+
// `Button variant="link"`. That variant hard-codes `text-[15px]`, and
|
|
4696
|
+
// the obvious override — `text-[inherit]` — does not beat it: Tailwind
|
|
4697
|
+
// and tailwind-merge read `text-[<non-length>]` as a COLOUR, so the
|
|
4698
|
+
// size class survives and the cell renders 2px larger than every other
|
|
4699
|
+
// cell in the row. Preflight already gives a bare button `font: inherit`,
|
|
4700
|
+
// so this simply inherits the cell's size at whatever density the table
|
|
4701
|
+
// is using, which is what a cell should do.
|
|
4702
|
+
/* @__PURE__ */ jsx53(
|
|
4703
|
+
"button",
|
|
4704
|
+
{
|
|
4705
|
+
type: "button",
|
|
4706
|
+
onClick,
|
|
4707
|
+
title: elided ? void 0 : value,
|
|
4708
|
+
"aria-label": elided ? value : void 0,
|
|
4709
|
+
className: cn(
|
|
4710
|
+
"cursor-pointer bg-transparent p-0 text-left underline-offset-4",
|
|
4711
|
+
"hover:underline focus-visible:underline focus-visible:outline-none",
|
|
4712
|
+
text
|
|
4713
|
+
),
|
|
4714
|
+
children: display ?? value
|
|
4715
|
+
}
|
|
4716
|
+
)
|
|
4717
|
+
) : /* @__PURE__ */ jsx53(
|
|
4718
|
+
"span",
|
|
4719
|
+
{
|
|
4720
|
+
className: text,
|
|
4721
|
+
title: elided ? void 0 : value,
|
|
4722
|
+
"aria-hidden": elided || void 0,
|
|
4723
|
+
children: display ?? value
|
|
4724
|
+
}
|
|
4725
|
+
);
|
|
4677
4726
|
return /* @__PURE__ */ jsxs34("div", { className: cn("group/copy flex min-w-0 items-center gap-1", className), children: [
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
// size class survives and the cell renders 2px larger than every other
|
|
4684
|
-
// cell in the row. Preflight already gives a bare button `font: inherit`,
|
|
4685
|
-
// so this simply inherits the cell's size at whatever density the table
|
|
4686
|
-
// is using, which is what a cell should do.
|
|
4687
|
-
/* @__PURE__ */ jsx53(
|
|
4688
|
-
"button",
|
|
4689
|
-
{
|
|
4690
|
-
type: "button",
|
|
4691
|
-
onClick,
|
|
4692
|
-
title: value,
|
|
4693
|
-
className: cn(
|
|
4694
|
-
"cursor-pointer bg-transparent p-0 text-left underline-offset-4",
|
|
4695
|
-
"hover:underline focus-visible:underline focus-visible:outline-none",
|
|
4696
|
-
text
|
|
4697
|
-
),
|
|
4698
|
-
children: display ?? value
|
|
4699
|
-
}
|
|
4700
|
-
)
|
|
4701
|
-
) : /* @__PURE__ */ jsx53("span", { className: text, title: value, children: display ?? value }),
|
|
4727
|
+
elided ? /* @__PURE__ */ jsx53(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs34(Tooltip, { children: [
|
|
4728
|
+
/* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: valueNode }),
|
|
4729
|
+
/* @__PURE__ */ jsx53(TooltipContent, { side: "top", className: "text-xs", children: value })
|
|
4730
|
+
] }) }) : valueNode,
|
|
4731
|
+
elided && !onClick && /* @__PURE__ */ jsx53("span", { className: "sr-only", children: value }),
|
|
4702
4732
|
/* @__PURE__ */ jsx53(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs34(Tooltip, { children: [
|
|
4703
4733
|
/* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx53(
|
|
4704
4734
|
Button,
|
|
@@ -5652,11 +5682,12 @@ function CalendarDayButton({
|
|
|
5652
5682
|
}
|
|
5653
5683
|
|
|
5654
5684
|
// src/date-picker.tsx
|
|
5655
|
-
import { useState as useState12, useRef as useRef8, useEffect as useEffect8 } from "react";
|
|
5685
|
+
import { useState as useState12, useRef as useRef8, useEffect as useEffect8, useMemo as useMemo7, useCallback as useCallback5 } from "react";
|
|
5656
5686
|
import { createPortal } from "react-dom";
|
|
5687
|
+
import { RemoveScroll } from "react-remove-scroll";
|
|
5657
5688
|
import { ChevronLeft as ChevronLeft6, ChevronRight as ChevronRight8, ChevronDown as ChevronDown8, CalendarDays } from "lucide-react";
|
|
5658
5689
|
import { AnimatePresence, motion } from "framer-motion";
|
|
5659
|
-
import { jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
5690
|
+
import { Fragment as Fragment8, jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
5660
5691
|
var MONTHS = [
|
|
5661
5692
|
"January",
|
|
5662
5693
|
"February",
|
|
@@ -5673,30 +5704,117 @@ var MONTHS = [
|
|
|
5673
5704
|
];
|
|
5674
5705
|
var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
5675
5706
|
var PRIMARY = "#0061E3";
|
|
5676
|
-
var
|
|
5707
|
+
var CALENDAR_W = 296;
|
|
5708
|
+
var TIME_COL_W = 58;
|
|
5709
|
+
var TIME_ITEM_H = 28;
|
|
5710
|
+
var TIME_COL_H = 232;
|
|
5677
5711
|
function daysInMonth(y, m) {
|
|
5678
5712
|
return new Date(y, m + 1, 0).getDate();
|
|
5679
5713
|
}
|
|
5680
5714
|
function firstDayOf(y, m) {
|
|
5681
5715
|
return new Date(y, m, 1).getDay();
|
|
5682
5716
|
}
|
|
5683
|
-
function
|
|
5717
|
+
function pad(n) {
|
|
5718
|
+
return String(n).padStart(2, "0");
|
|
5719
|
+
}
|
|
5720
|
+
function parseValue(s) {
|
|
5684
5721
|
if (!s) return null;
|
|
5685
|
-
const [
|
|
5722
|
+
const [datePart, timePart = ""] = s.trim().split(/[ T]/);
|
|
5723
|
+
const [y, m, d] = datePart.split("-").map(Number);
|
|
5686
5724
|
if (!y || !m || !d) return null;
|
|
5687
|
-
|
|
5725
|
+
const [hh = 0, mm = 0, ss = 0] = timePart ? timePart.split(":").map(Number) : [];
|
|
5726
|
+
return {
|
|
5727
|
+
y,
|
|
5728
|
+
m: m - 1,
|
|
5729
|
+
d,
|
|
5730
|
+
hh: Number.isFinite(hh) ? hh : 0,
|
|
5731
|
+
mm: Number.isFinite(mm) ? mm : 0,
|
|
5732
|
+
ss: Number.isFinite(ss) ? ss : 0
|
|
5733
|
+
};
|
|
5734
|
+
}
|
|
5735
|
+
function parseYMD(s) {
|
|
5736
|
+
const p = parseValue(s);
|
|
5737
|
+
return p ? { y: p.y, m: p.m, d: p.d } : null;
|
|
5688
5738
|
}
|
|
5689
5739
|
function toYMD(y, m, d) {
|
|
5690
|
-
return `${y}-${
|
|
5740
|
+
return `${y}-${pad(m + 1)}-${pad(d)}`;
|
|
5691
5741
|
}
|
|
5692
|
-
function
|
|
5693
|
-
const
|
|
5742
|
+
function formatValue(p, showTime, showSecond) {
|
|
5743
|
+
const date = toYMD(p.y, p.m, p.d);
|
|
5744
|
+
if (!showTime) return date;
|
|
5745
|
+
return showSecond ? `${date} ${pad(p.hh)}:${pad(p.mm)}:${pad(p.ss)}` : `${date} ${pad(p.hh)}:${pad(p.mm)}`;
|
|
5746
|
+
}
|
|
5747
|
+
function displayTime(p, showSecond) {
|
|
5748
|
+
const period = p.hh < 12 ? "AM" : "PM";
|
|
5749
|
+
const h12 = p.hh % 12 === 0 ? 12 : p.hh % 12;
|
|
5750
|
+
const base = showSecond ? `${pad(h12)}:${pad(p.mm)}:${pad(p.ss)}` : `${pad(h12)}:${pad(p.mm)}`;
|
|
5751
|
+
return `${base} ${period}`;
|
|
5752
|
+
}
|
|
5753
|
+
function displayValue(value, showTime, showSecond) {
|
|
5754
|
+
const p = parseValue(value);
|
|
5694
5755
|
if (!p) return "";
|
|
5695
|
-
|
|
5756
|
+
const date = `${pad(p.d)} ${MONTHS[p.m].slice(0, 3)} ${p.y}`;
|
|
5757
|
+
return showTime ? `${date}, ${displayTime(p, showSecond)}` : date;
|
|
5758
|
+
}
|
|
5759
|
+
function step(n) {
|
|
5760
|
+
return Math.max(1, Math.floor(n ?? 1));
|
|
5761
|
+
}
|
|
5762
|
+
function TimeColumn({
|
|
5763
|
+
label,
|
|
5764
|
+
items,
|
|
5765
|
+
selected,
|
|
5766
|
+
onSelect,
|
|
5767
|
+
render
|
|
5768
|
+
}) {
|
|
5769
|
+
const ref = useRef8(null);
|
|
5770
|
+
const index = items.indexOf(selected);
|
|
5771
|
+
useEffect8(() => {
|
|
5772
|
+
const el = ref.current;
|
|
5773
|
+
if (!el || index < 0) return;
|
|
5774
|
+
el.scrollTo({ top: index * TIME_ITEM_H, behavior: "smooth" });
|
|
5775
|
+
}, [index]);
|
|
5776
|
+
return /* @__PURE__ */ jsxs41("div", { className: "flex flex-col border-l border-border", style: { width: TIME_COL_W }, children: [
|
|
5777
|
+
/* @__PURE__ */ jsx62("div", { className: "py-1 text-center text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/70", children: label }),
|
|
5778
|
+
/* @__PURE__ */ jsxs41(
|
|
5779
|
+
"div",
|
|
5780
|
+
{
|
|
5781
|
+
ref,
|
|
5782
|
+
className: "overflow-y-auto",
|
|
5783
|
+
style: { height: TIME_COL_H, scrollbarWidth: "none", msOverflowStyle: "none" },
|
|
5784
|
+
children: [
|
|
5785
|
+
items.map((item) => {
|
|
5786
|
+
const active = item === selected;
|
|
5787
|
+
return /* @__PURE__ */ jsx62(
|
|
5788
|
+
"button",
|
|
5789
|
+
{
|
|
5790
|
+
type: "button",
|
|
5791
|
+
onClick: () => onSelect(item),
|
|
5792
|
+
className: cn(
|
|
5793
|
+
"flex w-full items-center justify-center rounded-md text-[13px] font-medium transition-colors",
|
|
5794
|
+
active ? "font-semibold text-white" : "text-foreground hover:bg-muted"
|
|
5795
|
+
),
|
|
5796
|
+
style: { height: TIME_ITEM_H, background: active ? PRIMARY : void 0 },
|
|
5797
|
+
children: render ? render(item) : String(item)
|
|
5798
|
+
},
|
|
5799
|
+
String(item)
|
|
5800
|
+
);
|
|
5801
|
+
}),
|
|
5802
|
+
/* @__PURE__ */ jsx62("div", { style: { height: TIME_COL_H - TIME_ITEM_H } })
|
|
5803
|
+
]
|
|
5804
|
+
}
|
|
5805
|
+
)
|
|
5806
|
+
] });
|
|
5696
5807
|
}
|
|
5697
|
-
function DatePicker({ value, onChange, placeholder = "Select date", className, min, max, label }) {
|
|
5808
|
+
function DatePicker({ value, onChange, placeholder = "Select date", className, min, max, label, showTime = false, showNow = true }) {
|
|
5698
5809
|
const today = /* @__PURE__ */ new Date();
|
|
5699
|
-
const parsed =
|
|
5810
|
+
const parsed = parseValue(value);
|
|
5811
|
+
const timeOptions = useMemo7(
|
|
5812
|
+
() => typeof showTime === "object" ? showTime : {},
|
|
5813
|
+
[showTime]
|
|
5814
|
+
);
|
|
5815
|
+
const withTime = showTime !== false && showTime !== void 0;
|
|
5816
|
+
const use12Hours = timeOptions.use12Hours ?? true;
|
|
5817
|
+
const showSecond = timeOptions.showSecond ?? false;
|
|
5700
5818
|
const [open, setOpen] = useState12(false);
|
|
5701
5819
|
const [panelPos, setPanelPos] = useState12({ top: 0, left: 0 });
|
|
5702
5820
|
const [viewYear, setViewYear] = useState12(parsed?.y ?? today.getFullYear());
|
|
@@ -5715,34 +5833,39 @@ function DatePicker({ value, onChange, placeholder = "Select date", className, m
|
|
|
5715
5833
|
setViewMonth(parsed.m);
|
|
5716
5834
|
}
|
|
5717
5835
|
}, [value]);
|
|
5836
|
+
const columnCount = withTime ? (showSecond ? 3 : 2) + (use12Hours ? 1 : 0) : 0;
|
|
5837
|
+
const PANEL_W2 = CALENDAR_W + columnCount * TIME_COL_W;
|
|
5838
|
+
const PANEL_H2 = withTime ? 392 : 340;
|
|
5718
5839
|
function openPanel() {
|
|
5719
5840
|
if (!triggerRef.current) return;
|
|
5720
5841
|
const trigger = triggerRef.current;
|
|
5721
5842
|
const vw = window.innerWidth;
|
|
5722
5843
|
const vh = window.innerHeight;
|
|
5723
|
-
const PANEL_H2 = 340;
|
|
5724
5844
|
trigger.scrollIntoView({ block: "center", behavior: "auto" });
|
|
5725
5845
|
requestAnimationFrame(() => {
|
|
5726
5846
|
if (!triggerRef.current) return;
|
|
5727
5847
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
5728
5848
|
let left = rect.left;
|
|
5729
|
-
if (left +
|
|
5849
|
+
if (left + PANEL_W2 > vw - 8) left = vw - PANEL_W2 - 8;
|
|
5850
|
+
if (left < 8) left = 8;
|
|
5730
5851
|
let top = rect.bottom + 6;
|
|
5731
5852
|
if (top + PANEL_H2 > vh - 8) top = rect.top - PANEL_H2 - 6;
|
|
5853
|
+
if (top < 8) top = 8;
|
|
5732
5854
|
setPanelPos({ top, left });
|
|
5733
5855
|
setOpen(true);
|
|
5734
5856
|
});
|
|
5735
5857
|
}
|
|
5858
|
+
function closePanel() {
|
|
5859
|
+
setOpen(false);
|
|
5860
|
+
setYearMenu(false);
|
|
5861
|
+
setMonthMenu(false);
|
|
5862
|
+
}
|
|
5736
5863
|
useEffect8(() => {
|
|
5737
5864
|
if (!open) return;
|
|
5738
5865
|
function handler(e) {
|
|
5739
5866
|
const inTrigger = triggerRef.current?.contains(e.target);
|
|
5740
5867
|
const inPanel = panelRef.current?.contains(e.target);
|
|
5741
|
-
if (!inTrigger && !inPanel)
|
|
5742
|
-
setOpen(false);
|
|
5743
|
-
setYearMenu(false);
|
|
5744
|
-
setMonthMenu(false);
|
|
5745
|
-
}
|
|
5868
|
+
if (!inTrigger && !inPanel) closePanel();
|
|
5746
5869
|
}
|
|
5747
5870
|
document.addEventListener("mousedown", handler);
|
|
5748
5871
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -5785,18 +5908,251 @@ function DatePicker({ value, onChange, placeholder = "Select date", className, m
|
|
|
5785
5908
|
cells.push({ d, m, y, current: false });
|
|
5786
5909
|
}
|
|
5787
5910
|
const years = Array.from({ length: 15 }, (_, i) => today.getFullYear() - 2 + i);
|
|
5911
|
+
const fallback = parseValue(`2000-01-01 ${timeOptions.defaultValue ?? "00:00"}`);
|
|
5912
|
+
const current = parsed ?? {
|
|
5913
|
+
y: today.getFullYear(),
|
|
5914
|
+
m: today.getMonth(),
|
|
5915
|
+
d: today.getDate(),
|
|
5916
|
+
hh: fallback.hh,
|
|
5917
|
+
mm: fallback.mm,
|
|
5918
|
+
ss: fallback.ss
|
|
5919
|
+
};
|
|
5920
|
+
const emit = useCallback5(
|
|
5921
|
+
(next) => onChange(formatValue(next, withTime, showSecond)),
|
|
5922
|
+
[onChange, withTime, showSecond]
|
|
5923
|
+
);
|
|
5924
|
+
function patchTime(patch) {
|
|
5925
|
+
emit({ ...current, ...patch });
|
|
5926
|
+
}
|
|
5927
|
+
const hourStep = step(timeOptions.hourStep);
|
|
5928
|
+
const minuteStep = step(timeOptions.minuteStep);
|
|
5929
|
+
const secondStep = step(timeOptions.secondStep);
|
|
5930
|
+
const hourItems = use12Hours ? Array.from({ length: Math.ceil(12 / hourStep) }, (_, i) => i * hourStep % 12) : Array.from({ length: Math.ceil(24 / hourStep) }, (_, i) => i * hourStep);
|
|
5931
|
+
const minuteItems = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => i * minuteStep);
|
|
5932
|
+
const secondItems = Array.from({ length: Math.ceil(60 / secondStep) }, (_, i) => i * secondStep);
|
|
5933
|
+
const selectedHour = use12Hours ? current.hh % 12 : current.hh;
|
|
5934
|
+
const selectedMeridiem = current.hh < 12 ? "AM" : "PM";
|
|
5935
|
+
function selectHour(h) {
|
|
5936
|
+
if (!use12Hours) return patchTime({ hh: h });
|
|
5937
|
+
patchTime({ hh: selectedMeridiem === "AM" ? h : h + 12 });
|
|
5938
|
+
}
|
|
5939
|
+
function selectMeridiem(p) {
|
|
5940
|
+
const base = current.hh % 12;
|
|
5941
|
+
patchTime({ hh: p === "AM" ? base : base + 12 });
|
|
5942
|
+
}
|
|
5788
5943
|
function selectDay(cell) {
|
|
5789
5944
|
if (!cell.current) {
|
|
5790
5945
|
setViewYear(cell.y);
|
|
5791
5946
|
setViewMonth(cell.m);
|
|
5792
5947
|
}
|
|
5793
5948
|
if (cell.current && isDisabled(cell.y, cell.m, cell.d)) return;
|
|
5794
|
-
|
|
5795
|
-
setOpen(false);
|
|
5949
|
+
emit({ y: cell.y, m: cell.m, d: cell.d, hh: current.hh, mm: current.mm, ss: current.ss });
|
|
5950
|
+
if (!withTime) setOpen(false);
|
|
5951
|
+
}
|
|
5952
|
+
function selectNow() {
|
|
5953
|
+
const n = /* @__PURE__ */ new Date();
|
|
5954
|
+
if (isDisabled(n.getFullYear(), n.getMonth(), n.getDate())) return;
|
|
5955
|
+
emit({
|
|
5956
|
+
y: n.getFullYear(),
|
|
5957
|
+
m: n.getMonth(),
|
|
5958
|
+
d: n.getDate(),
|
|
5959
|
+
hh: n.getHours(),
|
|
5960
|
+
mm: n.getMinutes(),
|
|
5961
|
+
ss: n.getSeconds()
|
|
5962
|
+
});
|
|
5963
|
+
closePanel();
|
|
5796
5964
|
}
|
|
5797
5965
|
const isToday = (c) => c.d === today.getDate() && c.m === today.getMonth() && c.y === today.getFullYear();
|
|
5798
5966
|
const isSelected = (c) => !!parsed && c.d === parsed.d && c.m === parsed.m && c.y === parsed.y;
|
|
5799
|
-
const
|
|
5967
|
+
const calendar = /* @__PURE__ */ jsxs41("div", { style: { width: CALENDAR_W }, className: "flex flex-col", children: [
|
|
5968
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between px-4 pt-4 pb-3", children: [
|
|
5969
|
+
/* @__PURE__ */ jsx62(
|
|
5970
|
+
"button",
|
|
5971
|
+
{
|
|
5972
|
+
type: "button",
|
|
5973
|
+
onClick: prevMonth,
|
|
5974
|
+
className: "w-8 h-8 rounded-full flex items-center justify-center text-muted-foreground hover:bg-muted transition-colors",
|
|
5975
|
+
children: /* @__PURE__ */ jsx62(ChevronLeft6, { className: "w-4 h-4" })
|
|
5976
|
+
}
|
|
5977
|
+
),
|
|
5978
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-1", children: [
|
|
5979
|
+
/* @__PURE__ */ jsxs41("div", { className: "relative", children: [
|
|
5980
|
+
/* @__PURE__ */ jsxs41(
|
|
5981
|
+
"button",
|
|
5982
|
+
{
|
|
5983
|
+
type: "button",
|
|
5984
|
+
onClick: () => {
|
|
5985
|
+
setMonthMenu((o) => !o);
|
|
5986
|
+
setYearMenu(false);
|
|
5987
|
+
},
|
|
5988
|
+
className: "flex items-center gap-1 px-2 py-1 rounded-lg text-[14px] font-semibold text-foreground hover:bg-muted transition-colors",
|
|
5989
|
+
children: [
|
|
5990
|
+
MONTHS[viewMonth].slice(0, 3),
|
|
5991
|
+
/* @__PURE__ */ jsx62(ChevronDown8, { className: "w-3 h-3 text-muted-foreground" })
|
|
5992
|
+
]
|
|
5993
|
+
}
|
|
5994
|
+
),
|
|
5995
|
+
/* @__PURE__ */ jsx62(AnimatePresence, { children: monthMenu && /* @__PURE__ */ jsx62(
|
|
5996
|
+
motion.div,
|
|
5997
|
+
{
|
|
5998
|
+
initial: { opacity: 0, y: -4 },
|
|
5999
|
+
animate: { opacity: 1, y: 0 },
|
|
6000
|
+
exit: { opacity: 0, y: -4 },
|
|
6001
|
+
transition: { duration: 0.12 },
|
|
6002
|
+
className: "absolute top-full left-0 z-[10000] mt-1 max-h-[220px] min-w-[130px] overflow-y-auto rounded-xl border border-border bg-popover py-1 shadow-lg",
|
|
6003
|
+
children: MONTHS.map((mn, mi) => /* @__PURE__ */ jsx62(
|
|
6004
|
+
"button",
|
|
6005
|
+
{
|
|
6006
|
+
type: "button",
|
|
6007
|
+
onClick: () => {
|
|
6008
|
+
setViewMonth(mi);
|
|
6009
|
+
setMonthMenu(false);
|
|
6010
|
+
},
|
|
6011
|
+
className: "w-full px-3 py-2 text-left text-[13px] text-foreground transition-colors hover:bg-muted",
|
|
6012
|
+
style: { fontWeight: mi === viewMonth ? 600 : 400, color: mi === viewMonth ? PRIMARY : void 0 },
|
|
6013
|
+
children: mn
|
|
6014
|
+
},
|
|
6015
|
+
mn
|
|
6016
|
+
))
|
|
6017
|
+
}
|
|
6018
|
+
) })
|
|
6019
|
+
] }),
|
|
6020
|
+
/* @__PURE__ */ jsxs41("div", { className: "relative", children: [
|
|
6021
|
+
/* @__PURE__ */ jsxs41(
|
|
6022
|
+
"button",
|
|
6023
|
+
{
|
|
6024
|
+
type: "button",
|
|
6025
|
+
onClick: () => {
|
|
6026
|
+
setYearMenu((o) => !o);
|
|
6027
|
+
setMonthMenu(false);
|
|
6028
|
+
},
|
|
6029
|
+
className: "flex items-center gap-1 px-2 py-1 rounded-lg text-[14px] font-semibold text-foreground hover:bg-muted transition-colors",
|
|
6030
|
+
children: [
|
|
6031
|
+
viewYear,
|
|
6032
|
+
/* @__PURE__ */ jsx62(ChevronDown8, { className: "w-3 h-3 text-muted-foreground" })
|
|
6033
|
+
]
|
|
6034
|
+
}
|
|
6035
|
+
),
|
|
6036
|
+
/* @__PURE__ */ jsx62(AnimatePresence, { children: yearMenu && /* @__PURE__ */ jsx62(
|
|
6037
|
+
motion.div,
|
|
6038
|
+
{
|
|
6039
|
+
initial: { opacity: 0, y: -4 },
|
|
6040
|
+
animate: { opacity: 1, y: 0 },
|
|
6041
|
+
exit: { opacity: 0, y: -4 },
|
|
6042
|
+
transition: { duration: 0.12 },
|
|
6043
|
+
className: "absolute top-full left-0 z-[10000] mt-1 max-h-[200px] min-w-[90px] overflow-y-auto rounded-xl border border-border bg-popover py-1 shadow-lg",
|
|
6044
|
+
children: years.map((yr) => /* @__PURE__ */ jsx62(
|
|
6045
|
+
"button",
|
|
6046
|
+
{
|
|
6047
|
+
type: "button",
|
|
6048
|
+
onClick: () => {
|
|
6049
|
+
setViewYear(yr);
|
|
6050
|
+
setYearMenu(false);
|
|
6051
|
+
},
|
|
6052
|
+
className: "w-full px-3 py-2 text-left text-[13px] text-foreground transition-colors hover:bg-muted",
|
|
6053
|
+
style: { fontWeight: yr === viewYear ? 600 : 400, color: yr === viewYear ? PRIMARY : void 0 },
|
|
6054
|
+
children: yr
|
|
6055
|
+
},
|
|
6056
|
+
yr
|
|
6057
|
+
))
|
|
6058
|
+
}
|
|
6059
|
+
) })
|
|
6060
|
+
] })
|
|
6061
|
+
] }),
|
|
6062
|
+
/* @__PURE__ */ jsx62(
|
|
6063
|
+
"button",
|
|
6064
|
+
{
|
|
6065
|
+
type: "button",
|
|
6066
|
+
onClick: nextMonth,
|
|
6067
|
+
className: "w-8 h-8 rounded-full flex items-center justify-center text-muted-foreground hover:bg-muted transition-colors",
|
|
6068
|
+
children: /* @__PURE__ */ jsx62(ChevronRight8, { className: "w-4 h-4" })
|
|
6069
|
+
}
|
|
6070
|
+
)
|
|
6071
|
+
] }),
|
|
6072
|
+
/* @__PURE__ */ jsx62(
|
|
6073
|
+
"div",
|
|
6074
|
+
{
|
|
6075
|
+
className: "px-3 pb-1",
|
|
6076
|
+
style: { display: "grid", gridTemplateColumns: "repeat(7, minmax(0, 1fr))" },
|
|
6077
|
+
children: DAYS.map((d) => /* @__PURE__ */ jsx62("div", { className: "py-1 text-center text-[11.5px] font-semibold text-muted-foreground", children: d }, d))
|
|
6078
|
+
}
|
|
6079
|
+
),
|
|
6080
|
+
/* @__PURE__ */ jsx62(
|
|
6081
|
+
"div",
|
|
6082
|
+
{
|
|
6083
|
+
className: "gap-y-0.5 px-3 pb-4",
|
|
6084
|
+
style: { display: "grid", gridTemplateColumns: "repeat(7, minmax(0, 1fr))" },
|
|
6085
|
+
children: cells.map((cell, i) => {
|
|
6086
|
+
const selected = isSelected(cell);
|
|
6087
|
+
const tod = isToday(cell);
|
|
6088
|
+
const disabled = cell.current && isDisabled(cell.y, cell.m, cell.d);
|
|
6089
|
+
return /* @__PURE__ */ jsx62(
|
|
6090
|
+
"button",
|
|
6091
|
+
{
|
|
6092
|
+
type: "button",
|
|
6093
|
+
onClick: () => selectDay(cell),
|
|
6094
|
+
disabled,
|
|
6095
|
+
className: cn(
|
|
6096
|
+
"h-9 w-9 mx-auto rounded-full text-[13px] font-medium flex items-center justify-center transition-all",
|
|
6097
|
+
selected && "text-white font-semibold",
|
|
6098
|
+
!selected && tod && "font-semibold",
|
|
6099
|
+
!selected && !tod && cell.current && !disabled && "text-gray-800 hover:bg-gray-100",
|
|
6100
|
+
!selected && !cell.current && "text-gray-300 hover:bg-gray-50",
|
|
6101
|
+
disabled && "opacity-30 cursor-not-allowed"
|
|
6102
|
+
),
|
|
6103
|
+
style: selected ? { background: PRIMARY } : tod ? { background: `${PRIMARY}18`, color: PRIMARY } : {},
|
|
6104
|
+
children: cell.d
|
|
6105
|
+
},
|
|
6106
|
+
i
|
|
6107
|
+
);
|
|
6108
|
+
})
|
|
6109
|
+
}
|
|
6110
|
+
)
|
|
6111
|
+
] });
|
|
6112
|
+
const timeColumns = withTime && /* @__PURE__ */ jsxs41("div", { className: "flex pt-3", children: [
|
|
6113
|
+
/* @__PURE__ */ jsx62(
|
|
6114
|
+
TimeColumn,
|
|
6115
|
+
{
|
|
6116
|
+
label: "Hr",
|
|
6117
|
+
items: hourItems,
|
|
6118
|
+
selected: selectedHour,
|
|
6119
|
+
onSelect: selectHour,
|
|
6120
|
+
render: (h) => pad(use12Hours && h === 0 ? 12 : h)
|
|
6121
|
+
}
|
|
6122
|
+
),
|
|
6123
|
+
/* @__PURE__ */ jsx62(TimeColumn, { label: "Min", items: minuteItems, selected: current.mm, onSelect: (m) => patchTime({ mm: m }), render: pad }),
|
|
6124
|
+
showSecond && /* @__PURE__ */ jsx62(TimeColumn, { label: "Sec", items: secondItems, selected: current.ss, onSelect: (s) => patchTime({ ss: s }), render: pad }),
|
|
6125
|
+
use12Hours && /* @__PURE__ */ jsx62(TimeColumn, { label: "AM/PM", items: ["AM", "PM"], selected: selectedMeridiem, onSelect: selectMeridiem })
|
|
6126
|
+
] });
|
|
6127
|
+
const body = /* @__PURE__ */ jsxs41(Fragment8, { children: [
|
|
6128
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex", children: [
|
|
6129
|
+
calendar,
|
|
6130
|
+
timeColumns
|
|
6131
|
+
] }),
|
|
6132
|
+
withTime && /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between border-t border-border px-4 py-2.5", children: [
|
|
6133
|
+
showNow ? /* @__PURE__ */ jsx62(
|
|
6134
|
+
"button",
|
|
6135
|
+
{
|
|
6136
|
+
type: "button",
|
|
6137
|
+
onClick: selectNow,
|
|
6138
|
+
className: "rounded-md px-1 text-[13px] font-medium transition-colors hover:underline",
|
|
6139
|
+
style: { color: PRIMARY },
|
|
6140
|
+
children: "Now"
|
|
6141
|
+
}
|
|
6142
|
+
) : /* @__PURE__ */ jsx62("span", {}),
|
|
6143
|
+
/* @__PURE__ */ jsx62(
|
|
6144
|
+
"button",
|
|
6145
|
+
{
|
|
6146
|
+
type: "button",
|
|
6147
|
+
onClick: closePanel,
|
|
6148
|
+
className: "rounded-lg px-3 py-1.5 text-[13px] font-semibold text-white transition-opacity hover:opacity-90",
|
|
6149
|
+
style: { background: PRIMARY },
|
|
6150
|
+
children: "OK"
|
|
6151
|
+
}
|
|
6152
|
+
)
|
|
6153
|
+
] })
|
|
6154
|
+
] });
|
|
6155
|
+
const panel = /* @__PURE__ */ jsx62(AnimatePresence, { children: open && /* @__PURE__ */ jsx62(
|
|
5800
6156
|
motion.div,
|
|
5801
6157
|
{
|
|
5802
6158
|
ref: panelRef,
|
|
@@ -5809,149 +6165,21 @@ function DatePicker({ value, onChange, placeholder = "Select date", className, m
|
|
|
5809
6165
|
position: "fixed",
|
|
5810
6166
|
top: panelPos.top,
|
|
5811
6167
|
left: panelPos.left,
|
|
5812
|
-
width:
|
|
6168
|
+
width: PANEL_W2,
|
|
5813
6169
|
zIndex: 2e4,
|
|
6170
|
+
// A modal Radix Dialog sets `pointer-events: none` on <body> while
|
|
6171
|
+
// it is open, and this panel is portaled to <body> — so without
|
|
6172
|
+
// this every click on a day landed on nothing and the calendar
|
|
6173
|
+
// looked frozen inside a Dialog or Drawer. Hit-testing is
|
|
6174
|
+
// per-element, so re-enabling it here is enough; the page behind
|
|
6175
|
+
// the dialog stays inert. The click still reaches the dialog's
|
|
6176
|
+
// DismissableLayer through React's portal event propagation, so it
|
|
6177
|
+
// is treated as inside and does not dismiss the dialog.
|
|
6178
|
+
pointerEvents: "auto",
|
|
5814
6179
|
backgroundColor: "var(--popover)",
|
|
5815
6180
|
boxShadow: "0 16px 40px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.07)"
|
|
5816
6181
|
},
|
|
5817
|
-
children:
|
|
5818
|
-
/* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between px-4 pt-4 pb-3", children: [
|
|
5819
|
-
/* @__PURE__ */ jsx62(
|
|
5820
|
-
"button",
|
|
5821
|
-
{
|
|
5822
|
-
onClick: prevMonth,
|
|
5823
|
-
className: "w-8 h-8 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 transition-colors",
|
|
5824
|
-
children: /* @__PURE__ */ jsx62(ChevronLeft6, { className: "w-4 h-4" })
|
|
5825
|
-
}
|
|
5826
|
-
),
|
|
5827
|
-
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-1", children: [
|
|
5828
|
-
/* @__PURE__ */ jsxs41("div", { className: "relative", children: [
|
|
5829
|
-
/* @__PURE__ */ jsxs41(
|
|
5830
|
-
"button",
|
|
5831
|
-
{
|
|
5832
|
-
onClick: () => {
|
|
5833
|
-
setMonthMenu((o) => !o);
|
|
5834
|
-
setYearMenu(false);
|
|
5835
|
-
},
|
|
5836
|
-
className: "flex items-center gap-1 px-2 py-1 rounded-lg text-[14px] font-semibold text-gray-900 hover:bg-gray-100 transition-colors",
|
|
5837
|
-
children: [
|
|
5838
|
-
MONTHS[viewMonth].slice(0, 3),
|
|
5839
|
-
/* @__PURE__ */ jsx62(ChevronDown8, { className: "w-3 h-3 text-gray-400" })
|
|
5840
|
-
]
|
|
5841
|
-
}
|
|
5842
|
-
),
|
|
5843
|
-
/* @__PURE__ */ jsx62(AnimatePresence, { children: monthMenu && /* @__PURE__ */ jsx62(
|
|
5844
|
-
motion.div,
|
|
5845
|
-
{
|
|
5846
|
-
initial: { opacity: 0, y: -4 },
|
|
5847
|
-
animate: { opacity: 1, y: 0 },
|
|
5848
|
-
exit: { opacity: 0, y: -4 },
|
|
5849
|
-
transition: { duration: 0.12 },
|
|
5850
|
-
className: "absolute top-full left-0 z-[10000] mt-1 max-h-[220px] min-w-[130px] overflow-y-auto rounded-xl border border-border bg-popover py-1 shadow-lg",
|
|
5851
|
-
children: MONTHS.map((mn, mi) => /* @__PURE__ */ jsx62(
|
|
5852
|
-
"button",
|
|
5853
|
-
{
|
|
5854
|
-
onClick: () => {
|
|
5855
|
-
setViewMonth(mi);
|
|
5856
|
-
setMonthMenu(false);
|
|
5857
|
-
},
|
|
5858
|
-
className: "w-full px-3 py-2 text-left text-[13px] text-foreground transition-colors hover:bg-muted",
|
|
5859
|
-
style: { fontWeight: mi === viewMonth ? 600 : 400, color: mi === viewMonth ? PRIMARY : void 0 },
|
|
5860
|
-
children: mn
|
|
5861
|
-
},
|
|
5862
|
-
mn
|
|
5863
|
-
))
|
|
5864
|
-
}
|
|
5865
|
-
) })
|
|
5866
|
-
] }),
|
|
5867
|
-
/* @__PURE__ */ jsxs41("div", { className: "relative", children: [
|
|
5868
|
-
/* @__PURE__ */ jsxs41(
|
|
5869
|
-
"button",
|
|
5870
|
-
{
|
|
5871
|
-
onClick: () => {
|
|
5872
|
-
setYearMenu((o) => !o);
|
|
5873
|
-
setMonthMenu(false);
|
|
5874
|
-
},
|
|
5875
|
-
className: "flex items-center gap-1 px-2 py-1 rounded-lg text-[14px] font-semibold text-gray-900 hover:bg-gray-100 transition-colors",
|
|
5876
|
-
children: [
|
|
5877
|
-
viewYear,
|
|
5878
|
-
/* @__PURE__ */ jsx62(ChevronDown8, { className: "w-3 h-3 text-gray-400" })
|
|
5879
|
-
]
|
|
5880
|
-
}
|
|
5881
|
-
),
|
|
5882
|
-
/* @__PURE__ */ jsx62(AnimatePresence, { children: yearMenu && /* @__PURE__ */ jsx62(
|
|
5883
|
-
motion.div,
|
|
5884
|
-
{
|
|
5885
|
-
initial: { opacity: 0, y: -4 },
|
|
5886
|
-
animate: { opacity: 1, y: 0 },
|
|
5887
|
-
exit: { opacity: 0, y: -4 },
|
|
5888
|
-
transition: { duration: 0.12 },
|
|
5889
|
-
className: "absolute top-full left-0 z-[10000] mt-1 max-h-[200px] min-w-[90px] overflow-y-auto rounded-xl border border-border bg-popover py-1 shadow-lg",
|
|
5890
|
-
children: years.map((yr) => /* @__PURE__ */ jsx62(
|
|
5891
|
-
"button",
|
|
5892
|
-
{
|
|
5893
|
-
onClick: () => {
|
|
5894
|
-
setViewYear(yr);
|
|
5895
|
-
setYearMenu(false);
|
|
5896
|
-
},
|
|
5897
|
-
className: "w-full px-3 py-2 text-left text-[13px] text-foreground transition-colors hover:bg-muted",
|
|
5898
|
-
style: { fontWeight: yr === viewYear ? 600 : 400, color: yr === viewYear ? PRIMARY : void 0 },
|
|
5899
|
-
children: yr
|
|
5900
|
-
},
|
|
5901
|
-
yr
|
|
5902
|
-
))
|
|
5903
|
-
}
|
|
5904
|
-
) })
|
|
5905
|
-
] })
|
|
5906
|
-
] }),
|
|
5907
|
-
/* @__PURE__ */ jsx62(
|
|
5908
|
-
"button",
|
|
5909
|
-
{
|
|
5910
|
-
onClick: nextMonth,
|
|
5911
|
-
className: "w-8 h-8 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 transition-colors",
|
|
5912
|
-
children: /* @__PURE__ */ jsx62(ChevronRight8, { className: "w-4 h-4" })
|
|
5913
|
-
}
|
|
5914
|
-
)
|
|
5915
|
-
] }),
|
|
5916
|
-
/* @__PURE__ */ jsx62(
|
|
5917
|
-
"div",
|
|
5918
|
-
{
|
|
5919
|
-
className: "px-3 pb-1",
|
|
5920
|
-
style: { display: "grid", gridTemplateColumns: "repeat(7, minmax(0, 1fr))" },
|
|
5921
|
-
children: DAYS.map((d) => /* @__PURE__ */ jsx62("div", { className: "py-1 text-center text-[11.5px] font-semibold text-muted-foreground", children: d }, d))
|
|
5922
|
-
}
|
|
5923
|
-
),
|
|
5924
|
-
/* @__PURE__ */ jsx62(
|
|
5925
|
-
"div",
|
|
5926
|
-
{
|
|
5927
|
-
className: "gap-y-0.5 px-3 pb-4",
|
|
5928
|
-
style: { display: "grid", gridTemplateColumns: "repeat(7, minmax(0, 1fr))" },
|
|
5929
|
-
children: cells.map((cell, i) => {
|
|
5930
|
-
const selected = isSelected(cell);
|
|
5931
|
-
const tod = isToday(cell);
|
|
5932
|
-
const disabled = cell.current && isDisabled(cell.y, cell.m, cell.d);
|
|
5933
|
-
return /* @__PURE__ */ jsx62(
|
|
5934
|
-
"button",
|
|
5935
|
-
{
|
|
5936
|
-
onClick: () => selectDay(cell),
|
|
5937
|
-
disabled,
|
|
5938
|
-
className: cn(
|
|
5939
|
-
"h-9 w-9 mx-auto rounded-full text-[13px] font-medium flex items-center justify-center transition-all",
|
|
5940
|
-
selected && "text-white font-semibold",
|
|
5941
|
-
!selected && tod && "font-semibold",
|
|
5942
|
-
!selected && !tod && cell.current && !disabled && "text-gray-800 hover:bg-gray-100",
|
|
5943
|
-
!selected && !cell.current && "text-gray-300 hover:bg-gray-50",
|
|
5944
|
-
disabled && "opacity-30 cursor-not-allowed"
|
|
5945
|
-
),
|
|
5946
|
-
style: selected ? { background: PRIMARY } : tod ? { background: `${PRIMARY}18`, color: PRIMARY } : {},
|
|
5947
|
-
children: cell.d
|
|
5948
|
-
},
|
|
5949
|
-
i
|
|
5950
|
-
);
|
|
5951
|
-
})
|
|
5952
|
-
}
|
|
5953
|
-
)
|
|
5954
|
-
]
|
|
6182
|
+
children: withTime ? /* @__PURE__ */ jsx62(RemoveScroll, { allowPinchZoom: true, children: body }) : body
|
|
5955
6183
|
}
|
|
5956
6184
|
) });
|
|
5957
6185
|
return /* @__PURE__ */ jsxs41("div", { className: cn("relative", className), children: [
|
|
@@ -5961,14 +6189,14 @@ function DatePicker({ value, onChange, placeholder = "Select date", className, m
|
|
|
5961
6189
|
{
|
|
5962
6190
|
ref: triggerRef,
|
|
5963
6191
|
type: "button",
|
|
5964
|
-
onClick: () => open ?
|
|
6192
|
+
onClick: () => open ? closePanel() : openPanel(),
|
|
5965
6193
|
className: cn(
|
|
5966
6194
|
"flex h-12 min-h-12 w-full items-center gap-3 rounded-xl border border-border bg-card px-5 text-left text-[15px] shadow-sm transition-colors",
|
|
5967
6195
|
open ? "border-ring ring-2 ring-ring/20" : "hover:border-muted-foreground/45"
|
|
5968
6196
|
),
|
|
5969
6197
|
children: [
|
|
5970
6198
|
/* @__PURE__ */ jsx62(CalendarDays, { className: "size-[1.125rem] shrink-0 text-muted-foreground" }),
|
|
5971
|
-
/* @__PURE__ */ jsx62("span", { className: cn("flex-1", value ? "text-foreground" : "text-muted-foreground"), children: value ?
|
|
6199
|
+
/* @__PURE__ */ jsx62("span", { className: cn("flex-1", value ? "text-foreground" : "text-muted-foreground"), children: value ? displayValue(value, withTime, showSecond) : placeholder }),
|
|
5972
6200
|
/* @__PURE__ */ jsx62(ChevronDown8, { className: cn("size-[1.125rem] shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
|
|
5973
6201
|
]
|
|
5974
6202
|
}
|
|
@@ -5980,7 +6208,7 @@ function DatePicker({ value, onChange, placeholder = "Select date", className, m
|
|
|
5980
6208
|
// src/chart.tsx
|
|
5981
6209
|
import * as React41 from "react";
|
|
5982
6210
|
import * as RechartsPrimitive from "recharts";
|
|
5983
|
-
import { Fragment as
|
|
6211
|
+
import { Fragment as Fragment9, jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
5984
6212
|
var THEMES = { light: "", dark: ".dark" };
|
|
5985
6213
|
var INITIAL_DIMENSION = { width: 320, height: 200 };
|
|
5986
6214
|
var ChartContext = React41.createContext(null);
|
|
@@ -6114,7 +6342,7 @@ function ChartTooltipContent({
|
|
|
6114
6342
|
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
|
|
6115
6343
|
indicator === "dot" && "items-center"
|
|
6116
6344
|
),
|
|
6117
|
-
children: formatter && item?.value !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxs42(
|
|
6345
|
+
children: formatter && item?.value !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxs42(Fragment9, { children: [
|
|
6118
6346
|
itemConfig?.icon ? /* @__PURE__ */ jsx63(itemConfig.icon, {}) : !hideIndicator && /* @__PURE__ */ jsx63(
|
|
6119
6347
|
"div",
|
|
6120
6348
|
{
|
|
@@ -6241,7 +6469,7 @@ import {
|
|
|
6241
6469
|
Info as Info5,
|
|
6242
6470
|
Minus as Minus2
|
|
6243
6471
|
} from "lucide-react";
|
|
6244
|
-
import { Fragment as
|
|
6472
|
+
import { Fragment as Fragment10, jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
6245
6473
|
var gridStroke = "color-mix(in srgb, var(--border) 65%, transparent)";
|
|
6246
6474
|
var tickFill = "var(--muted-foreground)";
|
|
6247
6475
|
function MetricSparklineCard({
|
|
@@ -6406,7 +6634,7 @@ function DashboardAreaChartTemplate({
|
|
|
6406
6634
|
}
|
|
6407
6635
|
) : null
|
|
6408
6636
|
] }) }) }),
|
|
6409
|
-
footer ? /* @__PURE__ */ jsxs43(
|
|
6637
|
+
footer ? /* @__PURE__ */ jsxs43(Fragment10, { children: [
|
|
6410
6638
|
/* @__PURE__ */ jsx64(Separator, {}),
|
|
6411
6639
|
/* @__PURE__ */ jsx64("div", { className: "px-5 py-3", children: footer })
|
|
6412
6640
|
] }) : null
|
|
@@ -6653,7 +6881,7 @@ function Toaster({ theme, ...props }) {
|
|
|
6653
6881
|
// src/inline-edit.tsx
|
|
6654
6882
|
import * as React43 from "react";
|
|
6655
6883
|
import { Check as Check10, Pencil, X as X8 } from "lucide-react";
|
|
6656
|
-
import { Fragment as
|
|
6884
|
+
import { Fragment as Fragment11, jsx as jsx66, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
6657
6885
|
var InlineEdit = React43.forwardRef(
|
|
6658
6886
|
({
|
|
6659
6887
|
value,
|
|
@@ -6727,7 +6955,7 @@ var InlineEdit = React43.forwardRef(
|
|
|
6727
6955
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
6728
6956
|
inputClassName
|
|
6729
6957
|
);
|
|
6730
|
-
return /* @__PURE__ */ jsx66("div", { ref, "data-inline-edit": "", className: "relative inline-flex flex-col gap-1 max-w-full", children: editing ? /* @__PURE__ */ jsxs44(
|
|
6958
|
+
return /* @__PURE__ */ jsx66("div", { ref, "data-inline-edit": "", className: "relative inline-flex flex-col gap-1 max-w-full", children: editing ? /* @__PURE__ */ jsxs44(Fragment11, { children: [
|
|
6731
6959
|
multiline ? /* @__PURE__ */ jsx66(
|
|
6732
6960
|
"textarea",
|
|
6733
6961
|
{
|
|
@@ -7277,7 +7505,7 @@ function useBreakpoint() {
|
|
|
7277
7505
|
import * as React47 from "react";
|
|
7278
7506
|
import * as PopoverPrimitive4 from "@radix-ui/react-popover";
|
|
7279
7507
|
import { Check as Check11, ChevronDown as ChevronDown9, Search as Search4 } from "lucide-react";
|
|
7280
|
-
import { Fragment as
|
|
7508
|
+
import { Fragment as Fragment12, jsx as jsx70, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
7281
7509
|
var COUNTRIES = [
|
|
7282
7510
|
{ code: "US", name: "United States", flag: "\u{1F1FA}\u{1F1F8}", dialCode: "+1" },
|
|
7283
7511
|
{ code: "GB", name: "United Kingdom", flag: "\u{1F1EC}\u{1F1E7}", dialCode: "+44" },
|
|
@@ -7359,7 +7587,7 @@ var CountrySelect = React47.forwardRef(
|
|
|
7359
7587
|
className
|
|
7360
7588
|
),
|
|
7361
7589
|
children: [
|
|
7362
|
-
/* @__PURE__ */ jsx70("span", { className: "flex min-w-0 items-center gap-2.5", children: selected ? /* @__PURE__ */ jsxs47(
|
|
7590
|
+
/* @__PURE__ */ jsx70("span", { className: "flex min-w-0 items-center gap-2.5", children: selected ? /* @__PURE__ */ jsxs47(Fragment12, { children: [
|
|
7363
7591
|
/* @__PURE__ */ jsx70("span", { className: "text-base leading-none", "aria-hidden": "true", children: selected.flag }),
|
|
7364
7592
|
/* @__PURE__ */ jsx70("span", { className: "truncate", children: selected.name }),
|
|
7365
7593
|
showDialCode && /* @__PURE__ */ jsx70("span", { className: "shrink-0 text-muted-foreground", children: selected.dialCode })
|
|
@@ -7538,9 +7766,10 @@ IconButton.displayName = "IconButton";
|
|
|
7538
7766
|
// src/time-picker.tsx
|
|
7539
7767
|
import * as React48 from "react";
|
|
7540
7768
|
import { createPortal as createPortal2 } from "react-dom";
|
|
7769
|
+
import { RemoveScroll as RemoveScroll2 } from "react-remove-scroll";
|
|
7541
7770
|
import { Clock as Clock2, ChevronDown as ChevronDown10, X as X11 } from "lucide-react";
|
|
7542
|
-
import { Fragment as
|
|
7543
|
-
function
|
|
7771
|
+
import { Fragment as Fragment13, jsx as jsx72, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
7772
|
+
function pad2(n) {
|
|
7544
7773
|
return String(n).padStart(2, "0");
|
|
7545
7774
|
}
|
|
7546
7775
|
function parseHHMM(v) {
|
|
@@ -7553,15 +7782,15 @@ function parseHHMM(v) {
|
|
|
7553
7782
|
return { h, m };
|
|
7554
7783
|
}
|
|
7555
7784
|
function toHHMM(h, m) {
|
|
7556
|
-
return `${
|
|
7785
|
+
return `${pad2(h)}:${pad2(m)}`;
|
|
7557
7786
|
}
|
|
7558
|
-
function
|
|
7787
|
+
function displayTime2(value, use24Hour) {
|
|
7559
7788
|
const p = parseHHMM(value);
|
|
7560
7789
|
if (!p) return "";
|
|
7561
|
-
if (use24Hour) return `${
|
|
7790
|
+
if (use24Hour) return `${pad2(p.h)}:${pad2(p.m)}`;
|
|
7562
7791
|
const period = p.h < 12 ? "AM" : "PM";
|
|
7563
7792
|
const displayH = p.h % 12 === 0 ? 12 : p.h % 12;
|
|
7564
|
-
return `${
|
|
7793
|
+
return `${pad2(displayH)}:${pad2(p.m)} ${period}`;
|
|
7565
7794
|
}
|
|
7566
7795
|
var ITEM_H = 36;
|
|
7567
7796
|
var VISIBLE = 5;
|
|
@@ -7665,7 +7894,7 @@ function ScrollColumn({
|
|
|
7665
7894
|
)
|
|
7666
7895
|
] });
|
|
7667
7896
|
}
|
|
7668
|
-
var
|
|
7897
|
+
var PANEL_W = 224;
|
|
7669
7898
|
var PANEL_H = 220;
|
|
7670
7899
|
var TimePicker = React48.forwardRef(
|
|
7671
7900
|
({
|
|
@@ -7719,7 +7948,7 @@ var TimePicker = React48.forwardRef(
|
|
|
7719
7948
|
const vw = window.innerWidth;
|
|
7720
7949
|
const vh = window.innerHeight;
|
|
7721
7950
|
let left = rect.left;
|
|
7722
|
-
if (left +
|
|
7951
|
+
if (left + PANEL_W > vw - 8) left = vw - PANEL_W - 8;
|
|
7723
7952
|
let top = rect.bottom + 6;
|
|
7724
7953
|
if (top + PANEL_H > vh - 8) top = rect.top - PANEL_H - 6;
|
|
7725
7954
|
setPanelPos({ top, left });
|
|
@@ -7762,7 +7991,7 @@ var TimePicker = React48.forwardRef(
|
|
|
7762
7991
|
e.stopPropagation();
|
|
7763
7992
|
onValueChange("");
|
|
7764
7993
|
}
|
|
7765
|
-
const panel = open ? /* @__PURE__ */ jsxs48(
|
|
7994
|
+
const panel = open ? /* @__PURE__ */ jsx72(RemoveScroll2, { allowPinchZoom: true, children: /* @__PURE__ */ jsxs48(
|
|
7766
7995
|
"div",
|
|
7767
7996
|
{
|
|
7768
7997
|
ref: panelRef,
|
|
@@ -7774,13 +8003,17 @@ var TimePicker = React48.forwardRef(
|
|
|
7774
8003
|
position: "fixed",
|
|
7775
8004
|
top: panelPos.top,
|
|
7776
8005
|
left: panelPos.left,
|
|
7777
|
-
width:
|
|
7778
|
-
zIndex: 2e4
|
|
8006
|
+
width: PANEL_W,
|
|
8007
|
+
zIndex: 2e4,
|
|
8008
|
+
// See DatePicker: a modal Radix Dialog puts `pointer-events: none`
|
|
8009
|
+
// on <body>, which this portaled panel would otherwise inherit —
|
|
8010
|
+
// the columns rendered but no row could be clicked.
|
|
8011
|
+
pointerEvents: "auto"
|
|
7779
8012
|
},
|
|
7780
8013
|
children: [
|
|
7781
8014
|
/* @__PURE__ */ jsxs48("div", { className: "flex items-center gap-1.5 border-b border-border px-4 py-2.5", children: [
|
|
7782
8015
|
/* @__PURE__ */ jsx72(Clock2, { className: "size-3.5 text-muted-foreground" }),
|
|
7783
|
-
/* @__PURE__ */ jsx72("span", { className: "text-[13px] font-medium text-muted-foreground", children: value ?
|
|
8016
|
+
/* @__PURE__ */ jsx72("span", { className: "text-[13px] font-medium text-muted-foreground", children: value ? displayTime2(value, use24Hour) : "\u2014" })
|
|
7784
8017
|
] }),
|
|
7785
8018
|
/* @__PURE__ */ jsxs48(
|
|
7786
8019
|
"div",
|
|
@@ -7801,7 +8034,7 @@ var TimePicker = React48.forwardRef(
|
|
|
7801
8034
|
items: hours,
|
|
7802
8035
|
selected: hour,
|
|
7803
8036
|
onSelect: handleHourChange,
|
|
7804
|
-
renderItem: (h) =>
|
|
8037
|
+
renderItem: (h) => pad2(h),
|
|
7805
8038
|
getKey: (h) => h
|
|
7806
8039
|
}
|
|
7807
8040
|
),
|
|
@@ -7812,11 +8045,11 @@ var TimePicker = React48.forwardRef(
|
|
|
7812
8045
|
items: minutes,
|
|
7813
8046
|
selected: minute,
|
|
7814
8047
|
onSelect: handleMinuteChange,
|
|
7815
|
-
renderItem: (m) =>
|
|
8048
|
+
renderItem: (m) => pad2(m),
|
|
7816
8049
|
getKey: (m) => m
|
|
7817
8050
|
}
|
|
7818
8051
|
),
|
|
7819
|
-
!use24Hour && /* @__PURE__ */ jsxs48(
|
|
8052
|
+
!use24Hour && /* @__PURE__ */ jsxs48(Fragment13, { children: [
|
|
7820
8053
|
/* @__PURE__ */ jsx72("div", { className: "w-px self-stretch bg-border mx-1" }),
|
|
7821
8054
|
/* @__PURE__ */ jsx72(
|
|
7822
8055
|
ScrollColumn,
|
|
@@ -7832,7 +8065,7 @@ var TimePicker = React48.forwardRef(
|
|
|
7832
8065
|
] })
|
|
7833
8066
|
]
|
|
7834
8067
|
}
|
|
7835
|
-
) : null;
|
|
8068
|
+
) }) : null;
|
|
7836
8069
|
function mergeRef(el) {
|
|
7837
8070
|
triggerRef.current = el;
|
|
7838
8071
|
if (typeof ref === "function") ref(el);
|
|
@@ -7864,7 +8097,7 @@ var TimePicker = React48.forwardRef(
|
|
|
7864
8097
|
"flex-1 truncate",
|
|
7865
8098
|
value ? "text-foreground" : "text-muted-foreground"
|
|
7866
8099
|
),
|
|
7867
|
-
children: value ?
|
|
8100
|
+
children: value ? displayTime2(value, use24Hour) : placeholder
|
|
7868
8101
|
}
|
|
7869
8102
|
),
|
|
7870
8103
|
value && !disabled ? /* @__PURE__ */ jsx72(
|
|
@@ -8132,11 +8365,11 @@ VisuallyHidden.displayName = "VisuallyHidden";
|
|
|
8132
8365
|
import {
|
|
8133
8366
|
createContext as createContext5,
|
|
8134
8367
|
forwardRef as forwardRef55,
|
|
8135
|
-
useCallback as
|
|
8368
|
+
useCallback as useCallback11,
|
|
8136
8369
|
useContext as useContext4,
|
|
8137
8370
|
useEffect as useEffect15,
|
|
8138
8371
|
useId as useId3,
|
|
8139
|
-
useMemo as
|
|
8372
|
+
useMemo as useMemo10,
|
|
8140
8373
|
useRef as useRef14,
|
|
8141
8374
|
useState as useState19
|
|
8142
8375
|
} from "react";
|
|
@@ -8235,7 +8468,7 @@ function formatMonthLabel(monthKey2) {
|
|
|
8235
8468
|
}
|
|
8236
8469
|
|
|
8237
8470
|
// src/filter-chips.tsx
|
|
8238
|
-
import { Fragment as
|
|
8471
|
+
import { Fragment as Fragment14, jsx as jsx76, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
8239
8472
|
var POPOVER_FIT = "flex max-h-[var(--radix-popover-content-available-height)] flex-col overflow-hidden";
|
|
8240
8473
|
var FILTER_SCROLL_AREA = "min-h-0 flex-1 overflow-y-auto";
|
|
8241
8474
|
var FilterChipGroupContext = createContext5(null);
|
|
@@ -8247,11 +8480,11 @@ function FilterChipGroup({
|
|
|
8247
8480
|
const openKeyRef = useRef14(null);
|
|
8248
8481
|
const frameRef = useRef14(null);
|
|
8249
8482
|
const handoffFromRef = useRef14(null);
|
|
8250
|
-
const apply =
|
|
8483
|
+
const apply = useCallback11((next) => {
|
|
8251
8484
|
openKeyRef.current = next;
|
|
8252
8485
|
setOpenKey(next);
|
|
8253
8486
|
}, []);
|
|
8254
|
-
const setOpen =
|
|
8487
|
+
const setOpen = useCallback11(
|
|
8255
8488
|
(key, open) => {
|
|
8256
8489
|
if (frameRef.current !== null) {
|
|
8257
8490
|
cancelAnimationFrame(frameRef.current);
|
|
@@ -8280,12 +8513,12 @@ function FilterChipGroup({
|
|
|
8280
8513
|
},
|
|
8281
8514
|
[]
|
|
8282
8515
|
);
|
|
8283
|
-
const consumeHandoff =
|
|
8516
|
+
const consumeHandoff = useCallback11((key) => {
|
|
8284
8517
|
if (handoffFromRef.current !== key) return false;
|
|
8285
8518
|
handoffFromRef.current = null;
|
|
8286
8519
|
return true;
|
|
8287
8520
|
}, []);
|
|
8288
|
-
const value =
|
|
8521
|
+
const value = useMemo10(
|
|
8289
8522
|
() => ({ openKey, setOpen, consumeHandoff }),
|
|
8290
8523
|
[openKey, setOpen, consumeHandoff]
|
|
8291
8524
|
);
|
|
@@ -8295,7 +8528,7 @@ function useFilterChipState(key, controlled) {
|
|
|
8295
8528
|
const group = useContext4(FilterChipGroupContext);
|
|
8296
8529
|
const [localOpen, setLocalOpen] = useState19(false);
|
|
8297
8530
|
const isControlled = controlled?.open !== void 0;
|
|
8298
|
-
const onOpenChange =
|
|
8531
|
+
const onOpenChange = useCallback11(
|
|
8299
8532
|
(next) => {
|
|
8300
8533
|
controlled?.onOpenChange?.(next);
|
|
8301
8534
|
if (isControlled) return;
|
|
@@ -8305,7 +8538,7 @@ function useFilterChipState(key, controlled) {
|
|
|
8305
8538
|
[controlled, isControlled, group, key]
|
|
8306
8539
|
);
|
|
8307
8540
|
const open = isControlled ? controlled.open : group ? group.openKey === key : localOpen;
|
|
8308
|
-
const onCloseAutoFocus =
|
|
8541
|
+
const onCloseAutoFocus = useCallback11(
|
|
8309
8542
|
(event) => {
|
|
8310
8543
|
if (group?.consumeHandoff(key)) {
|
|
8311
8544
|
event.preventDefault();
|
|
@@ -8469,7 +8702,7 @@ function SelectFilterChip({
|
|
|
8469
8702
|
const [query, setQuery] = useState19("");
|
|
8470
8703
|
const supportsInvert = !!onInvertChange;
|
|
8471
8704
|
const isActive = selected.length > 0;
|
|
8472
|
-
const visible =
|
|
8705
|
+
const visible = useMemo10(() => {
|
|
8473
8706
|
const q = query.trim().toLowerCase();
|
|
8474
8707
|
if (!q) return options;
|
|
8475
8708
|
return options.filter(
|
|
@@ -8746,7 +8979,7 @@ function DateRangeFilterChip({
|
|
|
8746
8979
|
className: "h-8 text-[12.5px]"
|
|
8747
8980
|
}
|
|
8748
8981
|
)
|
|
8749
|
-
] }, unit.key)) }) : /* @__PURE__ */ jsxs50(
|
|
8982
|
+
] }, unit.key)) }) : /* @__PURE__ */ jsxs50(Fragment14, { children: [
|
|
8750
8983
|
/* @__PURE__ */ jsxs50("div", { className: "space-y-1", children: [
|
|
8751
8984
|
/* @__PURE__ */ jsx76("p", { className: "text-[11px] font-medium text-muted-foreground", children: "From" }),
|
|
8752
8985
|
/* @__PURE__ */ jsx76(
|
|
@@ -9107,7 +9340,7 @@ function AddFilterMenu({
|
|
|
9107
9340
|
const listRef = useRef14(null);
|
|
9108
9341
|
const listId = useId3();
|
|
9109
9342
|
const q = query.trim().toLowerCase();
|
|
9110
|
-
const rows =
|
|
9343
|
+
const rows = useMemo10(() => {
|
|
9111
9344
|
const out = [];
|
|
9112
9345
|
if (q) {
|
|
9113
9346
|
const valueMatches = filters.flatMap(
|
|
@@ -9143,7 +9376,7 @@ function AddFilterMenu({
|
|
|
9143
9376
|
}
|
|
9144
9377
|
return out;
|
|
9145
9378
|
}, [filters, q, onSelectValue, onRemoveFilter]);
|
|
9146
|
-
const selectable =
|
|
9379
|
+
const selectable = useMemo10(
|
|
9147
9380
|
() => rows.map((r, i) => r.kind === "heading" ? -1 : i).filter((i) => i >= 0),
|
|
9148
9381
|
[rows]
|
|
9149
9382
|
);
|
|
@@ -9265,11 +9498,11 @@ function AddFilterMenu({
|
|
|
9265
9498
|
"flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-[12.5px] text-foreground",
|
|
9266
9499
|
i === cursor && "bg-muted"
|
|
9267
9500
|
),
|
|
9268
|
-
children: row.kind === "value" ? /* @__PURE__ */ jsxs50(
|
|
9501
|
+
children: row.kind === "value" ? /* @__PURE__ */ jsxs50(Fragment14, { children: [
|
|
9269
9502
|
row.option.icon,
|
|
9270
9503
|
/* @__PURE__ */ jsx76("span", { className: "min-w-0 flex-1 truncate", children: row.option.label }),
|
|
9271
9504
|
/* @__PURE__ */ jsx76("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: row.filter.label })
|
|
9272
|
-
] }) : /* @__PURE__ */ jsxs50(
|
|
9505
|
+
] }) : /* @__PURE__ */ jsxs50(Fragment14, { children: [
|
|
9273
9506
|
/* @__PURE__ */ jsx76("span", { className: "min-w-0 flex-1 truncate", children: row.filter.label }),
|
|
9274
9507
|
row.filter.activeCount ? /* @__PURE__ */ jsx76("span", { className: "shrink-0 rounded-full bg-primary/15 px-1.5 text-[10px] font-semibold tabular-nums text-primary", children: row.filter.activeCount }) : null,
|
|
9275
9508
|
visibleKeys.includes(row.filter.key) ? /* @__PURE__ */ jsx76(
|