@7onic-ui/react 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +2 -2
  2. package/dist/chart.mjs +3 -9
  3. package/dist/chart.mjs.map +1 -1
  4. package/dist/chunk-2WIIXHOV.mjs +148 -0
  5. package/dist/chunk-2WIIXHOV.mjs.map +1 -0
  6. package/dist/chunk-53MIUPSY.mjs +13 -0
  7. package/dist/chunk-53MIUPSY.mjs.map +1 -0
  8. package/dist/chunk-BN5BEA3V.mjs +195 -0
  9. package/dist/chunk-BN5BEA3V.mjs.map +1 -0
  10. package/dist/chunk-C5D3VRNJ.mjs +504 -0
  11. package/dist/chunk-C5D3VRNJ.mjs.map +1 -0
  12. package/dist/chunk-COW3B62M.mjs +214 -0
  13. package/dist/chunk-COW3B62M.mjs.map +1 -0
  14. package/dist/chunk-CTH6SN5Y.mjs +114 -0
  15. package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
  16. package/dist/chunk-D3NTQNDW.mjs +440 -0
  17. package/dist/chunk-D3NTQNDW.mjs.map +1 -0
  18. package/dist/chunk-DDRYEJBJ.mjs +164 -0
  19. package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
  20. package/dist/chunk-DJAEXCRU.mjs +190 -0
  21. package/dist/chunk-DJAEXCRU.mjs.map +1 -0
  22. package/dist/chunk-DYYQOHQR.mjs +214 -0
  23. package/dist/chunk-DYYQOHQR.mjs.map +1 -0
  24. package/dist/chunk-EG2GTK65.mjs +443 -0
  25. package/dist/chunk-EG2GTK65.mjs.map +1 -0
  26. package/dist/chunk-FHUAH6AJ.mjs +93 -0
  27. package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
  28. package/dist/chunk-GD4YE5AE.mjs +209 -0
  29. package/dist/chunk-GD4YE5AE.mjs.map +1 -0
  30. package/dist/chunk-HHX4GABH.mjs +129 -0
  31. package/dist/chunk-HHX4GABH.mjs.map +1 -0
  32. package/dist/chunk-HS2VRYSX.mjs +148 -0
  33. package/dist/chunk-HS2VRYSX.mjs.map +1 -0
  34. package/dist/chunk-IHHI3LIN.mjs +155 -0
  35. package/dist/chunk-IHHI3LIN.mjs.map +1 -0
  36. package/dist/chunk-IJ2FZ3L5.mjs +159 -0
  37. package/dist/chunk-IJ2FZ3L5.mjs.map +1 -0
  38. package/dist/chunk-IPCIC2BI.mjs +148 -0
  39. package/dist/chunk-IPCIC2BI.mjs.map +1 -0
  40. package/dist/chunk-JCJEVXER.mjs +170 -0
  41. package/dist/chunk-JCJEVXER.mjs.map +1 -0
  42. package/dist/chunk-KBPYAMGS.mjs +157 -0
  43. package/dist/chunk-KBPYAMGS.mjs.map +1 -0
  44. package/dist/chunk-L55ABE4H.mjs +283 -0
  45. package/dist/chunk-L55ABE4H.mjs.map +1 -0
  46. package/dist/chunk-LJJ6K4IU.mjs +318 -0
  47. package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
  48. package/dist/chunk-ND6TUVP2.mjs +148 -0
  49. package/dist/chunk-ND6TUVP2.mjs.map +1 -0
  50. package/dist/chunk-NWFMJWGX.mjs +165 -0
  51. package/dist/chunk-NWFMJWGX.mjs.map +1 -0
  52. package/dist/chunk-PTAPPOKU.mjs +117 -0
  53. package/dist/chunk-PTAPPOKU.mjs.map +1 -0
  54. package/dist/chunk-PVTBM7V7.mjs +316 -0
  55. package/dist/chunk-PVTBM7V7.mjs.map +1 -0
  56. package/dist/chunk-Q5WVLK2L.mjs +77 -0
  57. package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
  58. package/dist/chunk-R7FJEO4K.mjs +252 -0
  59. package/dist/chunk-R7FJEO4K.mjs.map +1 -0
  60. package/dist/chunk-RKSB2N5L.mjs +206 -0
  61. package/dist/chunk-RKSB2N5L.mjs.map +1 -0
  62. package/dist/chunk-S4DGVKBK.mjs +151 -0
  63. package/dist/chunk-S4DGVKBK.mjs.map +1 -0
  64. package/dist/chunk-S4T4PU7F.mjs +114 -0
  65. package/dist/chunk-S4T4PU7F.mjs.map +1 -0
  66. package/dist/chunk-SDDAGZWA.mjs +224 -0
  67. package/dist/chunk-SDDAGZWA.mjs.map +1 -0
  68. package/dist/chunk-SZPZOGPC.mjs +394 -0
  69. package/dist/chunk-SZPZOGPC.mjs.map +1 -0
  70. package/dist/chunk-T5A4APEL.mjs +140 -0
  71. package/dist/chunk-T5A4APEL.mjs.map +1 -0
  72. package/dist/chunk-V5UFWYFI.mjs +255 -0
  73. package/dist/chunk-V5UFWYFI.mjs.map +1 -0
  74. package/dist/chunk-W6YNEU53.mjs +175 -0
  75. package/dist/chunk-W6YNEU53.mjs.map +1 -0
  76. package/dist/chunk-XK52LYR4.mjs +182 -0
  77. package/dist/chunk-XK52LYR4.mjs.map +1 -0
  78. package/dist/chunk-YIAH6KHV.mjs +164 -0
  79. package/dist/chunk-YIAH6KHV.mjs.map +1 -0
  80. package/dist/chunk-YZ7HHFKA.mjs +375 -0
  81. package/dist/chunk-YZ7HHFKA.mjs.map +1 -0
  82. package/dist/chunk-ZDRUTJ4T.mjs +119 -0
  83. package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
  84. package/dist/components/accordion.mjs +19 -0
  85. package/dist/components/accordion.mjs.map +1 -0
  86. package/dist/components/alert.mjs +15 -0
  87. package/dist/components/alert.mjs.map +1 -0
  88. package/dist/components/avatar.mjs +23 -0
  89. package/dist/components/avatar.mjs.map +1 -0
  90. package/dist/components/badge.mjs +11 -0
  91. package/dist/components/badge.mjs.map +1 -0
  92. package/dist/components/breadcrumb.mjs +23 -0
  93. package/dist/components/breadcrumb.mjs.map +1 -0
  94. package/dist/components/button-group.mjs +11 -0
  95. package/dist/components/button-group.mjs.map +1 -0
  96. package/dist/components/button.mjs +12 -0
  97. package/dist/components/button.mjs.map +1 -0
  98. package/dist/components/card.mjs +25 -0
  99. package/dist/components/card.mjs.map +1 -0
  100. package/dist/components/chat-input.mjs +15 -0
  101. package/dist/components/chat-input.mjs.map +1 -0
  102. package/dist/components/chat-message.mjs +17 -0
  103. package/dist/components/chat-message.mjs.map +1 -0
  104. package/dist/components/checkbox.mjs +12 -0
  105. package/dist/components/checkbox.mjs.map +1 -0
  106. package/dist/components/divider.mjs +11 -0
  107. package/dist/components/divider.mjs.map +1 -0
  108. package/dist/components/drawer.mjs +33 -0
  109. package/dist/components/drawer.mjs.map +1 -0
  110. package/dist/components/dropdown.mjs +35 -0
  111. package/dist/components/dropdown.mjs.map +1 -0
  112. package/dist/components/field.mjs +19 -0
  113. package/dist/components/field.mjs.map +1 -0
  114. package/dist/components/icon-button.mjs +12 -0
  115. package/dist/components/icon-button.mjs.map +1 -0
  116. package/dist/components/input.mjs +12 -0
  117. package/dist/components/input.mjs.map +1 -0
  118. package/dist/components/metric-card.mjs +23 -0
  119. package/dist/components/metric-card.mjs.map +1 -0
  120. package/dist/components/modal.mjs +57 -0
  121. package/dist/components/modal.mjs.map +1 -0
  122. package/dist/components/navigation-menu.mjs +27 -0
  123. package/dist/components/navigation-menu.mjs.map +1 -0
  124. package/dist/components/pagination.mjs +33 -0
  125. package/dist/components/pagination.mjs.map +1 -0
  126. package/dist/components/popover.mjs +23 -0
  127. package/dist/components/popover.mjs.map +1 -0
  128. package/dist/components/progress.mjs +11 -0
  129. package/dist/components/progress.mjs.map +1 -0
  130. package/dist/components/quick-reply.mjs +15 -0
  131. package/dist/components/quick-reply.mjs.map +1 -0
  132. package/dist/components/radio-group.mjs +16 -0
  133. package/dist/components/radio-group.mjs.map +1 -0
  134. package/dist/components/segmented.mjs +15 -0
  135. package/dist/components/segmented.mjs.map +1 -0
  136. package/dist/components/select.mjs +24 -0
  137. package/dist/components/select.mjs.map +1 -0
  138. package/dist/components/skeleton.mjs +11 -0
  139. package/dist/components/skeleton.mjs.map +1 -0
  140. package/dist/components/slider.mjs +12 -0
  141. package/dist/components/slider.mjs.map +1 -0
  142. package/dist/components/spinner.mjs +11 -0
  143. package/dist/components/spinner.mjs.map +1 -0
  144. package/dist/components/switch.mjs +12 -0
  145. package/dist/components/switch.mjs.map +1 -0
  146. package/dist/components/table.mjs +23 -0
  147. package/dist/components/table.mjs.map +1 -0
  148. package/dist/components/tabs.mjs +19 -0
  149. package/dist/components/tabs.mjs.map +1 -0
  150. package/dist/components/textarea.mjs +12 -0
  151. package/dist/components/textarea.mjs.map +1 -0
  152. package/dist/components/toast.mjs +13 -0
  153. package/dist/components/toast.mjs.map +1 -0
  154. package/dist/components/toggle-group.mjs +15 -0
  155. package/dist/components/toggle-group.mjs.map +1 -0
  156. package/dist/components/toggle.mjs +11 -0
  157. package/dist/components/toggle.mjs.map +1 -0
  158. package/dist/components/tooltip.mjs +21 -0
  159. package/dist/components/tooltip.mjs.map +1 -0
  160. package/dist/components/typing-indicator.mjs +11 -0
  161. package/dist/components/typing-indicator.mjs.map +1 -0
  162. package/dist/index.d.ts +11 -2
  163. package/dist/index.js +95 -21
  164. package/dist/index.js.map +1 -1
  165. package/dist/index.mjs +296 -7536
  166. package/dist/index.mjs.map +1 -1
  167. package/llms.txt +50 -32
  168. package/package.json +14 -14
  169. package/dist/chart.d.mts +0 -147
  170. package/dist/index.d.mts +0 -1535
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/button-group.tsx
7
+ import * as React from "react";
8
+ var ButtonGroupContext = React.createContext(null);
9
+ function useButtonGroup() {
10
+ return React.useContext(ButtonGroupContext);
11
+ }
12
+ var ButtonGroup = React.forwardRef(
13
+ ({
14
+ className,
15
+ orientation = "horizontal",
16
+ attached = true,
17
+ variant,
18
+ size,
19
+ radius,
20
+ fontWeight,
21
+ disabled,
22
+ children,
23
+ ...props
24
+ }, ref) => {
25
+ const contextValue = React.useMemo(() => ({
26
+ variant,
27
+ size,
28
+ radius,
29
+ fontWeight,
30
+ disabled
31
+ }), [variant, size, radius, fontWeight, disabled]);
32
+ return /* @__PURE__ */ React.createElement(ButtonGroupContext.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(
33
+ "div",
34
+ {
35
+ ref,
36
+ role: "group",
37
+ className: cn(
38
+ "inline-flex",
39
+ orientation === "vertical" ? "flex-col" : "flex-row",
40
+ // Attached mode: use negative margin to overlap borders, raise z-index on hover/focus
41
+ attached && orientation === "horizontal" && [
42
+ "[&>*:not(:first-child)]:rounded-l-none",
43
+ "[&>*:not(:last-child)]:rounded-r-none",
44
+ "[&>*:not(:first-child)]:-ml-px",
45
+ "[&>*]:relative",
46
+ "[&>*:hover]:z-10",
47
+ "[&>*:focus-visible]:z-10",
48
+ "[&>*:active]:scale-none",
49
+ "[&>*:hover]:border-border"
50
+ ],
51
+ attached && orientation === "vertical" && [
52
+ "[&>*:not(:first-child)]:rounded-t-none",
53
+ "[&>*:not(:last-child)]:rounded-b-none",
54
+ "[&>*:not(:first-child)]:-mt-px",
55
+ "[&>*]:relative",
56
+ "[&>*]:w-full",
57
+ "[&>*:hover]:z-10",
58
+ "[&>*:focus-visible]:z-10",
59
+ "[&>*:active]:scale-none",
60
+ "[&>*:hover]:border-border"
61
+ ],
62
+ !attached && "gap-2",
63
+ className
64
+ ),
65
+ ...props
66
+ },
67
+ children
68
+ ));
69
+ }
70
+ );
71
+ ButtonGroup.displayName = "ButtonGroup";
72
+
73
+ export {
74
+ useButtonGroup,
75
+ ButtonGroup
76
+ };
77
+ //# sourceMappingURL=chunk-Q5WVLK2L.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/button-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\n\n// ButtonGroup Context\ntype ButtonGroupContextValue = {\n variant?: 'outline' | 'ghost'\n size?: 'xs' | 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n fontWeight?: 'normal' | 'semibold'\n disabled?: boolean\n}\n\nconst ButtonGroupContext = React.createContext<ButtonGroupContextValue | null>(null)\n\nexport function useButtonGroup() {\n return React.useContext(ButtonGroupContext)\n}\n\nexport interface ButtonGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: 'horizontal' | 'vertical'\n attached?: boolean\n variant?: 'outline' | 'ghost'\n size?: 'xs' | 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n fontWeight?: 'normal' | 'semibold'\n disabled?: boolean\n}\n\nconst ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({\n className,\n orientation = 'horizontal',\n attached = true,\n variant,\n size,\n radius,\n fontWeight,\n disabled,\n children,\n ...props\n }, ref) => {\n const contextValue = React.useMemo(() => ({\n variant,\n size,\n radius,\n fontWeight,\n disabled,\n }), [variant, size, radius, fontWeight, disabled])\n\n return (\n <ButtonGroupContext.Provider value={contextValue}>\n <div\n ref={ref}\n role=\"group\"\n className={cn(\n 'inline-flex',\n orientation === 'vertical' ? 'flex-col' : 'flex-row',\n // Attached mode: use negative margin to overlap borders, raise z-index on hover/focus\n attached && orientation === 'horizontal' && [\n '[&>*:not(:first-child)]:rounded-l-none',\n '[&>*:not(:last-child)]:rounded-r-none',\n '[&>*:not(:first-child)]:-ml-px',\n '[&>*]:relative',\n '[&>*:hover]:z-10',\n '[&>*:focus-visible]:z-10',\n '[&>*:active]:scale-none',\n '[&>*:hover]:border-border',\n ],\n attached && orientation === 'vertical' && [\n '[&>*:not(:first-child)]:rounded-t-none',\n '[&>*:not(:last-child)]:rounded-b-none',\n '[&>*:not(:first-child)]:-mt-px',\n '[&>*]:relative',\n '[&>*]:w-full',\n '[&>*:hover]:z-10',\n '[&>*:focus-visible]:z-10',\n '[&>*:active]:scale-none',\n '[&>*:hover]:border-border',\n ],\n !attached && 'gap-2',\n className\n )}\n {...props}\n >\n {children}\n </div>\n </ButtonGroupContext.Provider>\n )\n }\n)\nButtonGroup.displayName = 'ButtonGroup'\n\nexport { ButtonGroup }\n"],"mappings":";;;;;;AAEA,YAAY,WAAW;AAYvB,IAAM,qBAA2B,oBAA8C,IAAI;AAE5E,SAAS,iBAAiB;AAC/B,SAAa,iBAAW,kBAAkB;AAC5C;AAYA,IAAM,cAAoB;AAAA,EACxB,CAAC;AAAA,IACC;AAAA,IACA,cAAc;AAAA,IACd,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAAG,QAAQ;AACT,UAAM,eAAqB,cAAQ,OAAO;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,CAAC,SAAS,MAAM,QAAQ,YAAY,QAAQ,CAAC;AAEjD,WACE,oCAAC,mBAAmB,UAAnB,EAA4B,OAAO,gBAClC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW;AAAA,UACT;AAAA,UACA,gBAAgB,aAAa,aAAa;AAAA;AAAA,UAE1C,YAAY,gBAAgB,gBAAgB;AAAA,YAC1C;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,YAAY,gBAAgB,cAAc;AAAA,YACxC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,CAAC,YAAY;AAAA,UACb;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,MAEH;AAAA,IACH,CACF;AAAA,EAEJ;AACF;AACA,YAAY,cAAc;","names":[]}
@@ -0,0 +1,252 @@
1
+ "use client";
2
+ import {
3
+ TypingIndicator
4
+ } from "./chunk-S4T4PU7F.mjs";
5
+ import {
6
+ Avatar,
7
+ AvatarFallback,
8
+ AvatarImage
9
+ } from "./chunk-GD4YE5AE.mjs";
10
+ import {
11
+ cn
12
+ } from "./chunk-53MIUPSY.mjs";
13
+
14
+ // src/components/ui/chat-message.tsx
15
+ import * as React from "react";
16
+ var ChatMessageContext = React.createContext({
17
+ role: "assistant",
18
+ variant: "bubble",
19
+ color: "default",
20
+ size: "default",
21
+ radius: "2xl",
22
+ tail: true,
23
+ typing: false,
24
+ actions: void 0
25
+ });
26
+ var bubblePaddingMap = {
27
+ sm: "px-3 py-1.5",
28
+ default: "px-3.5 py-2",
29
+ lg: "px-4 py-2.5"
30
+ };
31
+ var bubbleTextMap = {
32
+ sm: "text-sm",
33
+ default: "text-md",
34
+ lg: "text-base"
35
+ };
36
+ var footerTextMap = {
37
+ sm: "text-2xs",
38
+ default: "text-2xs",
39
+ lg: "text-xs"
40
+ };
41
+ var rowGapMap = {
42
+ sm: "gap-2",
43
+ default: "gap-2.5",
44
+ lg: "gap-3"
45
+ };
46
+ var avatarGapMap = {
47
+ sm: "gap-1.5",
48
+ md: "gap-2.5",
49
+ lg: "gap-3"
50
+ };
51
+ var chatAvatarSizeMap = {
52
+ sm: "w-6 h-6",
53
+ // 24px
54
+ md: "w-7 h-7",
55
+ // 28px
56
+ lg: "w-8 h-8"
57
+ // 32px
58
+ };
59
+ var chatAvatarFontMap = {
60
+ sm: "text-2xs",
61
+ md: "text-2xs",
62
+ lg: "text-xs"
63
+ };
64
+ var bubbleRadiusTailMap = {
65
+ md: { assistant: "rounded-tl-md rounded-tr-md rounded-br-md rounded-bl-none", user: "rounded-tl-md rounded-tr-md rounded-br-none rounded-bl-md" },
66
+ lg: { assistant: "rounded-tl-lg rounded-tr-lg rounded-br-lg rounded-bl-none", user: "rounded-tl-lg rounded-tr-lg rounded-br-none rounded-bl-lg" },
67
+ xl: { assistant: "rounded-tl-xl rounded-tr-xl rounded-br-xl rounded-bl-none", user: "rounded-tl-xl rounded-tr-xl rounded-br-none rounded-bl-xl" },
68
+ "2xl": { assistant: "rounded-tl-2xl rounded-tr-2xl rounded-br-2xl rounded-bl-none", user: "rounded-tl-2xl rounded-tr-2xl rounded-br-none rounded-bl-2xl" }
69
+ };
70
+ var bubbleRadiusSymMap = {
71
+ md: "rounded-md",
72
+ lg: "rounded-lg",
73
+ xl: "rounded-xl",
74
+ "2xl": "rounded-2xl"
75
+ };
76
+ function getBubbleColors(color, variant) {
77
+ if (variant === "flat") {
78
+ return color === "muted" ? "bg-background-muted text-foreground" : "text-foreground";
79
+ }
80
+ switch (color) {
81
+ case "default":
82
+ return "bg-background-paper border border-border text-foreground";
83
+ case "muted":
84
+ return "bg-background-muted text-foreground";
85
+ case "primary":
86
+ return "bg-primary text-primary-foreground";
87
+ case "dark":
88
+ return "bg-foreground text-background";
89
+ }
90
+ }
91
+ var builtInStatusLabels = {
92
+ sending: { label: "Sending...", className: "text-text-subtle" },
93
+ sent: { label: "Sent", className: "text-text-subtle" },
94
+ read: { label: "Read", className: "text-text-subtle" },
95
+ error: { label: "Failed", className: "text-error" }
96
+ };
97
+ var typingSizeMap = {
98
+ sm: "sm",
99
+ default: "sm",
100
+ lg: "default"
101
+ };
102
+ var typingMinWidthMap = {
103
+ sm: "min-w-12",
104
+ default: "min-w-12",
105
+ lg: "min-w-16"
106
+ };
107
+ var ChatMessage = React.forwardRef(
108
+ ({
109
+ className,
110
+ role = "assistant",
111
+ variant = "bubble",
112
+ color = "default",
113
+ size = "default",
114
+ radius = "2xl",
115
+ tail = true,
116
+ typing = false,
117
+ avatarSize,
118
+ actions,
119
+ children,
120
+ ...props
121
+ }, ref) => {
122
+ const ctx = React.useMemo(
123
+ () => ({ role, variant, color, size, radius, tail, typing, actions }),
124
+ [role, variant, color, size, radius, tail, typing, actions]
125
+ );
126
+ const gapClass = avatarSize ? avatarGapMap[avatarSize] : rowGapMap[size];
127
+ return /* @__PURE__ */ React.createElement(ChatMessageContext.Provider, { value: ctx }, /* @__PURE__ */ React.createElement(
128
+ "div",
129
+ {
130
+ ref,
131
+ className: cn(
132
+ "group/message flex items-end",
133
+ gapClass,
134
+ role === "user" && variant !== "flat" ? "flex-row-reverse" : "flex-row",
135
+ className
136
+ ),
137
+ ...props
138
+ },
139
+ children
140
+ ));
141
+ }
142
+ );
143
+ ChatMessage.displayName = "ChatMessage";
144
+ function DefaultAiIcon() {
145
+ return /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "w-3/5 h-3/5", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M12 3l1.8 5.4 5.4 1.8-5.4 1.8L12 17.4l-1.8-5.4L4.8 10.2l5.4-1.8z" }), /* @__PURE__ */ React.createElement("path", { d: "M19.5 3.5l.8 2.4 2.4.8-2.4.8L19.5 10l-.8-2.5-2.4-.8 2.4-.8z", opacity: ".6" }), /* @__PURE__ */ React.createElement("path", { d: "M4.5 14.5l.7 2 2 .7-2 .7L4.5 20l-.7-2-2-.7 2-.7z", opacity: ".4" }));
146
+ }
147
+ var ChatMessageAvatar = React.forwardRef(
148
+ ({ className, size: avatarSize = "md", src, alt = "Avatar", initials, icon }, ref) => /* @__PURE__ */ React.createElement(
149
+ Avatar,
150
+ {
151
+ ref,
152
+ "aria-hidden": "true",
153
+ className: cn(chatAvatarSizeMap[avatarSize], "shrink-0", className)
154
+ },
155
+ src && /* @__PURE__ */ React.createElement(AvatarImage, { src, alt }),
156
+ /* @__PURE__ */ React.createElement(AvatarFallback, { className: cn("font-semibold", chatAvatarFontMap[avatarSize]) }, icon ?? (initials || /* @__PURE__ */ React.createElement(DefaultAiIcon, null)))
157
+ )
158
+ );
159
+ ChatMessageAvatar.displayName = "ChatMessageAvatar";
160
+ var ChatMessageContent = React.forwardRef(
161
+ ({ className, children, ...props }, ref) => {
162
+ const { role, variant, color, size, radius, tail, typing, actions } = React.useContext(ChatMessageContext);
163
+ const isTyping = !!typing;
164
+ const typingProps = typeof typing === "object" ? typing : {};
165
+ const isDarkBg = color === "primary" || color === "dark";
166
+ const invertDots = variant === "bubble" && isDarkBg;
167
+ const effectiveTail = variant === "flat" ? false : tail;
168
+ const radiusClasses = effectiveTail ? bubbleRadiusTailMap[radius][role] : bubbleRadiusSymMap[radius];
169
+ const bubble = /* @__PURE__ */ React.createElement(
170
+ "div",
171
+ {
172
+ ref,
173
+ className: cn(
174
+ bubbleTextMap[size],
175
+ variant === "bubble" && "max-w-[75%]",
176
+ isTyping && [typingMinWidthMap[size], "text-center"],
177
+ getBubbleColors(color, variant),
178
+ (variant === "bubble" || variant === "flat") && bubblePaddingMap[size],
179
+ (variant === "bubble" || variant === "flat" && color === "muted") && radiusClasses,
180
+ className
181
+ ),
182
+ ...props
183
+ },
184
+ isTyping ? /* @__PURE__ */ React.createElement(
185
+ TypingIndicator,
186
+ {
187
+ size: typingSizeMap[size],
188
+ color: "muted",
189
+ ...typingProps,
190
+ className: cn("align-middle", invertDots && "[&>div>div]:bg-current")
191
+ }
192
+ ) : children
193
+ );
194
+ if (!actions) return bubble;
195
+ return /* @__PURE__ */ React.createElement("div", { className: cn("flex items-end gap-1.5", role === "user" && variant !== "flat" ? "flex-row-reverse" : "flex-row") }, bubble, /* @__PURE__ */ React.createElement("div", { className: cn(
196
+ "shrink-0 flex items-center gap-1 pb-0.5",
197
+ "opacity-0 group-hover/message:opacity-100",
198
+ "transition-opacity duration-normal"
199
+ ) }, actions));
200
+ }
201
+ );
202
+ ChatMessageContent.displayName = "ChatMessageContent";
203
+ var ChatMessageFooter = React.forwardRef(
204
+ ({
205
+ className,
206
+ timestamp,
207
+ status,
208
+ role: roleProp,
209
+ size: sizeProp,
210
+ children,
211
+ ...props
212
+ }, ref) => {
213
+ const ctx = React.useContext(ChatMessageContext);
214
+ const role = roleProp ?? ctx.role;
215
+ const size = sizeProp ?? ctx.size;
216
+ const variant = ctx.variant;
217
+ const statusContent = React.useMemo(() => {
218
+ if (status == null) return null;
219
+ if (typeof status === "string" && status in builtInStatusLabels) {
220
+ const { label, className: cls } = builtInStatusLabels[status];
221
+ return /* @__PURE__ */ React.createElement("span", { className: cls }, label);
222
+ }
223
+ return status;
224
+ }, [status]);
225
+ return /* @__PURE__ */ React.createElement(
226
+ "div",
227
+ {
228
+ ref,
229
+ className: cn(
230
+ "flex items-center gap-1 select-none",
231
+ footerTextMap[size],
232
+ "text-text-subtle",
233
+ role === "user" && variant !== "flat" ? "justify-end" : "justify-start",
234
+ className
235
+ ),
236
+ ...props
237
+ },
238
+ children,
239
+ statusContent,
240
+ timestamp && /* @__PURE__ */ React.createElement("span", null, timestamp)
241
+ );
242
+ }
243
+ );
244
+ ChatMessageFooter.displayName = "ChatMessageFooter";
245
+
246
+ export {
247
+ ChatMessage,
248
+ ChatMessageAvatar,
249
+ ChatMessageContent,
250
+ ChatMessageFooter
251
+ };
252
+ //# sourceMappingURL=chunk-R7FJEO4K.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/chat-message.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'\nimport { TypingIndicator, type TypingIndicatorProps } from '@/components/ui/typing-indicator'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ChatMessageRole = 'user' | 'assistant'\nexport type ChatMessageVariant = 'bubble' | 'flat'\nexport type ChatMessageColor = 'default' | 'muted' | 'primary' | 'dark'\nexport type ChatMessageSize = 'sm' | 'default' | 'lg'\nexport type ChatMessageRadius = 'md' | 'lg' | 'xl' | '2xl'\nexport type ChatMessageAvatarSize = 'sm' | 'md' | 'lg'\n\n/** Built-in status presets (pass as string to Footer.status for auto-rendering) */\nexport type ChatMessageStatus = 'sending' | 'sent' | 'read' | 'error'\n\n// ============================================================================\n// Context — propagates root props to sub-components\n// ============================================================================\n\ninterface ChatMessageContextValue {\n role: ChatMessageRole\n variant: ChatMessageVariant\n color: ChatMessageColor\n size: ChatMessageSize\n radius: ChatMessageRadius\n tail: boolean\n typing: boolean | Omit<TypingIndicatorProps, 'className'>\n actions?: React.ReactNode\n}\n\nconst ChatMessageContext = React.createContext<ChatMessageContextValue>({\n role: 'assistant',\n variant: 'bubble',\n color: 'default',\n size: 'default',\n radius: '2xl',\n tail: true,\n typing: false,\n actions: undefined,\n})\n\n// ============================================================================\n// Size maps\n// ============================================================================\n\n/** Bubble padding per size */\nconst bubblePaddingMap: Record<ChatMessageSize, string> = {\n sm: 'px-3 py-1.5',\n default: 'px-3.5 py-2',\n lg: 'px-4 py-2.5',\n}\n\n/** Bubble text class per size */\nconst bubbleTextMap: Record<ChatMessageSize, string> = {\n sm: 'text-sm',\n default: 'text-md',\n lg: 'text-base',\n}\n\n/** Footer text size per size */\nconst footerTextMap: Record<ChatMessageSize, string> = {\n sm: 'text-2xs',\n default: 'text-2xs',\n lg: 'text-xs',\n}\n\n/** Gap between avatar and content per message size */\nconst rowGapMap: Record<ChatMessageSize, string> = {\n sm: 'gap-2',\n default: 'gap-2.5',\n lg: 'gap-3',\n}\n\n/** Gap override when avatarSize is explicitly set */\nconst avatarGapMap: Record<ChatMessageAvatarSize, string> = {\n sm: 'gap-1.5',\n md: 'gap-2.5',\n lg: 'gap-3',\n}\n\n// ============================================================================\n// Chat avatar sizes (independent from message size)\n// ============================================================================\n\nconst chatAvatarSizeMap: Record<ChatMessageAvatarSize, string> = {\n sm: 'w-6 h-6', // 24px\n md: 'w-7 h-7', // 28px\n lg: 'w-8 h-8', // 32px\n}\n\nconst chatAvatarFontMap: Record<ChatMessageAvatarSize, string> = {\n sm: 'text-2xs',\n md: 'text-2xs',\n lg: 'text-xs',\n}\n\n// ============================================================================\n// Bubble radius — static maps for Tailwind JIT scanner compatibility\n// ============================================================================\n\n/**\n * Asymmetric with tail: tail corner = rounded-none (0px).\n * assistant → tail at bottom-left | user → tail at bottom-right\n */\nconst bubbleRadiusTailMap: Record<ChatMessageRadius, Record<ChatMessageRole, string>> = {\n md: { assistant: 'rounded-tl-md rounded-tr-md rounded-br-md rounded-bl-none', user: 'rounded-tl-md rounded-tr-md rounded-br-none rounded-bl-md' },\n lg: { assistant: 'rounded-tl-lg rounded-tr-lg rounded-br-lg rounded-bl-none', user: 'rounded-tl-lg rounded-tr-lg rounded-br-none rounded-bl-lg' },\n xl: { assistant: 'rounded-tl-xl rounded-tr-xl rounded-br-xl rounded-bl-none', user: 'rounded-tl-xl rounded-tr-xl rounded-br-none rounded-bl-xl' },\n '2xl': { assistant: 'rounded-tl-2xl rounded-tr-2xl rounded-br-2xl rounded-bl-none', user: 'rounded-tl-2xl rounded-tr-2xl rounded-br-none rounded-bl-2xl' },\n}\n\n/** Symmetric: all corners same radius */\nconst bubbleRadiusSymMap: Record<ChatMessageRadius, string> = {\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n}\n\n// ============================================================================\n// Bubble color helper — applies to both roles uniformly\n// ============================================================================\n\nfunction getBubbleColors(color: ChatMessageColor, variant: ChatMessageVariant): string {\n if (variant === 'flat') {\n return color === 'muted' ? 'bg-background-muted text-foreground' : 'text-foreground'\n }\n switch (color) {\n case 'default': return 'bg-background-paper border border-border text-foreground'\n case 'muted': return 'bg-background-muted text-foreground'\n case 'primary': return 'bg-primary text-primary-foreground'\n case 'dark': return 'bg-foreground text-background'\n }\n}\n\n// ============================================================================\n// Built-in status labels\n// ============================================================================\n\nconst builtInStatusLabels: Record<string, { label: string; className: string }> = {\n sending: { label: 'Sending...', className: 'text-text-subtle' },\n sent: { label: 'Sent', className: 'text-text-subtle' },\n read: { label: 'Read', className: 'text-text-subtle' },\n error: { label: 'Failed', className: 'text-error' },\n}\n\n// ============================================================================\n// TypingIndicator size mapping (chat sizes → indicator sizes)\n// ============================================================================\n\nconst typingSizeMap: Record<ChatMessageSize, 'sm' | 'default' | 'lg'> = {\n sm: 'sm',\n default: 'sm',\n lg: 'default',\n}\n\n/** Minimum bubble width when typing — accounts for dot size + padding per chat size */\nconst typingMinWidthMap: Record<ChatMessageSize, string> = {\n sm: 'min-w-12',\n default: 'min-w-12',\n lg: 'min-w-16',\n}\n\n// ============================================================================\n// Props interfaces\n// ============================================================================\n\nexport interface ChatMessageRootProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Sender role — controls alignment (left=assistant, right=user) */\n role?: ChatMessageRole\n /** Bubble visual style */\n variant?: ChatMessageVariant\n /** Bubble background color */\n color?: ChatMessageColor\n /** Size scale — affects text and padding */\n size?: ChatMessageSize\n /** Bubble corner radius */\n radius?: ChatMessageRadius\n /** Asymmetric tail corner (radius=0 on the avatar side) */\n tail?: boolean\n /** Show typing indicator inside Content. Pass true for defaults, or TypingIndicatorProps for custom. */\n typing?: boolean | Omit<TypingIndicatorProps, 'className'>\n /** Avatar size — overrides default gap between avatar and bubble */\n avatarSize?: ChatMessageAvatarSize\n /** Action buttons revealed on hover */\n actions?: React.ReactNode\n}\n\nexport interface ChatMessageAvatarProps {\n /** Avatar size: sm(24px), md(28px), lg(32px) */\n size?: ChatMessageAvatarSize\n /** Image URL */\n src?: string\n /** Alt text for avatar image */\n alt?: string\n /** Initials to display when no image (1–2 characters) */\n initials?: string\n /** Custom icon or ReactNode to render inside the avatar */\n icon?: React.ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\nexport interface ChatMessageContentProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport interface ChatMessageFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Pre-formatted timestamp string (e.g. \"12:34 PM\") */\n timestamp?: string\n /** Status: built-in preset ('sending' | 'sent' | 'read' | 'error') or custom ReactNode */\n status?: React.ReactNode\n /** Size override (defaults to context value from ChatMessage root) */\n size?: ChatMessageSize\n}\n\n// ============================================================================\n// ChatMessage Root\n// ============================================================================\n\nconst ChatMessage = React.forwardRef<HTMLDivElement, ChatMessageRootProps>(\n (\n {\n className,\n role = 'assistant',\n variant = 'bubble',\n color = 'default',\n size = 'default',\n radius = '2xl',\n tail = true,\n typing = false,\n avatarSize,\n actions,\n children,\n ...props\n },\n ref\n ) => {\n const ctx = React.useMemo<ChatMessageContextValue>(\n () => ({ role, variant, color, size, radius, tail, typing, actions }),\n [role, variant, color, size, radius, tail, typing, actions]\n )\n\n const gapClass = avatarSize ? avatarGapMap[avatarSize] : rowGapMap[size]\n\n return (\n <ChatMessageContext.Provider value={ctx}>\n <div\n ref={ref}\n className={cn(\n 'group/message flex items-end',\n gapClass,\n role === 'user' && variant !== 'flat' ? 'flex-row-reverse' : 'flex-row',\n className\n )}\n {...props}\n >\n {children}\n </div>\n </ChatMessageContext.Provider>\n )\n }\n)\nChatMessage.displayName = 'ChatMessage'\n\n// ============================================================================\n// Default AI sparkle icon\n// ============================================================================\n\nfunction DefaultAiIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-3/5 h-3/5\" aria-hidden=\"true\">\n <path d=\"M12 3l1.8 5.4 5.4 1.8-5.4 1.8L12 17.4l-1.8-5.4L4.8 10.2l5.4-1.8z\" />\n <path d=\"M19.5 3.5l.8 2.4 2.4.8-2.4.8L19.5 10l-.8-2.5-2.4-.8 2.4-.8z\" opacity=\".6\" />\n <path d=\"M4.5 14.5l.7 2 2 .7-2 .7L4.5 20l-.7-2-2-.7 2-.7z\" opacity=\".4\" />\n </svg>\n )\n}\n\n// ============================================================================\n// ChatMessageAvatar — wraps Avatar component with chat-specific sizes\n// ============================================================================\n\nconst ChatMessageAvatar = React.forwardRef<HTMLSpanElement, ChatMessageAvatarProps>(\n ({ className, size: avatarSize = 'md', src, alt = 'Avatar', initials, icon }, ref) => (\n <Avatar\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref={ref as any}\n aria-hidden=\"true\"\n className={cn(chatAvatarSizeMap[avatarSize], 'shrink-0', className)}\n >\n {src && <AvatarImage src={src} alt={alt} />}\n <AvatarFallback className={cn('font-semibold', chatAvatarFontMap[avatarSize])}>\n {icon ?? (initials || <DefaultAiIcon />)}\n </AvatarFallback>\n </Avatar>\n )\n)\nChatMessageAvatar.displayName = 'ChatMessageAvatar'\n\n// ============================================================================\n// ChatMessageContent\n// ============================================================================\n\nconst ChatMessageContent = React.forwardRef<HTMLDivElement, ChatMessageContentProps>(\n ({ className, children, ...props }, ref) => {\n const { role, variant, color, size, radius, tail, typing, actions } = React.useContext(ChatMessageContext)\n const isTyping = !!typing\n const typingProps = typeof typing === 'object' ? typing : {}\n\n // Dark bubble backgrounds need inverted typing dot colors\n const isDarkBg = color === 'primary' || color === 'dark'\n const invertDots = variant === 'bubble' && isDarkBg\n\n // flat variant never has a tail (asymmetric corner)\n const effectiveTail = variant === 'flat' ? false : tail\n const radiusClasses = effectiveTail\n ? bubbleRadiusTailMap[radius][role]\n : bubbleRadiusSymMap[radius]\n\n const bubble = (\n <div\n ref={ref}\n className={cn(\n bubbleTextMap[size],\n variant === 'bubble' && 'max-w-[75%]',\n isTyping && [typingMinWidthMap[size], 'text-center'],\n getBubbleColors(color, variant),\n (variant === 'bubble' || variant === 'flat') && bubblePaddingMap[size],\n (variant === 'bubble' || (variant === 'flat' && color === 'muted')) && radiusClasses,\n className\n )}\n {...props}\n >\n {isTyping ? (\n <TypingIndicator\n size={typingSizeMap[size]}\n color=\"muted\"\n {...typingProps}\n className={cn('align-middle', invertDots && '[&>div>div]:bg-current')}\n />\n ) : children}\n </div>\n )\n\n if (!actions) return bubble\n\n return (\n <div className={cn('flex items-end gap-1.5', role === 'user' && variant !== 'flat' ? 'flex-row-reverse' : 'flex-row')}>\n {bubble}\n <div className={cn(\n 'shrink-0 flex items-center gap-1 pb-0.5',\n 'opacity-0 group-hover/message:opacity-100',\n 'transition-opacity duration-normal',\n )}>\n {actions}\n </div>\n </div>\n )\n }\n)\nChatMessageContent.displayName = 'ChatMessageContent'\n\n// ============================================================================\n// ChatMessageFooter\n// ============================================================================\n\nconst ChatMessageFooter = React.forwardRef<HTMLDivElement, ChatMessageFooterProps>(\n (\n {\n className,\n timestamp,\n status,\n role: roleProp,\n size: sizeProp,\n children,\n ...props\n },\n ref\n ) => {\n const ctx = React.useContext(ChatMessageContext)\n const role = roleProp ?? ctx.role\n const size = sizeProp ?? ctx.size\n const variant = ctx.variant\n\n // Resolve status: built-in preset string → label, or pass-through ReactNode\n const statusContent = React.useMemo(() => {\n if (status == null) return null\n if (typeof status === 'string' && status in builtInStatusLabels) {\n const { label, className: cls } = builtInStatusLabels[status]\n return <span className={cls}>{label}</span>\n }\n return status\n }, [status])\n\n return (\n <div\n ref={ref}\n className={cn(\n 'flex items-center gap-1 select-none',\n footerTextMap[size],\n 'text-text-subtle',\n role === 'user' && variant !== 'flat' ? 'justify-end' : 'justify-start',\n className\n )}\n {...props}\n >\n {children}\n {statusContent}\n {timestamp && <span>{timestamp}</span>}\n </div>\n )\n }\n)\nChatMessageFooter.displayName = 'ChatMessageFooter'\n\nexport {\n ChatMessage,\n ChatMessageAvatar,\n ChatMessageContent,\n ChatMessageFooter,\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,206 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/segmented.tsx
7
+ import * as React from "react";
8
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
9
+ import { cva } from "class-variance-authority";
10
+ var SegmentedContext = React.createContext({});
11
+ var useSegmentedContext = () => React.useContext(SegmentedContext);
12
+ var segmentedVariants = cva(
13
+ "inline-flex items-center text-text-subtle",
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: "bg-background-muted gap-1",
18
+ outline: "bg-background border border-border gap-1",
19
+ underline: "bg-transparent border-b border-border gap-0",
20
+ ghost: "bg-transparent gap-1"
21
+ },
22
+ size: {
23
+ sm: "h-8",
24
+ // 32px height
25
+ md: "h-9",
26
+ // 36px height
27
+ default: "h-10",
28
+ // 40px height
29
+ lg: "h-12"
30
+ // 48px height
31
+ },
32
+ radius: {
33
+ none: "rounded-none",
34
+ sm: "rounded-sm",
35
+ base: "rounded",
36
+ default: "rounded-md",
37
+ lg: "rounded-lg",
38
+ xl: "rounded-xl",
39
+ "2xl": "rounded-2xl",
40
+ "3xl": "rounded-3xl",
41
+ full: "rounded-full"
42
+ },
43
+ fontWeight: {
44
+ normal: "[&>*]:font-normal",
45
+ semibold: "[&>*]:font-semibold"
46
+ }
47
+ },
48
+ compoundVariants: [
49
+ // Padding for default/outline/ghost variants
50
+ { variant: "default", className: "p-1" },
51
+ { variant: "outline", className: "p-1" },
52
+ { variant: "ghost", className: "p-1" },
53
+ // Underline has no padding
54
+ { variant: "underline", className: "p-0" }
55
+ ],
56
+ defaultVariants: {
57
+ variant: "default",
58
+ size: "default",
59
+ radius: "default",
60
+ fontWeight: "normal"
61
+ }
62
+ }
63
+ );
64
+ var segmentedItemVariants = cva(
65
+ [
66
+ "inline-flex items-center justify-center whitespace-nowrap h-full",
67
+ "transition-all duration-micro ease-out",
68
+ "focus-visible:focus-ring",
69
+ "disabled:pointer-events-none disabled:opacity-50"
70
+ ].join(" "),
71
+ {
72
+ variants: {
73
+ variant: {
74
+ // Default: light background when selected, text emphasis on hover
75
+ default: [
76
+ "hover:text-foreground",
77
+ "data-[state=checked]:bg-background data-[state=checked]:text-foreground",
78
+ "data-[state=checked]:shadow-sm"
79
+ ].join(" "),
80
+ // Outline: gray background when selected
81
+ outline: [
82
+ "data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground",
83
+ "hover:text-foreground hover:bg-background-muted"
84
+ ].join(" "),
85
+ // Underline: bottom border indicator (Stripe/GitHub style)
86
+ underline: [
87
+ "border-b-2 border-transparent -mb-px",
88
+ "hover:text-foreground hover:border-border",
89
+ "data-[state=checked]:text-foreground data-[state=checked]:border-foreground"
90
+ ].join(" "),
91
+ // Ghost: pill background only on selected (Notion/Figma style)
92
+ ghost: [
93
+ "hover:text-foreground hover:bg-background-muted",
94
+ "data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground"
95
+ ].join(" ")
96
+ },
97
+ size: {
98
+ sm: "text-xs",
99
+ // 12px
100
+ md: "text-sm",
101
+ // 13px
102
+ default: "text-sm",
103
+ // 13px
104
+ lg: "text-md"
105
+ // 14px
106
+ },
107
+ radius: {
108
+ none: "rounded-none",
109
+ sm: "rounded-sm",
110
+ base: "rounded",
111
+ default: "rounded-md",
112
+ lg: "rounded-md",
113
+ xl: "rounded-lg",
114
+ "2xl": "rounded-xl",
115
+ "3xl": "rounded-2xl",
116
+ full: "rounded-full"
117
+ },
118
+ // Content type determines padding and aspect ratio
119
+ contentType: {
120
+ // Icon only: square aspect ratio like IconButton
121
+ icon: "aspect-square",
122
+ // Icon + text: rectangular (gap is set via compoundVariants)
123
+ "icon-text": "",
124
+ // Text only: standard button padding
125
+ text: ""
126
+ }
127
+ },
128
+ compoundVariants: [
129
+ // Icon + text - same padding rules as Button/Toggle
130
+ { contentType: "icon-text", size: "sm", className: "px-3 gap-2" },
131
+ // 12px padding, 8px gap
132
+ { contentType: "icon-text", size: "md", className: "px-3.5 gap-2" },
133
+ // 14px padding, 8px gap
134
+ { contentType: "icon-text", size: "default", className: "px-4 gap-2" },
135
+ // 16px padding, 8px gap
136
+ { contentType: "icon-text", size: "lg", className: "px-6 gap-2" },
137
+ // 24px padding, 8px gap
138
+ // Text only - same padding rules as Button/Toggle
139
+ { contentType: "text", size: "sm", className: "px-3.5" },
140
+ // 14px
141
+ { contentType: "text", size: "md", className: "px-3.5" },
142
+ // 14px
143
+ { contentType: "text", size: "default", className: "px-4" },
144
+ // 16px
145
+ { contentType: "text", size: "lg", className: "px-6" },
146
+ // 24px
147
+ // Underline variant has no rounded corners
148
+ { variant: "underline", className: "rounded-none" }
149
+ ],
150
+ defaultVariants: {
151
+ variant: "default",
152
+ size: "default",
153
+ radius: "default",
154
+ contentType: "text"
155
+ }
156
+ }
157
+ );
158
+ var Segmented = React.forwardRef(({ className, variant, size, radius, fontWeight, ...props }, ref) => {
159
+ const resolvedFontWeight = fontWeight ?? "normal";
160
+ return /* @__PURE__ */ React.createElement(SegmentedContext.Provider, { value: { variant: variant || "default", size: size || "default", radius: radius || "default" } }, /* @__PURE__ */ React.createElement(
161
+ RadioGroupPrimitive.Root,
162
+ {
163
+ className: cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className),
164
+ ...props,
165
+ ref
166
+ }
167
+ ));
168
+ });
169
+ Segmented.displayName = "Segmented";
170
+ var iconSizeClasses = {
171
+ sm: "[&>svg]:icon-xs",
172
+ // 14px
173
+ md: "[&>svg]:icon-sm",
174
+ // 16px
175
+ default: "[&>svg]:icon-sm",
176
+ // 16px
177
+ lg: "[&>svg]:icon-sm"
178
+ // 16px
179
+ };
180
+ var SegmentedItem = React.forwardRef(({ className, children, size, radius, contentType, ...props }, ref) => {
181
+ const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext();
182
+ const resolvedSize = size || contextSize || "default";
183
+ const resolvedRadius = radius || contextRadius || "default";
184
+ return /* @__PURE__ */ React.createElement(
185
+ RadioGroupPrimitive.Item,
186
+ {
187
+ ref,
188
+ className: cn(
189
+ segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),
190
+ iconSizeClasses[resolvedSize],
191
+ className
192
+ ),
193
+ ...props
194
+ },
195
+ children
196
+ );
197
+ });
198
+ SegmentedItem.displayName = "SegmentedItem";
199
+
200
+ export {
201
+ segmentedVariants,
202
+ segmentedItemVariants,
203
+ Segmented,
204
+ SegmentedItem
205
+ };
206
+ //# sourceMappingURL=chunk-RKSB2N5L.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/segmented.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// Context to pass variant and size from Segmented to SegmentedItem\ntype SegmentedContextValue = {\n variant?: 'default' | 'outline' | 'underline' | 'ghost'\n size?: 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst SegmentedContext = React.createContext<SegmentedContextValue>({})\nconst useSegmentedContext = () => React.useContext(SegmentedContext)\n\nconst segmentedVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n default: 'bg-background-muted gap-1',\n outline: 'bg-background border border-border gap-1',\n underline: 'bg-transparent border-b border-border gap-0',\n ghost: 'bg-transparent gap-1',\n },\n size: {\n sm: 'h-8', // 32px height\n md: 'h-9', // 36px height\n default: 'h-10', // 40px height\n lg: 'h-12', // 48px height\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n fontWeight: {\n normal: '[&>*]:font-normal',\n semibold: '[&>*]:font-semibold',\n },\n },\n compoundVariants: [\n // Padding for default/outline/ghost variants\n { variant: 'default', className: 'p-1' },\n { variant: 'outline', className: 'p-1' },\n { variant: 'ghost', className: 'p-1' },\n // Underline has no padding\n { variant: 'underline', className: 'p-0' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst segmentedItemVariants = cva(\n [\n 'inline-flex items-center justify-center whitespace-nowrap h-full',\n 'transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n // Default: light background when selected, text emphasis on hover\n default: [\n 'hover:text-foreground',\n 'data-[state=checked]:bg-background data-[state=checked]:text-foreground',\n 'data-[state=checked]:shadow-sm',\n ].join(' '),\n // Outline: gray background when selected\n outline: [\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n 'hover:text-foreground hover:bg-background-muted',\n ].join(' '),\n // Underline: bottom border indicator (Stripe/GitHub style)\n underline: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border',\n 'data-[state=checked]:text-foreground data-[state=checked]:border-foreground',\n ].join(' '),\n // Ghost: pill background only on selected (Notion/Figma style)\n ghost: [\n 'hover:text-foreground hover:bg-background-muted',\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n ].join(' '),\n },\n size: {\n sm: 'text-xs', // 12px\n md: 'text-sm', // 13px\n default: 'text-sm', // 13px\n lg: 'text-md', // 14px\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n // Content type determines padding and aspect ratio\n contentType: {\n // Icon only: square aspect ratio like IconButton\n icon: 'aspect-square',\n // Icon + text: rectangular (gap is set via compoundVariants)\n 'icon-text': '',\n // Text only: standard button padding\n text: '',\n },\n },\n compoundVariants: [\n // Icon + text - same padding rules as Button/Toggle\n { contentType: 'icon-text', size: 'sm', className: 'px-3 gap-2' }, // 12px padding, 8px gap\n { contentType: 'icon-text', size: 'md', className: 'px-3.5 gap-2' }, // 14px padding, 8px gap\n { contentType: 'icon-text', size: 'default', className: 'px-4 gap-2' }, // 16px padding, 8px gap\n { contentType: 'icon-text', size: 'lg', className: 'px-6 gap-2' }, // 24px padding, 8px gap\n // Text only - same padding rules as Button/Toggle\n { contentType: 'text', size: 'sm', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'md', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'default', className: 'px-4' }, // 16px\n { contentType: 'text', size: 'lg', className: 'px-6' }, // 24px\n // Underline variant has no rounded corners\n { variant: 'underline', className: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n contentType: 'text',\n },\n }\n)\n\nexport interface SegmentedProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n VariantProps<typeof segmentedVariants> {}\n\nconst Segmented = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n SegmentedProps\n>(({ className, variant, size, radius, fontWeight, ...props }, ref) => {\n // All variants default to normal font weight\n const resolvedFontWeight = fontWeight ?? 'normal'\n\n return (\n <SegmentedContext.Provider value={{ variant: variant || 'default', size: size || 'default', radius: radius || 'default' }}>\n <RadioGroupPrimitive.Root\n className={cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className)}\n {...props}\n ref={ref}\n />\n </SegmentedContext.Provider>\n )\n})\nSegmented.displayName = 'Segmented'\n\n// Icon size for segmented control (4-step scale, Icon+Text mode)\n// sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nexport interface SegmentedItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n Omit<VariantProps<typeof segmentedItemVariants>, 'variant'> {}\n\nconst SegmentedItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n SegmentedItemProps\n>(({ className, children, size, radius, contentType, ...props }, ref) => {\n const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext()\n const resolvedSize = size || contextSize || 'default'\n const resolvedRadius = radius || contextRadius || 'default'\n\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </RadioGroupPrimitive.Item>\n )\n})\nSegmentedItem.displayName = 'SegmentedItem'\n\nexport { Segmented, SegmentedItem, segmentedVariants, segmentedItemVariants }\n"],"mappings":";;;;;;AAEA,YAAY,WAAW;AACvB,YAAY,yBAAyB;AACrC,SAAS,WAA8B;AASvC,IAAM,mBAAyB,oBAAqC,CAAC,CAAC;AACtE,IAAM,sBAAsB,MAAY,iBAAW,gBAAgB;AAEnE,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,QACX,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,IAAI;AAAA;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,YAAY;AAAA,QACV,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,WAAW,WAAW,MAAM;AAAA,MACvC,EAAE,SAAS,WAAW,WAAW,MAAM;AAAA,MACvC,EAAE,SAAS,SAAS,WAAW,MAAM;AAAA;AAAA,MAErC,EAAE,SAAS,aAAa,WAAW,MAAM;AAAA,IAC3C;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA;AAAA,QAEP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA;AAAA,QAEV,SAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA;AAAA,QAEV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA;AAAA,QAEV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,IAAI;AAAA;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA;AAAA,MAEA,aAAa;AAAA;AAAA,QAEX,MAAM;AAAA;AAAA,QAEN,aAAa;AAAA;AAAA,QAEb,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA;AAAA,MAEhB,EAAE,aAAa,aAAa,MAAM,MAAM,WAAW,aAAa;AAAA;AAAA,MAChE,EAAE,aAAa,aAAa,MAAM,MAAM,WAAW,eAAe;AAAA;AAAA,MAClE,EAAE,aAAa,aAAa,MAAM,WAAW,WAAW,aAAa;AAAA;AAAA,MACrE,EAAE,aAAa,aAAa,MAAM,MAAM,WAAW,aAAa;AAAA;AAAA;AAAA,MAEhE,EAAE,aAAa,QAAQ,MAAM,MAAM,WAAW,SAAS;AAAA;AAAA,MACvD,EAAE,aAAa,QAAQ,MAAM,MAAM,WAAW,SAAS;AAAA;AAAA,MACvD,EAAE,aAAa,QAAQ,MAAM,WAAW,WAAW,OAAO;AAAA;AAAA,MAC1D,EAAE,aAAa,QAAQ,MAAM,MAAM,WAAW,OAAO;AAAA;AAAA;AAAA,MAErD,EAAE,SAAS,aAAa,WAAW,eAAe;AAAA,IACpD;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAMA,IAAM,YAAkB,iBAGtB,CAAC,EAAE,WAAW,SAAS,MAAM,QAAQ,YAAY,GAAG,MAAM,GAAG,QAAQ;AAErE,QAAM,qBAAqB,cAAc;AAEzC,SACE,oCAAC,iBAAiB,UAAjB,EAA0B,OAAO,EAAE,SAAS,WAAW,WAAW,MAAM,QAAQ,WAAW,QAAQ,UAAU,UAAU,KACtH;AAAA,IAAqB;AAAA,IAApB;AAAA,MACC,WAAW,GAAG,kBAAkB,EAAE,SAAS,MAAM,QAAQ,YAAY,mBAAmB,CAAC,GAAG,SAAS;AAAA,MACpG,GAAG;AAAA,MACJ;AAAA;AAAA,EACF,CACF;AAEJ,CAAC;AACD,UAAU,cAAc;AAIxB,IAAM,kBAAkB;AAAA,EACtB,IAAI;AAAA;AAAA,EACJ,IAAI;AAAA;AAAA,EACJ,SAAS;AAAA;AAAA,EACT,IAAI;AAAA;AACN;AAMA,IAAM,gBAAsB,iBAG1B,CAAC,EAAE,WAAW,UAAU,MAAM,QAAQ,aAAa,GAAG,MAAM,GAAG,QAAQ;AACvE,QAAM,EAAE,SAAS,MAAM,aAAa,QAAQ,cAAc,IAAI,oBAAoB;AAClF,QAAM,eAAe,QAAQ,eAAe;AAC5C,QAAM,iBAAiB,UAAU,iBAAiB;AAElD,SACE;AAAA,IAAqB;AAAA,IAApB;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT,sBAAsB,EAAE,SAAS,MAAM,cAAc,QAAQ,gBAAgB,YAAY,CAAC;AAAA,QAC1F,gBAAgB,YAAY;AAAA,QAC5B;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,IAEH;AAAA,EACH;AAEJ,CAAC;AACD,cAAc,cAAc;","names":[]}