@keboola/design 1.2.1 → 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.
- package/README.md +25 -0
- package/dist/icon-names.cjs +18 -0
- package/dist/icon-names.cjs.map +1 -0
- package/dist/icon-names.js +16 -0
- package/dist/icon-names.js.map +1 -0
- package/dist/icons.cjs +731 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.js +29 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.cjs +14728 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +14553 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown-editor.cjs +4440 -0
- package/dist/markdown-editor.cjs.map +1 -0
- package/dist/markdown-editor.js +4413 -0
- package/dist/markdown-editor.js.map +1 -0
- package/dist/mermaid.cjs +1011 -0
- package/dist/mermaid.cjs.map +1 -0
- package/dist/mermaid.js +1005 -0
- package/dist/mermaid.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +10 -3
- package/src/blocks/AIKit/CollapsibleStepHeader.tsx +7 -8
- package/src/blocks/AIKit/InlineStepLabel.tsx +7 -7
- package/src/blocks/AIKit/MessageBubble.stories.tsx +11 -3
- package/src/blocks/AIKit/MessageBubble.tsx +1 -1
- package/src/blocks/AIKit/PlanApproval.tsx +9 -8
- package/src/blocks/AIKit/PlanRewritingIndicator.tsx +2 -2
- package/src/blocks/AIKit/PromptInput.stories.tsx +10 -2
- package/src/blocks/AIKit/PromptInputSubmit.tsx +12 -8
- package/src/blocks/AIKit/Question.tsx +8 -9
- package/src/blocks/AIKit/SuggestedPrompt.tsx +12 -5
- package/src/blocks/AIKit/ThinkingIndicator.tsx +2 -2
- package/src/blocks/AutoSaveTextarea/AutoSaveTextarea.tsx +4 -4
- package/src/blocks/ClipboardButton/ClipboardButton.tsx +7 -5
- package/src/blocks/ClipboardButton/ClipboardInline.tsx +2 -3
- package/src/blocks/ColorInput/ColorInput.tsx +4 -2
- package/src/blocks/ColorInput/ColorPicker.tsx +5 -2
- package/src/blocks/EmptyState/EmptyState.tsx +16 -0
- package/src/blocks/ErrorState/ErrorState.tsx +15 -0
- package/src/blocks/Form/formHook.ts +15 -0
- package/src/blocks/MultiActionButtonGroup/MultiActionButton.stories.tsx +12 -11
- package/src/blocks/MultiActionButtonGroup/MultiActionButton.tsx +4 -4
- package/src/blocks/MultiCombobox/MultiCombobox.tsx +28 -12
- package/src/blocks/PageHeader/AGENTS.md +63 -3
- package/src/blocks/PageHeader/PageHeader.stories.tsx +124 -28
- package/src/blocks/PageHeader/PageHeader.tsx +15 -0
- package/src/blocks/PageHeader/PageHeaderDetail.tsx +23 -1
- package/src/blocks/PageHeader/PageHeaderIndex.tsx +20 -1
- package/src/blocks/PageLayout/PageLayout.tsx +26 -0
- package/src/blocks/PageToolbar/PageToolbar.stories.tsx +348 -0
- package/src/blocks/PageToolbar/PageToolbar.tsx +119 -0
- package/src/blocks/PageToolbar/index.ts +1 -0
- package/src/blocks/PasswordInput/PasswordInput.tsx +10 -10
- package/src/blocks/SearchInput/SearchInput.tsx +30 -4
- package/src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.tsx +9 -6
- package/src/blocks/SplitButton/SplitButton.stories.tsx +7 -4
- package/src/blocks/SplitButton/SplitButton.tsx +17 -4
- package/src/blocks/Tagger/TagItem.tsx +4 -1
- package/src/blocks/Tagger/TagSelectPopover/TagSelectCreateItem.tsx +3 -1
- package/src/blocks/Tagger/TagSelectPopover/TagSelectList.tsx +2 -2
- package/src/blocks/Tagger/Tagger.tsx +2 -2
- package/src/components/Alert/Alert.stories.tsx +11 -3
- package/src/components/Alert/Alert.tsx +19 -1
- package/src/components/Alert/AlertCollapsibleIcon.tsx +3 -4
- package/src/components/Alert/AlertIcon.tsx +18 -21
- package/src/components/Badge/Badge.stories.tsx +22 -4
- package/src/components/Badge/Badge.tsx +16 -0
- package/src/components/Badge/BadgeButton.tsx +7 -6
- package/src/components/Breadcrumb/BreadcrumbEllipsis.tsx +2 -2
- package/src/components/Breadcrumb/BreadcrumbSeparator.tsx +2 -2
- package/src/components/Button/Button.stories.tsx +14 -2
- package/src/components/Button/Button.tsx +42 -5
- package/src/components/Button/styles.ts +4 -6
- package/src/components/ButtonGroup/ButtonGroup.stories.tsx +32 -10
- package/src/components/Card/Card.tsx +17 -0
- package/src/components/Checkbox/Checkbox.tsx +3 -6
- package/src/components/CodeEditor/highlighting.ts +1 -1
- package/src/components/CollapsiblePanel.tsx +2 -5
- package/src/components/Combobox/Combobox.tsx +12 -14
- package/src/components/Combobox/ComboboxChips.tsx +6 -1
- package/src/components/Combobox/ComboboxItem.tsx +3 -4
- package/src/components/Combobox/ComboboxItemIndicator.tsx +6 -4
- package/src/components/Combobox/types.ts +2 -6
- package/src/components/Command/Command.stories.tsx +47 -56
- package/src/components/Command/CommandItem/CheckIndicator.tsx +26 -14
- package/src/components/Command/CommandItem/CommandItem.tsx +6 -3
- package/src/components/DropdownMenu/DropdownMenu.stories.tsx +8 -4
- package/src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx +4 -1
- package/src/components/DropdownMenu/DropdownMenuItem.tsx +12 -6
- package/src/components/DropdownMenu/DropdownMenuItemIndicator.tsx +12 -6
- package/src/components/DropdownMenu/DropdownMenuRadioGroup/DropdownMenuRadioItem.tsx +8 -5
- package/src/components/DropdownMenu/DropdownMenuSub/DropdownMenuSubTrigger.tsx +2 -2
- package/src/components/DropdownMenu/ItemIcon.tsx +16 -8
- package/src/components/FormGroup/FormGroup.tsx +15 -0
- package/src/components/FullScreenModal/FullScreenModalHeader.tsx +4 -1
- package/src/components/Input/DateInput/DateInput.tsx +4 -1
- package/src/components/Input/DateRangeInput/DateRangeInput.tsx +4 -6
- package/src/components/Input/Input.tsx +18 -2
- package/src/components/Input/TextInput/TextInput.tsx +16 -0
- package/src/components/Input/TimeInput/TimeInput.tsx +4 -1
- package/src/components/InputGroup/InputGroup.stories.tsx +11 -3
- package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +63 -1
- package/src/components/MarkdownEditor/MarkdownEditor.tsx +105 -15
- package/src/components/MarkdownEditor/nodes/ImageNode.tsx +10 -10
- package/src/components/MarkdownEditor/nodes/MermaidNode.tsx +8 -8
- package/src/components/MarkdownEditor/plugins/KeyboardPlugin.tsx +47 -3
- package/src/components/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx +12 -3
- package/src/components/MarkdownEditor/plugins/ToolbarPlugin.tsx +20 -10
- package/src/components/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx +20 -14
- package/src/components/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx +25 -16
- package/src/components/MarkdownEditor/plugins/toolbar/LinkPanel.tsx +3 -3
- package/src/components/MarkdownEditor/transformers.ts +10 -0
- package/src/components/MergeEditor/AcceptControls/AcceptButton.tsx +9 -4
- package/src/components/MergeEditor/AcceptControls/AcceptControls.tsx +25 -14
- package/src/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.tsx +2 -2
- package/src/components/MergeEditor/MergeEditor.stories.tsx +15 -0
- package/src/components/MergeEditor/MergeEditor.tsx +9 -0
- package/src/components/MergeEditor/MergePane.tsx +22 -4
- package/src/components/MergeEditor/decorations.ts +2 -2
- package/src/components/Modal/Modal.stories.tsx +6 -4
- package/src/components/Modal/Modal.tsx +26 -0
- package/src/components/Modal/ModalBody.tsx +5 -0
- package/src/components/Modal/ModalCloseIcon.tsx +2 -3
- package/src/components/Modal/ModalContent.tsx +8 -0
- package/src/components/Modal/ModalFooter.tsx +5 -0
- package/src/components/Modal/ModalHeader.tsx +11 -0
- package/src/components/Modal/ModalIcon.tsx +45 -19
- package/src/components/Navbar/Navbar.stories.tsx +26 -13
- package/src/components/Navbar/NavbarMenuButton.tsx +11 -10
- package/src/components/Pagination/PaginationEllipsis.tsx +2 -2
- package/src/components/Pagination/PaginationNext.tsx +2 -1
- package/src/components/Pagination/PaginationPrevious.tsx +4 -1
- package/src/components/PanelWithDetails.tsx +3 -4
- package/src/components/Popconfirm/Popconfirm.stories.tsx +13 -5
- package/src/components/RadioGroup/Radio.tsx +6 -12
- package/src/components/Search/ClearButton.tsx +2 -2
- package/src/components/Search/Search.tsx +3 -3
- package/src/components/Select/Select.tsx +16 -5
- package/src/components/Select/SelectContent.tsx +13 -4
- package/src/components/Select/SelectItem.tsx +6 -5
- package/src/components/Select/SelectTrigger.tsx +2 -2
- package/src/components/Sidebar/Sidebar.stories.tsx +55 -19
- package/src/components/Sidebar/SidebarGroup/SidebarGroupAction.tsx +8 -4
- package/src/components/Sidebar/SidebarMenu/SidebarMenuButton.tsx +4 -2
- package/src/components/Sidebar/SidebarMenu/SidebarMenuCard.tsx +3 -2
- package/src/components/Sidebar/SidebarMenu/SidebarMenuIcon.tsx +12 -12
- package/src/components/Sidebar/SidebarMenu/SidebarMenuSub.tsx +3 -7
- package/src/components/Sidebar/SidebarMenu/SidebarSearchInput.tsx +3 -5
- package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
- package/src/components/Skeleton/Skeleton.tsx +24 -1
- package/src/components/Table/Table.stories.tsx +223 -1
- package/src/components/Table/Table.tsx +17 -0
- package/src/components/Tabs.tsx +25 -2
- package/src/components/Toast/ToastDismiss.tsx +3 -3
- package/src/components/Toast/ToastRoot.tsx +24 -19
- package/src/components/Toggle/Toggle.tsx +11 -6
- package/src/components/Tooltip/Tooltip.tsx +23 -0
- package/src/components/ZoomableSvg/ZoomableSvg.tsx +8 -6
- package/src/icons/Keboola.tsx +28 -0
- package/src/icons/icons.stories.tsx +174 -0
- package/src/icons/index.ts +180 -0
- package/src/index.ts +1 -0
- package/src/patterns/AlertWithAction.stories.tsx +30 -0
- package/src/patterns/CardWithEmptyState.stories.tsx +66 -0
- package/src/patterns/ConfirmDialog.stories.tsx +72 -0
- package/src/patterns/CreatableMultiCombobox.stories.tsx +33 -0
- package/src/patterns/DataCardWithSkeleton.stories.tsx +48 -0
- package/src/patterns/DisabledButtonTooltip.stories.tsx +30 -0
- package/src/patterns/FilterToolbar.stories.tsx +71 -0
- package/src/patterns/InfoTooltip.stories.tsx +56 -0
- package/src/patterns/ListDetail.stories.tsx +65 -0
- package/src/patterns/ModalForm.stories.tsx +59 -0
- package/src/patterns/PageHeaderTabs.stories.tsx +48 -0
- package/src/styles.css +16 -8
- 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
|
+
};
|