@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.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: (step) => setCurrentStep(Math.max(0, Math.min(step, steps.length - 1)))
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((step, i) => /* @__PURE__ */ jsxs28(React36.Fragment, { children: [
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
- step.status === "complete" && "bg-primary border-primary text-primary-foreground",
3621
- step.status === "current" && "bg-primary/10 border-primary text-primary",
3622
- step.status === "upcoming" && "bg-card border-border text-muted-foreground"
3623
- ), children: step.status === "complete" ? /* @__PURE__ */ jsx47(Check7, { className: "size-4", strokeWidth: 2.5 }) : i + 1 }),
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", step.status === "upcoming" ? "text-muted-foreground" : "text-foreground"), children: step.label }),
3626
- step.description && /* @__PURE__ */ jsx47("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: step.description })
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", step.status === "complete" ? "bg-primary" : "bg-border") }) })
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: pad2,
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
- pad2,
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" : elided ? `Copy ${value}` : `Copy ${label}`;
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
- onClick ? (
4679
- // A bare <button>, deliberately, where the rest of flux would reach for
4680
- // `Button variant="link"`. That variant hard-codes `text-[15px]`, and
4681
- // the obvious override — `text-[inherit]` does not beat it: Tailwind
4682
- // and tailwind-merge read `text-[<non-length>]` as a COLOUR, so the
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 PANEL_W = 296;
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 parseYMD(s) {
5717
+ function pad(n) {
5718
+ return String(n).padStart(2, "0");
5719
+ }
5720
+ function parseValue(s) {
5684
5721
  if (!s) return null;
5685
- const [y, m, d] = s.split("-").map(Number);
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
- return { y, m: m - 1, d };
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}-${String(m + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
5740
+ return `${y}-${pad(m + 1)}-${pad(d)}`;
5691
5741
  }
5692
- function displayDate(ymd) {
5693
- const p = parseYMD(ymd);
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
- return `${String(p.d).padStart(2, "0")} ${MONTHS[p.m].slice(0, 3)} ${p.y}`;
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 = parseYMD(value);
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 + PANEL_W > vw - 8) left = vw - PANEL_W - 8;
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
- onChange(toYMD(cell.y, cell.m, cell.d));
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 panel = /* @__PURE__ */ jsx62(AnimatePresence, { children: open && /* @__PURE__ */ jsxs41(
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: PANEL_W,
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 ? setOpen(false) : openPanel(),
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 ? displayDate(value) : placeholder }),
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 Fragment8, jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
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(Fragment8, { children: [
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 Fragment9, jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
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(Fragment9, { children: [
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 Fragment10, jsx as jsx66, jsxs as jsxs44 } from "react/jsx-runtime";
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(Fragment10, { children: [
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 Fragment11, jsx as jsx70, jsxs as jsxs47 } from "react/jsx-runtime";
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(Fragment11, { children: [
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 Fragment12, jsx as jsx72, jsxs as jsxs48 } from "react/jsx-runtime";
7543
- function pad(n) {
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 `${pad(h)}:${pad(m)}`;
7785
+ return `${pad2(h)}:${pad2(m)}`;
7557
7786
  }
7558
- function displayTime(value, use24Hour) {
7787
+ function displayTime2(value, use24Hour) {
7559
7788
  const p = parseHHMM(value);
7560
7789
  if (!p) return "";
7561
- if (use24Hour) return `${pad(p.h)}:${pad(p.m)}`;
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 `${pad(displayH)}:${pad(p.m)} ${period}`;
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 PANEL_W2 = 224;
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 + PANEL_W2 > vw - 8) left = vw - PANEL_W2 - 8;
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: PANEL_W2,
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 ? displayTime(value, use24Hour) : "\u2014" })
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) => pad(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) => pad(m),
8048
+ renderItem: (m) => pad2(m),
7816
8049
  getKey: (m) => m
7817
8050
  }
7818
8051
  ),
7819
- !use24Hour && /* @__PURE__ */ jsxs48(Fragment12, { children: [
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 ? displayTime(value, use24Hour) : placeholder
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 useCallback10,
8368
+ useCallback as useCallback11,
8136
8369
  useContext as useContext4,
8137
8370
  useEffect as useEffect15,
8138
8371
  useId as useId3,
8139
- useMemo as useMemo9,
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 Fragment13, jsx as jsx76, jsxs as jsxs50 } from "react/jsx-runtime";
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 = useCallback10((next) => {
8483
+ const apply = useCallback11((next) => {
8251
8484
  openKeyRef.current = next;
8252
8485
  setOpenKey(next);
8253
8486
  }, []);
8254
- const setOpen = useCallback10(
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 = useCallback10((key) => {
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 = useMemo9(
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 = useCallback10(
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 = useCallback10(
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 = useMemo9(() => {
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(Fragment13, { children: [
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 = useMemo9(() => {
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 = useMemo9(
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(Fragment13, { children: [
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(Fragment13, { children: [
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(