@nebutra/ui 0.2.2 → 0.2.3

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.
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Accordion as Accordion$1 } from '@base-ui/react/accordion';
3
- import { ChevronUpDown, Check, ChevronRight, ChevronDown, MagnifyingGlass, Plus, Cross, MoreHorizontal, Status, Copy, Hash, Code, Link, Information, Warning, External, LoaderCircle, EyeOff, Eye, Minus, LockClosed, CheckCircle, MoreVertical, DeviceDesktop, Sun, Moon, FolderOpen, FolderClosed, File, ChevronLeft, ChevronUp, FileText } from '@nebutra/icons';
3
+ import { ChevronUpDown, Check, ChevronRight, ChevronDown, MagnifyingGlass, Plus, Cross, MoreHorizontal, Status, Copy, Information, Warning, External, LoaderCircle, EyeOff, Eye, Minus, LockClosed, CheckCircle, MoreVertical, DeviceDesktop, Sun, Moon, Hash, Code, Link, FolderOpen, FolderClosed, File, ChevronLeft, ChevronUp, FileText } from '@nebutra/icons';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -8,9 +8,9 @@ import { cva } from 'class-variance-authority';
8
8
  import { AlertDialog as AlertDialog$1 } from '@base-ui/react/alert-dialog';
9
9
  import * as React24 from 'react';
10
10
  import React24__default, { createContext, useId, useRef, useState, useMemo, use, useCallback, useEffect, Children, isValidElement, cloneElement } from 'react';
11
- import { colors, flow, emerge } from '@nebutra/brand';
11
+ import { colors, brandSpring, flow, emerge } from '@nebutra/brand';
12
12
  export { brandSpring } from '@nebutra/brand';
13
- import { useReducedMotion, motion, AnimatePresence, LazyMotion, domAnimation, m } from 'framer-motion';
13
+ import { useReducedMotion, LazyMotion, domAnimation, AnimatePresence, motion, m } from 'framer-motion';
14
14
  import { Avatar as Avatar$1 } from '@base-ui/react/avatar';
15
15
  import { Prism } from 'react-syntax-highlighter';
16
16
  import { nightOwl } from 'react-syntax-highlighter/dist/esm/styles/prism';
@@ -41,6 +41,10 @@ function cn(...inputs) {
41
41
  }
42
42
 
43
43
  // src/utils/primitive-props.ts
44
+ function asPlainStyle(style) {
45
+ if (style == null || typeof style === "function") return {};
46
+ return style;
47
+ }
44
48
  function withHtmlProps(Component) {
45
49
  return Component;
46
50
  }
@@ -73,7 +77,7 @@ var AccordionTrigger = ({
73
77
  {
74
78
  ref,
75
79
  className: cn(
76
- "font-medium flex flex-1 items-center justify-between transition-[color,box-shadow] duration-flow ease-out hover:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none [&[data-panel-open]>svg]:rotate-45",
80
+ "font-medium flex flex-1 items-center justify-between transition-[color,box-shadow] duration-flow ease-out hover:text-muted-foreground focus-visible:outline-none [&[data-panel-open]>svg]:rotate-45",
77
81
  size === "small" ? "py-2.5 text-sm" : "py-4 text-[15px]",
78
82
  className
79
83
  ),
@@ -305,7 +309,7 @@ function Alert({
305
309
  className: cn(
306
310
  "group shrink-0 size-4 inline-flex items-center justify-center rounded-[var(--radius-sm)]",
307
311
  "opacity-70 hover:opacity-100 transition-opacity",
308
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
312
+ "focus-visible:outline-none"
309
313
  ),
310
314
  children: /* @__PURE__ */ jsx(Cross, { className: "size-4" })
311
315
  }
@@ -472,7 +476,7 @@ var shadowClasses = {
472
476
  "2xl": "shadow-2xl"};
473
477
 
474
478
  // src/tokens/components/overlay.ts
475
- var overlayFocusRingClassName = "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2";
479
+ var overlayFocusRingClassName = "outline-none";
476
480
  var overlayZIndex = {
477
481
  backdrop: 1040,
478
482
  modal: 1050,
@@ -553,7 +557,6 @@ var buttonVariants = cva(
553
557
  "rounded-[var(--btn-default-radius,var(--radius-md))]",
554
558
  "text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
555
559
  "transition-colors duration-micro ease-out",
556
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
557
560
  "disabled:pointer-events-none disabled:opacity-50",
558
561
  "aria-busy:cursor-wait"
559
562
  ].join(" "),
@@ -580,8 +583,30 @@ var buttonVariants = cva(
580
583
  },
581
584
  shape: {
582
585
  default: "",
583
- square: "",
584
- circle: ""
586
+ // Radius from --btn-default-radius / --radius-md — brand-switchable.
587
+ // Do not hardcode rounded-md here; a language must be able to retarget
588
+ // the corner treatment of every icon trigger at once.
589
+ square: "rounded-[var(--btn-default-radius,var(--radius-md))]",
590
+ // Pill radius token, not Tailwind rounded-full — same 9999px default,
591
+ // but a brand that ships a softer "circle" can override --radius-pill.
592
+ circle: "rounded-[var(--radius-pill,9999px)]",
593
+ pill: "rounded-[var(--radius-pill,9999px)]"
594
+ },
595
+ // Icon-only box size — orthogonal to `size` (which tunes text-button
596
+ // height/padding/font together) and to `shape` (which picks the
597
+ // corner treatment). Only takes effect combined with shape="square"
598
+ // or shape="circle" (see compoundVariants below); every other
599
+ // combination ignores it. 28/32/36 cover the icon-trigger sizes that
600
+ // actually occur in the app — 24/40/48 are already reachable via
601
+ // shape + size (tiny/default/lg). Heights read --control-height-icon-*
602
+ // so density-aware Brand Packages can scale them with the ladder.
603
+ iconSize: {
604
+ sm: "",
605
+ // 28px default
606
+ md: "",
607
+ // 32px default
608
+ lg: ""
609
+ // 36px default
585
610
  }
586
611
  },
587
612
  compoundVariants: [
@@ -592,22 +617,56 @@ var buttonVariants = cva(
592
617
  {
593
618
  shape: "circle",
594
619
  size: "tiny",
595
- className: "w-[var(--control-height-tiny,1.5rem)] px-0 rounded-full"
620
+ className: "w-[var(--control-height-tiny,1.5rem)] px-0"
596
621
  },
597
622
  {
598
623
  shape: "circle",
599
624
  size: "sm",
600
- className: "w-[var(--control-height-sm,2rem)] px-0 rounded-full"
625
+ className: "w-[var(--control-height-sm,2rem)] px-0"
601
626
  },
602
627
  {
603
628
  shape: "circle",
604
629
  size: "default",
605
- className: "w-[var(--control-height-md,2.5rem)] px-0 rounded-full"
630
+ className: "w-[var(--control-height-md,2.5rem)] px-0"
606
631
  },
607
632
  {
608
633
  shape: "circle",
609
634
  size: "lg",
610
- className: "w-[var(--control-height-lg,3rem)] px-0 rounded-full"
635
+ className: "w-[var(--control-height-lg,3rem)] px-0"
636
+ },
637
+ // iconSize wins over the size-driven box above — matched on shape +
638
+ // iconSize only, so it applies regardless of whatever `size` was
639
+ // passed (or left at its "default" fallback). Corner treatment stays
640
+ // on the shape variant (token-backed); only the box is set here.
641
+ {
642
+ shape: "square",
643
+ iconSize: "sm",
644
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
645
+ },
646
+ {
647
+ shape: "square",
648
+ iconSize: "md",
649
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
650
+ },
651
+ {
652
+ shape: "square",
653
+ iconSize: "lg",
654
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
655
+ },
656
+ {
657
+ shape: "circle",
658
+ iconSize: "sm",
659
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
660
+ },
661
+ {
662
+ shape: "circle",
663
+ iconSize: "md",
664
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
665
+ },
666
+ {
667
+ shape: "circle",
668
+ iconSize: "lg",
669
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
611
670
  }
612
671
  ],
613
672
  defaultVariants: {
@@ -818,13 +877,61 @@ var PRESETS = {
818
877
  /** Fade + rise */
819
878
  fadeUp: motionVariants.fadeInUp,
820
879
  /** Scale in */
821
- scale: motionVariants.scaleIn
880
+ scale: motionVariants.scaleIn,
881
+ /**
882
+ * Keyed content swap — short, symmetric, blur-softened. Rises in, sinks out.
883
+ * Shorter and shallower than `emerge` on purpose: a swap replaces content the
884
+ * reader is already looking at, so it must resolve inside the reveal rail.
885
+ * Pair with `AnimateSwap`.
886
+ */
887
+ swap: {
888
+ initial: { opacity: 0, y: 10, filter: "blur(4px)" },
889
+ animate: { opacity: 1, y: 0, filter: "blur(0px)" },
890
+ exit: { opacity: 0, y: -10, filter: "blur(4px)" },
891
+ transition: { duration: motionDurations.reveal / 1e3 }
892
+ },
893
+ /** Off-canvas panel entering from the right edge (drawer, sheet). */
894
+ slideFromRight: {
895
+ initial: { x: "100%" },
896
+ animate: { x: 0 },
897
+ exit: { x: "100%" },
898
+ transition: brandSpring.default
899
+ },
900
+ /** Off-canvas panel entering from the left edge. */
901
+ slideFromLeft: {
902
+ initial: { x: "-100%" },
903
+ animate: { x: 0 },
904
+ exit: { x: "-100%" },
905
+ transition: brandSpring.default
906
+ },
907
+ /** Off-canvas panel entering from the top edge (banner, command bar). */
908
+ slideFromTop: {
909
+ initial: { y: "-100%" },
910
+ animate: { y: 0 },
911
+ exit: { y: "-100%" },
912
+ transition: brandSpring.default
913
+ },
914
+ /** Off-canvas panel entering from the bottom edge (mobile action sheet). */
915
+ slideFromBottom: {
916
+ initial: { y: "100%" },
917
+ animate: { y: 0 },
918
+ exit: { y: "100%" },
919
+ transition: brandSpring.default
920
+ }
822
921
  };
823
922
  function MotionDiv(props) {
824
923
  return /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, children: /* @__PURE__ */ jsx(m.div, { ...props }) });
825
924
  }
826
925
  function AnimateIn(props) {
827
- const { children, preset = "emerge", delay = 0, duration, inView = false, className } = props;
926
+ const {
927
+ children,
928
+ preset = "emerge",
929
+ delay = 0,
930
+ duration,
931
+ inView = false,
932
+ className,
933
+ ...rest
934
+ } = props;
828
935
  const shouldReduce = useReducedMotion();
829
936
  const base = PRESETS[preset] || PRESETS.emerge;
830
937
  const initial = shouldReduce ? { opacity: 0 } : base.initial;
@@ -839,6 +946,7 @@ function AnimateIn(props) {
839
946
  return /* @__PURE__ */ jsx(
840
947
  MotionDiv,
841
948
  {
949
+ ...rest,
842
950
  className,
843
951
  initial,
844
952
  whileInView: animate2,
@@ -852,6 +960,7 @@ function AnimateIn(props) {
852
960
  return /* @__PURE__ */ jsx(
853
961
  MotionDiv,
854
962
  {
963
+ ...rest,
855
964
  className,
856
965
  initial,
857
966
  animate: animate2,
@@ -861,6 +970,10 @@ function AnimateIn(props) {
861
970
  }
862
971
  );
863
972
  }
973
+ function AnimateSwap(props) {
974
+ const { swapKey, ...animateInProps } = props;
975
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(AnimateIn, { ...animateInProps }, swapKey) }) });
976
+ }
864
977
  function AnimateInGroup(props) {
865
978
  const { children, stagger = "normal", inView = false, className } = props;
866
979
  const shouldReduce = useReducedMotion();
@@ -963,9 +1076,18 @@ function getAvatarFallbackClass(size) {
963
1076
  }
964
1077
  function getAvatarStyle(size, style) {
965
1078
  if (typeof size !== "number") return style;
966
- return {
1079
+ const numericVars = {
967
1080
  "--avatar-size": `${size}px`,
968
- "--avatar-font-size": `${Math.max(10, Math.round(size * 0.375))}px`,
1081
+ "--avatar-font-size": `${Math.max(10, Math.round(size * 0.375))}px`
1082
+ };
1083
+ if (typeof style === "function") {
1084
+ return (state) => ({
1085
+ ...numericVars,
1086
+ ...style(state)
1087
+ });
1088
+ }
1089
+ return {
1090
+ ...numericVars,
969
1091
  ...style
970
1092
  };
971
1093
  }
@@ -1134,7 +1256,7 @@ function AvatarGroup({
1134
1256
  ] });
1135
1257
  }
1136
1258
  var badgeVariants = cva(
1137
- "inline-flex justify-center items-center align-middle shrink-0 rounded-full font-sans font-medium whitespace-nowrap tabular-nums transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 border border-transparent",
1259
+ "inline-flex justify-center items-center align-middle shrink-0 rounded-full font-sans font-medium whitespace-nowrap tabular-nums transition-colors focus-visible:outline-none border border-transparent",
1138
1260
  {
1139
1261
  variants: {
1140
1262
  variant: {
@@ -1156,15 +1278,26 @@ var badgeVariants = cva(
1156
1278
  purple: "bg-secondary text-secondary-foreground fill-current",
1157
1279
  "purple-subtle": "bg-secondary/40 text-secondary-foreground fill-current border-transparent",
1158
1280
  amber: "bg-warning text-warning-foreground fill-current",
1159
- "amber-subtle": "bg-warning/15 text-warning fill-current border-transparent",
1281
+ "amber-subtle": (
1282
+ // --warning is a FILL (2.13:1). As ink on its own tint it measured 1.91:1.
1283
+ // --warning-strong is the AA-safe amber foreground: 5.01:1 light / 6.20:1 dark.
1284
+ "bg-warning/10 text-[hsl(var(--warning-strong))] fill-current border-transparent"
1285
+ ),
1160
1286
  red: "bg-destructive text-destructive-foreground fill-current",
1161
- "red-subtle": "bg-destructive/15 text-destructive fill-current border-transparent",
1287
+ "red-subtle": (
1288
+ // --destructive is fill-only in dark (2.01:1 as ink on its own tint).
1289
+ // --destructive-strong: 4.58:1 light / 4.97:1 dark.
1290
+ "bg-destructive/10 text-[hsl(var(--destructive-strong))] fill-current border-transparent"
1291
+ ),
1162
1292
  pink: "bg-accent text-accent-foreground fill-current",
1163
1293
  "pink-subtle": "bg-accent/40 text-accent-foreground fill-current border-transparent",
1164
1294
  green: "bg-success text-success-foreground fill-current",
1165
- "green-subtle": "bg-success/15 text-success fill-current border-transparent",
1295
+ "green-subtle": (
1296
+ // --success-strong closes the 4.49:1 light gap: 4.99:1 light / 4.83:1 dark.
1297
+ "bg-success/10 text-[hsl(var(--success-strong))] fill-current border-transparent"
1298
+ ),
1166
1299
  teal: "bg-info text-info-foreground fill-current",
1167
- "teal-subtle": "bg-info/15 text-info fill-current border-transparent",
1300
+ "teal-subtle": "bg-info/10 text-info fill-current border-transparent",
1168
1301
  inverted: "bg-foreground text-background fill-current",
1169
1302
  // Special visual treatments (intentional product design, not brand hex)
1170
1303
  trial: "bg-gradient-to-br from-trial-start to-trial-end text-primary-foreground fill-current",
@@ -1381,7 +1514,10 @@ function Spinner({ className }) {
1381
1514
  }
1382
1515
  );
1383
1516
  }
1384
- function getIconSizeClass(size) {
1517
+ function getIconSizeClass(size, iconSize2) {
1518
+ if (iconSize2 === "sm") return "[&>svg]:size-3.5";
1519
+ if (iconSize2 === "md") return "[&>svg]:size-3.5";
1520
+ if (iconSize2 === "lg") return "[&>svg]:size-4";
1385
1521
  switch (size) {
1386
1522
  case "tiny":
1387
1523
  return "[&>svg]:size-3";
@@ -1396,7 +1532,10 @@ function getIconSizeClass(size) {
1396
1532
  return "[&>svg]:size-4";
1397
1533
  }
1398
1534
  }
1399
- function getSpinnerSizeClass(size) {
1535
+ function getSpinnerSizeClass(size, iconSize2) {
1536
+ if (iconSize2 === "sm") return "size-3.5";
1537
+ if (iconSize2 === "md") return "size-3.5";
1538
+ if (iconSize2 === "lg") return "size-4";
1400
1539
  switch (size) {
1401
1540
  case "tiny":
1402
1541
  return "size-3";
@@ -1421,10 +1560,10 @@ function resolveShadowClass(shadow) {
1421
1560
  const level = shadow === true ? "md" : shadow;
1422
1561
  return SHADOW_CLASSES[level];
1423
1562
  }
1424
- function ButtonContent({ loading, prefix, suffix, size, children }) {
1425
- const iconSizeClass = getIconSizeClass(size);
1563
+ function ButtonContent({ loading, prefix, suffix, size, iconSize: iconSize2, children }) {
1564
+ const iconSizeClass = getIconSizeClass(size, iconSize2);
1426
1565
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1427
- loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size) }),
1566
+ loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize2) }),
1428
1567
  prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
1429
1568
  children,
1430
1569
  suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
@@ -1435,6 +1574,7 @@ var Button = ({
1435
1574
  variant,
1436
1575
  size,
1437
1576
  shape,
1577
+ iconSize: iconSize2,
1438
1578
  asChild = false,
1439
1579
  loading = false,
1440
1580
  disabled,
@@ -1452,11 +1592,21 @@ var Button = ({
1452
1592
  Comp,
1453
1593
  {
1454
1594
  ref,
1455
- className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
1595
+ className: cn(buttonVariants({ variant, size, shape, iconSize: iconSize2 }), shadowClass, className),
1456
1596
  disabled: isDisabled,
1457
1597
  "aria-busy": loading || void 0,
1458
1598
  ...props,
1459
- children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
1599
+ children: asChild ? children : /* @__PURE__ */ jsx(
1600
+ ButtonContent,
1601
+ {
1602
+ loading,
1603
+ prefix,
1604
+ suffix,
1605
+ size,
1606
+ iconSize: iconSize2,
1607
+ children
1608
+ }
1609
+ )
1460
1610
  }
1461
1611
  );
1462
1612
  };
@@ -1466,6 +1616,7 @@ var ButtonLink = ({
1466
1616
  variant,
1467
1617
  size,
1468
1618
  shape,
1619
+ iconSize: iconSize2,
1469
1620
  prefix,
1470
1621
  suffix,
1471
1622
  shadow,
@@ -1485,14 +1636,24 @@ var ButtonLink = ({
1485
1636
  {
1486
1637
  ref,
1487
1638
  className: cn(
1488
- buttonVariants({ variant, size, shape }),
1639
+ buttonVariants({ variant, size, shape, iconSize: iconSize2 }),
1489
1640
  shadowClass,
1490
1641
  loading && "pointer-events-none opacity-50",
1491
1642
  className
1492
1643
  ),
1493
1644
  ...loadingProps,
1494
1645
  ...props,
1495
- children: /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
1646
+ children: /* @__PURE__ */ jsx(
1647
+ ButtonContent,
1648
+ {
1649
+ loading,
1650
+ prefix,
1651
+ suffix,
1652
+ size,
1653
+ iconSize: iconSize2,
1654
+ children
1655
+ }
1656
+ )
1496
1657
  }
1497
1658
  );
1498
1659
  };
@@ -1559,8 +1720,68 @@ var CardFooter = ({
1559
1720
  ...props
1560
1721
  }) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props });
1561
1722
  CardFooter.displayName = "CardFooter";
1723
+ var DEFAULT_STROKE_WIDTH = 1.6;
1724
+ function CheckGlyph({
1725
+ size = 16,
1726
+ width,
1727
+ height,
1728
+ strokeWidth = DEFAULT_STROKE_WIDTH,
1729
+ ...props
1730
+ }) {
1731
+ return /* @__PURE__ */ jsx(
1732
+ "svg",
1733
+ {
1734
+ "aria-hidden": "true",
1735
+ className: "shrink-0",
1736
+ viewBox: "0 0 16 16",
1737
+ width: width ?? size,
1738
+ height: height ?? size,
1739
+ ...props,
1740
+ children: /* @__PURE__ */ jsx(
1741
+ "path",
1742
+ {
1743
+ d: "M11.2 5.6L6.8 10L4.8 8",
1744
+ strokeLinecap: "round",
1745
+ strokeLinejoin: "round",
1746
+ strokeWidth
1747
+ }
1748
+ )
1749
+ }
1750
+ );
1751
+ }
1752
+ function IndeterminateGlyph({
1753
+ size = 16,
1754
+ width,
1755
+ height,
1756
+ strokeWidth = DEFAULT_STROKE_WIDTH,
1757
+ ...props
1758
+ }) {
1759
+ return /* @__PURE__ */ jsx(
1760
+ "svg",
1761
+ {
1762
+ "aria-hidden": "true",
1763
+ className: "shrink-0",
1764
+ viewBox: "0 0 16 16",
1765
+ width: width ?? size,
1766
+ height: height ?? size,
1767
+ ...props,
1768
+ children: /* @__PURE__ */ jsx(
1769
+ "line",
1770
+ {
1771
+ x1: "4",
1772
+ x2: "12",
1773
+ y1: "8",
1774
+ y2: "8",
1775
+ strokeLinecap: "round",
1776
+ strokeLinejoin: "round",
1777
+ strokeWidth
1778
+ }
1779
+ )
1780
+ }
1781
+ );
1782
+ }
1562
1783
  var getInputClasses = (checked, disabled, indeterminate) => {
1563
- let className = "relative border w-4 h-4 duration-200 rounded inline-flex items-center justify-center";
1784
+ let className = "relative border w-4 h-4 duration-micro rounded inline-flex items-center justify-center";
1564
1785
  if (disabled) {
1565
1786
  if (!checked || indeterminate) {
1566
1787
  className += " bg-geist-gray-100 border-geist-gray-500";
@@ -1623,26 +1844,7 @@ var Checkbox = ({
1623
1844
  className: "sr-only"
1624
1845
  }
1625
1846
  ),
1626
- /* @__PURE__ */ jsx("span", { className: getInputClasses(checked, disabled, indeterminate), children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "shrink-0", height: "16", viewBox: "0 0 20 20", width: "16", children: indeterminate ? /* @__PURE__ */ jsx(
1627
- "line",
1628
- {
1629
- strokeLinecap: "round",
1630
- strokeLinejoin: "round",
1631
- strokeWidth: "2",
1632
- x1: "5",
1633
- x2: "15",
1634
- y1: "10",
1635
- y2: "10"
1636
- }
1637
- ) : /* @__PURE__ */ jsx(
1638
- "path",
1639
- {
1640
- d: "M14 7L8.5 12.5L6 10",
1641
- strokeLinecap: "round",
1642
- strokeLinejoin: "round",
1643
- strokeWidth: "2"
1644
- }
1645
- ) }) }),
1847
+ /* @__PURE__ */ jsx("span", { className: getInputClasses(checked, disabled, indeterminate), children: indeterminate ? /* @__PURE__ */ jsx(IndeterminateGlyph, {}) : /* @__PURE__ */ jsx(CheckGlyph, {}) }),
1646
1848
  children && /* @__PURE__ */ jsx("span", { className: "ml-2", children })
1647
1849
  ]
1648
1850
  }
@@ -1878,6 +2080,11 @@ var overlayPrimitiveClassNames = {
1878
2080
  "data-[highlighted]:bg-accent data-[popup-open]:bg-accent"
1879
2081
  ].join(" "),
1880
2082
  menuCheckboxItem: [menuItemBaseClassName, menuHighlightedClassName, "pl-8"].join(" "),
2083
+ menuFilterInput: [
2084
+ "h-7 w-full rounded-[var(--radius-sm)] bg-muted px-2 text-sm text-foreground",
2085
+ "placeholder:text-muted-foreground outline-none"
2086
+ ].join(" "),
2087
+ menuEmpty: "px-2 py-3 text-center text-sm text-muted-foreground",
1881
2088
  menuIndicator: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center text-muted-foreground",
1882
2089
  menubarRoot: "flex h-10 items-center space-x-1 rounded-[var(--radius-md)] border border-border bg-background p-1 outline-none",
1883
2090
  menubarTrigger: [
@@ -2087,6 +2294,40 @@ var DropdownMenuRadioItem = ({
2087
2294
  }
2088
2295
  );
2089
2296
  DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
2297
+ var MENU_RESERVED_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "Enter", "Tab"]);
2298
+ var DropdownMenuFilterInput = ({
2299
+ className,
2300
+ onKeyDown,
2301
+ ref,
2302
+ ...props
2303
+ }) => /* @__PURE__ */ jsx(
2304
+ "input",
2305
+ {
2306
+ ref,
2307
+ type: "search",
2308
+ className: cn(overlayPrimitiveClassNames.menuFilterInput, className),
2309
+ onKeyDown: (event) => {
2310
+ onKeyDown?.(event);
2311
+ if (!MENU_RESERVED_KEYS.has(event.key)) {
2312
+ event.stopPropagation();
2313
+ }
2314
+ },
2315
+ ...props
2316
+ }
2317
+ );
2318
+ DropdownMenuFilterInput.displayName = "DropdownMenuFilterInput";
2319
+ var DropdownMenuEmpty = ({
2320
+ className,
2321
+ ...props
2322
+ }) => /* @__PURE__ */ jsx(
2323
+ "div",
2324
+ {
2325
+ role: "presentation",
2326
+ className: cn(overlayPrimitiveClassNames.menuEmpty, className),
2327
+ ...props
2328
+ }
2329
+ );
2330
+ DropdownMenuEmpty.displayName = "DropdownMenuEmpty";
2090
2331
  var DropdownMenuLabel = ({
2091
2332
  className,
2092
2333
  inset,
@@ -3246,7 +3487,6 @@ var comboboxTriggerVariants = cva(
3246
3487
  "text-[length:var(--combobox-font-size)] ring-offset-background",
3247
3488
  "transition-colors duration-micro ease-out",
3248
3489
  "placeholder:text-muted-foreground",
3249
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3250
3490
  "disabled:cursor-not-allowed disabled:opacity-50",
3251
3491
  "[&>span]:line-clamp-1 [&>span]:text-left"
3252
3492
  ].join(" "),
@@ -3258,7 +3498,7 @@ var comboboxTriggerVariants = cva(
3258
3498
  large: ""
3259
3499
  },
3260
3500
  error: {
3261
- true: "border-destructive focus-visible:ring-destructive",
3501
+ true: "border-destructive",
3262
3502
  false: ""
3263
3503
  }
3264
3504
  },
@@ -3825,20 +4065,27 @@ var TooltipContent = ({
3825
4065
  }
3826
4066
  ) });
3827
4067
  TooltipContent.displayName = "TooltipContent";
4068
+ var COPIED_TINT = "text-[hsl(var(--success-strong))]";
4069
+ function CopiedAnnouncement({ copied, message }) {
4070
+ return /* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "sr-only", children: copied ? message : "" });
4071
+ }
3828
4072
  function CopyButton({
3829
4073
  value,
3830
4074
  label,
4075
+ copiedLabel = "Copied",
3831
4076
  successMessage = "Copied to clipboard",
3832
4077
  tooltipText = "Copy",
3833
4078
  iconType = "copy",
4079
+ iconPosition = "leading",
3834
4080
  showToast = true,
4081
+ timeout = 2e3,
3835
4082
  onCopied,
3836
4083
  variant = "ghost",
3837
4084
  size = "icon",
3838
4085
  className,
3839
4086
  ...props
3840
4087
  }) {
3841
- const [copied, setCopied] = React24.useState(false);
4088
+ const { copied, copy } = useCopyToClipboard({ successMessage, showToast, timeout });
3842
4089
  const IconComponent = {
3843
4090
  copy: Copy,
3844
4091
  link: Link,
@@ -3846,38 +4093,30 @@ function CopyButton({
3846
4093
  hash: Hash
3847
4094
  }[iconType];
3848
4095
  const handleCopy = async () => {
3849
- try {
3850
- await navigator.clipboard.writeText(value);
3851
- setCopied(true);
3852
- if (showToast) {
3853
- toast.success(successMessage);
3854
- }
3855
- onCopied?.(value);
3856
- setTimeout(() => setCopied(false), 2e3);
3857
- } catch (error) {
3858
- console.error("Failed to copy:", error);
3859
- toast.error("Failed to copy to clipboard");
3860
- }
4096
+ if (await copy(value)) onCopied?.(value);
3861
4097
  };
4098
+ const icon = copied ? /* @__PURE__ */ jsx(Check, { className: COPIED_TINT }) : /* @__PURE__ */ jsx(IconComponent, {});
4099
+ const iconSlot = iconPosition === "trailing" ? { suffix: icon } : { prefix: icon };
3862
4100
  const button = /* @__PURE__ */ jsxs(
3863
4101
  Button,
3864
4102
  {
3865
4103
  variant,
3866
4104
  size,
3867
4105
  onClick: handleCopy,
3868
- className: cn("transition-colors", copied && "text-green-600 dark:text-green-400", className),
4106
+ className: cn("transition-colors", className),
4107
+ ...iconSlot,
3869
4108
  ...props,
3870
4109
  children: [
3871
- copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(IconComponent, { className: "size-4" }),
3872
- label && /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: label }),
3873
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: tooltipText })
4110
+ label && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: copied && copiedLabel ? copiedLabel : label }),
4111
+ !label && /* @__PURE__ */ jsx("span", { className: "sr-only", children: tooltipText }),
4112
+ /* @__PURE__ */ jsx(CopiedAnnouncement, { copied, message: successMessage })
3874
4113
  ]
3875
4114
  }
3876
4115
  );
3877
4116
  if (!label) {
3878
4117
  return /* @__PURE__ */ jsxs(Tooltip, { children: [
3879
4118
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: button }),
3880
- /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: copied ? "Copied!" : tooltipText }) })
4119
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: copied ? "Copied" : tooltipText }) })
3881
4120
  ] });
3882
4121
  }
3883
4122
  return button;
@@ -3933,6 +4172,36 @@ function CopyCodeButton({
3933
4172
  }
3934
4173
  );
3935
4174
  }
4175
+ function CopyMenuItem({
4176
+ value,
4177
+ children,
4178
+ successMessage = "Copied to clipboard",
4179
+ showToast = false,
4180
+ timeout = 2e3,
4181
+ closeOnCopy = false,
4182
+ onCopied,
4183
+ className,
4184
+ ...props
4185
+ }) {
4186
+ const { copied, copy } = useCopyToClipboard({ successMessage, showToast, timeout });
4187
+ const handleCopy = async () => {
4188
+ if (await copy(value)) onCopied?.(value);
4189
+ };
4190
+ return /* @__PURE__ */ jsxs(
4191
+ DropdownMenuItem,
4192
+ {
4193
+ closeOnClick: closeOnCopy,
4194
+ onClick: handleCopy,
4195
+ className: cn("cursor-pointer", className),
4196
+ ...props,
4197
+ children: [
4198
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
4199
+ copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: cn("size-4", COPIED_TINT) }) : /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "size-4 text-muted-foreground" }),
4200
+ /* @__PURE__ */ jsx(CopiedAnnouncement, { copied, message: successMessage })
4201
+ ]
4202
+ }
4203
+ );
4204
+ }
3936
4205
  function CopyableField({ value, label, truncate = true, className }) {
3937
4206
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
3938
4207
  label && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground shrink-0", children: [
@@ -4142,7 +4411,7 @@ var ContextCardTrigger = ({
4142
4411
  "transition-[opacity,transform,display] duration-[var(--context-card-duration)] ease-[var(--context-card-easing)]",
4143
4412
  "data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:scale-[0.98] data-ending-style:scale-[0.98]",
4144
4413
  "motion-reduce:transition-none motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100",
4145
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
4414
+ "",
4146
4415
  "data-[side=bottom]:origin-top data-[side=left]:origin-right data-[side=right]:origin-left data-[side=top]:origin-bottom",
4147
4416
  className
4148
4417
  ),
@@ -5146,11 +5415,11 @@ var formControlInvalidClassNames = {
5146
5415
  };
5147
5416
  var inputVariants = cva(
5148
5417
  [
5149
- "flex h-[var(--input-height)] w-full rounded-[var(--input-radius)] border border-input bg-background",
5150
- "px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground shadow-xs",
5418
+ "flex h-[var(--input-height)] w-full rounded-[var(--input-radius)]",
5419
+ "px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground",
5151
5420
  "transition-[background-color,border-color,box-shadow,color] duration-micro ease-out",
5152
5421
  "placeholder:text-muted-foreground",
5153
- formControlFocusClassNames.input,
5422
+ "outline-none",
5154
5423
  "disabled:cursor-not-allowed disabled:opacity-50",
5155
5424
  "read-only:bg-muted/70 read-only:cursor-default",
5156
5425
  "file:h-full file:border-0 file:border-e file:border-solid file:border-input file:bg-transparent",
@@ -5173,11 +5442,31 @@ var inputVariants = cva(
5173
5442
  prefix: "pl-[var(--input-padding-left)]",
5174
5443
  suffix: "pr-[var(--input-padding-right)]",
5175
5444
  both: "pl-[var(--input-padding-left)] pr-[var(--input-padding-right)]"
5445
+ },
5446
+ /**
5447
+ * `bare` drops the field's own stroke, fill and lift so it can sit inside
5448
+ * a container that already provides them — a footer subscribe group, a
5449
+ * search well, a segmented composer. Those surfaces were each being built
5450
+ * by hand with a raw <input>, because overriding the bordered look from
5451
+ * outside is not reliable: `border-transparent` passed via className and
5452
+ * `border-input` from the base are both border-color utilities, so which
5453
+ * one wins depends on their order in the generated stylesheet rather than
5454
+ * on the order they were written. That is why the stroke, fill and shadow
5455
+ * live in this variant instead of the base — the two tones now never emit
5456
+ * a competing declaration.
5457
+ *
5458
+ * A bare field draws no focus ring of its own. The container owns it, so
5459
+ * the ring surrounds the whole group rather than a box inside it.
5460
+ */
5461
+ tone: {
5462
+ bordered: `border border-input bg-background shadow-xs ${formControlFocusClassNames.input}`,
5463
+ bare: "border-0 bg-transparent shadow-none"
5176
5464
  }
5177
5465
  },
5178
5466
  defaultVariants: {
5179
5467
  size: "md",
5180
- affix: "none"
5468
+ affix: "none",
5469
+ tone: "bordered"
5181
5470
  }
5182
5471
  }
5183
5472
  );
@@ -5200,7 +5489,7 @@ var inputControlButtonVariants = cva(
5200
5489
  "absolute right-[var(--input-control-inset)] top-1/2 flex size-[var(--input-control-size)] -translate-y-1/2 items-center justify-center",
5201
5490
  "rounded-[var(--radius-sm)] text-muted-foreground transition-colors duration-micro ease-out",
5202
5491
  "hover:bg-accent hover:text-foreground",
5203
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
5492
+ "focus-visible:outline-none",
5204
5493
  "disabled:pointer-events-none disabled:opacity-50",
5205
5494
  "[&_svg]:size-[var(--input-control-icon-size)]"
5206
5495
  ].join(" ")
@@ -5239,7 +5528,7 @@ function getInputStyle(size, style) {
5239
5528
  "--input-focus-ring-width": `${inputTokens.focusRingWidth}px`,
5240
5529
  borderRadius: "var(--input-radius)",
5241
5530
  outline: "none",
5242
- ...style
5531
+ ...asPlainStyle(style)
5243
5532
  };
5244
5533
  }
5245
5534
  function getAffixMode(prefix, hasRightAdornment) {
@@ -5265,6 +5554,7 @@ var Input = ({
5265
5554
  className,
5266
5555
  type = "text",
5267
5556
  size = "md",
5557
+ tone = "bordered",
5268
5558
  prefix,
5269
5559
  suffix,
5270
5560
  clearable,
@@ -5384,7 +5674,7 @@ var Input = ({
5384
5674
  "aria-describedby": describedBy,
5385
5675
  "aria-busy": loading || void 0,
5386
5676
  className: cn(
5387
- inputVariants({ size, affix }),
5677
+ inputVariants({ size, affix, tone }),
5388
5678
  type === "file" && "p-0 pr-[var(--input-padding-x)] text-muted-foreground",
5389
5679
  className
5390
5680
  ),
@@ -6577,7 +6867,7 @@ var MultiSelectTrigger = ({
6577
6867
  "gap-[var(--multi-select-trigger-gap)] rounded-[var(--multi-select-trigger-radius)] border border-input bg-background",
6578
6868
  "px-[var(--multi-select-trigger-padding-x)] text-left text-[length:var(--multi-select-trigger-font-size)] text-foreground shadow-xs",
6579
6869
  "transition-[background-color,border-color,box-shadow,color] duration-[var(--multi-select-duration)] ease-[var(--multi-select-easing)]",
6580
- "hover:bg-accent/60 focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6870
+ "hover:bg-accent/60 focus-visible:border-ring focus-visible:outline-none",
6581
6871
  "disabled:cursor-not-allowed disabled:opacity-50",
6582
6872
  className
6583
6873
  ),
@@ -6768,7 +7058,7 @@ var MultiSelectRow = ({
6768
7058
  "peer size-[var(--multi-select-checkbox-size)] appearance-none rounded-[var(--radius-sm)] border border-input bg-background",
6769
7059
  "transition-[background-color,border-color,box-shadow] duration-[var(--multi-select-duration)] ease-[var(--multi-select-easing)]",
6770
7060
  "hover:border-ring checked:border-primary checked:bg-primary",
6771
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
7061
+ "focus-visible:outline-none"
6772
7062
  )
6773
7063
  }
6774
7064
  ),
@@ -6798,7 +7088,7 @@ var MultiSelectRow = ({
6798
7088
  className: cn(
6799
7089
  "min-w-[var(--multi-select-action-min-width)] shrink-0 rounded-[var(--radius-sm)] px-2 py-1 text-right text-[length:var(--multi-select-row-description-size)] font-medium text-muted-foreground",
6800
7090
  "opacity-0 transition-[background-color,color,opacity] duration-[var(--multi-select-duration)] ease-[var(--multi-select-easing)]",
6801
- "hover:bg-background hover:text-foreground focus-visible:bg-background focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
7091
+ "hover:bg-background hover:text-foreground focus-visible:bg-background focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none",
6802
7092
  "group-hover:opacity-100 group-focus-within:opacity-100"
6803
7093
  ),
6804
7094
  children: action.label
@@ -7848,7 +8138,7 @@ function PaginationRail({
7848
8138
  "group flex min-h-[var(--pagination-min-height)] min-w-0 items-center gap-[var(--pagination-gap)] rounded-[var(--pagination-radius)] border border-border bg-background",
7849
8139
  "px-[var(--pagination-padding-x)] py-[var(--pagination-padding-y)] text-foreground shadow-xs",
7850
8140
  "transition-[background-color,border-color,box-shadow,color,transform] duration-[var(--pagination-duration)] ease-[var(--pagination-easing)]",
7851
- "hover:border-ring hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
8141
+ "hover:border-ring hover:bg-accent focus-visible:outline-none",
7852
8142
  "motion-reduce:transition-none",
7853
8143
  isPrevious ? "justify-start text-left" : "justify-end text-right"
7854
8144
  ),
@@ -8081,7 +8371,7 @@ var variantMap = {
8081
8371
  cta: "text-foreground decoration-border hover:text-foreground hover:decoration-foreground"
8082
8372
  }
8083
8373
  };
8084
- var ctaBase = "font-medium underline underline-offset-[5px] transition-colors duration-100";
8374
+ var ctaBase = "font-medium underline underline-offset-[5px] transition-colors duration-micro";
8085
8375
  function ProjectBanner({
8086
8376
  variant = "info",
8087
8377
  label,
@@ -8141,7 +8431,7 @@ var radioControlClassName = cn(
8141
8431
  "transition-[background-color,border-color,box-shadow] duration-[var(--radio-motion-duration)] ease-[var(--radio-motion-easing)]",
8142
8432
  "after:size-[var(--radio-dot-size)] after:scale-0 after:rounded-[var(--radius-full)] after:bg-current after:opacity-0 after:transition-[opacity,transform] after:duration-[var(--radio-motion-duration)] after:ease-[var(--radio-motion-easing)] after:content-['']",
8143
8433
  "peer-checked:border-[var(--neutral-12)] peer-checked:after:scale-100 peer-checked:after:opacity-100",
8144
- "peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2",
8434
+ "peer-focus-visible:outline-none",
8145
8435
  "peer-disabled:border-[var(--neutral-5)] peer-disabled:bg-muted peer-disabled:text-[var(--neutral-8)]"
8146
8436
  );
8147
8437
  function useRadioGroupContext() {
@@ -8360,7 +8650,7 @@ var ResizableHandle = ({
8360
8650
  Separator,
8361
8651
  {
8362
8652
  className: cn(
8363
- "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
8653
+ "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
8364
8654
  className
8365
8655
  ),
8366
8656
  ...props,
@@ -8505,7 +8795,7 @@ function ScrollerButton({
8505
8795
  "absolute z-20 grid size-[var(--scroller-button-size)] place-items-center rounded-[var(--scroller-button-radius)]",
8506
8796
  "border border-border bg-background text-muted-foreground shadow-[var(--scroller-button-shadow)]",
8507
8797
  "transition-[background-color,border-color,color,opacity,transform] duration-[var(--scroller-duration)] ease-[var(--scroller-easing)]",
8508
- "hover:border-ring hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
8798
+ "hover:border-ring hover:text-foreground focus-visible:outline-none",
8509
8799
  "disabled:pointer-events-none disabled:opacity-0 motion-reduce:transition-none",
8510
8800
  axis === "x" && direction === "previous" && "left-[var(--scroller-button-offset)] top-1/2 -translate-y-1/2",
8511
8801
  axis === "x" && direction === "next" && "right-[var(--scroller-button-offset)] top-1/2 -translate-y-1/2",
@@ -8600,7 +8890,7 @@ function Scroller({
8600
8890
  onScroll: updateEdgeState,
8601
8891
  className: cn(
8602
8892
  "h-[var(--scroller-height)] rounded-[var(--scroller-radius)] outline-none",
8603
- "scroll-smooth overscroll-contain focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 motion-reduce:scroll-auto",
8893
+ "scroll-smooth overscroll-contain motion-reduce:scroll-auto",
8604
8894
  resolveScrollClasses(overflow)
8605
8895
  ),
8606
8896
  children: /* @__PURE__ */ jsx(
@@ -8651,7 +8941,7 @@ function getSelectTriggerStyle(size, style) {
8651
8941
  "--select-focus-ring-width": `${selectTokens.focusRingWidth}px`,
8652
8942
  borderRadius: "var(--select-radius)",
8653
8943
  outline: "none",
8654
- ...style
8944
+ ...asPlainStyle(style)
8655
8945
  };
8656
8946
  }
8657
8947
  function getNativeSelectStyle(size, style) {
@@ -8670,7 +8960,7 @@ function getNativeSelectStyle(size, style) {
8670
8960
  "--select-message-gap": `${selectTokens.messageGap}px`,
8671
8961
  "--select-duration": `${selectTokens.motion.duration}ms`,
8672
8962
  "--select-easing": selectTokens.motion.easing,
8673
- ...style
8963
+ ...asPlainStyle(style)
8674
8964
  };
8675
8965
  }
8676
8966
  function getSelectContentStyle(style) {
@@ -8690,7 +8980,7 @@ function getSelectContentStyle(style) {
8690
8980
  "--select-item-indicator-size": `${selectTokens.item.indicatorSize}px`,
8691
8981
  "--select-item-indicator-icon-size": `${selectTokens.item.indicatorIconSize}px`,
8692
8982
  zIndex: overlayZIndex.popover,
8693
- ...style
8983
+ ...asPlainStyle(style)
8694
8984
  };
8695
8985
  }
8696
8986
  function textOf(node) {
@@ -9126,7 +9416,7 @@ function getSheetStyle(style) {
9126
9416
  "--sheet-shadow": sheetTokens.surface.shadow,
9127
9417
  "--sheet-duration": `${overlayTokens.motion.duration}ms`,
9128
9418
  "--sheet-easing": overlayTokens.motion.easing,
9129
- ...style
9419
+ ...asPlainStyle(style)
9130
9420
  };
9131
9421
  }
9132
9422
  function Sheet({ modal = "trap-focus", disablePointerDismissal = true, ...props }) {
@@ -9428,7 +9718,7 @@ var ShowMore = ({
9428
9718
  "h-[var(--show-more-trigger-height)] rounded-[var(--show-more-radius)] px-[var(--show-more-trigger-padding-x)]",
9429
9719
  "transition-[background-color,border-color,color] duration-[var(--show-more-duration)] ease-[var(--show-more-easing)]",
9430
9720
  "hover:border-border hover:bg-muted",
9431
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
9721
+ "focus-visible:outline-none",
9432
9722
  "disabled:pointer-events-none disabled:opacity-50",
9433
9723
  "motion-reduce:transition-none",
9434
9724
  buttonClassName
@@ -9581,7 +9871,7 @@ function getSliderStyle(progress, style) {
9581
9871
  "--slider-duration": `${sliderTokens.motion.duration}ms`,
9582
9872
  "--slider-easing": sliderTokens.motion.easing,
9583
9873
  "--slider-progress": `${progress}%`,
9584
- ...style
9874
+ ...asPlainStyle(style)
9585
9875
  };
9586
9876
  }
9587
9877
  function formatSliderValue(value, unit) {
@@ -9697,7 +9987,7 @@ var Slider = ({
9697
9987
  onBlur,
9698
9988
  className: cn(
9699
9989
  "h-[var(--slider-height)] w-full cursor-pointer appearance-none rounded-[var(--slider-radius)] bg-[linear-gradient(to_right,var(--slider-track-fill)_0,var(--slider-track-fill)_var(--slider-progress),var(--slider-track-background)_var(--slider-progress),var(--slider-track-background)_100%)] bg-[length:100%_var(--slider-track-height)] bg-center bg-no-repeat outline-none",
9700
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
9990
+ "disabled:cursor-not-allowed disabled:opacity-50",
9701
9991
  "[&::-moz-range-thumb]:size-[var(--slider-thumb-size)] [&::-moz-range-thumb]:appearance-none [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border [&::-moz-range-thumb]:border-border [&::-moz-range-thumb]:bg-[var(--slider-thumb-background)] [&::-moz-range-thumb]:shadow-[var(--slider-thumb-shadow)]",
9702
9992
  "[&::-webkit-slider-thumb]:size-[var(--slider-thumb-size)] [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border [&::-webkit-slider-thumb]:border-border [&::-webkit-slider-thumb]:bg-[var(--slider-thumb-background)] [&::-webkit-slider-thumb]:shadow-[var(--slider-thumb-shadow)]",
9703
9993
  "[&::-moz-range-thumb]:transition-transform [&::-moz-range-thumb]:duration-[var(--slider-duration)] [&::-moz-range-thumb]:ease-[var(--slider-easing)]",
@@ -9730,7 +10020,7 @@ function getSpinnerStyle(size, style) {
9730
10020
  "--spinner-bar-radius": `${spinnerTokens.barRadius}px`,
9731
10021
  "--spinner-duration": `${spinnerTokens.motion.duration}ms`,
9732
10022
  "--spinner-easing": spinnerTokens.motion.easing,
9733
- ...style
10023
+ ...asPlainStyle(style)
9734
10024
  };
9735
10025
  }
9736
10026
  function getBarOpacity(index) {
@@ -10109,7 +10399,7 @@ function getSwitchStyle(size, style) {
10109
10399
  "--switch-control-radius": `${switchTokens.controlRadius}px`,
10110
10400
  "--switch-duration": `${switchTokens.motion.duration}ms`,
10111
10401
  "--switch-easing": switchTokens.motion.easing,
10112
- ...style
10402
+ ...asPlainStyle(style)
10113
10403
  };
10114
10404
  }
10115
10405
  function getSwitchControlStyle(size, style) {
@@ -10120,7 +10410,7 @@ function getSwitchControlStyle(size, style) {
10120
10410
  "--switch-control-padding-x": `${sizeTokens.paddingX}px`,
10121
10411
  "--switch-icon-size": `${sizeTokens.iconSize}px`,
10122
10412
  "--switch-font-size": `${sizeTokens.fontSize}px`,
10123
- ...style
10413
+ ...asPlainStyle(style)
10124
10414
  };
10125
10415
  }
10126
10416
  var SwitchRoot = function SwitchRoot2({
@@ -10230,7 +10520,7 @@ var SwitchControl = function SwitchControl2({
10230
10520
  "inline-flex h-full w-full items-center justify-center gap-1.5 whitespace-nowrap rounded-[var(--switch-control-radius)] px-[var(--switch-control-padding-x)] font-medium text-[length:var(--switch-font-size)]",
10231
10521
  "text-muted-foreground transition-[background-color,box-shadow,color] duration-[var(--switch-duration)] ease-[var(--switch-easing)]",
10232
10522
  "peer-checked:bg-background peer-checked:text-foreground peer-checked:shadow-sm",
10233
- "peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background",
10523
+ "",
10234
10524
  "peer-disabled:pointer-events-none peer-disabled:text-muted-foreground/60",
10235
10525
  "[&_svg]:size-[var(--switch-icon-size)]"
10236
10526
  ),
@@ -10249,7 +10539,12 @@ SwitchControl.displayName = "Switch.Control";
10249
10539
  var Switch = Object.assign(SwitchRoot, {
10250
10540
  Control: SwitchControl
10251
10541
  });
10252
- function createTableVars(style) {
10542
+ var ALIGNMENT_CLASS = {
10543
+ start: "text-left",
10544
+ center: "text-center",
10545
+ end: "text-right"
10546
+ };
10547
+ function createTableVars(style, bare) {
10253
10548
  return {
10254
10549
  "--table-min-width": `${tableTokens.wrapper.minWidth}px`,
10255
10550
  "--table-padding": `${tableTokens.wrapper.padding}px`,
@@ -10261,7 +10556,7 @@ function createTableVars(style) {
10261
10556
  "--table-font-size": `${tableTokens.typography.size}px`,
10262
10557
  "--table-heading-weight": tableTokens.typography.headingWeight,
10263
10558
  "--table-body-weight": tableTokens.typography.bodyWeight,
10264
- "--table-body-spacer": `${tableTokens.spacer.bodyTop}px`,
10559
+ "--table-body-spacer": bare ? "0px" : `${tableTokens.spacer.bodyTop}px`,
10265
10560
  "--table-motion-duration": `${tableTokens.motion.duration}ms`,
10266
10561
  "--table-motion-easing": tableTokens.motion.easing,
10267
10562
  ...style
@@ -10272,16 +10567,18 @@ var TableRoot = ({
10272
10567
  wrapperClassName,
10273
10568
  wrapperStyle,
10274
10569
  style,
10570
+ bare = false,
10275
10571
  ref,
10276
10572
  ...props
10277
10573
  }) => /* @__PURE__ */ jsx(
10278
10574
  "div",
10279
10575
  {
10280
10576
  className: cn(
10281
- "relative w-full min-w-[var(--table-min-width)] overflow-auto rounded-[var(--table-radius)] border border-border bg-card p-[var(--table-padding)]",
10577
+ "relative w-full overflow-auto",
10578
+ !bare && "min-w-[var(--table-min-width)] rounded-[var(--table-radius)] border border-border bg-card p-[var(--table-padding)]",
10282
10579
  wrapperClassName
10283
10580
  ),
10284
- style: createTableVars(wrapperStyle),
10581
+ style: createTableVars(wrapperStyle, bare),
10285
10582
  children: /* @__PURE__ */ jsx(
10286
10583
  "table",
10287
10584
  {
@@ -10367,6 +10664,7 @@ TableRow.displayName = "TableRow";
10367
10664
  var TableHead = ({
10368
10665
  className,
10369
10666
  numeric = false,
10667
+ alignment,
10370
10668
  scope = "col",
10371
10669
  ref,
10372
10670
  ...props
@@ -10377,8 +10675,10 @@ var TableHead = ({
10377
10675
  scope,
10378
10676
  className: cn(
10379
10677
  "h-[var(--table-header-height)] px-[var(--table-cell-padding-x)] text-left align-middle font-[var(--table-heading-weight)] text-muted-foreground",
10380
- "last:text-right [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-px",
10678
+ "[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-px",
10679
+ !alignment && "last:text-right",
10381
10680
  numeric && "text-right font-mono tabular-nums",
10681
+ alignment && ALIGNMENT_CLASS[alignment],
10382
10682
  className
10383
10683
  ),
10384
10684
  ...props
@@ -10388,6 +10688,7 @@ TableHead.displayName = "TableHead";
10388
10688
  var TableCell = ({
10389
10689
  className,
10390
10690
  numeric = false,
10691
+ alignment,
10391
10692
  ref,
10392
10693
  ...props
10393
10694
  }) => /* @__PURE__ */ jsx(
@@ -10396,8 +10697,10 @@ var TableCell = ({
10396
10697
  ref,
10397
10698
  className: cn(
10398
10699
  "px-[var(--table-cell-padding-x)] py-[var(--table-cell-padding-y)] align-middle",
10399
- "last:text-right [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-px",
10700
+ "[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-px",
10701
+ !alignment && "last:text-right",
10400
10702
  numeric && "text-right font-mono tabular-nums",
10703
+ alignment && ALIGNMENT_CLASS[alignment],
10401
10704
  className
10402
10705
  ),
10403
10706
  ...props
@@ -10464,7 +10767,7 @@ var tabsListVariants = cva(
10464
10767
  }
10465
10768
  );
10466
10769
  var tabsTriggerVariants = cva(
10467
- "relative inline-flex h-[calc(var(--tabs-height)-var(--tabs-padding)*2)] min-w-[var(--tabs-trigger-min-width)] shrink-0 cursor-pointer items-center justify-center gap-[var(--tabs-trigger-gap)] whitespace-nowrap rounded-[var(--tabs-trigger-radius)] px-[var(--tabs-trigger-padding-x)] font-medium text-[length:var(--tabs-font-size)] outline-none transition-[background-color,border-color,box-shadow,color,opacity] duration-[var(--tabs-duration)] ease-[var(--tabs-easing)] focus-visible:ring-[length:var(--tabs-focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--tabs-focus-ring-offset)] focus-visible:ring-offset-background disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:size-[var(--tabs-icon-size)] [&_svg]:shrink-0",
10770
+ "relative inline-flex h-[calc(var(--tabs-height)-var(--tabs-padding)*2)] min-w-[var(--tabs-trigger-min-width)] shrink-0 cursor-pointer items-center justify-center gap-[var(--tabs-trigger-gap)] whitespace-nowrap rounded-[var(--tabs-trigger-radius)] px-[var(--tabs-trigger-padding-x)] font-medium text-[length:var(--tabs-font-size)] outline-none transition-[background-color,border-color,box-shadow,color,opacity] duration-[var(--tabs-duration)] ease-[var(--tabs-easing)] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:size-[var(--tabs-icon-size)] [&_svg]:shrink-0",
10468
10771
  {
10469
10772
  variants: {
10470
10773
  variant: {
@@ -10501,7 +10804,7 @@ var tabsIndicatorVariants = cva(
10501
10804
  }
10502
10805
  );
10503
10806
  var tabsContentVariants = cva(
10504
- "mt-[var(--tabs-panel-gap)] text-[length:var(--tabs-font-size)] text-muted-foreground focus-visible:outline-none focus-visible:ring-[length:var(--tabs-focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--tabs-focus-ring-offset)] focus-visible:ring-offset-background",
10807
+ "mt-[var(--tabs-panel-gap)] text-[length:var(--tabs-font-size)] text-muted-foreground focus-visible:outline-none",
10505
10808
  {
10506
10809
  variants: {
10507
10810
  variant: {
@@ -10543,7 +10846,7 @@ function getTabsStyle(size, style) {
10543
10846
  "--tabs-badge-font-size": `${tabsTokens.badgeFontSize}px`,
10544
10847
  "--tabs-duration": `${tabsTokens.motion.duration}ms`,
10545
10848
  "--tabs-easing": tabsTokens.motion.easing,
10546
- ...style
10849
+ ...asPlainStyle(style)
10547
10850
  };
10548
10851
  }
10549
10852
  function getFirstEnabledValue(tabs) {
@@ -10739,7 +11042,7 @@ function getTextareaStyle(size, style) {
10739
11042
  "--textarea-focus-ring-width": `${textareaTokens.focusRingWidth}px`,
10740
11043
  borderRadius: "var(--textarea-radius)",
10741
11044
  outline: "none",
10742
- ...style
11045
+ ...asPlainStyle(style)
10743
11046
  };
10744
11047
  }
10745
11048
  function getTextareaFieldStyle() {
@@ -10852,7 +11155,7 @@ function getThemeSwitcherStyle(size, style) {
10852
11155
  "--theme-switcher-focus-ring-offset": `${themeSwitcherTokens.focusRingOffset}px`,
10853
11156
  "--theme-switcher-duration": `${themeSwitcherTokens.motion.duration}ms`,
10854
11157
  "--theme-switcher-easing": themeSwitcherTokens.motion.easing,
10855
- ...style
11158
+ ...asPlainStyle(style)
10856
11159
  };
10857
11160
  }
10858
11161
  function isThemeSwitcherValue(value) {
@@ -10951,7 +11254,7 @@ function getThemeToggleStyle(size, style) {
10951
11254
  "--theme-toggle-radius": `${token.radius}px`,
10952
11255
  "--theme-toggle-duration": `${themeToggleTokens.motion.duration}ms`,
10953
11256
  "--theme-toggle-easing": themeToggleTokens.motion.easing,
10954
- ...style
11257
+ ...asPlainStyle(style)
10955
11258
  };
10956
11259
  }
10957
11260
  function readDocumentTheme() {
@@ -11076,7 +11379,6 @@ var ThemeToggle = ({
11076
11379
  "inline-flex size-[var(--theme-toggle-size)] shrink-0 items-center justify-center rounded-[var(--theme-toggle-radius)] p-[var(--theme-toggle-padding)] text-foreground",
11077
11380
  "transition-[background-color,color,box-shadow] duration-[var(--theme-toggle-duration)] ease-[var(--theme-toggle-easing)]",
11078
11381
  "hover:bg-accent hover:text-accent-foreground",
11079
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
11080
11382
  "disabled:pointer-events-none disabled:opacity-50",
11081
11383
  "motion-reduce:transition-none",
11082
11384
  className
@@ -11351,7 +11653,7 @@ function getToggleStyle(size, color, style) {
11351
11653
  "--toggle-thumb": colorTokens.thumb,
11352
11654
  "--toggle-icon-on": colorTokens.iconOn,
11353
11655
  "--toggle-icon-off": colorTokens.iconOff,
11354
- ...style
11656
+ ...asPlainStyle(style)
11355
11657
  };
11356
11658
  }
11357
11659
  var Toggle = ({
@@ -11425,7 +11727,7 @@ var Toggle = ({
11425
11727
  "border-[var(--toggle-track-border)] transition-[background-color,border-color] duration-[var(--toggle-duration)] ease-[var(--toggle-easing)]",
11426
11728
  "peer-checked:bg-[var(--toggle-track-on)]",
11427
11729
  "peer-checked:[&>span]:translate-x-[var(--toggle-thumb-translate)] peer-checked:[&>span]:text-[var(--toggle-icon-on)]",
11428
- "peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background",
11730
+ "",
11429
11731
  "peer-disabled:cursor-not-allowed peer-disabled:opacity-60",
11430
11732
  "motion-reduce:transition-none"
11431
11733
  ),
@@ -11478,7 +11780,10 @@ var toggleGroupVariants = cva(
11478
11780
  variants: {
11479
11781
  variant: {
11480
11782
  default: "",
11481
- outline: "bg-transparent border"
11783
+ outline: "bg-transparent border",
11784
+ // Segmented pill look — theme-toggle / mode-pills style. Rounded-full
11785
+ // track with a rounded-full active segment (see toggleGroupItemVariants).
11786
+ pill: "rounded-full bg-neutral-2 p-0.5"
11482
11787
  }
11483
11788
  },
11484
11789
  defaultVariants: {
@@ -11487,12 +11792,13 @@ var toggleGroupVariants = cva(
11487
11792
  }
11488
11793
  );
11489
11794
  var toggleGroupItemVariants = cva(
11490
- "inline-flex items-center justify-center whitespace-nowrap rounded-[var(--radius-md)] px-3 py-1.5 text-sm font-medium ring-offset-background transition-[background-color,box-shadow,color,opacity] duration-flow ease-out motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-background data-[state=on]:text-foreground data-[state=on]:shadow-sm",
11795
+ "inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-[var(--radius-md)] px-3 py-1.5 text-sm font-medium ring-offset-background transition-[background-color,box-shadow,color,opacity] duration-flow ease-out motion-reduce:transition-none disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-background data-[state=on]:text-foreground data-[state=on]:shadow-sm",
11491
11796
  {
11492
11797
  variants: {
11493
11798
  variant: {
11494
11799
  default: "",
11495
- outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground"
11800
+ outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
11801
+ pill: "rounded-full text-neutral-11 hover:text-neutral-12 data-[state=on]:bg-primary/5 data-[state=on]:text-primary data-[state=on]:shadow-none"
11496
11802
  },
11497
11803
  size: {
11498
11804
  default: "h-9 px-3",
@@ -11550,7 +11856,17 @@ var ToggleGroup = ({
11550
11856
  }
11551
11857
  onValueChange?.(newValue);
11552
11858
  }
11553
- return /* @__PURE__ */ jsx("div", { ref, className: cn(toggleGroupVariants({ variant }), className), ...props, children: /* @__PURE__ */ jsx(ToggleGroupTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx(ToggleGroupValueContext.Provider, { value, children: /* @__PURE__ */ jsx(ToggleGroupChangeContext.Provider, { value: changeToggleGroupValue, children: /* @__PURE__ */ jsx(ToggleGroupDisabledContext.Provider, { value: disabled, children: /* @__PURE__ */ jsx(ToggleGroupVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(ToggleGroupSizeContext.Provider, { value: size, children }) }) }) }) }) }) });
11859
+ return /* @__PURE__ */ jsx(
11860
+ "div",
11861
+ {
11862
+ ref,
11863
+ role: type === "single" ? "radiogroup" : "group",
11864
+ "data-toggle-group-root": "",
11865
+ className: cn(toggleGroupVariants({ variant }), className),
11866
+ ...props,
11867
+ children: /* @__PURE__ */ jsx(ToggleGroupTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx(ToggleGroupValueContext.Provider, { value, children: /* @__PURE__ */ jsx(ToggleGroupChangeContext.Provider, { value: changeToggleGroupValue, children: /* @__PURE__ */ jsx(ToggleGroupDisabledContext.Provider, { value: disabled, children: /* @__PURE__ */ jsx(ToggleGroupVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(ToggleGroupSizeContext.Provider, { value: size, children }) }) }) }) }) })
11868
+ }
11869
+ );
11554
11870
  };
11555
11871
  ToggleGroup.displayName = "ToggleGroup";
11556
11872
  var ToggleGroupItem = ({
@@ -11568,7 +11884,8 @@ var ToggleGroupItem = ({
11568
11884
  function toggleItemSelection(event) {
11569
11885
  if (isDisabled) return;
11570
11886
  if (context.type === "single") {
11571
- context.onValueChange(isSelected ? "" : value);
11887
+ if (isSelected) return;
11888
+ context.onValueChange(value);
11572
11889
  } else {
11573
11890
  const currentArray = Array.isArray(context.value) ? context.value : [];
11574
11891
  context.onValueChange(
@@ -11577,26 +11894,75 @@ var ToggleGroupItem = ({
11577
11894
  }
11578
11895
  props.onClick?.(event);
11579
11896
  }
11580
- return /* @__PURE__ */ jsx(
11581
- "button",
11582
- {
11583
- ref,
11584
- type: "button",
11585
- disabled: isDisabled,
11586
- "data-state": isSelected ? "on" : "off",
11587
- "aria-pressed": isSelected,
11588
- className: cn(
11589
- toggleGroupItemVariants({
11590
- variant: variant ?? context.variant,
11591
- size: size ?? context.size
11592
- }),
11593
- className,
11594
- "focus-visible:z-10"
11595
- ),
11596
- onClick: toggleItemSelection,
11597
- ...props,
11598
- children
11599
- }
11897
+ function handleItemKeyDown(event) {
11898
+ props.onKeyDown?.(event);
11899
+ if (context.type !== "single" || event.defaultPrevented) return;
11900
+ const container = event.currentTarget.closest("[data-toggle-group-root]");
11901
+ if (!container) return;
11902
+ const items = Array.from(
11903
+ container.querySelectorAll("[data-toggle-item]:not(:disabled)")
11904
+ );
11905
+ const currentIndex = items.indexOf(event.currentTarget);
11906
+ if (currentIndex === -1 || items.length === 0) return;
11907
+ const focusAndSelect = (targetIndex) => {
11908
+ const wrapped = (targetIndex % items.length + items.length) % items.length;
11909
+ const target = items[wrapped];
11910
+ if (!target) return;
11911
+ target.focus();
11912
+ const targetValue = target.dataset.toggleValue;
11913
+ if (targetValue !== void 0) context.onValueChange(targetValue);
11914
+ };
11915
+ switch (event.key) {
11916
+ case "ArrowRight":
11917
+ case "ArrowDown":
11918
+ event.preventDefault();
11919
+ focusAndSelect(currentIndex + 1);
11920
+ break;
11921
+ case "ArrowLeft":
11922
+ case "ArrowUp":
11923
+ event.preventDefault();
11924
+ focusAndSelect(currentIndex - 1);
11925
+ break;
11926
+ case "Home":
11927
+ event.preventDefault();
11928
+ focusAndSelect(0);
11929
+ break;
11930
+ case "End":
11931
+ event.preventDefault();
11932
+ focusAndSelect(items.length - 1);
11933
+ break;
11934
+ }
11935
+ }
11936
+ const rovingTabIndex = context.type === "single" ? isSelected || context.value === "" ? 0 : -1 : void 0;
11937
+ return (
11938
+ // biome-ignore lint/a11y/useAriaPropsSupportedByRole: see comment above.
11939
+ /* @__PURE__ */ jsx(
11940
+ "button",
11941
+ {
11942
+ ref,
11943
+ type: "button",
11944
+ disabled: isDisabled,
11945
+ "data-state": isSelected ? "on" : "off",
11946
+ "data-toggle-item": "",
11947
+ "data-toggle-value": value,
11948
+ role: context.type === "single" ? "radio" : void 0,
11949
+ "aria-checked": context.type === "single" ? isSelected : void 0,
11950
+ "aria-pressed": context.type === "multiple" ? isSelected : void 0,
11951
+ tabIndex: rovingTabIndex,
11952
+ className: cn(
11953
+ toggleGroupItemVariants({
11954
+ variant: variant ?? context.variant,
11955
+ size: size ?? context.size
11956
+ }),
11957
+ className,
11958
+ "focus-visible:z-10"
11959
+ ),
11960
+ onClick: toggleItemSelection,
11961
+ ...props,
11962
+ onKeyDown: handleItemKeyDown,
11963
+ children
11964
+ }
11965
+ )
11600
11966
  );
11601
11967
  };
11602
11968
  ToggleGroupItem.displayName = "ToggleGroupItem";
@@ -11898,6 +12264,6 @@ var TreeIcon = ({ icon, hasChildren = false, className, ...props }) => {
11898
12264
  };
11899
12265
  var TreeLabel = ({ className, ...props }) => /* @__PURE__ */ jsx("span", { className: cn("font flex-1 truncate text-sm", className), ...props });
11900
12266
 
11901
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertContent, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertIcon, AlertTitle, AlertToolbar, AnimateIn, AnimateInGroup, AnimatedThemeToggler, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonLink, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxGroup, CodeBlock, Collapse, CollapseGroup, Combobox, ComboboxEmpty, ComboboxGroupSub, ComboboxInput, ComboboxList, ComboboxOptionItem, ComboboxRoot, ComboboxSeparator, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandResults, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuRoot, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CopyCodeButton, CopyIdButton, CopyLinkButton, CopyableField, Description, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EmptyStateIcon, EmptyStateRoot, ErrorSurface as Error, ErrorMessage, Field, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gauge, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, Label, LoadingDots, Menu, MenuButton, MenuContainer, MenuItem, MenuItemLocked, MenuLink, MenuSection, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Modal, MultiSelectContent, MultiSelectRoot, MultiSelectRow, MultiSelectTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Note, Pagination, Popover, PopoverAnchor, PopoverContent, PopoverPositioner, PopoverTrigger, Progress, ProjectBanner, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, Scroller, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, ShowMore, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonText, Slider, Spinner2 as Spinner, SplitButton, SplitButtonMenuItem, Stack, StatusDot, Switch, Table, TableBody, TableCaption, TableCell, TableCol, TableColgroup, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeSwitcher, ThemeToggle, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TreeExpander, TreeIcon, TreeLabel, TreeLines, TreeNode, TreeNodeContent, TreeNodeTrigger, TreeProvider, TreeView, alertVariants, badgeVariants, buttonVariants, containerWidths, flexLayouts, gridLayouts, labelVariants, navigationMenuTriggerStyle, progressIndicatorVariants, progressVariants, tabsContentVariants, tabsListVariants, tabsTriggerVariants, toggleGroupItemVariants, toggleGroupVariants, useCopyToClipboard, useFormField, useToasts, zIndex };
12267
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertContent, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertIcon, AlertTitle, AlertToolbar, AnimateIn, AnimateInGroup, AnimateSwap, AnimatedThemeToggler, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonLink, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxGroup, CodeBlock, Collapse, CollapseGroup, Combobox, ComboboxEmpty, ComboboxGroupSub, ComboboxInput, ComboboxList, ComboboxOptionItem, ComboboxRoot, ComboboxSeparator, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandResults, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuRoot, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CopyCodeButton, CopyIdButton, CopyLinkButton, CopyMenuItem, CopyableField, Description, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuEmpty, DropdownMenuFilterInput, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EmptyStateIcon, EmptyStateRoot, ErrorSurface as Error, ErrorMessage, Field, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gauge, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, Label, LoadingDots, Menu, MenuButton, MenuContainer, MenuItem, MenuItemLocked, MenuLink, MenuSection, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Modal, MultiSelectContent, MultiSelectRoot, MultiSelectRow, MultiSelectTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Note, Pagination, Popover, PopoverAnchor, PopoverContent, PopoverPositioner, PopoverTrigger, Progress, ProjectBanner, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, Scroller, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, ShowMore, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonText, Slider, Spinner2 as Spinner, SplitButton, SplitButtonMenuItem, Stack, StatusDot, Switch, Table, TableBody, TableCaption, TableCell, TableCol, TableColgroup, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeSwitcher, ThemeToggle, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TreeExpander, TreeIcon, TreeLabel, TreeLines, TreeNode, TreeNodeContent, TreeNodeTrigger, TreeProvider, TreeView, alertVariants, badgeVariants, buttonVariants, containerWidths, flexLayouts, gridLayouts, labelVariants, navigationMenuTriggerStyle, progressIndicatorVariants, progressVariants, tabsContentVariants, tabsListVariants, tabsTriggerVariants, toggleGroupItemVariants, toggleGroupVariants, useCopyToClipboard, useFormField, useToasts, zIndex };
11902
12268
  //# sourceMappingURL=canonical.js.map
11903
12269
  //# sourceMappingURL=canonical.js.map