@lovett/ui 0.0.10 → 0.0.11

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
@@ -1,8 +1,8 @@
1
- import React2, { forwardRef, Children, isValidElement, useState, createContext, useContext, useId, useRef, useEffect, memo, useCallback, useMemo, useLayoutEffect, Fragment as Fragment$1, cloneElement } from 'react';
1
+ import React2, { forwardRef, Children, isValidElement, useState, createContext, useContext, useId, useRef, useEffect, cloneElement, useMemo, useCallback, useLayoutEffect, memo, Fragment as Fragment$1 } from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
- import { Minus, Check, EyeOff, Eye, ChevronDown, Search, Play, VolumeX, Volume2, X, Pencil, House, GripVertical, Loader2, ChevronUp, ChevronsUpDown, ChevronLeft, ChevronRight, SlidersHorizontal, Copy, Plus, FolderClosed, FolderPlus, Folder, Paperclip, Upload, Image, Code, Table as Table$1, FileText, FileType, AlertCircle, RotateCcw, Link2, ArrowRight, MoreHorizontal, ThumbsUp as ThumbsUp$1, MessageCircle, Share2, Lock, Info, BarChart3, ExternalLink } from 'lucide-react';
5
+ import { Minus, Check, ChevronDown, X, Loader2, EyeOff, Eye, Search, Play, VolumeX, Volume2, Pencil, House, GripVertical, ChevronUp, ChevronsUpDown, ChevronLeft, ChevronRight, SlidersHorizontal, Copy, Plus, FolderClosed, FolderPlus, Folder, Paperclip, Upload, Image, Code, Table as Table$1, FileText, FileType, AlertCircle, RotateCcw, Link2, ArrowRight, MoreHorizontal, ThumbsUp as ThumbsUp$1, MessageCircle, Share2, Lock, Info, ExternalLink } from 'lucide-react';
6
6
  import { createPortal } from 'react-dom';
7
7
  import { Link } from 'react-router-dom';
8
8
  import { toast, Toaster as Toaster$1 } from 'sonner';
@@ -17,7 +17,7 @@ import css from 'react-syntax-highlighter/dist/esm/languages/prism/css';
17
17
  import diff from 'react-syntax-highlighter/dist/esm/languages/prism/diff';
18
18
  import javascript from 'react-syntax-highlighter/dist/esm/languages/prism/javascript';
19
19
  import json from 'react-syntax-highlighter/dist/esm/languages/prism/json';
20
- import jsx66 from 'react-syntax-highlighter/dist/esm/languages/prism/jsx';
20
+ import jsx70 from 'react-syntax-highlighter/dist/esm/languages/prism/jsx';
21
21
  import markdown from 'react-syntax-highlighter/dist/esm/languages/prism/markdown';
22
22
  import markup from 'react-syntax-highlighter/dist/esm/languages/prism/markup';
23
23
  import python from 'react-syntax-highlighter/dist/esm/languages/prism/python';
@@ -481,7 +481,8 @@ var Textarea = forwardRef(function Textarea2({ error, shellClassName, className,
481
481
  }
482
482
  );
483
483
  });
484
- var openPanels = [];
484
+
485
+ // src/lib/focus.ts
485
486
  var FOCUSABLE_SELECTOR = [
486
487
  "a[href]",
487
488
  "area[href]",
@@ -494,11 +495,90 @@ var FOCUSABLE_SELECTOR = [
494
495
  '[contenteditable="true"]',
495
496
  "[tabindex]"
496
497
  ].join(",");
497
- function tabbablesWithin(panel) {
498
- return Array.from(panel.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
498
+ function tabbablesWithin(root) {
499
+ return Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
499
500
  (el) => el.tabIndex >= 0 && !el.hasAttribute("inert") && el.getAttribute("aria-hidden") !== "true" && !el.closest("[hidden]")
500
501
  );
501
502
  }
503
+ var stack = [];
504
+ var listening = false;
505
+ function onDocumentKeyDown(event) {
506
+ if (event.key !== "Escape") return;
507
+ const top = stack[stack.length - 1];
508
+ if (!top) return;
509
+ event.stopPropagation();
510
+ top.onEscape(event);
511
+ }
512
+ function pushLayer(record) {
513
+ stack.push(record);
514
+ if (!listening) {
515
+ document.addEventListener("keydown", onDocumentKeyDown);
516
+ listening = true;
517
+ }
518
+ return () => {
519
+ const at = stack.lastIndexOf(record);
520
+ if (at !== -1) stack.splice(at, 1);
521
+ if (stack.length === 0 && listening) {
522
+ document.removeEventListener("keydown", onDocumentKeyDown);
523
+ listening = false;
524
+ }
525
+ };
526
+ }
527
+ function useLayer(options) {
528
+ const { enabled, kind, elementRef, onEscape } = options;
529
+ const onEscapeRef = useRef(onEscape);
530
+ useEffect(() => {
531
+ onEscapeRef.current = onEscape;
532
+ });
533
+ const recordRef = useRef(null);
534
+ useEffect(() => {
535
+ if (!enabled) return;
536
+ const record = {
537
+ kind,
538
+ element: () => elementRef?.current ?? null,
539
+ onEscape: (event) => onEscapeRef.current(event)
540
+ };
541
+ recordRef.current = record;
542
+ const pop = pushLayer(record);
543
+ return () => {
544
+ pop();
545
+ if (recordRef.current === record) recordRef.current = null;
546
+ };
547
+ }, [enabled, kind, elementRef]);
548
+ return useMemo(
549
+ () => ({
550
+ isTop: () => {
551
+ const record = recordRef.current;
552
+ return record !== null && stack[stack.length - 1] === record;
553
+ },
554
+ isTopOfKind: () => {
555
+ const record = recordRef.current;
556
+ if (!record) return false;
557
+ for (let i = stack.length - 1; i >= 0; i--) {
558
+ const layer = stack[i];
559
+ if (layer === record) return true;
560
+ if (layer?.kind === record.kind) return false;
561
+ }
562
+ return false;
563
+ },
564
+ containsInLayerAbove: (node) => {
565
+ const record = recordRef.current;
566
+ if (!record) return false;
567
+ const at = stack.indexOf(record);
568
+ if (at === -1) return false;
569
+ for (let i = at + 1; i < stack.length; i++) {
570
+ if (stack[i]?.element()?.contains(node)) return true;
571
+ }
572
+ return false;
573
+ }
574
+ }),
575
+ []
576
+ );
577
+ }
578
+ function useEscapeKey(onEscape, options = {}) {
579
+ const { enabled = true, kind = "popover" } = options;
580
+ return useLayer({ enabled, kind, onEscape });
581
+ }
502
582
  function Modal({ isOpen, onClose, title, children, className, ariaLabel }) {
503
583
  const panelRef = useRef(null);
504
584
  const titleId = useId();
@@ -507,26 +587,25 @@ function Modal({ isOpen, onClose, title, children, className, ariaLabel }) {
507
587
  const panel = panelRef.current;
508
588
  if (!panel) return;
509
589
  const previous = document.activeElement instanceof HTMLElement && document.activeElement !== document.body ? document.activeElement : null;
510
- openPanels.push(panel);
511
590
  const initial = panel.querySelector("[data-autofocus]");
512
591
  (initial ?? panel).focus();
513
592
  return () => {
514
- const at = openPanels.indexOf(panel);
515
- if (at !== -1) openPanels.splice(at, 1);
516
593
  if (previous && previous.isConnected) previous.focus();
517
594
  };
518
595
  }, [isOpen]);
596
+ const layer = useLayer({
597
+ enabled: isOpen,
598
+ kind: "modal",
599
+ elementRef: panelRef,
600
+ onEscape: () => onClose()
601
+ });
519
602
  useEffect(() => {
520
603
  if (!isOpen) return;
521
604
  const panel = panelRef.current;
522
605
  if (!panel) return;
523
606
  const handleKeyDown = (e) => {
524
- if (openPanels[openPanels.length - 1] !== panel) return;
525
- if (e.key === "Escape") {
526
- onClose();
527
- return;
528
- }
529
607
  if (e.key !== "Tab") return;
608
+ if (!layer.isTopOfKind()) return;
530
609
  const active = document.activeElement;
531
610
  if (!(active instanceof HTMLElement) || !panel.contains(active)) return;
532
611
  const tabbables = tabbablesWithin(panel);
@@ -554,7 +633,7 @@ function Modal({ isOpen, onClose, title, children, className, ariaLabel }) {
554
633
  };
555
634
  document.addEventListener("keydown", handleKeyDown);
556
635
  return () => document.removeEventListener("keydown", handleKeyDown);
557
- }, [isOpen, onClose]);
636
+ }, [isOpen, layer]);
558
637
  if (!isOpen) return null;
559
638
  return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
560
639
  /* @__PURE__ */ jsx(
@@ -2596,6 +2675,16 @@ function OptionTileGroup(props) {
2596
2675
  }
2597
2676
  );
2598
2677
  }
2678
+
2679
+ // src/lib/clipboard.ts
2680
+ async function copyText(value, label) {
2681
+ try {
2682
+ await navigator.clipboard.writeText(value);
2683
+ toast.success(label ? `Copied ${label}` : `Copied ${value}`);
2684
+ } catch {
2685
+ toast.error("Copy failed");
2686
+ }
2687
+ }
2599
2688
  var TONE_COLOR = {
2600
2689
  neutral: "rgb(var(--foreground))",
2601
2690
  accent: "rgb(var(--accent))",
@@ -2610,7 +2699,9 @@ function MetricCard({
2610
2699
  tone = "neutral",
2611
2700
  icon,
2612
2701
  labelPosition = "bottom",
2613
- className
2702
+ className,
2703
+ copyable = false,
2704
+ copyValue
2614
2705
  }) {
2615
2706
  const labelEl = labelPosition === "top" ? /* @__PURE__ */ jsx(
2616
2707
  "div",
@@ -2638,24 +2729,40 @@ function MetricCard({
2638
2729
  }
2639
2730
  )
2640
2731
  ] });
2641
- return /* @__PURE__ */ jsx(
2642
- "div",
2643
- {
2644
- className: className ?? "flex flex-col gap-1 px-4 py-3 border",
2645
- style: {
2646
- background: "rgb(var(--surface-overlay-soft))",
2647
- borderColor: "rgb(var(--border))",
2648
- borderRadius: "var(--radius-lg)"
2649
- },
2650
- children: labelPosition === "top" ? /* @__PURE__ */ jsxs(Fragment, { children: [
2651
- labelEl,
2652
- valueEl
2653
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2654
- valueEl,
2655
- labelEl
2656
- ] })
2657
- }
2658
- );
2732
+ const body = labelPosition === "top" ? /* @__PURE__ */ jsxs(Fragment, { children: [
2733
+ labelEl,
2734
+ valueEl
2735
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2736
+ valueEl,
2737
+ labelEl
2738
+ ] });
2739
+ const surfaceClass = className ?? "flex flex-col gap-1 px-4 py-3 border";
2740
+ const surfaceStyle = {
2741
+ background: "rgb(var(--surface-overlay-soft))",
2742
+ borderColor: "rgb(var(--border))",
2743
+ borderRadius: "var(--radius-lg)"
2744
+ };
2745
+ const text = copyValue ?? (typeof value === "string" ? value : void 0);
2746
+ if (copyable && text !== void 0) {
2747
+ return /* @__PURE__ */ jsx(
2748
+ "button",
2749
+ {
2750
+ type: "button",
2751
+ onClick: () => void copyText(text, label),
2752
+ title: `Copy ${label}`,
2753
+ "aria-label": `Copy ${label}: ${text}`,
2754
+ className: cn(
2755
+ surfaceClass,
2756
+ "text-left cursor-pointer transition-[border-color,box-shadow]",
2757
+ "hover:border-[rgb(var(--border-strong))] hover:[box-shadow:var(--shadow-sm)]",
2758
+ "focus-visible:outline-none focus-visible:[box-shadow:var(--ring-focus)]"
2759
+ ),
2760
+ style: surfaceStyle,
2761
+ children: body
2762
+ }
2763
+ );
2764
+ }
2765
+ return /* @__PURE__ */ jsx("div", { className: surfaceClass, style: surfaceStyle, children: body });
2659
2766
  }
2660
2767
  function ProgressBar({ label, percent, status, height = 8 }) {
2661
2768
  const determinate = typeof percent === "number";
@@ -2911,16 +3018,6 @@ function TokenBadge({
2911
3018
  }
2912
3019
  );
2913
3020
  }
2914
-
2915
- // src/lib/clipboard.ts
2916
- async function copyText(value, label) {
2917
- try {
2918
- await navigator.clipboard.writeText(value);
2919
- toast.success(label ? `Copied ${label}` : `Copied ${value}`);
2920
- } catch {
2921
- toast.error("Copy failed");
2922
- }
2923
- }
2924
3021
  var ValueChip = forwardRef(
2925
3022
  function ValueChip2({ children, copyValue, copyLabel, size = "md", fill, className, ...rest }, ref) {
2926
3023
  const shared = cn(
@@ -3610,6 +3707,403 @@ var Checkbox = forwardRef(
3610
3707
  );
3611
3708
  }
3612
3709
  );
3710
+
3711
+ // src/lib/refs.ts
3712
+ function assignRef(ref, node) {
3713
+ if (!ref) return;
3714
+ if (typeof ref === "function") {
3715
+ ref(node);
3716
+ return;
3717
+ }
3718
+ ref.current = node;
3719
+ }
3720
+ function composeRefs(...refs) {
3721
+ return (node) => {
3722
+ for (const ref of refs) assignRef(ref, node);
3723
+ };
3724
+ }
3725
+ var OPPOSITE = {
3726
+ top: "bottom",
3727
+ bottom: "top",
3728
+ left: "right",
3729
+ right: "left"
3730
+ };
3731
+ function isVertical(side) {
3732
+ return side === "top" || side === "bottom";
3733
+ }
3734
+ function clampNumber(value, min, max) {
3735
+ return Math.max(min, Math.min(value, max));
3736
+ }
3737
+ function computeAnchoredPosition(anchor, floating, viewport, options = {}) {
3738
+ const {
3739
+ side: preferred = "bottom",
3740
+ align = "start",
3741
+ offset = 6,
3742
+ alignOffset = 0,
3743
+ flip = true,
3744
+ clampToViewport = true,
3745
+ gutter = 8
3746
+ } = options;
3747
+ const anchorRight = anchor.left + anchor.width;
3748
+ const anchorBottom = anchor.top + anchor.height;
3749
+ const room = {
3750
+ top: anchor.top - gutter,
3751
+ bottom: viewport.height - anchorBottom - gutter,
3752
+ left: anchor.left - gutter,
3753
+ right: viewport.width - anchorRight - gutter
3754
+ };
3755
+ const needed = (side2) => (isVertical(side2) ? floating.height : floating.width) + offset;
3756
+ let side = preferred;
3757
+ if (flip && room[preferred] < needed(preferred)) {
3758
+ const opposite = OPPOSITE[preferred];
3759
+ if (room[opposite] >= needed(opposite) || room[opposite] > room[preferred]) {
3760
+ side = opposite;
3761
+ }
3762
+ }
3763
+ let left;
3764
+ let top;
3765
+ if (isVertical(side)) {
3766
+ top = side === "bottom" ? anchorBottom + offset : anchor.top - floating.height - offset;
3767
+ switch (align) {
3768
+ case "start":
3769
+ left = anchor.left + alignOffset;
3770
+ break;
3771
+ case "center":
3772
+ left = anchor.left + anchor.width / 2 - floating.width / 2 + alignOffset;
3773
+ break;
3774
+ case "end":
3775
+ left = anchorRight - floating.width - alignOffset;
3776
+ break;
3777
+ }
3778
+ } else {
3779
+ left = side === "right" ? anchorRight + offset : anchor.left - floating.width - offset;
3780
+ switch (align) {
3781
+ case "start":
3782
+ top = anchor.top + alignOffset;
3783
+ break;
3784
+ case "center":
3785
+ top = anchor.top + anchor.height / 2 - floating.height / 2 + alignOffset;
3786
+ break;
3787
+ case "end":
3788
+ top = anchorBottom - floating.height - alignOffset;
3789
+ break;
3790
+ }
3791
+ }
3792
+ if (clampToViewport) {
3793
+ left = clampNumber(left, gutter, viewport.width - floating.width - gutter);
3794
+ top = clampNumber(top, gutter, viewport.height - floating.height - gutter);
3795
+ }
3796
+ return {
3797
+ left: Math.round(left),
3798
+ top: Math.round(top),
3799
+ placement: { side, align }
3800
+ };
3801
+ }
3802
+ var PARKED_STYLE = {
3803
+ position: "fixed",
3804
+ // Parked far off-screen, not at (0, 0): if a renderer paints the
3805
+ // unpositioned frame despite `visibility: hidden`, nothing flashes at the
3806
+ // viewport's top-left corner.
3807
+ left: -99999,
3808
+ top: -99999,
3809
+ visibility: "hidden",
3810
+ opacity: 0,
3811
+ pointerEvents: "none"
3812
+ };
3813
+ function viewportSize() {
3814
+ const root = document.documentElement;
3815
+ return {
3816
+ width: root.clientWidth || window.innerWidth,
3817
+ height: root.clientHeight || window.innerHeight
3818
+ };
3819
+ }
3820
+ function samePosition(a, b) {
3821
+ return a !== null && a.left === b.left && a.top === b.top && a.placement.side === b.placement.side && a.placement.align === b.placement.align;
3822
+ }
3823
+ function useAnchoredPosition(options) {
3824
+ const {
3825
+ anchorRef,
3826
+ anchorRect = null,
3827
+ enabled = true,
3828
+ side = "bottom",
3829
+ align = "start",
3830
+ offset = 6,
3831
+ alignOffset = 0,
3832
+ flip = true,
3833
+ clampToViewport = true,
3834
+ gutter = 8
3835
+ } = options;
3836
+ const floatingRef = useRef(null);
3837
+ const [floating, setFloating] = useState(null);
3838
+ const ref = useCallback((node) => {
3839
+ floatingRef.current = node;
3840
+ setFloating(node);
3841
+ }, []);
3842
+ const [position, setPosition] = useState(null);
3843
+ const anchorRectRef = useRef(anchorRect);
3844
+ useLayoutEffect(() => {
3845
+ anchorRectRef.current = anchorRect;
3846
+ });
3847
+ const rectKey = anchorRect ? `${anchorRect.left}|${anchorRect.top}|${anchorRect.width}|${anchorRect.height}` : "";
3848
+ const measure = useCallback(() => {
3849
+ const node = floatingRef.current;
3850
+ if (!node) return;
3851
+ const rect = anchorRectRef.current ?? anchorRef?.current?.getBoundingClientRect() ?? null;
3852
+ if (!rect) return;
3853
+ const next = computeAnchoredPosition(
3854
+ rect,
3855
+ { width: node.offsetWidth, height: node.offsetHeight },
3856
+ viewportSize(),
3857
+ { side, align, offset, alignOffset, flip, clampToViewport, gutter }
3858
+ );
3859
+ setPosition((prev) => samePosition(prev, next) ? prev : next);
3860
+ }, [anchorRef, side, align, offset, alignOffset, flip, clampToViewport, gutter]);
3861
+ useLayoutEffect(() => {
3862
+ if (!enabled || !floating) {
3863
+ setPosition((prev) => prev === null ? prev : null);
3864
+ return;
3865
+ }
3866
+ measure();
3867
+ window.addEventListener("resize", measure);
3868
+ window.addEventListener("scroll", measure, true);
3869
+ let observer = null;
3870
+ if (typeof ResizeObserver !== "undefined") {
3871
+ observer = new ResizeObserver(() => measure());
3872
+ observer.observe(floating);
3873
+ const anchorEl = anchorRef?.current;
3874
+ if (anchorEl) observer.observe(anchorEl);
3875
+ }
3876
+ return () => {
3877
+ window.removeEventListener("resize", measure);
3878
+ window.removeEventListener("scroll", measure, true);
3879
+ observer?.disconnect();
3880
+ };
3881
+ }, [enabled, floating, measure, anchorRef, rectKey]);
3882
+ const positioned = position !== null;
3883
+ const style = positioned ? { position: "fixed", left: position.left, top: position.top } : PARKED_STYLE;
3884
+ return {
3885
+ ref,
3886
+ floatingRef,
3887
+ style,
3888
+ placement: position?.placement ?? null,
3889
+ positioned,
3890
+ update: measure
3891
+ };
3892
+ }
3893
+ function useOutsideClick(targets, onOutside, options = {}) {
3894
+ const { enabled = true, layer } = options;
3895
+ const targetsRef = useRef(targets);
3896
+ const handlerRef = useRef(onOutside);
3897
+ useEffect(() => {
3898
+ targetsRef.current = targets;
3899
+ handlerRef.current = onOutside;
3900
+ });
3901
+ useEffect(() => {
3902
+ if (!enabled) return;
3903
+ const onPointerDown = (event) => {
3904
+ const target = event.target;
3905
+ if (!(target instanceof Node)) return;
3906
+ for (const candidate of targetsRef.current) {
3907
+ const el = candidate instanceof Node ? candidate : candidate?.current;
3908
+ if (el?.contains(target)) return;
3909
+ }
3910
+ if (layer?.containsInLayerAbove(target)) return;
3911
+ handlerRef.current(event);
3912
+ };
3913
+ document.addEventListener("pointerdown", onPointerDown);
3914
+ return () => document.removeEventListener("pointerdown", onPointerDown);
3915
+ }, [enabled, layer]);
3916
+ }
3917
+ var POPOVER_SURFACE_STYLE = {
3918
+ background: "rgb(var(--popover))",
3919
+ color: "rgb(var(--popover-foreground))",
3920
+ border: "1px solid rgb(var(--border))",
3921
+ boxShadow: "var(--shadow-lg)"
3922
+ };
3923
+ var PopoverCtx = createContext(null);
3924
+ function usePopoverCtx(consumer) {
3925
+ const ctx = useContext(PopoverCtx);
3926
+ if (!ctx) {
3927
+ throw new Error(
3928
+ `${consumer} must be rendered inside <Popover>. Wrap your trigger + content with the Popover root component.`
3929
+ );
3930
+ }
3931
+ return ctx;
3932
+ }
3933
+ function PopoverRoot({
3934
+ open: controlledOpen,
3935
+ defaultOpen,
3936
+ onOpenChange,
3937
+ anchorRect = null,
3938
+ children
3939
+ }) {
3940
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));
3941
+ const isControlled = controlledOpen !== void 0;
3942
+ const open = isControlled ? Boolean(controlledOpen) : uncontrolledOpen;
3943
+ const triggerRef = useRef(null);
3944
+ const interactedOutsideRef = useRef(false);
3945
+ const generatedId = useId();
3946
+ const contentId = `popover-${generatedId.replace(/:/g, "")}`;
3947
+ const setOpen = useCallback(
3948
+ (next) => {
3949
+ if (!isControlled) setUncontrolledOpen(next);
3950
+ onOpenChange?.(next);
3951
+ },
3952
+ [isControlled, onOpenChange]
3953
+ );
3954
+ const value = useMemo(
3955
+ () => ({ open, setOpen, triggerRef, contentId, anchorRect, interactedOutsideRef }),
3956
+ [open, setOpen, contentId, anchorRect]
3957
+ );
3958
+ return /* @__PURE__ */ jsx(PopoverCtx.Provider, { value, children });
3959
+ }
3960
+ var PopoverTrigger = forwardRef(
3961
+ function PopoverTrigger2({ asChild, onClick, children, ...rest }, forwardedRef) {
3962
+ const { open, setOpen, triggerRef, contentId } = usePopoverCtx("Popover.Trigger");
3963
+ const ariaProps = {
3964
+ "aria-haspopup": "dialog",
3965
+ "aria-expanded": open,
3966
+ "aria-controls": open ? contentId : void 0,
3967
+ "data-state": open ? "open" : "closed"
3968
+ };
3969
+ if (asChild) {
3970
+ if (!isValidElement(children)) {
3971
+ throw new Error("Popover.Trigger with `asChild` expects exactly one element child.");
3972
+ }
3973
+ const child = children;
3974
+ const childOnClick = child.props.onClick;
3975
+ return cloneElement(child, {
3976
+ ...rest,
3977
+ ...ariaProps,
3978
+ ref: composeRefs(child.props.ref, forwardedRef, triggerRef),
3979
+ onClick: (event) => {
3980
+ childOnClick?.(event);
3981
+ onClick?.(event);
3982
+ if (!event.defaultPrevented) setOpen(!open);
3983
+ }
3984
+ });
3985
+ }
3986
+ return /* @__PURE__ */ jsx(
3987
+ "button",
3988
+ {
3989
+ ref: composeRefs(forwardedRef, triggerRef),
3990
+ type: "button",
3991
+ ...ariaProps,
3992
+ onClick: (event) => {
3993
+ onClick?.(event);
3994
+ if (!event.defaultPrevented) setOpen(!open);
3995
+ },
3996
+ ...rest,
3997
+ children
3998
+ }
3999
+ );
4000
+ }
4001
+ );
4002
+ var PopoverContent = forwardRef(
4003
+ function PopoverContent2({
4004
+ children,
4005
+ side = "bottom",
4006
+ align = "start",
4007
+ offset = 6,
4008
+ alignOffset = 0,
4009
+ flip = true,
4010
+ clampToViewport = true,
4011
+ role = "dialog",
4012
+ unstyled,
4013
+ className,
4014
+ style,
4015
+ ...rest
4016
+ }, forwardedRef) {
4017
+ const { open, setOpen, triggerRef, contentId, anchorRect, interactedOutsideRef } = usePopoverCtx("Popover.Content");
4018
+ const contentRef = useRef(null);
4019
+ const {
4020
+ ref: positionRef,
4021
+ style: positionStyle,
4022
+ placement,
4023
+ positioned
4024
+ } = useAnchoredPosition({
4025
+ anchorRef: triggerRef,
4026
+ anchorRect,
4027
+ side,
4028
+ align,
4029
+ offset,
4030
+ alignOffset,
4031
+ flip,
4032
+ clampToViewport,
4033
+ enabled: open
4034
+ });
4035
+ const layer = useLayer({
4036
+ enabled: open,
4037
+ kind: "popover",
4038
+ elementRef: contentRef,
4039
+ onEscape: () => setOpen(false)
4040
+ });
4041
+ useOutsideClick(
4042
+ [triggerRef, contentRef],
4043
+ () => {
4044
+ interactedOutsideRef.current = true;
4045
+ setOpen(false);
4046
+ },
4047
+ { enabled: open, layer }
4048
+ );
4049
+ useEffect(() => {
4050
+ if (!open || !positioned) return;
4051
+ const node = contentRef.current;
4052
+ if (!node) return;
4053
+ interactedOutsideRef.current = false;
4054
+ const trigger = triggerRef.current;
4055
+ const previous = document.activeElement instanceof HTMLElement && document.activeElement !== document.body ? document.activeElement : null;
4056
+ const initial = node.querySelector("[data-autofocus]") ?? tabbablesWithin(node)[0] ?? node;
4057
+ initial.focus();
4058
+ return () => {
4059
+ if (interactedOutsideRef.current) return;
4060
+ const active = document.activeElement;
4061
+ if (active !== null && active !== document.body && !node.contains(active)) return;
4062
+ const target = trigger ?? previous;
4063
+ if (target?.isConnected) target.focus();
4064
+ };
4065
+ }, [open, positioned, triggerRef, interactedOutsideRef]);
4066
+ const ref = useMemo(
4067
+ () => composeRefs(forwardedRef, contentRef, positionRef),
4068
+ [forwardedRef, positionRef]
4069
+ );
4070
+ if (!open || typeof document === "undefined") return null;
4071
+ return createPortal(
4072
+ /* @__PURE__ */ jsx(
4073
+ "div",
4074
+ {
4075
+ ref,
4076
+ id: contentId,
4077
+ role: role === "none" ? void 0 : role,
4078
+ tabIndex: -1,
4079
+ "data-slot": "popover-content",
4080
+ "data-state": "open",
4081
+ "data-side": placement?.side,
4082
+ "data-align": placement?.align,
4083
+ "data-positioned": positioned ? "true" : "false",
4084
+ className: cn(
4085
+ "fixed z-[100] outline-none",
4086
+ !unstyled && "rounded-[var(--radius-lg)] p-3",
4087
+ positioned && "ds-enter-pop",
4088
+ className
4089
+ ),
4090
+ style: {
4091
+ ...positionStyle,
4092
+ ...unstyled ? void 0 : POPOVER_SURFACE_STYLE,
4093
+ ...style
4094
+ },
4095
+ ...rest,
4096
+ children
4097
+ }
4098
+ ),
4099
+ document.body
4100
+ );
4101
+ }
4102
+ );
4103
+ var Popover = Object.assign(PopoverRoot, {
4104
+ Trigger: PopoverTrigger,
4105
+ Content: PopoverContent
4106
+ });
3613
4107
  var DropdownMenuCtx = createContext(null);
3614
4108
  function useDropdownMenuCtx(consumer) {
3615
4109
  const ctx = useContext(DropdownMenuCtx);
@@ -3647,22 +4141,21 @@ function DropdownMenu({
3647
4141
  );
3648
4142
  return /* @__PURE__ */ jsx(DropdownMenuCtx.Provider, { value, children });
3649
4143
  }
3650
- function DropdownMenuTrigger({
3651
- unstyled,
3652
- className,
3653
- onClick,
3654
- children,
3655
- ...rest
3656
- }) {
4144
+ var DropdownMenuTrigger = forwardRef(function DropdownMenuTrigger2({ unstyled, className, onClick, children, ...rest }, forwardedRef) {
3657
4145
  const { open, setOpen, triggerRef, contentId } = useDropdownMenuCtx("DropdownMenuTrigger");
4146
+ const ref = useMemo(
4147
+ () => composeRefs(forwardedRef, triggerRef),
4148
+ [forwardedRef, triggerRef]
4149
+ );
3658
4150
  return /* @__PURE__ */ jsx(
3659
4151
  "button",
3660
4152
  {
3661
- ref: triggerRef,
4153
+ ref,
3662
4154
  type: "button",
3663
4155
  "aria-haspopup": "menu",
3664
4156
  "aria-expanded": open,
3665
4157
  "aria-controls": open ? contentId : void 0,
4158
+ "data-state": open ? "open" : "closed",
3666
4159
  className: cn(
3667
4160
  !unstyled && "btn btn-secondary",
3668
4161
  className
@@ -3675,8 +4168,8 @@ function DropdownMenuTrigger({
3675
4168
  children
3676
4169
  }
3677
4170
  );
3678
- }
3679
- function DropdownMenuContent({
4171
+ });
4172
+ var DropdownMenuContent = forwardRef(function DropdownMenuContent2({
3680
4173
  children,
3681
4174
  align = "start",
3682
4175
  alignOffset = 0,
@@ -3685,100 +4178,62 @@ function DropdownMenuContent({
3685
4178
  className,
3686
4179
  style,
3687
4180
  ...rest
3688
- }) {
4181
+ }, forwardedRef) {
3689
4182
  const { open, setOpen, triggerRef, contentId } = useDropdownMenuCtx("DropdownMenuContent");
3690
4183
  const contentRef = useRef(null);
3691
- const [position, setPosition] = useState(
3692
- null
3693
- );
3694
- useLayoutEffect(() => {
3695
- if (!open) {
3696
- setPosition(null);
3697
- return;
3698
- }
3699
- const measure = () => {
3700
- const triggerEl = triggerRef.current;
3701
- const contentEl = contentRef.current;
3702
- if (!triggerEl || !contentEl) return;
3703
- const triggerRect = triggerEl.getBoundingClientRect();
3704
- const contentRect = contentEl.getBoundingClientRect();
3705
- let left = triggerRect.left + alignOffset;
3706
- if (align === "end") left = triggerRect.right - contentRect.width - alignOffset;
3707
- else if (align === "center")
3708
- left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + alignOffset;
3709
- let top = side === "bottom" ? triggerRect.bottom + sideOffset : triggerRect.top - contentRect.height - sideOffset;
3710
- const gutter = 8;
3711
- const maxLeft = window.innerWidth - contentRect.width - gutter;
3712
- const maxTop = window.innerHeight - contentRect.height - gutter;
3713
- left = Math.max(gutter, Math.min(left, maxLeft));
3714
- top = Math.max(gutter, Math.min(top, maxTop));
3715
- setPosition({ left, top });
3716
- };
3717
- measure();
3718
- window.addEventListener("resize", measure);
3719
- window.addEventListener("scroll", measure, true);
3720
- return () => {
3721
- window.removeEventListener("resize", measure);
3722
- window.removeEventListener("scroll", measure, true);
3723
- };
3724
- }, [open, align, alignOffset, side, sideOffset, triggerRef]);
3725
- useEffect(() => {
3726
- if (!open) return;
3727
- const onPointerDown = (event) => {
3728
- const target = event.target;
3729
- if (!target) return;
3730
- if (contentRef.current?.contains(target)) return;
3731
- if (triggerRef.current?.contains(target)) return;
4184
+ const {
4185
+ ref: positionRef,
4186
+ style: positionStyle,
4187
+ placement,
4188
+ positioned
4189
+ } = useAnchoredPosition({
4190
+ anchorRef: triggerRef,
4191
+ side,
4192
+ align,
4193
+ offset: sideOffset,
4194
+ alignOffset,
4195
+ enabled: open
4196
+ });
4197
+ const layer = useLayer({
4198
+ enabled: open,
4199
+ kind: "popover",
4200
+ elementRef: contentRef,
4201
+ onEscape: () => {
3732
4202
  setOpen(false);
3733
- };
3734
- const onKeyDown = (event) => {
3735
- if (event.key === "Escape") {
3736
- event.stopPropagation();
3737
- setOpen(false);
3738
- triggerRef.current?.focus();
3739
- }
3740
- };
3741
- document.addEventListener("pointerdown", onPointerDown);
3742
- document.addEventListener("keydown", onKeyDown);
3743
- return () => {
3744
- document.removeEventListener("pointerdown", onPointerDown);
3745
- document.removeEventListener("keydown", onKeyDown);
3746
- };
3747
- }, [open, setOpen, triggerRef]);
4203
+ triggerRef.current?.focus();
4204
+ }
4205
+ });
4206
+ useOutsideClick([triggerRef, contentRef], () => setOpen(false), {
4207
+ enabled: open,
4208
+ layer
4209
+ });
4210
+ const ref = useMemo(
4211
+ () => composeRefs(forwardedRef, contentRef, positionRef),
4212
+ [forwardedRef, positionRef]
4213
+ );
3748
4214
  if (!open || typeof document === "undefined") return null;
3749
- const isPositioned = position !== null;
3750
4215
  return createPortal(
3751
4216
  /* @__PURE__ */ jsx(
3752
4217
  "div",
3753
4218
  {
3754
- ref: contentRef,
4219
+ ref,
3755
4220
  id: contentId,
3756
4221
  role: "menu",
3757
4222
  "data-slot": "dropdown-menu-content",
3758
4223
  "data-state": "open",
3759
- "data-positioned": isPositioned ? "true" : "false",
4224
+ "data-side": placement?.side,
4225
+ "data-align": placement?.align,
4226
+ "data-positioned": positioned ? "true" : "false",
3760
4227
  className: cn(
3761
4228
  "fixed z-[100] min-w-48 max-w-[min(28rem,calc(100vw-16px))]",
3762
4229
  "p-1.5 overflow-y-auto",
3763
4230
  "rounded-[var(--radius-lg)]",
3764
- isPositioned && "ds-enter-pop",
4231
+ positioned && "ds-enter-pop",
3765
4232
  className
3766
4233
  ),
3767
4234
  style: {
3768
- // Anchor the unpositioned phase WAY off-screen as a defense
3769
- // against any browser/renderer that doesn't fully respect
3770
- // visibility:hidden during a same-frame double-render. If the
3771
- // first paint slips through, it's at (-99999, -99999), not at
3772
- // viewport (0, 0) where a left-edge flash would be visible.
3773
- left: position?.left ?? -99999,
3774
- top: position?.top ?? -99999,
3775
- opacity: isPositioned ? void 0 : 0,
3776
- pointerEvents: isPositioned ? void 0 : "none",
3777
- visibility: isPositioned ? "visible" : "hidden",
3778
- background: "rgb(var(--popover))",
3779
- color: "rgb(var(--popover-foreground))",
3780
- border: "1px solid rgb(var(--border))",
3781
- boxShadow: "var(--shadow-lg, 0 10px 32px rgba(0,0,0,0.18))",
4235
+ ...positionStyle,
4236
+ ...POPOVER_SURFACE_STYLE,
3782
4237
  ...style
3783
4238
  },
3784
4239
  ...rest,
@@ -3787,19 +4242,13 @@ function DropdownMenuContent({
3787
4242
  ),
3788
4243
  document.body
3789
4244
  );
3790
- }
3791
- function DropdownMenuItem({
3792
- variant = "default",
3793
- inset,
3794
- className,
3795
- onClick,
3796
- children,
3797
- ...rest
3798
- }) {
4245
+ });
4246
+ var DropdownMenuItem = forwardRef(function DropdownMenuItem2({ variant = "default", inset, className, onClick, children, ...rest }, forwardedRef) {
3799
4247
  const { setOpen } = useDropdownMenuCtx("DropdownMenuItem");
3800
4248
  return /* @__PURE__ */ jsx(
3801
4249
  "button",
3802
4250
  {
4251
+ ref: forwardedRef,
3803
4252
  role: "menuitem",
3804
4253
  type: "button",
3805
4254
  "data-slot": "dropdown-menu-item",
@@ -3824,19 +4273,12 @@ function DropdownMenuItem({
3824
4273
  children
3825
4274
  }
3826
4275
  );
3827
- }
3828
- function DropdownMenuCheckboxItem({
3829
- checked,
3830
- onCheckedChange,
3831
- className,
3832
- children,
3833
- onClick,
3834
- disabled,
3835
- ...rest
3836
- }) {
4276
+ });
4277
+ var DropdownMenuCheckboxItem = forwardRef(function DropdownMenuCheckboxItem2({ checked, onCheckedChange, className, children, onClick, disabled, ...rest }, forwardedRef) {
3837
4278
  return /* @__PURE__ */ jsxs(
3838
4279
  "button",
3839
4280
  {
4281
+ ref: forwardedRef,
3840
4282
  role: "menuitemcheckbox",
3841
4283
  type: "button",
3842
4284
  "data-slot": "dropdown-menu-checkbox-item",
@@ -3870,7 +4312,7 @@ function DropdownMenuCheckboxItem({
3870
4312
  ]
3871
4313
  }
3872
4314
  );
3873
- }
4315
+ });
3874
4316
  function DropdownMenuSeparator({
3875
4317
  className,
3876
4318
  ...rest
@@ -5515,113 +5957,1169 @@ function DataGrid({
5515
5957
  sort: sort ?? null,
5516
5958
  onSortChange
5517
5959
  }
5518
- ) })
5960
+ ) })
5961
+ ]
5962
+ }
5963
+ ),
5964
+ renderDrawerPanel ? renderDrawerPanel(drawerPanelProps) : /* @__PURE__ */ jsx(
5965
+ DrawerPanel,
5966
+ {
5967
+ isOpen: drawerIsOpen,
5968
+ onClose: closeDrawer,
5969
+ drawerRow,
5970
+ drawerColumn,
5971
+ drawerCellValue,
5972
+ getRowLabel,
5973
+ isEditableColumn,
5974
+ isEmptyValue,
5975
+ modal: drawerModal,
5976
+ size: drawerSize ?? void 0
5977
+ }
5978
+ )
5979
+ ] });
5980
+ }
5981
+ function DataGridToolbar({
5982
+ search,
5983
+ children,
5984
+ className
5985
+ }) {
5986
+ return /* @__PURE__ */ jsxs(
5987
+ "div",
5988
+ {
5989
+ className: cn(
5990
+ "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
5991
+ className
5992
+ ),
5993
+ children: [
5994
+ search ? /* @__PURE__ */ jsx("div", { className: "w-full sm:max-w-sm", children: search }) : /* @__PURE__ */ jsx("span", {}),
5995
+ children ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 sm:justify-end", children }) : null
5996
+ ]
5997
+ }
5998
+ );
5999
+ }
6000
+ function DataGridColumnOptionsMenu({
6001
+ showSummaries,
6002
+ onShowSummariesChange,
6003
+ visibleColumns,
6004
+ visibleColumnIds,
6005
+ hiddenColumns,
6006
+ toggleColumnVisibility,
6007
+ optionsSensors,
6008
+ onOptionColumnDragEnd,
6009
+ optionsDndContextId,
6010
+ triggerLabel = "Options"
6011
+ }) {
6012
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
6013
+ /* @__PURE__ */ jsxs(DropdownMenuTrigger, { "aria-label": "Open table options", children: [
6014
+ /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4" }),
6015
+ /* @__PURE__ */ jsx("span", { children: triggerLabel })
6016
+ ] }),
6017
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
6018
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Options" }) }),
6019
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
6020
+ /* @__PURE__ */ jsx(
6021
+ DropdownMenuCheckboxItem,
6022
+ {
6023
+ checked: showSummaries,
6024
+ onCheckedChange: (checked) => onShowSummariesChange(checked === true),
6025
+ children: "Show summary row"
6026
+ }
6027
+ ),
6028
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
6029
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Columns" }) }),
6030
+ /* @__PURE__ */ jsx(
6031
+ DndContext,
6032
+ {
6033
+ id: optionsDndContextId,
6034
+ sensors: optionsSensors,
6035
+ collisionDetection: closestCenter,
6036
+ onDragEnd: onOptionColumnDragEnd,
6037
+ children: /* @__PURE__ */ jsx(
6038
+ SortableContext,
6039
+ {
6040
+ items: visibleColumns.map((column) => column.id),
6041
+ strategy: verticalListSortingStrategy,
6042
+ children: visibleColumns.map((column) => /* @__PURE__ */ jsx(
6043
+ SortableColumnOptionItem,
6044
+ {
6045
+ column,
6046
+ checked: true,
6047
+ disabled: visibleColumnIds.length === 1,
6048
+ onCheckedChange: (checked) => toggleColumnVisibility(column.id, checked)
6049
+ },
6050
+ column.id
6051
+ ))
6052
+ }
6053
+ )
6054
+ }
6055
+ ),
6056
+ hiddenColumns.length > 0 ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
6057
+ hiddenColumns.map((column) => /* @__PURE__ */ jsx(
6058
+ DropdownMenuCheckboxItem,
6059
+ {
6060
+ checked: false,
6061
+ onCheckedChange: (checked) => toggleColumnVisibility(column.id, checked === true),
6062
+ children: column.label
6063
+ },
6064
+ column.id
6065
+ ))
6066
+ ] })
6067
+ ] });
6068
+ }
6069
+ var SHELL_SIZE_CLASS = {
6070
+ sm: "size-sm",
6071
+ md: ""
6072
+ };
6073
+ var VALUE_SIZE_CLASS = {
6074
+ sm: "gap-2 pl-2.5 text-[12.5px]",
6075
+ md: "gap-2 pl-3 text-[13.5px]"
6076
+ };
6077
+ var LISTBOX_CLASS = "fixed z-[100] max-h-[min(60vh,20rem)] overflow-y-auto rounded-[var(--radius-lg)] p-1.5 outline-none";
6078
+ var TYPEAHEAD_RESET_MS = 500;
6079
+ function isPrintableKey(event) {
6080
+ return event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey;
6081
+ }
6082
+ function sanitizeId(id) {
6083
+ return id.replace(/[^a-zA-Z0-9_-]/g, "");
6084
+ }
6085
+ function ListboxOption({
6086
+ id,
6087
+ label,
6088
+ description,
6089
+ icon,
6090
+ count,
6091
+ selected,
6092
+ highlighted,
6093
+ disabled,
6094
+ onSelect,
6095
+ onHighlight,
6096
+ children
6097
+ }) {
6098
+ return /* @__PURE__ */ jsxs(
6099
+ "button",
6100
+ {
6101
+ type: "button",
6102
+ role: "option",
6103
+ id,
6104
+ "aria-selected": selected,
6105
+ "aria-disabled": disabled ? true : void 0,
6106
+ tabIndex: -1,
6107
+ "data-slot": "listbox-option",
6108
+ "data-highlighted": highlighted ? "" : void 0,
6109
+ "data-selected": selected ? "" : void 0,
6110
+ "data-disabled": disabled ? "" : void 0,
6111
+ className: cn(
6112
+ "flex w-full cursor-default items-center gap-2.5 text-left",
6113
+ "rounded-[var(--radius-md)] px-2.5 py-2 text-[13px] font-medium",
6114
+ "outline-none transition-colors",
6115
+ "aria-disabled:pointer-events-none aria-disabled:opacity-50"
6116
+ ),
6117
+ style: {
6118
+ background: highlighted ? "rgb(var(--surface-overlay))" : "transparent",
6119
+ color: "rgb(var(--foreground))"
6120
+ },
6121
+ onClick: () => {
6122
+ if (!disabled) onSelect();
6123
+ },
6124
+ onPointerMove: () => {
6125
+ if (!disabled && !highlighted) onHighlight();
6126
+ },
6127
+ children: [
6128
+ children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
6129
+ icon ? /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: icon }) : null,
6130
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
6131
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: label }),
6132
+ description ? /* @__PURE__ */ jsx(
6133
+ "span",
6134
+ {
6135
+ className: "block truncate text-[11.5px] font-normal",
6136
+ style: { color: "rgb(var(--text-tertiary))" },
6137
+ children: description
6138
+ }
6139
+ ) : null
6140
+ ] }),
6141
+ typeof count === "number" ? /* @__PURE__ */ jsx(
6142
+ "span",
6143
+ {
6144
+ className: "shrink-0 text-[11px] font-medium tabular-nums",
6145
+ style: { color: "rgb(var(--text-muted))" },
6146
+ children: count.toLocaleString()
6147
+ }
6148
+ ) : null
6149
+ ] }),
6150
+ /* @__PURE__ */ jsx("span", { className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center", "aria-hidden": "true", children: selected ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5", style: { color: "rgb(var(--accent))" } }) : null })
6151
+ ]
6152
+ }
6153
+ );
6154
+ }
6155
+ var SelectImpl = forwardRef(function Select({
6156
+ options,
6157
+ value: valueProp,
6158
+ defaultValue = null,
6159
+ onValueChange,
6160
+ placeholder = "Select\u2026",
6161
+ size = "md",
6162
+ error,
6163
+ open: openProp,
6164
+ defaultOpen,
6165
+ onOpenChange,
6166
+ side = "bottom",
6167
+ align = "start",
6168
+ listboxClassName,
6169
+ id,
6170
+ className,
6171
+ style,
6172
+ disabled,
6173
+ onClick,
6174
+ onKeyDown,
6175
+ "aria-label": ariaLabel,
6176
+ "aria-labelledby": ariaLabelledby,
6177
+ ...rest
6178
+ }, forwardedRef) {
6179
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
6180
+ const isControlledValue = valueProp !== void 0;
6181
+ const value = isControlledValue ? valueProp : uncontrolledValue;
6182
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));
6183
+ const isControlledOpen = openProp !== void 0;
6184
+ const open = isControlledOpen ? Boolean(openProp) : uncontrolledOpen;
6185
+ const setOpen = useCallback(
6186
+ (next) => {
6187
+ if (!isControlledOpen) setUncontrolledOpen(next);
6188
+ onOpenChange?.(next);
6189
+ },
6190
+ [isControlledOpen, onOpenChange]
6191
+ );
6192
+ const triggerRef = useRef(null);
6193
+ const listboxRef = useRef(null);
6194
+ const baseId = sanitizeId(useId());
6195
+ const triggerId = id ?? `select-${baseId}`;
6196
+ const listboxId = `select-listbox-${baseId}`;
6197
+ const optionId = (index) => `${listboxId}-opt-${index}`;
6198
+ const selectedIndex = useMemo(
6199
+ () => options.findIndex((option) => option.value === value),
6200
+ [options, value]
6201
+ );
6202
+ const selected = selectedIndex >= 0 ? options[selectedIndex] : void 0;
6203
+ const firstEnabled = options.findIndex((option) => !option.disabled);
6204
+ let lastEnabled = -1;
6205
+ for (let i = options.length - 1; i >= 0; i--) {
6206
+ if (!options[i]?.disabled) {
6207
+ lastEnabled = i;
6208
+ break;
6209
+ }
6210
+ }
6211
+ const [highlight, setHighlight] = useState(null);
6212
+ const activeIndex = highlight !== null && highlight < options.length ? highlight : selectedIndex >= 0 ? selectedIndex : firstEnabled;
6213
+ const openList = useCallback(
6214
+ (initial) => {
6215
+ setHighlight(initial);
6216
+ setOpen(true);
6217
+ },
6218
+ [setOpen]
6219
+ );
6220
+ const closeList = useCallback(() => {
6221
+ setOpen(false);
6222
+ setHighlight(null);
6223
+ }, [setOpen]);
6224
+ const commit = (index) => {
6225
+ const option = options[index];
6226
+ if (!option || option.disabled) return;
6227
+ if (option.value !== value) {
6228
+ if (!isControlledValue) setUncontrolledValue(option.value);
6229
+ onValueChange?.(option.value);
6230
+ }
6231
+ closeList();
6232
+ triggerRef.current?.focus();
6233
+ };
6234
+ const step = (from, direction) => {
6235
+ for (let i = from + direction; i >= 0 && i < options.length; i += direction) {
6236
+ if (!options[i]?.disabled) return i;
6237
+ }
6238
+ return from;
6239
+ };
6240
+ const typeaheadRef = useRef({ text: "", timer: null });
6241
+ useEffect(() => {
6242
+ const state = typeaheadRef.current;
6243
+ return () => {
6244
+ if (state.timer !== null) window.clearTimeout(state.timer);
6245
+ };
6246
+ }, []);
6247
+ const typeahead = (char, from) => {
6248
+ const state = typeaheadRef.current;
6249
+ if (state.timer !== null) window.clearTimeout(state.timer);
6250
+ state.text += char.toLowerCase();
6251
+ state.timer = window.setTimeout(() => {
6252
+ state.text = "";
6253
+ state.timer = null;
6254
+ }, TYPEAHEAD_RESET_MS);
6255
+ const typed = state.text;
6256
+ const first = typed.charAt(0);
6257
+ const repeated = typed.length > 1 && typed.split("").every((c) => c === first);
6258
+ const needle = repeated ? first : typed;
6259
+ const count = options.length;
6260
+ if (count === 0) return null;
6261
+ const startAt = needle.length === 1 ? from + 1 : Math.max(from, 0);
6262
+ for (let k = 0; k < count; k++) {
6263
+ const i = (startAt + k) % count;
6264
+ const option = options[i];
6265
+ if (option && !option.disabled && option.label.toLowerCase().startsWith(needle)) return i;
6266
+ }
6267
+ return null;
6268
+ };
6269
+ const handleKeyDown = (event) => {
6270
+ onKeyDown?.(event);
6271
+ if (event.defaultPrevented) return;
6272
+ const { key } = event;
6273
+ if (!open) {
6274
+ if (key === "ArrowDown" || key === "ArrowUp" || key === "Enter" || key === " ") {
6275
+ event.preventDefault();
6276
+ openList(null);
6277
+ return;
6278
+ }
6279
+ if (key === "Home" || key === "End") {
6280
+ event.preventDefault();
6281
+ openList(key === "Home" ? firstEnabled : lastEnabled);
6282
+ return;
6283
+ }
6284
+ if (isPrintableKey(event)) {
6285
+ event.preventDefault();
6286
+ openList(typeahead(key, selectedIndex));
6287
+ }
6288
+ return;
6289
+ }
6290
+ switch (key) {
6291
+ case "ArrowDown":
6292
+ event.preventDefault();
6293
+ setHighlight(step(activeIndex, 1));
6294
+ return;
6295
+ case "ArrowUp":
6296
+ event.preventDefault();
6297
+ setHighlight(step(activeIndex, -1));
6298
+ return;
6299
+ case "Home":
6300
+ event.preventDefault();
6301
+ setHighlight(firstEnabled);
6302
+ return;
6303
+ case "End":
6304
+ event.preventDefault();
6305
+ setHighlight(lastEnabled);
6306
+ return;
6307
+ case "Enter":
6308
+ case " ":
6309
+ event.preventDefault();
6310
+ commit(activeIndex);
6311
+ return;
6312
+ case "Tab":
6313
+ closeList();
6314
+ return;
6315
+ case "Escape":
6316
+ return;
6317
+ default:
6318
+ if (isPrintableKey(event)) {
6319
+ event.preventDefault();
6320
+ const match = typeahead(key, activeIndex);
6321
+ if (match !== null) setHighlight(match);
6322
+ }
6323
+ }
6324
+ };
6325
+ const {
6326
+ ref: positionRef,
6327
+ style: positionStyle,
6328
+ placement,
6329
+ positioned
6330
+ } = useAnchoredPosition({
6331
+ anchorRef: triggerRef,
6332
+ side,
6333
+ align,
6334
+ enabled: open
6335
+ });
6336
+ const layer = useLayer({
6337
+ enabled: open,
6338
+ kind: "popover",
6339
+ elementRef: listboxRef,
6340
+ onEscape: () => {
6341
+ closeList();
6342
+ triggerRef.current?.focus();
6343
+ }
6344
+ });
6345
+ useOutsideClick([triggerRef, listboxRef], closeList, { enabled: open, layer });
6346
+ const [triggerWidth, setTriggerWidth] = useState(null);
6347
+ useLayoutEffect(() => {
6348
+ if (!open) return;
6349
+ setTriggerWidth(triggerRef.current?.offsetWidth ?? null);
6350
+ }, [open]);
6351
+ useEffect(() => {
6352
+ if (!open) return;
6353
+ listboxRef.current?.querySelector("[data-highlighted]")?.scrollIntoView({ block: "nearest" });
6354
+ }, [open, activeIndex]);
6355
+ const triggerRefs = useMemo(
6356
+ () => composeRefs(forwardedRef, triggerRef),
6357
+ [forwardedRef]
6358
+ );
6359
+ const listboxRefs = useMemo(
6360
+ () => composeRefs(listboxRef, positionRef),
6361
+ [positionRef]
6362
+ );
6363
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6364
+ /* @__PURE__ */ jsxs(
6365
+ "button",
6366
+ {
6367
+ ref: triggerRefs,
6368
+ id: triggerId,
6369
+ type: "button",
6370
+ role: "combobox",
6371
+ "aria-haspopup": "listbox",
6372
+ "aria-expanded": open,
6373
+ "aria-controls": open ? listboxId : void 0,
6374
+ "aria-activedescendant": open && activeIndex >= 0 ? optionId(activeIndex) : void 0,
6375
+ "aria-label": ariaLabel,
6376
+ "aria-labelledby": ariaLabelledby,
6377
+ "aria-invalid": error ? true : void 0,
6378
+ disabled,
6379
+ "data-slot": "select-trigger",
6380
+ "data-state": open ? "open" : "closed",
6381
+ "data-size": size,
6382
+ "data-placeholder": selected ? void 0 : "",
6383
+ className: cn(
6384
+ "input-shell appearance-none p-0 text-left",
6385
+ SHELL_SIZE_CLASS[size],
6386
+ error && "is-error",
6387
+ disabled && "is-disabled",
6388
+ className
6389
+ ),
6390
+ style: { alignItems: "center", ...style },
6391
+ onClick: (event) => {
6392
+ onClick?.(event);
6393
+ if (event.defaultPrevented) return;
6394
+ if (open) closeList();
6395
+ else openList(null);
6396
+ },
6397
+ onKeyDown: handleKeyDown,
6398
+ ...rest,
6399
+ children: [
6400
+ /* @__PURE__ */ jsxs(
6401
+ "span",
6402
+ {
6403
+ "data-slot": "select-value",
6404
+ className: cn(
6405
+ "flex min-w-0 flex-1 items-center font-medium leading-[1.4]",
6406
+ VALUE_SIZE_CLASS[size]
6407
+ ),
6408
+ children: [
6409
+ selected?.icon ? /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: selected.icon }) : null,
6410
+ /* @__PURE__ */ jsx(
6411
+ "span",
6412
+ {
6413
+ className: "truncate",
6414
+ style: {
6415
+ color: selected ? "rgb(var(--foreground))" : "rgb(var(--text-tertiary))"
6416
+ },
6417
+ children: selected ? selected.label : placeholder
6418
+ }
6419
+ )
6420
+ ]
6421
+ }
6422
+ ),
6423
+ /* @__PURE__ */ jsx("span", { className: "affix", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
6424
+ ChevronDown,
6425
+ {
6426
+ className: cn(
6427
+ "h-4 w-4 transition-transform duration-[var(--dur-fast)] ease-[var(--ease-out)] motion-reduce:transition-none",
6428
+ open && "rotate-180"
6429
+ )
6430
+ }
6431
+ ) })
6432
+ ]
6433
+ }
6434
+ ),
6435
+ open && typeof document !== "undefined" ? createPortal(
6436
+ /* @__PURE__ */ jsx(
6437
+ "div",
6438
+ {
6439
+ ref: listboxRefs,
6440
+ id: listboxId,
6441
+ role: "listbox",
6442
+ "aria-label": ariaLabelledby ? void 0 : ariaLabel,
6443
+ "aria-labelledby": ariaLabelledby ?? (ariaLabel ? void 0 : triggerId),
6444
+ tabIndex: -1,
6445
+ "data-slot": "select-listbox",
6446
+ "data-state": "open",
6447
+ "data-side": placement?.side,
6448
+ "data-align": placement?.align,
6449
+ "data-positioned": positioned ? "true" : "false",
6450
+ className: cn(LISTBOX_CLASS, positioned && "ds-enter-pop", listboxClassName),
6451
+ style: {
6452
+ ...positionStyle,
6453
+ ...POPOVER_SURFACE_STYLE,
6454
+ ...triggerWidth ? { minWidth: triggerWidth } : void 0
6455
+ },
6456
+ onMouseDown: (event) => event.preventDefault(),
6457
+ children: options.length === 0 ? /* @__PURE__ */ jsx(
6458
+ "div",
6459
+ {
6460
+ "data-slot": "select-empty",
6461
+ className: "px-2.5 py-2 text-[12.5px]",
6462
+ style: { color: "rgb(var(--text-tertiary))" },
6463
+ children: "No options"
6464
+ }
6465
+ ) : options.map((option, index) => /* @__PURE__ */ jsx(
6466
+ ListboxOption,
6467
+ {
6468
+ id: optionId(index),
6469
+ label: option.label,
6470
+ description: option.description,
6471
+ icon: option.icon,
6472
+ selected: option.value === value,
6473
+ highlighted: index === activeIndex,
6474
+ disabled: option.disabled,
6475
+ onSelect: () => commit(index),
6476
+ onHighlight: () => setHighlight(index)
6477
+ },
6478
+ option.value
6479
+ ))
6480
+ }
6481
+ ),
6482
+ document.body
6483
+ ) : null
6484
+ ] });
6485
+ });
6486
+ var Select2 = SelectImpl;
6487
+ var SHELL_SIZE_CLASS2 = {
6488
+ sm: "size-sm",
6489
+ md: ""
6490
+ };
6491
+ var MULTI_SHELL_STYLE = {
6492
+ sm: {
6493
+ height: "auto",
6494
+ minHeight: "var(--ctrl-sm)",
6495
+ alignItems: "center",
6496
+ flexWrap: "wrap",
6497
+ gap: "var(--space-1)",
6498
+ paddingTop: "var(--space-1)",
6499
+ paddingBottom: "var(--space-1)"
6500
+ },
6501
+ md: {
6502
+ height: "auto",
6503
+ minHeight: "var(--ctrl-md)",
6504
+ alignItems: "center",
6505
+ flexWrap: "wrap",
6506
+ gap: "var(--space-1)",
6507
+ paddingTop: "var(--space-1)",
6508
+ paddingBottom: "var(--space-1)"
6509
+ }
6510
+ };
6511
+ var MULTI_INPUT_STYLE = { minWidth: "6rem" };
6512
+ function defaultFilter(option, query) {
6513
+ const needle = query.toLowerCase();
6514
+ return option.label.toLowerCase().includes(needle) || (option.description?.toLowerCase().includes(needle) ?? false);
6515
+ }
6516
+ function sanitizeId2(id) {
6517
+ return id.replace(/[^a-zA-Z0-9_-]/g, "");
6518
+ }
6519
+ var ComboboxImpl = forwardRef(function Combobox(props, forwardedRef) {
6520
+ const {
6521
+ options,
6522
+ groups,
6523
+ loading,
6524
+ placeholder,
6525
+ size = "md",
6526
+ disabled,
6527
+ error,
6528
+ inputValue: inputValueProp,
6529
+ defaultInputValue = "",
6530
+ onInputValueChange,
6531
+ shouldFilter = true,
6532
+ filter,
6533
+ emptyMessage = "No results",
6534
+ loadingMessage = "Loading\u2026",
6535
+ renderOption,
6536
+ open: openProp,
6537
+ onOpenChange,
6538
+ side = "bottom",
6539
+ align = "start",
6540
+ id,
6541
+ autoFocus,
6542
+ "aria-label": ariaLabel,
6543
+ "aria-labelledby": ariaLabelledby,
6544
+ className,
6545
+ listboxClassName
6546
+ } = props;
6547
+ const isMultiple = props.multiple === true;
6548
+ const [uncontrolledSelection, setUncontrolledSelection] = useState(() => {
6549
+ if (props.multiple === true) return [...props.defaultValue ?? []];
6550
+ return props.defaultValue == null ? [] : [props.defaultValue];
6551
+ });
6552
+ const isControlledValue = props.value !== void 0;
6553
+ const selection = props.value === void 0 ? uncontrolledSelection : props.multiple === true ? props.value : props.value === null ? [] : [props.value];
6554
+ const emit = (next) => {
6555
+ if (!isControlledValue) setUncontrolledSelection(next);
6556
+ if (props.multiple === true) props.onValueChange?.(next);
6557
+ else props.onValueChange?.(next[0] ?? null);
6558
+ };
6559
+ const [uncontrolledInput, setUncontrolledInput] = useState(defaultInputValue);
6560
+ const inputValue = inputValueProp ?? uncontrolledInput;
6561
+ const setInputValue = (next) => {
6562
+ if (inputValueProp === void 0) setUncontrolledInput(next);
6563
+ onInputValueChange?.(next);
6564
+ };
6565
+ const [dirty, setDirty] = useState(false);
6566
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
6567
+ const isControlledOpen = openProp !== void 0;
6568
+ const open = isControlledOpen ? Boolean(openProp) : uncontrolledOpen;
6569
+ const setOpen = useCallback(
6570
+ (next) => {
6571
+ if (!isControlledOpen) setUncontrolledOpen(next);
6572
+ onOpenChange?.(next);
6573
+ },
6574
+ [isControlledOpen, onOpenChange]
6575
+ );
6576
+ const openRef = useRef(open);
6577
+ useLayoutEffect(() => {
6578
+ openRef.current = open;
6579
+ });
6580
+ const shellRef = useRef(null);
6581
+ const inputRef = useRef(null);
6582
+ const listboxRef = useRef(null);
6583
+ const baseId = sanitizeId2(useId());
6584
+ const inputId = id ?? `combobox-${baseId}`;
6585
+ const listboxId = `combobox-listbox-${baseId}`;
6586
+ const optionId = (index) => `${listboxId}-opt-${index}`;
6587
+ const byValue = useMemo(() => {
6588
+ const map = /* @__PURE__ */ new Map();
6589
+ for (const option of options) map.set(option.value, option);
6590
+ return map;
6591
+ }, [options]);
6592
+ const selectedSingle = isMultiple ? void 0 : byValue.get(selection[0] ?? "");
6593
+ const filterQuery = dirty ? inputValue.trim() : "";
6594
+ const { sections, flat } = useMemo(() => {
6595
+ const matches = filter ?? defaultFilter;
6596
+ const visible = shouldFilter && filterQuery ? options.filter((option) => matches(option, filterQuery)) : options;
6597
+ const byGroup = /* @__PURE__ */ new Map();
6598
+ for (const option of visible) {
6599
+ const key = option.group ?? null;
6600
+ const list = byGroup.get(key) ?? [];
6601
+ list.push(option);
6602
+ byGroup.set(key, list);
6603
+ }
6604
+ const order = [{ key: null, label: null }];
6605
+ if (groups) {
6606
+ for (const group of groups) order.push({ key: group.id, label: group.label });
6607
+ for (const key of byGroup.keys()) {
6608
+ if (key !== null && !groups.some((group) => group.id === key)) {
6609
+ order.push({ key, label: key });
6610
+ }
6611
+ }
6612
+ } else {
6613
+ for (const key of byGroup.keys()) if (key !== null) order.push({ key, label: key });
6614
+ }
6615
+ const flatList = [];
6616
+ const sectionList = [];
6617
+ for (const { key, label } of order) {
6618
+ const members = byGroup.get(key);
6619
+ if (!members || members.length === 0) continue;
6620
+ sectionList.push({
6621
+ key: key ?? "__ungrouped",
6622
+ label,
6623
+ items: members.map((option) => ({ option, index: flatList.push(option) - 1 }))
6624
+ });
6625
+ }
6626
+ return { sections: sectionList, flat: flatList };
6627
+ }, [options, groups, filter, shouldFilter, filterQuery]);
6628
+ const firstEnabled = flat.findIndex((option) => !option.disabled);
6629
+ const selectedFlatIndex = !isMultiple && !dirty && selectedSingle ? flat.findIndex((option) => option.value === selectedSingle.value) : -1;
6630
+ const [highlight, setHighlight] = useState(null);
6631
+ const activeIndex = highlight !== null && highlight < flat.length ? highlight : selectedFlatIndex >= 0 ? selectedFlatIndex : firstEnabled;
6632
+ const step = (from, direction) => {
6633
+ for (let i = from + direction; i >= 0 && i < flat.length; i += direction) {
6634
+ if (!flat[i]?.disabled) return i;
6635
+ }
6636
+ return from;
6637
+ };
6638
+ const openList = () => {
6639
+ if (openRef.current) return;
6640
+ setHighlight(null);
6641
+ setOpen(true);
6642
+ };
6643
+ const closeList = (clearIfEmpty) => {
6644
+ if (!openRef.current) return;
6645
+ openRef.current = false;
6646
+ if (!isMultiple && clearIfEmpty && dirty && inputValue.trim() === "" && selection.length > 0) {
6647
+ emit([]);
6648
+ }
6649
+ if (isMultiple && inputValue !== "") setInputValue("");
6650
+ setDirty(false);
6651
+ setHighlight(null);
6652
+ setOpen(false);
6653
+ };
6654
+ const choose = (index) => {
6655
+ const option = flat[index];
6656
+ if (!option || option.disabled) return;
6657
+ if (isMultiple) {
6658
+ const has = selection.includes(option.value);
6659
+ emit(has ? selection.filter((value) => value !== option.value) : [...selection, option.value]);
6660
+ } else {
6661
+ if (selection[0] !== option.value) emit([option.value]);
6662
+ closeList(false);
6663
+ }
6664
+ inputRef.current?.focus();
6665
+ };
6666
+ const removeChip = (value) => {
6667
+ emit(selection.filter((candidate) => candidate !== value));
6668
+ inputRef.current?.focus();
6669
+ };
6670
+ const text = isMultiple || dirty ? inputValue : selectedSingle?.label ?? "";
6671
+ const handleChange = (next) => {
6672
+ setInputValue(next);
6673
+ setDirty(true);
6674
+ setHighlight(null);
6675
+ if (!openRef.current) setOpen(true);
6676
+ };
6677
+ const handleKeyDown = (event) => {
6678
+ switch (event.key) {
6679
+ case "ArrowDown":
6680
+ event.preventDefault();
6681
+ if (!open) openList();
6682
+ else setHighlight(step(activeIndex, 1));
6683
+ return;
6684
+ case "ArrowUp":
6685
+ event.preventDefault();
6686
+ if (!open) openList();
6687
+ else setHighlight(step(activeIndex, -1));
6688
+ return;
6689
+ case "Enter":
6690
+ if (open) {
6691
+ event.preventDefault();
6692
+ if (activeIndex >= 0) choose(activeIndex);
6693
+ }
6694
+ return;
6695
+ case "Backspace":
6696
+ if (isMultiple && text === "" && selection.length > 0) {
6697
+ event.preventDefault();
6698
+ emit(selection.slice(0, -1));
6699
+ }
6700
+ return;
6701
+ case "Tab":
6702
+ if (open) closeList(true);
6703
+ return;
6704
+ default:
6705
+ return;
6706
+ }
6707
+ };
6708
+ const handleBlur = (event) => {
6709
+ if (event.relatedTarget instanceof Node && shellRef.current?.contains(event.relatedTarget)) {
6710
+ return;
6711
+ }
6712
+ closeList(true);
6713
+ };
6714
+ const {
6715
+ ref: positionRef,
6716
+ style: positionStyle,
6717
+ placement,
6718
+ positioned
6719
+ } = useAnchoredPosition({
6720
+ anchorRef: shellRef,
6721
+ side,
6722
+ align,
6723
+ enabled: open
6724
+ });
6725
+ const layer = useLayer({
6726
+ enabled: open,
6727
+ kind: "popover",
6728
+ elementRef: listboxRef,
6729
+ onEscape: () => closeList(false)
6730
+ });
6731
+ useOutsideClick([shellRef, listboxRef], () => closeList(true), { enabled: open, layer });
6732
+ const [shellWidth, setShellWidth] = useState(null);
6733
+ useLayoutEffect(() => {
6734
+ if (!open) return;
6735
+ setShellWidth(shellRef.current?.offsetWidth ?? null);
6736
+ }, [open]);
6737
+ useEffect(() => {
6738
+ if (!open) return;
6739
+ listboxRef.current?.querySelector("[data-highlighted]")?.scrollIntoView({ block: "nearest" });
6740
+ }, [open, activeIndex]);
6741
+ useEffect(() => {
6742
+ if (!autoFocus) return;
6743
+ const node = inputRef.current;
6744
+ if (!node) return;
6745
+ if (node.closest('[data-positioned="false"]')) return;
6746
+ node.focus();
6747
+ }, []);
6748
+ const inputRefs = useMemo(
6749
+ () => composeRefs(forwardedRef, inputRef),
6750
+ [forwardedRef]
6751
+ );
6752
+ const listboxRefs = useMemo(
6753
+ () => composeRefs(listboxRef, positionRef),
6754
+ [positionRef]
6755
+ );
6756
+ const chips = isMultiple ? selection : [];
6757
+ const hasChips = chips.length > 0;
6758
+ const shellStyle = isMultiple ? hasChips ? { ...MULTI_SHELL_STYLE[size], paddingLeft: "var(--space-2)" } : MULTI_SHELL_STYLE[size] : void 0;
6759
+ const renderItem = ({ option, index }) => {
6760
+ const selected = selection.includes(option.value);
6761
+ const highlighted = index === activeIndex;
6762
+ return /* @__PURE__ */ jsx(
6763
+ ListboxOption,
6764
+ {
6765
+ id: optionId(index),
6766
+ label: option.label,
6767
+ description: option.description,
6768
+ icon: option.icon,
6769
+ count: option.count,
6770
+ selected,
6771
+ highlighted,
6772
+ disabled: option.disabled,
6773
+ onSelect: () => choose(index),
6774
+ onHighlight: () => setHighlight(index),
6775
+ children: renderOption ? renderOption(option, { selected, highlighted, query: filterQuery }) : void 0
6776
+ },
6777
+ option.value
6778
+ );
6779
+ };
6780
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6781
+ /* @__PURE__ */ jsxs(
6782
+ "div",
6783
+ {
6784
+ ref: shellRef,
6785
+ "data-slot": "combobox",
6786
+ "data-state": open ? "open" : "closed",
6787
+ "data-size": size,
6788
+ className: cn(
6789
+ "input-shell has-trailing",
6790
+ SHELL_SIZE_CLASS2[size],
6791
+ hasChips && "has-leading",
6792
+ error && "is-error",
6793
+ disabled && "is-disabled",
6794
+ className
6795
+ ),
6796
+ style: shellStyle,
6797
+ children: [
6798
+ chips.map((value) => {
6799
+ const label = byValue.get(value)?.label ?? value;
6800
+ return /* @__PURE__ */ jsxs(
6801
+ "span",
6802
+ {
6803
+ "data-slot": "combobox-chip",
6804
+ className: "inline-flex items-center gap-1 rounded-[var(--radius-xs)] py-0.5 pl-2 pr-1 text-[12px] font-medium",
6805
+ style: {
6806
+ background: "rgb(var(--surface-overlay))",
6807
+ color: "rgb(var(--foreground))"
6808
+ },
6809
+ children: [
6810
+ /* @__PURE__ */ jsx("span", { className: "max-w-[12rem] truncate", children: label }),
6811
+ /* @__PURE__ */ jsx(
6812
+ "button",
6813
+ {
6814
+ type: "button",
6815
+ "aria-label": `Remove ${label}`,
6816
+ disabled,
6817
+ onClick: () => removeChip(value),
6818
+ className: "inline-flex h-4 w-4 items-center justify-center rounded-[var(--radius-xs)] transition-colors hover:bg-[rgb(var(--surface-overlay-strong))]",
6819
+ style: { color: "rgb(var(--text-muted))" },
6820
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3", "aria-hidden": "true" })
6821
+ }
6822
+ )
6823
+ ]
6824
+ },
6825
+ value
6826
+ );
6827
+ }),
6828
+ /* @__PURE__ */ jsx(
6829
+ "input",
6830
+ {
6831
+ ref: inputRefs,
6832
+ id: inputId,
6833
+ type: "text",
6834
+ role: "combobox",
6835
+ "aria-haspopup": "listbox",
6836
+ "aria-expanded": open,
6837
+ "aria-controls": open ? listboxId : void 0,
6838
+ "aria-autocomplete": "list",
6839
+ "aria-activedescendant": open && activeIndex >= 0 ? optionId(activeIndex) : void 0,
6840
+ "aria-label": ariaLabel,
6841
+ "aria-labelledby": ariaLabelledby,
6842
+ "aria-invalid": error ? true : void 0,
6843
+ autoComplete: "off",
6844
+ spellCheck: false,
6845
+ disabled,
6846
+ placeholder: hasChips ? "" : placeholder,
6847
+ value: text,
6848
+ "data-slot": "combobox-input",
6849
+ "data-autofocus": autoFocus ? "" : void 0,
6850
+ style: isMultiple ? MULTI_INPUT_STYLE : void 0,
6851
+ onChange: (event) => handleChange(event.target.value),
6852
+ onKeyDown: handleKeyDown,
6853
+ onClick: openList,
6854
+ onFocus: (event) => event.currentTarget.select(),
6855
+ onBlur: handleBlur
6856
+ }
6857
+ ),
6858
+ loading ? /* @__PURE__ */ jsx("span", { className: "affix", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin motion-reduce:animate-none" }) }) : null,
6859
+ /* @__PURE__ */ jsx(
6860
+ "button",
6861
+ {
6862
+ type: "button",
6863
+ tabIndex: -1,
6864
+ "aria-label": open ? "Close options" : "Open options",
6865
+ disabled,
6866
+ className: "affix action",
6867
+ onMouseDown: (event) => event.preventDefault(),
6868
+ onClick: () => {
6869
+ if (open) closeList(false);
6870
+ else openList();
6871
+ inputRef.current?.focus();
6872
+ },
6873
+ children: /* @__PURE__ */ jsx(
6874
+ ChevronDown,
6875
+ {
6876
+ className: cn(
6877
+ "h-4 w-4 transition-transform duration-[var(--dur-fast)] ease-[var(--ease-out)] motion-reduce:transition-none",
6878
+ open && "rotate-180"
6879
+ ),
6880
+ "aria-hidden": "true"
6881
+ }
6882
+ )
6883
+ }
6884
+ )
5519
6885
  ]
5520
6886
  }
5521
6887
  ),
5522
- renderDrawerPanel ? renderDrawerPanel(drawerPanelProps) : /* @__PURE__ */ jsx(
5523
- DrawerPanel,
5524
- {
5525
- isOpen: drawerIsOpen,
5526
- onClose: closeDrawer,
5527
- drawerRow,
5528
- drawerColumn,
5529
- drawerCellValue,
5530
- getRowLabel,
5531
- isEditableColumn,
5532
- isEmptyValue,
5533
- modal: drawerModal,
5534
- size: drawerSize ?? void 0
5535
- }
5536
- )
6888
+ open && typeof document !== "undefined" ? createPortal(
6889
+ /* @__PURE__ */ jsx(
6890
+ "div",
6891
+ {
6892
+ ref: listboxRefs,
6893
+ id: listboxId,
6894
+ role: "listbox",
6895
+ "aria-multiselectable": isMultiple || void 0,
6896
+ "aria-busy": loading || void 0,
6897
+ "aria-label": ariaLabelledby ? void 0 : ariaLabel,
6898
+ "aria-labelledby": ariaLabelledby,
6899
+ tabIndex: -1,
6900
+ "data-slot": "combobox-listbox",
6901
+ "data-state": "open",
6902
+ "data-side": placement?.side,
6903
+ "data-align": placement?.align,
6904
+ "data-positioned": positioned ? "true" : "false",
6905
+ className: cn(LISTBOX_CLASS, positioned && "ds-enter-pop", listboxClassName),
6906
+ style: {
6907
+ ...positionStyle,
6908
+ ...POPOVER_SURFACE_STYLE,
6909
+ ...shellWidth ? { minWidth: shellWidth } : void 0
6910
+ },
6911
+ onMouseDown: (event) => event.preventDefault(),
6912
+ children: flat.length === 0 ? /* @__PURE__ */ jsx(
6913
+ "div",
6914
+ {
6915
+ "data-slot": "combobox-empty",
6916
+ className: "px-2.5 py-2 text-[12.5px]",
6917
+ style: { color: "rgb(var(--text-tertiary))" },
6918
+ children: loading ? loadingMessage : emptyMessage
6919
+ }
6920
+ ) : sections.map(
6921
+ (section) => section.label === null ? section.items.map(renderItem) : /* @__PURE__ */ jsxs(
6922
+ "div",
6923
+ {
6924
+ role: "group",
6925
+ "aria-labelledby": `${listboxId}-group-${sanitizeId2(section.key)}`,
6926
+ "data-slot": "combobox-group",
6927
+ children: [
6928
+ /* @__PURE__ */ jsx(
6929
+ "div",
6930
+ {
6931
+ id: `${listboxId}-group-${sanitizeId2(section.key)}`,
6932
+ "data-slot": "combobox-group-label",
6933
+ className: "px-2.5 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-[0.4px]",
6934
+ style: { color: "rgb(var(--text-muted))" },
6935
+ children: section.label
6936
+ }
6937
+ ),
6938
+ section.items.map(renderItem)
6939
+ ]
6940
+ },
6941
+ section.key
6942
+ )
6943
+ )
6944
+ }
6945
+ ),
6946
+ document.body
6947
+ ) : null
5537
6948
  ] });
5538
- }
5539
- function DataGridToolbar({
5540
- search,
6949
+ });
6950
+ var Combobox2 = ComboboxImpl;
6951
+ var TOOLTIP_SURFACE_STYLE = {
6952
+ background: "rgb(var(--popover))",
6953
+ color: "rgb(var(--popover-foreground))",
6954
+ border: "1px solid rgb(var(--border))",
6955
+ boxShadow: "var(--shadow-md)",
6956
+ borderRadius: "var(--radius-sm)",
6957
+ padding: "var(--space-1) var(--space-2)"
6958
+ };
6959
+ function Tooltip({
6960
+ content,
5541
6961
  children,
6962
+ side = "top",
6963
+ align = "center",
6964
+ offset = 6,
6965
+ openDelay = 300,
6966
+ closeDelay = 0,
6967
+ open: openProp,
6968
+ defaultOpen,
6969
+ onOpenChange,
5542
6970
  className
5543
6971
  }) {
5544
- return /* @__PURE__ */ jsxs(
5545
- "div",
5546
- {
5547
- className: cn(
5548
- "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
5549
- className
5550
- ),
5551
- children: [
5552
- search ? /* @__PURE__ */ jsx("div", { className: "w-full sm:max-w-sm", children: search }) : /* @__PURE__ */ jsx("span", {}),
5553
- children ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 sm:justify-end", children }) : null
5554
- ]
6972
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));
6973
+ const isControlled = openProp !== void 0;
6974
+ const open = isControlled ? Boolean(openProp) : uncontrolledOpen;
6975
+ const setOpen = useCallback(
6976
+ (next) => {
6977
+ if (!isControlled) setUncontrolledOpen(next);
6978
+ onOpenChange?.(next);
6979
+ },
6980
+ [isControlled, onOpenChange]
6981
+ );
6982
+ const triggerRef = useRef(null);
6983
+ const tipRef = useRef(null);
6984
+ const timerRef = useRef(null);
6985
+ const pointerDownRef = useRef(false);
6986
+ const pressEndListenerRef = useRef(null);
6987
+ const clearPressEndListener = useCallback(() => {
6988
+ const listener = pressEndListenerRef.current;
6989
+ if (listener === null) return;
6990
+ pressEndListenerRef.current = null;
6991
+ document.removeEventListener("pointerup", listener);
6992
+ document.removeEventListener("pointercancel", listener);
6993
+ }, []);
6994
+ useEffect(() => clearPressEndListener, [clearPressEndListener]);
6995
+ const tipId = `tooltip-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
6996
+ const clearTimer = useCallback(() => {
6997
+ if (timerRef.current !== null) {
6998
+ window.clearTimeout(timerRef.current);
6999
+ timerRef.current = null;
5555
7000
  }
7001
+ }, []);
7002
+ useEffect(() => clearTimer, [clearTimer]);
7003
+ const scheduleOpen = useCallback(
7004
+ (delay) => {
7005
+ clearTimer();
7006
+ if (delay <= 0) {
7007
+ setOpen(true);
7008
+ return;
7009
+ }
7010
+ timerRef.current = window.setTimeout(() => {
7011
+ timerRef.current = null;
7012
+ setOpen(true);
7013
+ }, delay);
7014
+ },
7015
+ [clearTimer, setOpen]
5556
7016
  );
5557
- }
5558
- function DataGridColumnOptionsMenu({
5559
- showSummaries,
5560
- onShowSummariesChange,
5561
- visibleColumns,
5562
- visibleColumnIds,
5563
- hiddenColumns,
5564
- toggleColumnVisibility,
5565
- optionsSensors,
5566
- onOptionColumnDragEnd,
5567
- optionsDndContextId,
5568
- triggerLabel = "Options"
5569
- }) {
5570
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
5571
- /* @__PURE__ */ jsxs(DropdownMenuTrigger, { "aria-label": "Open table options", children: [
5572
- /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4" }),
5573
- /* @__PURE__ */ jsx("span", { children: triggerLabel })
5574
- ] }),
5575
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
5576
- /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Options" }) }),
5577
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5578
- /* @__PURE__ */ jsx(
5579
- DropdownMenuCheckboxItem,
5580
- {
5581
- checked: showSummaries,
5582
- onCheckedChange: (checked) => onShowSummariesChange(checked === true),
5583
- children: "Show summary row"
5584
- }
5585
- ),
5586
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5587
- /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Columns" }) }),
7017
+ const scheduleClose = useCallback(
7018
+ (delay) => {
7019
+ clearTimer();
7020
+ if (delay <= 0) {
7021
+ setOpen(false);
7022
+ return;
7023
+ }
7024
+ timerRef.current = window.setTimeout(() => {
7025
+ timerRef.current = null;
7026
+ setOpen(false);
7027
+ }, delay);
7028
+ },
7029
+ [clearTimer, setOpen]
7030
+ );
7031
+ const {
7032
+ ref: positionRef,
7033
+ style: positionStyle,
7034
+ placement,
7035
+ positioned
7036
+ } = useAnchoredPosition({
7037
+ anchorRef: triggerRef,
7038
+ side,
7039
+ align,
7040
+ offset,
7041
+ enabled: open
7042
+ });
7043
+ useLayer({
7044
+ enabled: open,
7045
+ kind: "popover",
7046
+ elementRef: tipRef,
7047
+ onEscape: () => {
7048
+ clearTimer();
7049
+ setOpen(false);
7050
+ }
7051
+ });
7052
+ const tipRefs = useMemo(
7053
+ () => composeRefs(tipRef, positionRef),
7054
+ [positionRef]
7055
+ );
7056
+ if (!isValidElement(children)) {
7057
+ throw new Error("Tooltip expects exactly one element child to use as its trigger.");
7058
+ }
7059
+ if (content === null || content === void 0 || content === false) return children;
7060
+ const childProps = children.props;
7061
+ const describedBy = open ? [childProps["aria-describedby"], tipId].filter(Boolean).join(" ") : childProps["aria-describedby"];
7062
+ const trigger = cloneElement(children, {
7063
+ ref: composeRefs(childProps.ref, triggerRef),
7064
+ "aria-describedby": describedBy,
7065
+ onPointerEnter: (event) => {
7066
+ childProps.onPointerEnter?.(event);
7067
+ if (event.pointerType === "touch") return;
7068
+ scheduleOpen(openDelay);
7069
+ },
7070
+ onPointerLeave: (event) => {
7071
+ childProps.onPointerLeave?.(event);
7072
+ scheduleClose(closeDelay);
7073
+ },
7074
+ onPointerDown: (event) => {
7075
+ childProps.onPointerDown?.(event);
7076
+ pointerDownRef.current = true;
7077
+ clearPressEndListener();
7078
+ const onPressEnd = () => {
7079
+ pointerDownRef.current = false;
7080
+ clearPressEndListener();
7081
+ };
7082
+ pressEndListenerRef.current = onPressEnd;
7083
+ document.addEventListener("pointerup", onPressEnd);
7084
+ document.addEventListener("pointercancel", onPressEnd);
7085
+ clearTimer();
7086
+ setOpen(false);
7087
+ },
7088
+ onFocus: (event) => {
7089
+ childProps.onFocus?.(event);
7090
+ if (pointerDownRef.current) return;
7091
+ scheduleOpen(0);
7092
+ },
7093
+ onBlur: (event) => {
7094
+ childProps.onBlur?.(event);
7095
+ scheduleClose(0);
7096
+ }
7097
+ });
7098
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7099
+ trigger,
7100
+ open && typeof document !== "undefined" ? createPortal(
5588
7101
  /* @__PURE__ */ jsx(
5589
- DndContext,
7102
+ "div",
5590
7103
  {
5591
- id: optionsDndContextId,
5592
- sensors: optionsSensors,
5593
- collisionDetection: closestCenter,
5594
- onDragEnd: onOptionColumnDragEnd,
5595
- children: /* @__PURE__ */ jsx(
5596
- SortableContext,
5597
- {
5598
- items: visibleColumns.map((column) => column.id),
5599
- strategy: verticalListSortingStrategy,
5600
- children: visibleColumns.map((column) => /* @__PURE__ */ jsx(
5601
- SortableColumnOptionItem,
5602
- {
5603
- column,
5604
- checked: true,
5605
- disabled: visibleColumnIds.length === 1,
5606
- onCheckedChange: (checked) => toggleColumnVisibility(column.id, checked)
5607
- },
5608
- column.id
5609
- ))
5610
- }
5611
- )
7104
+ ref: tipRefs,
7105
+ id: tipId,
7106
+ role: "tooltip",
7107
+ "data-slot": "tooltip",
7108
+ "data-state": "open",
7109
+ "data-side": placement?.side,
7110
+ "data-align": placement?.align,
7111
+ "data-positioned": positioned ? "true" : "false",
7112
+ className: cn(
7113
+ "pointer-events-none fixed z-[110] max-w-xs text-xs font-medium leading-snug",
7114
+ positioned && "ds-enter-pop",
7115
+ className
7116
+ ),
7117
+ style: { ...positionStyle, ...TOOLTIP_SURFACE_STYLE },
7118
+ children: content
5612
7119
  }
5613
7120
  ),
5614
- hiddenColumns.length > 0 ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
5615
- hiddenColumns.map((column) => /* @__PURE__ */ jsx(
5616
- DropdownMenuCheckboxItem,
5617
- {
5618
- checked: false,
5619
- onCheckedChange: (checked) => toggleColumnVisibility(column.id, checked === true),
5620
- children: column.label
5621
- },
5622
- column.id
5623
- ))
5624
- ] })
7121
+ document.body
7122
+ ) : null
5625
7123
  ] });
5626
7124
  }
5627
7125
  var VARIANT_CLASS2 = {
@@ -8445,7 +9943,7 @@ var LANGUAGES = {
8445
9943
  javascript,
8446
9944
  js: javascript,
8447
9945
  json,
8448
- jsx: jsx66,
9946
+ jsx: jsx70,
8449
9947
  markdown,
8450
9948
  md: markdown,
8451
9949
  html: markup,
@@ -9194,26 +10692,6 @@ function HeaderTitle({ title }) {
9194
10692
  /* @__PURE__ */ jsx("span", { style: accent, children: last })
9195
10693
  ] });
9196
10694
  }
9197
- function BenchmarkPlaceholder() {
9198
- return /* @__PURE__ */ jsxs(
9199
- "div",
9200
- {
9201
- className: "flex items-center",
9202
- style: {
9203
- gap: 10,
9204
- padding: "12px 16px",
9205
- borderRadius: "var(--radius-lg)",
9206
- background: "rgb(var(--muted))",
9207
- border: "1px dashed rgb(var(--border))",
9208
- color: "rgb(var(--text-muted))"
9209
- },
9210
- children: [
9211
- /* @__PURE__ */ jsx(BarChart3, { size: 15 }),
9212
- /* @__PURE__ */ jsx("span", { style: { fontSize: 12, fontWeight: 500 }, children: "Benchmark unavailable in manual mode" })
9213
- ]
9214
- }
9215
- );
9216
- }
9217
10695
  function AssumptionsPopover({ children }) {
9218
10696
  const [open, setOpen] = useState(false);
9219
10697
  return /* @__PURE__ */ jsxs(
@@ -9307,10 +10785,9 @@ function CalculatorShellV2({
9307
10785
  const header = /* @__PURE__ */ jsxs(
9308
10786
  "header",
9309
10787
  {
9310
- className: "flex items-center",
10788
+ className: "flex items-center px-4 py-4 sm:px-6 sm:py-5",
9311
10789
  style: {
9312
10790
  gap: 16,
9313
- padding: "20px 24px",
9314
10791
  background: "rgb(var(--brand-ink))",
9315
10792
  borderRadius: isOpen ? "var(--radius-xl)" : 0
9316
10793
  },
@@ -9334,7 +10811,8 @@ function CalculatorShellV2({
9334
10811
  /* @__PURE__ */ jsx(
9335
10812
  "div",
9336
10813
  {
9337
- className: "font-semibold uppercase",
10814
+ className: "font-semibold uppercase truncate",
10815
+ title: eyebrow,
9338
10816
  style: {
9339
10817
  fontFamily: "var(--font-mono)",
9340
10818
  fontSize: 11,
@@ -9364,10 +10842,9 @@ function CalculatorShellV2({
9364
10842
  const footer = /* @__PURE__ */ jsxs(
9365
10843
  "footer",
9366
10844
  {
9367
- className: "flex items-center",
10845
+ className: "flex flex-wrap items-center px-4 py-4 sm:px-6",
9368
10846
  style: {
9369
10847
  gap: 12,
9370
- padding: "16px 24px",
9371
10848
  borderTop: isOpen ? "none" : "1px solid rgb(var(--border))",
9372
10849
  marginTop: isOpen ? 4 : 0,
9373
10850
  background: isOpen ? "transparent" : "rgb(var(--bg-card))"
@@ -9414,7 +10891,7 @@ function CalculatorShellV2({
9414
10891
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
9415
10892
  inputs,
9416
10893
  result,
9417
- benchmarkSlot ?? /* @__PURE__ */ jsx(BenchmarkPlaceholder, {})
10894
+ benchmarkSlot
9418
10895
  ] });
9419
10896
  return /* @__PURE__ */ jsx(
9420
10897
  "div",
@@ -9448,8 +10925,8 @@ function CalculatorShellV2({
9448
10925
  /* @__PURE__ */ jsx(
9449
10926
  "div",
9450
10927
  {
9451
- className: "flex flex-col",
9452
- style: { padding: "var(--space-6)", gap: "var(--space-4)" },
10928
+ className: "flex flex-col p-4 sm:p-6",
10929
+ style: { gap: "var(--space-4)" },
9453
10930
  children: body
9454
10931
  }
9455
10932
  ),
@@ -9460,90 +10937,104 @@ function CalculatorShellV2({
9460
10937
  }
9461
10938
  );
9462
10939
  }
9463
- function StatRow({ steps, className }) {
9464
- return /* @__PURE__ */ jsx("div", { className, style: { display: "flex", alignItems: "stretch", gap: 0 }, children: steps.map((s, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
9465
- i > 0 && /* @__PURE__ */ jsx(
9466
- "div",
9467
- {
9468
- className: "flex items-center shrink-0",
9469
- style: { padding: "0 2px", color: "rgb(var(--text-muted))" },
9470
- "aria-hidden": "true",
9471
- children: /* @__PURE__ */ jsx(ArrowRight, { size: 14, strokeWidth: 2.2 })
9472
- }
9473
- ),
9474
- /* @__PURE__ */ jsxs(
9475
- "div",
9476
- {
9477
- "data-pivotal": s.pivotal ? "true" : void 0,
9478
- style: {
9479
- flex: 1,
9480
- minWidth: 0,
9481
- borderRadius: "var(--radius-lg)",
9482
- padding: 5,
9483
- background: s.pivotal ? "rgb(var(--accent))" : "rgb(var(--brand-ink))"
9484
- },
9485
- children: [
10940
+ function StatRow({ steps, copyable = false, className }) {
10941
+ return /* @__PURE__ */ jsx(
10942
+ "div",
10943
+ {
10944
+ className: cn("grid grid-cols-2 gap-2 sm:flex sm:items-stretch sm:gap-0", className),
10945
+ children: steps.map((s, i) => {
10946
+ const panelStyle = {
10947
+ background: "rgb(var(--bg-card))",
10948
+ borderRadius: 10,
10949
+ padding: "12px 10px",
10950
+ minHeight: 46
10951
+ };
10952
+ const figure = /* @__PURE__ */ jsx(
10953
+ "span",
10954
+ {
10955
+ className: "font-extrabold tabular-nums",
10956
+ style: {
10957
+ fontSize: 22,
10958
+ letterSpacing: "-0.025em",
10959
+ lineHeight: 1,
10960
+ color: s.pivotal ? "rgb(var(--accent))" : "rgb(var(--foreground))"
10961
+ },
10962
+ children: s.value
10963
+ }
10964
+ );
10965
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
10966
+ i > 0 && /* @__PURE__ */ jsx(
10967
+ "div",
10968
+ {
10969
+ className: "hidden sm:flex items-center shrink-0",
10970
+ style: { padding: "0 2px", color: "rgb(var(--text-muted))" },
10971
+ "aria-hidden": "true",
10972
+ children: /* @__PURE__ */ jsx(ArrowRight, { size: 14, strokeWidth: 2.2 })
10973
+ }
10974
+ ),
9486
10975
  /* @__PURE__ */ jsxs(
9487
10976
  "div",
9488
10977
  {
9489
- className: "flex items-center",
10978
+ "data-pivotal": s.pivotal ? "true" : void 0,
9490
10979
  style: {
9491
- gap: 5,
9492
- padding: "4px 7px 6px",
9493
- color: "rgb(255 255 255 / 0.7)",
9494
- minWidth: 0
10980
+ flex: 1,
10981
+ minWidth: 0,
10982
+ borderRadius: "var(--radius-lg)",
10983
+ padding: 5,
10984
+ background: s.pivotal ? "rgb(var(--accent))" : "rgb(var(--brand-ink))"
9495
10985
  },
9496
10986
  children: [
9497
- /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0", children: s.icon }),
9498
- /* @__PURE__ */ jsx(
9499
- "span",
10987
+ /* @__PURE__ */ jsxs(
10988
+ "div",
9500
10989
  {
9501
- className: "font-bold uppercase",
9502
- title: s.label,
10990
+ className: "flex items-center",
9503
10991
  style: {
9504
- fontSize: "9.5px",
9505
- letterSpacing: "0.05em",
9506
- whiteSpace: "nowrap",
9507
- overflow: "hidden",
9508
- textOverflow: "ellipsis",
9509
- minWidth: 0,
9510
- flex: 1
10992
+ gap: 5,
10993
+ padding: "4px 7px 6px",
10994
+ color: "rgb(255 255 255 / 0.7)",
10995
+ minWidth: 0
9511
10996
  },
9512
- children: s.label
10997
+ children: [
10998
+ /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0", children: s.icon }),
10999
+ /* @__PURE__ */ jsx(
11000
+ "span",
11001
+ {
11002
+ className: "font-bold uppercase",
11003
+ title: s.label,
11004
+ style: {
11005
+ fontSize: "9.5px",
11006
+ letterSpacing: "0.05em",
11007
+ whiteSpace: "nowrap",
11008
+ overflow: "hidden",
11009
+ textOverflow: "ellipsis",
11010
+ minWidth: 0,
11011
+ flex: 1
11012
+ },
11013
+ children: s.label
11014
+ }
11015
+ )
11016
+ ]
9513
11017
  }
9514
- )
11018
+ ),
11019
+ copyable ? /* @__PURE__ */ jsx(
11020
+ "button",
11021
+ {
11022
+ type: "button",
11023
+ onClick: () => void copyText(s.copyValue ?? s.value, s.label),
11024
+ title: `Copy ${s.label}`,
11025
+ "aria-label": `Copy ${s.label}: ${s.value}`,
11026
+ className: "grid w-full place-items-center text-center cursor-pointer transition-[box-shadow,transform] hover:-translate-y-px hover:[box-shadow:var(--shadow-sm)] focus-visible:outline-none focus-visible:[box-shadow:var(--ring-focus)]",
11027
+ style: { ...panelStyle, border: "none" },
11028
+ children: figure
11029
+ }
11030
+ ) : /* @__PURE__ */ jsx("div", { className: "grid place-items-center text-center", style: panelStyle, children: figure })
9515
11031
  ]
9516
11032
  }
9517
- ),
9518
- /* @__PURE__ */ jsx(
9519
- "div",
9520
- {
9521
- className: "grid place-items-center text-center",
9522
- style: {
9523
- background: "rgb(var(--bg-card))",
9524
- borderRadius: 10,
9525
- padding: "12px 10px",
9526
- minHeight: 46
9527
- },
9528
- children: /* @__PURE__ */ jsx(
9529
- "span",
9530
- {
9531
- className: "font-extrabold tabular-nums",
9532
- style: {
9533
- fontSize: 22,
9534
- letterSpacing: "-0.025em",
9535
- lineHeight: 1,
9536
- color: s.pivotal ? "rgb(var(--accent))" : "rgb(var(--foreground))"
9537
- },
9538
- children: s.value
9539
- }
9540
- )
9541
- }
9542
11033
  )
9543
- ]
9544
- }
9545
- )
9546
- ] }, i)) });
11034
+ ] }, i);
11035
+ })
11036
+ }
11037
+ );
9547
11038
  }
9548
11039
  function Slider({
9549
11040
  value,
@@ -14645,6 +16136,6 @@ var PLACEMENT_CONFIGS = [
14645
16136
  }
14646
16137
  ];
14647
16138
 
14648
- export { AccordionCompound as Accordion, AllocationSparkbar, AppScroll, BRAND_ICONS, Badge, BrandFacebook, BrandIcon, BrandInstagram, BrandLinkedIn, BrandLogoTile, BrandMessenger, BrandMeta, BrandNextdoor, BrandPinterest, BrandSnapchat, BrandTikTok, BulkActionBar, Button, ButtonGroup, CalculatorShell, CalculatorShellV2, card_default as Card, Checkbox, ChipNav, Choropleth, CodeBlock, CollapsibleCard, CompletionRing, CopyField, DataGrid, DataGridColumnOptionsMenu, DataGridDragOverlay, DataGridDropIndicator, DataGridToolbar, DetailSection, DeviceFrame, DragHandle, DropdownButton, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EmptyPlaceholder, EmptyState, FOLDER_COLOR_KEYS, FileDropZone, FilePreviewGrid, FilePreviewItem, FileThumbnail, FileUploadButton, FilterBar, FilterDropdown, FloatingDrawer, FloatingStatusBar, FolderCard, FolderTreePicker, FrameStack, HEADER_HEIGHT, HeroFormCardCompound as HeroFormCard, HomeCrumbLink, IconTile, IdentityLabel, IdentityValue, Input, Kbd, ListItem, MarkdownCode, MarkdownRenderer, MenuButton, MetaCell, meta_previews_exports as MetaPreviews, MetricCard, MicrosoftLogo, modal_default as Modal, OptionTile, OptionTileGroup, PLACEMENT_CONFIGS, PageHeaderHost, PageHeaderSlotProvider, PageHero, page_shell_default as PageShell, Pagination, PillButton, profile_section_default as ProfileSection, ProgressBar, Radio, RadioGroup, RangeSlider, ResizableHandle, ResizablePane, SECTION_SCROLL_OFFSET, SearchBar, SectionLabel, SegmentedPill, Shell2 as Shell, ShellStat, Slider, SortableItem, SortableList, SortableTable, StatRow, StatsGrid, StepLoader, Tabs, TagChipInput, TagRow, TextInput, Textarea, TextareaInput, Toaster, TokenBadge, ValueChip, bestTextOn, cn, contrastRatio, copyText, folderColorVar, formatCurrency, formatNumber, formatPercent, formatRatio, hasBrandIcon, hexToRgbTuple, hslString, relativeLuminance, rgbCss, rgbString, useBreadcrumbHome, useFileUpload, wcagBadges };
16139
+ export { AccordionCompound as Accordion, AllocationSparkbar, AppScroll, BRAND_ICONS, Badge, BrandFacebook, BrandIcon, BrandInstagram, BrandLinkedIn, BrandLogoTile, BrandMessenger, BrandMeta, BrandNextdoor, BrandPinterest, BrandSnapchat, BrandTikTok, BulkActionBar, Button, ButtonGroup, CalculatorShell, CalculatorShellV2, card_default as Card, Checkbox, ChipNav, Choropleth, CodeBlock, CollapsibleCard, Combobox2 as Combobox, CompletionRing, CopyField, DataGrid, DataGridColumnOptionsMenu, DataGridDragOverlay, DataGridDropIndicator, DataGridToolbar, DetailSection, DeviceFrame, DragHandle, DropdownButton, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EmptyPlaceholder, EmptyState, FOLDER_COLOR_KEYS, FileDropZone, FilePreviewGrid, FilePreviewItem, FileThumbnail, FileUploadButton, FilterBar, FilterDropdown, FloatingDrawer, FloatingStatusBar, FolderCard, FolderTreePicker, FrameStack, HEADER_HEIGHT, HeroFormCardCompound as HeroFormCard, HomeCrumbLink, IconTile, IdentityLabel, IdentityValue, Input, Kbd, LISTBOX_CLASS, ListItem, ListboxOption, MarkdownCode, MarkdownRenderer, MenuButton, MetaCell, meta_previews_exports as MetaPreviews, MetricCard, MicrosoftLogo, modal_default as Modal, OptionTile, OptionTileGroup, PLACEMENT_CONFIGS, POPOVER_SURFACE_STYLE, PageHeaderHost, PageHeaderSlotProvider, PageHero, page_shell_default as PageShell, Pagination, PillButton, Popover, profile_section_default as ProfileSection, ProgressBar, Radio, RadioGroup, RangeSlider, ResizableHandle, ResizablePane, SECTION_SCROLL_OFFSET, SearchBar, SectionLabel, SegmentedPill, Select2 as Select, Shell2 as Shell, ShellStat, Slider, SortableItem, SortableList, SortableTable, StatRow, StatsGrid, StepLoader, Tabs, TagChipInput, TagRow, TextInput, Textarea, TextareaInput, Toaster, TokenBadge, Tooltip, ValueChip, bestTextOn, cn, computeAnchoredPosition, contrastRatio, copyText, folderColorVar, formatCurrency, formatNumber, formatPercent, formatRatio, hasBrandIcon, hexToRgbTuple, hslString, relativeLuminance, rgbCss, rgbString, useAnchoredPosition, useBreadcrumbHome, useEscapeKey, useFileUpload, useLayer, useOutsideClick, wcagBadges };
14649
16140
  //# sourceMappingURL=index.js.map
14650
16141
  //# sourceMappingURL=index.js.map