@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,678 @@
1
+ import { useReducer } from 'react';
2
+ import type { ComponentProps, FormEventHandler } from 'react';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
+ import { action } from 'storybook/actions';
5
+
6
+ import { Alert } from '../Alert';
7
+ import { Button } from '../Button';
8
+ import { ButtonGroup } from '../ButtonGroup';
9
+ import { FormGroup } from '../FormGroup';
10
+ import { Label } from '../Label';
11
+ import { Tabs, TabsContent } from '../Tabs';
12
+
13
+ import { Modal } from './Modal';
14
+ import { ModalContent } from './ModalContent';
15
+
16
+ const meta = {
17
+ component: Modal,
18
+ } satisfies Meta<typeof Modal>;
19
+
20
+ export default meta;
21
+
22
+ type Story = StoryObj<typeof meta>;
23
+
24
+ const ModalDefault = (props: ComponentProps<typeof Modal>) => (
25
+ <Modal {...props}>
26
+ <Modal.Trigger asChild>
27
+ <Button>Open Modal</Button>
28
+ </Modal.Trigger>
29
+
30
+ <Modal.Content>
31
+ <Modal.Icon icon="rocket" color="red" />
32
+ <Modal.Header title="Default Modal" description="Opens default modal">
33
+ <Alert variant="info">Additional Header stuff</Alert>
34
+ </Modal.Header>
35
+
36
+ <Modal.Body>
37
+ <p>Some contents...</p>
38
+ <p>Some contents...</p>
39
+ <p>Some contents...</p>
40
+ </Modal.Body>
41
+
42
+ <Modal.Footer>
43
+ <ButtonGroup variant="block">
44
+ <Modal.Close asChild>
45
+ <Button type="button" variant="secondary">
46
+ Close
47
+ </Button>
48
+ </Modal.Close>
49
+
50
+ <Button type="button">Ok</Button>
51
+ </ButtonGroup>
52
+ </Modal.Footer>
53
+ </Modal.Content>
54
+ </Modal>
55
+ );
56
+
57
+ /**
58
+ * Default Modal component in uncontrolled mode __(Recommended)__
59
+ */
60
+ export const Default: Story = {
61
+ render: ModalDefault,
62
+ };
63
+
64
+ const ModalLongContent = (props: ComponentProps<typeof Modal>) => (
65
+ <Modal {...props}>
66
+ <Modal.Trigger asChild>
67
+ <Button>Open Modal</Button>
68
+ </Modal.Trigger>
69
+
70
+ <Modal.Content>
71
+ <Modal.Icon icon="rocket" color="red" />
72
+ <Modal.Header title="Default Modal" description="Opens default modal">
73
+ <Alert variant="info">Addiitonal Header staff</Alert>
74
+ </Modal.Header>
75
+
76
+ <Modal.Body>
77
+ <p>
78
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris fringilla, risus ut
79
+ imperdiet pellentesque, justo augue placerat dui, eget porta augue justo sed enim. Vivamus
80
+ dui nulla, interdum vitae dolor vitae, condimentum sagittis odio. Sed sit amet nisi
81
+ pulvinar, lacinia nibh at, pulvinar velit. Etiam arcu eros, consequat in volutpat nec,
82
+ scelerisque at risus. Donec nibh ipsum, tristique ut nisi vitae, auctor vulputate erat.
83
+ Fusce egestas augue eu nisl euismod, non mattis massa lacinia. Nulla facilisi. Mauris
84
+ gravida tincidunt tristique. Morbi sollicitudin laoreet enim, at rutrum libero volutpat
85
+ eu. Nunc accumsan viverra dolor, id dapibus tortor sodales sed. In sit amet viverra magna.
86
+ Suspendisse eget quam vulputate, imperdiet massa ac, volutpat sem. Ut sit amet tortor
87
+ mollis, imperdiet nisi vel, gravida urna. Mauris quis consectetur turpis. Phasellus vel
88
+ tortor ornare, finibus velit sed, vestibulum mauris. Suspendisse efficitur nulla enim,
89
+ eget congue urna iaculis ut. In hac habitasse platea dictumst. Mauris quis finibus sapien,
90
+ in pretium justo. Etiam gravida orci eget tincidunt ornare. Suspendisse eget malesuada
91
+ lorem. Fusce pretium orci tempor ante consectetur laoreet. Morbi placerat dignissim massa
92
+ sed rhoncus. Duis eu leo ac justo egestas faucibus. Quisque risus justo, mattis sed
93
+ lobortis et, fringilla eu nibh. Donec tempor arcu a est rhoncus, non tempor mauris tempor.
94
+ Etiam auctor aliquet ipsum, vitae tincidunt mauris aliquam sit amet. In fermentum molestie
95
+ felis, vel tincidunt mi sodales egestas. Fusce in nibh vitae tortor hendrerit mollis nec
96
+ et enim. Donec euismod orci eu consectetur volutpat. Vivamus at mauris eget elit aliquet
97
+ venenatis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
98
+ cubilia curae; Cras lobortis, purus at dignissim viverra, tortor mauris lobortis urna,
99
+ consequat facilisis dolor lacus imperdiet est. In sit amet viverra est. Vestibulum a diam
100
+ a purus commodo gravida vitae eleifend dui. Pellentesque vitae eros ut libero sodales
101
+ vulputate et sed risus. Mauris et sapien efficitur, sollicitudin ipsum quis, volutpat
102
+ nisl. Mauris pellentesque, ipsum in accumsan laoreet, sem est mollis nibh, in dictum lacus
103
+ diam lacinia tellus. Quisque sit amet ante vitae odio congue molestie. Lorem ipsum dolor
104
+ sit amet, consectetur adipiscing elit. Phasellus ut quam ut nisl faucibus feugiat non id
105
+ urna. Pellentesque rutrum justo at egestas egestas. In elementum purus dapibus, dapibus
106
+ risus eget, viverra tortor. Pellentesque volutpat cursus faucibus. Vivamus laoreet, tellus
107
+ id fringilla luctus, elit tellus convallis mauris, non finibus nisl magna a libero.
108
+ Integer porta euismod pellentesque. Morbi porta accumsan nibh ut molestie. Proin mattis
109
+ eros sed mauris fringilla ornare. Suspendisse ut rutrum ligula. Sed in laoreet tortor, eu
110
+ congue elit. Morbi accumsan tincidunt arcu, vitae dapibus orci tincidunt sit amet. Duis
111
+ efficitur ipsum nec cursus feugiat. Etiam lacinia felis ut ligula suscipit vehicula.
112
+ Aliquam vitae luctus erat. Pellentesque lacinia ante et odio semper tincidunt. Quisque
113
+ volutpat sem in nunc faucibus, eget pulvinar nisi molestie. Etiam nec placerat eros. Donec
114
+ viverra eros porta imperdiet condimentum. Integer neque mauris, convallis in nisi at,
115
+ vestibulum porta lacus. Pellentesque tristique dictum felis, scelerisque pulvinar sem
116
+ semper sit amet. Sed sollicitudin maximus purus, sit amet lacinia enim aliquam
117
+ condimentum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris fringilla,
118
+ risus ut imperdiet pellentesque, justo augue placerat dui, eget porta augue justo sed
119
+ enim. Vivamus dui nulla, interdum vitae dolor vitae, condimentum sagittis odio. Sed sit
120
+ amet nisi pulvinar, lacinia nibh at, pulvinar velit. Etiam arcu eros, consequat in
121
+ volutpat nec, scelerisque at risus. Donec nibh ipsum, tristique ut nisi vitae, auctor
122
+ vulputate erat. Fusce egestas augue eu nisl euismod, non mattis massa lacinia. Nulla
123
+ facilisi. Mauris gravida tincidunt tristique. Morbi sollicitudin laoreet enim, at rutrum
124
+ libero volutpat eu. Nunc accumsan viverra dolor, id dapibus tortor sodales sed. In sit
125
+ amet viverra magna. Suspendisse eget quam vulputate, imperdiet massa ac, volutpat sem. Ut
126
+ sit amet tortor mollis, imperdiet nisi vel, gravida urna. Mauris quis consectetur turpis.
127
+ Phasellus vel tortor ornare, finibus velit sed, vestibulum mauris. Suspendisse efficitur
128
+ nulla enim, eget congue urna iaculis ut. In hac habitasse platea dictumst. Mauris quis
129
+ finibus sapien, in pretium justo. Etiam gravida orci eget tincidunt ornare. Suspendisse
130
+ eget malesuada lorem. Fusce pretium orci tempor ante consectetur laoreet. Morbi placerat
131
+ dignissim massa sed rhoncus. Duis eu leo ac justo egestas faucibus. Quisque risus justo,
132
+ mattis sed lobortis et, fringilla eu nibh. Donec tempor arcu a est rhoncus, non tempor
133
+ mauris tempor. Etiam auctor aliquet ipsum, vitae tincidunt mauris aliquam sit amet. In
134
+ fermentum molestie felis, vel tincidunt mi sodales egestas. Fusce in nibh vitae tortor
135
+ hendrerit mollis nec et enim. Donec euismod orci eu consectetur volutpat. Vivamus at
136
+ mauris eget elit aliquet venenatis. Vestibulum ante ipsum primis in faucibus orci luctus
137
+ et ultrices posuere cubilia curae; Cras lobortis, purus at dignissim viverra, tortor
138
+ mauris lobortis urna, consequat facilisis dolor lacus imperdiet est. In sit amet viverra
139
+ est. Vestibulum a diam a purus commodo gravida vitae eleifend dui. Pellentesque vitae eros
140
+ ut libero sodales vulputate et sed risus. Mauris et sapien efficitur, sollicitudin ipsum
141
+ quis, volutpat nisl. Mauris pellentesque, ipsum in accumsan laoreet, sem est mollis nibh,
142
+ in dictum lacus diam lacinia tellus. Quisque sit amet ante vitae odio congue molestie.
143
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ut quam ut nisl
144
+ faucibus feugiat non id urna. Pellentesque rutrum justo at egestas egestas. In elementum
145
+ purus dapibus, dapibus risus eget, viverra tortor. Pellentesque volutpat cursus faucibus.
146
+ Vivamus laoreet, tellus id fringilla luctus, elit tellus convallis mauris, non finibus
147
+ nisl magna a libero. Integer porta euismod pellentesque. Morbi porta accumsan nibh ut
148
+ molestie. Proin mattis eros sed mauris fringilla ornare. Suspendisse ut rutrum ligula. Sed
149
+ in laoreet tortor, eu congue elit. Morbi accumsan tincidunt arcu, vitae dapibus orci
150
+ tincidunt sit amet. Duis efficitur ipsum nec cursus feugiat. Etiam lacinia felis ut ligula
151
+ suscipit vehicula. Aliquam vitae luctus erat. Pellentesque lacinia ante et odio semper
152
+ tincidunt. Quisque volutpat sem in nunc faucibus, eget pulvinar nisi molestie. Etiam nec
153
+ placerat eros. Donec viverra eros porta imperdiet condimentum. Integer neque mauris,
154
+ convallis in nisi at, vestibulum porta lacus. Pellentesque tristique dictum felis,
155
+ scelerisque pulvinar sem semper sit amet. Sed sollicitudin maximus purus, sit amet lacinia
156
+ enim aliquam condimentum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris
157
+ fringilla, risus ut imperdiet pellentesque, justo augue placerat dui, eget porta augue
158
+ justo sed enim. Vivamus dui nulla, interdum vitae dolor vitae, condimentum sagittis odio.
159
+ Sed sit amet nisi pulvinar, lacinia nibh at, pulvinar velit. Etiam arcu eros, consequat in
160
+ volutpat nec, scelerisque at risus. Donec nibh ipsum, tristique ut nisi vitae, auctor
161
+ vulputate erat. Fusce egestas augue eu nisl euismod, non mattis massa lacinia. Nulla
162
+ facilisi. Mauris gravida tincidunt tristique. Morbi sollicitudin laoreet enim, at rutrum
163
+ libero volutpat eu. Nunc accumsan viverra dolor, id dapibus tortor sodales sed. In sit
164
+ amet viverra magna. Suspendisse eget quam vulputate, imperdiet massa ac, volutpat sem. Ut
165
+ sit amet tortor mollis, imperdiet nisi vel, gravida urna. Mauris quis consectetur turpis.
166
+ Phasellus vel tortor ornare, finibus velit sed, vestibulum mauris. Suspendisse efficitur
167
+ nulla enim, eget congue urna iaculis ut. In hac habitasse platea dictumst. Mauris quis
168
+ finibus sapien, in pretium justo. Etiam gravida orci eget tincidunt ornare. Suspendisse
169
+ eget malesuada lorem. Fusce pretium orci tempor ante consectetur laoreet. Morbi placerat
170
+ dignissim massa sed rhoncus. Duis eu leo ac justo egestas faucibus. Quisque risus justo,
171
+ mattis sed lobortis et, fringilla eu nibh. Donec tempor arcu a est rhoncus, non tempor
172
+ mauris tempor. Etiam auctor aliquet ipsum, vitae tincidunt mauris aliquam sit amet. In
173
+ fermentum molestie felis, vel tincidunt mi sodales egestas. Fusce in nibh vitae tortor
174
+ hendrerit mollis nec et enim. Donec euismod orci eu consectetur volutpat. Vivamus at
175
+ mauris eget elit aliquet venenatis. Vestibulum ante ipsum primis in faucibus orci luctus
176
+ et ultrices posuere cubilia curae; Cras lobortis, purus at dignissim viverra, tortor
177
+ mauris lobortis urna, consequat facilisis dolor lacus imperdiet est. In sit amet viverra
178
+ est. Vestibulum a diam a purus commodo gravida vitae eleifend dui. Pellentesque vitae eros
179
+ ut libero sodales vulputate et sed risus. Mauris et sapien efficitur, sollicitudin ipsum
180
+ quis, volutpat nisl. Mauris pellentesque, ipsum in accumsan laoreet, sem est mollis nibh,
181
+ in dictum lacus diam lacinia tellus. Quisque sit amet ante vitae odio congue molestie.
182
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ut quam ut nisl
183
+ faucibus feugiat non id urna. Pellentesque rutrum justo at egestas egestas. In elementum
184
+ purus dapibus, dapibus risus eget, viverra tortor. Pellentesque volutpat cursus faucibus.
185
+ Vivamus laoreet, tellus id fringilla luctus, elit tellus convallis mauris, non finibus
186
+ nisl magna a libero. Integer porta euismod pellentesque. Morbi porta accumsan nibh ut
187
+ molestie. Proin mattis eros sed mauris fringilla ornare. Suspendisse ut rutrum ligula. Sed
188
+ in laoreet tortor, eu congue elit. Morbi accumsan tincidunt arcu, vitae dapibus orci
189
+ tincidunt sit amet. Duis efficitur ipsum nec cursus feugiat. Etiam lacinia felis ut ligula
190
+ suscipit vehicula. Aliquam vitae luctus erat. Pellentesque lacinia ante et odio semper
191
+ tincidunt. Quisque volutpat sem in nunc faucibus, eget pulvinar nisi molestie. Etiam nec
192
+ placerat eros. Donec viverra eros porta imperdiet condimentum. Integer neque mauris,
193
+ convallis in nisi at, vestibulum porta lacus. Pellentesque tristique dictum felis,
194
+ scelerisque pulvinar sem semper sit amet. Sed sollicitudin maximus purus, sit amet lacinia
195
+ enim aliquam condimentum.
196
+ </p>
197
+ </Modal.Body>
198
+
199
+ <Modal.Footer>
200
+ <ButtonGroup variant="block">
201
+ <Modal.Close asChild>
202
+ <Button type="button" variant="secondary">
203
+ Close
204
+ </Button>
205
+ </Modal.Close>
206
+
207
+ <Button type="button">Ok</Button>
208
+ </ButtonGroup>
209
+ </Modal.Footer>
210
+ </Modal.Content>
211
+ </Modal>
212
+ );
213
+
214
+ export const LongContent: Story = {
215
+ render: ModalLongContent,
216
+ };
217
+
218
+ const FORM_NAME = 'user-form';
219
+
220
+ const ModalRemoteFormSubmission = (props: ComponentProps<typeof Modal>) => {
221
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
222
+ event.preventDefault();
223
+ const formData = new FormData(event.currentTarget);
224
+ const formValues = Object.fromEntries(formData.entries());
225
+ action('onSubmit')(formValues);
226
+ };
227
+
228
+ return (
229
+ <Modal {...props}>
230
+ <Modal.Trigger asChild>
231
+ <Button>Create User</Button>
232
+ </Modal.Trigger>
233
+
234
+ <Modal.Content>
235
+ <Modal.Icon icon="rocket" color="red" />
236
+
237
+ <Modal.Header title="Crate User" description="Opens modal with remote form submission" />
238
+
239
+ <Modal.Body className="tw-flex tw-flex-col tw-gap-4">
240
+ <form onSubmit={handleSubmit} id={FORM_NAME}>
241
+ <FormGroup>
242
+ <Label htmlFor="name">Name</Label>
243
+ <FormGroup.TextInput name="name" id="name" variant="secondary" />
244
+ </FormGroup>
245
+ </form>
246
+ </Modal.Body>
247
+
248
+ <Modal.Footer>
249
+ <ButtonGroup variant="block">
250
+ <Modal.Close asChild>
251
+ <Button type="button" variant="secondary">
252
+ Close
253
+ </Button>
254
+ </Modal.Close>
255
+
256
+ <Button form={FORM_NAME} type="submit">
257
+ Save changes
258
+ </Button>
259
+ </ButtonGroup>
260
+ </Modal.Footer>
261
+ </Modal.Content>
262
+ </Modal>
263
+ );
264
+ };
265
+
266
+ /**
267
+ * Modal with remote form submission
268
+ * It is not recommended to wrap Modal.Body and Modal.Footer in a single form tag as it can break the styling, use remote a form submission.
269
+ */
270
+ export const RemoteFormSubmission: Story = {
271
+ render: ModalRemoteFormSubmission,
272
+ };
273
+
274
+ const ModalReusableOwnContentComponent = () => (
275
+ <>
276
+ <Modal.Header title="Reusable Modal With Own Content Component" />
277
+ <Modal.Body>Here defined reusable layout</Modal.Body>
278
+ </>
279
+ );
280
+
281
+ const ModalReusableWithOwnContentComponent = (props: Record<string, unknown>) => (
282
+ <Modal {...props}>
283
+ <Modal.Trigger asChild>
284
+ <Button>Open Modal</Button>
285
+ </Modal.Trigger>
286
+
287
+ <Modal.Content>
288
+ <ModalReusableOwnContentComponent />
289
+ </Modal.Content>
290
+ </Modal>
291
+ );
292
+
293
+ export const ReusableModalWithOwnContentComponent: Story = {
294
+ render: ModalReusableWithOwnContentComponent,
295
+ };
296
+
297
+ const ModalReusableTriggerAsChild = (props: ComponentProps<typeof Modal>) => (
298
+ <Modal>
299
+ <Modal.Trigger asChild>{props.children}</Modal.Trigger>
300
+ <ModalContent>
301
+ <Modal.Header title="Reusable Modal With Trigger as Child" />
302
+ <Modal.Body>
303
+ <p>Some contents...</p>
304
+ <p>Some contents...</p>
305
+ <p>Some contents...</p>
306
+ </Modal.Body>
307
+ </ModalContent>
308
+ </Modal>
309
+ );
310
+
311
+ export const ReusableModalWithTriggerAsChild: Story = {
312
+ render: (props) => (
313
+ <ModalReusableTriggerAsChild {...props}>
314
+ <Button>Open Modal</Button>
315
+ </ModalReusableTriggerAsChild>
316
+ ),
317
+ };
318
+
319
+ type StepProps = {
320
+ id: string;
321
+ onSubmit: FormEventHandler<HTMLFormElement>;
322
+ defaultValues?: Record<string, string> | null;
323
+ };
324
+
325
+ // Steps are exclusive, we can safely use the same id for each step
326
+ const WIZARD_FORM_NAME = 'WIZARD_FORM_NAME';
327
+ const FIRST_NAME_FIELD_NAME = 'firstName';
328
+ const USERNAME_FIELD_NAME = 'username';
329
+ const FIRST_STEP = 1;
330
+ const LAST_STEP = 3;
331
+
332
+ const Step1 = ({ id, onSubmit, defaultValues }: StepProps) => (
333
+ <form id={id} onSubmit={onSubmit}>
334
+ <FormGroup>
335
+ <Label htmlFor={FIRST_NAME_FIELD_NAME}>Fist Name</Label>
336
+ <FormGroup.TextInput
337
+ name={FIRST_NAME_FIELD_NAME}
338
+ defaultValue={defaultValues?.[FIRST_NAME_FIELD_NAME]}
339
+ placeholder="Enter your first name"
340
+ />
341
+ </FormGroup>
342
+ </form>
343
+ );
344
+
345
+ const Step2 = ({ id, onSubmit, defaultValues }: StepProps) => (
346
+ <form id={id} onSubmit={onSubmit}>
347
+ <FormGroup>
348
+ <Label htmlFor={USERNAME_FIELD_NAME}>Username</Label>
349
+ <FormGroup.TextInput
350
+ name={USERNAME_FIELD_NAME}
351
+ defaultValue={defaultValues?.[USERNAME_FIELD_NAME]}
352
+ placeholder="Enter your username"
353
+ />
354
+ </FormGroup>
355
+ </form>
356
+ );
357
+
358
+ type StepperState = {
359
+ step: number;
360
+ values: Record<number, Record<string, string>>;
361
+ };
362
+
363
+ type Action =
364
+ | {
365
+ type: 'NEXT';
366
+ values: Record<string, string>;
367
+ }
368
+ | {
369
+ type: 'PREVIOUS';
370
+ };
371
+
372
+ const reducer = (state: StepperState, action: Action) => {
373
+ switch (action.type) {
374
+ case 'NEXT': {
375
+ const currStep = state.step;
376
+ return {
377
+ ...state,
378
+ step: Math.min(currStep + 1, LAST_STEP),
379
+ values: {
380
+ ...state.values,
381
+ [currStep]: action.values,
382
+ },
383
+ };
384
+ }
385
+ case 'PREVIOUS': {
386
+ return {
387
+ ...state,
388
+ step: Math.max(state.step - 1, FIRST_STEP),
389
+ };
390
+ }
391
+ default:
392
+ return state;
393
+ }
394
+ };
395
+
396
+ const ModalMultiStepContent = () => {
397
+ const [state, dispatch] = useReducer(reducer, {
398
+ step: 1,
399
+ values: {},
400
+ });
401
+ const isLastStep = state.step === LAST_STEP;
402
+ const isFirstStep = state.step === FIRST_STEP;
403
+
404
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
405
+ event.preventDefault();
406
+ const formData = new FormData(event.currentTarget);
407
+ const formValues = Object.fromEntries(formData.entries()) as Record<string, string>;
408
+ dispatch({ type: 'NEXT', values: formValues });
409
+ };
410
+
411
+ const handlePreviousClick = () => {
412
+ dispatch({ type: 'PREVIOUS' });
413
+ };
414
+
415
+ const handleSubmitClick = () => {
416
+ action('onSubmit')(state.values);
417
+ };
418
+
419
+ return (
420
+ <>
421
+ <Modal.Icon icon="rocket" color="blue" />
422
+ <Modal.Header title="Wizard Form" description="Opens modal with multi-step form" />
423
+
424
+ <Modal.Body>
425
+ {state.step === 1 && (
426
+ <Step1
427
+ id={WIZARD_FORM_NAME}
428
+ onSubmit={handleSubmit}
429
+ defaultValues={state.values?.[state.step]}
430
+ />
431
+ )}
432
+ {state.step === 2 && (
433
+ <Step2
434
+ id={WIZARD_FORM_NAME}
435
+ onSubmit={handleSubmit}
436
+ defaultValues={state.values?.[state.step]}
437
+ />
438
+ )}
439
+
440
+ {state.step === 3 && (
441
+ <>
442
+ <h3>Wizard is Done</h3>
443
+ <pre>{JSON.stringify(state.values, null, 4)}</pre>
444
+ </>
445
+ )}
446
+ </Modal.Body>
447
+
448
+ <Modal.Footer>
449
+ <ButtonGroup variant="block">
450
+ <Button type="button" onClick={handlePreviousClick} disabled={isFirstStep}>
451
+ Previous
452
+ </Button>
453
+
454
+ {isLastStep ? (
455
+ <Button type="button" onClick={handleSubmitClick}>
456
+ Submit
457
+ </Button>
458
+ ) : (
459
+ <Button form={WIZARD_FORM_NAME} type="submit">
460
+ Next
461
+ </Button>
462
+ )}
463
+ </ButtonGroup>
464
+ </Modal.Footer>
465
+ </>
466
+ );
467
+ };
468
+
469
+ /**
470
+ * Example of a multi-step (wizard form) inside modal.
471
+ * 1. State should be manged in a component inside Modal.Content, which is re-mounted on each open. No need to for state reset.
472
+ * 2. If state reset is needed, you can use `<Modal.Content onEscapeKeyDown={} onPointerDownOutside={}/>` callbacks.
473
+ */
474
+ export const WizardFormInsideModal: Story = {
475
+ render: (props) => (
476
+ <Modal {...props}>
477
+ <Modal.Trigger asChild>
478
+ <Button>Open modal</Button>
479
+ </Modal.Trigger>
480
+
481
+ <Modal.Content>
482
+ <ModalMultiStepContent />
483
+ </Modal.Content>
484
+ </Modal>
485
+ ),
486
+ };
487
+
488
+ const ModalMediumSize = (props: ComponentProps<typeof Modal>) => (
489
+ <Modal {...props}>
490
+ <Modal.Trigger asChild>
491
+ <Button>Open Modal</Button>
492
+ </Modal.Trigger>
493
+ <Modal.Content>
494
+ <Modal.Header title="Medium Modal" description="This is a medium-sized modal (default)" />
495
+ <Modal.Body>
496
+ <p>This modal uses the default medium size (max-width: 672px / 42rem).</p>
497
+ <p>Some contents...</p>
498
+ <p>Some contents...</p>
499
+ </Modal.Body>
500
+ <Modal.Footer>
501
+ <ButtonGroup variant="block">
502
+ <Modal.Close asChild>
503
+ <Button type="button" variant="secondary">
504
+ Close
505
+ </Button>
506
+ </Modal.Close>
507
+ <Button type="button">Ok</Button>
508
+ </ButtonGroup>
509
+ </Modal.Footer>
510
+ </Modal.Content>
511
+ </Modal>
512
+ );
513
+
514
+ /**
515
+ * Modal with medium size (default)
516
+ */
517
+ export const MediumSize: Story = {
518
+ render: ModalMediumSize,
519
+ };
520
+
521
+ const ModalLargeSize = (props: ComponentProps<typeof Modal>) => (
522
+ <Modal {...props}>
523
+ <Modal.Trigger asChild>
524
+ <Button>Open Modal</Button>
525
+ </Modal.Trigger>
526
+ <Modal.Content size="large">
527
+ <Modal.Header title="Large Modal" description="This is a large-sized modal" />
528
+ <Modal.Body>
529
+ <p>This modal uses the large size (max-width: 896px / 56rem).</p>
530
+ <p>
531
+ Large modals are useful for content that needs more horizontal space, such as wide forms,
532
+ tables, or detailed information displays.
533
+ </p>
534
+ <p>Some contents...</p>
535
+ </Modal.Body>
536
+ <Modal.Footer>
537
+ <ButtonGroup variant="block">
538
+ <Modal.Close asChild>
539
+ <Button type="button" variant="secondary">
540
+ Close
541
+ </Button>
542
+ </Modal.Close>
543
+ <Button type="button">Ok</Button>
544
+ </ButtonGroup>
545
+ </Modal.Footer>
546
+ </Modal.Content>
547
+ </Modal>
548
+ );
549
+
550
+ /**
551
+ * Modal with large size
552
+ */
553
+ export const LargeSize: Story = {
554
+ render: ModalLargeSize,
555
+ };
556
+
557
+ const ModalWithImageIcon = (props: ComponentProps<typeof Modal>) => (
558
+ <Modal {...props}>
559
+ <Modal.Trigger asChild>
560
+ <Button>Open Modal</Button>
561
+ </Modal.Trigger>
562
+ <Modal.Content>
563
+ <Modal.Icon
564
+ iconUrl="https://ui.keboola-assets.com/developer-portal/icons/keboola.ex-db-snowflake/64/1576250365598.png"
565
+ iconAlt="Snowflake extractor"
566
+ />
567
+ <Modal.Header
568
+ title="Modal with Image Icon"
569
+ description="This modal uses an image URL instead of a FontAwesome icon"
570
+ />
571
+ <Modal.Body>
572
+ <p>The icon displays a custom image from a URL with a white background and shadow.</p>
573
+ <p>You can optionally provide an iconAlt prop for accessibility.</p>
574
+ </Modal.Body>
575
+ <Modal.Footer>
576
+ <ButtonGroup variant="block">
577
+ <Modal.Close asChild>
578
+ <Button type="button" variant="secondary">
579
+ Close
580
+ </Button>
581
+ </Modal.Close>
582
+ <Button type="button">Ok</Button>
583
+ </ButtonGroup>
584
+ </Modal.Footer>
585
+ </Modal.Content>
586
+ </Modal>
587
+ );
588
+
589
+ /**
590
+ * Modal with an image icon (iconUrl) instead of a FontAwesome icon.
591
+ * By default, the image icon has a white background with shadow.
592
+ */
593
+ export const WithImageIcon: Story = {
594
+ render: ModalWithImageIcon,
595
+ };
596
+
597
+ const ModalWithImageIconError = (props: ComponentProps<typeof Modal>) => (
598
+ <Modal {...props}>
599
+ <Modal.Trigger asChild>
600
+ <Button>Open Modal</Button>
601
+ </Modal.Trigger>
602
+ <Modal.Content>
603
+ <Modal.Icon iconUrl="xxx" />
604
+ <Modal.Header
605
+ title="Modal with Failed Image"
606
+ description="The icon is hidden because the image failed to load"
607
+ />
608
+ <Modal.Body>
609
+ <p>When the image URL is invalid or fails to load, the icon is automatically hidden.</p>
610
+ </Modal.Body>
611
+ <Modal.Footer>
612
+ <ButtonGroup variant="block">
613
+ <Modal.Close asChild>
614
+ <Button type="button" variant="secondary">
615
+ Close
616
+ </Button>
617
+ </Modal.Close>
618
+ <Button type="button">Ok</Button>
619
+ </ButtonGroup>
620
+ </Modal.Footer>
621
+ </Modal.Content>
622
+ </Modal>
623
+ );
624
+
625
+ /**
626
+ * Modal with an image icon that fails to load.
627
+ * The icon is hidden when the image cannot be loaded.
628
+ */
629
+ export const WithImageIconError: Story = {
630
+ render: ModalWithImageIconError,
631
+ };
632
+
633
+ const ModalWithTabs = (props: ComponentProps<typeof Modal>) => (
634
+ <Modal {...props}>
635
+ <Modal.Trigger asChild>
636
+ <Button>Open Modal</Button>
637
+ </Modal.Trigger>
638
+ <Modal.Content>
639
+ <Modal.Header
640
+ title="Modal With Tabs"
641
+ description="Header border collapses automatically because Tabs render their own bottom border."
642
+ />
643
+ <Modal.Body>
644
+ <Tabs
645
+ triggers={[
646
+ { value: 'first', title: 'First Tab' },
647
+ { value: 'second', title: 'Second Tab' },
648
+ ]}
649
+ >
650
+ <TabsContent value="first">
651
+ <p>Content of the first tab.</p>
652
+ </TabsContent>
653
+ <TabsContent value="second">
654
+ <p>Content of the second tab.</p>
655
+ </TabsContent>
656
+ </Tabs>
657
+ </Modal.Body>
658
+ <Modal.Footer>
659
+ <ButtonGroup variant="block">
660
+ <Modal.Close asChild>
661
+ <Button type="button" variant="secondary">
662
+ Close
663
+ </Button>
664
+ </Modal.Close>
665
+ <Button type="button">Ok</Button>
666
+ </ButtonGroup>
667
+ </Modal.Footer>
668
+ </Modal.Content>
669
+ </Modal>
670
+ );
671
+
672
+ /**
673
+ * Modal with Tabs inside the body — Modal.Header automatically drops its bottom border
674
+ * and padding so the Tabs' own bottom border is the single visual separator.
675
+ */
676
+ export const WithTabs: Story = {
677
+ render: ModalWithTabs,
678
+ };