@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.
- package/README.md +25 -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 +429 -333
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +426 -331
- package/dist/index.js.map +1 -1
- package/dist/markdown-editor.cjs +270 -135
- package/dist/markdown-editor.cjs.map +1 -1
- package/dist/markdown-editor.js +270 -135
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.cjs +24 -15
- package/dist/mermaid.cjs.map +1 -1
- package/dist/mermaid.js +24 -15
- package/dist/mermaid.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +12 -5
- 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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
3
|
|
|
4
|
+
import { ArrowLeft, ArrowRight, ChevronLeft, ChevronRight, Plus } from '@keboola/design/icons';
|
|
5
|
+
|
|
4
6
|
import { Button } from '../Button';
|
|
5
7
|
|
|
6
8
|
import { ButtonGroup } from './ButtonGroup';
|
|
@@ -61,11 +63,17 @@ export const BlockWithIcons: Story = {
|
|
|
61
63
|
variant: 'block',
|
|
62
64
|
children: (
|
|
63
65
|
<>
|
|
64
|
-
<Button variant="outline"
|
|
66
|
+
<Button variant="outline" size="icon" aria-label="Left">
|
|
67
|
+
<ChevronLeft className="tw-size-5" />
|
|
68
|
+
</Button>
|
|
65
69
|
<Button variant="outline">Left button</Button>
|
|
66
|
-
<Button variant="outline"
|
|
70
|
+
<Button variant="outline" size="icon" aria-label="Plus">
|
|
71
|
+
<Plus className="tw-size-4" />
|
|
72
|
+
</Button>
|
|
67
73
|
<Button>Right Button</Button>
|
|
68
|
-
<Button variant="outline"
|
|
74
|
+
<Button variant="outline" size="icon" aria-label="Right">
|
|
75
|
+
<ChevronRight className="tw-size-5" />
|
|
76
|
+
</Button>
|
|
69
77
|
</>
|
|
70
78
|
),
|
|
71
79
|
},
|
|
@@ -77,15 +85,21 @@ export const ArgoBlock: Story = {
|
|
|
77
85
|
variant: 'block',
|
|
78
86
|
children: (
|
|
79
87
|
<>
|
|
80
|
-
<Button argo
|
|
88
|
+
<Button argo size="icon" variant="outline" aria-label="move-left">
|
|
89
|
+
<ChevronLeft className="tw-size-5" />
|
|
90
|
+
</Button>
|
|
81
91
|
<Button argo variant="primary">
|
|
82
92
|
Left button
|
|
83
93
|
</Button>
|
|
84
|
-
<Button argo
|
|
94
|
+
<Button argo size="icon" variant="outline" aria-label="add">
|
|
95
|
+
<Plus className="tw-size-4" />
|
|
96
|
+
</Button>
|
|
85
97
|
<Button argo variant="danger">
|
|
86
98
|
Right Button
|
|
87
99
|
</Button>
|
|
88
|
-
<Button argo
|
|
100
|
+
<Button argo size="icon" variant="outline" aria-label="move-right">
|
|
101
|
+
<ChevronRight className="tw-size-5" />
|
|
102
|
+
</Button>
|
|
89
103
|
</>
|
|
90
104
|
),
|
|
91
105
|
},
|
|
@@ -96,9 +110,13 @@ export const Compact: Story = {
|
|
|
96
110
|
space: 'compact',
|
|
97
111
|
children: (
|
|
98
112
|
<>
|
|
99
|
-
<Button variant="outline"
|
|
113
|
+
<Button variant="outline" size="icon" aria-label="Left">
|
|
114
|
+
<ArrowLeft className="tw-size-4" />
|
|
115
|
+
</Button>
|
|
100
116
|
<Button variant="outline">Submit</Button>
|
|
101
|
-
<Button variant="outline"
|
|
117
|
+
<Button variant="outline" size="icon" aria-label="Right">
|
|
118
|
+
<ArrowRight className="tw-size-4" />
|
|
119
|
+
</Button>
|
|
102
120
|
</>
|
|
103
121
|
),
|
|
104
122
|
},
|
|
@@ -109,9 +127,13 @@ export const ArgoCompact: Story = {
|
|
|
109
127
|
space: 'compact',
|
|
110
128
|
children: (
|
|
111
129
|
<>
|
|
112
|
-
<Button argo size="icon"
|
|
130
|
+
<Button argo size="icon" aria-label="move-right">
|
|
131
|
+
<ArrowLeft className="tw-size-4" />
|
|
132
|
+
</Button>
|
|
113
133
|
<Button argo>Submit</Button>
|
|
114
|
-
<Button argo size="icon"
|
|
134
|
+
<Button argo size="icon" aria-label="move-right">
|
|
135
|
+
<ArrowRight className="tw-size-4" />
|
|
136
|
+
</Button>
|
|
115
137
|
</>
|
|
116
138
|
),
|
|
117
139
|
},
|
|
@@ -6,8 +6,25 @@ import { CardHeader } from './CardHeader';
|
|
|
6
6
|
import { CardTitle } from './CardTitle';
|
|
7
7
|
import { cardClassnames } from './styles';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Props for `Card`. `padding` controls internal spacing; `bordered` adds a subtle border.
|
|
11
|
+
* All standard `<div>` attributes pass through.
|
|
12
|
+
*/
|
|
9
13
|
type Props = HTMLAttributes<HTMLDivElement> & VariantProps<typeof cardClassnames>;
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Semantic content surface — a panel with its own padding, optional border, and header / content slots.
|
|
17
|
+
*
|
|
18
|
+
* **When to use:** wrapping a conceptually-distinct chunk of content (a config section, a stats panel,
|
|
19
|
+
* a list of heterogeneous items). Each `Card` is a self-contained surface inside `PageLayout.Content`.
|
|
20
|
+
* **When NOT to use:** for tabular data use `Table`; for ad-hoc layout grids use Tailwind utility classes
|
|
21
|
+
* directly; for empty / error placeholders use `EmptyState` / `ErrorState`.
|
|
22
|
+
* **Composition:** nest `Card.Header` + `Card.Title` for the header row, then `Card.Content` for the body.
|
|
23
|
+
* Multiple cards usually share a `tw-grid` or `tw-flex tw-flex-col tw-gap-4` parent.
|
|
24
|
+
*
|
|
25
|
+
* @see RECIPES.md#card-with-empty-state — for an empty card placeholder pattern
|
|
26
|
+
* @see RECIPES.md#data-card-with-skeleton — for a loading card with `Skeleton` placeholders
|
|
27
|
+
*/
|
|
11
28
|
export const Card = ({
|
|
12
29
|
children,
|
|
13
30
|
className,
|
|
@@ -4,10 +4,10 @@ import type { CheckedState } from '@radix-ui/react-checkbox';
|
|
|
4
4
|
import { Indicator, Root } from '@radix-ui/react-checkbox';
|
|
5
5
|
import type { VariantProps } from 'class-variance-authority';
|
|
6
6
|
|
|
7
|
+
import { Check, Minus } from '../../icons';
|
|
7
8
|
import { cn } from '../../utils';
|
|
8
9
|
import { FieldBox } from '../FieldBox';
|
|
9
10
|
import type { fieldBoxVariants } from '../FieldBox/styles';
|
|
10
|
-
import { Icon } from '../Icon';
|
|
11
11
|
import type { Props as TooltipProps } from '../Tooltip';
|
|
12
12
|
import { Tooltip } from '../Tooltip';
|
|
13
13
|
|
|
@@ -58,11 +58,8 @@ export function Checkbox({
|
|
|
58
58
|
const checkboxElement = (
|
|
59
59
|
<Root id={id} {...rest} className={cn(rootVariants({ variant: styleVariant, className }))}>
|
|
60
60
|
<Indicator className={cn(indicatorVariants({ variant: styleVariant }))}>
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
icon="minus"
|
|
64
|
-
className="tw-hidden tw-size-3 group-data-[state=indeterminate]:tw-block"
|
|
65
|
-
/>
|
|
61
|
+
<Check className="tw-hidden tw-size-3 tw-stroke-[4px] group-data-[state=checked]:tw-block" />
|
|
62
|
+
<Minus className="tw-hidden tw-size-3 tw-stroke-[4px] group-data-[state=indeterminate]:tw-block" />
|
|
66
63
|
</Indicator>
|
|
67
64
|
</Root>
|
|
68
65
|
);
|
|
@@ -15,7 +15,7 @@ export type HighlightedLines = {
|
|
|
15
15
|
|
|
16
16
|
// Gutter markers for highlighting
|
|
17
17
|
class HighlightMarker extends GutterMarker {
|
|
18
|
-
toDOM() {
|
|
18
|
+
override toDOM() {
|
|
19
19
|
const marker = document.createElement('div');
|
|
20
20
|
marker.className = 'cm-highlight-marker';
|
|
21
21
|
return marker;
|
|
@@ -2,8 +2,8 @@ import { useState } from 'react';
|
|
|
2
2
|
import type { KeyboardEvent, MouseEvent, ReactNode } from 'react';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
|
|
5
|
-
import { Icon } from '../components/Icon';
|
|
6
5
|
import { keyCodes } from '../constants/keyCodes';
|
|
6
|
+
import { ChevronDown } from '../icons';
|
|
7
7
|
import { cn } from '../utils';
|
|
8
8
|
|
|
9
9
|
import { Collapse } from './Collapse';
|
|
@@ -115,10 +115,7 @@ export const CollapsiblePanel = ({
|
|
|
115
115
|
</div>
|
|
116
116
|
{!isDisabled && (
|
|
117
117
|
<div className="tw-ml-auto tw-shrink-0">
|
|
118
|
-
<
|
|
119
|
-
icon="chevron-down"
|
|
120
|
-
className={cn('tw-text-xs group-data-[state=open]:tw-rotate-180')}
|
|
121
|
-
/>
|
|
118
|
+
<ChevronDown className={cn('tw-size-5 group-data-[state=open]:tw-rotate-180')} />
|
|
122
119
|
</div>
|
|
123
120
|
)}
|
|
124
121
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ComponentProps, type ReactNode, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { Combobox as BaseCombobox } from '@base-ui/react/combobox';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { ChevronDown, Plus, X } from '../../icons';
|
|
5
5
|
import { InputGroup } from '../InputGroup';
|
|
6
6
|
|
|
7
7
|
import { ComboboxChips } from './ComboboxChips';
|
|
@@ -35,7 +35,6 @@ type ComboboxInputProps = ComponentProps<typeof ComboboxInput>;
|
|
|
35
35
|
type ComboboxInputGroupProps = ComponentProps<typeof ComboboxInputGroup>;
|
|
36
36
|
type ComboboxItemProps = ComponentProps<typeof ComboboxItem>;
|
|
37
37
|
|
|
38
|
-
type IconName = ComponentProps<typeof Icon>['icon'];
|
|
39
38
|
type Indicator = NonNullable<ComboboxItemProps['indicator']>;
|
|
40
39
|
|
|
41
40
|
type PublicComboboxInputProps = Pick<ComboboxInputProps, 'placeholder' | 'id'> &
|
|
@@ -74,7 +73,7 @@ type Props<Value, GroupShape extends Group<Value> = Group<Value>> = PublicCombob
|
|
|
74
73
|
|
|
75
74
|
// item specific
|
|
76
75
|
itemToLabel?: (item: Value) => ReactNode;
|
|
77
|
-
itemToIcon?: (item: Value) =>
|
|
76
|
+
itemToIcon?: (item: Value) => ReactNode;
|
|
78
77
|
itemToDisabled?: (item: Value) => boolean;
|
|
79
78
|
|
|
80
79
|
// group specific
|
|
@@ -273,17 +272,16 @@ export const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>(
|
|
|
273
272
|
<ComboboxInput id={id} placeholder={placeholder} disabled={disabled} />
|
|
274
273
|
<InputGroup.Addon align="inline-end">
|
|
275
274
|
{allowClear && (
|
|
276
|
-
<InputGroup.Button asChild
|
|
277
|
-
<BaseCombobox.Clear
|
|
275
|
+
<InputGroup.Button asChild aria-label="Clear" disabled={disabled}>
|
|
276
|
+
<BaseCombobox.Clear>
|
|
277
|
+
<X className="tw-size-4" />
|
|
278
|
+
</BaseCombobox.Clear>
|
|
278
279
|
</InputGroup.Button>
|
|
279
280
|
)}
|
|
280
|
-
<InputGroup.Button
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
aria-label="Open combobox"
|
|
285
|
-
>
|
|
286
|
-
<BaseCombobox.Trigger />
|
|
281
|
+
<InputGroup.Button disabled={disabled} asChild aria-label="Open combobox">
|
|
282
|
+
<BaseCombobox.Trigger>
|
|
283
|
+
<ChevronDown className="tw-size-4" />
|
|
284
|
+
</BaseCombobox.Trigger>
|
|
287
285
|
</InputGroup.Button>
|
|
288
286
|
</InputGroup.Addon>
|
|
289
287
|
</ComboboxInputGroup>
|
|
@@ -293,7 +291,7 @@ export const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>(
|
|
|
293
291
|
{(itemOrGroup: Value | GroupShape) => {
|
|
294
292
|
if (isCreatableItem(itemOrGroup))
|
|
295
293
|
return (
|
|
296
|
-
<Combobox.Item value={itemOrGroup} icon=
|
|
294
|
+
<Combobox.Item value={itemOrGroup} icon={<Plus />}>
|
|
297
295
|
{queryToCreateLabel(itemOrGroup.value)}
|
|
298
296
|
</Combobox.Item>
|
|
299
297
|
);
|
|
@@ -303,7 +301,7 @@ export const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>(
|
|
|
303
301
|
|
|
304
302
|
if (isCreatableItem(maybeCreatable)) {
|
|
305
303
|
return (
|
|
306
|
-
<Combobox.Item value={maybeCreatable} icon=
|
|
304
|
+
<Combobox.Item value={maybeCreatable} icon={<Plus />}>
|
|
307
305
|
{queryToCreateLabel(maybeCreatable.value)}
|
|
308
306
|
</Combobox.Item>
|
|
309
307
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentProps, ReactNode } from 'react';
|
|
2
2
|
import { Combobox as BaseCombobox } from '@base-ui/react/combobox';
|
|
3
3
|
|
|
4
|
+
import { X } from '../../icons';
|
|
4
5
|
import { Badge } from '../Badge';
|
|
5
6
|
|
|
6
7
|
import { defaultItemToLabel } from './utils';
|
|
@@ -45,7 +46,11 @@ export const ComboboxChips = <Value,>({
|
|
|
45
46
|
<Badge.Label>{itemToChipLabel(value)}</Badge.Label>
|
|
46
47
|
<Badge.Addon variant="inline" align="inline-end">
|
|
47
48
|
<BaseCombobox.ChipRemove
|
|
48
|
-
render={
|
|
49
|
+
render={
|
|
50
|
+
<Badge.Button aria-label="Remove value">
|
|
51
|
+
<X className="tw-size-3" />
|
|
52
|
+
</Badge.Button>
|
|
53
|
+
}
|
|
49
54
|
/>
|
|
50
55
|
</Badge.Addon>
|
|
51
56
|
</BaseCombobox.Chip>
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { ComponentProps, ElementRef, Ref } from 'react';
|
|
1
|
+
import type { ComponentProps, ElementRef, ReactNode, Ref } from 'react';
|
|
2
2
|
import { Combobox as BaseCombobox } from '@base-ui/react/combobox';
|
|
3
3
|
|
|
4
4
|
import { cn } from '../../utils';
|
|
5
|
-
import { Icon } from '../Icon';
|
|
6
5
|
|
|
7
6
|
import { ComboboxItemIndicator } from './ComboboxItemIndicator';
|
|
8
7
|
|
|
9
8
|
type Props = Omit<ComponentProps<typeof BaseCombobox.Item>, 'className'> & {
|
|
10
9
|
className?: string;
|
|
11
|
-
icon?:
|
|
10
|
+
icon?: ReactNode;
|
|
12
11
|
indicator?: ComponentProps<typeof ComboboxItemIndicator>['variant'];
|
|
13
12
|
};
|
|
14
13
|
|
|
@@ -65,7 +64,7 @@ export const ComboboxItem = ({
|
|
|
65
64
|
)}
|
|
66
65
|
>
|
|
67
66
|
{<ComboboxItemIndicator variant={variant} />}
|
|
68
|
-
{icon
|
|
67
|
+
{icon}
|
|
69
68
|
<span className="tw-truncate">{children}</span>
|
|
70
69
|
</BaseCombobox.Item>
|
|
71
70
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps, ElementRef, Ref } from 'react';
|
|
2
2
|
import { Combobox as BaseCombobox } from '@base-ui/react/combobox';
|
|
3
3
|
|
|
4
|
+
import { Check } from '../../icons';
|
|
4
5
|
import { cn } from '../../utils';
|
|
5
|
-
import { Icon } from '../Icon';
|
|
6
6
|
|
|
7
7
|
type Variant = 'check' | 'checkbox';
|
|
8
8
|
|
|
@@ -42,11 +42,11 @@ export const ComboboxItemIndicator = ({
|
|
|
42
42
|
)}
|
|
43
43
|
{...props}
|
|
44
44
|
>
|
|
45
|
-
<
|
|
46
|
-
icon="check"
|
|
45
|
+
<Check
|
|
47
46
|
className={cn(
|
|
48
47
|
'tw-hidden',
|
|
49
48
|
'tw-size-3',
|
|
49
|
+
'tw-stroke-[4px]',
|
|
50
50
|
'!tw-text-white',
|
|
51
51
|
'group-data-[selected]/combobox-item-indicator:tw-block',
|
|
52
52
|
)}
|
|
@@ -65,12 +65,14 @@ export const ComboboxItemIndicator = ({
|
|
|
65
65
|
'tw-right-2',
|
|
66
66
|
|
|
67
67
|
'group-data-[variant=default]/combobox-content:tw-right-4',
|
|
68
|
+
// Lucide SVGs default to 24×24 — constrain the rendered child so the
|
|
69
|
+
// 16px indicator slot owns the actual size.
|
|
68
70
|
'[&_svg]:tw-size-4',
|
|
69
71
|
'group-data-[highlighted]/combobox-item:tw-text-accent-foreground',
|
|
70
72
|
'group-data-[variant=default]/combobox-content:group-data-[highlighted]/combobox-item:tw-text-foreground',
|
|
71
73
|
className,
|
|
72
74
|
)}
|
|
73
|
-
render={<
|
|
75
|
+
render={<Check />}
|
|
74
76
|
/>
|
|
75
77
|
);
|
|
76
78
|
};
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import type { Icon } from '../../components/Icon';
|
|
4
|
-
|
|
5
|
-
export type IconName = ComponentProps<typeof Icon>['icon'];
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
6
2
|
|
|
7
3
|
// Mirrors Base UI's internal `Group<Item>` interface from
|
|
8
4
|
// `@base-ui/react/internals/resolveValueLabel`. Any object with an `items`
|
|
@@ -17,7 +13,7 @@ export type Group<Item = unknown> = {
|
|
|
17
13
|
export type LabeledItem = {
|
|
18
14
|
value: string;
|
|
19
15
|
label: string;
|
|
20
|
-
icon?:
|
|
16
|
+
icon?: ReactNode;
|
|
21
17
|
disabled?: boolean;
|
|
22
18
|
};
|
|
23
19
|
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
4
|
|
|
5
|
+
import {
|
|
6
|
+
ArrowLeft,
|
|
7
|
+
Copy,
|
|
8
|
+
Eye,
|
|
9
|
+
Gauge,
|
|
10
|
+
Gift,
|
|
11
|
+
Layers,
|
|
12
|
+
Link as LinkIcon,
|
|
13
|
+
Plus,
|
|
14
|
+
Search,
|
|
15
|
+
Settings,
|
|
16
|
+
Star,
|
|
17
|
+
Wrench,
|
|
18
|
+
Zap,
|
|
19
|
+
} from '@keboola/design/icons';
|
|
20
|
+
|
|
5
21
|
import { Button } from '../Button';
|
|
6
|
-
import { Icon } from '../Icon';
|
|
7
22
|
import { Modal } from '../Modal';
|
|
8
23
|
import { Popover } from '../Popover';
|
|
9
24
|
|
|
@@ -12,48 +27,20 @@ import { Command } from './Command';
|
|
|
12
27
|
type Item = {
|
|
13
28
|
value: string;
|
|
14
29
|
label: string;
|
|
15
|
-
icon?:
|
|
30
|
+
icon?: ReactNode;
|
|
16
31
|
};
|
|
17
32
|
|
|
18
33
|
const planets: Item[] = [
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
icon: 'eye',
|
|
26
|
-
value: 'saturn',
|
|
27
|
-
label: 'Saturn',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
icon: 'wrench',
|
|
31
|
-
value: 'jupiter',
|
|
32
|
-
label: 'Jupiter',
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
value: 'mars',
|
|
36
|
-
label: 'Mars',
|
|
37
|
-
icon: 'bolt',
|
|
38
|
-
},
|
|
34
|
+
{ icon: <Gift />, value: 'earth', label: 'Earth' },
|
|
35
|
+
{ icon: <Eye />, value: 'saturn', label: 'Saturn' },
|
|
36
|
+
{ icon: <Wrench />, value: 'jupiter', label: 'Jupiter' },
|
|
37
|
+
{ value: 'mars', label: 'Mars', icon: <Zap /> },
|
|
39
38
|
];
|
|
40
39
|
|
|
41
40
|
const colors: Item[] = [
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
label: 'Red',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
icon: 'chain',
|
|
49
|
-
value: 'green',
|
|
50
|
-
label: 'Green',
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
icon: 'arrow-left',
|
|
54
|
-
value: 'blue',
|
|
55
|
-
label: 'Blue',
|
|
56
|
-
},
|
|
41
|
+
{ icon: <Settings />, value: 'red', label: 'Red' },
|
|
42
|
+
{ icon: <LinkIcon />, value: 'green', label: 'Green' },
|
|
43
|
+
{ icon: <ArrowLeft />, value: 'blue', label: 'Blue' },
|
|
57
44
|
];
|
|
58
45
|
|
|
59
46
|
/**
|
|
@@ -225,7 +212,7 @@ export const AsSearchableMenu: Story = {
|
|
|
225
212
|
<Command {...args}>
|
|
226
213
|
<Command.Input
|
|
227
214
|
focusVariant="off"
|
|
228
|
-
prefix={<
|
|
215
|
+
prefix={<Search className="tw-text-neutral-400" />}
|
|
229
216
|
variant="secondary"
|
|
230
217
|
placeholder="Search"
|
|
231
218
|
/>
|
|
@@ -264,7 +251,7 @@ export const AsGlobalSearch: Story = {
|
|
|
264
251
|
<Command {...args}>
|
|
265
252
|
<Command.Input
|
|
266
253
|
focusVariant="off"
|
|
267
|
-
prefix={<
|
|
254
|
+
prefix={<Search className="tw-text-neutral-400" />}
|
|
268
255
|
variant="secondary"
|
|
269
256
|
placeholder="Search"
|
|
270
257
|
/>
|
|
@@ -275,16 +262,22 @@ export const AsGlobalSearch: Story = {
|
|
|
275
262
|
|
|
276
263
|
<Command.List>
|
|
277
264
|
<Command.Group heading="Link">
|
|
278
|
-
<Command.Item icon="
|
|
279
|
-
<Command.Item icon="
|
|
280
|
-
|
|
281
|
-
|
|
265
|
+
<Command.Item icon={<Gauge className="tw-size-4" />}>Go to Dashboard</Command.Item>
|
|
266
|
+
<Command.Item icon={<Layers className="tw-size-4" />}>
|
|
267
|
+
Go to Workspaces
|
|
268
|
+
</Command.Item>
|
|
269
|
+
<Command.Item icon={<Copy className="tw-size-4" />}>
|
|
270
|
+
Go to Transformation
|
|
271
|
+
</Command.Item>
|
|
272
|
+
<Command.Item icon={<Eye className="tw-size-4" />}>Go to App</Command.Item>
|
|
282
273
|
</Command.Group>
|
|
283
274
|
|
|
284
275
|
<Command.Group heading="Actions">
|
|
285
|
-
<Command.Item icon="
|
|
286
|
-
<Command.Item icon="
|
|
287
|
-
<Command.Item icon="
|
|
276
|
+
<Command.Item icon={<Plus className="tw-size-4" />}>Create Workspace</Command.Item>
|
|
277
|
+
<Command.Item icon={<Plus className="tw-size-4" />}>Create App</Command.Item>
|
|
278
|
+
<Command.Item icon={<Plus className="tw-size-4" />}>
|
|
279
|
+
Create Transformation
|
|
280
|
+
</Command.Item>
|
|
288
281
|
</Command.Group>
|
|
289
282
|
</Command.List>
|
|
290
283
|
</Command>
|
|
@@ -309,7 +302,7 @@ export const ArgoAppearance: Story = {
|
|
|
309
302
|
<div className="tw-mb-1 tw-px-4 tw-pb-0 tw-pt-4">
|
|
310
303
|
<Command.Input
|
|
311
304
|
variant="secondary"
|
|
312
|
-
prefix={<
|
|
305
|
+
prefix={<Search className="tw-size-4 tw-text-neutral-400" />}
|
|
313
306
|
placeholder="Search..."
|
|
314
307
|
allowClear
|
|
315
308
|
focusVariant="off"
|
|
@@ -334,13 +327,9 @@ export const ArgoAppearance: Story = {
|
|
|
334
327
|
disabled={isDisabled}
|
|
335
328
|
actions={
|
|
336
329
|
isDisabled ? undefined : (
|
|
337
|
-
<Button
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
icon="star"
|
|
341
|
-
aria-label="Favorite"
|
|
342
|
-
size="icon-sm"
|
|
343
|
-
/>
|
|
330
|
+
<Button argo variant="outline" aria-label="Favorite" size="icon-sm">
|
|
331
|
+
<Star className="tw-size-4" />
|
|
332
|
+
</Button>
|
|
344
333
|
)
|
|
345
334
|
}
|
|
346
335
|
>
|
|
@@ -362,7 +351,9 @@ export const ArgoAppearance: Story = {
|
|
|
362
351
|
onSelect={handleOnSelect}
|
|
363
352
|
checked={item.value === value}
|
|
364
353
|
actions={
|
|
365
|
-
<Button argo variant="outline"
|
|
354
|
+
<Button argo variant="outline" aria-label="Favorite" size="icon-sm">
|
|
355
|
+
<Star className="tw-size-4" />
|
|
356
|
+
</Button>
|
|
366
357
|
}
|
|
367
358
|
>
|
|
368
359
|
{item.label}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Check, Circle } from '../../../icons';
|
|
1
2
|
import { cn } from '../../../utils';
|
|
2
|
-
import { Icon } from '../../Icon';
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
variant?: 'checkbox' | 'radio' | 'argo' | 'default';
|
|
@@ -10,8 +10,7 @@ export const CheckIndicator = ({ variant = 'default' }: Props) => {
|
|
|
10
10
|
|
|
11
11
|
if (variant === 'argo') {
|
|
12
12
|
return (
|
|
13
|
-
<
|
|
14
|
-
icon="check"
|
|
13
|
+
<Check
|
|
15
14
|
className={cn(
|
|
16
15
|
// visibility
|
|
17
16
|
'tw-hidden',
|
|
@@ -58,17 +57,30 @@ export const CheckIndicator = ({ variant = 'default' }: Props) => {
|
|
|
58
57
|
'tw-shrink-0',
|
|
59
58
|
)}
|
|
60
59
|
>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
{variant === 'checkbox' ? (
|
|
61
|
+
<Check
|
|
62
|
+
className={cn(
|
|
63
|
+
'tw-hidden',
|
|
64
|
+
// Lucide SVGs default to 24×24; constrain to the 16px indicator slot.
|
|
65
|
+
'tw-size-3',
|
|
66
|
+
'tw-stroke-[4px]',
|
|
67
|
+
'group-data-[checked=true]/command-item:tw-block',
|
|
68
|
+
'group-data-[variant=checkbox]/check-indicator:tw-text-white',
|
|
69
|
+
)}
|
|
70
|
+
/>
|
|
71
|
+
) : (
|
|
72
|
+
<Circle
|
|
73
|
+
className={cn(
|
|
74
|
+
'tw-hidden',
|
|
75
|
+
// Lucide Circle is stroke-only — force fill to match the stroke so
|
|
76
|
+
// the indicator reads as a solid dot.
|
|
77
|
+
'tw-size-3',
|
|
78
|
+
'tw-fill-current',
|
|
79
|
+
'group-data-[checked=true]/command-item:tw-block',
|
|
80
|
+
'group-data-[variant=radio]/check-indicator:tw-text-secondary-500',
|
|
81
|
+
)}
|
|
82
|
+
/>
|
|
83
|
+
)}
|
|
72
84
|
</span>
|
|
73
85
|
);
|
|
74
86
|
};
|
|
@@ -2,12 +2,11 @@ import type { ComponentProps, ReactNode } from 'react';
|
|
|
2
2
|
import { Command as CommandPrimitive } from 'cmdk';
|
|
3
3
|
|
|
4
4
|
import { cn } from '../../../utils';
|
|
5
|
-
import { Icon } from '../../Icon';
|
|
6
5
|
|
|
7
6
|
import { CheckIndicator } from './CheckIndicator';
|
|
8
7
|
|
|
9
8
|
type Props = ComponentProps<typeof CommandPrimitive.Item> & {
|
|
10
|
-
icon?:
|
|
9
|
+
icon?: ReactNode;
|
|
11
10
|
checked?: boolean;
|
|
12
11
|
variant?: ComponentProps<typeof CheckIndicator>['variant'];
|
|
13
12
|
actions?: ReactNode;
|
|
@@ -69,7 +68,11 @@ export const CommandItem = ({
|
|
|
69
68
|
)}
|
|
70
69
|
>
|
|
71
70
|
<CheckIndicator variant={variant} />
|
|
72
|
-
{icon &&
|
|
71
|
+
{icon && (
|
|
72
|
+
<span className="tw-inline-flex tw-size-4 tw-shrink-0 tw-items-center tw-justify-center tw-text-neutral-400 [&_svg]:tw-size-4">
|
|
73
|
+
{icon}
|
|
74
|
+
</span>
|
|
75
|
+
)}
|
|
73
76
|
{children}
|
|
74
77
|
</CommandPrimitive.Item>
|
|
75
78
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ComponentProps, useState } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
3
|
|
|
4
|
+
import { Settings } from '@keboola/design/icons';
|
|
5
|
+
|
|
4
6
|
import { Button } from '../Button';
|
|
5
7
|
|
|
6
8
|
import { DropdownMenu } from './DropdownMenu';
|
|
@@ -51,13 +53,15 @@ export const MenuItems: Story = {
|
|
|
51
53
|
|
|
52
54
|
<DropdownMenu.Content>
|
|
53
55
|
<DropdownMenu.Item>Default</DropdownMenu.Item>
|
|
54
|
-
<DropdownMenu.Item icon="
|
|
56
|
+
<DropdownMenu.Item icon={<Settings className="tw-size-4" />}>
|
|
57
|
+
Default - Icon
|
|
58
|
+
</DropdownMenu.Item>
|
|
55
59
|
<DropdownMenu.Item disabled>Default - Disabled</DropdownMenu.Item>
|
|
56
|
-
<DropdownMenu.Item icon="
|
|
60
|
+
<DropdownMenu.Item disabled icon={<Settings className="tw-size-4" />}>
|
|
57
61
|
Default - Icon- Disabled
|
|
58
62
|
</DropdownMenu.Item>
|
|
59
63
|
<DropdownMenu.Item isLoading>Default - Loading</DropdownMenu.Item>
|
|
60
|
-
<DropdownMenu.Item icon="
|
|
64
|
+
<DropdownMenu.Item isLoading icon={<Settings className="tw-size-4" />}>
|
|
61
65
|
Default - Icon - Loading
|
|
62
66
|
</DropdownMenu.Item>
|
|
63
67
|
<DropdownMenu.Item>Default - Selected</DropdownMenu.Item>
|
|
@@ -68,7 +72,7 @@ export const MenuItems: Story = {
|
|
|
68
72
|
<a href="#">Anchor</a>
|
|
69
73
|
</DropdownMenu.Item>
|
|
70
74
|
|
|
71
|
-
<DropdownMenu.Item asChild icon="
|
|
75
|
+
<DropdownMenu.Item asChild icon={<Settings className="tw-size-4" />}>
|
|
72
76
|
{/* oxlint-disable-next-line jsx-a11y/anchor-is-valid */}
|
|
73
77
|
<a href="#">Anchor - Icon</a>
|
|
74
78
|
</DropdownMenu.Item>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentProps } from 'react';
|
|
2
2
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
3
3
|
|
|
4
|
+
import { Loader2 } from '../../icons';
|
|
4
5
|
import { cn } from '../../utils';
|
|
5
6
|
|
|
6
7
|
import { DropdownMenuItemIndicator } from './DropdownMenuItemIndicator';
|
|
@@ -27,7 +28,9 @@ export const DropdownMenuCheckboxItem = ({
|
|
|
27
28
|
}: Props) => {
|
|
28
29
|
const isAtStart = indicatorAlign === 'start';
|
|
29
30
|
const indicatorEle = isLoading ? (
|
|
30
|
-
<ItemIcon
|
|
31
|
+
<ItemIcon className={isAtStart ? '' : 'tw-ml-auto'}>
|
|
32
|
+
<Loader2 className="tw-animate-spin" />
|
|
33
|
+
</ItemIcon>
|
|
31
34
|
) : (
|
|
32
35
|
<DropdownMenuItemIndicator variant={indicator} className={isAtStart ? '' : 'tw-ml-auto'} />
|
|
33
36
|
);
|