@humain/ui 2.1.63 → 2.1.65

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 (160) hide show
  1. package/dist/components/organisms/ai/AIToolCall/AIToolCall.d.ts +9 -3
  2. package/dist/components/organisms/ai/AIToolRun/index.d.ts +1 -1
  3. package/dist/components/organisms/ai/AIToolRun/validation.d.ts +24 -3
  4. package/dist/components/organisms/ai/_shared/format-ai-duration.d.ts +1 -0
  5. package/dist/components/organisms/ai/_shared/workflow-step-renderer.d.ts +1 -0
  6. package/dist/index.js +52 -52
  7. package/dist/index151.js +1 -1
  8. package/dist/index174.js +7 -339
  9. package/dist/index174.js.map +1 -1
  10. package/dist/index175.js +310 -137
  11. package/dist/index175.js.map +1 -1
  12. package/dist/index176.js +148 -174
  13. package/dist/index176.js.map +1 -1
  14. package/dist/index177.js +186 -78
  15. package/dist/index177.js.map +1 -1
  16. package/dist/index178.js +74 -124
  17. package/dist/index178.js.map +1 -1
  18. package/dist/index179.js +133 -1
  19. package/dist/index179.js.map +1 -0
  20. package/dist/index180.js +2 -201
  21. package/dist/index181.js +201 -0
  22. package/dist/{index180.js.map → index181.js.map} +1 -1
  23. package/dist/index183.js +130 -166
  24. package/dist/index183.js.map +1 -1
  25. package/dist/index184.js +195 -983
  26. package/dist/index184.js.map +1 -1
  27. package/dist/index185.js +1069 -369
  28. package/dist/index185.js.map +1 -1
  29. package/dist/index186.js +395 -197
  30. package/dist/index186.js.map +1 -1
  31. package/dist/index187.js +198 -243
  32. package/dist/index187.js.map +1 -1
  33. package/dist/index188.js +263 -3
  34. package/dist/index188.js.map +1 -1
  35. package/dist/index189.js +3 -209
  36. package/dist/index189.js.map +1 -1
  37. package/dist/index190.js +190 -777
  38. package/dist/index190.js.map +1 -1
  39. package/dist/index191.js +771 -252
  40. package/dist/index191.js.map +1 -1
  41. package/dist/index192.js +250 -65
  42. package/dist/index192.js.map +1 -1
  43. package/dist/index193.js +72 -523
  44. package/dist/index193.js.map +1 -1
  45. package/dist/index194.js +537 -144
  46. package/dist/index194.js.map +1 -1
  47. package/dist/index195.js +139 -720
  48. package/dist/index195.js.map +1 -1
  49. package/dist/index196.js +707 -167
  50. package/dist/index196.js.map +1 -1
  51. package/dist/index197.js +175 -151
  52. package/dist/index197.js.map +1 -1
  53. package/dist/index198.js +152 -487
  54. package/dist/index198.js.map +1 -1
  55. package/dist/index199.js +472 -225
  56. package/dist/index199.js.map +1 -1
  57. package/dist/index200.js +236 -260
  58. package/dist/index200.js.map +1 -1
  59. package/dist/index201.js +265 -215
  60. package/dist/index201.js.map +1 -1
  61. package/dist/index202.js +207 -307
  62. package/dist/index202.js.map +1 -1
  63. package/dist/index203.js +302 -135
  64. package/dist/index203.js.map +1 -1
  65. package/dist/index204.js +140 -271
  66. package/dist/index204.js.map +1 -1
  67. package/dist/index205.js +263 -253
  68. package/dist/index205.js.map +1 -1
  69. package/dist/index206.js +244 -137
  70. package/dist/index206.js.map +1 -1
  71. package/dist/index207.js +100 -238
  72. package/dist/index207.js.map +1 -1
  73. package/dist/index208.js +278 -74
  74. package/dist/index208.js.map +1 -1
  75. package/dist/index209.js +56 -97
  76. package/dist/index209.js.map +1 -1
  77. package/dist/index210.js +142 -47
  78. package/dist/index210.js.map +1 -1
  79. package/dist/index211.js +38 -84
  80. package/dist/index211.js.map +1 -1
  81. package/dist/index212.js +72 -252
  82. package/dist/index212.js.map +1 -1
  83. package/dist/index213.js +274 -26
  84. package/dist/index213.js.map +1 -1
  85. package/dist/index214.js +29 -94
  86. package/dist/index214.js.map +1 -1
  87. package/dist/index215.js +98 -25
  88. package/dist/index215.js.map +1 -1
  89. package/dist/index216.js +20 -565
  90. package/dist/index216.js.map +1 -1
  91. package/dist/index217.js +564 -17
  92. package/dist/index217.js.map +1 -1
  93. package/dist/index218.js +20 -23
  94. package/dist/index218.js.map +1 -1
  95. package/dist/index219.js +20 -95
  96. package/dist/index219.js.map +1 -1
  97. package/dist/index220.js +92 -88
  98. package/dist/index220.js.map +1 -1
  99. package/dist/index221.js +97 -29
  100. package/dist/index221.js.map +1 -1
  101. package/dist/index222.js +24 -470
  102. package/dist/index222.js.map +1 -1
  103. package/dist/index223.js +446 -196
  104. package/dist/index223.js.map +1 -1
  105. package/dist/index224.js +199 -729
  106. package/dist/index224.js.map +1 -1
  107. package/dist/index225.js +750 -61
  108. package/dist/index225.js.map +1 -1
  109. package/dist/index226.js +58 -181
  110. package/dist/index226.js.map +1 -1
  111. package/dist/index227.js +175 -259
  112. package/dist/index227.js.map +1 -1
  113. package/dist/index228.js +246 -172
  114. package/dist/index228.js.map +1 -1
  115. package/dist/index229.js +195 -32
  116. package/dist/index229.js.map +1 -1
  117. package/dist/index230.js +12 -40
  118. package/dist/index230.js.map +1 -1
  119. package/dist/index231.js +23 -26
  120. package/dist/index231.js.map +1 -1
  121. package/dist/index232.js +45 -22
  122. package/dist/index232.js.map +1 -1
  123. package/dist/index233.js +27 -48
  124. package/dist/index233.js.map +1 -1
  125. package/dist/index234.js +52 -26
  126. package/dist/index234.js.map +1 -1
  127. package/dist/index235.js +40 -225
  128. package/dist/index235.js.map +1 -1
  129. package/dist/index236.js +217 -39
  130. package/dist/index236.js.map +1 -1
  131. package/dist/index237.js +50 -0
  132. package/dist/index237.js.map +1 -0
  133. package/dist/styles.css +1 -1
  134. package/dist/wc/AIToolCall.js +218 -0
  135. package/dist/wc/AIToolCall.js.map +1 -0
  136. package/dist/wc/hf-ai-tool-call.js +34 -219
  137. package/dist/wc/hf-ai-tool-call.js.map +1 -1
  138. package/dist/wc/hf-ai-tool-run.js +673 -576
  139. package/dist/wc/hf-ai-tool-run.js.map +1 -1
  140. package/dist/wc/workflow-step-renderer.js +79 -78
  141. package/dist/wc/workflow-step-renderer.js.map +1 -1
  142. package/dist/wc-react/AIToolCall.js +218 -0
  143. package/dist/wc-react/AIToolCall.js.map +1 -0
  144. package/dist/wc-react/hf-ai-tool-call.js +32 -217
  145. package/dist/wc-react/hf-ai-tool-call.js.map +1 -1
  146. package/dist/wc-react/hf-ai-tool-run.js +698 -601
  147. package/dist/wc-react/hf-ai-tool-run.js.map +1 -1
  148. package/dist/wc-react/workflow-step-renderer.js +58 -57
  149. package/dist/wc-react/workflow-step-renderer.js.map +1 -1
  150. package/package.json +1 -1
  151. package/skills/humain-ui/SKILL.md +1 -1
  152. package/skills/humain-ui-wc/SKILL.md +1 -1
  153. package/skills/humain-ui-wc.skill +0 -0
  154. package/skills/humain-ui.skill +0 -0
  155. package/dist/index182.js +0 -143
  156. package/dist/index182.js.map +0 -1
  157. package/dist/wc/wrench.js +0 -10
  158. package/dist/wc/wrench.js.map +0 -1
  159. package/dist/wc-react/wrench.js +0 -10
  160. package/dist/wc-react/wrench.js.map +0 -1
package/dist/index177.js CHANGED
@@ -1,84 +1,192 @@
1
1
  import { cn } from "./index2.js";
2
- import { jsx } from "react/jsx-runtime";
3
- //#region src/components/ui/table.tsx
4
- function Table({ className, disableOverflow, ...props }) {
5
- return /* @__PURE__ */ jsx("div", {
6
- "data-slot": "table-container",
7
- className: cn("relative w-full", !disableOverflow && "overflow-x-auto"),
8
- children: /* @__PURE__ */ jsx("table", {
9
- "data-slot": "table",
10
- className: cn("w-full caption-bottom text-sm", className),
11
- ...props
12
- })
13
- });
14
- }
15
- function TableHeader({ className, ...props }) {
16
- return /* @__PURE__ */ jsx("thead", {
17
- "data-slot": "table-header",
18
- className: cn("[&_tr]:border-b", className),
19
- ...props
20
- });
21
- }
22
- function TableBody({ className, ...props }) {
23
- return /* @__PURE__ */ jsx("tbody", {
24
- "data-slot": "table-body",
25
- className: cn("[&_tr:last-child]:border-0", className),
26
- ...props
27
- });
28
- }
29
- function TableFooter({ className, ...props }) {
30
- return /* @__PURE__ */ jsx("tfoot", {
31
- "data-slot": "table-footer",
32
- className: cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className),
33
- ...props
34
- });
35
- }
36
- function TableRow({ className, ...props }) {
37
- return /* @__PURE__ */ jsx("tr", {
38
- "data-slot": "table-row",
39
- className: cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-200 ease-smooth motion-reduce:transition-none", className),
40
- ...props
41
- });
42
- }
43
- function TableHead({ className, ...props }) {
44
- return /* @__PURE__ */ jsx("th", {
45
- "data-slot": "table-head",
46
- className: cn("text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0", className),
47
- ...props
48
- });
49
- }
50
- function TableCell({ className, ...props }) {
51
- return /* @__PURE__ */ jsx("td", {
52
- "data-slot": "table-cell",
53
- className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0", className),
54
- ...props
55
- });
2
+ import { Button } from "./index5.js";
3
+ import { cva } from "class-variance-authority";
4
+ import { AlertCircle, AlertTriangle, CheckCircle, Info, X } from "lucide-react";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { AnimatePresence, motion } from "motion/react";
8
+ //#region src/components/organisms/ai/AISystemMessage/AISystemMessage.tsx
9
+ var systemMessageVariants = cva("flex items-start gap-3 px-4 py-3 rounded-xl border", {
10
+ variants: {
11
+ variant: {
12
+ info: "bg-primary/10 border-primary text-primary",
13
+ success: "bg-success/10 border-success/50 text-success",
14
+ warning: "bg-warning/10 border-warning/50 text-warning",
15
+ error: "bg-destructive/10 border-destructive/50 text-destructive",
16
+ neutral: "bg-muted border-border text-secondary-foreground"
17
+ },
18
+ size: {
19
+ sm: "px-3 py-2 text-xs",
20
+ md: "px-4 py-3 text-sm",
21
+ lg: "px-5 py-4 text-base"
22
+ }
23
+ },
24
+ defaultVariants: {
25
+ variant: "info",
26
+ size: "md"
27
+ }
28
+ });
29
+ var systemMessageIconVariants = cva("shrink-0 mt-0.5", {
30
+ variants: {
31
+ variant: {
32
+ info: "text-primary",
33
+ success: "text-success",
34
+ warning: "text-warning",
35
+ error: "text-destructive",
36
+ neutral: "text-text-quaternary"
37
+ },
38
+ size: {
39
+ sm: "size-4",
40
+ md: "size-5",
41
+ lg: "size-6"
42
+ }
43
+ },
44
+ defaultVariants: {
45
+ variant: "info",
46
+ size: "md"
47
+ }
48
+ });
49
+ var iconMap = {
50
+ info: Info,
51
+ success: CheckCircle,
52
+ warning: AlertTriangle,
53
+ error: AlertCircle,
54
+ neutral: Info
55
+ };
56
+ function AISystemMessage({ children, title, variant = "info", size = "md", dismissible = false, onDismiss, icon, hideIcon = false, actions, className }) {
57
+ const [isVisible, setIsVisible] = React.useState(true);
58
+ const handleDismiss = () => {
59
+ setIsVisible(false);
60
+ onDismiss?.();
61
+ };
62
+ const IconComponent = iconMap[variant || "info"];
63
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: isVisible && /* @__PURE__ */ jsxs(motion.div, {
64
+ "data-slot": "ai-system-message",
65
+ role: "status",
66
+ "aria-live": "polite",
67
+ initial: {
68
+ opacity: 0,
69
+ y: -10
70
+ },
71
+ animate: {
72
+ opacity: 1,
73
+ y: 0
74
+ },
75
+ exit: {
76
+ opacity: 0,
77
+ y: -10,
78
+ height: 0,
79
+ marginBottom: 0
80
+ },
81
+ transition: {
82
+ duration: .2,
83
+ ease: [
84
+ .4,
85
+ 0,
86
+ .2,
87
+ 1
88
+ ]
89
+ },
90
+ className: cn(systemMessageVariants({
91
+ variant,
92
+ size
93
+ }), "motion-reduce:transition-none", className),
94
+ children: [
95
+ !hideIcon && /* @__PURE__ */ jsx("div", {
96
+ className: systemMessageIconVariants({
97
+ variant,
98
+ size
99
+ }),
100
+ "aria-hidden": "true",
101
+ children: icon || /* @__PURE__ */ jsx(IconComponent, { className: "size-full" })
102
+ }),
103
+ /* @__PURE__ */ jsxs("div", {
104
+ className: "flex-1 min-w-0",
105
+ children: [
106
+ title && /* @__PURE__ */ jsx("p", {
107
+ className: "font-medium mb-0.5",
108
+ children: title
109
+ }),
110
+ /* @__PURE__ */ jsx("div", {
111
+ className: cn(!title && "leading-snug"),
112
+ children
113
+ }),
114
+ actions && /* @__PURE__ */ jsx("div", {
115
+ className: "flex items-center gap-2 mt-2",
116
+ children: actions
117
+ })
118
+ ]
119
+ }),
120
+ dismissible && /* @__PURE__ */ jsx(Button, {
121
+ appearance: "ghost",
122
+ variant: "secondary",
123
+ size: "sm",
124
+ onClick: handleDismiss,
125
+ "aria-label": "Dismiss message",
126
+ className: "size-6 p-0 shrink-0 -mt-0.5 -me-1 hover:bg-foreground/5",
127
+ children: /* @__PURE__ */ jsx(X, { className: "size-4" })
128
+ })
129
+ ]
130
+ }) });
56
131
  }
57
- function TableCaption({ className, ...props }) {
58
- return /* @__PURE__ */ jsx("caption", {
59
- "data-slot": "table-caption",
60
- className: cn("text-muted-foreground mt-4 text-sm", className),
61
- ...props
62
- });
132
+ AISystemMessage.displayName = "AISystemMessage";
133
+ function AISystemMessageBanner({ children, variant = "info", dismissible = false, onDismiss, icon, action, className }) {
134
+ const [isVisible, setIsVisible] = React.useState(true);
135
+ const handleDismiss = () => {
136
+ setIsVisible(false);
137
+ onDismiss?.();
138
+ };
139
+ const IconComponent = iconMap[variant || "info"];
140
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: isVisible && /* @__PURE__ */ jsxs(motion.div, {
141
+ "data-slot": "ai-system-message-banner",
142
+ role: "status",
143
+ "aria-live": "polite",
144
+ initial: {
145
+ opacity: 0,
146
+ height: 0
147
+ },
148
+ animate: {
149
+ opacity: 1,
150
+ height: "auto"
151
+ },
152
+ exit: {
153
+ opacity: 0,
154
+ height: 0
155
+ },
156
+ transition: {
157
+ duration: .2,
158
+ ease: [
159
+ .4,
160
+ 0,
161
+ .2,
162
+ 1
163
+ ]
164
+ },
165
+ className: cn("w-full px-4 py-2 flex items-center justify-center gap-3 motion-reduce:transition-none", variant === "info" && "bg-primary/10 text-primary", variant === "success" && "bg-success/10 text-success", variant === "warning" && "bg-warning/10 text-warning", variant === "error" && "bg-destructive/10 text-destructive", variant === "neutral" && "bg-muted text-secondary-foreground", className),
166
+ children: [/* @__PURE__ */ jsxs("div", {
167
+ className: "flex items-center gap-2 flex-1 justify-center",
168
+ children: [
169
+ icon || /* @__PURE__ */ jsx(IconComponent, {
170
+ "aria-hidden": "true",
171
+ className: cn("size-4 shrink-0", variant === "info" && "text-primary", variant === "success" && "text-success", variant === "warning" && "text-warning", variant === "error" && "text-destructive", variant === "neutral" && "text-text-quaternary")
172
+ }),
173
+ /* @__PURE__ */ jsx("span", {
174
+ className: "text-sm",
175
+ children
176
+ }),
177
+ action
178
+ ]
179
+ }), dismissible && /* @__PURE__ */ jsx("button", {
180
+ type: "button",
181
+ onClick: handleDismiss,
182
+ "aria-label": "Dismiss banner",
183
+ className: "p-1 rounded hover:bg-foreground/5 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
184
+ children: /* @__PURE__ */ jsx(X, { className: "size-4" })
185
+ })]
186
+ }) });
63
187
  }
64
- Table.displayName = "Table";
65
- TableHeader.displayName = "Table.Header";
66
- TableBody.displayName = "Table.Body";
67
- TableFooter.displayName = "Table.Footer";
68
- TableRow.displayName = "Table.Row";
69
- TableHead.displayName = "Table.Head";
70
- TableCell.displayName = "Table.Cell";
71
- TableCaption.displayName = "Table.Caption";
72
- var TableNamespace = Object.assign(Table, {
73
- Header: TableHeader,
74
- Body: TableBody,
75
- Footer: TableFooter,
76
- Row: TableRow,
77
- Head: TableHead,
78
- Cell: TableCell,
79
- Caption: TableCaption
80
- });
188
+ AISystemMessageBanner.displayName = "AISystemMessageBanner";
81
189
  //#endregion
82
- export { TableNamespace as Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
190
+ export { AISystemMessage, AISystemMessageBanner, systemMessageIconVariants, systemMessageVariants };
83
191
 
84
192
  //# sourceMappingURL=index177.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index177.js","names":[],"sources":["../src/components/ui/table.tsx"],"sourcesContent":["import type * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\ninterface TableProps extends React.ComponentProps<'table'> {\n /** Disable the overflow-x-auto wrapper (useful when parent handles scrolling) */\n disableOverflow?: boolean;\n}\n\nfunction Table({ className, disableOverflow, ...props }: TableProps) {\n return (\n <div\n data-slot=\"table-container\"\n className={cn('relative w-full', !disableOverflow && 'overflow-x-auto')}\n >\n <table\n data-slot=\"table\"\n className={cn('w-full caption-bottom text-sm', className)}\n {...props}\n />\n </div>\n );\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn('[&_tr]:border-b', className)}\n {...props}\n />\n );\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn('[&_tr:last-child]:border-0', className)}\n {...props}\n />\n );\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n 'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n 'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-200 ease-smooth motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<'th'>) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n 'text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<'caption'>) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn('text-muted-foreground mt-4 text-sm', className)}\n {...props}\n />\n );\n}\n\nTable.displayName = 'Table';\nTableHeader.displayName = 'Table.Header';\nTableBody.displayName = 'Table.Body';\nTableFooter.displayName = 'Table.Footer';\nTableRow.displayName = 'Table.Row';\nTableHead.displayName = 'Table.Head';\nTableCell.displayName = 'Table.Cell';\nTableCaption.displayName = 'Table.Caption';\n\nconst TableNamespace = Object.assign(Table, {\n Header: TableHeader,\n Body: TableBody,\n Footer: TableFooter,\n Row: TableRow,\n Head: TableHead,\n Cell: TableCell,\n Caption: TableCaption,\n});\n\nexport {\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableNamespace as Table,\n TableRow,\n};\n"],"mappings":";;;AASA,SAAS,MAAM,EAAE,WAAW,iBAAiB,GAAG,SAAqB;CACnE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,mBAAmB,CAAC,mBAAmB,iBAAiB;YAEtE,oBAAC,SAAD;GACE,aAAU;GACV,WAAW,GAAG,iCAAiC,SAAS;GACxD,GAAI;EACL,CAAA;CACE,CAAA;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,mBAAmB,SAAS;EAC1C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAwC;CACzE,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2DACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAqC;CACrE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,sIACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,iHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,oEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SAC+B;CAClC,OACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,cAAc;AACpB,YAAY,cAAc;AAC1B,UAAU,cAAc;AACxB,YAAY,cAAc;AAC1B,SAAS,cAAc;AACvB,UAAU,cAAc;AACxB,UAAU,cAAc;AACxB,aAAa,cAAc;AAE3B,IAAM,iBAAiB,OAAO,OAAO,OAAO;CAC1C,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,KAAK;CACL,MAAM;CACN,MAAM;CACN,SAAS;AACX,CAAC"}
1
+ {"version":3,"file":"index177.js","names":[],"sources":["../src/components/organisms/ai/AISystemMessage/AISystemMessage.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { AlertCircle, AlertTriangle, CheckCircle, Info, X } from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst systemMessageVariants = cva(\n 'flex items-start gap-3 px-4 py-3 rounded-xl border',\n {\n variants: {\n variant: {\n info: 'bg-primary/10 border-primary text-primary',\n success: 'bg-success/10 border-success/50 text-success',\n warning: 'bg-warning/10 border-warning/50 text-warning',\n error: 'bg-destructive/10 border-destructive/50 text-destructive',\n neutral: 'bg-muted border-border text-secondary-foreground',\n },\n size: {\n sm: 'px-3 py-2 text-xs',\n md: 'px-4 py-3 text-sm',\n lg: 'px-5 py-4 text-base',\n },\n },\n defaultVariants: {\n variant: 'info',\n size: 'md',\n },\n },\n);\n\nconst systemMessageIconVariants = cva('shrink-0 mt-0.5', {\n variants: {\n variant: {\n info: 'text-primary',\n success: 'text-success',\n warning: 'text-warning',\n error: 'text-destructive',\n neutral: 'text-text-quaternary',\n },\n size: {\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n },\n defaultVariants: {\n variant: 'info',\n size: 'md',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type SystemMessageVariant =\n | 'info'\n | 'success'\n | 'warning'\n | 'error'\n | 'neutral';\n\n// =============================================================================\n// Icon Map\n// =============================================================================\n\nconst iconMap = {\n info: Info,\n success: CheckCircle,\n warning: AlertTriangle,\n error: AlertCircle,\n neutral: Info,\n};\n\n// =============================================================================\n// Main AISystemMessage Component\n// =============================================================================\n\nexport interface AISystemMessageProps\n extends VariantProps<typeof systemMessageVariants> {\n /** Message content */\n children: React.ReactNode;\n /** Title for the message */\n title?: string;\n /** Whether the message can be dismissed */\n dismissible?: boolean;\n /** Callback when dismissed */\n onDismiss?: () => void;\n /** Custom icon */\n icon?: React.ReactNode;\n /** Hide the icon */\n hideIcon?: boolean;\n /** Actions to display */\n actions?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISystemMessage({\n children,\n title,\n variant = 'info',\n size = 'md',\n dismissible = false,\n onDismiss,\n icon,\n hideIcon = false,\n actions,\n className,\n}: AISystemMessageProps) {\n const [isVisible, setIsVisible] = React.useState(true);\n\n const handleDismiss = () => {\n setIsVisible(false);\n onDismiss?.();\n };\n\n const IconComponent = iconMap[variant || 'info'];\n\n return (\n <AnimatePresence>\n {isVisible && (\n <motion.div\n data-slot=\"ai-system-message\"\n role=\"status\"\n aria-live=\"polite\"\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10, height: 0, marginBottom: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className={cn(\n systemMessageVariants({ variant, size }),\n 'motion-reduce:transition-none',\n className,\n )}\n >\n {/* Icon */}\n {!hideIcon && (\n <div\n className={systemMessageIconVariants({ variant, size })}\n aria-hidden=\"true\"\n >\n {icon || <IconComponent className=\"size-full\" />}\n </div>\n )}\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n {title && <p className=\"font-medium mb-0.5\">{title}</p>}\n <div className={cn(!title && 'leading-snug')}>{children}</div>\n\n {/* Actions */}\n {actions && (\n <div className=\"flex items-center gap-2 mt-2\">{actions}</div>\n )}\n </div>\n\n {/* Dismiss button */}\n {dismissible && (\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleDismiss}\n aria-label=\"Dismiss message\"\n className=\"size-6 p-0 shrink-0 -mt-0.5 -me-1 hover:bg-foreground/5\"\n >\n <X className=\"size-4\" />\n </Button>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\nAISystemMessage.displayName = 'AISystemMessage';\n\n// =============================================================================\n// System Message Banner (Full-width variant)\n// =============================================================================\n\nexport interface AISystemMessageBannerProps\n extends VariantProps<typeof systemMessageVariants> {\n /** Message content */\n children: React.ReactNode;\n /** Whether the banner can be dismissed */\n dismissible?: boolean;\n /** Callback when dismissed */\n onDismiss?: () => void;\n /** Custom icon */\n icon?: React.ReactNode;\n /** Action button */\n action?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISystemMessageBanner({\n children,\n variant = 'info',\n dismissible = false,\n onDismiss,\n icon,\n action,\n className,\n}: AISystemMessageBannerProps) {\n const [isVisible, setIsVisible] = React.useState(true);\n\n const handleDismiss = () => {\n setIsVisible(false);\n onDismiss?.();\n };\n\n const IconComponent = iconMap[variant || 'info'];\n\n return (\n <AnimatePresence>\n {isVisible && (\n <motion.div\n data-slot=\"ai-system-message-banner\"\n role=\"status\"\n aria-live=\"polite\"\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className={cn(\n 'w-full px-4 py-2 flex items-center justify-center gap-3 motion-reduce:transition-none',\n variant === 'info' && 'bg-primary/10 text-primary',\n variant === 'success' && 'bg-success/10 text-success',\n variant === 'warning' && 'bg-warning/10 text-warning',\n variant === 'error' && 'bg-destructive/10 text-destructive',\n variant === 'neutral' && 'bg-muted text-secondary-foreground',\n className,\n )}\n >\n <div className=\"flex items-center gap-2 flex-1 justify-center\">\n {icon || (\n <IconComponent\n aria-hidden=\"true\"\n className={cn(\n 'size-4 shrink-0',\n variant === 'info' && 'text-primary',\n variant === 'success' && 'text-success',\n variant === 'warning' && 'text-warning',\n variant === 'error' && 'text-destructive',\n variant === 'neutral' && 'text-text-quaternary',\n )}\n />\n )}\n <span className=\"text-sm\">{children}</span>\n {action}\n </div>\n\n {dismissible && (\n <button\n type=\"button\"\n onClick={handleDismiss}\n aria-label=\"Dismiss banner\"\n className=\"p-1 rounded hover:bg-foreground/5 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <X className=\"size-4\" />\n </button>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\nAISystemMessageBanner.displayName = 'AISystemMessageBanner';\n\nexport {\n AISystemMessage,\n AISystemMessageBanner,\n systemMessageIconVariants,\n systemMessageVariants,\n};\n"],"mappings":"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"}
package/dist/index178.js CHANGED
@@ -1,134 +1,84 @@
1
- "use client";
2
1
  import { cn } from "./index2.js";
3
- import { useAIInteraction } from "./index138.js";
4
- import { validateTableBlockSchema } from "./index143.js";
5
- import { Checkbox } from "./index161.js";
6
- import { Table as TableNamespace, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./index177.js";
7
- import * as React from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- //#region src/components/organisms/ai/AITable/AITable.tsx
10
- /**
11
- * Get the row ID from a data row
12
- * Uses 'id' field if available, otherwise falls back to first column key
13
- */
14
- function getRowId(row, columns, index) {
15
- if (row.id !== void 0) {
16
- const id = String(row.id);
17
- if (id) return id;
18
- }
19
- if (columns.length > 0) {
20
- const firstKey = columns[0].key;
21
- const id = String(row[firstKey] ?? "");
22
- if (id) return id;
23
- }
24
- return `row-${index + 1}`;
25
- }
26
- function InvalidTableSchema({ className }) {
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/ui/table.tsx
4
+ function Table({ className, disableOverflow, ...props }) {
27
5
  return /* @__PURE__ */ jsx("div", {
28
- "data-slot": "ai-table",
29
- role: "alert",
30
- className: cn("rounded-lg border border-destructive bg-destructive/20 p-4 text-sm text-destructive", className),
31
- children: "Invalid table schema"
6
+ "data-slot": "table-container",
7
+ className: cn("relative w-full", !disableOverflow && "overflow-x-auto"),
8
+ children: /* @__PURE__ */ jsx("table", {
9
+ "data-slot": "table",
10
+ className: cn("w-full caption-bottom text-sm", className),
11
+ ...props
12
+ })
13
+ });
14
+ }
15
+ function TableHeader({ className, ...props }) {
16
+ return /* @__PURE__ */ jsx("thead", {
17
+ "data-slot": "table-header",
18
+ className: cn("[&_tr]:border-b", className),
19
+ ...props
20
+ });
21
+ }
22
+ function TableBody({ className, ...props }) {
23
+ return /* @__PURE__ */ jsx("tbody", {
24
+ "data-slot": "table-body",
25
+ className: cn("[&_tr:last-child]:border-0", className),
26
+ ...props
27
+ });
28
+ }
29
+ function TableFooter({ className, ...props }) {
30
+ return /* @__PURE__ */ jsx("tfoot", {
31
+ "data-slot": "table-footer",
32
+ className: cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className),
33
+ ...props
34
+ });
35
+ }
36
+ function TableRow({ className, ...props }) {
37
+ return /* @__PURE__ */ jsx("tr", {
38
+ "data-slot": "table-row",
39
+ className: cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-200 ease-smooth motion-reduce:transition-none", className),
40
+ ...props
32
41
  });
33
42
  }
34
- /**
35
- * AITable - Renders interactive data tables from JSON schema.
36
- *
37
- * Supports row selection with checkboxes and emits interaction events
38
- * through the AIInteractionContext when selections change.
39
- */
40
- function AITable({ schema, className }) {
41
- const { onInteraction } = useAIInteraction();
42
- const tableSchema = React.useMemo(() => validateTableBlockSchema(schema) ? schema : null, [schema]);
43
- const [selectedRows, setSelectedRows] = React.useState(/* @__PURE__ */ new Set());
44
- const id = tableSchema?.id ?? "";
45
- const title = tableSchema?.title;
46
- const columns = tableSchema?.columns ?? [];
47
- const data = tableSchema?.data ?? [];
48
- const selectable = tableSchema?.selectable ?? false;
49
- const allRowIds = React.useMemo(() => data.map((row, index) => getRowId(row, columns, index)), [data, columns]);
50
- const emitSelectionChange = React.useCallback((newSelectedRows) => {
51
- onInteraction?.({
52
- componentId: id,
53
- componentType: "table",
54
- action: "select",
55
- value: { selectedRows: newSelectedRows },
56
- timestamp: Date.now()
57
- });
58
- }, [id, onInteraction]);
59
- const handleRowSelect = React.useCallback((rowId, checked) => {
60
- setSelectedRows((prev) => {
61
- const next = new Set(prev);
62
- if (checked) next.add(rowId);
63
- else next.delete(rowId);
64
- emitSelectionChange(Array.from(next));
65
- return next;
66
- });
67
- }, [emitSelectionChange]);
68
- const handleSelectAll = React.useCallback((checked) => {
69
- if (checked) {
70
- setSelectedRows(new Set(allRowIds));
71
- emitSelectionChange(allRowIds);
72
- } else {
73
- setSelectedRows(/* @__PURE__ */ new Set());
74
- emitSelectionChange([]);
75
- }
76
- }, [allRowIds, emitSelectionChange]);
77
- const allSelected = allRowIds.length > 0 && selectedRows.size === allRowIds.length;
78
- const someSelected = selectedRows.size > 0 && selectedRows.size < allRowIds.length;
79
- if (!tableSchema) return /* @__PURE__ */ jsx(InvalidTableSchema, { className });
80
- if (!data || data.length === 0) return /* @__PURE__ */ jsx("div", {
81
- "data-slot": "ai-table",
82
- role: "status",
83
- className: cn("flex items-center justify-center rounded-lg border border-border bg-muted p-8 text-muted-foreground", className),
84
- children: "No data available"
43
+ function TableHead({ className, ...props }) {
44
+ return /* @__PURE__ */ jsx("th", {
45
+ "data-slot": "table-head",
46
+ className: cn("text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0", className),
47
+ ...props
85
48
  });
86
- return /* @__PURE__ */ jsxs("div", {
87
- "data-slot": "ai-table",
88
- className: cn("flex flex-col gap-2", className),
89
- children: [
90
- title && /* @__PURE__ */ jsx("h3", {
91
- className: "text-sm font-medium text-foreground",
92
- children: title
93
- }),
94
- selectable && /* @__PURE__ */ jsx("div", {
95
- className: "sr-only",
96
- "aria-live": "polite",
97
- "aria-atomic": "true",
98
- children: selectedRows.size > 0 ? `${selectedRows.size} of ${allRowIds.length} rows selected` : "No rows selected"
99
- }),
100
- /* @__PURE__ */ jsxs(TableNamespace, {
101
- "aria-label": title ?? "Interactive data table",
102
- children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [selectable && /* @__PURE__ */ jsx(TableHead, {
103
- className: "w-[40px]",
104
- children: /* @__PURE__ */ jsx(Checkbox, {
105
- checked: allSelected,
106
- indeterminate: someSelected,
107
- onCheckedChange: handleSelectAll,
108
- "aria-label": "Select all rows"
109
- })
110
- }), columns.map((column) => /* @__PURE__ */ jsx(TableHead, {
111
- style: { width: typeof column.width === "number" ? Number.isFinite(column.width) ? `${column.width}px` : void 0 : column.width },
112
- children: column.label
113
- }, column.key))] }) }), /* @__PURE__ */ jsx(TableBody, { children: data.map((row, index) => {
114
- const rowId = getRowId(row, columns, index);
115
- const isSelected = selectedRows.has(rowId);
116
- return /* @__PURE__ */ jsxs(TableRow, {
117
- "data-state": isSelected ? "selected" : void 0,
118
- className: "transition-colors",
119
- children: [selectable && /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Checkbox, {
120
- checked: isSelected,
121
- onCheckedChange: (checked) => handleRowSelect(rowId, checked === true),
122
- "aria-label": `Select row ${rowId}`
123
- }) }), columns.map((column) => /* @__PURE__ */ jsx(TableCell, { children: String(row[column.key] ?? "") }, column.key))]
124
- }, rowId);
125
- }) })]
126
- })
127
- ]
49
+ }
50
+ function TableCell({ className, ...props }) {
51
+ return /* @__PURE__ */ jsx("td", {
52
+ "data-slot": "table-cell",
53
+ className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0", className),
54
+ ...props
55
+ });
56
+ }
57
+ function TableCaption({ className, ...props }) {
58
+ return /* @__PURE__ */ jsx("caption", {
59
+ "data-slot": "table-caption",
60
+ className: cn("text-muted-foreground mt-4 text-sm", className),
61
+ ...props
128
62
  });
129
63
  }
130
- AITable.displayName = "AITable";
64
+ Table.displayName = "Table";
65
+ TableHeader.displayName = "Table.Header";
66
+ TableBody.displayName = "Table.Body";
67
+ TableFooter.displayName = "Table.Footer";
68
+ TableRow.displayName = "Table.Row";
69
+ TableHead.displayName = "Table.Head";
70
+ TableCell.displayName = "Table.Cell";
71
+ TableCaption.displayName = "Table.Caption";
72
+ var TableNamespace = Object.assign(Table, {
73
+ Header: TableHeader,
74
+ Body: TableBody,
75
+ Footer: TableFooter,
76
+ Row: TableRow,
77
+ Head: TableHead,
78
+ Cell: TableCell,
79
+ Caption: TableCaption
80
+ });
131
81
  //#endregion
132
- export { AITable, AITable as default };
82
+ export { TableNamespace as Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
133
83
 
134
84
  //# sourceMappingURL=index178.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index178.js","names":[],"sources":["../src/components/organisms/ai/AITable/AITable.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useAIInteraction } from '@/components/organisms/ai/_shared/interaction-context';\nimport { validateTableBlockSchema } from '@/components/organisms/ai/_shared/schema-validation';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Schema for a table column\n */\nexport interface TableColumnSchema {\n /** Unique key for the column, maps to data field */\n key: string;\n /** Display label for the column header */\n label: string;\n /** Whether the column is sortable (not yet implemented) */\n sortable?: boolean;\n /** Whether cells in this column are editable (not yet implemented) */\n editable?: boolean;\n /** Column width - can be number (pixels) or string (e.g., '100px', '20%') */\n width?: number | string;\n}\n\n/**\n * Schema for configuring an AITable\n */\nexport interface TableBlockSchema {\n /** Unique identifier for the component instance */\n id: string;\n /** Optional title displayed above the table */\n title?: string;\n /** Column definitions */\n columns: TableColumnSchema[];\n /** Array of row data */\n data: Record<string, unknown>[];\n /** Whether rows can be selected with checkboxes */\n selectable?: boolean;\n /** Pagination configuration (not yet implemented) */\n pagination?: boolean | { pageSize: number };\n}\n\n/**\n * Props for AITable\n */\nexport interface AITableProps {\n /** Schema defining the table configuration */\n schema: TableBlockSchema;\n /** Additional class names */\n className?: string;\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Get the row ID from a data row\n * Uses 'id' field if available, otherwise falls back to first column key\n */\nfunction getRowId(\n row: Record<string, unknown>,\n columns: TableColumnSchema[],\n index: number,\n): string {\n if (row.id !== undefined) {\n const id = String(row.id);\n if (id) {\n return id;\n }\n }\n if (columns.length > 0) {\n const firstKey = columns[0].key;\n const id = String(row[firstKey] ?? '');\n if (id) {\n return id;\n }\n }\n return `row-${index + 1}`;\n}\n\nfunction InvalidTableSchema({\n className,\n}: {\n className?: string;\n}): React.ReactElement {\n return (\n <div\n data-slot=\"ai-table\"\n role=\"alert\"\n className={cn(\n 'rounded-lg border border-destructive bg-destructive/20 p-4 text-sm text-destructive',\n className,\n )}\n >\n Invalid table schema\n </div>\n );\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * AITable - Renders interactive data tables from JSON schema.\n *\n * Supports row selection with checkboxes and emits interaction events\n * through the AIInteractionContext when selections change.\n */\nexport function AITable({\n schema,\n className,\n}: AITableProps): React.ReactElement {\n const { onInteraction } = useAIInteraction();\n const tableSchema = React.useMemo(\n () => (validateTableBlockSchema(schema) ? schema : null),\n [schema],\n );\n const [selectedRows, setSelectedRows] = React.useState<Set<string>>(\n new Set(),\n );\n\n const id = tableSchema?.id ?? '';\n const title = tableSchema?.title;\n const columns = tableSchema?.columns ?? [];\n const data = tableSchema?.data ?? [];\n const selectable = tableSchema?.selectable ?? false;\n\n // Get all row IDs\n const allRowIds = React.useMemo(\n () => data.map((row, index) => getRowId(row, columns, index)),\n [data, columns],\n );\n\n // Emit interaction event when selection changes\n const emitSelectionChange = React.useCallback(\n (newSelectedRows: string[]) => {\n onInteraction?.({\n componentId: id,\n componentType: 'table',\n action: 'select',\n value: { selectedRows: newSelectedRows },\n timestamp: Date.now(),\n });\n },\n [id, onInteraction],\n );\n\n // Handle individual row selection\n const handleRowSelect = React.useCallback(\n (rowId: string, checked: boolean) => {\n setSelectedRows((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(rowId);\n } else {\n next.delete(rowId);\n }\n emitSelectionChange(Array.from(next));\n return next;\n });\n },\n [emitSelectionChange],\n );\n\n // Handle select all\n const handleSelectAll = React.useCallback(\n (checked: boolean) => {\n if (checked) {\n setSelectedRows(new Set(allRowIds));\n emitSelectionChange(allRowIds);\n } else {\n setSelectedRows(new Set());\n emitSelectionChange([]);\n }\n },\n [allRowIds, emitSelectionChange],\n );\n\n // Check if all rows are selected\n const allSelected =\n allRowIds.length > 0 && selectedRows.size === allRowIds.length;\n const someSelected =\n selectedRows.size > 0 && selectedRows.size < allRowIds.length;\n\n if (!tableSchema) {\n return <InvalidTableSchema className={className} />;\n }\n\n // Empty state\n if (!data || data.length === 0) {\n return (\n <div\n data-slot=\"ai-table\"\n role=\"status\"\n className={cn(\n 'flex items-center justify-center rounded-lg border border-border bg-muted p-8 text-muted-foreground',\n className,\n )}\n >\n No data available\n </div>\n );\n }\n\n return (\n <div data-slot=\"ai-table\" className={cn('flex flex-col gap-2', className)}>\n {title && (\n <h3 className=\"text-sm font-medium text-foreground\">{title}</h3>\n )}\n\n {/* Live region for selection count */}\n {selectable && (\n <div className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {selectedRows.size > 0\n ? `${selectedRows.size} of ${allRowIds.length} rows selected`\n : 'No rows selected'}\n </div>\n )}\n\n <Table aria-label={title ?? 'Interactive data table'}>\n <TableHeader>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-[40px]\">\n <Checkbox\n checked={allSelected}\n indeterminate={someSelected}\n onCheckedChange={handleSelectAll}\n aria-label=\"Select all rows\"\n />\n </TableHead>\n )}\n {columns.map((column) => (\n <TableHead\n key={column.key}\n style={{\n width:\n typeof column.width === 'number'\n ? Number.isFinite(column.width)\n ? `${column.width}px`\n : undefined\n : column.width,\n }}\n >\n {column.label}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.map((row, index) => {\n const rowId = getRowId(row, columns, index);\n const isSelected = selectedRows.has(rowId);\n\n return (\n <TableRow\n key={rowId}\n data-state={isSelected ? 'selected' : undefined}\n className=\"transition-colors\"\n >\n {selectable && (\n <TableCell>\n <Checkbox\n checked={isSelected}\n onCheckedChange={(checked) =>\n handleRowSelect(rowId, checked === true)\n }\n aria-label={`Select row ${rowId}`}\n />\n </TableCell>\n )}\n {columns.map((column) => (\n <TableCell key={column.key}>\n {String(row[column.key] ?? '')}\n </TableCell>\n ))}\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n );\n}\n\nAITable.displayName = 'AITable';\n\nexport default AITable;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index178.js","names":[],"sources":["../src/components/ui/table.tsx"],"sourcesContent":["import type * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\ninterface TableProps extends React.ComponentProps<'table'> {\n /** Disable the overflow-x-auto wrapper (useful when parent handles scrolling) */\n disableOverflow?: boolean;\n}\n\nfunction Table({ className, disableOverflow, ...props }: TableProps) {\n return (\n <div\n data-slot=\"table-container\"\n className={cn('relative w-full', !disableOverflow && 'overflow-x-auto')}\n >\n <table\n data-slot=\"table\"\n className={cn('w-full caption-bottom text-sm', className)}\n {...props}\n />\n </div>\n );\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn('[&_tr]:border-b', className)}\n {...props}\n />\n );\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn('[&_tr:last-child]:border-0', className)}\n {...props}\n />\n );\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n 'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n 'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-200 ease-smooth motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<'th'>) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n 'text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<'caption'>) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn('text-muted-foreground mt-4 text-sm', className)}\n {...props}\n />\n );\n}\n\nTable.displayName = 'Table';\nTableHeader.displayName = 'Table.Header';\nTableBody.displayName = 'Table.Body';\nTableFooter.displayName = 'Table.Footer';\nTableRow.displayName = 'Table.Row';\nTableHead.displayName = 'Table.Head';\nTableCell.displayName = 'Table.Cell';\nTableCaption.displayName = 'Table.Caption';\n\nconst TableNamespace = Object.assign(Table, {\n Header: TableHeader,\n Body: TableBody,\n Footer: TableFooter,\n Row: TableRow,\n Head: TableHead,\n Cell: TableCell,\n Caption: TableCaption,\n});\n\nexport {\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableNamespace as Table,\n TableRow,\n};\n"],"mappings":";;;AASA,SAAS,MAAM,EAAE,WAAW,iBAAiB,GAAG,SAAqB;CACnE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,mBAAmB,CAAC,mBAAmB,iBAAiB;YAEtE,oBAAC,SAAD;GACE,aAAU;GACV,WAAW,GAAG,iCAAiC,SAAS;GACxD,GAAI;EACL,CAAA;CACE,CAAA;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,mBAAmB,SAAS;EAC1C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAwC;CACzE,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2DACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAqC;CACrE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,sIACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,iHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,oEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SAC+B;CAClC,OACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,cAAc;AACpB,YAAY,cAAc;AAC1B,UAAU,cAAc;AACxB,YAAY,cAAc;AAC1B,SAAS,cAAc;AACvB,UAAU,cAAc;AACxB,UAAU,cAAc;AACxB,aAAa,cAAc;AAE3B,IAAM,iBAAiB,OAAO,OAAO,OAAO;CAC1C,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,KAAK;CACL,MAAM;CACN,MAAM;CACN,SAAS;AACX,CAAC"}