@keboola/design 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) hide show
  1. package/README.md +83 -0
  2. package/package.json +151 -0
  3. package/src/blocks/AIKit/AnswerSummary.stories.tsx +38 -0
  4. package/src/blocks/AIKit/AnswerSummary.tsx +63 -0
  5. package/src/blocks/AIKit/CollapsibleStepHeader.stories.tsx +53 -0
  6. package/src/blocks/AIKit/CollapsibleStepHeader.tsx +65 -0
  7. package/src/blocks/AIKit/InlineStepDetail.stories.tsx +25 -0
  8. package/src/blocks/AIKit/InlineStepDetail.tsx +13 -0
  9. package/src/blocks/AIKit/InlineStepLabel.stories.tsx +37 -0
  10. package/src/blocks/AIKit/InlineStepLabel.tsx +36 -0
  11. package/src/blocks/AIKit/MessageBubble.stories.tsx +137 -0
  12. package/src/blocks/AIKit/MessageBubble.tsx +68 -0
  13. package/src/blocks/AIKit/PlanApproval.stories.tsx +121 -0
  14. package/src/blocks/AIKit/PlanApproval.test.tsx +241 -0
  15. package/src/blocks/AIKit/PlanApproval.tsx +345 -0
  16. package/src/blocks/AIKit/PlanRewritingIndicator.test.tsx +17 -0
  17. package/src/blocks/AIKit/PlanRewritingIndicator.tsx +20 -0
  18. package/src/blocks/AIKit/PromptInput.stories.tsx +98 -0
  19. package/src/blocks/AIKit/PromptInput.tsx +218 -0
  20. package/src/blocks/AIKit/PromptInputAction.tsx +18 -0
  21. package/src/blocks/AIKit/PromptInputSubmit.tsx +55 -0
  22. package/src/blocks/AIKit/Question.stories.tsx +235 -0
  23. package/src/blocks/AIKit/Question.tsx +323 -0
  24. package/src/blocks/AIKit/QuestionBlock.stories.tsx +99 -0
  25. package/src/blocks/AIKit/QuestionBlock.tsx +83 -0
  26. package/src/blocks/AIKit/SuggestedPrompt.stories.tsx +88 -0
  27. package/src/blocks/AIKit/SuggestedPrompt.tsx +35 -0
  28. package/src/blocks/AIKit/ThinkingIndicator.stories.tsx +21 -0
  29. package/src/blocks/AIKit/ThinkingIndicator.tsx +14 -0
  30. package/src/blocks/AIKit/index.ts +12 -0
  31. package/src/blocks/AutoSaveTextarea/AutoSaveTextarea.stories.tsx +78 -0
  32. package/src/blocks/AutoSaveTextarea/AutoSaveTextarea.tsx +103 -0
  33. package/src/blocks/AutoSaveTextarea/index.ts +1 -0
  34. package/src/blocks/ClipboardButton/ClipboardButton.stories.tsx +28 -0
  35. package/src/blocks/ClipboardButton/ClipboardButton.tsx +41 -0
  36. package/src/blocks/ClipboardButton/ClipboardInline.tsx +41 -0
  37. package/src/blocks/ClipboardButton/index.ts +2 -0
  38. package/src/blocks/ColorInput/ColorInput.stories.tsx +109 -0
  39. package/src/blocks/ColorInput/ColorInput.test.tsx +163 -0
  40. package/src/blocks/ColorInput/ColorInput.tsx +169 -0
  41. package/src/blocks/ColorInput/ColorPicker.tsx +39 -0
  42. package/src/blocks/ColorInput/index.ts +1 -0
  43. package/src/blocks/ColorInput/utils.test.ts +189 -0
  44. package/src/blocks/ColorInput/utils.ts +74 -0
  45. package/src/blocks/EmptyConfigurationActionCard/EmptyConfigurationActionCard.stories.tsx +30 -0
  46. package/src/blocks/EmptyConfigurationActionCard/EmptyConfigurationActionCard.tsx +20 -0
  47. package/src/blocks/EmptyConfigurationActionCard/index.ts +1 -0
  48. package/src/blocks/EmptyState/EmptyState.stories.tsx +93 -0
  49. package/src/blocks/EmptyState/EmptyState.tsx +130 -0
  50. package/src/blocks/EmptyState/index.ts +1 -0
  51. package/src/blocks/ErrorState/ErrorState.stories.tsx +125 -0
  52. package/src/blocks/ErrorState/ErrorState.tsx +132 -0
  53. package/src/blocks/ErrorState/index.ts +1 -0
  54. package/src/blocks/Form/components/FormBody.tsx +27 -0
  55. package/src/blocks/Form/components/SubmitButton.tsx +30 -0
  56. package/src/blocks/Form/connectors/CheckboxField.tsx +34 -0
  57. package/src/blocks/Form/connectors/FieldShell.tsx +46 -0
  58. package/src/blocks/Form/connectors/NumberField.tsx +36 -0
  59. package/src/blocks/Form/connectors/PasswordField.tsx +38 -0
  60. package/src/blocks/Form/connectors/SelectField.tsx +73 -0
  61. package/src/blocks/Form/connectors/SwitchField.tsx +34 -0
  62. package/src/blocks/Form/connectors/TextAreaField.tsx +36 -0
  63. package/src/blocks/Form/connectors/TextField.tsx +36 -0
  64. package/src/blocks/Form/contexts.ts +4 -0
  65. package/src/blocks/Form/formHook.ts +30 -0
  66. package/src/blocks/Form/index.ts +2 -0
  67. package/src/blocks/Form/setServerFieldErrors.test.ts +38 -0
  68. package/src/blocks/Form/setServerFieldErrors.ts +21 -0
  69. package/src/blocks/MermaidDiagram/MermaidDiagram.stories.tsx +87 -0
  70. package/src/blocks/MermaidDiagram/MermaidDiagram.tsx +266 -0
  71. package/src/blocks/MermaidDiagram/index.ts +1 -0
  72. package/src/blocks/MultiActionButtonGroup/MultiActionButton.stories.tsx +118 -0
  73. package/src/blocks/MultiActionButtonGroup/MultiActionButton.tsx +40 -0
  74. package/src/blocks/MultiActionButtonGroup/MultiActionButtonGroup.tsx +16 -0
  75. package/src/blocks/MultiActionButtonGroup/index.ts +1 -0
  76. package/src/blocks/MultiCombobox/MultiCombobox.stories.tsx +324 -0
  77. package/src/blocks/MultiCombobox/MultiCombobox.tsx +241 -0
  78. package/src/blocks/MultiCombobox/index.ts +1 -0
  79. package/src/blocks/NumberInput/NumberInput.stories.tsx +112 -0
  80. package/src/blocks/NumberInput/NumberInput.test.tsx +148 -0
  81. package/src/blocks/NumberInput/NumberInput.tsx +89 -0
  82. package/src/blocks/NumberInput/index.ts +1 -0
  83. package/src/blocks/PageHeader/AGENTS.md +77 -0
  84. package/src/blocks/PageHeader/PageHeader.stories.tsx +272 -0
  85. package/src/blocks/PageHeader/PageHeader.tsx +7 -0
  86. package/src/blocks/PageHeader/PageHeaderDetail.tsx +62 -0
  87. package/src/blocks/PageHeader/PageHeaderIndex.tsx +56 -0
  88. package/src/blocks/PageHeader/index.ts +1 -0
  89. package/src/blocks/PageHeader/styles.ts +6 -0
  90. package/src/blocks/PageLayout/AGENTS.md +94 -0
  91. package/src/blocks/PageLayout/PageLayout.stories.tsx +143 -0
  92. package/src/blocks/PageLayout/PageLayout.tsx +130 -0
  93. package/src/blocks/PageLayout/index.ts +1 -0
  94. package/src/blocks/PasswordInput/PasswordInput.stories.tsx +114 -0
  95. package/src/blocks/PasswordInput/PasswordInput.test.tsx +219 -0
  96. package/src/blocks/PasswordInput/PasswordInput.tsx +180 -0
  97. package/src/blocks/PasswordInput/index.ts +1 -0
  98. package/src/blocks/SearchInput/SearchInput.stories.tsx +127 -0
  99. package/src/blocks/SearchInput/SearchInput.test.tsx +162 -0
  100. package/src/blocks/SearchInput/SearchInput.tsx +146 -0
  101. package/src/blocks/SearchInput/index.ts +1 -0
  102. package/src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.stories.tsx +73 -0
  103. package/src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.tsx +89 -0
  104. package/src/blocks/SearchInputWithNavigation/index.ts +1 -0
  105. package/src/blocks/SplitButton/SplitButton.stories.tsx +88 -0
  106. package/src/blocks/SplitButton/SplitButton.tsx +68 -0
  107. package/src/blocks/SplitButton/index.ts +1 -0
  108. package/src/blocks/Tagger/TagItem.tsx +29 -0
  109. package/src/blocks/Tagger/TagSelectPopover/TagSelectCreateItem.tsx +42 -0
  110. package/src/blocks/Tagger/TagSelectPopover/TagSelectItem.tsx +31 -0
  111. package/src/blocks/Tagger/TagSelectPopover/TagSelectList.tsx +67 -0
  112. package/src/blocks/Tagger/TagSelectPopover/TagSelectPopover.tsx +34 -0
  113. package/src/blocks/Tagger/TagSelectPopover/TagSelectValue.tsx +47 -0
  114. package/src/blocks/Tagger/TagSelectPopover/index.ts +1 -0
  115. package/src/blocks/Tagger/Tagger.stories.tsx +80 -0
  116. package/src/blocks/Tagger/Tagger.tsx +101 -0
  117. package/src/blocks/Tagger/index.ts +1 -0
  118. package/src/blocks/Tagger/types.ts +11 -0
  119. package/src/blocks/Textarea/Textarea.stories.tsx +47 -0
  120. package/src/blocks/Textarea/Textarea.tsx +50 -0
  121. package/src/blocks/Textarea/index.ts +1 -0
  122. package/src/components/Alert/Alert.stories.tsx +93 -0
  123. package/src/components/Alert/Alert.tsx +103 -0
  124. package/src/components/Alert/AlertAction.tsx +31 -0
  125. package/src/components/Alert/AlertCollapsibleIcon.tsx +26 -0
  126. package/src/components/Alert/AlertDescription.tsx +31 -0
  127. package/src/components/Alert/AlertIcon.tsx +43 -0
  128. package/src/components/Alert/AlertRoot.tsx +64 -0
  129. package/src/components/Alert/AlertTitle.tsx +25 -0
  130. package/src/components/Alert/index.ts +1 -0
  131. package/src/components/Avatar.stories.tsx +22 -0
  132. package/src/components/Avatar.tsx +88 -0
  133. package/src/components/Badge/Badge.stories.tsx +106 -0
  134. package/src/components/Badge/Badge.tsx +55 -0
  135. package/src/components/Badge/BadgeAddon.tsx +63 -0
  136. package/src/components/Badge/BadgeButton.tsx +39 -0
  137. package/src/components/Badge/BadgeLabel.tsx +37 -0
  138. package/src/components/Badge/BadgeRoot.tsx +21 -0
  139. package/src/components/Badge/index.ts +1 -0
  140. package/src/components/Badge/styles.ts +74 -0
  141. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +135 -0
  142. package/src/components/Breadcrumb/Breadcrumb.tsx +23 -0
  143. package/src/components/Breadcrumb/BreadcrumbEllipsis.tsx +43 -0
  144. package/src/components/Breadcrumb/BreadcrumbItem.tsx +9 -0
  145. package/src/components/Breadcrumb/BreadcrumbLink.tsx +48 -0
  146. package/src/components/Breadcrumb/BreadcrumbList.tsx +26 -0
  147. package/src/components/Breadcrumb/BreadcrumbPage.tsx +22 -0
  148. package/src/components/Breadcrumb/BreadcrumbSeparator.tsx +28 -0
  149. package/src/components/Breadcrumb/index.ts +1 -0
  150. package/src/components/Button/Button.stories.tsx +68 -0
  151. package/src/components/Button/Button.tsx +73 -0
  152. package/src/components/Button/ButtonInline.stories.tsx +54 -0
  153. package/src/components/Button/ButtonInline.tsx +73 -0
  154. package/src/components/Button/index.ts +3 -0
  155. package/src/components/Button/styles.ts +292 -0
  156. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +118 -0
  157. package/src/components/ButtonGroup/ButtonGroup.tsx +79 -0
  158. package/src/components/ButtonGroup/index.ts +1 -0
  159. package/src/components/Calendar/Calendar.stories.tsx +101 -0
  160. package/src/components/Calendar/Calendar.tsx +44 -0
  161. package/src/components/Calendar/index.ts +2 -0
  162. package/src/components/Card/Card.stories.tsx +60 -0
  163. package/src/components/Card/Card.tsx +25 -0
  164. package/src/components/Card/CardContent.tsx +5 -0
  165. package/src/components/Card/CardHeader.tsx +5 -0
  166. package/src/components/Card/CardTitle.tsx +13 -0
  167. package/src/components/Card/index.ts +1 -0
  168. package/src/components/Card/styles.ts +32 -0
  169. package/src/components/Checkbox/Checkbox.stories.tsx +210 -0
  170. package/src/components/Checkbox/Checkbox.test.tsx +140 -0
  171. package/src/components/Checkbox/Checkbox.tsx +86 -0
  172. package/src/components/Checkbox/index.ts +1 -0
  173. package/src/components/Checkbox/styles.ts +77 -0
  174. package/src/components/Clipboard/Clipboard.stories.tsx +44 -0
  175. package/src/components/Clipboard/Clipboard.tsx +89 -0
  176. package/src/components/Clipboard/index.ts +1 -0
  177. package/src/components/CodeEditor/ButtonToolbar.tsx +14 -0
  178. package/src/components/CodeEditor/CodeEditor.tsx +155 -0
  179. package/src/components/CodeEditor/SqlEditor.stories.tsx +76 -0
  180. package/src/components/CodeEditor/SqlEditor.tsx +206 -0
  181. package/src/components/CodeEditor/ToggleComponentHelp.tsx +7 -0
  182. package/src/components/CodeEditor/activeQueryHighlight.test.ts +178 -0
  183. package/src/components/CodeEditor/activeQueryHighlight.ts +245 -0
  184. package/src/components/CodeEditor/helpers.ts +100 -0
  185. package/src/components/CodeEditor/highlighting.ts +184 -0
  186. package/src/components/CodeEditor/index.ts +3 -0
  187. package/src/components/CodeEditor/search.ts +186 -0
  188. package/src/components/Collapse.stories.tsx +56 -0
  189. package/src/components/Collapse.tsx +61 -0
  190. package/src/components/Collapsible/Collapsible.stories.tsx +55 -0
  191. package/src/components/Collapsible/Collapsible.tsx +11 -0
  192. package/src/components/Collapsible/CollapsibleContent.tsx +25 -0
  193. package/src/components/Collapsible/index.ts +1 -0
  194. package/src/components/CollapsiblePanel.stories.tsx +25 -0
  195. package/src/components/CollapsiblePanel.tsx +130 -0
  196. package/src/components/Combobox/Combobox.stories.tsx +426 -0
  197. package/src/components/Combobox/Combobox.test.tsx +165 -0
  198. package/src/components/Combobox/Combobox.tsx +347 -0
  199. package/src/components/Combobox/ComboboxChips.tsx +63 -0
  200. package/src/components/Combobox/ComboboxContent.tsx +95 -0
  201. package/src/components/Combobox/ComboboxEmpty.tsx +30 -0
  202. package/src/components/Combobox/ComboboxInput.tsx +10 -0
  203. package/src/components/Combobox/ComboboxInputGroup.tsx +38 -0
  204. package/src/components/Combobox/ComboboxItem.tsx +71 -0
  205. package/src/components/Combobox/ComboboxItemIndicator.tsx +76 -0
  206. package/src/components/Combobox/ComboboxList.tsx +32 -0
  207. package/src/components/Combobox/ComboboxRoot.tsx +5 -0
  208. package/src/components/Combobox/ComboboxSeparator.tsx +20 -0
  209. package/src/components/Combobox/Group/ComboboxCollection.tsx +7 -0
  210. package/src/components/Combobox/Group/ComboboxGroup.tsx +23 -0
  211. package/src/components/Combobox/Group/ComboboxGroupLabel.tsx +38 -0
  212. package/src/components/Combobox/Group/index.ts +3 -0
  213. package/src/components/Combobox/index.ts +1 -0
  214. package/src/components/Combobox/types.ts +26 -0
  215. package/src/components/Combobox/utils.test.ts +95 -0
  216. package/src/components/Combobox/utils.ts +103 -0
  217. package/src/components/Command/Command.stories.tsx +376 -0
  218. package/src/components/Command/Command.tsx +37 -0
  219. package/src/components/Command/CommandContent.tsx +19 -0
  220. package/src/components/Command/CommandEmpty.tsx +6 -0
  221. package/src/components/Command/CommandGroup.tsx +26 -0
  222. package/src/components/Command/CommandInput.tsx +27 -0
  223. package/src/components/Command/CommandItem/CheckIndicator.tsx +74 -0
  224. package/src/components/Command/CommandItem/CommandItem.tsx +91 -0
  225. package/src/components/Command/CommandItem/index.ts +1 -0
  226. package/src/components/Command/CommandList.tsx +32 -0
  227. package/src/components/Command/CommandSeparator.tsx +13 -0
  228. package/src/components/Command/index.ts +6 -0
  229. package/src/components/DatePicker/DatePicker.tsx +37 -0
  230. package/src/components/DatePicker/index.ts +1 -0
  231. package/src/components/DiffView/DiffView.stories.tsx +80 -0
  232. package/src/components/DiffView/DiffView.tsx +131 -0
  233. package/src/components/DiffView/DiffViewMark.tsx +21 -0
  234. package/src/components/DiffView/DiffViewTd.tsx +84 -0
  235. package/src/components/DiffView/DiffViewTh.tsx +23 -0
  236. package/src/components/DiffView/index.ts +11 -0
  237. package/src/components/DiffView/util.test.ts +231 -0
  238. package/src/components/DiffView/util.ts +311 -0
  239. package/src/components/DotsLoader.tsx +22 -0
  240. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +306 -0
  241. package/src/components/DropdownMenu/DropdownMenu.tsx +61 -0
  242. package/src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx +52 -0
  243. package/src/components/DropdownMenu/DropdownMenuContent.tsx +52 -0
  244. package/src/components/DropdownMenu/DropdownMenuContext.tsx +13 -0
  245. package/src/components/DropdownMenu/DropdownMenuItem.tsx +74 -0
  246. package/src/components/DropdownMenu/DropdownMenuItemDescription.tsx +42 -0
  247. package/src/components/DropdownMenu/DropdownMenuItemIndicator.tsx +98 -0
  248. package/src/components/DropdownMenu/DropdownMenuLabel.tsx +21 -0
  249. package/src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioGroup.tsx +31 -0
  250. package/src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioItem.tsx +64 -0
  251. package/src/components/DropdownMenu/DropdownMenuRadioGroup/index.ts +2 -0
  252. package/src/components/DropdownMenu/DropdownMenuSeparator.tsx +35 -0
  253. package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSub.tsx +3 -0
  254. package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubContent.tsx +21 -0
  255. package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubTrigger.tsx +17 -0
  256. package/src/components/DropdownMenu/DropdownMenuSub/index.ts +3 -0
  257. package/src/components/DropdownMenu/DropdownMenuTrigger.tsx +19 -0
  258. package/src/components/DropdownMenu/ItemIcon.tsx +22 -0
  259. package/src/components/DropdownMenu/index.ts +1 -0
  260. package/src/components/DropdownMenu/styles.ts +82 -0
  261. package/src/components/EmptySearchContent.stories.tsx +12 -0
  262. package/src/components/EmptySearchContent.tsx +13 -0
  263. package/src/components/FieldBox/FieldBox.stories.tsx +138 -0
  264. package/src/components/FieldBox/FieldBox.tsx +43 -0
  265. package/src/components/FieldBox/FieldBoxDescription.tsx +18 -0
  266. package/src/components/FieldBox/FieldBoxTitle.tsx +20 -0
  267. package/src/components/FieldBox/index.ts +1 -0
  268. package/src/components/FieldBox/styles.ts +37 -0
  269. package/src/components/FormGroup/FormGroup.stories.tsx +120 -0
  270. package/src/components/FormGroup/FormGroup.tsx +33 -0
  271. package/src/components/FormGroup/FormGroupColorInput.tsx +15 -0
  272. package/src/components/FormGroup/FormGroupHelp.tsx +17 -0
  273. package/src/components/FormGroup/FormGroupNumberInput.tsx +15 -0
  274. package/src/components/FormGroup/FormGroupTextInput.tsx +15 -0
  275. package/src/components/FormGroup/FormGroupTextarea.tsx +12 -0
  276. package/src/components/FormGroup/context.ts +11 -0
  277. package/src/components/FormGroup/index.ts +2 -0
  278. package/src/components/FormGroup/types.ts +5 -0
  279. package/src/components/FullScreenModal/FullScreenModal.tsx +8 -0
  280. package/src/components/FullScreenModal/FullScreenModalBody.tsx +16 -0
  281. package/src/components/FullScreenModal/FullScreenModalHeader.tsx +89 -0
  282. package/src/components/FullScreenModal/FullScreenModalRoot.tsx +79 -0
  283. package/src/components/FullScreenModal/index.ts +3 -0
  284. package/src/components/HelpBlock/HelpBlock.stories.tsx +28 -0
  285. package/src/components/HelpBlock/HelpBlock.tsx +31 -0
  286. package/src/components/HelpBlock/index.ts +1 -0
  287. package/src/components/HoverCard/HoverCard.stories.tsx +77 -0
  288. package/src/components/HoverCard/HoverCard.tsx +13 -0
  289. package/src/components/HoverCard/HoverCardContent.tsx +63 -0
  290. package/src/components/HoverCard/index.ts +1 -0
  291. package/src/components/Icon/Icon.stories.tsx +26 -0
  292. package/src/components/Icon/Icon.tsx +10 -0
  293. package/src/components/Icon/Icons.mdx +28 -0
  294. package/src/components/Icon/constants.ts +1 -0
  295. package/src/components/Icon/index.ts +27 -0
  296. package/src/components/Input/DateInput/DateInput.stories.tsx +58 -0
  297. package/src/components/Input/DateInput/DateInput.tsx +140 -0
  298. package/src/components/Input/DateInput/helpers.test.ts +102 -0
  299. package/src/components/Input/DateInput/helpers.ts +59 -0
  300. package/src/components/Input/DateInput/index.ts +1 -0
  301. package/src/components/Input/DateRangeInput/DateRangeInput.stories.tsx +66 -0
  302. package/src/components/Input/DateRangeInput/DateRangeInput.tsx +141 -0
  303. package/src/components/Input/DateRangeInput/helpers.test.ts +146 -0
  304. package/src/components/Input/DateRangeInput/helpers.ts +36 -0
  305. package/src/components/Input/DateRangeInput/index.ts +1 -0
  306. package/src/components/Input/Input.stories.tsx +93 -0
  307. package/src/components/Input/Input.test.tsx +112 -0
  308. package/src/components/Input/Input.tsx +147 -0
  309. package/src/components/Input/TextInput/TextInput.stories.tsx +68 -0
  310. package/src/components/Input/TextInput/TextInput.test.tsx +52 -0
  311. package/src/components/Input/TextInput/TextInput.tsx +57 -0
  312. package/src/components/Input/TextInput/index.ts +1 -0
  313. package/src/components/Input/TimeInput/TimeInput.stories.tsx +89 -0
  314. package/src/components/Input/TimeInput/TimeInput.tsx +103 -0
  315. package/src/components/Input/TimeInput/index.ts +1 -0
  316. package/src/components/Input/index.ts +4 -0
  317. package/src/components/Input/utils.ts +11 -0
  318. package/src/components/InputGroup/InputGroup.stories.tsx +208 -0
  319. package/src/components/InputGroup/InputGroup.tsx +228 -0
  320. package/src/components/InputGroup/InputGroupAddon.tsx +46 -0
  321. package/src/components/InputGroup/InputGroupButton.tsx +25 -0
  322. package/src/components/InputGroup/InputGroupInput.tsx +34 -0
  323. package/src/components/InputGroup/InputGroupText.tsx +21 -0
  324. package/src/components/InputGroup/InputGroupTextArea.tsx +78 -0
  325. package/src/components/InputGroup/index.ts +1 -0
  326. package/src/components/Kbd/Kbd.stories.tsx +82 -0
  327. package/src/components/Kbd/Kbd.tsx +17 -0
  328. package/src/components/Kbd/KbdGroup.tsx +35 -0
  329. package/src/components/Kbd/KbdSeparator.tsx +9 -0
  330. package/src/components/Kbd/index.ts +3 -0
  331. package/src/components/Kbd/keyboardKeys.ts +40 -0
  332. package/src/components/Kbd/styles.ts +39 -0
  333. package/src/components/Label/Label.stories.tsx +53 -0
  334. package/src/components/Label/Label.tsx +31 -0
  335. package/src/components/Label/index.ts +1 -0
  336. package/src/components/Link.stories.tsx +19 -0
  337. package/src/components/Link.tsx +37 -0
  338. package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +120 -0
  339. package/src/components/MarkdownEditor/MarkdownEditor.test.ts +171 -0
  340. package/src/components/MarkdownEditor/MarkdownEditor.tsx +155 -0
  341. package/src/components/MarkdownEditor/context.ts +10 -0
  342. package/src/components/MarkdownEditor/index.ts +1 -0
  343. package/src/components/MarkdownEditor/nodes/ImageNode.tsx +115 -0
  344. package/src/components/MarkdownEditor/nodes/ImageNodeComponent.tsx +18 -0
  345. package/src/components/MarkdownEditor/nodes/MermaidNode.tsx +72 -0
  346. package/src/components/MarkdownEditor/nodes/MermaidNodeComponent.tsx +35 -0
  347. package/src/components/MarkdownEditor/plugins/ImagePastePlugin.tsx +149 -0
  348. package/src/components/MarkdownEditor/plugins/KeyboardPlugin.tsx +37 -0
  349. package/src/components/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx +56 -0
  350. package/src/components/MarkdownEditor/plugins/ToolbarPlugin.tsx +274 -0
  351. package/src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx +93 -0
  352. package/src/components/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx +133 -0
  353. package/src/components/MarkdownEditor/plugins/toolbar/LinkPanel.tsx +160 -0
  354. package/src/components/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx +36 -0
  355. package/src/components/MarkdownEditor/plugins/toolbar/ToolbarDivider.tsx +1 -0
  356. package/src/components/MarkdownEditor/theme.ts +39 -0
  357. package/src/components/MarkdownEditor/transformers.ts +179 -0
  358. package/src/components/MarkedText/MarkedText.stories.tsx +46 -0
  359. package/src/components/MarkedText/MarkedText.tsx +36 -0
  360. package/src/components/MarkedText/index.ts +1 -0
  361. package/src/components/MarkedText/utils.test.ts +193 -0
  362. package/src/components/MarkedText/utils.ts +37 -0
  363. package/src/components/MergeEditor/AcceptControls/AcceptButton.tsx +20 -0
  364. package/src/components/MergeEditor/AcceptControls/AcceptControls.tsx +66 -0
  365. package/src/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.tsx +38 -0
  366. package/src/components/MergeEditor/MergeEditor.stories.tsx +211 -0
  367. package/src/components/MergeEditor/MergeEditor.tsx +116 -0
  368. package/src/components/MergeEditor/MergePane.tsx +95 -0
  369. package/src/components/MergeEditor/PaneHeader.tsx +11 -0
  370. package/src/components/MergeEditor/constants.ts +48 -0
  371. package/src/components/MergeEditor/decorations.ts +126 -0
  372. package/src/components/MergeEditor/helpers.test.ts +172 -0
  373. package/src/components/MergeEditor/helpers.ts +118 -0
  374. package/src/components/MergeEditor/index.ts +5 -0
  375. package/src/components/MergeEditor/useMergeDiff.ts +573 -0
  376. package/src/components/MergeEditor/useScrollSync.ts +79 -0
  377. package/src/components/Modal/Modal.stories.tsx +678 -0
  378. package/src/components/Modal/Modal.tsx +23 -0
  379. package/src/components/Modal/ModalBody.tsx +23 -0
  380. package/src/components/Modal/ModalCloseIcon.tsx +32 -0
  381. package/src/components/Modal/ModalContent.tsx +87 -0
  382. package/src/components/Modal/ModalDescription.tsx +20 -0
  383. package/src/components/Modal/ModalFooter.tsx +15 -0
  384. package/src/components/Modal/ModalHeader.tsx +50 -0
  385. package/src/components/Modal/ModalIcon.tsx +83 -0
  386. package/src/components/Modal/ModalOverlay.tsx +42 -0
  387. package/src/components/Modal/ModalTitle.tsx +12 -0
  388. package/src/components/Modal/index.ts +1 -0
  389. package/src/components/Navbar/Navbar.stories.tsx +179 -0
  390. package/src/components/Navbar/Navbar.tsx +80 -0
  391. package/src/components/Navbar/NavbarContent.tsx +20 -0
  392. package/src/components/Navbar/NavbarFooter.tsx +11 -0
  393. package/src/components/Navbar/NavbarHeader.tsx +11 -0
  394. package/src/components/Navbar/NavbarMenu.tsx +30 -0
  395. package/src/components/Navbar/NavbarMenuAvatar.tsx +67 -0
  396. package/src/components/Navbar/NavbarMenuButton.tsx +134 -0
  397. package/src/components/Navbar/NavbarMenuItem.tsx +9 -0
  398. package/src/components/Navbar/NavbarMenuItemAdornment.tsx +65 -0
  399. package/src/components/Navbar/index.ts +1 -0
  400. package/src/components/Pagination/Pagination.stories.tsx +132 -0
  401. package/src/components/Pagination/Pagination.tsx +34 -0
  402. package/src/components/Pagination/PaginationButton.tsx +36 -0
  403. package/src/components/Pagination/PaginationContent.tsx +12 -0
  404. package/src/components/Pagination/PaginationEllipsis.tsx +26 -0
  405. package/src/components/Pagination/PaginationItem.tsx +9 -0
  406. package/src/components/Pagination/PaginationNext.tsx +19 -0
  407. package/src/components/Pagination/PaginationPrevious.tsx +11 -0
  408. package/src/components/Pagination/index.ts +1 -0
  409. package/src/components/PanelWithDetails.stories.tsx +28 -0
  410. package/src/components/PanelWithDetails.tsx +66 -0
  411. package/src/components/Popconfirm/Popconfirm.stories.tsx +365 -0
  412. package/src/components/Popconfirm/Popconfirm.tsx +82 -0
  413. package/src/components/Popconfirm/PopconfirmBody.tsx +5 -0
  414. package/src/components/Popconfirm/PopconfirmCancel.tsx +45 -0
  415. package/src/components/Popconfirm/PopconfirmConfirm.tsx +57 -0
  416. package/src/components/Popconfirm/PopconfirmContent.tsx +33 -0
  417. package/src/components/Popconfirm/PopconfirmFooter.tsx +9 -0
  418. package/src/components/Popconfirm/PopconfirmTrigger.tsx +22 -0
  419. package/src/components/Popconfirm/context.ts +19 -0
  420. package/src/components/Popconfirm/index.ts +1 -0
  421. package/src/components/Popover/Popover.stories.tsx +85 -0
  422. package/src/components/Popover/Popover.tsx +15 -0
  423. package/src/components/Popover/PopoverContent.tsx +99 -0
  424. package/src/components/Popover/index.ts +1 -0
  425. package/src/components/Progress/Progress.stories.tsx +67 -0
  426. package/src/components/Progress/Progress.tsx +45 -0
  427. package/src/components/Progress/index.ts +1 -0
  428. package/src/components/RadioGroup/Radio.tsx +67 -0
  429. package/src/components/RadioGroup/RadioGroup.stories.tsx +300 -0
  430. package/src/components/RadioGroup/RadioGroup.tsx +64 -0
  431. package/src/components/RadioGroup/RadioGroupItem.tsx +60 -0
  432. package/src/components/RadioGroup/RadioGroupItemButton.tsx +79 -0
  433. package/src/components/RadioGroup/RadioGroupSeparator.tsx +12 -0
  434. package/src/components/RadioGroup/context.ts +13 -0
  435. package/src/components/RadioGroup/index.ts +1 -0
  436. package/src/components/Resizable/Resizable.stories.tsx +50 -0
  437. package/src/components/Resizable/ResizableHandle.tsx +50 -0
  438. package/src/components/Resizable/ResizablePanel.tsx +12 -0
  439. package/src/components/Resizable/ResizablePanelGroup.tsx +19 -0
  440. package/src/components/Resizable/index.ts +3 -0
  441. package/src/components/ScrollArea/ScrollArea.stories.tsx +43 -0
  442. package/src/components/ScrollArea/ScrollArea.tsx +50 -0
  443. package/src/components/ScrollArea/ScrollBar.tsx +32 -0
  444. package/src/components/ScrollArea/index.ts +2 -0
  445. package/src/components/Search/ClearButton.tsx +42 -0
  446. package/src/components/Search/Search.stories.tsx +77 -0
  447. package/src/components/Search/Search.test.tsx +224 -0
  448. package/src/components/Search/Search.tsx +139 -0
  449. package/src/components/Search/SearchForm.tsx +37 -0
  450. package/src/components/Search/index.ts +2 -0
  451. package/src/components/Search/styles.ts +88 -0
  452. package/src/components/Search/utils.ts +11 -0
  453. package/src/components/Select/Select.stories.tsx +109 -0
  454. package/src/components/Select/Select.tsx +130 -0
  455. package/src/components/Select/SelectContent.tsx +101 -0
  456. package/src/components/Select/SelectGroup.tsx +10 -0
  457. package/src/components/Select/SelectItem.tsx +71 -0
  458. package/src/components/Select/SelectLabel.tsx +32 -0
  459. package/src/components/Select/SelectRoot.tsx +6 -0
  460. package/src/components/Select/SelectSeparator.tsx +13 -0
  461. package/src/components/Select/SelectTrigger.tsx +161 -0
  462. package/src/components/Select/index.ts +1 -0
  463. package/src/components/Separator/Separator.stories.tsx +41 -0
  464. package/src/components/Separator/Separator.tsx +84 -0
  465. package/src/components/Separator/index.ts +1 -0
  466. package/src/components/Sheet/Sheet.stories.tsx +63 -0
  467. package/src/components/Sheet/Sheet.tsx +21 -0
  468. package/src/components/Sheet/SheetBody.tsx +12 -0
  469. package/src/components/Sheet/SheetContent.tsx +131 -0
  470. package/src/components/Sheet/SheetFooter.tsx +9 -0
  471. package/src/components/Sheet/SheetHeader.tsx +39 -0
  472. package/src/components/Sheet/SheetOverlay.tsx +11 -0
  473. package/src/components/Sheet/SheetTitle.tsx +12 -0
  474. package/src/components/Sheet/index.ts +1 -0
  475. package/src/components/Sidebar/Sidebar.stories.tsx +812 -0
  476. package/src/components/Sidebar/Sidebar.tsx +225 -0
  477. package/src/components/Sidebar/SidebarContent.tsx +61 -0
  478. package/src/components/Sidebar/SidebarFillTrigger.tsx +25 -0
  479. package/src/components/Sidebar/SidebarFooter.tsx +13 -0
  480. package/src/components/Sidebar/SidebarGroup/SidebarGroup.tsx +23 -0
  481. package/src/components/Sidebar/SidebarGroup/SidebarGroupAction.tsx +49 -0
  482. package/src/components/Sidebar/SidebarGroup/SidebarGroupContent.tsx +20 -0
  483. package/src/components/Sidebar/SidebarGroup/SidebarGroupLabel.tsx +76 -0
  484. package/src/components/Sidebar/SidebarGroup/index.ts +4 -0
  485. package/src/components/Sidebar/SidebarHeader.tsx +20 -0
  486. package/src/components/Sidebar/SidebarInstanceContext.ts +18 -0
  487. package/src/components/Sidebar/SidebarMenu/SidebarMenu.tsx +28 -0
  488. package/src/components/Sidebar/SidebarMenu/SidebarMenuAction.tsx +69 -0
  489. package/src/components/Sidebar/SidebarMenu/SidebarMenuBadge.tsx +56 -0
  490. package/src/components/Sidebar/SidebarMenu/SidebarMenuButton.tsx +108 -0
  491. package/src/components/Sidebar/SidebarMenu/SidebarMenuCard.tsx +107 -0
  492. package/src/components/Sidebar/SidebarMenu/SidebarMenuIcon.tsx +30 -0
  493. package/src/components/Sidebar/SidebarMenu/SidebarMenuItem.tsx +9 -0
  494. package/src/components/Sidebar/SidebarMenu/SidebarMenuSub.tsx +143 -0
  495. package/src/components/Sidebar/SidebarMenu/SidebarMenuSubItem.tsx +106 -0
  496. package/src/components/Sidebar/SidebarMenu/SidebarSearchInput.tsx +90 -0
  497. package/src/components/Sidebar/SidebarMenu/index.ts +10 -0
  498. package/src/components/Sidebar/SidebarProvider/SidebarProvider.tsx +171 -0
  499. package/src/components/Sidebar/SidebarProvider/context.ts +35 -0
  500. package/src/components/Sidebar/SidebarProvider/index.ts +2 -0
  501. package/src/components/Sidebar/SidebarProvider/useHoverTracking.test.ts +199 -0
  502. package/src/components/Sidebar/SidebarProvider/useHoverTracking.ts +72 -0
  503. package/src/components/Sidebar/SidebarProvider/useSidebarState.ts +50 -0
  504. package/src/components/Sidebar/SidebarProvider/useTransitionPresence.test.ts +179 -0
  505. package/src/components/Sidebar/SidebarProvider/useTransitionPresence.ts +53 -0
  506. package/src/components/Sidebar/SidebarResizeHandle.tsx +28 -0
  507. package/src/components/Sidebar/SidebarSeparator.tsx +15 -0
  508. package/src/components/Sidebar/SidebarTrigger.tsx +40 -0
  509. package/src/components/Sidebar/index.ts +3 -0
  510. package/src/components/Sidebar/types.ts +6 -0
  511. package/src/components/Sidebar/useResizeSidebar.ts +112 -0
  512. package/src/components/Sidebar/utils.test.ts +178 -0
  513. package/src/components/Sidebar/utils.ts +70 -0
  514. package/src/components/Skeleton/Skeleton.stories.tsx +54 -0
  515. package/src/components/Skeleton/Skeleton.tsx +54 -0
  516. package/src/components/Skeleton/SkeletonList.stories.tsx +11 -0
  517. package/src/components/Skeleton/SkeletonList.tsx +65 -0
  518. package/src/components/Slider/Slider.stories.tsx +99 -0
  519. package/src/components/Slider/Slider.tsx +85 -0
  520. package/src/components/Slider/SliderThumb.tsx +57 -0
  521. package/src/components/Slider/SliderTrack.tsx +49 -0
  522. package/src/components/Slider/index.ts +1 -0
  523. package/src/components/Slider/useInteracting.test.ts +159 -0
  524. package/src/components/Slider/useInteracting.ts +64 -0
  525. package/src/components/Switch/Switch.stories.tsx +177 -0
  526. package/src/components/Switch/Switch.tsx +58 -0
  527. package/src/components/Switch/index.ts +1 -0
  528. package/src/components/Switch/styles.ts +173 -0
  529. package/src/components/Table/Table.stories.tsx +106 -0
  530. package/src/components/Table/Table.tsx +51 -0
  531. package/src/components/Table/TableBody.tsx +22 -0
  532. package/src/components/Table/TableCell.tsx +7 -0
  533. package/src/components/Table/TableFooter.tsx +15 -0
  534. package/src/components/Table/TableHead.tsx +15 -0
  535. package/src/components/Table/TableHeader.tsx +20 -0
  536. package/src/components/Table/TableRow.tsx +11 -0
  537. package/src/components/Table/index.ts +1 -0
  538. package/src/components/Tabs.stories.tsx +123 -0
  539. package/src/components/Tabs.tsx +111 -0
  540. package/src/components/ThemeProvider/AIGradientSvg.tsx +18 -0
  541. package/src/components/ThemeProvider/ThemeProvider.tsx +25 -0
  542. package/src/components/ThemeProvider/index.ts +1 -0
  543. package/src/components/TimePicker/TimePicker.tsx +95 -0
  544. package/src/components/TimePicker/TimePickerButton.tsx +39 -0
  545. package/src/components/TimePicker/index.ts +1 -0
  546. package/src/components/TimePicker/utils.ts +31 -0
  547. package/src/components/Timeline/Timeline.stories.tsx +246 -0
  548. package/src/components/Timeline/Timeline.tsx +35 -0
  549. package/src/components/Timeline/TimelineConnector.tsx +154 -0
  550. package/src/components/Timeline/TimelineContent.tsx +18 -0
  551. package/src/components/Timeline/TimelineItem.tsx +14 -0
  552. package/src/components/Timeline/index.ts +1 -0
  553. package/src/components/Timeline/useLastLineHeight.ts +36 -0
  554. package/src/components/Toast/Toast.stories.tsx +178 -0
  555. package/src/components/Toast/ToastAction.tsx +40 -0
  556. package/src/components/Toast/ToastDescription.tsx +28 -0
  557. package/src/components/Toast/ToastDismiss.tsx +36 -0
  558. package/src/components/Toast/ToastDuration.tsx +43 -0
  559. package/src/components/Toast/ToastRoot.tsx +130 -0
  560. package/src/components/Toast/ToastTitle.tsx +33 -0
  561. package/src/components/Toast/Toaster.tsx +25 -0
  562. package/src/components/Toast/index.ts +3 -0
  563. package/src/components/Toast/toast.tsx +94 -0
  564. package/src/components/Toast/useNotification.tsx +33 -0
  565. package/src/components/Toggle/Toggle.stories.tsx +67 -0
  566. package/src/components/Toggle/Toggle.tsx +197 -0
  567. package/src/components/Toggle/index.ts +1 -0
  568. package/src/components/Tooltip/Tooltip.stories.tsx +82 -0
  569. package/src/components/Tooltip/Tooltip.tsx +87 -0
  570. package/src/components/Tooltip/TooltipContent.tsx +90 -0
  571. package/src/components/Tooltip/TooltipRoot.tsx +12 -0
  572. package/src/components/Tooltip/TooltipTrigger.tsx +42 -0
  573. package/src/components/Tooltip/index.ts +1 -0
  574. package/src/components/Truncated.stories.tsx +72 -0
  575. package/src/components/Truncated.tsx +78 -0
  576. package/src/components/ZoomableSvg/ZoomableSvg.stories.tsx +53 -0
  577. package/src/components/ZoomableSvg/ZoomableSvg.tsx +198 -0
  578. package/src/components/ZoomableSvg/index.ts +1 -0
  579. package/src/constants/keyCodes.ts +5 -0
  580. package/src/docs/Colors.mdx +19 -0
  581. package/src/docs/Spacing.mdx +35 -0
  582. package/src/docs/Typography.mdx +63 -0
  583. package/src/docs/components/Typeset.tsx +35 -0
  584. package/src/hooks/useAutosizeInput.stories.tsx +142 -0
  585. package/src/hooks/useAutosizeInput.test.tsx +77 -0
  586. package/src/hooks/useAutosizeInput.tsx +107 -0
  587. package/src/hooks/useElement.ts +16 -0
  588. package/src/hooks/useScrollbarPosition.ts +68 -0
  589. package/src/icon-names.ts +20 -0
  590. package/src/index.ts +87 -0
  591. package/src/styles.css +212 -0
  592. package/src/utils/classNames.test.ts +16 -0
  593. package/src/utils/classNames.ts +27 -0
  594. package/src/utils/copyToClipboard.ts +3 -0
  595. package/src/utils/createChangeInputEvent.ts +28 -0
  596. package/src/utils/createPrefixedString.ts +2 -0
  597. package/src/utils/debounce.test.ts +63 -0
  598. package/src/utils/debounce.ts +17 -0
  599. package/src/utils/decorators.tsx +16 -0
  600. package/src/utils/escapeStringRegexp.ts +4 -0
  601. package/src/utils/index.ts +11 -0
  602. package/src/utils/isMac.ts +26 -0
  603. package/src/utils/mergeRefs.ts +23 -0
  604. package/src/utils/noop.ts +1 -0
  605. package/src/utils/useSHA256.ts +21 -0
  606. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,137 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Button } from '../../components/Button';
4
+
5
+ import { MessageBubble } from './MessageBubble';
6
+
7
+ export default {
8
+ title: 'AI Kit/MessageBubble',
9
+ component: MessageBubble,
10
+ args: {
11
+ variant: 'assistant',
12
+ },
13
+ argTypes: {
14
+ variant: {
15
+ control: 'radio',
16
+ options: ['user', 'assistant'],
17
+ },
18
+ actions: {
19
+ control: false,
20
+ },
21
+ },
22
+ decorators: [
23
+ (Story) => (
24
+ <div className="tw-grid tw-gap-4">
25
+ <Story />
26
+ </div>
27
+ ),
28
+ ],
29
+ } satisfies Meta<typeof MessageBubble>;
30
+
31
+ type Story = StoryObj<typeof MessageBubble>;
32
+
33
+ export const Assistant: Story = {
34
+ args: {
35
+ variant: 'assistant',
36
+ children: (
37
+ <>
38
+ Hello! I'm an AI assistant. How can I help you today? I can answer questions, help with
39
+ code, explain concepts, and much more.
40
+ </>
41
+ ),
42
+ },
43
+ };
44
+
45
+ export const User: Story = {
46
+ args: {
47
+ variant: 'user',
48
+ user: { name: 'John Doe', email: 'john@example.com' },
49
+ children: <>Can you help me write a function that calculates the factorial of a number?</>,
50
+ },
51
+ };
52
+
53
+ export const AssistantWithActions: Story = {
54
+ args: {
55
+ variant: 'assistant',
56
+ children: (
57
+ <div>
58
+ <p>Sure! Here's a factorial function in TypeScript:</p>
59
+ <pre className="tw-mt-2 tw-rounded tw-bg-neutral-100 tw-p-3 tw-text-sm">
60
+ {`function factorial(n: number): number {
61
+ if (n <= 1) return 1;
62
+ return n * factorial(n - 1);
63
+ }`}
64
+ </pre>
65
+ </div>
66
+ ),
67
+ actions: (
68
+ <div className="tw-flex tw-gap-2">
69
+ <Button size="icon-sm" variant="outline" icon="copy" aria-label="Copy" />
70
+ <Button size="icon-sm" variant="outline" icon="thumbs-up" aria-label="Helpful" />
71
+ <Button size="icon-sm" variant="outline" icon="thumbs-down" aria-label="Not helpful" />
72
+ </div>
73
+ ),
74
+ },
75
+ };
76
+
77
+ export const LongContent: Story = {
78
+ args: {
79
+ variant: 'assistant',
80
+ children: (
81
+ <div className="tw-flex tw-flex-col tw-gap-3">
82
+ <p>Here are several key React performance optimization techniques:</p>
83
+ <ol className="tw-list-inside tw-list-decimal tw-space-y-2">
84
+ <li>
85
+ <strong>Use React.memo()</strong> - Wrap functional components to prevent unnecessary
86
+ re-renders when props haven't changed.
87
+ </li>
88
+ <li>
89
+ <strong>Use useMemo() and useCallback()</strong> - Memoize expensive calculations and
90
+ callback functions to maintain referential equality.
91
+ </li>
92
+ <li>
93
+ <strong>Code splitting with React.lazy()</strong> - Load components on demand to reduce
94
+ initial bundle size.
95
+ </li>
96
+ <li>
97
+ <strong>Virtualize long lists</strong> - Use libraries like react-window or
98
+ react-virtualized for rendering large datasets.
99
+ </li>
100
+ <li>
101
+ <strong>Avoid inline functions in JSX</strong> - Define callbacks outside of render to
102
+ prevent new function instances on each render.
103
+ </li>
104
+ </ol>
105
+ </div>
106
+ ),
107
+ },
108
+ };
109
+
110
+ const exampleUser = { name: 'User', email: 'user@example.com' };
111
+
112
+ export const Conversation: Story = {
113
+ decorators: [],
114
+ render: () => (
115
+ <div className="tw-grid tw-gap-4">
116
+ <MessageBubble variant="user" user={exampleUser}>
117
+ <>What is the capital of France?</>
118
+ </MessageBubble>
119
+ <MessageBubble variant="assistant">
120
+ <>
121
+ The capital of France is <strong>Paris</strong>. It's located in the north-central part of
122
+ the country along the Seine River.
123
+ </>
124
+ </MessageBubble>
125
+ <MessageBubble variant="user" user={exampleUser}>
126
+ <>What's the population?</>
127
+ </MessageBubble>
128
+ <MessageBubble variant="assistant">
129
+ <>
130
+ Paris has a population of approximately 2.1 million people within the city limits. The
131
+ greater Paris metropolitan area (Ile-de-France) has over 12 million inhabitants, making it
132
+ one of the largest metropolitan areas in Europe.
133
+ </>
134
+ </MessageBubble>
135
+ </div>
136
+ ),
137
+ };
@@ -0,0 +1,68 @@
1
+ import type { ComponentProps, PropsWithChildren, ReactNode } from 'react';
2
+ import { cva } from 'class-variance-authority';
3
+
4
+ import { Avatar } from '../../components/Avatar';
5
+
6
+ const containerClasses = cva(['tw-flex', 'tw-max-w-full', 'tw-gap-4'], {
7
+ variants: {
8
+ variant: {
9
+ user: ['tw-justify-self-end', 'tw-flex-row-reverse'],
10
+ assistant: ['tw-justify-self-start', 'tw-w-full', 'tw-gap-3'],
11
+ },
12
+ },
13
+ defaultVariants: {
14
+ variant: 'assistant',
15
+ },
16
+ });
17
+
18
+ const contentClasses = cva(
19
+ [
20
+ 'tw-flex',
21
+ 'tw-flex-col',
22
+ 'tw-gap-4',
23
+ 'tw-break-words',
24
+ 'tw-leading-relaxed',
25
+ 'tw-text-neutral-800',
26
+ '[&_.tw-prose]:tw-text-neutral-800',
27
+ ],
28
+ {
29
+ variants: {
30
+ variant: {
31
+ assistant: ['tw-flex-1', 'tw-w-full', 'tw-min-w-0'],
32
+ user: [
33
+ 'tw-max-w-screen-sm',
34
+ 'tw-w-fit',
35
+ 'tw-bg-neutral-50',
36
+ 'tw-p-3',
37
+ 'tw-rounded-2xl',
38
+ 'tw-ml-6',
39
+ 'tw-overflow-hidden',
40
+ 'tw-break-anywhere',
41
+ ],
42
+ },
43
+ },
44
+
45
+ defaultVariants: {
46
+ variant: 'assistant',
47
+ },
48
+ },
49
+ );
50
+
51
+ type Props = {
52
+ variant: 'user' | 'assistant';
53
+ user?: ComponentProps<typeof Avatar>['user'];
54
+ actions?: ReactNode;
55
+ createdAt?: string;
56
+ } & PropsWithChildren;
57
+
58
+ export const MessageBubble = ({ variant, children, user, actions, createdAt }: Props) => {
59
+ return (
60
+ <div className={containerClasses({ variant })} data-testid={`chat-message-${variant}`}>
61
+ {variant === 'user' && <Avatar user={user} size={30} title={createdAt} />}
62
+ <div className="tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-gap-2">
63
+ <div className={contentClasses({ variant })}>{children}</div>
64
+ {actions}
65
+ </div>
66
+ </div>
67
+ );
68
+ };
@@ -0,0 +1,121 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { PlanApproval } from './PlanApproval';
4
+ import { PlanRewritingIndicator } from './PlanRewritingIndicator';
5
+
6
+ const samplePlanBody = (
7
+ <div className="tw-flex tw-flex-col tw-gap-3">
8
+ <p className="tw-m-0 tw-text-sm tw-font-semibold tw-text-neutral-800">
9
+ Audit plan for the KIO pipeline
10
+ </p>
11
+ <ol className="tw-m-0 tw-flex tw-flex-col tw-gap-2 tw-pl-5 tw-text-sm tw-text-neutral-700">
12
+ <li>Inspect the raw bucket schema and column types</li>
13
+ <li>List downstream transformations and their dependencies</li>
14
+ <li>Sample row counts per table and flag mismatches</li>
15
+ <li>Run referential integrity checks on the staging layer</li>
16
+ <li>Identify orphan rows and produce remediation suggestions</li>
17
+ <li>Summarize findings in a markdown report</li>
18
+ <li>Propose follow-up issues for owners to triage</li>
19
+ <li>Wait for approval before applying any fixes</li>
20
+ </ol>
21
+ </div>
22
+ );
23
+
24
+ const decorator = (Story: React.ComponentType) => (
25
+ <div style={{ maxWidth: 800 }}>
26
+ <Story />
27
+ </div>
28
+ );
29
+
30
+ const meta: Meta<typeof PlanApproval> = {
31
+ title: 'AI Kit/PlanApproval',
32
+ component: PlanApproval,
33
+ args: {
34
+ status: 'pending',
35
+ title: '8-step Audit plan for KIO pipeline covering',
36
+ summary: 'Short summary describing the high-level plan before the user expands the details.',
37
+ stepCount: 42,
38
+ planBody: samplePlanBody,
39
+ },
40
+ decorators: [decorator],
41
+ };
42
+
43
+ export default meta;
44
+
45
+ type Story = StoryObj<typeof PlanApproval>;
46
+
47
+ export const PendingCollapsed: Story = {
48
+ args: {
49
+ onApprove: () => alert('Approved'),
50
+ onRequestChanges: (reason) => alert(`Request Changes: ${reason}`),
51
+ onClose: () => alert('Dismissed'),
52
+ },
53
+ };
54
+
55
+ export const PendingExpanded: Story = {
56
+ args: {
57
+ defaultExpanded: true,
58
+ onApprove: () => alert('Approved'),
59
+ onRequestChanges: (reason) => alert(`Request Changes: ${reason}`),
60
+ onClose: () => alert('Dismissed'),
61
+ },
62
+ };
63
+
64
+ export const Approved: Story = {
65
+ args: {
66
+ status: 'approved',
67
+ },
68
+ };
69
+
70
+ export const Dismissed: Story = {
71
+ args: {
72
+ status: 'dismissed',
73
+ },
74
+ };
75
+
76
+ export const WithoutPlanBody: Story = {
77
+ args: {
78
+ planBody: undefined,
79
+ onApprove: () => alert('Approved'),
80
+ onRequestChanges: (reason) => alert(`Request Changes: ${reason}`),
81
+ onClose: () => alert('Dismissed'),
82
+ },
83
+ };
84
+
85
+ export const Submitting: Story = {
86
+ args: {
87
+ defaultExpanded: true,
88
+ isSubmitting: true,
89
+ onApprove: () => alert('Approved'),
90
+ onRequestChanges: (reason) => alert(`Request Changes: ${reason}`),
91
+ onClose: () => alert('Dismissed'),
92
+ },
93
+ };
94
+
95
+ export const PendingExpandedLongPlan: Story = {
96
+ args: {
97
+ defaultExpanded: true,
98
+ title: 'Plan: Migrate the analytics warehouse to BigQuery',
99
+ summary:
100
+ 'A long, multi-stage migration plan whose markdown body is bigger than the card max-height — the plan body scrolls internally so the header and the Approve / Request Changes buttons remain visible without scrolling the chat viewport.',
101
+ stepCount: 42,
102
+ planBody: (
103
+ <div className="tw-flex tw-flex-col tw-gap-3">
104
+ {Array.from({ length: 40 }).map((_, index) => (
105
+ <p key={index} className="tw-m-0 tw-text-sm tw-text-neutral-700">
106
+ <strong>Step {index + 1}.</strong> Lorem ipsum dolor sit amet, consectetur adipiscing
107
+ elit. Curabitur efficitur, sapien id finibus consectetur, lorem velit egestas urna, in
108
+ placerat nulla nisi a augue. Nulla facilisi.
109
+ </p>
110
+ ))}
111
+ </div>
112
+ ),
113
+ onApprove: () => alert('Approved'),
114
+ onRequestChanges: (reason) => alert(`Request Changes: ${reason}`),
115
+ onClose: () => alert('Dismissed'),
116
+ },
117
+ };
118
+
119
+ export const Rewriting: StoryObj<typeof PlanRewritingIndicator> = {
120
+ render: () => <PlanRewritingIndicator />,
121
+ };
@@ -0,0 +1,241 @@
1
+ import { fireEvent, render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+
5
+ import { PlanApproval } from './PlanApproval';
6
+
7
+ const baseProps = {
8
+ title: 'Audit plan for KIO',
9
+ summary: 'Short summary',
10
+ stepCount: 8,
11
+ };
12
+
13
+ describe('<PlanApproval />', () => {
14
+ it('renders the pending state with status pill, step count, and approve/request actions', () => {
15
+ render(
16
+ <PlanApproval
17
+ {...baseProps}
18
+ status="pending"
19
+ onApprove={vi.fn()}
20
+ onRequestChanges={vi.fn()}
21
+ onClose={vi.fn()}
22
+ />,
23
+ );
24
+
25
+ expect(screen.getByText('Ready for approval')).toBeInTheDocument();
26
+ expect(screen.getByText('8 steps')).toBeInTheDocument();
27
+ expect(screen.getByRole('button', { name: 'Approve' })).toBeEnabled();
28
+ expect(screen.getByRole('button', { name: 'Request Changes' })).toBeEnabled();
29
+ expect(screen.getByRole('button', { name: 'Dismiss plan' })).toBeEnabled();
30
+ });
31
+
32
+ it('renders the approved terminal state without action buttons or close', () => {
33
+ render(<PlanApproval {...baseProps} status="approved" planBody={<div>Body</div>} />);
34
+ expect(screen.getByText('Approved')).toBeInTheDocument();
35
+ expect(screen.queryByRole('button', { name: 'Approve' })).not.toBeInTheDocument();
36
+ expect(screen.queryByRole('button', { name: 'Request Changes' })).not.toBeInTheDocument();
37
+ expect(screen.queryByRole('button', { name: 'Dismiss plan' })).not.toBeInTheDocument();
38
+ expect(screen.getByRole('button', { name: /Show more/i })).toBeInTheDocument();
39
+ });
40
+
41
+ it('renders the dismissed terminal state with a Dismissed pill', () => {
42
+ render(<PlanApproval {...baseProps} status="dismissed" />);
43
+ expect(screen.getByText('Dismissed')).toBeInTheDocument();
44
+ expect(screen.queryByRole('button', { name: 'Approve' })).not.toBeInTheDocument();
45
+ });
46
+
47
+ it('renders the changes-requested terminal state with a Changes Requested pill', () => {
48
+ render(<PlanApproval {...baseProps} status="changes-requested" />);
49
+ expect(screen.getByText('Changes Requested')).toBeInTheDocument();
50
+ expect(screen.queryByRole('button', { name: 'Approve' })).not.toBeInTheDocument();
51
+ });
52
+
53
+ it('singularizes the step count when stepCount is 1', () => {
54
+ render(<PlanApproval {...baseProps} stepCount={1} status="pending" />);
55
+ expect(screen.getByText('1 step')).toBeInTheDocument();
56
+ });
57
+
58
+ it('omits the step count label when stepCount is missing or zero', () => {
59
+ const { rerender } = render(<PlanApproval title="t" summary="s" status="pending" />);
60
+ expect(screen.queryByText(/step/)).not.toBeInTheDocument();
61
+ rerender(<PlanApproval title="t" summary="s" stepCount={0} status="pending" />);
62
+ expect(screen.queryByText(/step/)).not.toBeInTheDocument();
63
+ });
64
+
65
+ it('toggles the plan body when Show more / Show less is clicked', async () => {
66
+ const user = userEvent.setup();
67
+ render(
68
+ <PlanApproval
69
+ {...baseProps}
70
+ status="pending"
71
+ planBody={<div data-testid="plan-body">Whole plan</div>}
72
+ />,
73
+ );
74
+
75
+ expect(screen.queryByTestId('plan-body')).not.toBeInTheDocument();
76
+
77
+ await user.click(screen.getByRole('button', { name: /Show more/i }));
78
+ expect(screen.getByTestId('plan-body')).toBeInTheDocument();
79
+
80
+ await user.click(screen.getByRole('button', { name: /Show less/i }));
81
+ expect(screen.queryByTestId('plan-body')).not.toBeInTheDocument();
82
+ });
83
+
84
+ it('hides the Show more toggle when no plan body is provided', () => {
85
+ render(<PlanApproval {...baseProps} status="pending" />);
86
+ expect(screen.queryByRole('button', { name: /Show more/i })).not.toBeInTheDocument();
87
+ });
88
+
89
+ it('calls onApprove when the Approve button is clicked', async () => {
90
+ const onApprove = vi.fn();
91
+ const user = userEvent.setup();
92
+ render(<PlanApproval {...baseProps} status="pending" onApprove={onApprove} />);
93
+
94
+ await user.click(screen.getByRole('button', { name: 'Approve' }));
95
+ expect(onApprove).toHaveBeenCalledTimes(1);
96
+ });
97
+
98
+ it('calls onClose when the close button is clicked', async () => {
99
+ const onClose = vi.fn();
100
+ const user = userEvent.setup();
101
+ render(<PlanApproval {...baseProps} status="pending" onClose={onClose} />);
102
+
103
+ await user.click(screen.getByRole('button', { name: 'Dismiss plan' }));
104
+ expect(onClose).toHaveBeenCalledTimes(1);
105
+ });
106
+
107
+ it('opens the change-request textarea and submits trimmed reason via onRequestChanges', async () => {
108
+ const onRequestChanges = vi.fn();
109
+ const user = userEvent.setup();
110
+ render(
111
+ <PlanApproval
112
+ {...baseProps}
113
+ status="pending"
114
+ defaultExpanded
115
+ planBody={<div>Body</div>}
116
+ onRequestChanges={onRequestChanges}
117
+ />,
118
+ );
119
+
120
+ await user.click(screen.getByRole('button', { name: 'Request Changes' }));
121
+
122
+ const textarea = screen.getByLabelText('What would you like to change in the plan?');
123
+ expect(textarea).toBeInTheDocument();
124
+
125
+ await user.click(screen.getByRole('button', { name: 'Send change request' }));
126
+ expect(onRequestChanges).not.toHaveBeenCalled();
127
+
128
+ await user.type(textarea, ' please add a rollback step ');
129
+ await user.click(screen.getByRole('button', { name: 'Send change request' }));
130
+
131
+ expect(onRequestChanges).toHaveBeenCalledTimes(1);
132
+ expect(onRequestChanges).toHaveBeenCalledWith('please add a rollback step');
133
+ });
134
+
135
+ it('disables Approve while composing a change request and re-enables on Cancel', async () => {
136
+ const onApprove = vi.fn();
137
+ const user = userEvent.setup();
138
+ render(
139
+ <PlanApproval
140
+ {...baseProps}
141
+ status="pending"
142
+ onApprove={onApprove}
143
+ onRequestChanges={vi.fn()}
144
+ />,
145
+ );
146
+
147
+ expect(screen.getByRole('button', { name: 'Approve' })).toBeEnabled();
148
+ await user.click(screen.getByRole('button', { name: 'Request Changes' }));
149
+ expect(screen.getByRole('button', { name: 'Approve' })).toBeDisabled();
150
+ expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled();
151
+
152
+ await user.click(screen.getByRole('button', { name: 'Cancel' }));
153
+ expect(screen.getByRole('button', { name: 'Approve' })).toBeEnabled();
154
+ expect(screen.getByRole('button', { name: 'Request Changes' })).toBeInTheDocument();
155
+ });
156
+
157
+ it('auto-expands when Request Changes is clicked from the collapsed state', async () => {
158
+ const user = userEvent.setup();
159
+ render(
160
+ <PlanApproval
161
+ {...baseProps}
162
+ status="pending"
163
+ planBody={<div data-testid="plan-body">Body</div>}
164
+ onRequestChanges={vi.fn()}
165
+ />,
166
+ );
167
+
168
+ expect(screen.queryByTestId('plan-body')).not.toBeInTheDocument();
169
+ await user.click(screen.getByRole('button', { name: 'Request Changes' }));
170
+ expect(screen.getByTestId('plan-body')).toBeInTheDocument();
171
+ });
172
+
173
+ it('disables all interactive controls while submitting', () => {
174
+ render(
175
+ <PlanApproval
176
+ {...baseProps}
177
+ status="pending"
178
+ isSubmitting
179
+ onApprove={vi.fn()}
180
+ onRequestChanges={vi.fn()}
181
+ onClose={vi.fn()}
182
+ />,
183
+ );
184
+
185
+ expect(screen.getByRole('button', { name: 'Approve' })).toBeDisabled();
186
+ expect(screen.getByRole('button', { name: 'Request Changes' })).toBeDisabled();
187
+ expect(screen.getByRole('button', { name: 'Dismiss plan' })).toBeDisabled();
188
+ });
189
+
190
+ it('submits change request on Enter and inserts a newline on Shift+Enter', async () => {
191
+ const onRequestChanges = vi.fn();
192
+ const user = userEvent.setup();
193
+ render(
194
+ <PlanApproval
195
+ {...baseProps}
196
+ status="pending"
197
+ defaultExpanded
198
+ planBody={<div>Body</div>}
199
+ onRequestChanges={onRequestChanges}
200
+ />,
201
+ );
202
+
203
+ await user.click(screen.getByRole('button', { name: 'Request Changes' }));
204
+ const textarea = screen.getByLabelText('What would you like to change in the plan?');
205
+ await user.type(textarea, 'add rollback{Shift>}{Enter}{/Shift}step');
206
+ expect((textarea as HTMLTextAreaElement).value).toBe('add rollback\nstep');
207
+
208
+ fireEvent.keyDown(textarea, { key: 'Enter' });
209
+ expect(onRequestChanges).toHaveBeenCalledWith('add rollback\nstep');
210
+ });
211
+
212
+ it('respects controlled isExpanded and notifies onExpandToggle', async () => {
213
+ const onExpandToggle = vi.fn();
214
+ const user = userEvent.setup();
215
+ const { rerender } = render(
216
+ <PlanApproval
217
+ {...baseProps}
218
+ status="pending"
219
+ isExpanded={false}
220
+ onExpandToggle={onExpandToggle}
221
+ planBody={<div data-testid="plan-body">Body</div>}
222
+ />,
223
+ );
224
+
225
+ expect(screen.queryByTestId('plan-body')).not.toBeInTheDocument();
226
+ await user.click(screen.getByRole('button', { name: /Show more/i }));
227
+ expect(onExpandToggle).toHaveBeenCalledWith(true);
228
+ expect(screen.queryByTestId('plan-body')).not.toBeInTheDocument();
229
+
230
+ rerender(
231
+ <PlanApproval
232
+ {...baseProps}
233
+ status="pending"
234
+ isExpanded
235
+ onExpandToggle={onExpandToggle}
236
+ planBody={<div data-testid="plan-body">Body</div>}
237
+ />,
238
+ );
239
+ expect(screen.getByTestId('plan-body')).toBeInTheDocument();
240
+ });
241
+ });