@hex-core/components 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/_tsup-dts-rollup.d.ts +3556 -0
  2. package/dist/accordion.d.ts +4 -13
  3. package/dist/alert-dialog.d.ts +11 -34
  4. package/dist/alert.d.ts +4 -17
  5. package/dist/aspect-ratio.d.ts +1 -7
  6. package/dist/attachment.d.ts +4 -0
  7. package/dist/attachment.js +157 -0
  8. package/dist/attachment.js.map +1 -0
  9. package/dist/avatar.d.ts +3 -11
  10. package/dist/badge.d.ts +3 -22
  11. package/dist/breadcrumb.d.ts +7 -27
  12. package/dist/button.d.ts +3 -13
  13. package/dist/calendar.d.ts +1 -17
  14. package/dist/card.d.ts +6 -16
  15. package/dist/checkbox.d.ts +2 -11
  16. package/dist/citation.d.ts +2 -0
  17. package/dist/citation.js +70 -0
  18. package/dist/citation.js.map +1 -0
  19. package/dist/cluster.d.ts +3 -34
  20. package/dist/code-block-copy.d.ts +2 -0
  21. package/dist/code-block-copy.js +108 -0
  22. package/dist/code-block-copy.js.map +1 -0
  23. package/dist/code-block.d.ts +3 -0
  24. package/dist/code-block.js +90 -0
  25. package/dist/code-block.js.map +1 -0
  26. package/dist/collapsible.d.ts +3 -11
  27. package/dist/color-picker.d.ts +2 -44
  28. package/dist/combobox.d.ts +3 -45
  29. package/dist/command.d.ts +9 -111
  30. package/dist/composer.d.ts +2 -0
  31. package/dist/composer.js +75 -0
  32. package/dist/composer.js.map +1 -0
  33. package/dist/container.d.ts +3 -41
  34. package/dist/context-menu.d.ts +12 -37
  35. package/dist/data-table.d.ts +2 -33
  36. package/dist/date-picker.d.ts +2 -43
  37. package/dist/dialog.d.ts +11 -46
  38. package/dist/drawer.d.ts +10 -41
  39. package/dist/dropdown-menu.d.ts +13 -39
  40. package/dist/dropzone.d.ts +3 -54
  41. package/dist/dropzone.js +46 -44
  42. package/dist/dropzone.js.map +1 -1
  43. package/dist/empty.d.ts +3 -0
  44. package/dist/empty.js +94 -0
  45. package/dist/empty.js.map +1 -0
  46. package/dist/error-state.d.ts +3 -0
  47. package/dist/error-state.js +67 -0
  48. package/dist/error-state.js.map +1 -0
  49. package/dist/file-tree.d.ts +3 -53
  50. package/dist/form.d.ts +8 -45
  51. package/dist/grid.d.ts +3 -50
  52. package/dist/hover-card.d.ts +3 -11
  53. package/dist/index.d.ts +325 -179
  54. package/dist/index.js +1592 -122
  55. package/dist/index.js.map +1 -1
  56. package/dist/input-otp.d.ts +5 -19
  57. package/dist/input.d.ts +2 -6
  58. package/dist/label.d.ts +2 -11
  59. package/dist/loading-indicator.d.ts +3 -0
  60. package/dist/loading-indicator.js +64 -0
  61. package/dist/loading-indicator.js.map +1 -0
  62. package/dist/loading.d.ts +3 -0
  63. package/dist/loading.js +80 -0
  64. package/dist/loading.js.map +1 -0
  65. package/dist/markdown.d.ts +2 -0
  66. package/dist/markdown.js +28 -0
  67. package/dist/markdown.js.map +1 -0
  68. package/dist/menubar.d.ts +11 -35
  69. package/dist/message-actions.d.ts +2 -0
  70. package/dist/message-actions.js +28 -0
  71. package/dist/message-actions.js.map +1 -0
  72. package/dist/message-list.d.ts +2 -0
  73. package/dist/message-list.js +49 -0
  74. package/dist/message-list.js.map +1 -0
  75. package/dist/message.d.ts +3 -0
  76. package/dist/message.js +35 -0
  77. package/dist/message.js.map +1 -0
  78. package/dist/multi-combobox.d.ts +3 -51
  79. package/dist/navigation-menu.d.ts +9 -23
  80. package/dist/pagination.d.ts +7 -40
  81. package/dist/popover.d.ts +4 -13
  82. package/dist/progress.d.ts +1 -10
  83. package/dist/radio-group.d.ts +2 -9
  84. package/dist/reasoning.d.ts +2 -0
  85. package/dist/reasoning.js +90 -0
  86. package/dist/reasoning.js.map +1 -0
  87. package/dist/resizable.d.ts +3 -28
  88. package/dist/schemas.d.ts +79 -121
  89. package/dist/schemas.js +1649 -1
  90. package/dist/schemas.js.map +1 -1
  91. package/dist/scroll-area.d.ts +3 -18
  92. package/dist/select.d.ts +8 -21
  93. package/dist/separator.d.ts +2 -11
  94. package/dist/sheet.d.ts +10 -39
  95. package/dist/sidebar.d.ts +8 -75
  96. package/dist/skeleton.d.ts +1 -11
  97. package/dist/slider.d.ts +2 -20
  98. package/dist/sonner.d.ts +2 -14
  99. package/dist/spacer.d.ts +3 -38
  100. package/dist/stack.d.ts +3 -34
  101. package/dist/stepper.d.ts +4 -48
  102. package/dist/suggestion.d.ts +2 -0
  103. package/dist/suggestion.js +55 -0
  104. package/dist/suggestion.js.map +1 -0
  105. package/dist/switch.d.ts +2 -11
  106. package/dist/table.d.ts +8 -24
  107. package/dist/tabs.d.ts +4 -13
  108. package/dist/tag.d.ts +3 -0
  109. package/dist/tag.js +107 -0
  110. package/dist/tag.js.map +1 -0
  111. package/dist/textarea.d.ts +2 -10
  112. package/dist/time-picker.d.ts +2 -34
  113. package/dist/timeline.d.ts +4 -42
  114. package/dist/toggle-group.d.ts +2 -17
  115. package/dist/toggle.d.ts +2 -19
  116. package/dist/tool-call.d.ts +2 -0
  117. package/dist/tool-call.js +133 -0
  118. package/dist/tool-call.js.map +1 -0
  119. package/dist/toolbar.d.ts +8 -0
  120. package/dist/toolbar.js +120 -0
  121. package/dist/toolbar.js.map +1 -0
  122. package/dist/tooltip.d.ts +4 -13
  123. package/dist/tree.d.ts +3 -0
  124. package/dist/tree.js +275 -0
  125. package/dist/tree.js.map +1 -0
  126. package/package.json +5 -1
  127. package/dist/button-variants-Bx6gCUFp.d.ts +0 -19
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { Slot } from '@radix-ui/react-slot';
3
3
  import * as React44 from 'react';
4
+ import { cache } from 'react';
4
5
  import { clsx } from 'clsx';
5
6
  import { twMerge } from 'tailwind-merge';
6
7
  import { cva } from 'class-variance-authority';
@@ -38,8 +39,12 @@ import { DayPicker } from 'react-day-picker';
38
39
  import { format } from 'date-fns';
39
40
  import { OTPInput, OTPInputContext } from 'input-otp';
40
41
  import { Command as Command$1 } from 'cmdk';
42
+ import * as ToolbarPrimitive from '@radix-ui/react-toolbar';
41
43
  import { Drawer as Drawer$1 } from 'vaul';
42
44
  import { Panel, Group, Separator as Separator$1 } from 'react-resizable-panels';
45
+ import { Streamdown } from 'streamdown';
46
+ import { codeToHtml } from 'shiki';
47
+ import { CodeBlockCopy } from './code-block-copy.js';
43
48
 
44
49
  // src/primitives/button/button.tsx
45
50
  function cn(...inputs) {
@@ -621,6 +626,288 @@ function Skeleton({ className, ...props }) {
621
626
  }
622
627
  );
623
628
  }
629
+ var emptyVariants = cva(
630
+ [
631
+ "flex flex-col items-center justify-center text-center",
632
+ "rounded-md border border-dashed border-border bg-muted/30"
633
+ ].join(" "),
634
+ {
635
+ variants: {
636
+ size: {
637
+ sm: "gap-[var(--space-2,0.5rem)] px-[var(--space-4,1rem)] py-[var(--space-6,1.5rem)] text-sm",
638
+ default: "gap-[var(--space-3,0.75rem)] px-[var(--space-6,1.5rem)] py-[var(--space-8,2rem)]",
639
+ lg: "gap-[var(--space-4,1rem)] px-[var(--space-8,2rem)] py-[var(--space-12,3rem)]"
640
+ }
641
+ },
642
+ defaultVariants: { size: "default" }
643
+ }
644
+ );
645
+ var emptyIconWrapperVariants = cva(
646
+ "flex shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground [&_svg]:size-5",
647
+ {
648
+ variants: {
649
+ size: {
650
+ sm: "h-9 w-9",
651
+ default: "h-12 w-12 [&_svg]:size-6",
652
+ lg: "h-16 w-16 [&_svg]:size-7"
653
+ }
654
+ },
655
+ defaultVariants: { size: "default" }
656
+ }
657
+ );
658
+ var emptyTitleVariants = cva("font-semibold text-foreground", {
659
+ variants: {
660
+ size: {
661
+ sm: "text-sm",
662
+ default: "text-base",
663
+ lg: "text-lg"
664
+ }
665
+ },
666
+ defaultVariants: { size: "default" }
667
+ });
668
+ var emptyDescriptionVariants = cva("max-w-md text-muted-foreground", {
669
+ variants: {
670
+ size: {
671
+ sm: "text-xs",
672
+ default: "text-sm",
673
+ lg: "text-base"
674
+ }
675
+ },
676
+ defaultVariants: { size: "default" }
677
+ });
678
+ function Empty({
679
+ className,
680
+ size,
681
+ icon,
682
+ title,
683
+ description,
684
+ action,
685
+ titleAs = "h3",
686
+ ref,
687
+ ...props
688
+ }) {
689
+ const titleId = React44.useId();
690
+ const TitleComp = titleAs;
691
+ return /* @__PURE__ */ jsxs(
692
+ "div",
693
+ {
694
+ ref,
695
+ role: "region",
696
+ "aria-labelledby": titleId,
697
+ className: cn(emptyVariants({ size }), className),
698
+ ...props,
699
+ children: [
700
+ icon ? /* @__PURE__ */ jsx("div", { className: emptyIconWrapperVariants({ size }), "aria-hidden": "true", children: icon }) : null,
701
+ /* @__PURE__ */ jsx(TitleComp, { id: titleId, className: emptyTitleVariants({ size }), children: title }),
702
+ description ? /* @__PURE__ */ jsx("div", { className: emptyDescriptionVariants({ size }), children: description }) : null,
703
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-[var(--space-2,0.5rem)]", children: action }) : null
704
+ ]
705
+ }
706
+ );
707
+ }
708
+ var loadingVariants = cva("flex w-full", {
709
+ variants: {
710
+ variant: {
711
+ list: "flex-col gap-[var(--space-3,0.75rem)]",
712
+ card: "flex-col gap-[var(--space-2,0.5rem)] rounded-md border border-border bg-card p-[var(--space-4,1rem)]",
713
+ stack: "flex-col gap-[var(--space-4,1rem)]"
714
+ }
715
+ },
716
+ defaultVariants: { variant: "list" }
717
+ });
718
+ function Loading({
719
+ className,
720
+ variant = "list",
721
+ rows = 3,
722
+ label = "Loading\u2026",
723
+ ref,
724
+ ...props
725
+ }) {
726
+ return /* @__PURE__ */ jsxs(
727
+ "div",
728
+ {
729
+ ref,
730
+ role: "status",
731
+ "aria-live": "polite",
732
+ className: cn(loadingVariants({ variant }), className),
733
+ ...props,
734
+ children: [
735
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label }),
736
+ Array.from({ length: rows }, (_, i) => (
737
+ // `variant` can be `null` per CVA's VariantProps shape — the
738
+ // destructured default only catches undefined. The fallback
739
+ // here narrows to the LoadingRow's "list" | "card" | "stack"
740
+ // signature.
741
+ /* @__PURE__ */ jsx(LoadingRow, { variant: variant ?? "list" }, i)
742
+ ))
743
+ ]
744
+ }
745
+ );
746
+ }
747
+ function LoadingRow({ variant }) {
748
+ if (variant === "card") {
749
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
750
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
751
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
752
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-5/6" })
753
+ ] });
754
+ }
755
+ if (variant === "stack") {
756
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[var(--space-3,0.75rem)]", children: [
757
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-10 shrink-0 rounded-full" }),
758
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-[var(--space-2,0.5rem)]", children: [
759
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/3" }),
760
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-2/3" })
761
+ ] })
762
+ ] });
763
+ }
764
+ return /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" });
765
+ }
766
+ var errorStateVariants = cva(
767
+ [
768
+ "flex flex-col items-center justify-center text-center",
769
+ "rounded-md border px-[var(--space-6,1.5rem)] py-[var(--space-8,2rem)] gap-[var(--space-3,0.75rem)]"
770
+ ].join(" "),
771
+ {
772
+ variants: {
773
+ variant: {
774
+ default: "border-border bg-muted/30",
775
+ destructive: "border-destructive/30 bg-destructive/5"
776
+ }
777
+ },
778
+ defaultVariants: { variant: "default" }
779
+ }
780
+ );
781
+ var errorIconWrapperVariants = cva(
782
+ "flex h-12 w-12 shrink-0 items-center justify-center rounded-full [&_svg]:size-6",
783
+ {
784
+ variants: {
785
+ variant: {
786
+ default: "bg-muted text-muted-foreground",
787
+ destructive: "bg-destructive/10 text-destructive"
788
+ }
789
+ },
790
+ defaultVariants: { variant: "default" }
791
+ }
792
+ );
793
+ function ErrorState({
794
+ className,
795
+ variant,
796
+ icon,
797
+ title = "Something went wrong",
798
+ message,
799
+ action,
800
+ ref,
801
+ ...props
802
+ }) {
803
+ return /* @__PURE__ */ jsxs(
804
+ "div",
805
+ {
806
+ ref,
807
+ role: "alert",
808
+ className: cn(errorStateVariants({ variant }), className),
809
+ ...props,
810
+ children: [
811
+ icon ? /* @__PURE__ */ jsx("div", { className: errorIconWrapperVariants({ variant }), "aria-hidden": "true", children: icon }) : null,
812
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-foreground", children: title }),
813
+ /* @__PURE__ */ jsx("div", { className: "max-w-md text-sm text-muted-foreground", children: message }),
814
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-[var(--space-2,0.5rem)]", children: action }) : null
815
+ ]
816
+ }
817
+ );
818
+ }
819
+ var tagVariants = cva(
820
+ [
821
+ "inline-flex items-center gap-[var(--gap-xs,0.25rem)] rounded-full border px-2.5 py-0.5 text-xs font-medium",
822
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
823
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
824
+ ].join(" "),
825
+ {
826
+ variants: {
827
+ variant: {
828
+ default: "border-transparent bg-primary text-primary-foreground",
829
+ secondary: "border-foreground/15 bg-secondary text-secondary-foreground hover:border-foreground/20",
830
+ destructive: "border-transparent bg-destructive text-destructive-foreground",
831
+ outline: "border-foreground/20 text-foreground hover:border-foreground/30"
832
+ }
833
+ },
834
+ defaultVariants: { variant: "default" }
835
+ }
836
+ );
837
+ function extractStringLabel(children) {
838
+ const parts = [];
839
+ const visit = (node) => {
840
+ if (node === null || node === void 0 || typeof node === "boolean") return;
841
+ if (typeof node === "string") {
842
+ parts.push(node);
843
+ return;
844
+ }
845
+ if (typeof node === "number") {
846
+ parts.push(String(node));
847
+ return;
848
+ }
849
+ if (Array.isArray(node)) {
850
+ for (const item of node) visit(item);
851
+ return;
852
+ }
853
+ if (React44.isValidElement(node)) {
854
+ const props = node.props;
855
+ visit(props.children);
856
+ }
857
+ };
858
+ visit(children);
859
+ const joined = parts.join(" ").replace(/\s+/g, " ").trim();
860
+ return joined.length > 0 ? joined : null;
861
+ }
862
+ function Tag({
863
+ className,
864
+ variant,
865
+ icon,
866
+ onRemove,
867
+ removeLabel,
868
+ children,
869
+ ref,
870
+ ...props
871
+ }) {
872
+ const labelText = extractStringLabel(children);
873
+ const ariaLabel = removeLabel ?? (labelText ? `Remove ${labelText}` : "Remove");
874
+ return /* @__PURE__ */ jsxs("span", { ref, className: cn(tagVariants({ variant }), className), ...props, children: [
875
+ icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "-ml-0.5 [&_svg]:size-3 [&_svg]:shrink-0", children: icon }) : null,
876
+ /* @__PURE__ */ jsx("span", { children }),
877
+ onRemove ? /* @__PURE__ */ jsx(
878
+ "button",
879
+ {
880
+ type: "button",
881
+ onClick: onRemove,
882
+ "aria-label": ariaLabel,
883
+ className: cn(
884
+ "-mr-0.5 inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full",
885
+ "transition-colors duration-[var(--duration-normal,200ms)] ease-out",
886
+ "hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
887
+ "active:scale-[0.92]"
888
+ ),
889
+ children: /* @__PURE__ */ jsxs(
890
+ "svg",
891
+ {
892
+ xmlns: "http://www.w3.org/2000/svg",
893
+ viewBox: "0 0 24 24",
894
+ fill: "none",
895
+ stroke: "currentColor",
896
+ strokeWidth: "2.5",
897
+ strokeLinecap: "round",
898
+ strokeLinejoin: "round",
899
+ className: "size-3",
900
+ "aria-hidden": "true",
901
+ children: [
902
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
903
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
904
+ ]
905
+ }
906
+ )
907
+ }
908
+ ) : null
909
+ ] });
910
+ }
624
911
  var Progress = React44.forwardRef(({ className, value, max = 100, ...props }, ref) => {
625
912
  const pct = Math.max(0, Math.min(100, (value ?? 0) / max * 100));
626
913
  return /* @__PURE__ */ jsx(
@@ -3354,31 +3641,31 @@ function Dropzone({
3354
3641
  isDisabled: disabled,
3355
3642
  openFileDialog
3356
3643
  };
3357
- return /* @__PURE__ */ jsxs(
3358
- "div",
3359
- {
3360
- role: "button",
3361
- tabIndex: disabled ? -1 : 0,
3362
- "aria-label": ariaLabel,
3363
- "aria-disabled": disabled || void 0,
3364
- "data-drag-over": isDragOver || void 0,
3365
- onClick: openFileDialog,
3366
- onKeyDown: handleKeyDown,
3367
- onDragEnter: handleDragEnter,
3368
- onDragOver: handleDragOver,
3369
- onDragLeave: handleDragLeave,
3370
- onDrop: handleDrop,
3371
- className: cn(
3372
- "flex w-full cursor-pointer select-none flex-col items-center justify-center gap-[var(--space-2,0.5rem)] rounded-md border-2 border-dashed border-input bg-background px-[var(--space-6,1.5rem)] py-[var(--space-8,2rem)] text-center text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out",
3373
- "hover:bg-accent hover:text-accent-foreground",
3374
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3375
- isDragOver && "border-primary bg-accent text-accent-foreground",
3376
- disabled && "pointer-events-none opacity-50",
3377
- className
3378
- ),
3379
- ...rest,
3380
- children: [
3381
- typeof children === "function" ? children(renderState) : children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
3644
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3645
+ /* @__PURE__ */ jsx(
3646
+ "div",
3647
+ {
3648
+ role: "button",
3649
+ tabIndex: disabled ? -1 : 0,
3650
+ "aria-label": ariaLabel,
3651
+ "aria-disabled": disabled || void 0,
3652
+ "data-drag-over": isDragOver || void 0,
3653
+ onClick: openFileDialog,
3654
+ onKeyDown: handleKeyDown,
3655
+ onDragEnter: handleDragEnter,
3656
+ onDragOver: handleDragOver,
3657
+ onDragLeave: handleDragLeave,
3658
+ onDrop: handleDrop,
3659
+ className: cn(
3660
+ "flex w-full cursor-pointer select-none flex-col items-center justify-center gap-[var(--space-2,0.5rem)] rounded-md border-2 border-dashed border-input bg-background px-[var(--space-6,1.5rem)] py-[var(--space-8,2rem)] text-center text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out",
3661
+ "hover:bg-accent hover:text-accent-foreground",
3662
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3663
+ isDragOver && "border-primary bg-accent text-accent-foreground",
3664
+ disabled && "pointer-events-none opacity-50",
3665
+ className
3666
+ ),
3667
+ ...rest,
3668
+ children: typeof children === "function" ? children(renderState) : children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
3382
3669
  /* @__PURE__ */ jsxs(
3383
3670
  "svg",
3384
3671
  {
@@ -3400,25 +3687,27 @@ function Dropzone({
3400
3687
  ),
3401
3688
  /* @__PURE__ */ jsx("span", { className: "font-medium", children: isDragOver ? "Drop files to upload" : "Drag files here or click to browse" }),
3402
3689
  accept ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: accept }) : null
3403
- ] }),
3404
- /* @__PURE__ */ jsx(
3405
- "input",
3406
- {
3407
- ref: inputRef,
3408
- type: "file",
3409
- accept,
3410
- multiple,
3411
- disabled,
3412
- className: "sr-only",
3413
- onChange: (e) => {
3414
- emit(e.target.files);
3415
- e.target.value = "";
3416
- }
3417
- }
3418
- )
3419
- ]
3420
- }
3421
- );
3690
+ ] })
3691
+ }
3692
+ ),
3693
+ /* @__PURE__ */ jsx(
3694
+ "input",
3695
+ {
3696
+ ref: inputRef,
3697
+ type: "file",
3698
+ accept,
3699
+ multiple,
3700
+ disabled,
3701
+ "aria-hidden": "true",
3702
+ tabIndex: -1,
3703
+ className: "sr-only",
3704
+ onChange: (e) => {
3705
+ emit(e.target.files);
3706
+ e.target.value = "";
3707
+ }
3708
+ }
3709
+ )
3710
+ ] });
3422
3711
  }
3423
3712
  Dropzone.displayName = "Dropzone";
3424
3713
  var TimePicker = React44.forwardRef(
@@ -3767,86 +4056,454 @@ function FileTree({
3767
4056
  );
3768
4057
  }
3769
4058
  FileTree.displayName = "FileTree";
3770
- var Sheet = DialogPrimitive.Root;
3771
- var SheetTrigger = DialogPrimitive.Trigger;
3772
- var SheetClose = DialogPrimitive.Close;
3773
- var SheetPortal = DialogPrimitive.Portal;
3774
- var SheetOverlay = React44.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3775
- DialogPrimitive.Overlay,
3776
- {
3777
- ref,
3778
- className: cn(
3779
- "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm",
3780
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
3781
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
3782
- className
3783
- ),
3784
- ...props
3785
- }
3786
- ));
3787
- SheetOverlay.displayName = "SheetOverlay";
3788
- var sheetVariants = cva(
3789
- cn(
3790
- "fixed z-50 gap-[var(--gap-md,1rem)] bg-background p-[var(--space-6,1.5rem)] shadow-lg",
3791
- "border-foreground/[0.08]",
3792
- "transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out",
3793
- "data-[state=closed]:duration-[var(--duration-slow,300ms)] data-[state=open]:duration-500"
3794
- ),
3795
- {
3796
- variants: {
3797
- side: {
3798
- top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
3799
- bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
3800
- left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
3801
- right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
4059
+ function flattenVisible(nodes, expanded) {
4060
+ const out = [];
4061
+ function walk(items, depth, parentId) {
4062
+ for (const node of items) {
4063
+ out.push({ node, depth, parentId });
4064
+ if (node.children && expanded.has(node.id)) {
4065
+ walk(node.children, depth + 1, node.id);
3802
4066
  }
3803
- },
3804
- defaultVariants: {
3805
- side: "right"
3806
4067
  }
3807
4068
  }
3808
- );
3809
- var SheetContent = React44.forwardRef(({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SheetPortal, { children: [
3810
- /* @__PURE__ */ jsx(SheetOverlay, {}),
3811
- /* @__PURE__ */ jsxs(
3812
- DialogPrimitive.Content,
3813
- {
3814
- ref,
3815
- className: cn(sheetVariants({ side }), className),
3816
- ...props,
3817
- children: [
3818
- children,
3819
- /* @__PURE__ */ jsxs(
3820
- DialogPrimitive.Close,
3821
- {
3822
- className: cn(
3823
- "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",
3824
- "transition-all duration-[var(--duration-normal,200ms)] ease-out hover:opacity-100",
3825
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3826
- "disabled:pointer-events-none"
3827
- ),
3828
- children: [
3829
- /* @__PURE__ */ jsxs(
3830
- "svg",
3831
- {
3832
- xmlns: "http://www.w3.org/2000/svg",
3833
- viewBox: "0 0 24 24",
3834
- fill: "none",
3835
- stroke: "currentColor",
3836
- strokeWidth: "2",
3837
- strokeLinecap: "round",
3838
- strokeLinejoin: "round",
3839
- className: "h-4 w-4",
3840
- "aria-hidden": "true",
3841
- children: [
3842
- /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
3843
- /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
3844
- ]
3845
- }
3846
- ),
3847
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
3848
- ]
3849
- }
4069
+ walk(nodes, 0, null);
4070
+ return out;
4071
+ }
4072
+ function Tree({
4073
+ data,
4074
+ defaultExpanded,
4075
+ expanded: expandedProp,
4076
+ onExpandedChange,
4077
+ selected: selectedProp,
4078
+ onSelect,
4079
+ "aria-label": ariaLabel,
4080
+ className,
4081
+ ref
4082
+ }) {
4083
+ const [internalExpanded, setInternalExpanded] = React44.useState(
4084
+ () => new Set(defaultExpanded ?? [])
4085
+ );
4086
+ const expanded = React44.useMemo(
4087
+ () => expandedProp ? new Set(expandedProp) : internalExpanded,
4088
+ [expandedProp, internalExpanded]
4089
+ );
4090
+ const [internalSelected, setInternalSelected] = React44.useState(null);
4091
+ const selected = selectedProp ?? internalSelected;
4092
+ const visible = React44.useMemo(() => flattenVisible(data, expanded), [data, expanded]);
4093
+ const [focusedId, setFocusedId] = React44.useState(
4094
+ () => visible[0]?.node.id ?? null
4095
+ );
4096
+ React44.useEffect(() => {
4097
+ if (focusedId && !visible.some((row) => row.node.id === focusedId)) {
4098
+ setFocusedId(visible[0]?.node.id ?? null);
4099
+ }
4100
+ }, [visible, focusedId]);
4101
+ const setExpandedSet = React44.useCallback(
4102
+ (next) => {
4103
+ if (expandedProp) {
4104
+ onExpandedChange?.([...next]);
4105
+ } else {
4106
+ setInternalExpanded(next);
4107
+ onExpandedChange?.([...next]);
4108
+ }
4109
+ },
4110
+ [expandedProp, onExpandedChange]
4111
+ );
4112
+ const toggleExpand = React44.useCallback(
4113
+ (id) => {
4114
+ const next = new Set(expanded);
4115
+ if (next.has(id)) next.delete(id);
4116
+ else next.add(id);
4117
+ setExpandedSet(next);
4118
+ },
4119
+ [expanded, setExpandedSet]
4120
+ );
4121
+ const activate = React44.useCallback(
4122
+ (id) => {
4123
+ if (selectedProp === void 0) setInternalSelected(id);
4124
+ onSelect?.(id);
4125
+ },
4126
+ [selectedProp, onSelect]
4127
+ );
4128
+ const handleKeyDown = React44.useCallback(
4129
+ (e) => {
4130
+ if (!focusedId) return;
4131
+ const idx = visible.findIndex((row2) => row2.node.id === focusedId);
4132
+ if (idx < 0) return;
4133
+ const row = visible[idx];
4134
+ if (!row) return;
4135
+ const node = row.node;
4136
+ const isParent = !!node.children;
4137
+ const isExpanded = expanded.has(node.id);
4138
+ switch (e.key) {
4139
+ case "ArrowDown": {
4140
+ e.preventDefault();
4141
+ const next = visible[idx + 1];
4142
+ if (next) setFocusedId(next.node.id);
4143
+ break;
4144
+ }
4145
+ case "ArrowUp": {
4146
+ e.preventDefault();
4147
+ const prev = visible[idx - 1];
4148
+ if (prev) setFocusedId(prev.node.id);
4149
+ break;
4150
+ }
4151
+ case "ArrowRight": {
4152
+ e.preventDefault();
4153
+ if (isParent && !isExpanded) toggleExpand(node.id);
4154
+ else if (isParent && isExpanded) {
4155
+ const next = visible[idx + 1];
4156
+ if (next) setFocusedId(next.node.id);
4157
+ }
4158
+ break;
4159
+ }
4160
+ case "ArrowLeft": {
4161
+ e.preventDefault();
4162
+ if (isParent && isExpanded) toggleExpand(node.id);
4163
+ else if (row.parentId) {
4164
+ setFocusedId(row.parentId);
4165
+ }
4166
+ break;
4167
+ }
4168
+ case "Home": {
4169
+ e.preventDefault();
4170
+ if (visible[0]) setFocusedId(visible[0].node.id);
4171
+ break;
4172
+ }
4173
+ case "End": {
4174
+ e.preventDefault();
4175
+ const last = visible[visible.length - 1];
4176
+ if (last) setFocusedId(last.node.id);
4177
+ break;
4178
+ }
4179
+ case "Enter":
4180
+ case " ": {
4181
+ e.preventDefault();
4182
+ if (node.disabled) return;
4183
+ if (isParent) toggleExpand(node.id);
4184
+ activate(node.id);
4185
+ break;
4186
+ }
4187
+ default:
4188
+ return;
4189
+ }
4190
+ },
4191
+ [focusedId, visible, expanded, toggleExpand, activate]
4192
+ );
4193
+ const isSelectable = onSelect !== void 0 || selectedProp !== void 0;
4194
+ return /* @__PURE__ */ jsx(
4195
+ "ul",
4196
+ {
4197
+ ref,
4198
+ role: "tree",
4199
+ "aria-label": ariaLabel,
4200
+ className: cn("flex flex-col text-sm text-foreground", className),
4201
+ onKeyDown: handleKeyDown,
4202
+ children: data.map((node) => /* @__PURE__ */ jsx(
4203
+ TreeItem2,
4204
+ {
4205
+ node,
4206
+ depth: 0,
4207
+ expanded,
4208
+ selected,
4209
+ isSelectable,
4210
+ focusedId,
4211
+ onFocus: setFocusedId,
4212
+ onToggleExpand: toggleExpand,
4213
+ onActivate: activate
4214
+ },
4215
+ node.id
4216
+ ))
4217
+ }
4218
+ );
4219
+ }
4220
+ function TreeItem2({
4221
+ node,
4222
+ depth,
4223
+ expanded,
4224
+ selected,
4225
+ isSelectable,
4226
+ focusedId,
4227
+ onFocus,
4228
+ onToggleExpand,
4229
+ onActivate
4230
+ }) {
4231
+ const children = node.children;
4232
+ const isParent = children !== void 0;
4233
+ const isExpanded = expanded.has(node.id);
4234
+ const isSelected = selected === node.id;
4235
+ const isFocused = focusedId === node.id;
4236
+ const handleClick = () => {
4237
+ if (node.disabled) return;
4238
+ onFocus(node.id);
4239
+ if (isParent) onToggleExpand(node.id);
4240
+ onActivate(node.id);
4241
+ };
4242
+ const labelId = React44.useId();
4243
+ return /* @__PURE__ */ jsxs(
4244
+ "li",
4245
+ {
4246
+ role: "treeitem",
4247
+ "aria-labelledby": labelId,
4248
+ "aria-level": depth + 1,
4249
+ "aria-expanded": isParent ? isExpanded : void 0,
4250
+ "aria-selected": isSelectable ? isSelected : void 0,
4251
+ "aria-disabled": node.disabled || void 0,
4252
+ tabIndex: isFocused ? 0 : -1,
4253
+ onClick: (e) => {
4254
+ e.stopPropagation();
4255
+ handleClick();
4256
+ },
4257
+ onFocus: (e) => {
4258
+ e.stopPropagation();
4259
+ if (!node.disabled) onFocus(node.id);
4260
+ },
4261
+ className: cn(
4262
+ "outline-none rounded-sm",
4263
+ // H1: focus-visible-driven ring (NOT state-driven) — the ring
4264
+ // only shows on keyboard focus, not on mouse clicks.
4265
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
4266
+ ),
4267
+ children: [
4268
+ /* @__PURE__ */ jsxs(
4269
+ "div",
4270
+ {
4271
+ className: cn(
4272
+ "flex cursor-pointer select-none items-center gap-[var(--gap-xs,0.25rem)] rounded-sm px-[var(--space-2,0.5rem)] py-[var(--space-1,0.25rem)]",
4273
+ "transition-colors duration-[var(--duration-normal,200ms)] ease-out",
4274
+ "hover:bg-accent hover:text-accent-foreground",
4275
+ isSelected && "bg-accent text-accent-foreground font-medium",
4276
+ node.disabled && "cursor-not-allowed opacity-50"
4277
+ ),
4278
+ style: { paddingLeft: `calc(${depth} * var(--space-4, 1rem) + var(--space-2, 0.5rem))` },
4279
+ children: [
4280
+ isParent ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex h-4 w-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(
4281
+ "svg",
4282
+ {
4283
+ xmlns: "http://www.w3.org/2000/svg",
4284
+ viewBox: "0 0 24 24",
4285
+ fill: "none",
4286
+ stroke: "currentColor",
4287
+ strokeWidth: "2",
4288
+ strokeLinecap: "round",
4289
+ strokeLinejoin: "round",
4290
+ className: cn(
4291
+ "h-3 w-3 transition-transform duration-[var(--duration-normal,200ms)] ease-out",
4292
+ isExpanded ? "rotate-90" : "rotate-0"
4293
+ ),
4294
+ children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
4295
+ }
4296
+ ) }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-block h-4 w-4 shrink-0" }),
4297
+ node.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex h-4 w-4 shrink-0 items-center justify-center [&_svg]:size-4", children: node.icon }) : null,
4298
+ /* @__PURE__ */ jsx("span", { id: labelId, className: "truncate", children: node.label })
4299
+ ]
4300
+ }
4301
+ ),
4302
+ isParent && isExpanded && children ? /* @__PURE__ */ jsx("ul", { role: "group", "aria-labelledby": labelId, className: "flex flex-col", children: children.map((child) => /* @__PURE__ */ jsx(
4303
+ TreeItem2,
4304
+ {
4305
+ node: child,
4306
+ depth: depth + 1,
4307
+ expanded,
4308
+ selected,
4309
+ isSelectable,
4310
+ focusedId,
4311
+ onFocus,
4312
+ onToggleExpand,
4313
+ onActivate
4314
+ },
4315
+ child.id
4316
+ )) }) : null
4317
+ ]
4318
+ }
4319
+ );
4320
+ }
4321
+ var toolbarVariants = cva("flex items-center gap-[var(--gap-xs,0.25rem)] rounded-md border border-border bg-card p-[var(--space-1,0.25rem)]", {
4322
+ variants: {
4323
+ orientation: {
4324
+ horizontal: "flex-row",
4325
+ vertical: "flex-col items-stretch"
4326
+ }
4327
+ },
4328
+ defaultVariants: { orientation: "horizontal" }
4329
+ });
4330
+ var toolbarItemBaseClasses = [
4331
+ "inline-flex items-center justify-center gap-[var(--gap-xs,0.25rem)] rounded-sm",
4332
+ "px-[var(--space-2,0.5rem)] h-[var(--control-height-sm,2.25rem)] text-sm font-medium",
4333
+ "text-foreground/80 hover:text-foreground hover:bg-accent",
4334
+ "transition-colors duration-[var(--duration-normal,200ms)] ease-out",
4335
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
4336
+ "disabled:pointer-events-none disabled:opacity-50",
4337
+ "data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
4338
+ "active:scale-[0.98]",
4339
+ "[&_svg]:size-4 [&_svg]:shrink-0"
4340
+ ].join(" ");
4341
+ function Toolbar({ className, orientation = "horizontal", ref, ...props }) {
4342
+ return /* @__PURE__ */ jsx(
4343
+ ToolbarPrimitive.Root,
4344
+ {
4345
+ ref,
4346
+ orientation,
4347
+ className: cn(toolbarVariants({ orientation }), className),
4348
+ ...props
4349
+ }
4350
+ );
4351
+ }
4352
+ function ToolbarButton({
4353
+ className,
4354
+ ref,
4355
+ ...props
4356
+ }) {
4357
+ return /* @__PURE__ */ jsx(
4358
+ ToolbarPrimitive.Button,
4359
+ {
4360
+ ref,
4361
+ className: cn(toolbarItemBaseClasses, className),
4362
+ ...props
4363
+ }
4364
+ );
4365
+ }
4366
+ function ToolbarLink({
4367
+ className,
4368
+ ref,
4369
+ ...props
4370
+ }) {
4371
+ return /* @__PURE__ */ jsx(
4372
+ ToolbarPrimitive.Link,
4373
+ {
4374
+ ref,
4375
+ className: cn(toolbarItemBaseClasses, "underline-offset-4 hover:underline", className),
4376
+ ...props
4377
+ }
4378
+ );
4379
+ }
4380
+ function ToolbarToggleGroup({
4381
+ className,
4382
+ ref,
4383
+ ...props
4384
+ }) {
4385
+ return /* @__PURE__ */ jsx(
4386
+ ToolbarPrimitive.ToggleGroup,
4387
+ {
4388
+ ref,
4389
+ className: cn("flex items-center gap-[var(--gap-xs,0.25rem)]", className),
4390
+ ...props
4391
+ }
4392
+ );
4393
+ }
4394
+ function ToolbarToggleItem({
4395
+ className,
4396
+ ref,
4397
+ ...props
4398
+ }) {
4399
+ return /* @__PURE__ */ jsx(
4400
+ ToolbarPrimitive.ToggleItem,
4401
+ {
4402
+ ref,
4403
+ className: cn(toolbarItemBaseClasses, className),
4404
+ ...props
4405
+ }
4406
+ );
4407
+ }
4408
+ function ToolbarSeparator({
4409
+ className,
4410
+ ref,
4411
+ ...props
4412
+ }) {
4413
+ return /* @__PURE__ */ jsx(
4414
+ ToolbarPrimitive.Separator,
4415
+ {
4416
+ ref,
4417
+ className: cn(
4418
+ "shrink-0 bg-border",
4419
+ "data-[orientation=horizontal]:h-4 data-[orientation=horizontal]:w-px data-[orientation=horizontal]:mx-[var(--space-1,0.25rem)]",
4420
+ "data-[orientation=vertical]:w-4 data-[orientation=vertical]:h-px data-[orientation=vertical]:my-[var(--space-1,0.25rem)]",
4421
+ className
4422
+ ),
4423
+ ...props
4424
+ }
4425
+ );
4426
+ }
4427
+ var Sheet = DialogPrimitive.Root;
4428
+ var SheetTrigger = DialogPrimitive.Trigger;
4429
+ var SheetClose = DialogPrimitive.Close;
4430
+ var SheetPortal = DialogPrimitive.Portal;
4431
+ var SheetOverlay = React44.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4432
+ DialogPrimitive.Overlay,
4433
+ {
4434
+ ref,
4435
+ className: cn(
4436
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm",
4437
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
4438
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4439
+ className
4440
+ ),
4441
+ ...props
4442
+ }
4443
+ ));
4444
+ SheetOverlay.displayName = "SheetOverlay";
4445
+ var sheetVariants = cva(
4446
+ cn(
4447
+ "fixed z-50 gap-[var(--gap-md,1rem)] bg-background p-[var(--space-6,1.5rem)] shadow-lg",
4448
+ "border-foreground/[0.08]",
4449
+ "transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out",
4450
+ "data-[state=closed]:duration-[var(--duration-slow,300ms)] data-[state=open]:duration-500"
4451
+ ),
4452
+ {
4453
+ variants: {
4454
+ side: {
4455
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
4456
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
4457
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
4458
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
4459
+ }
4460
+ },
4461
+ defaultVariants: {
4462
+ side: "right"
4463
+ }
4464
+ }
4465
+ );
4466
+ var SheetContent = React44.forwardRef(({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SheetPortal, { children: [
4467
+ /* @__PURE__ */ jsx(SheetOverlay, {}),
4468
+ /* @__PURE__ */ jsxs(
4469
+ DialogPrimitive.Content,
4470
+ {
4471
+ ref,
4472
+ className: cn(sheetVariants({ side }), className),
4473
+ ...props,
4474
+ children: [
4475
+ children,
4476
+ /* @__PURE__ */ jsxs(
4477
+ DialogPrimitive.Close,
4478
+ {
4479
+ className: cn(
4480
+ "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",
4481
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out hover:opacity-100",
4482
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4483
+ "disabled:pointer-events-none"
4484
+ ),
4485
+ children: [
4486
+ /* @__PURE__ */ jsxs(
4487
+ "svg",
4488
+ {
4489
+ xmlns: "http://www.w3.org/2000/svg",
4490
+ viewBox: "0 0 24 24",
4491
+ fill: "none",
4492
+ stroke: "currentColor",
4493
+ strokeWidth: "2",
4494
+ strokeLinecap: "round",
4495
+ strokeLinejoin: "round",
4496
+ className: "h-4 w-4",
4497
+ "aria-hidden": "true",
4498
+ children: [
4499
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
4500
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
4501
+ ]
4502
+ }
4503
+ ),
4504
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
4505
+ ]
4506
+ }
3850
4507
  )
3851
4508
  ]
3852
4509
  }
@@ -4199,7 +4856,820 @@ var SidebarItem = React44.forwardRef(
4199
4856
  }
4200
4857
  );
4201
4858
  SidebarItem.displayName = "SidebarItem";
4859
+ var messageVariants = cva(
4860
+ [
4861
+ "flex w-full gap-3 px-4 py-3 text-sm",
4862
+ "transition-colors duration-[var(--duration-normal,200ms)] ease-out"
4863
+ ].join(" "),
4864
+ {
4865
+ variants: {
4866
+ role: {
4867
+ user: "bg-secondary/40 text-foreground",
4868
+ assistant: "bg-card text-card-foreground",
4869
+ system: "bg-muted text-muted-foreground italic",
4870
+ tool: "bg-accent/15 text-accent-foreground border-l-2 border-accent"
4871
+ }
4872
+ },
4873
+ defaultVariants: {
4874
+ role: "assistant"
4875
+ }
4876
+ }
4877
+ );
4878
+ function Message({ role, className, children, ...props }) {
4879
+ return /* @__PURE__ */ jsx("div", { "data-role": role, className: cn(messageVariants({ role }), className), ...props, children });
4880
+ }
4881
+ var NEAR_BOTTOM_THRESHOLD_PX = 80;
4882
+ function MessageList({
4883
+ autoScroll = true,
4884
+ className,
4885
+ children,
4886
+ ...props
4887
+ }) {
4888
+ const ref = React44.useRef(null);
4889
+ const stickToBottomRef = React44.useRef(true);
4890
+ React44.useEffect(() => {
4891
+ const el = ref.current;
4892
+ if (!el || !autoScroll) return;
4893
+ if (stickToBottomRef.current) {
4894
+ el.scrollTop = el.scrollHeight;
4895
+ }
4896
+ }, [autoScroll, children]);
4897
+ function handleScroll(event) {
4898
+ const el = event.currentTarget;
4899
+ const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
4900
+ stickToBottomRef.current = distance < NEAR_BOTTOM_THRESHOLD_PX;
4901
+ props.onScroll?.(event);
4902
+ }
4903
+ return /* @__PURE__ */ jsx(
4904
+ "div",
4905
+ {
4906
+ ref,
4907
+ role: "log",
4908
+ "aria-live": "polite",
4909
+ "aria-relevant": "additions",
4910
+ className: cn("flex flex-col overflow-y-auto", className),
4911
+ ...props,
4912
+ onScroll: handleScroll,
4913
+ children
4914
+ }
4915
+ );
4916
+ }
4917
+ function Composer({
4918
+ value,
4919
+ onValueChange,
4920
+ onSubmit,
4921
+ disabled,
4922
+ placeholder,
4923
+ submitOnEnter = true,
4924
+ textareaAriaLabel,
4925
+ children,
4926
+ className,
4927
+ ...rest
4928
+ }) {
4929
+ function trySubmit() {
4930
+ const trimmed = value.trim();
4931
+ if (!trimmed || disabled) return;
4932
+ onSubmit(trimmed);
4933
+ }
4934
+ function handleKeyDown(event) {
4935
+ if (!submitOnEnter) return;
4936
+ if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
4937
+ event.preventDefault();
4938
+ trySubmit();
4939
+ }
4940
+ }
4941
+ function handleSubmit(event) {
4942
+ event.preventDefault();
4943
+ trySubmit();
4944
+ }
4945
+ return /* @__PURE__ */ jsxs(
4946
+ "form",
4947
+ {
4948
+ ...rest,
4949
+ onSubmit: handleSubmit,
4950
+ className: cn(
4951
+ "flex items-end gap-2 rounded-lg border bg-background p-2",
4952
+ "focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
4953
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
4954
+ className
4955
+ ),
4956
+ children: [
4957
+ /* @__PURE__ */ jsx(
4958
+ "textarea",
4959
+ {
4960
+ value,
4961
+ onChange: (event) => onValueChange(event.target.value),
4962
+ onKeyDown: handleKeyDown,
4963
+ disabled,
4964
+ placeholder,
4965
+ "aria-label": textareaAriaLabel ?? placeholder ?? "Message",
4966
+ rows: 1,
4967
+ className: cn(
4968
+ "flex-1 resize-none bg-transparent px-2 py-1.5 text-sm leading-6",
4969
+ "placeholder:text-muted-foreground focus:outline-none",
4970
+ "disabled:cursor-not-allowed disabled:opacity-50",
4971
+ "max-h-48 min-h-[2.25rem] overflow-y-auto"
4972
+ )
4973
+ }
4974
+ ),
4975
+ children
4976
+ ]
4977
+ }
4978
+ );
4979
+ }
4980
+ var loadingIndicatorVariants = cva("inline-flex items-center gap-2 text-muted-foreground", {
4981
+ variants: {
4982
+ size: {
4983
+ sm: "text-xs",
4984
+ md: "text-sm"
4985
+ }
4986
+ },
4987
+ defaultVariants: { size: "md" }
4988
+ });
4989
+ function LoadingIndicator({
4990
+ variant = "dots",
4991
+ size,
4992
+ label,
4993
+ className,
4994
+ ...props
4995
+ }) {
4996
+ const ariaLabel = label ?? "Loading";
4997
+ return /* @__PURE__ */ jsxs(
4998
+ "div",
4999
+ {
5000
+ role: "status",
5001
+ "aria-live": "polite",
5002
+ className: cn(loadingIndicatorVariants({ size }), className),
5003
+ ...props,
5004
+ children: [
5005
+ variant === "dots" ? /* @__PURE__ */ jsx(Dots, {}) : null,
5006
+ variant === "pulse" ? /* @__PURE__ */ jsx(Pulse, {}) : null,
5007
+ variant === "bar" ? /* @__PURE__ */ jsx(Bar, {}) : null,
5008
+ label ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: label }) : null,
5009
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: ariaLabel })
5010
+ ]
5011
+ }
5012
+ );
5013
+ }
5014
+ function Dots() {
5015
+ return /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
5016
+ /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.3s]" }),
5017
+ /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.15s]" }),
5018
+ /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-current" })
5019
+ ] });
5020
+ }
5021
+ function Pulse() {
5022
+ return /* @__PURE__ */ jsx("span", { className: "h-2 w-2 animate-pulse rounded-full bg-current" });
5023
+ }
5024
+ function Bar() {
5025
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
5026
+ /* @__PURE__ */ jsx("span", { className: "h-0.5 w-2 animate-pulse rounded-full bg-current [animation-delay:-0.4s]" }),
5027
+ /* @__PURE__ */ jsx("span", { className: "h-0.5 w-3 animate-pulse rounded-full bg-current [animation-delay:-0.2s]" }),
5028
+ /* @__PURE__ */ jsx("span", { className: "h-0.5 w-4 animate-pulse rounded-full bg-current" })
5029
+ ] });
5030
+ }
5031
+ function Suggestion({
5032
+ value,
5033
+ onSelect,
5034
+ children,
5035
+ className,
5036
+ type = "button",
5037
+ onClick,
5038
+ ...props
5039
+ }) {
5040
+ function handleClick(event) {
5041
+ const payload = value ?? extractText(children);
5042
+ onSelect(payload);
5043
+ onClick?.(event);
5044
+ }
5045
+ return /* @__PURE__ */ jsx(
5046
+ "button",
5047
+ {
5048
+ type,
5049
+ onClick: handleClick,
5050
+ className: cn(
5051
+ "inline-flex items-center rounded-full border border-foreground/15 bg-background px-3 py-1.5 text-sm",
5052
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5053
+ "hover:border-foreground/30 hover:bg-secondary/40 hover:shadow-sm",
5054
+ "active:scale-[0.98]",
5055
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5056
+ "disabled:cursor-not-allowed disabled:opacity-50",
5057
+ className
5058
+ ),
5059
+ ...props,
5060
+ children
5061
+ }
5062
+ );
5063
+ }
5064
+ function extractText(node) {
5065
+ if (node == null || typeof node === "boolean") return "";
5066
+ if (typeof node === "string" || typeof node === "number") return String(node);
5067
+ if (Array.isArray(node)) return node.map(extractText).join(" ").replace(/\s+/g, " ").trim();
5068
+ if (React44.isValidElement(node)) {
5069
+ return extractText(node.props.children);
5070
+ }
5071
+ return "";
5072
+ }
5073
+ var STATE_LABEL = {
5074
+ pending: "Pending",
5075
+ running: "Running",
5076
+ result: "Done",
5077
+ error: "Error"
5078
+ };
5079
+ var STATE_CLASSES = {
5080
+ pending: "bg-muted text-muted-foreground",
5081
+ running: "bg-primary/15 text-primary animate-pulse",
5082
+ result: "bg-accent/30 text-accent-foreground",
5083
+ error: "bg-destructive/15 text-destructive"
5084
+ };
5085
+ function ToolCall({
5086
+ name,
5087
+ state,
5088
+ args,
5089
+ result,
5090
+ defaultOpen = false,
5091
+ className
5092
+ }) {
5093
+ return /* @__PURE__ */ jsxs(
5094
+ CollapsiblePrimitive.Root,
5095
+ {
5096
+ defaultOpen,
5097
+ className: cn(
5098
+ "overflow-hidden rounded-md border bg-card text-card-foreground",
5099
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5100
+ "data-[state=open]:shadow-sm",
5101
+ className
5102
+ ),
5103
+ children: [
5104
+ /* @__PURE__ */ jsxs(
5105
+ CollapsiblePrimitive.Trigger,
5106
+ {
5107
+ className: cn(
5108
+ "group flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm",
5109
+ "hover:bg-muted/40",
5110
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
5111
+ ),
5112
+ children: [
5113
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
5114
+ /* @__PURE__ */ jsx(ToolGlyph, {}),
5115
+ /* @__PURE__ */ jsx("span", { className: "truncate font-mono text-xs text-foreground", children: name }),
5116
+ /* @__PURE__ */ jsx(
5117
+ "span",
5118
+ {
5119
+ className: cn(
5120
+ "inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium",
5121
+ STATE_CLASSES[state]
5122
+ ),
5123
+ children: STATE_LABEL[state]
5124
+ }
5125
+ )
5126
+ ] }),
5127
+ /* @__PURE__ */ jsx(Chevron2, {})
5128
+ ]
5129
+ }
5130
+ ),
5131
+ /* @__PURE__ */ jsxs(CollapsiblePrimitive.Content, { className: "overflow-hidden border-t bg-muted/20 px-3 py-2 text-xs", children: [
5132
+ args !== void 0 ? /* @__PURE__ */ jsx(CodeSection, { label: "Arguments", value: args }) : null,
5133
+ result !== void 0 ? /* @__PURE__ */ jsx(CodeSection, { label: "Result", value: result }) : null,
5134
+ args === void 0 && result === void 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No arguments or result yet." }) : null
5135
+ ] })
5136
+ ]
5137
+ }
5138
+ );
5139
+ }
5140
+ function CodeSection({ label, value }) {
5141
+ const text = typeof value === "string" ? value : safeStringify(value);
5142
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1 py-1", children: [
5143
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: label }),
5144
+ /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto rounded bg-background/60 p-2 font-mono text-[11px] leading-snug", children: text })
5145
+ ] });
5146
+ }
5147
+ function safeStringify(value) {
5148
+ try {
5149
+ return JSON.stringify(value, null, 2);
5150
+ } catch {
5151
+ return String(value);
5152
+ }
5153
+ }
5154
+ function ToolGlyph() {
5155
+ return /* @__PURE__ */ jsxs(
5156
+ "svg",
5157
+ {
5158
+ "aria-hidden": true,
5159
+ viewBox: "0 0 16 16",
5160
+ width: "14",
5161
+ height: "14",
5162
+ fill: "none",
5163
+ stroke: "currentColor",
5164
+ strokeWidth: "1.5",
5165
+ strokeLinecap: "round",
5166
+ strokeLinejoin: "round",
5167
+ className: "shrink-0 text-muted-foreground",
5168
+ children: [
5169
+ /* @__PURE__ */ jsx("path", { d: "M11.5 1.5l3 3-2.5 2.5-3-3 2.5-2.5z" }),
5170
+ /* @__PURE__ */ jsx("path", { d: "M9 4l-7 7v3h3l7-7" })
5171
+ ]
5172
+ }
5173
+ );
5174
+ }
5175
+ function Chevron2() {
5176
+ return /* @__PURE__ */ jsx(
5177
+ "svg",
5178
+ {
5179
+ "aria-hidden": true,
5180
+ viewBox: "0 0 16 16",
5181
+ width: "14",
5182
+ height: "14",
5183
+ fill: "none",
5184
+ stroke: "currentColor",
5185
+ strokeWidth: "1.5",
5186
+ strokeLinecap: "round",
5187
+ strokeLinejoin: "round",
5188
+ className: "shrink-0 text-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-180",
5189
+ children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
5190
+ }
5191
+ );
5192
+ }
5193
+ function Reasoning({
5194
+ children,
5195
+ defaultOpen = false,
5196
+ durationMs,
5197
+ label,
5198
+ className
5199
+ }) {
5200
+ const headerLabel = label ?? (typeof durationMs === "number" ? formatThoughtFor(durationMs) : "Thinking");
5201
+ return /* @__PURE__ */ jsxs(
5202
+ CollapsiblePrimitive.Root,
5203
+ {
5204
+ defaultOpen,
5205
+ className: cn("overflow-hidden rounded-md border-l-2 border-foreground/15 bg-muted/20", className),
5206
+ children: [
5207
+ /* @__PURE__ */ jsxs(
5208
+ CollapsiblePrimitive.Trigger,
5209
+ {
5210
+ className: cn(
5211
+ "group flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-muted-foreground",
5212
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5213
+ "hover:text-foreground",
5214
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
5215
+ ),
5216
+ children: [
5217
+ /* @__PURE__ */ jsx(SparkleGlyph, {}),
5218
+ /* @__PURE__ */ jsx("span", { className: "font-medium italic", children: headerLabel }),
5219
+ /* @__PURE__ */ jsx(Chevron3, {})
5220
+ ]
5221
+ }
5222
+ ),
5223
+ /* @__PURE__ */ jsx(CollapsiblePrimitive.Content, { className: "overflow-hidden border-t border-foreground/[0.06] px-3 py-2 text-sm text-muted-foreground", children })
5224
+ ]
5225
+ }
5226
+ );
5227
+ }
5228
+ function formatThoughtFor(ms) {
5229
+ if (ms < 1e3) return `Thought for ${ms}ms`;
5230
+ const seconds = ms / 1e3;
5231
+ const formatted = seconds >= 10 ? Math.round(seconds).toString() : seconds.toFixed(1);
5232
+ return `Thought for ${formatted}s`;
5233
+ }
5234
+ function SparkleGlyph() {
5235
+ return /* @__PURE__ */ jsx(
5236
+ "svg",
5237
+ {
5238
+ "aria-hidden": true,
5239
+ viewBox: "0 0 16 16",
5240
+ width: "12",
5241
+ height: "12",
5242
+ fill: "none",
5243
+ stroke: "currentColor",
5244
+ strokeWidth: "1.5",
5245
+ strokeLinecap: "round",
5246
+ strokeLinejoin: "round",
5247
+ className: "shrink-0",
5248
+ children: /* @__PURE__ */ jsx("path", { d: "M8 1.5l1.5 4 4 1.5-4 1.5L8 12.5 6.5 8.5l-4-1.5 4-1.5L8 1.5z" })
5249
+ }
5250
+ );
5251
+ }
5252
+ function Chevron3() {
5253
+ return /* @__PURE__ */ jsx(
5254
+ "svg",
5255
+ {
5256
+ "aria-hidden": true,
5257
+ viewBox: "0 0 16 16",
5258
+ width: "12",
5259
+ height: "12",
5260
+ fill: "none",
5261
+ stroke: "currentColor",
5262
+ strokeWidth: "1.5",
5263
+ strokeLinecap: "round",
5264
+ strokeLinejoin: "round",
5265
+ className: "ml-auto shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-180",
5266
+ children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
5267
+ }
5268
+ );
5269
+ }
5270
+ function MessageActions({ className, children, ...props }) {
5271
+ return /* @__PURE__ */ jsx(
5272
+ "div",
5273
+ {
5274
+ className: cn(
5275
+ "mt-2 flex items-center gap-1 opacity-60",
5276
+ "transition-opacity duration-[var(--duration-normal,200ms)] ease-out",
5277
+ "group-hover/message:opacity-100 hover:opacity-100 focus-within:opacity-100",
5278
+ className
5279
+ ),
5280
+ ...props,
5281
+ children
5282
+ }
5283
+ );
5284
+ }
5285
+ function Citation({ title, url, page, index, className, children }) {
5286
+ const baseClasses = cn(
5287
+ "inline-flex items-center gap-1.5 rounded-md border border-foreground/15 bg-card px-2 py-0.5 text-xs",
5288
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5289
+ className
5290
+ );
5291
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
5292
+ typeof index === "number" ? /* @__PURE__ */ jsxs("span", { className: "font-mono text-[10px] font-semibold text-muted-foreground", children: [
5293
+ "[",
5294
+ index,
5295
+ "]"
5296
+ ] }) : /* @__PURE__ */ jsx(DocGlyph, {}),
5297
+ /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: title }),
5298
+ typeof page === "number" ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
5299
+ "p.",
5300
+ page
5301
+ ] }) : null,
5302
+ children
5303
+ ] });
5304
+ if (url) {
5305
+ return /* @__PURE__ */ jsx(
5306
+ "a",
5307
+ {
5308
+ href: url,
5309
+ target: "_blank",
5310
+ rel: "noreferrer noopener",
5311
+ className: cn(
5312
+ baseClasses,
5313
+ "hover:border-foreground/30 hover:bg-secondary/40 hover:shadow-sm",
5314
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
5315
+ ),
5316
+ children: body
5317
+ }
5318
+ );
5319
+ }
5320
+ return /* @__PURE__ */ jsx("span", { className: baseClasses, children: body });
5321
+ }
5322
+ function DocGlyph() {
5323
+ return /* @__PURE__ */ jsxs(
5324
+ "svg",
5325
+ {
5326
+ "aria-hidden": true,
5327
+ viewBox: "0 0 16 16",
5328
+ width: "11",
5329
+ height: "11",
5330
+ fill: "none",
5331
+ stroke: "currentColor",
5332
+ strokeWidth: "1.5",
5333
+ strokeLinecap: "round",
5334
+ strokeLinejoin: "round",
5335
+ className: "shrink-0 text-muted-foreground",
5336
+ children: [
5337
+ /* @__PURE__ */ jsx("path", { d: "M9 1.5H4.5A1.5 1.5 0 0 0 3 3v10a1.5 1.5 0 0 0 1.5 1.5h7A1.5 1.5 0 0 0 13 13V5.5L9 1.5z" }),
5338
+ /* @__PURE__ */ jsx("path", { d: "M9 1.5V5.5h4" })
5339
+ ]
5340
+ }
5341
+ );
5342
+ }
5343
+ function Markdown({ children, className }) {
5344
+ return /* @__PURE__ */ jsx(
5345
+ Streamdown,
5346
+ {
5347
+ className: cn(
5348
+ "prose prose-sm max-w-none text-foreground",
5349
+ "prose-headings:text-foreground prose-strong:text-foreground",
5350
+ "prose-a:text-primary prose-a:underline-offset-4 hover:prose-a:underline",
5351
+ "prose-code:text-foreground prose-code:before:content-none prose-code:after:content-none",
5352
+ className
5353
+ ),
5354
+ children
5355
+ }
5356
+ );
5357
+ }
5358
+ var LABEL_TO_LANG = {
5359
+ pnpm: "bash",
5360
+ npm: "bash",
5361
+ yarn: "bash",
5362
+ bun: "bash",
5363
+ bash: "bash",
5364
+ sh: "bash",
5365
+ shell: "bash",
5366
+ zsh: "bash",
5367
+ ts: "ts",
5368
+ typescript: "ts",
5369
+ tsx: "tsx",
5370
+ js: "js",
5371
+ javascript: "js",
5372
+ jsx: "jsx",
5373
+ json: "json",
5374
+ css: "css",
5375
+ html: "html",
5376
+ md: "md",
5377
+ markdown: "md",
5378
+ py: "py",
5379
+ python: "py",
5380
+ text: "text",
5381
+ prompt: "text",
5382
+ plain: "text"
5383
+ };
5384
+ var DEFAULT_THEMES = { light: "github-light-high-contrast", dark: "github-dark" };
5385
+ var cachedCodeToHtml = cache(
5386
+ async (code, lang, themesKey, themes) => {
5387
+ return codeToHtml(code, { lang, themes, defaultColor: false });
5388
+ }
5389
+ );
5390
+ function resolveLang(label, language) {
5391
+ if (language) return language;
5392
+ if (label) {
5393
+ const fromLabel = LABEL_TO_LANG[label.toLowerCase()];
5394
+ if (fromLabel) return fromLabel;
5395
+ }
5396
+ return "text";
5397
+ }
5398
+ async function CodeBlock({
5399
+ code,
5400
+ label,
5401
+ language,
5402
+ themes = DEFAULT_THEMES,
5403
+ className
5404
+ }) {
5405
+ const lang = resolveLang(label, language);
5406
+ const themesKey = `${themes.light}|${themes.dark}`;
5407
+ const html = await cachedCodeToHtml(code, lang, themesKey, themes);
5408
+ const displayLabel = label ?? lang;
5409
+ return /* @__PURE__ */ jsxs(
5410
+ "div",
5411
+ {
5412
+ className: cn(
5413
+ "group relative overflow-hidden rounded-lg border bg-card text-card-foreground",
5414
+ className
5415
+ ),
5416
+ children: [
5417
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b bg-muted/40 px-3 py-1.5", children: [
5418
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-xs font-medium text-muted-foreground", children: displayLabel }),
5419
+ /* @__PURE__ */ jsx(CodeBlockCopy, { code })
5420
+ ] }),
5421
+ /* @__PURE__ */ jsx(
5422
+ "div",
5423
+ {
5424
+ "data-shiki": "",
5425
+ className: "overflow-x-auto p-4 font-mono text-sm [&_pre]:!bg-transparent",
5426
+ dangerouslySetInnerHTML: { __html: html }
5427
+ }
5428
+ )
5429
+ ]
5430
+ }
5431
+ );
5432
+ }
5433
+ var RESET_DELAY_MS = 1500;
5434
+ function CodeBlockCopy2({ code, className, ...props }) {
5435
+ const [state, setState] = React44.useState("idle");
5436
+ React44.useEffect(() => {
5437
+ if (state === "idle") return;
5438
+ const id = window.setTimeout(() => setState("idle"), RESET_DELAY_MS);
5439
+ return () => window.clearTimeout(id);
5440
+ }, [state]);
5441
+ async function handleClick() {
5442
+ try {
5443
+ await navigator.clipboard.writeText(code);
5444
+ setState("copied");
5445
+ } catch {
5446
+ setState("error");
5447
+ }
5448
+ }
5449
+ const ariaLabel = state === "copied" ? "Copied" : state === "error" ? "Copy failed" : "Copy code";
5450
+ return /* @__PURE__ */ jsx(
5451
+ "button",
5452
+ {
5453
+ type: "button",
5454
+ onClick: handleClick,
5455
+ "aria-label": ariaLabel,
5456
+ title: ariaLabel,
5457
+ className: cn(
5458
+ "inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground",
5459
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5460
+ "hover:bg-foreground/10 hover:text-foreground",
5461
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5462
+ className
5463
+ ),
5464
+ ...props,
5465
+ children: state === "copied" ? /* @__PURE__ */ jsx(CheckGlyph, {}) : state === "error" ? /* @__PURE__ */ jsx(ErrorGlyph, {}) : /* @__PURE__ */ jsx(CopyGlyph, {})
5466
+ }
5467
+ );
5468
+ }
5469
+ function CopyGlyph() {
5470
+ return /* @__PURE__ */ jsxs(
5471
+ "svg",
5472
+ {
5473
+ "aria-hidden": true,
5474
+ viewBox: "0 0 16 16",
5475
+ width: "13",
5476
+ height: "13",
5477
+ fill: "none",
5478
+ stroke: "currentColor",
5479
+ strokeWidth: "1.5",
5480
+ strokeLinecap: "round",
5481
+ strokeLinejoin: "round",
5482
+ children: [
5483
+ /* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5" }),
5484
+ /* @__PURE__ */ jsx("path", { d: "M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" })
5485
+ ]
5486
+ }
5487
+ );
5488
+ }
5489
+ function CheckGlyph() {
5490
+ return /* @__PURE__ */ jsx(
5491
+ "svg",
5492
+ {
5493
+ "aria-hidden": true,
5494
+ viewBox: "0 0 16 16",
5495
+ width: "13",
5496
+ height: "13",
5497
+ fill: "none",
5498
+ stroke: "currentColor",
5499
+ strokeWidth: "1.5",
5500
+ strokeLinecap: "round",
5501
+ strokeLinejoin: "round",
5502
+ className: "text-emerald-500",
5503
+ children: /* @__PURE__ */ jsx("path", { d: "M3 8l3.5 3.5L13 5" })
5504
+ }
5505
+ );
5506
+ }
5507
+ function ErrorGlyph() {
5508
+ return /* @__PURE__ */ jsxs(
5509
+ "svg",
5510
+ {
5511
+ "aria-hidden": true,
5512
+ viewBox: "0 0 16 16",
5513
+ width: "13",
5514
+ height: "13",
5515
+ fill: "none",
5516
+ stroke: "currentColor",
5517
+ strokeWidth: "1.5",
5518
+ strokeLinecap: "round",
5519
+ strokeLinejoin: "round",
5520
+ className: "text-destructive",
5521
+ children: [
5522
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6.5" }),
5523
+ /* @__PURE__ */ jsx("path", { d: "M8 5v3.5M8 11v.01" })
5524
+ ]
5525
+ }
5526
+ );
5527
+ }
5528
+ var attachmentVariants = cva(
5529
+ [
5530
+ "group/attachment relative inline-flex items-center gap-[var(--gap-sm,0.5rem)] rounded-md border border-border bg-card",
5531
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out"
5532
+ ].join(" "),
5533
+ {
5534
+ variants: {
5535
+ variant: {
5536
+ file: "px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] max-w-xs",
5537
+ image: "p-0 overflow-hidden"
5538
+ }
5539
+ },
5540
+ defaultVariants: { variant: "file" }
5541
+ }
5542
+ );
5543
+ function formatSize(bytes) {
5544
+ if (bytes < 1024) return `${bytes} B`;
5545
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
5546
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5547
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
5548
+ }
5549
+ function detectVariant(file) {
5550
+ const preview = "preview" in file ? file.preview : void 0;
5551
+ const isImage = file.type.startsWith("image/");
5552
+ return isImage && preview ? "image" : "file";
5553
+ }
5554
+ function resolvePreview(file) {
5555
+ return "preview" in file ? file.preview : void 0;
5556
+ }
5557
+ function Attachment({
5558
+ className,
5559
+ variant,
5560
+ file,
5561
+ onRemove,
5562
+ progress,
5563
+ ref,
5564
+ ...props
5565
+ }) {
5566
+ const preview = resolvePreview(file);
5567
+ const detected = detectVariant(file);
5568
+ const resolvedVariant = variant === "image" && !preview ? "file" : variant ?? detected;
5569
+ const showProgress = typeof progress === "number" && progress >= 0 && progress < 1;
5570
+ const progressPercent = showProgress ? Math.round(progress * 100) : 0;
5571
+ return /* @__PURE__ */ jsxs(
5572
+ "div",
5573
+ {
5574
+ ref,
5575
+ className: cn(attachmentVariants({ variant: resolvedVariant }), className),
5576
+ ...props,
5577
+ children: [
5578
+ resolvedVariant === "image" && preview ? (
5579
+ // Intentional plain <img> (not next/image) — Attachment is
5580
+ // framework-agnostic. Consumers can swap in next/image at the
5581
+ // callsite when they want optimization.
5582
+ /* @__PURE__ */ jsx(
5583
+ "img",
5584
+ {
5585
+ src: preview,
5586
+ alt: file.name,
5587
+ className: "block h-20 w-20 object-cover"
5588
+ }
5589
+ )
5590
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
5591
+ /* @__PURE__ */ jsx(FileIcon2, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
5592
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
5593
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium text-foreground", children: file.name }),
5594
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatSize(file.size) })
5595
+ ] })
5596
+ ] }),
5597
+ showProgress ? /* @__PURE__ */ jsx(
5598
+ "div",
5599
+ {
5600
+ role: "progressbar",
5601
+ "aria-valuemin": 0,
5602
+ "aria-valuemax": 100,
5603
+ "aria-valuenow": progressPercent,
5604
+ "aria-label": `Uploading ${file.name}`,
5605
+ className: "absolute inset-x-0 bottom-0 h-1 overflow-hidden rounded-b-md bg-muted",
5606
+ children: /* @__PURE__ */ jsx(
5607
+ "div",
5608
+ {
5609
+ className: "h-full bg-primary transition-[width] duration-[var(--duration-normal,200ms)] ease-out",
5610
+ style: { width: `${progressPercent}%` }
5611
+ }
5612
+ )
5613
+ }
5614
+ ) : null,
5615
+ onRemove ? /* @__PURE__ */ jsx(
5616
+ "button",
5617
+ {
5618
+ type: "button",
5619
+ onClick: onRemove,
5620
+ "aria-label": `Remove ${file.name}`,
5621
+ className: cn(
5622
+ "absolute -right-2 -top-2 inline-flex h-5 w-5 items-center justify-center rounded-full",
5623
+ "bg-card border border-border text-foreground shadow-sm",
5624
+ "transition-all duration-[var(--duration-normal,200ms)] ease-out",
5625
+ "hover:bg-accent hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
5626
+ "active:scale-90"
5627
+ ),
5628
+ children: /* @__PURE__ */ jsxs(
5629
+ "svg",
5630
+ {
5631
+ xmlns: "http://www.w3.org/2000/svg",
5632
+ viewBox: "0 0 24 24",
5633
+ fill: "none",
5634
+ stroke: "currentColor",
5635
+ strokeWidth: "2.5",
5636
+ strokeLinecap: "round",
5637
+ strokeLinejoin: "round",
5638
+ className: "size-3",
5639
+ "aria-hidden": "true",
5640
+ children: [
5641
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
5642
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
5643
+ ]
5644
+ }
5645
+ )
5646
+ }
5647
+ ) : null
5648
+ ]
5649
+ }
5650
+ );
5651
+ }
5652
+ function FileIcon2(props) {
5653
+ return /* @__PURE__ */ jsxs(
5654
+ "svg",
5655
+ {
5656
+ xmlns: "http://www.w3.org/2000/svg",
5657
+ viewBox: "0 0 24 24",
5658
+ fill: "none",
5659
+ stroke: "currentColor",
5660
+ strokeWidth: "2",
5661
+ strokeLinecap: "round",
5662
+ strokeLinejoin: "round",
5663
+ "aria-hidden": "true",
5664
+ ...props,
5665
+ children: [
5666
+ /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
5667
+ /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" })
5668
+ ]
5669
+ }
5670
+ );
5671
+ }
4202
5672
 
4203
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Cluster, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorPicker, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Container, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuTrigger, DataTable, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuTrigger, Dropzone, FileTree, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Grid, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarSeparator, MenubarShortcut, MenubarTrigger, MultiCombobox, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Spacer, Stack, Stepper, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, badgeVariants, buttonVariants, clusterVariants, cn, containerVariants, formatHslTriplet, gridVariants, hexToHslTriplet, hslToRgb, hslTripletToHex, navigationMenuTriggerStyle, parseHslTriplet, rgbToHsl, spacerVariants, stackVariants, toggleVariants, useFormField, useSidebar };
5673
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Attachment, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Citation, Cluster, CodeBlock, CodeBlockCopy2 as CodeBlockCopy, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorPicker, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Composer, Container, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuTrigger, DataTable, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuTrigger, Dropzone, Empty, ErrorState, FileTree, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Grid, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, Loading, LoadingIndicator, Markdown, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarSeparator, MenubarShortcut, MenubarTrigger, Message, MessageActions, MessageList, MultiCombobox, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, Reasoning, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Spacer, Stack, Stepper, Suggestion, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Textarea, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, Toolbar, ToolbarButton, ToolbarLink, ToolbarSeparator, ToolbarToggleGroup, ToolbarToggleItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Tree, alertVariants, attachmentVariants, badgeVariants, buttonVariants, clusterVariants, cn, containerVariants, emptyVariants, errorStateVariants, formatHslTriplet, gridVariants, hexToHslTriplet, hslToRgb, hslTripletToHex, loadingIndicatorVariants, loadingVariants, messageVariants, navigationMenuTriggerStyle, parseHslTriplet, rgbToHsl, spacerVariants, stackVariants, tagVariants, toggleVariants, toolbarVariants, useFormField, useSidebar };
4204
5674
  //# sourceMappingURL=index.js.map
4205
5675
  //# sourceMappingURL=index.js.map