@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,148 @@
1
+ import { fireEvent, render, screen } from '@testing-library/react';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+
4
+ import { NumberInput } from './NumberInput';
5
+
6
+ const getInput = () => screen.getByPlaceholderText('number') as HTMLInputElement;
7
+
8
+ describe('<NumberInput />', () => {
9
+ describe('controlled state', () => {
10
+ it('renders empty when value is null', () => {
11
+ render(<NumberInput placeholder="number" value={null} />);
12
+ expect(getInput().value).toBe('');
13
+ });
14
+
15
+ it('renders empty when value is undefined and no defaultValue', () => {
16
+ render(<NumberInput placeholder="number" />);
17
+ expect(getInput().value).toBe('');
18
+ });
19
+
20
+ it('renders the controlled value', () => {
21
+ render(<NumberInput placeholder="number" value={42} onValueChange={vi.fn()} />);
22
+ expect(getInput().value).toBe('42');
23
+ });
24
+
25
+ it('emits onValueChange with parsed number on input', () => {
26
+ const onValueChange = vi.fn();
27
+ render(<NumberInput placeholder="number" value={null} onValueChange={onValueChange} />);
28
+ fireEvent.change(getInput(), { target: { value: '7' } });
29
+ expect(onValueChange).toHaveBeenCalledWith(7);
30
+ });
31
+
32
+ it('emits onValueChange(null) when input is cleared', () => {
33
+ const onValueChange = vi.fn();
34
+ render(<NumberInput placeholder="number" value={5} onValueChange={onValueChange} />);
35
+ fireEvent.change(getInput(), { target: { value: '' } });
36
+ expect(onValueChange).toHaveBeenCalledWith(null);
37
+ });
38
+
39
+ it('emits onValueBlur with the current numeric value', () => {
40
+ const onValueBlur = vi.fn();
41
+ render(<NumberInput placeholder="number" value={3} onValueBlur={onValueBlur} />);
42
+ fireEvent.blur(getInput());
43
+ expect(onValueBlur).toHaveBeenCalledWith(3);
44
+ });
45
+
46
+ it('emits onValueBlur(null) when blurring an empty input', () => {
47
+ const onValueBlur = vi.fn();
48
+ render(<NumberInput placeholder="number" value={null} onValueBlur={onValueBlur} />);
49
+ fireEvent.blur(getInput());
50
+ expect(onValueBlur).toHaveBeenCalledWith(null);
51
+ });
52
+ });
53
+
54
+ describe('uncontrolled state', () => {
55
+ it('seeds the input from defaultValue', () => {
56
+ render(<NumberInput placeholder="number" defaultValue={5} />);
57
+ expect(getInput().value).toBe('5');
58
+ });
59
+
60
+ it('treats null defaultValue as empty', () => {
61
+ render(<NumberInput placeholder="number" defaultValue={null} />);
62
+ expect(getInput().value).toBe('');
63
+ });
64
+
65
+ it('propagates user typing through onValueChange', () => {
66
+ const onValueChange = vi.fn();
67
+ render(<NumberInput placeholder="number" onValueChange={onValueChange} />);
68
+ const input = getInput();
69
+ fireEvent.change(input, { target: { value: '12' } });
70
+ expect(input.value).toBe('12');
71
+ expect(onValueChange).toHaveBeenLastCalledWith(12);
72
+ });
73
+ });
74
+
75
+ describe('NaN handling', () => {
76
+ it('emits null (never NaN) when the input has no parseable value', () => {
77
+ const onValueChange = vi.fn();
78
+ render(<NumberInput placeholder="number" defaultValue={5} onValueChange={onValueChange} />);
79
+ fireEvent.change(getInput(), { target: { value: '' } });
80
+ expect(onValueChange).toHaveBeenCalledWith(null);
81
+ expect(onValueChange).not.toHaveBeenCalledWith(Number.NaN);
82
+ });
83
+ });
84
+
85
+ describe('pass-through', () => {
86
+ it('forwards min / max / step / disabled / readOnly / id / name to the underlying input', () => {
87
+ render(
88
+ <NumberInput
89
+ placeholder="number"
90
+ id="qty"
91
+ name="quantity"
92
+ min={1}
93
+ max={10}
94
+ step={2}
95
+ disabled
96
+ readOnly
97
+ />,
98
+ );
99
+ const input = getInput();
100
+ expect(input.id).toBe('qty');
101
+ expect(input.name).toBe('quantity');
102
+ expect(input.min).toBe('1');
103
+ expect(input.max).toBe('10');
104
+ expect(input.step).toBe('2');
105
+ expect(input.disabled).toBe(true);
106
+ expect(input.readOnly).toBe(true);
107
+ expect(input.type).toBe('number');
108
+ });
109
+ });
110
+
111
+ describe('forwardRef', () => {
112
+ it('forwards ref to the <input type="number"> element', () => {
113
+ let captured: HTMLInputElement | null = null;
114
+ render(
115
+ <NumberInput
116
+ placeholder="number"
117
+ ref={(node) => {
118
+ captured = node;
119
+ }}
120
+ />,
121
+ );
122
+ expect(captured).toBe(getInput());
123
+ expect(captured!.type).toBe('number');
124
+ });
125
+ });
126
+
127
+ describe('external onChange / onBlur', () => {
128
+ it('fires onChange alongside onValueChange', () => {
129
+ const onChange = vi.fn();
130
+ const onValueChange = vi.fn();
131
+ render(
132
+ <NumberInput placeholder="number" onChange={onChange} onValueChange={onValueChange} />,
133
+ );
134
+ fireEvent.change(getInput(), { target: { value: '9' } });
135
+ expect(onChange).toHaveBeenCalledTimes(1);
136
+ expect(onValueChange).toHaveBeenCalledWith(9);
137
+ });
138
+
139
+ it('fires onBlur alongside onValueBlur', () => {
140
+ const onBlur = vi.fn();
141
+ const onValueBlur = vi.fn();
142
+ render(<NumberInput placeholder="number" onBlur={onBlur} onValueBlur={onValueBlur} />);
143
+ fireEvent.blur(getInput());
144
+ expect(onBlur).toHaveBeenCalledTimes(1);
145
+ expect(onValueBlur).toHaveBeenCalled();
146
+ });
147
+ });
148
+ });
@@ -0,0 +1,89 @@
1
+ import type {
2
+ ChangeEvent,
3
+ ChangeEventHandler,
4
+ ComponentProps,
5
+ ElementRef,
6
+ FocusEventHandler,
7
+ ReactNode,
8
+ Ref,
9
+ } from 'react';
10
+
11
+ import { InputGroup } from '../../components/InputGroup';
12
+
13
+ type InputGroupProps = Pick<
14
+ ComponentProps<typeof InputGroup>,
15
+ 'variant' | 'focusVariant' | 'state' | 'sizing'
16
+ >;
17
+
18
+ type InputGroupInputProps = Omit<
19
+ ComponentProps<typeof InputGroup.Input>,
20
+ 'value' | 'defaultValue' | 'type' | 'prefix'
21
+ >;
22
+
23
+ type Props = InputGroupProps &
24
+ InputGroupInputProps & {
25
+ value?: number | null;
26
+ defaultValue?: number | null;
27
+ onValueChange?: (value: number | null) => void;
28
+ onValueBlur?: (value: number | null) => void;
29
+ prefix?: ReactNode;
30
+ suffix?: ReactNode;
31
+ };
32
+
33
+ const toNumberOrNull = (event: ChangeEvent<HTMLInputElement>) =>
34
+ Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber;
35
+
36
+ export const NumberInput = ({
37
+ ref,
38
+ state,
39
+ variant,
40
+ focusVariant,
41
+ sizing,
42
+ className,
43
+
44
+ value,
45
+ defaultValue,
46
+ onValueChange,
47
+ onValueBlur,
48
+ onChange,
49
+ onBlur,
50
+
51
+ prefix,
52
+ suffix,
53
+
54
+ ...inputProps
55
+ }: Props & { ref?: Ref<ElementRef<'input'>> }) => {
56
+ const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {
57
+ onValueChange?.(toNumberOrNull(event));
58
+ onChange?.(event);
59
+ };
60
+
61
+ const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {
62
+ onValueBlur?.(toNumberOrNull(event));
63
+ onBlur?.(event);
64
+ };
65
+
66
+ const isControlled = value !== undefined;
67
+ const valueProp = isControlled ? { value: value ?? '' } : { defaultValue: defaultValue ?? '' };
68
+
69
+ return (
70
+ <InputGroup
71
+ state={state}
72
+ variant={variant}
73
+ sizing={sizing}
74
+ focusVariant={focusVariant}
75
+ className={className}
76
+ >
77
+ {prefix && <InputGroup.Addon align="inline-start">{prefix}</InputGroup.Addon>}
78
+ <InputGroup.Input
79
+ {...inputProps}
80
+ {...valueProp}
81
+ ref={ref}
82
+ type="number"
83
+ onChange={handleChange}
84
+ onBlur={handleBlur}
85
+ />
86
+ {suffix && <InputGroup.Addon align="inline-end">{suffix}</InputGroup.Addon>}
87
+ </InputGroup>
88
+ );
89
+ };
@@ -0,0 +1 @@
1
+ export * from './NumberInput';
@@ -0,0 +1,77 @@
1
+ # PageHeader
2
+
3
+ Structured page-header block that encodes the
4
+ [evviku page-header patterns](https://github.com/evviku/design-system-docs/tree/main/docs/patterns/page-header)
5
+ 1:1 at the type level. Two discriminated variants:
6
+
7
+ - `PageHeader.Index` — top-level list/collection pages.
8
+ - `PageHeader.Detail` — single-entity pages.
9
+
10
+ The variant choice enforces the pattern constraints (e.g. you cannot pass an
11
+ overflow menu to `Index`, or `metadata` to `Detail`). Reach for
12
+ `PageLayout.Header` / `PageLayout.Breadcrumbs` only for layouts that don't fit
13
+ either variant.
14
+
15
+ ## When to use which
16
+
17
+ | Use `PageHeader.Index` when | Use `PageHeader.Detail` when |
18
+ | ------------------------------------------------------ | ---------------------------------------------------------- |
19
+ | The page is a top-level list (Flows, Storage, Jobs, …) | The page shows one entity (a bucket, flow, data app, …) |
20
+ | There is no parent in the same section | The entity has a parent hierarchy worth breadcrumbing |
21
+ | The primary action is "create / add a new X" | The primary action is "edit / deploy / run on this entity" |
22
+
23
+ ## API at a glance
24
+
25
+ ```tsx
26
+ // Index — no breadcrumbs, metadata > description, optional headerNav.
27
+ <PageHeader.Index
28
+ title="Storage"
29
+ metadata="3 buckets and 39 tables" // or `description` (mutually exclusive)
30
+ documentation={<Button argo variant="invisible" icon="book-blank" />}
31
+ action={<Button argo>New bucket</Button>}
32
+ headerNav={<Tabs ... />}
33
+ />
34
+
35
+ // Detail — mandatory breadcrumbs, overflow row, ≤2 visible actions.
36
+ <PageHeader.Detail
37
+ breadcrumbs={<Breadcrumb>...</Breadcrumb>}
38
+ overflowActions={<DropdownMenu>...</DropdownMenu>}
39
+ title="Marketing bucket"
40
+ badges={<><Badge>Active</Badge></>}
41
+ description="..."
42
+ secondaryAction={<Button argo variant="secondary">Open editor</Button>}
43
+ primaryAction={<Button argo>Deploy</Button>}
44
+ headerNav={<Tabs ... />}
45
+ />
46
+ ```
47
+
48
+ ## Rules from the patterns
49
+
50
+ - **Index**: no breadcrumbs, no overflow menu, no search/filter/sort. Search
51
+ belongs in `PageLayout.Toolbar`.
52
+ - **Detail**: breadcrumbs are required (use real entity names; last item is
53
+ not a link). Overflow menu lives on the breadcrumbs row, never in the title
54
+ row.
55
+ - **Max 2 visible actions on Detail** (`primaryAction` + optional
56
+ `secondaryAction`). Everything else goes in `overflowActions`.
57
+ - **`metadata` wins over `description`** on Index. Pass `metadata` for count
58
+ / system summaries; reserve `description` for prose.
59
+ - **`headerNav` only when there is >1 dataset / section** worth navigating to.
60
+
61
+ ## Component rules
62
+
63
+ - **Always opt into the `argo` variant** on the Buttons you pass into the
64
+ slots (`Button argo …`).
65
+ - **Compose** existing `Breadcrumb`, `Badge`, `DropdownMenu`, `Tabs` from
66
+ `@keboola/design` — slots take any `ReactNode`, but use the design-system
67
+ pieces.
68
+ - Title and description can be any `ReactNode`; pass an
69
+ `InlineEditableText` (when it lands) for editable titles per the Detail
70
+ pattern.
71
+
72
+ ## Stories
73
+
74
+ - `IndexFlows` — description + secondary/primary actions, no header nav.
75
+ - `IndexStorage` — `metadata` count summary + 5-tab `headerNav`.
76
+ - `DetailBucket` — breadcrumbs + overflow + badges + primary action.
77
+ - `DetailDataApp` — primary + secondary actions + 3-tab `headerNav`.
@@ -0,0 +1,272 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Badge } from '../../components/Badge';
4
+ import { Breadcrumb } from '../../components/Breadcrumb';
5
+ import { Button } from '../../components/Button';
6
+ import { DropdownMenu } from '../../components/DropdownMenu';
7
+ import { Tabs, TabsContent } from '../../components/Tabs';
8
+ import { PageLayout } from '../PageLayout';
9
+ import { SplitButton } from '../SplitButton';
10
+
11
+ import { PageHeader } from './PageHeader';
12
+
13
+ type Story = StoryObj<typeof PageHeader.Index>;
14
+
15
+ export default {
16
+ component: PageHeader.Index,
17
+ parameters: {
18
+ layout: 'fullscreen',
19
+ docs: {
20
+ description: {
21
+ component:
22
+ 'Structured page-header block matching the [evviku page-header patterns](https://github.com/evviku/design-system-docs/tree/main/docs/patterns/page-header). Two discriminated variants — `PageHeader.Index` (top-level list pages, no breadcrumbs) and `PageHeader.Detail` (entity pages, mandatory breadcrumbs + overflow row + ≤2 visible actions). The variant chosen at the type level enforces the pattern constraints (e.g. you cannot pass an overflow menu to `Index`, or `metadata` to `Detail`).',
23
+ },
24
+ },
25
+ },
26
+ } satisfies Meta<typeof PageHeader.Index>;
27
+
28
+ const Placeholder = ({ label, height = 'tw-h-48' }: { label: string; height?: string }) => (
29
+ <div
30
+ className={`tw-flex tw-items-center tw-justify-center tw-rounded tw-border tw-border-dashed tw-border-border tw-bg-muted/30 tw-text-sm tw-text-muted-foreground ${height}`}
31
+ >
32
+ {label}
33
+ </div>
34
+ );
35
+
36
+ // Index — Flows (description + primary + secondary actions, no header nav).
37
+ export const IndexFlows: Story = {
38
+ render: () => (
39
+ <PageLayout>
40
+ <PageHeader.Index
41
+ title="Flows"
42
+ description="Build flows with branching logic and conditions. Tasks run based on previous results, errors, or custom expressions."
43
+ documentation={
44
+ <Button argo variant="invisible" icon="book-blank" aria-label="Documentation" />
45
+ }
46
+ action={
47
+ <>
48
+ <Button argo variant="secondary" onClick={() => {}}>
49
+ New folder
50
+ </Button>
51
+ <Button argo onClick={() => {}}>
52
+ New flow
53
+ </Button>
54
+ </>
55
+ }
56
+ />
57
+ <PageLayout.Toolbar>
58
+ <Placeholder label="Search input + filter pills" height="tw-h-10" />
59
+ </PageLayout.Toolbar>
60
+ <PageLayout.Content>
61
+ <Placeholder label="EntityList" height="tw-h-96" />
62
+ </PageLayout.Content>
63
+ </PageLayout>
64
+ ),
65
+ };
66
+
67
+ // Index — Storage (metadata + header nav + SplitButton primary action).
68
+ // SSOT example: `action.type = "button-group"` → SplitButton in our design system.
69
+ export const IndexStorage: Story = {
70
+ render: () => (
71
+ <PageLayout>
72
+ <PageHeader.Index
73
+ title="Storage"
74
+ metadata="3 buckets and 39 tables"
75
+ documentation={
76
+ <Button argo variant="invisible" icon="book-blank" aria-label="Documentation" />
77
+ }
78
+ action={
79
+ <SplitButton
80
+ argo
81
+ onClick={() => {}}
82
+ actions={
83
+ <>
84
+ <SplitButton.Action icon="upload" onClick={() => {}}>
85
+ Upload file
86
+ </SplitButton.Action>
87
+ <SplitButton.Action icon="cloud-arrow-down" onClick={() => {}}>
88
+ Import from external storage
89
+ </SplitButton.Action>
90
+ </>
91
+ }
92
+ >
93
+ New bucket
94
+ </SplitButton>
95
+ }
96
+ headerNav={
97
+ <Tabs
98
+ defaultValue="tables"
99
+ triggers={[
100
+ { value: 'tables', title: 'Tables & Buckets' },
101
+ { value: 'files', title: 'Files' },
102
+ { value: 'data-streams', title: 'Data Streams' },
103
+ { value: 'storage-jobs', title: 'Storage Jobs' },
104
+ { value: 'events', title: 'Events' },
105
+ ]}
106
+ >
107
+ <TabsContent value="tables">
108
+ <Placeholder label="Tables & Buckets list" height="tw-h-96" />
109
+ </TabsContent>
110
+ <TabsContent value="files">
111
+ <Placeholder label="Files list" height="tw-h-96" />
112
+ </TabsContent>
113
+ <TabsContent value="data-streams">
114
+ <Placeholder label="Data Streams list" height="tw-h-96" />
115
+ </TabsContent>
116
+ <TabsContent value="storage-jobs">
117
+ <Placeholder label="Storage Jobs list" height="tw-h-96" />
118
+ </TabsContent>
119
+ <TabsContent value="events">
120
+ <Placeholder label="Events list" height="tw-h-96" />
121
+ </TabsContent>
122
+ </Tabs>
123
+ }
124
+ />
125
+ </PageLayout>
126
+ ),
127
+ };
128
+
129
+ // Detail — bucket (breadcrumbs + overflow + badges + primary action).
130
+ export const DetailBucket: Story = {
131
+ render: () => (
132
+ <PageLayout>
133
+ <PageHeader.Detail
134
+ breadcrumbs={
135
+ <Breadcrumb>
136
+ <Breadcrumb.List>
137
+ <Breadcrumb.Item>
138
+ <Breadcrumb.Link href="#">Storage</Breadcrumb.Link>
139
+ </Breadcrumb.Item>
140
+ <Breadcrumb.Separator />
141
+ <Breadcrumb.Item>
142
+ <Breadcrumb.Page>Marketing bucket</Breadcrumb.Page>
143
+ </Breadcrumb.Item>
144
+ </Breadcrumb.List>
145
+ </Breadcrumb>
146
+ }
147
+ overflowActions={
148
+ <DropdownMenu>
149
+ <DropdownMenu.Trigger asChild>
150
+ <Button
151
+ argo
152
+ variant="invisible"
153
+ size="icon-sm"
154
+ icon="ellipsis-vertical"
155
+ aria-label="More actions"
156
+ />
157
+ </DropdownMenu.Trigger>
158
+ <DropdownMenu.Content align="end">
159
+ <DropdownMenu.Item icon="copy">Copy</DropdownMenu.Item>
160
+ <DropdownMenu.Item icon="user-group">Manage permissions</DropdownMenu.Item>
161
+ <DropdownMenu.Separator />
162
+ <DropdownMenu.Item icon="trash">Delete</DropdownMenu.Item>
163
+ </DropdownMenu.Content>
164
+ </DropdownMenu>
165
+ }
166
+ title="Marketing bucket"
167
+ badges={
168
+ <>
169
+ <Badge color="green">Active</Badge>
170
+ <Badge color="gray">Shared</Badge>
171
+ </>
172
+ }
173
+ description="Contains marketing datasets and transformation outputs."
174
+ primaryAction={
175
+ <SplitButton
176
+ argo
177
+ onClick={() => {}}
178
+ actions={
179
+ <>
180
+ <SplitButton.Action icon="upload" onClick={() => {}}>
181
+ Upload CSV
182
+ </SplitButton.Action>
183
+ <SplitButton.Action icon="link" onClick={() => {}}>
184
+ Link existing table
185
+ </SplitButton.Action>
186
+ </>
187
+ }
188
+ >
189
+ Add table
190
+ </SplitButton>
191
+ }
192
+ />
193
+ <PageLayout.Content>
194
+ <Placeholder label="Bucket detail body" height="tw-h-96" />
195
+ </PageLayout.Content>
196
+ </PageLayout>
197
+ ),
198
+ };
199
+
200
+ // Detail — sales dashboard (primary + secondary actions + header nav).
201
+ export const DetailDataApp: Story = {
202
+ render: () => (
203
+ <PageLayout>
204
+ <PageHeader.Detail
205
+ breadcrumbs={
206
+ <Breadcrumb>
207
+ <Breadcrumb.List>
208
+ <Breadcrumb.Item>
209
+ <Breadcrumb.Link href="#">Data Apps</Breadcrumb.Link>
210
+ </Breadcrumb.Item>
211
+ <Breadcrumb.Separator />
212
+ <Breadcrumb.Item>
213
+ <Breadcrumb.Page>Sales dashboard</Breadcrumb.Page>
214
+ </Breadcrumb.Item>
215
+ </Breadcrumb.List>
216
+ </Breadcrumb>
217
+ }
218
+ overflowActions={
219
+ <DropdownMenu>
220
+ <DropdownMenu.Trigger asChild>
221
+ <Button
222
+ argo
223
+ variant="invisible"
224
+ size="icon-sm"
225
+ icon="ellipsis-vertical"
226
+ aria-label="More actions"
227
+ />
228
+ </DropdownMenu.Trigger>
229
+ <DropdownMenu.Content align="end">
230
+ <DropdownMenu.Item icon="copy">Duplicate</DropdownMenu.Item>
231
+ <DropdownMenu.Item icon="bug">Debug mode</DropdownMenu.Item>
232
+ <DropdownMenu.Separator />
233
+ <DropdownMenu.Item icon="trash">Delete</DropdownMenu.Item>
234
+ </DropdownMenu.Content>
235
+ </DropdownMenu>
236
+ }
237
+ title="Sales dashboard"
238
+ badges={<Badge color="green">Running</Badge>}
239
+ secondaryAction={
240
+ <Button argo variant="secondary" onClick={() => {}}>
241
+ Open editor
242
+ </Button>
243
+ }
244
+ primaryAction={
245
+ <Button argo onClick={() => {}}>
246
+ Deploy
247
+ </Button>
248
+ }
249
+ headerNav={
250
+ <Tabs
251
+ defaultValue="overview"
252
+ triggers={[
253
+ { value: 'overview', title: 'Overview' },
254
+ { value: 'events', title: 'Events' },
255
+ { value: 'settings', title: 'Settings' },
256
+ ]}
257
+ >
258
+ <TabsContent value="overview">
259
+ <Placeholder label="Overview" height="tw-h-96" />
260
+ </TabsContent>
261
+ <TabsContent value="events">
262
+ <Placeholder label="Events" height="tw-h-96" />
263
+ </TabsContent>
264
+ <TabsContent value="settings">
265
+ <Placeholder label="Settings" height="tw-h-96" />
266
+ </TabsContent>
267
+ </Tabs>
268
+ }
269
+ />
270
+ </PageLayout>
271
+ ),
272
+ };
@@ -0,0 +1,7 @@
1
+ import { PageHeaderDetail } from './PageHeaderDetail';
2
+ import { PageHeaderIndex } from './PageHeaderIndex';
3
+
4
+ export const PageHeader = {
5
+ Index: PageHeaderIndex,
6
+ Detail: PageHeaderDetail,
7
+ };
@@ -0,0 +1,62 @@
1
+ import type { ComponentPropsWithoutRef, ElementRef, ReactNode, Ref } from 'react';
2
+
3
+ import { cn } from '../../utils';
4
+
5
+ import { badgesClass, descriptionClass, titleClass, titleRowClass } from './styles';
6
+
7
+ // Detail page header — single entity pages (bucket, flow, data app, …).
8
+ // Pattern: docs/patterns/page-header/detail/detail-page-header.md
9
+ // - Breadcrumbs are required; overflow menu sits on the breadcrumbs row.
10
+ // - Max two visible actions: `primaryAction` + optional `secondaryAction`.
11
+ // - All other actions belong in the breadcrumbs-row overflow menu.
12
+ type PageHeaderDetailProps = ComponentPropsWithoutRef<'header'> & {
13
+ breadcrumbs: ReactNode;
14
+ overflowActions?: ReactNode;
15
+ title: ReactNode;
16
+ badges?: ReactNode;
17
+ description?: ReactNode;
18
+ primaryAction?: ReactNode;
19
+ secondaryAction?: ReactNode;
20
+ headerNav?: ReactNode;
21
+ };
22
+
23
+ export const PageHeaderDetail = ({
24
+ ref,
25
+ className,
26
+ breadcrumbs,
27
+ overflowActions,
28
+ title,
29
+ badges,
30
+ description,
31
+ primaryAction,
32
+ secondaryAction,
33
+ headerNav,
34
+ ...props
35
+ }: PageHeaderDetailProps & { ref?: Ref<ElementRef<'header'>> }) => (
36
+ <header ref={ref} className={cn('tw-flex tw-w-full tw-flex-col tw-gap-4', className)} {...props}>
37
+ <div className="tw-flex tw-w-full tw-items-center tw-justify-between tw-gap-4">
38
+ <div className="tw-min-w-0 tw-flex-1">{breadcrumbs}</div>
39
+ {overflowActions && (
40
+ <div className="tw-flex tw-shrink-0 tw-items-center tw-gap-2">{overflowActions}</div>
41
+ )}
42
+ </div>
43
+
44
+ <div className="tw-flex tw-w-full tw-items-start tw-justify-between tw-gap-4">
45
+ <div className="tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-gap-2 tw-pr-2">
46
+ <div className={titleRowClass}>
47
+ <h1 className={titleClass}>{title}</h1>
48
+ {badges && <div className={badgesClass}>{badges}</div>}
49
+ </div>
50
+ {description && <p className={descriptionClass}>{description}</p>}
51
+ </div>
52
+ {(primaryAction || secondaryAction) && (
53
+ <div className="tw-flex tw-shrink-0 tw-items-center tw-gap-2">
54
+ {secondaryAction}
55
+ {primaryAction}
56
+ </div>
57
+ )}
58
+ </div>
59
+
60
+ {headerNav}
61
+ </header>
62
+ );