@7onic-ui/react 0.3.8 → 0.3.10

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 (171) hide show
  1. package/README.md +2 -2
  2. package/dist/chart.js +1 -1
  3. package/dist/chart.js.map +1 -1
  4. package/dist/chart.mjs +4 -10
  5. package/dist/chart.mjs.map +1 -1
  6. package/dist/chunk-234NAXGV.mjs +252 -0
  7. package/dist/chunk-234NAXGV.mjs.map +1 -0
  8. package/dist/chunk-53MIUPSY.mjs +13 -0
  9. package/dist/chunk-53MIUPSY.mjs.map +1 -0
  10. package/dist/chunk-BN5BEA3V.mjs +195 -0
  11. package/dist/chunk-BN5BEA3V.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-DRVHHEAY.mjs +145 -0
  23. package/dist/chunk-DRVHHEAY.mjs.map +1 -0
  24. package/dist/chunk-DTLNWOTR.mjs +482 -0
  25. package/dist/chunk-DTLNWOTR.mjs.map +1 -0
  26. package/dist/chunk-DYYQOHQR.mjs +214 -0
  27. package/dist/chunk-DYYQOHQR.mjs.map +1 -0
  28. package/dist/chunk-FHUAH6AJ.mjs +93 -0
  29. package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
  30. package/dist/chunk-GD4YE5AE.mjs +209 -0
  31. package/dist/chunk-GD4YE5AE.mjs.map +1 -0
  32. package/dist/chunk-GRCJ35DX.mjs +144 -0
  33. package/dist/chunk-GRCJ35DX.mjs.map +1 -0
  34. package/dist/chunk-HHX4GABH.mjs +129 -0
  35. package/dist/chunk-HHX4GABH.mjs.map +1 -0
  36. package/dist/chunk-IPCIC2BI.mjs +148 -0
  37. package/dist/chunk-IPCIC2BI.mjs.map +1 -0
  38. package/dist/chunk-IY3R2VGB.mjs +272 -0
  39. package/dist/chunk-IY3R2VGB.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-LJJ6K4IU.mjs +318 -0
  45. package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
  46. package/dist/chunk-MRUVGHGP.mjs +375 -0
  47. package/dist/chunk-MRUVGHGP.mjs.map +1 -0
  48. package/dist/chunk-N4K2BDGM.mjs +153 -0
  49. package/dist/chunk-N4K2BDGM.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-RKSB2N5L.mjs +206 -0
  59. package/dist/chunk-RKSB2N5L.mjs.map +1 -0
  60. package/dist/chunk-S4DGVKBK.mjs +151 -0
  61. package/dist/chunk-S4DGVKBK.mjs.map +1 -0
  62. package/dist/chunk-S4T4PU7F.mjs +114 -0
  63. package/dist/chunk-S4T4PU7F.mjs.map +1 -0
  64. package/dist/chunk-SZPZOGPC.mjs +394 -0
  65. package/dist/chunk-SZPZOGPC.mjs.map +1 -0
  66. package/dist/chunk-T546XBQG.mjs +443 -0
  67. package/dist/chunk-T546XBQG.mjs.map +1 -0
  68. package/dist/chunk-UWTT5AE6.mjs +145 -0
  69. package/dist/chunk-UWTT5AE6.mjs.map +1 -0
  70. package/dist/chunk-V5UFWYFI.mjs +255 -0
  71. package/dist/chunk-V5UFWYFI.mjs.map +1 -0
  72. package/dist/chunk-VUPGBB5X.mjs +150 -0
  73. package/dist/chunk-VUPGBB5X.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-WWSN5YME.mjs +222 -0
  77. package/dist/chunk-WWSN5YME.mjs.map +1 -0
  78. package/dist/chunk-XK52LYR4.mjs +182 -0
  79. package/dist/chunk-XK52LYR4.mjs.map +1 -0
  80. package/dist/chunk-YIAH6KHV.mjs +164 -0
  81. package/dist/chunk-YIAH6KHV.mjs.map +1 -0
  82. package/dist/chunk-Z6JWWCNL.mjs +108 -0
  83. package/dist/chunk-Z6JWWCNL.mjs.map +1 -0
  84. package/dist/chunk-ZDRUTJ4T.mjs +119 -0
  85. package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
  86. package/dist/components/accordion.mjs +19 -0
  87. package/dist/components/accordion.mjs.map +1 -0
  88. package/dist/components/alert.mjs +15 -0
  89. package/dist/components/alert.mjs.map +1 -0
  90. package/dist/components/avatar.mjs +23 -0
  91. package/dist/components/avatar.mjs.map +1 -0
  92. package/dist/components/badge.mjs +11 -0
  93. package/dist/components/badge.mjs.map +1 -0
  94. package/dist/components/breadcrumb.mjs +23 -0
  95. package/dist/components/breadcrumb.mjs.map +1 -0
  96. package/dist/components/button-group.mjs +11 -0
  97. package/dist/components/button-group.mjs.map +1 -0
  98. package/dist/components/button.mjs +12 -0
  99. package/dist/components/button.mjs.map +1 -0
  100. package/dist/components/card.mjs +25 -0
  101. package/dist/components/card.mjs.map +1 -0
  102. package/dist/components/chat-input.mjs +15 -0
  103. package/dist/components/chat-input.mjs.map +1 -0
  104. package/dist/components/chat-message.mjs +17 -0
  105. package/dist/components/chat-message.mjs.map +1 -0
  106. package/dist/components/checkbox.mjs +12 -0
  107. package/dist/components/checkbox.mjs.map +1 -0
  108. package/dist/components/divider.mjs +11 -0
  109. package/dist/components/divider.mjs.map +1 -0
  110. package/dist/components/drawer.mjs +33 -0
  111. package/dist/components/drawer.mjs.map +1 -0
  112. package/dist/components/dropdown.mjs +35 -0
  113. package/dist/components/dropdown.mjs.map +1 -0
  114. package/dist/components/field.mjs +17 -0
  115. package/dist/components/field.mjs.map +1 -0
  116. package/dist/components/icon-button.mjs +12 -0
  117. package/dist/components/icon-button.mjs.map +1 -0
  118. package/dist/components/input.mjs +12 -0
  119. package/dist/components/input.mjs.map +1 -0
  120. package/dist/components/metric-card.mjs +23 -0
  121. package/dist/components/metric-card.mjs.map +1 -0
  122. package/dist/components/modal.mjs +57 -0
  123. package/dist/components/modal.mjs.map +1 -0
  124. package/dist/components/navigation-menu.mjs +27 -0
  125. package/dist/components/navigation-menu.mjs.map +1 -0
  126. package/dist/components/pagination.mjs +33 -0
  127. package/dist/components/pagination.mjs.map +1 -0
  128. package/dist/components/popover.mjs +23 -0
  129. package/dist/components/popover.mjs.map +1 -0
  130. package/dist/components/progress.mjs +11 -0
  131. package/dist/components/progress.mjs.map +1 -0
  132. package/dist/components/quick-reply.mjs +15 -0
  133. package/dist/components/quick-reply.mjs.map +1 -0
  134. package/dist/components/radio-group.mjs +16 -0
  135. package/dist/components/radio-group.mjs.map +1 -0
  136. package/dist/components/segmented.mjs +15 -0
  137. package/dist/components/segmented.mjs.map +1 -0
  138. package/dist/components/select.mjs +23 -0
  139. package/dist/components/select.mjs.map +1 -0
  140. package/dist/components/skeleton.mjs +11 -0
  141. package/dist/components/skeleton.mjs.map +1 -0
  142. package/dist/components/slider.mjs +11 -0
  143. package/dist/components/slider.mjs.map +1 -0
  144. package/dist/components/spinner.mjs +11 -0
  145. package/dist/components/spinner.mjs.map +1 -0
  146. package/dist/components/switch.mjs +12 -0
  147. package/dist/components/switch.mjs.map +1 -0
  148. package/dist/components/table.mjs +23 -0
  149. package/dist/components/table.mjs.map +1 -0
  150. package/dist/components/tabs.mjs +19 -0
  151. package/dist/components/tabs.mjs.map +1 -0
  152. package/dist/components/textarea.mjs +12 -0
  153. package/dist/components/textarea.mjs.map +1 -0
  154. package/dist/components/toast.mjs +13 -0
  155. package/dist/components/toast.mjs.map +1 -0
  156. package/dist/components/toggle-group.mjs +15 -0
  157. package/dist/components/toggle-group.mjs.map +1 -0
  158. package/dist/components/toggle.mjs +11 -0
  159. package/dist/components/toggle.mjs.map +1 -0
  160. package/dist/components/tooltip.mjs +21 -0
  161. package/dist/components/tooltip.mjs.map +1 -0
  162. package/dist/components/typing-indicator.mjs +11 -0
  163. package/dist/components/typing-indicator.mjs.map +1 -0
  164. package/dist/index.js +22 -7
  165. package/dist/index.js.map +1 -1
  166. package/dist/index.mjs +296 -7521
  167. package/dist/index.mjs.map +1 -1
  168. package/llms.txt +29 -25
  169. package/package.json +4 -3
  170. package/dist/chart.d.mts +0 -147
  171. package/dist/index.d.mts +0 -1535
@@ -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-234NAXGV.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\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\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,13 @@
1
+ "use client";
2
+
3
+ // src/lib/utils.ts
4
+ import { clsx } from "clsx";
5
+ import { twMerge } from "tailwind-merge";
6
+ function cn(...inputs) {
7
+ return twMerge(clsx(inputs));
8
+ }
9
+
10
+ export {
11
+ cn
12
+ };
13
+ //# sourceMappingURL=chunk-53MIUPSY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Combines class names with Tailwind CSS class merging\n * @param inputs - Class values to combine\n * @returns Merged class string\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";;;AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAOjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
@@ -0,0 +1,195 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/table.tsx
7
+ import * as React from "react";
8
+ import { cva } from "class-variance-authority";
9
+ var TableContext = React.createContext({ size: "default", variant: "default", stickyHeader: false });
10
+ var cellPaddingMap = {
11
+ sm: "px-3 py-2 text-sm",
12
+ default: "px-4 py-3 text-sm",
13
+ lg: "px-6 py-4 text-base"
14
+ };
15
+ var headPaddingMap = {
16
+ sm: "px-3 py-2 text-xs",
17
+ default: "px-4 py-3 text-xs",
18
+ lg: "px-6 py-3.5 text-sm"
19
+ };
20
+ var checkboxPaddingMap = {
21
+ sm: "[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0",
22
+ default: "[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0",
23
+ lg: "[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0"
24
+ };
25
+ var tableVariants = cva(
26
+ "w-full caption-bottom text-sm",
27
+ {
28
+ variants: {
29
+ variant: {
30
+ default: "",
31
+ bordered: "border border-border",
32
+ striped: ""
33
+ }
34
+ },
35
+ defaultVariants: {
36
+ variant: "default"
37
+ }
38
+ }
39
+ );
40
+ var Table = React.forwardRef(
41
+ ({ className, size = "default", variant = "default", stickyHeader = false, wrapperClassName, ...props }, ref) => /* @__PURE__ */ React.createElement(TableContext.Provider, { value: { size, variant, stickyHeader } }, /* @__PURE__ */ React.createElement("div", { className: cn("relative w-full overflow-auto", wrapperClassName) }, /* @__PURE__ */ React.createElement(
42
+ "table",
43
+ {
44
+ ref,
45
+ className: cn(tableVariants({ variant }), className),
46
+ ...props
47
+ }
48
+ )))
49
+ );
50
+ Table.displayName = "Table";
51
+ var TableHeader = React.forwardRef(({ className, ...props }, ref) => {
52
+ const { stickyHeader } = React.useContext(TableContext);
53
+ return /* @__PURE__ */ React.createElement(
54
+ "thead",
55
+ {
56
+ ref,
57
+ className: cn(
58
+ "[&_tr]:border-b [&_tr]:border-border",
59
+ stickyHeader && "sticky top-0 z-10 bg-background",
60
+ className
61
+ ),
62
+ ...props
63
+ }
64
+ );
65
+ });
66
+ TableHeader.displayName = "TableHeader";
67
+ var TableBody = React.forwardRef(({ className, ...props }, ref) => {
68
+ const { variant } = React.useContext(TableContext);
69
+ return /* @__PURE__ */ React.createElement(
70
+ "tbody",
71
+ {
72
+ ref,
73
+ className: cn(
74
+ "[&_tr:last-child]:border-b-0",
75
+ variant === "striped" && "[&_tr:nth-child(even)]:bg-background-muted",
76
+ className
77
+ ),
78
+ ...props
79
+ }
80
+ );
81
+ });
82
+ TableBody.displayName = "TableBody";
83
+ var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
84
+ "tfoot",
85
+ {
86
+ ref,
87
+ className: cn(
88
+ "border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0",
89
+ className
90
+ ),
91
+ ...props
92
+ }
93
+ ));
94
+ TableFooter.displayName = "TableFooter";
95
+ var TableRow = React.forwardRef(
96
+ ({ className, interactive = false, selected = false, ...props }, ref) => /* @__PURE__ */ React.createElement(
97
+ "tr",
98
+ {
99
+ ref,
100
+ "data-selected": selected || void 0,
101
+ className: cn(
102
+ "border-b border-border transition-colors duration-fast",
103
+ interactive && "hover:bg-background-muted/50 cursor-pointer",
104
+ className
105
+ ),
106
+ ...props
107
+ }
108
+ )
109
+ );
110
+ TableRow.displayName = "TableRow";
111
+ var defaultSortIcons = {
112
+ asc: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 15l7-7 7 7" })),
113
+ desc: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })),
114
+ default: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }))
115
+ };
116
+ var TableHead = React.forwardRef(
117
+ ({ className, align = "left", sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {
118
+ const { size } = React.useContext(TableContext);
119
+ const icons = { ...defaultSortIcons, ...sortIcon };
120
+ const content = sortable ? /* @__PURE__ */ React.createElement(
121
+ "button",
122
+ {
123
+ type: "button",
124
+ className: "inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group",
125
+ onClick: onSort
126
+ },
127
+ children,
128
+ /* @__PURE__ */ React.createElement("span", { className: cn(
129
+ "shrink-0 transition-colors duration-fast",
130
+ sortDirection ? "text-foreground" : "text-text-muted"
131
+ ) }, sortDirection === "asc" ? icons.asc : sortDirection === "desc" ? icons.desc : icons.default)
132
+ ) : children;
133
+ return /* @__PURE__ */ React.createElement(
134
+ "th",
135
+ {
136
+ ref,
137
+ className: cn(
138
+ "text-left align-middle font-semibold text-text-muted whitespace-nowrap",
139
+ headPaddingMap[size],
140
+ checkboxPaddingMap[size],
141
+ align === "center" && "text-center",
142
+ align === "right" && "text-right",
143
+ sortable && "select-none",
144
+ className
145
+ ),
146
+ "aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : void 0,
147
+ ...props
148
+ },
149
+ content
150
+ );
151
+ }
152
+ );
153
+ TableHead.displayName = "TableHead";
154
+ var TableCell = React.forwardRef(
155
+ ({ className, align = "left", ...props }, ref) => {
156
+ const { size } = React.useContext(TableContext);
157
+ return /* @__PURE__ */ React.createElement(
158
+ "td",
159
+ {
160
+ ref,
161
+ className: cn(
162
+ "text-foreground align-middle",
163
+ cellPaddingMap[size],
164
+ checkboxPaddingMap[size],
165
+ align === "center" && "text-center",
166
+ align === "right" && "text-right",
167
+ className
168
+ ),
169
+ ...props
170
+ }
171
+ );
172
+ }
173
+ );
174
+ TableCell.displayName = "TableCell";
175
+ var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
176
+ "caption",
177
+ {
178
+ ref,
179
+ className: cn("mt-4 text-sm text-text-muted", className),
180
+ ...props
181
+ }
182
+ ));
183
+ TableCaption.displayName = "TableCaption";
184
+
185
+ export {
186
+ Table,
187
+ TableHeader,
188
+ TableBody,
189
+ TableFooter,
190
+ TableRow,
191
+ TableHead,
192
+ TableCell,
193
+ TableCaption
194
+ };
195
+ //# sourceMappingURL=chunk-BN5BEA3V.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/table.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// Size variants for table density\ntype TableSize = 'sm' | 'default' | 'lg'\n\n// Visual style variants\ntype TableVariant = 'default' | 'bordered' | 'striped'\n\n// Root context — set at Root, consumed by children\nconst TableContext = React.createContext<{\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}>({ size: 'default', variant: 'default', stickyHeader: false })\n\n// Cell padding per size\nconst cellPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-sm',\n default: 'px-4 py-3 text-sm',\n lg: 'px-6 py-4 text-base',\n}\n\n// Head cell padding per size\nconst headPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-xs',\n default: 'px-4 py-3 text-xs',\n lg: 'px-6 py-3.5 text-sm',\n}\n\n// Checkbox column padding override per size (right padding removed — next column's left padding handles the gap)\nconst checkboxPaddingMap: Record<TableSize, string> = {\n sm: '[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0',\n default: '[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0',\n lg: '[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0',\n}\n\nconst tableVariants = cva(\n 'w-full caption-bottom text-sm',\n {\n variants: {\n variant: {\n default: '',\n bordered: 'border border-border',\n striped: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\n// ─── Root ────────────────────────────────────────────────────────\nexport interface TableProps\n extends React.HTMLAttributes<HTMLTableElement>,\n VariantProps<typeof tableVariants> {\n /** Table density */\n size?: TableSize\n /** Visual style */\n variant?: TableVariant\n /** Sticky header when scrolling */\n stickyHeader?: boolean\n /** Additional className for the scroll wrapper (e.g. max-h-[400px]) */\n wrapperClassName?: string\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, size = 'default', variant = 'default', stickyHeader = false, wrapperClassName, ...props }, ref) => (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className={cn('relative w-full overflow-auto', wrapperClassName)}>\n <table\n ref={ref}\n className={cn(tableVariants({ variant }), className)}\n {...props}\n />\n </div>\n </TableContext.Provider>\n )\n)\nTable.displayName = 'Table'\n\n// ─── Header ──────────────────────────────────────────────────────\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { stickyHeader } = React.useContext(TableContext)\n return (\n <thead\n ref={ref}\n className={cn(\n '[&_tr]:border-b [&_tr]:border-border',\n stickyHeader && 'sticky top-0 z-10 bg-background',\n className\n )}\n {...props}\n />\n )\n})\nTableHeader.displayName = 'TableHeader'\n\n// ─── Body ────────────────────────────────────────────────────────\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { variant } = React.useContext(TableContext)\n return (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-b-0',\n variant === 'striped' && '[&_tr:nth-child(even)]:bg-background-muted',\n className\n )}\n {...props}\n />\n )\n})\nTableBody.displayName = 'TableBody'\n\n// ─── Footer ──────────────────────────────────────────────────────\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = 'TableFooter'\n\n// ─── Row ─────────────────────────────────────────────────────────\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Enable hover highlight */\n interactive?: boolean\n /** Selected state background */\n selected?: boolean\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, interactive = false, selected = false, ...props }, ref) => (\n <tr\n ref={ref}\n data-selected={selected || undefined}\n className={cn(\n 'border-b border-border transition-colors duration-fast',\n interactive && 'hover:bg-background-muted/50 cursor-pointer',\n className\n )}\n {...props}\n />\n )\n)\nTableRow.displayName = 'TableRow'\n\n// ─── Head Cell ───────────────────────────────────────────────────\ntype SortDirection = 'asc' | 'desc' | null\n\n// Default sort icons\nconst defaultSortIcons = {\n asc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ),\n desc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ),\n default: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n ),\n}\n\nexport interface SortIconSet {\n /** Icon for ascending state */\n asc?: React.ReactNode\n /** Icon for descending state */\n desc?: React.ReactNode\n /** Icon for unsorted (default) state */\n default?: React.ReactNode\n}\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Enable sort indicator */\n sortable?: boolean\n /** Current sort direction */\n sortDirection?: SortDirection\n /** Sort click handler */\n onSort?: () => void\n /** Custom sort icons (overrides built-in icons) */\n sortIcon?: SortIconSet\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, align = 'left', sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n const icons = { ...defaultSortIcons, ...sortIcon }\n\n const content = sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group\"\n onClick={onSort}\n >\n {children}\n <span className={cn(\n 'shrink-0 transition-colors duration-fast',\n sortDirection ? 'text-foreground' : 'text-text-muted'\n )}>\n {sortDirection === 'asc' ? icons.asc\n : sortDirection === 'desc' ? icons.desc\n : icons.default}\n </span>\n </button>\n ) : children\n\n return (\n <th\n ref={ref}\n className={cn(\n 'text-left align-middle font-semibold text-text-muted whitespace-nowrap',\n headPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n sortable && 'select-none',\n className\n )}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : undefined}\n {...props}\n >\n {content}\n </th>\n )\n }\n)\nTableHead.displayName = 'TableHead'\n\n// ─── Data Cell ───────────────────────────────────────────────────\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, align = 'left', ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n return (\n <td\n ref={ref}\n className={cn(\n 'text-foreground align-middle',\n cellPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n className\n )}\n {...props}\n />\n )\n }\n)\nTableCell.displayName = 'TableCell'\n\n// ─── Caption ─────────────────────────────────────────────────────\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-text-muted', className)}\n {...props}\n />\n))\nTableCaption.displayName = 'TableCaption'\n\nexport type { TableSize, TableVariant, SortDirection }\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n}\n"],"mappings":"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","names":[]}