@adea-ai/ui 0.61.0 → 0.61.1

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 (248) hide show
  1. package/dist/r/accordion.json +3 -1
  2. package/dist/r/account-menu.json +2 -1
  3. package/dist/r/alert-dialog.json +3 -1
  4. package/dist/r/alert.json +3 -1
  5. package/dist/r/app-shell.json +3 -1
  6. package/dist/r/aspect-ratio.json +3 -1
  7. package/dist/r/avatar.json +3 -1
  8. package/dist/r/badge.json +3 -1
  9. package/dist/r/board.json +3 -1
  10. package/dist/r/breadcrumb.json +3 -1
  11. package/dist/r/button-group.json +2 -1
  12. package/dist/r/button.json +3 -1
  13. package/dist/r/calendar.json +2 -1
  14. package/dist/r/card.json +3 -1
  15. package/dist/r/carousel.json +2 -1
  16. package/dist/r/chart.json +3 -1
  17. package/dist/r/checkbox.json +3 -1
  18. package/dist/r/code-block.json +2 -1
  19. package/dist/r/collapsible.json +3 -1
  20. package/dist/r/combobox.json +3 -1
  21. package/dist/r/command.json +3 -1
  22. package/dist/r/context-menu.json +3 -1
  23. package/dist/r/conversation.json +2 -1
  24. package/dist/r/detail-panel.json +2 -1
  25. package/dist/r/dialog.json +3 -1
  26. package/dist/r/diff-block.json +3 -1
  27. package/dist/r/drawer.json +3 -1
  28. package/dist/r/dropdown-menu.json +3 -1
  29. package/dist/r/empty.json +3 -1
  30. package/dist/r/entity-icon.json +3 -1
  31. package/dist/r/field.json +3 -1
  32. package/dist/r/hover-card.json +3 -1
  33. package/dist/r/input-group.json +3 -1
  34. package/dist/r/input-otp.json +3 -1
  35. package/dist/r/input.json +3 -1
  36. package/dist/r/item.json +3 -1
  37. package/dist/r/kbd.json +3 -1
  38. package/dist/r/label.json +3 -1
  39. package/dist/r/lib.json +50 -0
  40. package/dist/r/list-row.json +3 -1
  41. package/dist/r/menubar.json +3 -1
  42. package/dist/r/modal-dialog.json +2 -1
  43. package/dist/r/motion.json +22 -0
  44. package/dist/r/navigation-menu.json +3 -1
  45. package/dist/r/page.json +3 -1
  46. package/dist/r/pagination.json +3 -1
  47. package/dist/r/panel.json +3 -1
  48. package/dist/r/popover.json +3 -1
  49. package/dist/r/progress.json +3 -1
  50. package/dist/r/radio-group.json +3 -1
  51. package/dist/r/registry.json +320 -73
  52. package/dist/r/resizable.json +3 -1
  53. package/dist/r/scroll-area.json +3 -1
  54. package/dist/r/select.json +3 -1
  55. package/dist/r/separator.json +3 -1
  56. package/dist/r/settings.json +3 -1
  57. package/dist/r/sheet.json +2 -1
  58. package/dist/r/side-rail.json +3 -1
  59. package/dist/r/sidebar-nav.json +3 -1
  60. package/dist/r/skeleton.json +3 -1
  61. package/dist/r/slider.json +3 -1
  62. package/dist/r/spinner.json +3 -1
  63. package/dist/r/src/components/composites/account-menu/account-menu.tsx +150 -0
  64. package/dist/r/src/components/composites/account-menu/index.ts +1 -0
  65. package/dist/r/src/components/composites/list-row/index.ts +1 -0
  66. package/dist/r/src/components/composites/list-row/list-row.tsx +116 -0
  67. package/dist/r/src/components/composites/settings/index.ts +1 -0
  68. package/dist/r/src/components/composites/settings/settings.tsx +142 -0
  69. package/dist/r/src/components/composites/stat/index.ts +9 -0
  70. package/dist/r/src/components/composites/stat/stat.tsx +155 -0
  71. package/dist/r/src/components/composites/update-dialog/index.ts +7 -0
  72. package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +529 -0
  73. package/dist/r/src/components/composites/workspace-mark/index.ts +1 -0
  74. package/dist/r/src/components/composites/workspace-mark/workspace-mark.tsx +72 -0
  75. package/dist/r/src/components/conversation/conversation-avatar.tsx +60 -0
  76. package/dist/r/src/components/conversation/conversation-surface.tsx +107 -0
  77. package/dist/r/src/components/conversation/index.ts +25 -0
  78. package/dist/r/src/components/conversation/message-composer.tsx +239 -0
  79. package/dist/r/src/components/conversation/message-row.tsx +387 -0
  80. package/dist/r/src/components/conversation/thread-panel.tsx +141 -0
  81. package/dist/r/src/components/layout/app-shell/app-shell.tsx +92 -0
  82. package/dist/r/src/components/layout/app-shell/index.ts +1 -0
  83. package/dist/r/src/components/layout/page/index.ts +9 -0
  84. package/dist/r/src/components/layout/page/page.tsx +122 -0
  85. package/dist/r/src/components/layout/panel/index.ts +12 -0
  86. package/dist/r/src/components/layout/panel/panel.tsx +166 -0
  87. package/dist/r/src/components/layout/side-rail/index.ts +12 -0
  88. package/dist/r/src/components/layout/side-rail/side-rail-context.ts +42 -0
  89. package/dist/r/src/components/layout/side-rail/side-rail.tsx +405 -0
  90. package/dist/r/src/components/layout/sidebar-nav/index.ts +14 -0
  91. package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +244 -0
  92. package/dist/r/src/components/layout/status-bar/index.ts +1 -0
  93. package/dist/r/src/components/layout/status-bar/status-bar.tsx +73 -0
  94. package/dist/r/src/components/layout/top-bar/index.ts +10 -0
  95. package/dist/r/src/components/layout/top-bar/top-bar.tsx +166 -0
  96. package/dist/r/src/components/motion/index.ts +2 -0
  97. package/dist/r/src/components/motion/presence.tsx +32 -0
  98. package/dist/r/src/components/theme/appearance-panel.tsx +179 -0
  99. package/dist/r/src/components/theme/index.ts +22 -0
  100. package/dist/r/src/components/theme/theme-picker.tsx +174 -0
  101. package/dist/r/src/components/theme/theme-provider.tsx +309 -0
  102. package/dist/r/src/components/theme/theme-toggle.tsx +64 -0
  103. package/dist/r/src/components/ui/accordion/accordion.tsx +66 -0
  104. package/dist/r/src/components/ui/accordion/index.ts +1 -0
  105. package/dist/r/src/components/ui/alert/alert.tsx +95 -0
  106. package/dist/r/src/components/ui/alert/index.ts +1 -0
  107. package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +176 -0
  108. package/dist/r/src/components/ui/alert-dialog/index.ts +13 -0
  109. package/dist/r/src/components/ui/aspect-ratio/aspect-ratio.tsx +38 -0
  110. package/dist/r/src/components/ui/aspect-ratio/index.ts +1 -0
  111. package/dist/r/src/components/ui/avatar/avatar.tsx +114 -0
  112. package/dist/r/src/components/ui/avatar/index.ts +9 -0
  113. package/dist/r/src/components/ui/badge/badge.tsx +59 -0
  114. package/dist/r/src/components/ui/badge/index.ts +1 -0
  115. package/dist/r/src/components/ui/board/board.tsx +254 -0
  116. package/dist/r/src/components/ui/board/index.ts +10 -0
  117. package/dist/r/src/components/ui/breadcrumb/breadcrumb.tsx +117 -0
  118. package/dist/r/src/components/ui/breadcrumb/index.ts +9 -0
  119. package/dist/r/src/components/ui/button/button.tsx +89 -0
  120. package/dist/r/src/components/ui/button/index.ts +1 -0
  121. package/dist/r/src/components/ui/button-group/button-group.tsx +92 -0
  122. package/dist/r/src/components/ui/button-group/index.ts +6 -0
  123. package/dist/r/src/components/ui/calendar/calendar.tsx +277 -0
  124. package/dist/r/src/components/ui/calendar/index.ts +1 -0
  125. package/dist/r/src/components/ui/card/card.tsx +82 -0
  126. package/dist/r/src/components/ui/card/index.ts +10 -0
  127. package/dist/r/src/components/ui/carousel/carousel.tsx +209 -0
  128. package/dist/r/src/components/ui/carousel/index.ts +1 -0
  129. package/dist/r/src/components/ui/chart/chart.tsx +413 -0
  130. package/dist/r/src/components/ui/chart/index.ts +17 -0
  131. package/dist/r/src/components/ui/checkbox/checkbox.tsx +99 -0
  132. package/dist/r/src/components/ui/checkbox/index.ts +1 -0
  133. package/dist/r/src/components/ui/code-block/code-block.tsx +238 -0
  134. package/dist/r/src/components/ui/code-block/index.ts +1 -0
  135. package/dist/r/src/components/ui/collapsible/collapsible.tsx +54 -0
  136. package/dist/r/src/components/ui/collapsible/index.ts +1 -0
  137. package/dist/r/src/components/ui/combobox/combobox.tsx +142 -0
  138. package/dist/r/src/components/ui/combobox/index.ts +10 -0
  139. package/dist/r/src/components/ui/command/command.tsx +214 -0
  140. package/dist/r/src/components/ui/command/index.ts +12 -0
  141. package/dist/r/src/components/ui/context-menu/context-menu.tsx +163 -0
  142. package/dist/r/src/components/ui/context-menu/index.ts +15 -0
  143. package/dist/r/src/components/ui/detail-panel/detail-panel.tsx +161 -0
  144. package/dist/r/src/components/ui/detail-panel/index.ts +9 -0
  145. package/dist/r/src/components/ui/dialog/dialog.tsx +138 -0
  146. package/dist/r/src/components/ui/dialog/index.ts +14 -0
  147. package/dist/r/src/components/ui/diff-block/diff-block.tsx +286 -0
  148. package/dist/r/src/components/ui/diff-block/index.ts +11 -0
  149. package/dist/r/src/components/ui/drawer/drawer.tsx +144 -0
  150. package/dist/r/src/components/ui/drawer/index.ts +13 -0
  151. package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +203 -0
  152. package/dist/r/src/components/ui/dropdown-menu/index.ts +18 -0
  153. package/dist/r/src/components/ui/empty/empty.tsx +104 -0
  154. package/dist/r/src/components/ui/empty/index.ts +10 -0
  155. package/dist/r/src/components/ui/entity-icon/entity-icon.tsx +154 -0
  156. package/dist/r/src/components/ui/entity-icon/index.ts +1 -0
  157. package/dist/r/src/components/ui/field/field.tsx +131 -0
  158. package/dist/r/src/components/ui/field/index.ts +11 -0
  159. package/dist/r/src/components/ui/hover-card/hover-card.tsx +48 -0
  160. package/dist/r/src/components/ui/hover-card/index.ts +1 -0
  161. package/dist/r/src/components/ui/input/index.ts +1 -0
  162. package/dist/r/src/components/ui/input/input.tsx +41 -0
  163. package/dist/r/src/components/ui/input-group/index.ts +8 -0
  164. package/dist/r/src/components/ui/input-group/input-group.tsx +111 -0
  165. package/dist/r/src/components/ui/input-otp/index.ts +1 -0
  166. package/dist/r/src/components/ui/input-otp/input-otp.tsx +108 -0
  167. package/dist/r/src/components/ui/item/index.ts +10 -0
  168. package/dist/r/src/components/ui/item/item.tsx +146 -0
  169. package/dist/r/src/components/ui/kbd/index.ts +1 -0
  170. package/dist/r/src/components/ui/kbd/kbd.tsx +42 -0
  171. package/dist/r/src/components/ui/label/index.ts +1 -0
  172. package/dist/r/src/components/ui/label/label.tsx +36 -0
  173. package/dist/r/src/components/ui/menubar/index.ts +16 -0
  174. package/dist/r/src/components/ui/menubar/menubar.tsx +190 -0
  175. package/dist/r/src/components/ui/modal-dialog/index.ts +1 -0
  176. package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +95 -0
  177. package/dist/r/src/components/ui/navigation-menu/index.ts +13 -0
  178. package/dist/r/src/components/ui/navigation-menu/navigation-menu.tsx +229 -0
  179. package/dist/r/src/components/ui/pagination/index.ts +8 -0
  180. package/dist/r/src/components/ui/pagination/pagination.tsx +144 -0
  181. package/dist/r/src/components/ui/popover/index.ts +10 -0
  182. package/dist/r/src/components/ui/popover/popover.tsx +81 -0
  183. package/dist/r/src/components/ui/progress/index.ts +1 -0
  184. package/dist/r/src/components/ui/progress/progress.tsx +67 -0
  185. package/dist/r/src/components/ui/radio-group/index.ts +1 -0
  186. package/dist/r/src/components/ui/radio-group/radio-group.tsx +78 -0
  187. package/dist/r/src/components/ui/resizable/index.ts +6 -0
  188. package/dist/r/src/components/ui/resizable/resizable.tsx +74 -0
  189. package/dist/r/src/components/ui/scroll-area/index.ts +1 -0
  190. package/dist/r/src/components/ui/scroll-area/scroll-area.tsx +66 -0
  191. package/dist/r/src/components/ui/select/index.ts +11 -0
  192. package/dist/r/src/components/ui/select/select.tsx +188 -0
  193. package/dist/r/src/components/ui/separator/index.ts +1 -0
  194. package/dist/r/src/components/ui/separator/separator.tsx +40 -0
  195. package/dist/r/src/components/ui/sheet/index.ts +13 -0
  196. package/dist/r/src/components/ui/sheet/sheet.tsx +132 -0
  197. package/dist/r/src/components/ui/skeleton/index.ts +1 -0
  198. package/dist/r/src/components/ui/skeleton/skeleton.tsx +28 -0
  199. package/dist/r/src/components/ui/slider/index.ts +1 -0
  200. package/dist/r/src/components/ui/slider/slider.tsx +81 -0
  201. package/dist/r/src/components/ui/spinner/index.ts +1 -0
  202. package/dist/r/src/components/ui/spinner/spinner.tsx +58 -0
  203. package/dist/r/src/components/ui/status-chip/index.ts +8 -0
  204. package/dist/r/src/components/ui/status-chip/status-chip.tsx +142 -0
  205. package/dist/r/src/components/ui/switch/index.ts +1 -0
  206. package/dist/r/src/components/ui/switch/switch.tsx +100 -0
  207. package/dist/r/src/components/ui/table/index.ts +11 -0
  208. package/dist/r/src/components/ui/table/table.tsx +125 -0
  209. package/dist/r/src/components/ui/tabs/index.ts +8 -0
  210. package/dist/r/src/components/ui/tabs/tabs.tsx +77 -0
  211. package/dist/r/src/components/ui/textarea/index.ts +1 -0
  212. package/dist/r/src/components/ui/textarea/textarea.tsx +36 -0
  213. package/dist/r/src/components/ui/toast/index.ts +1 -0
  214. package/dist/r/src/components/ui/toast/toast.tsx +220 -0
  215. package/dist/r/src/components/ui/toggle/index.ts +1 -0
  216. package/dist/r/src/components/ui/toggle/toggle.tsx +60 -0
  217. package/dist/r/src/components/ui/toggle-group/index.ts +6 -0
  218. package/dist/r/src/components/ui/toggle-group/toggle-group.tsx +66 -0
  219. package/dist/r/src/components/ui/tooltip/index.ts +9 -0
  220. package/dist/r/src/components/ui/tooltip/tooltip.tsx +102 -0
  221. package/dist/r/src/lib/keyed-rows.ts +68 -0
  222. package/dist/r/src/lib/overlay.ts +70 -0
  223. package/dist/r/src/lib/themes.ts +490 -0
  224. package/dist/r/src/lib/tokens.ts +688 -0
  225. package/dist/r/src/lib/utils.ts +76 -0
  226. package/dist/r/src/lib/variants.ts +62 -0
  227. package/dist/r/src/lib/version-notes.ts +65 -0
  228. package/dist/r/src/styles/base.css +644 -0
  229. package/dist/r/src/styles/fonts.css +26 -0
  230. package/dist/r/src/styles/globals.css +18 -0
  231. package/dist/r/src/styles/theme.css +864 -0
  232. package/dist/r/stat.json +3 -1
  233. package/dist/r/status-bar.json +3 -1
  234. package/dist/r/status-chip.json +2 -1
  235. package/dist/r/switch.json +3 -1
  236. package/dist/r/table.json +3 -1
  237. package/dist/r/tabs.json +3 -1
  238. package/dist/r/textarea.json +3 -1
  239. package/dist/r/theming.json +42 -0
  240. package/dist/r/toast.json +3 -1
  241. package/dist/r/toggle-group.json +2 -1
  242. package/dist/r/toggle.json +3 -1
  243. package/dist/r/tooltip.json +3 -1
  244. package/dist/r/top-bar.json +3 -1
  245. package/dist/r/update-dialog.json +2 -1
  246. package/dist/r/workspace-mark.json +2 -1
  247. package/package.json +1 -1
  248. package/registry.json +320 -73
@@ -0,0 +1,125 @@
1
+ import type { ComponentProps } from 'solid-js'
2
+ import { splitProps } from 'solid-js'
3
+ import { cn } from '../../../lib/utils'
4
+
5
+ /**
6
+ * Table.
7
+ *
8
+ * Semantic markup, not a grid of divs. A `<table>` with a caption, a header
9
+ * scope and cells is navigable by a screen reader in ways a flex layout cannot
10
+ * be reproduced into, and it is what makes "row 3 of 12, Name column" work.
11
+ *
12
+ * Two decisions worth keeping:
13
+ *
14
+ * - The header is sticky by default. A scrollable table whose header leaves
15
+ * the viewport makes every row below it anonymous.
16
+ * - Numbers are right-aligned and tabular. `text-end` plus `tabular-nums` is
17
+ * what lets a column of figures be compared by eye; a proportional font
18
+ * with ragged digits is unreadable at a glance.
19
+ *
20
+ * `TableNumericCell` exists so callers do not have to remember the second
21
+ * half of that rule.
22
+ */
23
+ export function Table(props: ComponentProps<'table'>) {
24
+ const [local, rest] = splitProps(props, ['class'])
25
+
26
+ return (
27
+ <div data-slot="table-container" class="relative w-full overflow-x-auto">
28
+ <table data-slot="table" class={cn('w-full caption-bottom text-sm', local.class)} {...rest} />
29
+ </div>
30
+ )
31
+ }
32
+
33
+ export function TableHeader(props: ComponentProps<'thead'>) {
34
+ const [local, rest] = splitProps(props, ['class'])
35
+ return (
36
+ <thead
37
+ data-slot="table-header"
38
+ class={cn(
39
+ '[&_tr]:border-b [&_tr]:border-border sticky top-0 z-(--z-docked) bg-background',
40
+ local.class
41
+ )}
42
+ {...rest}
43
+ />
44
+ )
45
+ }
46
+
47
+ export function TableBody(props: ComponentProps<'tbody'>) {
48
+ const [local, rest] = splitProps(props, ['class'])
49
+ return (
50
+ <tbody data-slot="table-body" class={cn('[&_tr:last-child]:border-0', local.class)} {...rest} />
51
+ )
52
+ }
53
+
54
+ export function TableFooter(props: ComponentProps<'tfoot'>) {
55
+ const [local, rest] = splitProps(props, ['class'])
56
+ return (
57
+ <tfoot
58
+ data-slot="table-footer"
59
+ class={cn(
60
+ 'bg-surface-hover border-t border-border font-medium [&>tr]:last:border-b-0',
61
+ local.class
62
+ )}
63
+ {...rest}
64
+ />
65
+ )
66
+ }
67
+
68
+ export function TableRow(props: ComponentProps<'tr'>) {
69
+ const [local, rest] = splitProps(props, ['class'])
70
+
71
+ return (
72
+ <tr
73
+ data-slot="table-row"
74
+ class={cn(
75
+ 'border-b border-border transition-colors ease-out',
76
+ 'hover:bg-surface-hover data-[state=selected]:bg-primary-subtle',
77
+ local.class
78
+ )}
79
+ {...rest}
80
+ />
81
+ )
82
+ }
83
+
84
+ export function TableHead(props: ComponentProps<'th'>) {
85
+ const [local, rest] = splitProps(props, ['class'])
86
+
87
+ return (
88
+ <th
89
+ data-slot="table-head"
90
+ scope={props.scope ?? 'col'}
91
+ class={cn(
92
+ 'text-muted-foreground h-9 px-3 text-start align-middle text-xs font-medium whitespace-nowrap',
93
+ local.class
94
+ )}
95
+ {...rest}
96
+ />
97
+ )
98
+ }
99
+
100
+ export function TableCell(props: ComponentProps<'td'>) {
101
+ const [local, rest] = splitProps(props, ['class'])
102
+ return <td data-slot="table-cell" class={cn('px-3 py-2 align-middle', local.class)} {...rest} />
103
+ }
104
+
105
+ export function TableNumericCell(props: ComponentProps<'td'>) {
106
+ const [local, rest] = splitProps(props, ['class'])
107
+ return (
108
+ <td
109
+ data-slot="table-cell"
110
+ class={cn('px-3 py-2 text-end align-middle tabular-nums', local.class)}
111
+ {...rest}
112
+ />
113
+ )
114
+ }
115
+
116
+ export function TableCaption(props: ComponentProps<'caption'>) {
117
+ const [local, rest] = splitProps(props, ['class'])
118
+ return (
119
+ <caption
120
+ data-slot="table-caption"
121
+ class={cn('text-muted-foreground mt-3 text-sm', local.class)}
122
+ {...rest}
123
+ />
124
+ )
125
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ Tabs,
3
+ TabsContent,
4
+ TabsList,
5
+ TabsTrigger,
6
+ type TabsListProps,
7
+ type TabsTriggerProps,
8
+ } from './tabs'
@@ -0,0 +1,77 @@
1
+ import { Tabs as KobalteTabs } from '@kobalte/core/tabs'
2
+ import type { ComponentProps } from 'solid-js'
3
+ import { splitProps } from 'solid-js'
4
+ import { cn } from '../../../lib/utils'
5
+
6
+ /**
7
+ * Tabs.
8
+ *
9
+ * For switching between sibling views of the *same* subject — a file's code,
10
+ * diff and history. Not for moving between pages: a tab is expected to keep
11
+ * its panel and its scroll position, which a route does not.
12
+ *
13
+ * `appearance="segmented"` gives the joined bar KiroCrew uses inside a pane
14
+ * where a full-width underline would collide with the panel's own header rule.
15
+ */
16
+ export function Tabs(props: ComponentProps<typeof KobalteTabs>) {
17
+ const [local, rest] = splitProps(props, ['class'])
18
+ return (
19
+ <KobalteTabs
20
+ class={cn('flex flex-col gap-2 data-[orientation=vertical]:flex-row', local.class)}
21
+ {...rest}
22
+ />
23
+ )
24
+ }
25
+
26
+ export type TabsListProps = ComponentProps<typeof KobalteTabs.List> & {
27
+ appearance?: 'underline' | 'segmented'
28
+ }
29
+
30
+ export function TabsList(props: TabsListProps) {
31
+ const [local, rest] = splitProps(props, ['class', 'appearance'])
32
+
33
+ return (
34
+ <KobalteTabs.List
35
+ class={cn(
36
+ 'inline-flex w-fit shrink-0 items-center justify-center',
37
+ local.appearance === 'segmented'
38
+ ? 'gap-0.5 rounded-lg bg-surface-hover p-0.5'
39
+ : 'gap-1 rounded-none border-b border-border',
40
+ 'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',
41
+ local.class
42
+ )}
43
+ {...rest}
44
+ />
45
+ )
46
+ }
47
+
48
+ export type TabsTriggerProps = ComponentProps<typeof KobalteTabs.Trigger> & {
49
+ appearance?: 'underline' | 'segmented'
50
+ }
51
+
52
+ export function TabsTrigger(props: TabsTriggerProps) {
53
+ const [local, rest] = splitProps(props, ['class', 'appearance'])
54
+
55
+ return (
56
+ <KobalteTabs.Trigger
57
+ class={cn(
58
+ 'inline-flex shrink-0 items-center justify-center gap-1.5 whitespace-nowrap text-sm font-medium',
59
+ 'transition-colors ease-out outline-none select-none',
60
+ 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',
61
+ 'disabled:pointer-events-none disabled:opacity-50',
62
+ 'text-muted-foreground hover:text-foreground data-[selected]:text-foreground',
63
+ '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4',
64
+ local.appearance === 'segmented'
65
+ ? 'h-control-sm rounded-md px-control-sm data-[selected]:bg-card data-[selected]:shadow-xs'
66
+ : 'h-control-md -mb-px rounded-none border-b-2 border-transparent px-2 pb-2 data-[selected]:border-primary',
67
+ local.class
68
+ )}
69
+ {...rest}
70
+ />
71
+ )
72
+ }
73
+
74
+ export function TabsContent(props: ComponentProps<typeof KobalteTabs.Content>) {
75
+ const [local, rest] = splitProps(props, ['class'])
76
+ return <KobalteTabs.Content class={cn('flex-1 outline-none', local.class)} {...rest} />
77
+ }
@@ -0,0 +1 @@
1
+ export { Textarea } from './textarea'
@@ -0,0 +1,36 @@
1
+ import type { ComponentProps } from 'solid-js'
2
+ import { splitProps } from 'solid-js'
3
+ import { cn } from '../../../lib/utils'
4
+
5
+ /**
6
+ * Textarea.
7
+ *
8
+ * Shares the Input's border, focus and invalid treatment exactly — the two are
9
+ * the same control at different aspect ratios, and a form that mixes them must
10
+ * not show a seam between them.
11
+ *
12
+ * `field-sizing: content` lets the element grow with its content where the
13
+ * engine supports it, which is the behaviour a chat composer wants; `rows`
14
+ * remains the fallback so an unsupported engine still gets a usable height.
15
+ */
16
+ export function Textarea(props: ComponentProps<'textarea'>) {
17
+ const [local, rest] = splitProps(props, ['class'])
18
+
19
+ return (
20
+ <textarea
21
+ data-slot="textarea"
22
+ class={cn(
23
+ 'flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-control-md py-2 text-sm',
24
+ 'transition-[color,box-shadow,border-color] ease-out outline-none',
25
+ 'placeholder:text-muted-foreground',
26
+ 'selection:bg-primary selection:text-primary-foreground',
27
+ 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',
28
+ 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',
29
+ 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
30
+ 'resize-y',
31
+ local.class
32
+ )}
33
+ {...rest}
34
+ />
35
+ )
36
+ }
@@ -0,0 +1 @@
1
+ export { Toaster, toast, toaster, type ToastOptions, type ToasterProps } from './toast'
@@ -0,0 +1,220 @@
1
+ import { Toast as KobalteToast, type ToastComponentProps, toaster } from '@kobalte/core/toast'
2
+ import { X } from 'lucide-solid'
3
+ import type { ComponentProps, JSX } from 'solid-js'
4
+ import { Show, splitProps } from 'solid-js'
5
+ import { cn } from '../../../lib/utils'
6
+
7
+ /**
8
+ * Toast.
9
+ *
10
+ * A short, self-dismissing message about something that already happened.
11
+ *
12
+ * The rules that make toasts helpful rather than hostile are built into this
13
+ * API rather than left to callers:
14
+ *
15
+ * - A toast never carries the only route to an action. Anything important
16
+ * enough to need doing belongs in the interface, not in a message that
17
+ * disappears. `action` exists, but it is a convenience, not a flow.
18
+ * - Errors from user-initiated work get `priority="high"` so a screen reader
19
+ * interrupts to announce them; background progress uses the default low
20
+ * priority so it is not read over whatever the user is doing.
21
+ * - A toast with a way to undo is preferred to a confirmation dialog for a
22
+ * reversible action. Undo after the fact costs the user nothing; a modal
23
+ * before it costs everyone a click.
24
+ *
25
+ * `Toaster` is mounted once, near the root of the app.
26
+ */
27
+
28
+ type ToastTone = 'default' | 'success' | 'warning' | 'destructive' | 'info'
29
+
30
+ /**
31
+ * The tone dot's colour. A custom property rather than five colour utilities
32
+ * because the value is applied inline (the tone is data, not markup) and a
33
+ * Tailwind colour class cannot be built from a runtime value without becoming
34
+ * invisible to the linter.
35
+ */
36
+ const toastTones: Record<ToastTone, string> = {
37
+ default: 'var(--foreground)',
38
+ success: 'var(--success)',
39
+ warning: 'var(--warning)',
40
+ destructive: 'var(--destructive)',
41
+ info: 'var(--info)',
42
+ }
43
+
44
+ export type ToastOptions = {
45
+ title: string
46
+ description?: string
47
+ tone?: ToastTone
48
+ /** A control rendered inside the toast, usually an Undo. */
49
+ action?: JSX.Element
50
+ /** Keep the toast until it is dismissed. Use for a failure the user must see. */
51
+ persistent?: boolean
52
+ /** Milliseconds before auto-dismiss. Overrides the region's setting. */
53
+ duration?: number
54
+ /** Which Toaster region to render into. */
55
+ region?: string
56
+ }
57
+
58
+ function ToastCard(props: ToastComponentProps & ToastOptions) {
59
+ const tone = () => props.tone ?? 'default'
60
+
61
+ return (
62
+ <KobalteToast
63
+ toastId={props.toastId}
64
+ /**
65
+ * A user-initiated outcome is announced; a background one waits its turn.
66
+ * A failure the user caused is worth interrupting for; a sync finishing
67
+ * quietly is not.
68
+ */
69
+ priority={tone() === 'destructive' ? 'high' : 'low'}
70
+ duration={props.duration}
71
+ persistent={props.persistent}
72
+ class={cn(
73
+ 'pointer-events-auto flex w-full items-start gap-3 rounded-xl border border-border bg-popover p-3 shadow-lg',
74
+ 'data-[opened]:animate-in data-[opened]:slide-in-from-right-full data-[opened]:fade-in-0',
75
+ 'data-[closed]:animate-out data-[closed]:slide-out-to-right-full data-[closed]:fade-out-0',
76
+ 'data-[swipe=move]:translate-x-(--kb-toast-swipe-move-x) data-[swipe=move]:transition-none',
77
+ 'data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-transform',
78
+ 'data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full'
79
+ )}
80
+ style={{ '--toast-tone': toastTones[tone()] }}
81
+ >
82
+ <span
83
+ aria-hidden="true"
84
+ class="mt-1.5 size-1.5 shrink-0 rounded-full"
85
+ style={{ 'background-color': 'var(--toast-tone)' }}
86
+ />
87
+ <div class="flex min-w-0 flex-1 flex-col gap-0.5">
88
+ <KobalteToast.Title class="text-sm font-medium">{props.title}</KobalteToast.Title>
89
+ <Show when={props.description}>
90
+ <KobalteToast.Description class="text-sm text-muted-foreground">
91
+ {props.description}
92
+ </KobalteToast.Description>
93
+ </Show>
94
+ <Show when={props.action}>
95
+ <div class="mt-1.5 flex items-center gap-2">{props.action}</div>
96
+ </Show>
97
+ </div>
98
+ <KobalteToast.CloseButton
99
+ aria-label="Dismiss notification"
100
+ class="text-muted-foreground shrink-0 rounded-sm p-0.5 transition-colors ease-out outline-none hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle"
101
+ >
102
+ <X class="size-3.5" />
103
+ </KobalteToast.CloseButton>
104
+ </KobalteToast>
105
+ )
106
+ }
107
+
108
+ /**
109
+ * The toast API. `show` is the general form; the tone helpers are shorthand for
110
+ * the four cases that come up constantly.
111
+ */
112
+ export const toast = {
113
+ show(options: ToastOptions): number {
114
+ return toaster.show((props) => <ToastCard {...props} {...options} />, {
115
+ region: options.region,
116
+ })
117
+ },
118
+ success(title: string, options?: Omit<ToastOptions, 'title' | 'tone'>): number {
119
+ return toast.show({ ...options, title, tone: 'success' })
120
+ },
121
+ error(title: string, options?: Omit<ToastOptions, 'title' | 'tone'>): number {
122
+ return toast.show({ ...options, title, tone: 'destructive', persistent: true })
123
+ },
124
+ warning(title: string, options?: Omit<ToastOptions, 'title' | 'tone'>): number {
125
+ return toast.show({ ...options, title, tone: 'warning' })
126
+ },
127
+ info(title: string, options?: Omit<ToastOptions, 'title' | 'tone'>): number {
128
+ return toast.show({ ...options, title, tone: 'info' })
129
+ },
130
+ /**
131
+ * A toast that resolves with a promise: pending, then success or failure.
132
+ * The right shape for an operation with a visible duration, because the user
133
+ * gets one message instead of three.
134
+ */
135
+ promise<T>(
136
+ promise: Promise<T> | (() => Promise<T>),
137
+ messages: {
138
+ pending: string
139
+ success: string | ((data: T) => string)
140
+ error: string | ((error: unknown) => string)
141
+ }
142
+ ): Promise<T> {
143
+ const resolved = typeof promise === 'function' ? promise() : promise
144
+ toaster.promise(resolved, (props) => {
145
+ const tone: ToastTone =
146
+ props.state === 'fulfilled'
147
+ ? 'success'
148
+ : props.state === 'rejected'
149
+ ? 'destructive'
150
+ : 'default'
151
+ const title =
152
+ props.state === 'pending'
153
+ ? messages.pending
154
+ : props.state === 'fulfilled'
155
+ ? typeof messages.success === 'function'
156
+ ? messages.success(props.data as T)
157
+ : messages.success
158
+ : typeof messages.error === 'function'
159
+ ? messages.error(props.error)
160
+ : messages.error
161
+ return (
162
+ <ToastCard
163
+ toastId={props.toastId}
164
+ title={title}
165
+ tone={tone}
166
+ persistent={props.state === 'rejected'}
167
+ />
168
+ )
169
+ })
170
+ return resolved
171
+ },
172
+ dismiss: toaster.dismiss,
173
+ clear: toaster.clear,
174
+ }
175
+
176
+ export type ToasterProps = ComponentProps<typeof KobalteToast.Region> & {
177
+ /** Where the stack sits. Defaults to the bottom-right, clear of the shell. */
178
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
179
+ region?: string
180
+ }
181
+
182
+ const toasterPosition = {
183
+ 'top-left': 'top-0 left-0 items-start',
184
+ 'top-right': 'top-0 right-0 items-end',
185
+ 'bottom-left': 'bottom-0 left-0 items-start',
186
+ 'bottom-right': 'bottom-0 right-0 items-end',
187
+ }
188
+
189
+ /** Mount once, near the root. Renders the stack and owns its timing defaults. */
190
+ export function Toaster(props: ToasterProps) {
191
+ const [local, rest] = splitProps(props, ['position', 'region', 'class'])
192
+
193
+ return (
194
+ <KobalteToast.Region
195
+ regionId={local.region}
196
+ duration={5000}
197
+ limit={3}
198
+ swipeDirection="right"
199
+ pauseOnInteraction
200
+ pauseOnPageIdle
201
+ /**
202
+ * The toast region is a top layer: opening a dialog must not hide an
203
+ * in-flight notification, and clicking a toast must not dismiss the
204
+ * dialog behind it.
205
+ */
206
+ class="pointer-events-none fixed z-(--z-toast) flex max-h-screen w-full flex-col gap-2 p-4 sm:max-w-sm"
207
+ {...rest}
208
+ >
209
+ <KobalteToast.List
210
+ class={cn(
211
+ 'flex flex-col gap-2',
212
+ toasterPosition[local.position ?? 'bottom-right'],
213
+ local.class
214
+ )}
215
+ />
216
+ </KobalteToast.Region>
217
+ )
218
+ }
219
+
220
+ export { toaster }
@@ -0,0 +1 @@
1
+ export { Toggle, toggleVariants, type ToggleProps } from './toggle'
@@ -0,0 +1,60 @@
1
+ import { ToggleButton } from '@kobalte/core/toggle-button'
2
+ import type { ComponentProps } from 'solid-js'
3
+ import { splitProps } from 'solid-js'
4
+ import { cva, controlInteractive, controlSize, type VariantProps } from '../../../lib/variants'
5
+ import { cn } from '../../../lib/utils'
6
+
7
+ /**
8
+ * Toggle.
9
+ *
10
+ * A button that stays pressed. The difference from Button is state, not looks:
11
+ * a Toggle reports `aria-pressed` and holds its pressed appearance until
12
+ * released, which is what makes it right for a formatting control and wrong
13
+ * for a command.
14
+ *
15
+ * Kobalte supplies the pressed state and the keyboard behaviour; the styling
16
+ * adds the one thing a headless primitive cannot know — that a pressed toggle
17
+ * in a toolbar should read as *filled*, not merely outlined.
18
+ */
19
+ export const toggleVariants = cva(
20
+ `${controlInteractive} inline-flex items-center justify-center rounded-md font-medium whitespace-nowrap select-none hover:bg-surface-hover hover:text-foreground data-[pressed]:bg-surface-active data-[pressed]:text-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,
21
+ {
22
+ variants: {
23
+ variant: {
24
+ default: 'bg-transparent',
25
+ /** Sits inside a field or toolbar that already has a fill. */
26
+ outline: 'border border-border bg-transparent',
27
+ /** Filled even when unpressed, for a segmented control's idle item. */
28
+ subtle: 'bg-surface-hover',
29
+ },
30
+ size: {
31
+ '2xs': `${controlSize['2xs']} [&_svg]:size-3`,
32
+ xs: `${controlSize.xs} [&_svg]:size-3.5`,
33
+ sm: `${controlSize.sm} [&_svg]:size-3.5`,
34
+ md: `${controlSize.md} [&_svg]:size-4`,
35
+ lg: `${controlSize.lg} [&_svg]:size-4`,
36
+ xl: `${controlSize.xl} [&_svg]:size-5`,
37
+ 'icon-2xs': 'size-control-2xs p-0 [&_svg]:size-3',
38
+ 'icon-xs': 'size-control-xs p-0 [&_svg]:size-3.5',
39
+ 'icon-sm': 'size-control-sm p-0 [&_svg]:size-3.5',
40
+ 'icon-md': 'size-control-md p-0 [&_svg]:size-4',
41
+ 'icon-lg': 'size-control-lg p-0 [&_svg]:size-4',
42
+ 'icon-xl': 'size-control-xl p-0 [&_svg]:size-5',
43
+ },
44
+ },
45
+ defaultVariants: { variant: 'default', size: 'md' },
46
+ }
47
+ )
48
+
49
+ export type ToggleProps = ComponentProps<typeof ToggleButton> & VariantProps<typeof toggleVariants>
50
+
51
+ export function Toggle(props: ToggleProps) {
52
+ const [local, rest] = splitProps(props, ['variant', 'size', 'class'])
53
+
54
+ return (
55
+ <ToggleButton
56
+ class={cn(toggleVariants({ variant: local.variant, size: local.size }), local.class)}
57
+ {...rest}
58
+ />
59
+ )
60
+ }
@@ -0,0 +1,6 @@
1
+ export {
2
+ ToggleGroup,
3
+ ToggleGroupItem,
4
+ type ToggleGroupItemProps,
5
+ type ToggleGroupProps,
6
+ } from './toggle-group'
@@ -0,0 +1,66 @@
1
+ import { ToggleGroup as KobalteToggleGroup } from '@kobalte/core/toggle-group'
2
+ import type { ComponentProps } from 'solid-js'
3
+ import { splitProps } from 'solid-js'
4
+ import type { VariantProps } from '../../../lib/variants'
5
+ import { cn } from '../../../lib/utils'
6
+ import { toggleVariants } from '../toggle/toggle'
7
+
8
+ /**
9
+ * ToggleGroup.
10
+ *
11
+ * A set of related toggles that behave as one control: at most one pressed
12
+ * (`multiple={false}`, the default) or any number (`multiple={true}`). The
13
+ * group owns the selection and the roving focus, which is what makes arrow keys
14
+ * move between items and a screen reader announce the position within the set.
15
+ * A row of independent Toggles looks identical and does neither.
16
+ *
17
+ * `attached` joins the items into one rounded run for a segmented control. The
18
+ * joining lives on the *group*, via child selectors, so an item never has to
19
+ * know whether it sits at an end — which is also where the border collapse
20
+ * (`-ms-px`) belongs.
21
+ */
22
+ /**
23
+ * `multiple` is optional here although Kobalte requires it: the primitive models
24
+ * single and multiple selection as two shapes, which forces every caller to state
25
+ * the obvious. Defaulting to single selection keeps the common case a one-word
26
+ * component, and a caller that wants many passes `multiple`.
27
+ */
28
+ export type ToggleGroupProps = Omit<ComponentProps<typeof KobalteToggleGroup>, 'multiple'> & {
29
+ multiple?: boolean
30
+ variant?: VariantProps<typeof toggleVariants>['variant']
31
+ size?: VariantProps<typeof toggleVariants>['size']
32
+ /** Join the items into one rounded run instead of a spaced row. */
33
+ attached?: boolean
34
+ }
35
+
36
+ export function ToggleGroup(props: ToggleGroupProps) {
37
+ const [local, rest] = splitProps(props, ['class', 'attached', 'multiple'])
38
+
39
+ return (
40
+ <KobalteToggleGroup
41
+ multiple={local.multiple ?? false}
42
+ class={cn(
43
+ 'flex w-fit flex-row items-center',
44
+ local.attached
45
+ ? '[&>*:first-child]:rounded-e-none [&>*:last-child]:rounded-s-none [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:not(:first-child)]:-ms-px'
46
+ : 'gap-1',
47
+ local.class
48
+ )}
49
+ {...rest}
50
+ />
51
+ )
52
+ }
53
+
54
+ export type ToggleGroupItemProps = ComponentProps<typeof KobalteToggleGroup.Item> &
55
+ VariantProps<typeof toggleVariants>
56
+
57
+ export function ToggleGroupItem(props: ToggleGroupItemProps) {
58
+ const [local, rest] = splitProps(props, ['class', 'variant', 'size'])
59
+
60
+ return (
61
+ <KobalteToggleGroup.Item
62
+ class={cn(toggleVariants({ variant: local.variant, size: local.size }), local.class)}
63
+ {...rest}
64
+ />
65
+ )
66
+ }
@@ -0,0 +1,9 @@
1
+ export {
2
+ Tooltip,
3
+ TooltipContent,
4
+ TooltipProvider,
5
+ TooltipTrigger,
6
+ type TooltipContentProps,
7
+ type TooltipProviderProps,
8
+ type TooltipRootProps,
9
+ } from './tooltip'