@keboola/design 1.2.0 → 1.3.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 (173) hide show
  1. package/README.md +25 -0
  2. package/dist/icons.cjs +731 -0
  3. package/dist/icons.cjs.map +1 -0
  4. package/dist/icons.js +29 -0
  5. package/dist/icons.js.map +1 -0
  6. package/dist/index.cjs +429 -333
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.js +426 -331
  9. package/dist/index.js.map +1 -1
  10. package/dist/markdown-editor.cjs +270 -135
  11. package/dist/markdown-editor.cjs.map +1 -1
  12. package/dist/markdown-editor.js +270 -135
  13. package/dist/markdown-editor.js.map +1 -1
  14. package/dist/mermaid.cjs +24 -15
  15. package/dist/mermaid.cjs.map +1 -1
  16. package/dist/mermaid.js +24 -15
  17. package/dist/mermaid.js.map +1 -1
  18. package/dist/styles.css +1 -1
  19. package/package.json +12 -5
  20. package/src/blocks/AIKit/CollapsibleStepHeader.tsx +7 -8
  21. package/src/blocks/AIKit/InlineStepLabel.tsx +7 -7
  22. package/src/blocks/AIKit/MessageBubble.stories.tsx +11 -3
  23. package/src/blocks/AIKit/MessageBubble.tsx +1 -1
  24. package/src/blocks/AIKit/PlanApproval.tsx +9 -8
  25. package/src/blocks/AIKit/PlanRewritingIndicator.tsx +2 -2
  26. package/src/blocks/AIKit/PromptInput.stories.tsx +10 -2
  27. package/src/blocks/AIKit/PromptInputSubmit.tsx +12 -8
  28. package/src/blocks/AIKit/Question.tsx +8 -9
  29. package/src/blocks/AIKit/SuggestedPrompt.tsx +12 -5
  30. package/src/blocks/AIKit/ThinkingIndicator.tsx +2 -2
  31. package/src/blocks/AutoSaveTextarea/AutoSaveTextarea.tsx +4 -4
  32. package/src/blocks/ClipboardButton/ClipboardButton.tsx +7 -5
  33. package/src/blocks/ClipboardButton/ClipboardInline.tsx +2 -3
  34. package/src/blocks/ColorInput/ColorInput.tsx +4 -2
  35. package/src/blocks/ColorInput/ColorPicker.tsx +5 -2
  36. package/src/blocks/EmptyState/EmptyState.tsx +16 -0
  37. package/src/blocks/ErrorState/ErrorState.tsx +15 -0
  38. package/src/blocks/Form/formHook.ts +15 -0
  39. package/src/blocks/MultiActionButtonGroup/MultiActionButton.stories.tsx +12 -11
  40. package/src/blocks/MultiActionButtonGroup/MultiActionButton.tsx +4 -4
  41. package/src/blocks/MultiCombobox/MultiCombobox.tsx +28 -12
  42. package/src/blocks/PageHeader/AGENTS.md +63 -3
  43. package/src/blocks/PageHeader/PageHeader.stories.tsx +124 -28
  44. package/src/blocks/PageHeader/PageHeader.tsx +15 -0
  45. package/src/blocks/PageHeader/PageHeaderDetail.tsx +23 -1
  46. package/src/blocks/PageHeader/PageHeaderIndex.tsx +20 -1
  47. package/src/blocks/PageLayout/PageLayout.tsx +26 -0
  48. package/src/blocks/PageToolbar/PageToolbar.stories.tsx +348 -0
  49. package/src/blocks/PageToolbar/PageToolbar.tsx +119 -0
  50. package/src/blocks/PageToolbar/index.ts +1 -0
  51. package/src/blocks/PasswordInput/PasswordInput.tsx +10 -10
  52. package/src/blocks/SearchInput/SearchInput.tsx +30 -4
  53. package/src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.tsx +9 -6
  54. package/src/blocks/SplitButton/SplitButton.stories.tsx +7 -4
  55. package/src/blocks/SplitButton/SplitButton.tsx +17 -4
  56. package/src/blocks/Tagger/TagItem.tsx +4 -1
  57. package/src/blocks/Tagger/TagSelectPopover/TagSelectCreateItem.tsx +3 -1
  58. package/src/blocks/Tagger/TagSelectPopover/TagSelectList.tsx +2 -2
  59. package/src/blocks/Tagger/Tagger.tsx +2 -2
  60. package/src/components/Alert/Alert.stories.tsx +11 -3
  61. package/src/components/Alert/Alert.tsx +19 -1
  62. package/src/components/Alert/AlertCollapsibleIcon.tsx +3 -4
  63. package/src/components/Alert/AlertIcon.tsx +18 -21
  64. package/src/components/Badge/Badge.stories.tsx +22 -4
  65. package/src/components/Badge/Badge.tsx +16 -0
  66. package/src/components/Badge/BadgeButton.tsx +7 -6
  67. package/src/components/Breadcrumb/BreadcrumbEllipsis.tsx +2 -2
  68. package/src/components/Breadcrumb/BreadcrumbSeparator.tsx +2 -2
  69. package/src/components/Button/Button.stories.tsx +14 -2
  70. package/src/components/Button/Button.tsx +42 -5
  71. package/src/components/Button/styles.ts +4 -6
  72. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +32 -10
  73. package/src/components/Card/Card.tsx +17 -0
  74. package/src/components/Checkbox/Checkbox.tsx +3 -6
  75. package/src/components/CodeEditor/highlighting.ts +1 -1
  76. package/src/components/CollapsiblePanel.tsx +2 -5
  77. package/src/components/Combobox/Combobox.tsx +12 -14
  78. package/src/components/Combobox/ComboboxChips.tsx +6 -1
  79. package/src/components/Combobox/ComboboxItem.tsx +3 -4
  80. package/src/components/Combobox/ComboboxItemIndicator.tsx +6 -4
  81. package/src/components/Combobox/types.ts +2 -6
  82. package/src/components/Command/Command.stories.tsx +47 -56
  83. package/src/components/Command/CommandItem/CheckIndicator.tsx +26 -14
  84. package/src/components/Command/CommandItem/CommandItem.tsx +6 -3
  85. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +8 -4
  86. package/src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx +4 -1
  87. package/src/components/DropdownMenu/DropdownMenuItem.tsx +12 -6
  88. package/src/components/DropdownMenu/DropdownMenuItemIndicator.tsx +12 -6
  89. package/src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioItem.tsx +8 -5
  90. package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubTrigger.tsx +2 -2
  91. package/src/components/DropdownMenu/ItemIcon.tsx +16 -8
  92. package/src/components/FormGroup/FormGroup.tsx +15 -0
  93. package/src/components/FullScreenModal/FullScreenModalHeader.tsx +4 -1
  94. package/src/components/Input/DateInput/DateInput.tsx +4 -1
  95. package/src/components/Input/DateRangeInput/DateRangeInput.tsx +4 -6
  96. package/src/components/Input/Input.tsx +18 -2
  97. package/src/components/Input/TextInput/TextInput.tsx +16 -0
  98. package/src/components/Input/TimeInput/TimeInput.tsx +4 -1
  99. package/src/components/InputGroup/InputGroup.stories.tsx +11 -3
  100. package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +63 -1
  101. package/src/components/MarkdownEditor/MarkdownEditor.tsx +105 -15
  102. package/src/components/MarkdownEditor/nodes/ImageNode.tsx +10 -10
  103. package/src/components/MarkdownEditor/nodes/MermaidNode.tsx +8 -8
  104. package/src/components/MarkdownEditor/plugins/KeyboardPlugin.tsx +47 -3
  105. package/src/components/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx +12 -3
  106. package/src/components/MarkdownEditor/plugins/ToolbarPlugin.tsx +20 -10
  107. package/src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx +20 -14
  108. package/src/components/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx +25 -16
  109. package/src/components/MarkdownEditor/plugins/toolbar/LinkPanel.tsx +3 -3
  110. package/src/components/MarkdownEditor/transformers.ts +10 -0
  111. package/src/components/MergeEditor/AcceptControls/AcceptButton.tsx +9 -4
  112. package/src/components/MergeEditor/AcceptControls/AcceptControls.tsx +25 -14
  113. package/src/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.tsx +2 -2
  114. package/src/components/MergeEditor/MergeEditor.stories.tsx +15 -0
  115. package/src/components/MergeEditor/MergeEditor.tsx +9 -0
  116. package/src/components/MergeEditor/MergePane.tsx +22 -4
  117. package/src/components/MergeEditor/decorations.ts +2 -2
  118. package/src/components/Modal/Modal.stories.tsx +6 -4
  119. package/src/components/Modal/Modal.tsx +26 -0
  120. package/src/components/Modal/ModalBody.tsx +5 -0
  121. package/src/components/Modal/ModalCloseIcon.tsx +2 -3
  122. package/src/components/Modal/ModalContent.tsx +8 -0
  123. package/src/components/Modal/ModalFooter.tsx +5 -0
  124. package/src/components/Modal/ModalHeader.tsx +11 -0
  125. package/src/components/Modal/ModalIcon.tsx +45 -19
  126. package/src/components/Navbar/Navbar.stories.tsx +26 -13
  127. package/src/components/Navbar/NavbarMenuButton.tsx +11 -10
  128. package/src/components/Pagination/PaginationEllipsis.tsx +2 -2
  129. package/src/components/Pagination/PaginationNext.tsx +2 -1
  130. package/src/components/Pagination/PaginationPrevious.tsx +4 -1
  131. package/src/components/PanelWithDetails.tsx +3 -4
  132. package/src/components/Popconfirm/Popconfirm.stories.tsx +13 -5
  133. package/src/components/RadioGroup/Radio.tsx +6 -12
  134. package/src/components/Search/ClearButton.tsx +2 -2
  135. package/src/components/Search/Search.tsx +3 -3
  136. package/src/components/Select/Select.tsx +16 -5
  137. package/src/components/Select/SelectContent.tsx +13 -4
  138. package/src/components/Select/SelectItem.tsx +6 -5
  139. package/src/components/Select/SelectTrigger.tsx +2 -2
  140. package/src/components/Sidebar/Sidebar.stories.tsx +55 -19
  141. package/src/components/Sidebar/SidebarGroup/SidebarGroupAction.tsx +8 -4
  142. package/src/components/Sidebar/SidebarMenu/SidebarMenuButton.tsx +4 -2
  143. package/src/components/Sidebar/SidebarMenu/SidebarMenuCard.tsx +3 -2
  144. package/src/components/Sidebar/SidebarMenu/SidebarMenuIcon.tsx +12 -12
  145. package/src/components/Sidebar/SidebarMenu/SidebarMenuSub.tsx +3 -7
  146. package/src/components/Sidebar/SidebarMenu/SidebarSearchInput.tsx +3 -5
  147. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  148. package/src/components/Skeleton/Skeleton.tsx +24 -1
  149. package/src/components/Table/Table.stories.tsx +223 -1
  150. package/src/components/Table/Table.tsx +17 -0
  151. package/src/components/Tabs.tsx +25 -2
  152. package/src/components/Toast/ToastDismiss.tsx +3 -3
  153. package/src/components/Toast/ToastRoot.tsx +24 -19
  154. package/src/components/Toggle/Toggle.tsx +11 -6
  155. package/src/components/Tooltip/Tooltip.tsx +23 -0
  156. package/src/components/ZoomableSvg/ZoomableSvg.tsx +8 -6
  157. package/src/icons/Keboola.tsx +28 -0
  158. package/src/icons/icons.stories.tsx +174 -0
  159. package/src/icons/index.ts +180 -0
  160. package/src/index.ts +1 -0
  161. package/src/patterns/AlertWithAction.stories.tsx +30 -0
  162. package/src/patterns/CardWithEmptyState.stories.tsx +66 -0
  163. package/src/patterns/ConfirmDialog.stories.tsx +72 -0
  164. package/src/patterns/CreatableMultiCombobox.stories.tsx +33 -0
  165. package/src/patterns/DataCardWithSkeleton.stories.tsx +48 -0
  166. package/src/patterns/DisabledButtonTooltip.stories.tsx +30 -0
  167. package/src/patterns/FilterToolbar.stories.tsx +71 -0
  168. package/src/patterns/InfoTooltip.stories.tsx +56 -0
  169. package/src/patterns/ListDetail.stories.tsx +65 -0
  170. package/src/patterns/ModalForm.stories.tsx +59 -0
  171. package/src/patterns/PageHeaderTabs.stories.tsx +48 -0
  172. package/src/styles.css +16 -8
  173. package/src/utils/legacyIcon.tsx +28 -0
@@ -0,0 +1,174 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import type { LucideIcon } from 'lucide-react';
3
+
4
+ import {
5
+ AlertCircle,
6
+ AlertTriangle,
7
+ ArrowLeft,
8
+ ArrowRight,
9
+ Bell,
10
+ BookOpen,
11
+ Bug,
12
+ Calendar,
13
+ Check,
14
+ ChevronDown,
15
+ ChevronLeft,
16
+ ChevronRight,
17
+ ChevronUp,
18
+ Circle,
19
+ CircleCheck,
20
+ CircleHelp,
21
+ Clock,
22
+ CloudDownload,
23
+ Code,
24
+ Copy,
25
+ EllipsisVertical,
26
+ Expand,
27
+ Eye,
28
+ FolderOpen,
29
+ Gauge,
30
+ Info,
31
+ Keboola,
32
+ Layers,
33
+ Link,
34
+ List,
35
+ Loader2,
36
+ Minus,
37
+ PanelLeft,
38
+ Pencil,
39
+ Pipette,
40
+ Play,
41
+ Plus,
42
+ Rocket,
43
+ Search,
44
+ Send,
45
+ Settings,
46
+ SquareCode,
47
+ Star,
48
+ Table,
49
+ ThumbsDown,
50
+ ThumbsUp,
51
+ Trash2,
52
+ Unlink,
53
+ Upload,
54
+ Users,
55
+ Warehouse,
56
+ X,
57
+ XCircle,
58
+ Zap,
59
+ } from './index';
60
+
61
+ type IconEntry = {
62
+ Icon: LucideIcon;
63
+ name: string;
64
+ fa: string;
65
+ };
66
+
67
+ const entries: IconEntry[] = [
68
+ { Icon: AlertCircle, name: 'AlertCircle', fa: 'circle-exclamation' },
69
+ { Icon: AlertTriangle, name: 'AlertTriangle', fa: 'triangle-exclamation' },
70
+ { Icon: ArrowLeft, name: 'ArrowLeft', fa: 'arrow-left' },
71
+ { Icon: ArrowRight, name: 'ArrowRight', fa: 'arrow-right' },
72
+ { Icon: Bell, name: 'Bell', fa: 'bell' },
73
+ { Icon: BookOpen, name: 'BookOpen', fa: 'book-blank' },
74
+ { Icon: Bug, name: 'Bug', fa: 'bug' },
75
+ { Icon: Calendar, name: 'Calendar', fa: 'calendar' },
76
+ { Icon: Check, name: 'Check', fa: 'check' },
77
+ { Icon: ChevronDown, name: 'ChevronDown', fa: 'chevron-down / angle-down / caret-down' },
78
+ { Icon: ChevronLeft, name: 'ChevronLeft', fa: 'chevron-left / angle-left' },
79
+ { Icon: ChevronRight, name: 'ChevronRight', fa: 'chevron-right' },
80
+ { Icon: ChevronUp, name: 'ChevronUp', fa: 'chevron-up / angle-up' },
81
+ { Icon: Circle, name: 'Circle', fa: 'dot-circle' },
82
+ { Icon: CircleCheck, name: 'CircleCheck', fa: 'circle-check / check-circle' },
83
+ { Icon: CircleHelp, name: 'CircleHelp', fa: 'circle-question' },
84
+ { Icon: Clock, name: 'Clock', fa: 'clock' },
85
+ { Icon: CloudDownload, name: 'CloudDownload', fa: 'cloud-arrow-down' },
86
+ { Icon: Code, name: 'Code', fa: 'code' },
87
+ { Icon: Copy, name: 'Copy', fa: 'copy' },
88
+ { Icon: EllipsisVertical, name: 'EllipsisVertical', fa: 'ellipsis-vertical' },
89
+ { Icon: Expand, name: 'Expand', fa: 'expand-alt' },
90
+ { Icon: Eye, name: 'Eye', fa: 'eye' },
91
+ { Icon: FolderOpen, name: 'FolderOpen', fa: 'folder-open' },
92
+ { Icon: Gauge, name: 'Gauge', fa: 'gauge' },
93
+ { Icon: Info, name: 'Info', fa: 'circle-info / info-circle' },
94
+ { Icon: Keboola, name: 'Keboola', fa: "['fak', 'keboola']" },
95
+ { Icon: Layers, name: 'Layers', fa: 'layer-group' },
96
+ { Icon: Link, name: 'Link', fa: 'link' },
97
+ { Icon: List, name: 'List', fa: 'list-ul' },
98
+ { Icon: Minus, name: 'Minus', fa: 'minus' },
99
+ { Icon: PanelLeft, name: 'PanelLeft', fa: 'sidebar' },
100
+ { Icon: Pencil, name: 'Pencil', fa: 'pen' },
101
+ { Icon: Pipette, name: 'Pipette', fa: 'eye-dropper' },
102
+ { Icon: Play, name: 'Play', fa: 'play' },
103
+ { Icon: Plus, name: 'Plus', fa: 'plus' },
104
+ { Icon: Rocket, name: 'Rocket', fa: 'rocket' },
105
+ { Icon: Search, name: 'Search', fa: 'magnifying-glass / search' },
106
+ { Icon: Send, name: 'Send', fa: 'paper-plane-top' },
107
+ { Icon: Settings, name: 'Settings', fa: 'cog' },
108
+ { Icon: SquareCode, name: 'SquareCode', fa: 'square-code' },
109
+ { Icon: Star, name: 'Star', fa: 'star' },
110
+ { Icon: Table, name: 'Table', fa: 'table' },
111
+ { Icon: ThumbsDown, name: 'ThumbsDown', fa: 'thumbs-down' },
112
+ { Icon: ThumbsUp, name: 'ThumbsUp', fa: 'thumbs-up' },
113
+ { Icon: Trash2, name: 'Trash2', fa: 'trash' },
114
+ { Icon: Unlink, name: 'Unlink', fa: 'link-slash' },
115
+ { Icon: Upload, name: 'Upload', fa: 'upload / up-from-line' },
116
+ { Icon: Users, name: 'Users', fa: 'user-group' },
117
+ { Icon: Warehouse, name: 'Warehouse', fa: 'warehouse' },
118
+ { Icon: X, name: 'X', fa: 'xmark / times / close / cancel' },
119
+ { Icon: XCircle, name: 'XCircle', fa: 'circle-xmark' },
120
+ { Icon: Zap, name: 'Zap', fa: 'bolt' },
121
+ ];
122
+
123
+ const Grid = () => (
124
+ <div className="tw-grid tw-grid-cols-2 tw-gap-4 md:tw-grid-cols-3 lg:tw-grid-cols-4">
125
+ {entries.map(({ Icon, name, fa }) => (
126
+ <div
127
+ key={name}
128
+ className="tw-flex tw-flex-col tw-items-start tw-gap-2 tw-rounded-md tw-border tw-border-border tw-p-4"
129
+ >
130
+ <Icon className="tw-size-6" />
131
+ <div className="tw-font-semibold">{name}</div>
132
+ <div className="tw-text-sm tw-text-muted-foreground">FA: {fa}</div>
133
+ </div>
134
+ ))}
135
+ </div>
136
+ );
137
+
138
+ const meta = {
139
+ title: 'Foundations/Icons (Lucide)',
140
+ component: Grid,
141
+ parameters: {
142
+ docs: {
143
+ description: {
144
+ component:
145
+ 'Canonical icon surface for `@keboola/design`. Import named icons directly from `@keboola/design/icons` — Lucide icons and Keboola-custom icons are interchangeable (both typed `LucideIcon`):\n\n```tsx\nimport { ChevronDown, Keboola, Loader2 } from \'@keboola/design/icons\';\n\n<ChevronDown className="tw-size-4" />\n<Loader2 className="tw-size-4 tw-animate-spin" />\n<Keboola className="tw-size-6" />\n```\n\nSizing uses the prefixed Tailwind `tw-size-*` utility (`tw-size-4` = 16px, `tw-size-5` = 20px). Spinner animation is explicit via `tw-animate-spin` (FA\'s `<Icon icon="spinner" />` had it built-in).',
146
+ },
147
+ },
148
+ },
149
+ } satisfies Meta<typeof Grid>;
150
+
151
+ export default meta;
152
+ type Story = StoryObj<typeof meta>;
153
+
154
+ export const Curated: Story = {};
155
+
156
+ export const Spinner: Story = {
157
+ render: () => (
158
+ <div className="tw-flex tw-items-center tw-gap-4">
159
+ <Loader2 className="tw-size-4 tw-animate-spin" />
160
+ <Loader2 className="tw-size-6 tw-animate-spin" />
161
+ <Loader2 className="tw-size-10 tw-animate-spin" />
162
+ </div>
163
+ ),
164
+ };
165
+
166
+ export const BrandMark: Story = {
167
+ render: () => (
168
+ <div className="tw-flex tw-items-center tw-gap-4">
169
+ <Keboola className="tw-size-4" />
170
+ <Keboola className="tw-size-6" />
171
+ <Keboola className="tw-size-10" />
172
+ </div>
173
+ ),
174
+ };
@@ -0,0 +1,180 @@
1
+ export {
2
+ AlertCircle,
3
+ AlertTriangle,
4
+ AlignCenter,
5
+ AlignJustify,
6
+ AlignLeft,
7
+ AlignRight,
8
+ ArrowBigUpDash,
9
+ ArrowDown,
10
+ ArrowDownToLine,
11
+ ArrowLeft,
12
+ ArrowLeftRight,
13
+ ArrowLeftToLine,
14
+ ArrowRight,
15
+ ArrowRightLeft,
16
+ ArrowUp,
17
+ ArrowUpRight,
18
+ Ban,
19
+ Bell,
20
+ BellRing,
21
+ Bold,
22
+ BookOpen,
23
+ Braces,
24
+ Bug,
25
+ Calendar,
26
+ Camera,
27
+ Check,
28
+ ChevronDown,
29
+ ChevronLeft,
30
+ ChevronRight,
31
+ ChevronUp,
32
+ ChevronsLeft,
33
+ ChevronsRight,
34
+ ChevronsUpDown,
35
+ Circle,
36
+ CircleAlert,
37
+ CircleArrowDown,
38
+ CircleArrowRight,
39
+ CircleArrowUp,
40
+ CircleCheck,
41
+ CircleChevronDown,
42
+ CircleChevronUp,
43
+ CircleHelp,
44
+ CirclePause,
45
+ CirclePlay,
46
+ CirclePlus,
47
+ CircleUser,
48
+ CircleX,
49
+ Clock,
50
+ CloudDownload,
51
+ Code,
52
+ Cog,
53
+ Columns2,
54
+ Columns3,
55
+ Copy,
56
+ CreditCard,
57
+ Crosshair,
58
+ Database,
59
+ Diamond,
60
+ Download,
61
+ Ellipsis,
62
+ EllipsisVertical,
63
+ Expand,
64
+ ExternalLink,
65
+ Eye,
66
+ EyeOff,
67
+ File,
68
+ FileDown,
69
+ FileInput,
70
+ FileSpreadsheet,
71
+ FileText,
72
+ Flag,
73
+ Folder,
74
+ FolderOpen,
75
+ FolderTree,
76
+ FolderUp,
77
+ Gauge,
78
+ Gift,
79
+ GitBranch,
80
+ GitCompare,
81
+ GitMerge,
82
+ GitPullRequest,
83
+ Globe,
84
+ GripVertical,
85
+ Heading1,
86
+ Heading2,
87
+ Heading3,
88
+ History,
89
+ Hourglass,
90
+ Image,
91
+ Info,
92
+ Italic,
93
+ KanbanSquare,
94
+ Key,
95
+ Keyboard,
96
+ Layers,
97
+ LayoutGrid,
98
+ LineChart,
99
+ Link,
100
+ List,
101
+ ListChecks,
102
+ ListOrdered,
103
+ Loader2,
104
+ Lock,
105
+ LogIn,
106
+ Mail,
107
+ Map,
108
+ Maximize,
109
+ Maximize2,
110
+ Menu,
111
+ MessageCircleQuestion,
112
+ Minimize,
113
+ Minimize2,
114
+ Minus,
115
+ Moon,
116
+ MoveHorizontal,
117
+ MoveVertical,
118
+ OctagonAlert,
119
+ PanelLeft,
120
+ PartyPopper,
121
+ Pause,
122
+ Pencil,
123
+ PencilLine,
124
+ Pipette,
125
+ Play,
126
+ Plus,
127
+ Quote,
128
+ RefreshCw,
129
+ Repeat,
130
+ Repeat2,
131
+ Reply,
132
+ Rocket,
133
+ RotateCcw,
134
+ RotateCw,
135
+ Rows3,
136
+ ScanLine,
137
+ Search,
138
+ Send,
139
+ Settings,
140
+ Share,
141
+ Share2,
142
+ Slash,
143
+ Sliders,
144
+ SlidersHorizontal,
145
+ Sparkle,
146
+ Sparkles,
147
+ Split,
148
+ Square,
149
+ SquareChevronRight,
150
+ SquareCode,
151
+ SquareKanban,
152
+ SquarePen,
153
+ SquareTerminal,
154
+ Star,
155
+ StickyNote,
156
+ Strikethrough,
157
+ Table,
158
+ ThumbsDown,
159
+ ThumbsUp,
160
+ ToggleRight,
161
+ Trash2,
162
+ TriangleAlert,
163
+ Type,
164
+ Underline,
165
+ Unlink,
166
+ Upload,
167
+ User,
168
+ Users,
169
+ Wand2,
170
+ Warehouse,
171
+ Webhook,
172
+ Workflow,
173
+ Wrench,
174
+ X,
175
+ XCircle,
176
+ Zap,
177
+ } from 'lucide-react';
178
+
179
+ export { Keboola } from './Keboola';
180
+ export type { LucideIcon, LucideProps } from 'lucide-react';
package/src/index.ts CHANGED
@@ -69,6 +69,7 @@ export * from './blocks/EmptyState';
69
69
  export * from './blocks/ErrorState';
70
70
  export * from './blocks/PageLayout';
71
71
  export * from './blocks/PageHeader';
72
+ export * from './blocks/PageToolbar';
72
73
  export * from './blocks/SearchInput';
73
74
  export * from './blocks/SearchInputWithNavigation';
74
75
  export * from './blocks/Tagger';
@@ -0,0 +1,30 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Alert, Button } from '@keboola/design';
4
+
5
+ const TrialEndingAlert = ({ onExtend }: { onExtend: () => void }) => (
6
+ <Alert
7
+ variant="warning"
8
+ title="Trial ends in 3 days"
9
+ actions={
10
+ <Button size="small" variant="outline" onClick={onExtend}>
11
+ Extend
12
+ </Button>
13
+ }
14
+ >
15
+ Add a payment method to keep your project active after the trial expires.
16
+ </Alert>
17
+ );
18
+
19
+ const meta = {
20
+ title: 'Patterns/AlertWithAction',
21
+ component: TrialEndingAlert,
22
+ } satisfies Meta<typeof TrialEndingAlert>;
23
+
24
+ export default meta;
25
+
26
+ type Story = StoryObj<typeof meta>;
27
+
28
+ export const Default: Story = {
29
+ args: { onExtend: () => {} },
30
+ };
@@ -0,0 +1,66 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Button, Card, EmptyState, Table } from '@keboola/design';
4
+ import { Plus } from '@keboola/design/icons';
5
+
6
+ type Token = { id: string; name: string };
7
+
8
+ const TokensCard = ({ tokens }: { tokens: Token[] }) => (
9
+ <Card bordered padding="none">
10
+ <Card.Header className="tw-flex tw-items-center tw-justify-between tw-p-4">
11
+ <Card.Title>Tokens</Card.Title>
12
+ <Button size="small">
13
+ <Plus className="tw-size-4" />
14
+ New token
15
+ </Button>
16
+ </Card.Header>
17
+ <Card.Content className="tw-p-0">
18
+ {tokens.length === 0 ? (
19
+ <EmptyState variant="compact">
20
+ <EmptyState.Title>No tokens yet</EmptyState.Title>
21
+ <EmptyState.Description>Create your first token to get started.</EmptyState.Description>
22
+ <EmptyState.Actions>
23
+ <Button size="small">Create token</Button>
24
+ </EmptyState.Actions>
25
+ </EmptyState>
26
+ ) : (
27
+ <Table>
28
+ <Table.Header>
29
+ <Table.Row>
30
+ <Table.Head>Name</Table.Head>
31
+ </Table.Row>
32
+ </Table.Header>
33
+ <Table.Body>
34
+ {tokens.map((token) => (
35
+ <Table.Row key={token.id}>
36
+ <Table.Cell>{token.name}</Table.Cell>
37
+ </Table.Row>
38
+ ))}
39
+ </Table.Body>
40
+ </Table>
41
+ )}
42
+ </Card.Content>
43
+ </Card>
44
+ );
45
+
46
+ const meta = {
47
+ title: 'Patterns/CardWithEmptyState',
48
+ component: TokensCard,
49
+ } satisfies Meta<typeof TokensCard>;
50
+
51
+ export default meta;
52
+
53
+ type Story = StoryObj<typeof meta>;
54
+
55
+ export const Empty: Story = {
56
+ args: { tokens: [] },
57
+ };
58
+
59
+ export const Populated: Story = {
60
+ args: {
61
+ tokens: [
62
+ { id: '1', name: 'CI deploy token' },
63
+ { id: '2', name: 'Local dev token' },
64
+ ],
65
+ },
66
+ };
@@ -0,0 +1,72 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+
4
+ import { Button, ButtonGroup, Modal } from '@keboola/design';
5
+ import { AlertTriangle, Trash2 } from '@keboola/design/icons';
6
+
7
+ const DeleteBucketButton = ({
8
+ name,
9
+ onConfirm,
10
+ }: {
11
+ name: string;
12
+ onConfirm: () => Promise<void>;
13
+ }) => {
14
+ const [open, setOpen] = useState(false);
15
+ const [isDeleting, setIsDeleting] = useState(false);
16
+
17
+ const handleConfirm = async () => {
18
+ setIsDeleting(true);
19
+ try {
20
+ await onConfirm();
21
+ setOpen(false);
22
+ } finally {
23
+ setIsDeleting(false);
24
+ }
25
+ };
26
+
27
+ return (
28
+ <Modal open={open} onOpenChange={setOpen}>
29
+ <Modal.Trigger asChild>
30
+ <Button variant="danger">
31
+ <Trash2 className="tw-size-4" />
32
+ Delete
33
+ </Button>
34
+ </Modal.Trigger>
35
+ <Modal.Content size="small">
36
+ <Modal.Icon color="red" icon={<AlertTriangle />} />
37
+ <Modal.Header
38
+ title={`Delete bucket "${name}"?`}
39
+ description="This action cannot be undone. All tables in the bucket will be lost."
40
+ />
41
+ <Modal.Footer>
42
+ <ButtonGroup variant="block">
43
+ <Modal.Close asChild>
44
+ <Button type="button" variant="secondary" disabled={isDeleting}>
45
+ Cancel
46
+ </Button>
47
+ </Modal.Close>
48
+ <Button type="button" variant="danger" isLoading={isDeleting} onClick={handleConfirm}>
49
+ Delete bucket
50
+ </Button>
51
+ </ButtonGroup>
52
+ </Modal.Footer>
53
+ </Modal.Content>
54
+ </Modal>
55
+ );
56
+ };
57
+
58
+ const meta = {
59
+ title: 'Patterns/ConfirmDialog',
60
+ component: DeleteBucketButton,
61
+ } satisfies Meta<typeof DeleteBucketButton>;
62
+
63
+ export default meta;
64
+
65
+ type Story = StoryObj<typeof meta>;
66
+
67
+ export const Default: Story = {
68
+ args: {
69
+ name: 'marketing',
70
+ onConfirm: () => new Promise((resolve) => setTimeout(resolve, 500)),
71
+ },
72
+ };
@@ -0,0 +1,33 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+
4
+ import { Combobox } from '@keboola/design';
5
+
6
+ const TAGS = ['marketing', 'sales', 'analytics', 'internal'] as const;
7
+
8
+ const TagPicker = () => {
9
+ const [tag, setTag] = useState<string | null>(null);
10
+
11
+ return (
12
+ <Combobox
13
+ items={TAGS}
14
+ value={tag}
15
+ onValueChange={setTag}
16
+ allowCreate
17
+ allowClear
18
+ placeholder="Pick or create a tag"
19
+ className="tw-w-64"
20
+ />
21
+ );
22
+ };
23
+
24
+ const meta = {
25
+ title: 'Patterns/CreatableMultiCombobox',
26
+ component: TagPicker,
27
+ } satisfies Meta<typeof TagPicker>;
28
+
29
+ export default meta;
30
+
31
+ type Story = StoryObj<typeof meta>;
32
+
33
+ export const Default: Story = {};
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Card, Skeleton, SkeletonList } from '@keboola/design';
4
+
5
+ type Stats = { tables: number; rows: number };
6
+
7
+ const StatsCard = ({ stats, isLoading }: { stats: Stats | null; isLoading: boolean }) => (
8
+ <Card bordered>
9
+ <Card.Header>
10
+ <Card.Title>
11
+ {isLoading ? <Skeleton height="md" className="tw-w-32" /> : 'Storage'}
12
+ </Card.Title>
13
+ </Card.Header>
14
+ <Card.Content>
15
+ {isLoading || !stats ? (
16
+ <SkeletonList groups={2} rowHeight="sm" />
17
+ ) : (
18
+ <dl className="tw-flex tw-flex-col tw-gap-2">
19
+ <div className="tw-flex tw-justify-between">
20
+ <dt className="tw-text-muted-foreground">Tables</dt>
21
+ <dd>{stats.tables}</dd>
22
+ </div>
23
+ <div className="tw-flex tw-justify-between">
24
+ <dt className="tw-text-muted-foreground">Rows</dt>
25
+ <dd>{stats.rows.toLocaleString()}</dd>
26
+ </div>
27
+ </dl>
28
+ )}
29
+ </Card.Content>
30
+ </Card>
31
+ );
32
+
33
+ const meta = {
34
+ title: 'Patterns/DataCardWithSkeleton',
35
+ component: StatsCard,
36
+ } satisfies Meta<typeof StatsCard>;
37
+
38
+ export default meta;
39
+
40
+ type Story = StoryObj<typeof meta>;
41
+
42
+ export const Loading: Story = {
43
+ args: { stats: null, isLoading: true },
44
+ };
45
+
46
+ export const Ready: Story = {
47
+ args: { stats: { tables: 39, rows: 1284502 }, isLoading: false },
48
+ };
@@ -0,0 +1,30 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Button, Tooltip } from '@keboola/design';
4
+
5
+ const SaveButton = ({ canSave, reason }: { canSave: boolean; reason: string }) => (
6
+ <Tooltip tooltip={canSave ? null : reason} placement="top" triggerAsChild>
7
+ <span className={canSave ? undefined : 'tw-inline-block tw-cursor-not-allowed'}>
8
+ <Button disabled={!canSave} className={canSave ? undefined : 'tw-pointer-events-none'}>
9
+ Save
10
+ </Button>
11
+ </span>
12
+ </Tooltip>
13
+ );
14
+
15
+ const meta = {
16
+ title: 'Patterns/DisabledButtonTooltip',
17
+ component: SaveButton,
18
+ } satisfies Meta<typeof SaveButton>;
19
+
20
+ export default meta;
21
+
22
+ type Story = StoryObj<typeof meta>;
23
+
24
+ export const Disabled: Story = {
25
+ args: { canSave: false, reason: 'Fill in all required fields first.' },
26
+ };
27
+
28
+ export const Enabled: Story = {
29
+ args: { canSave: true, reason: '' },
30
+ };