@shipfox/react-ui 0.14.0 → 0.15.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/.storybook/preview.tsx +7 -0
- package/.turbo/turbo-build.log +7 -7
- package/.turbo/turbo-check.log +2 -2
- package/.turbo/turbo-type.log +1 -1
- package/CHANGELOG.md +10 -0
- package/dist/components/avatar/avatar.js +1 -1
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/button-group/button-group.d.ts +17 -0
- package/dist/components/button-group/button-group.d.ts.map +1 -0
- package/dist/components/button-group/button-group.js +74 -0
- package/dist/components/button-group/button-group.js.map +1 -0
- package/dist/components/button-group/button-group.stories.js +644 -0
- package/dist/components/button-group/button-group.stories.js.map +1 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/button-group/index.d.ts.map +1 -0
- package/dist/components/button-group/index.js +3 -0
- package/dist/components/button-group/index.js.map +1 -0
- package/dist/components/code-block/code-block-footer.d.ts.map +1 -1
- package/dist/components/code-block/code-block-footer.js +4 -2
- package/dist/components/code-block/code-block-footer.js.map +1 -1
- package/dist/components/command/command.d.ts +28 -0
- package/dist/components/command/command.d.ts.map +1 -0
- package/dist/components/command/command.js +190 -0
- package/dist/components/command/command.js.map +1 -0
- package/dist/components/command/command.stories.js +228 -0
- package/dist/components/command/command.stories.js.map +1 -0
- package/dist/components/command/index.d.ts +2 -0
- package/dist/components/command/index.d.ts.map +1 -0
- package/dist/components/command/index.js +3 -0
- package/dist/components/command/index.js.map +1 -0
- package/dist/components/dashboard/components/analytics-content.d.ts +2 -0
- package/dist/components/dashboard/components/analytics-content.d.ts.map +1 -0
- package/dist/components/dashboard/components/analytics-content.js +180 -0
- package/dist/components/dashboard/components/analytics-content.js.map +1 -0
- package/dist/components/dashboard/components/animated-logo.d.ts +4 -0
- package/dist/components/dashboard/components/animated-logo.d.ts.map +1 -0
- package/dist/components/dashboard/components/animated-logo.js +23 -0
- package/dist/components/dashboard/components/animated-logo.js.map +1 -0
- package/dist/components/dashboard/components/complete-setup-button.d.ts +4 -0
- package/dist/components/dashboard/components/complete-setup-button.d.ts.map +1 -0
- package/dist/components/dashboard/components/complete-setup-button.js +28 -0
- package/dist/components/dashboard/components/complete-setup-button.js.map +1 -0
- package/dist/components/dashboard/components/jobs-content.d.ts +2 -0
- package/dist/components/dashboard/components/jobs-content.d.ts.map +1 -0
- package/dist/components/dashboard/components/jobs-content.js +69 -0
- package/dist/components/dashboard/components/jobs-content.js.map +1 -0
- package/dist/components/dashboard/components/mobile-menu.d.ts +2 -0
- package/dist/components/dashboard/components/mobile-menu.d.ts.map +1 -0
- package/dist/components/dashboard/components/mobile-menu.js +65 -0
- package/dist/components/dashboard/components/mobile-menu.js.map +1 -0
- package/dist/components/dashboard/components/organization-selector.d.ts +2 -0
- package/dist/components/dashboard/components/organization-selector.d.ts.map +1 -0
- package/dist/components/dashboard/components/organization-selector.js +92 -0
- package/dist/components/dashboard/components/organization-selector.js.map +1 -0
- package/dist/components/dashboard/components/top-menu.d.ts +5 -0
- package/dist/components/dashboard/components/top-menu.d.ts.map +1 -0
- package/dist/components/dashboard/components/top-menu.js +31 -0
- package/dist/components/dashboard/components/top-menu.js.map +1 -0
- package/dist/components/dashboard/components/topbar-button.d.ts +7 -0
- package/dist/components/dashboard/components/topbar-button.d.ts.map +1 -0
- package/dist/components/dashboard/components/topbar-button.js +18 -0
- package/dist/components/dashboard/components/topbar-button.js.map +1 -0
- package/dist/components/dashboard/components/topbar.d.ts +4 -0
- package/dist/components/dashboard/components/topbar.d.ts.map +1 -0
- package/dist/components/dashboard/components/topbar.js +62 -0
- package/dist/components/dashboard/components/topbar.js.map +1 -0
- package/dist/components/dashboard/components/user-profile.d.ts +2 -0
- package/dist/components/dashboard/components/user-profile.d.ts.map +1 -0
- package/dist/components/dashboard/components/user-profile.js +146 -0
- package/dist/components/dashboard/components/user-profile.js.map +1 -0
- package/dist/components/dashboard/dashboard.d.ts +2 -0
- package/dist/components/dashboard/dashboard.d.ts.map +1 -0
- package/dist/components/dashboard/dashboard.js +70 -0
- package/dist/components/dashboard/dashboard.js.map +1 -0
- package/dist/components/dashboard/dashboard.stories.js +23 -0
- package/dist/components/dashboard/dashboard.stories.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +2 -0
- package/dist/components/dashboard/index.d.ts.map +1 -0
- package/dist/components/dashboard/index.js +3 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/form/form.stories.js +6 -1
- package/dist/components/form/form.stories.js.map +1 -1
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +7 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/kbd/index.d.ts +2 -0
- package/dist/components/kbd/index.d.ts.map +1 -0
- package/dist/components/kbd/index.js +3 -0
- package/dist/components/kbd/index.js.map +1 -0
- package/dist/components/kbd/kbd.d.ts +7 -0
- package/dist/components/kbd/kbd.d.ts.map +1 -0
- package/dist/components/kbd/kbd.js +18 -0
- package/dist/components/kbd/kbd.js.map +1 -0
- package/dist/components/kbd/kbd.stories.js +119 -0
- package/dist/components/kbd/kbd.stories.js.map +1 -0
- package/dist/components/search/index.d.ts +7 -0
- package/dist/components/search/index.d.ts.map +1 -0
- package/dist/components/search/index.js +8 -0
- package/dist/components/search/index.js.map +1 -0
- package/dist/components/search/search-context.d.ts +11 -0
- package/dist/components/search/search-context.d.ts.map +1 -0
- package/dist/components/search/search-context.js +56 -0
- package/dist/components/search/search-context.js.map +1 -0
- package/dist/components/search/search-inline.d.ts +9 -0
- package/dist/components/search/search-inline.d.ts.map +1 -0
- package/dist/components/search/search-inline.js +85 -0
- package/dist/components/search/search-inline.js.map +1 -0
- package/dist/components/search/search-modal.d.ts +25 -0
- package/dist/components/search/search-modal.d.ts.map +1 -0
- package/dist/components/search/search-modal.js +162 -0
- package/dist/components/search/search-modal.js.map +1 -0
- package/dist/components/search/search-trigger.d.ts +9 -0
- package/dist/components/search/search-trigger.d.ts.map +1 -0
- package/dist/components/search/search-trigger.js +37 -0
- package/dist/components/search/search-trigger.js.map +1 -0
- package/dist/components/search/search-variants.d.ts +14 -0
- package/dist/components/search/search-variants.d.ts.map +1 -0
- package/dist/components/search/search-variants.js +90 -0
- package/dist/components/search/search-variants.js.map +1 -0
- package/dist/components/search/search.d.ts +11 -0
- package/dist/components/search/search.d.ts.map +1 -0
- package/dist/components/search/search.js +35 -0
- package/dist/components/search/search.js.map +1 -0
- package/dist/components/search/search.stories.js +630 -0
- package/dist/components/search/search.stories.js.map +1 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.d.ts.map +1 -0
- package/dist/components/select/index.js +3 -0
- package/dist/components/select/index.js.map +1 -0
- package/dist/components/select/select.d.ts +25 -0
- package/dist/components/select/select.d.ts.map +1 -0
- package/dist/components/select/select.js +153 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/select/select.stories.js +393 -0
- package/dist/components/select/select.stories.js.map +1 -0
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/index.d.ts.map +1 -0
- package/dist/components/skeleton/index.js +3 -0
- package/dist/components/skeleton/index.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +5 -0
- package/dist/components/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton/skeleton.js +11 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/skeleton/skeleton.stories.js +345 -0
- package/dist/components/skeleton/skeleton.stories.js.map +1 -0
- package/dist/components/table/data-table.d.ts +70 -0
- package/dist/components/table/data-table.d.ts.map +1 -0
- package/dist/components/table/data-table.js +159 -0
- package/dist/components/table/data-table.js.map +1 -0
- package/dist/components/table/index.d.ts +6 -0
- package/dist/components/table/index.d.ts.map +1 -0
- package/dist/components/table/index.js +6 -0
- package/dist/components/table/index.js.map +1 -0
- package/dist/components/table/table-column-header.d.ts +79 -0
- package/dist/components/table/table-column-header.d.ts.map +1 -0
- package/dist/components/table/table-column-header.js +99 -0
- package/dist/components/table/table-column-header.js.map +1 -0
- package/dist/components/table/table-pagination.d.ts +53 -0
- package/dist/components/table/table-pagination.d.ts.map +1 -0
- package/dist/components/table/table-pagination.js +139 -0
- package/dist/components/table/table-pagination.js.map +1 -0
- package/dist/components/table/table.d.ts +11 -0
- package/dist/components/table/table.d.ts.map +1 -0
- package/dist/components/table/table.js +64 -0
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/table/table.stories.columns.d.ts +24 -0
- package/dist/components/table/table.stories.columns.d.ts.map +1 -0
- package/dist/components/table/table.stories.columns.js +310 -0
- package/dist/components/table/table.stories.columns.js.map +1 -0
- package/dist/components/table/table.stories.components.d.ts +14 -0
- package/dist/components/table/table.stories.components.d.ts.map +1 -0
- package/dist/components/table/table.stories.components.js +107 -0
- package/dist/components/table/table.stories.components.js.map +1 -0
- package/dist/components/table/table.stories.data.d.ts +54 -0
- package/dist/components/table/table.stories.data.d.ts.map +1 -0
- package/dist/components/table/table.stories.data.js +122 -0
- package/dist/components/table/table.stories.data.js.map +1 -0
- package/dist/components/table/table.stories.js +302 -0
- package/dist/components/table/table.stories.js.map +1 -0
- package/dist/styles.css +1 -1
- package/index.css +48 -0
- package/package.json +3 -2
- package/src/components/avatar/avatar.tsx +1 -1
- package/src/components/button-group/button-group.stories.tsx +361 -0
- package/src/components/button-group/button-group.tsx +111 -0
- package/src/components/button-group/index.ts +1 -0
- package/src/components/code-block/code-block-footer.tsx +8 -1
- package/src/components/command/command.stories.tsx +133 -0
- package/src/components/command/command.tsx +265 -0
- package/src/components/command/index.ts +1 -0
- package/src/components/dashboard/components/analytics-content.tsx +102 -0
- package/src/components/dashboard/components/animated-logo.tsx +25 -0
- package/src/components/dashboard/components/complete-setup-button.tsx +30 -0
- package/src/components/dashboard/components/jobs-content.tsx +51 -0
- package/src/components/dashboard/components/mobile-menu.tsx +50 -0
- package/src/components/dashboard/components/organization-selector.tsx +51 -0
- package/src/components/dashboard/components/top-menu.tsx +26 -0
- package/src/components/dashboard/components/topbar-button.tsx +27 -0
- package/src/components/dashboard/components/topbar.tsx +40 -0
- package/src/components/dashboard/components/user-profile.tsx +90 -0
- package/src/components/dashboard/dashboard.stories.tsx +25 -0
- package/src/components/dashboard/dashboard.tsx +61 -0
- package/src/components/dashboard/index.ts +1 -0
- package/src/components/form/form.stories.tsx +5 -0
- package/src/components/index.ts +7 -0
- package/src/components/kbd/index.ts +1 -0
- package/src/components/kbd/kbd.stories.tsx +64 -0
- package/src/components/kbd/kbd.tsx +32 -0
- package/src/components/search/index.ts +28 -0
- package/src/components/search/search-context.tsx +78 -0
- package/src/components/search/search-inline.tsx +107 -0
- package/src/components/search/search-modal.tsx +198 -0
- package/src/components/search/search-trigger.tsx +47 -0
- package/src/components/search/search-variants.ts +88 -0
- package/src/components/search/search.stories.tsx +392 -0
- package/src/components/search/search.tsx +47 -0
- package/src/components/select/index.ts +1 -0
- package/src/components/select/select.stories.tsx +207 -0
- package/src/components/select/select.tsx +220 -0
- package/src/components/skeleton/index.ts +1 -0
- package/src/components/skeleton/skeleton.stories.tsx +178 -0
- package/src/components/skeleton/skeleton.tsx +14 -0
- package/src/components/table/data-table.tsx +254 -0
- package/src/components/table/index.ts +5 -0
- package/src/components/table/table-column-header.tsx +141 -0
- package/src/components/table/table-pagination.tsx +161 -0
- package/src/components/table/table.stories.columns.tsx +198 -0
- package/src/components/table/table.stories.components.tsx +104 -0
- package/src/components/table/table.stories.data.ts +117 -0
- package/src/components/table/table.stories.tsx +256 -0
- package/src/components/table/table.tsx +95 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {useState} from 'react';
|
|
3
|
+
import {Icon} from '../icon';
|
|
4
|
+
import {
|
|
5
|
+
Search,
|
|
6
|
+
SearchContent,
|
|
7
|
+
SearchEmpty,
|
|
8
|
+
SearchFooter,
|
|
9
|
+
SearchGroup,
|
|
10
|
+
SearchInline,
|
|
11
|
+
SearchInput,
|
|
12
|
+
SearchItem,
|
|
13
|
+
SearchList,
|
|
14
|
+
SearchSeparator,
|
|
15
|
+
SearchTrigger,
|
|
16
|
+
} from './index';
|
|
17
|
+
|
|
18
|
+
const meta: Meta = {
|
|
19
|
+
title: 'Components/Search',
|
|
20
|
+
tags: ['autodocs'],
|
|
21
|
+
parameters: {
|
|
22
|
+
docs: {
|
|
23
|
+
description: {
|
|
24
|
+
component:
|
|
25
|
+
'A search component with two types: inline (input-style) and modal (trigger + overlay). Supports primary/secondary variants, base/small sizes, and squared/rounded radius options.',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default meta;
|
|
32
|
+
|
|
33
|
+
type Story = StoryObj;
|
|
34
|
+
|
|
35
|
+
export const Inline: Story = {
|
|
36
|
+
render: () => {
|
|
37
|
+
function InlineDemo() {
|
|
38
|
+
const [value, setValue] = useState('');
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className="flex flex-col gap-16 max-w-400">
|
|
42
|
+
<SearchInline
|
|
43
|
+
placeholder="Search..."
|
|
44
|
+
value={value}
|
|
45
|
+
onChange={(e) => setValue(e.target.value)}
|
|
46
|
+
onClear={() => setValue('')}
|
|
47
|
+
/>
|
|
48
|
+
{value && (
|
|
49
|
+
<p className="text-sm text-foreground-neutral-muted">Searching for: "{value}"</p>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return <InlineDemo />;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const InlineVariants: Story = {
|
|
59
|
+
render: () => (
|
|
60
|
+
<div className="flex flex-col gap-16">
|
|
61
|
+
<div className="flex flex-col gap-8">
|
|
62
|
+
<span className="text-xs text-foreground-neutral-muted">Primary (default)</span>
|
|
63
|
+
<div className="flex gap-8">
|
|
64
|
+
<SearchInline
|
|
65
|
+
variant="primary"
|
|
66
|
+
radius="squared"
|
|
67
|
+
placeholder="Search..."
|
|
68
|
+
defaultValue="random"
|
|
69
|
+
className="w-200"
|
|
70
|
+
/>
|
|
71
|
+
<SearchInline
|
|
72
|
+
variant="primary"
|
|
73
|
+
radius="rounded"
|
|
74
|
+
placeholder="Search..."
|
|
75
|
+
defaultValue="random"
|
|
76
|
+
className="w-200"
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div className="flex flex-col gap-8">
|
|
81
|
+
<span className="text-xs text-foreground-neutral-muted">Secondary</span>
|
|
82
|
+
<div className="flex gap-8">
|
|
83
|
+
<SearchInline
|
|
84
|
+
variant="secondary"
|
|
85
|
+
radius="squared"
|
|
86
|
+
placeholder="Search..."
|
|
87
|
+
defaultValue="random"
|
|
88
|
+
className="w-200"
|
|
89
|
+
/>
|
|
90
|
+
<SearchInline
|
|
91
|
+
variant="secondary"
|
|
92
|
+
radius="rounded"
|
|
93
|
+
placeholder="Search..."
|
|
94
|
+
defaultValue="random"
|
|
95
|
+
className="w-200"
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const InlineSizes: Story = {
|
|
104
|
+
render: () => (
|
|
105
|
+
<div className="flex flex-col gap-16">
|
|
106
|
+
<div className="flex flex-col gap-8">
|
|
107
|
+
<span className="text-xs text-foreground-neutral-muted">Base (32px)</span>
|
|
108
|
+
<div className="flex gap-8">
|
|
109
|
+
<SearchInline
|
|
110
|
+
size="base"
|
|
111
|
+
placeholder="Search..."
|
|
112
|
+
defaultValue="random"
|
|
113
|
+
className="w-200"
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div className="flex flex-col gap-8">
|
|
118
|
+
<span className="text-xs text-foreground-neutral-muted">Small (28px)</span>
|
|
119
|
+
<div className="flex gap-8">
|
|
120
|
+
<SearchInline
|
|
121
|
+
size="small"
|
|
122
|
+
placeholder="Search..."
|
|
123
|
+
defaultValue="random"
|
|
124
|
+
className="w-200"
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
function ModalSearchDemo() {
|
|
133
|
+
const [open, setOpen] = useState(false);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<Search open={open} onOpenChange={setOpen} shortcutKey="meta+k">
|
|
137
|
+
<SearchTrigger placeholder="Find..." className="w-full max-w-280" />
|
|
138
|
+
<SearchContent aria-describedby={undefined}>
|
|
139
|
+
<SearchInput placeholder="Search for anything..." />
|
|
140
|
+
<SearchList>
|
|
141
|
+
<SearchEmpty>No results found.</SearchEmpty>
|
|
142
|
+
<SearchGroup heading="Recent">
|
|
143
|
+
<SearchItem
|
|
144
|
+
icon={
|
|
145
|
+
<Icon name="gitBranchLine" className="size-16 text-foreground-neutral-subtle" />
|
|
146
|
+
}
|
|
147
|
+
description="qr-attendance"
|
|
148
|
+
>
|
|
149
|
+
feat/data-processing
|
|
150
|
+
</SearchItem>
|
|
151
|
+
<SearchItem
|
|
152
|
+
icon={
|
|
153
|
+
<Icon name="gitBranchLine" className="size-16 text-foreground-neutral-subtle" />
|
|
154
|
+
}
|
|
155
|
+
description="qr-attendance"
|
|
156
|
+
>
|
|
157
|
+
feat/pagination-polling
|
|
158
|
+
</SearchItem>
|
|
159
|
+
</SearchGroup>
|
|
160
|
+
<SearchSeparator />
|
|
161
|
+
<SearchGroup heading="Team">
|
|
162
|
+
<SearchItem
|
|
163
|
+
icon={<Icon name="rocketLine" className="size-16 text-foreground-neutral-subtle" />}
|
|
164
|
+
description="Team"
|
|
165
|
+
>
|
|
166
|
+
Deployments
|
|
167
|
+
</SearchItem>
|
|
168
|
+
<SearchItem
|
|
169
|
+
icon={<Icon name="linksLine" className="size-16 text-foreground-neutral-subtle" />}
|
|
170
|
+
description="Team"
|
|
171
|
+
>
|
|
172
|
+
Integrations
|
|
173
|
+
</SearchItem>
|
|
174
|
+
</SearchGroup>
|
|
175
|
+
</SearchList>
|
|
176
|
+
<SearchFooter />
|
|
177
|
+
</SearchContent>
|
|
178
|
+
</Search>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const Modal: Story = {
|
|
183
|
+
render: () => <ModalSearchDemo />,
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
function TriggerPreview({
|
|
187
|
+
variant,
|
|
188
|
+
size,
|
|
189
|
+
radius,
|
|
190
|
+
className,
|
|
191
|
+
}: {
|
|
192
|
+
variant?: 'primary' | 'secondary';
|
|
193
|
+
size?: 'base' | 'small';
|
|
194
|
+
radius?: 'squared' | 'rounded';
|
|
195
|
+
className?: string;
|
|
196
|
+
}) {
|
|
197
|
+
return (
|
|
198
|
+
<Search>
|
|
199
|
+
<SearchTrigger variant={variant} size={size} radius={radius} className={className} />
|
|
200
|
+
</Search>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export const ModalTriggerVariants: Story = {
|
|
205
|
+
render: () => (
|
|
206
|
+
<div className="flex flex-col gap-16">
|
|
207
|
+
<div className="flex flex-col gap-8">
|
|
208
|
+
<span className="text-xs text-foreground-neutral-muted">Primary (default)</span>
|
|
209
|
+
<div className="flex gap-8">
|
|
210
|
+
<TriggerPreview variant="primary" radius="squared" className="w-200" />
|
|
211
|
+
<TriggerPreview variant="primary" radius="rounded" className="w-200" />
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
<div className="flex flex-col gap-8">
|
|
215
|
+
<span className="text-xs text-foreground-neutral-muted">Secondary</span>
|
|
216
|
+
<div className="flex gap-8">
|
|
217
|
+
<TriggerPreview variant="secondary" radius="squared" className="w-200" />
|
|
218
|
+
<TriggerPreview variant="secondary" radius="rounded" className="w-200" />
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
),
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export const ModalTriggerSizes: Story = {
|
|
226
|
+
render: () => (
|
|
227
|
+
<div className="flex flex-col gap-16">
|
|
228
|
+
<div className="flex flex-col gap-8">
|
|
229
|
+
<span className="text-xs text-foreground-neutral-muted">Base (32px)</span>
|
|
230
|
+
<div className="flex gap-8">
|
|
231
|
+
<TriggerPreview size="base" variant="primary" className="w-200" />
|
|
232
|
+
<TriggerPreview size="base" variant="secondary" className="w-200" />
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
<div className="flex flex-col gap-8">
|
|
236
|
+
<span className="text-xs text-foreground-neutral-muted">Small (28px)</span>
|
|
237
|
+
<div className="flex gap-8">
|
|
238
|
+
<TriggerPreview size="small" variant="primary" className="w-200" />
|
|
239
|
+
<TriggerPreview size="small" variant="secondary" className="w-200" />
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
),
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export const AllCombinations: Story = {
|
|
247
|
+
render: () => (
|
|
248
|
+
<div className="flex flex-col gap-24">
|
|
249
|
+
<div>
|
|
250
|
+
<h3 className="text-sm font-medium text-foreground-neutral-base mb-12">Inline Search</h3>
|
|
251
|
+
<div className="grid grid-cols-4 gap-12">
|
|
252
|
+
<div className="flex flex-col gap-4">
|
|
253
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Squared / Base</span>
|
|
254
|
+
<SearchInline
|
|
255
|
+
variant="primary"
|
|
256
|
+
radius="squared"
|
|
257
|
+
size="base"
|
|
258
|
+
placeholder="Search..."
|
|
259
|
+
className="w-full"
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
<div className="flex flex-col gap-4">
|
|
263
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Squared / Small</span>
|
|
264
|
+
<SearchInline
|
|
265
|
+
variant="primary"
|
|
266
|
+
radius="squared"
|
|
267
|
+
size="small"
|
|
268
|
+
placeholder="Search..."
|
|
269
|
+
className="w-full"
|
|
270
|
+
/>
|
|
271
|
+
</div>
|
|
272
|
+
<div className="flex flex-col gap-4">
|
|
273
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Rounded / Base</span>
|
|
274
|
+
<SearchInline
|
|
275
|
+
variant="primary"
|
|
276
|
+
radius="rounded"
|
|
277
|
+
size="base"
|
|
278
|
+
placeholder="Search..."
|
|
279
|
+
className="w-full"
|
|
280
|
+
/>
|
|
281
|
+
</div>
|
|
282
|
+
<div className="flex flex-col gap-4">
|
|
283
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Rounded / Small</span>
|
|
284
|
+
<SearchInline
|
|
285
|
+
variant="primary"
|
|
286
|
+
radius="rounded"
|
|
287
|
+
size="small"
|
|
288
|
+
placeholder="Search..."
|
|
289
|
+
className="w-full"
|
|
290
|
+
/>
|
|
291
|
+
</div>
|
|
292
|
+
<div className="flex flex-col gap-4">
|
|
293
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
294
|
+
Secondary / Squared / Base
|
|
295
|
+
</span>
|
|
296
|
+
<SearchInline
|
|
297
|
+
variant="secondary"
|
|
298
|
+
radius="squared"
|
|
299
|
+
size="base"
|
|
300
|
+
placeholder="Search..."
|
|
301
|
+
className="w-full"
|
|
302
|
+
/>
|
|
303
|
+
</div>
|
|
304
|
+
<div className="flex flex-col gap-4">
|
|
305
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
306
|
+
Secondary / Squared / Small
|
|
307
|
+
</span>
|
|
308
|
+
<SearchInline
|
|
309
|
+
variant="secondary"
|
|
310
|
+
radius="squared"
|
|
311
|
+
size="small"
|
|
312
|
+
placeholder="Search..."
|
|
313
|
+
className="w-full"
|
|
314
|
+
/>
|
|
315
|
+
</div>
|
|
316
|
+
<div className="flex flex-col gap-4">
|
|
317
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
318
|
+
Secondary / Rounded / Base
|
|
319
|
+
</span>
|
|
320
|
+
<SearchInline
|
|
321
|
+
variant="secondary"
|
|
322
|
+
radius="rounded"
|
|
323
|
+
size="base"
|
|
324
|
+
placeholder="Search..."
|
|
325
|
+
className="w-full"
|
|
326
|
+
/>
|
|
327
|
+
</div>
|
|
328
|
+
<div className="flex flex-col gap-4">
|
|
329
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
330
|
+
Secondary / Rounded / Small
|
|
331
|
+
</span>
|
|
332
|
+
<SearchInline
|
|
333
|
+
variant="secondary"
|
|
334
|
+
radius="rounded"
|
|
335
|
+
size="small"
|
|
336
|
+
placeholder="Search..."
|
|
337
|
+
className="w-full"
|
|
338
|
+
/>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div>
|
|
344
|
+
<h3 className="text-sm font-medium text-foreground-neutral-base mb-12">
|
|
345
|
+
Modal Search Triggers
|
|
346
|
+
</h3>
|
|
347
|
+
<div className="grid grid-cols-4 gap-12">
|
|
348
|
+
<div className="flex flex-col gap-4">
|
|
349
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Squared / Base</span>
|
|
350
|
+
<TriggerPreview variant="primary" radius="squared" size="base" className="w-full" />
|
|
351
|
+
</div>
|
|
352
|
+
<div className="flex flex-col gap-4">
|
|
353
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Squared / Small</span>
|
|
354
|
+
<TriggerPreview variant="primary" radius="squared" size="small" className="w-full" />
|
|
355
|
+
</div>
|
|
356
|
+
<div className="flex flex-col gap-4">
|
|
357
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Rounded / Base</span>
|
|
358
|
+
<TriggerPreview variant="primary" radius="rounded" size="base" className="w-full" />
|
|
359
|
+
</div>
|
|
360
|
+
<div className="flex flex-col gap-4">
|
|
361
|
+
<span className="text-xs text-foreground-neutral-muted">Primary / Rounded / Small</span>
|
|
362
|
+
<TriggerPreview variant="primary" radius="rounded" size="small" className="w-full" />
|
|
363
|
+
</div>
|
|
364
|
+
<div className="flex flex-col gap-4">
|
|
365
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
366
|
+
Secondary / Squared / Base
|
|
367
|
+
</span>
|
|
368
|
+
<TriggerPreview variant="secondary" radius="squared" size="base" className="w-full" />
|
|
369
|
+
</div>
|
|
370
|
+
<div className="flex flex-col gap-4">
|
|
371
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
372
|
+
Secondary / Squared / Small
|
|
373
|
+
</span>
|
|
374
|
+
<TriggerPreview variant="secondary" radius="squared" size="small" className="w-full" />
|
|
375
|
+
</div>
|
|
376
|
+
<div className="flex flex-col gap-4">
|
|
377
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
378
|
+
Secondary / Rounded / Base
|
|
379
|
+
</span>
|
|
380
|
+
<TriggerPreview variant="secondary" radius="rounded" size="base" className="w-full" />
|
|
381
|
+
</div>
|
|
382
|
+
<div className="flex flex-col gap-4">
|
|
383
|
+
<span className="text-xs text-foreground-neutral-muted">
|
|
384
|
+
Secondary / Rounded / Small
|
|
385
|
+
</span>
|
|
386
|
+
<TriggerPreview variant="secondary" radius="rounded" size="small" className="w-full" />
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
),
|
|
392
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {Command as CommandPrimitive} from 'cmdk';
|
|
2
|
+
import type {ReactNode} from 'react';
|
|
3
|
+
import {useCallback, useState} from 'react';
|
|
4
|
+
import {SearchContext, useControllableState, useKeyboardShortcut} from './search-context';
|
|
5
|
+
|
|
6
|
+
export type SearchProps = {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
open?: boolean;
|
|
9
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
|
+
defaultOpen?: boolean;
|
|
11
|
+
shortcutKey?: string;
|
|
12
|
+
shouldFilter?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function Search({
|
|
16
|
+
children,
|
|
17
|
+
open: controlledOpen,
|
|
18
|
+
onOpenChange,
|
|
19
|
+
defaultOpen = false,
|
|
20
|
+
shortcutKey,
|
|
21
|
+
shouldFilter = true,
|
|
22
|
+
}: SearchProps) {
|
|
23
|
+
const [open, setOpen] = useControllableState(controlledOpen, defaultOpen, onOpenChange);
|
|
24
|
+
const [searchValue, setSearchValue] = useState('');
|
|
25
|
+
|
|
26
|
+
const handleOpen = useCallback(() => setOpen(true), [setOpen]);
|
|
27
|
+
|
|
28
|
+
useKeyboardShortcut(shortcutKey, handleOpen);
|
|
29
|
+
|
|
30
|
+
const handleSetOpen = useCallback(
|
|
31
|
+
(newOpen: boolean) => {
|
|
32
|
+
if (!newOpen) {
|
|
33
|
+
setSearchValue('');
|
|
34
|
+
}
|
|
35
|
+
setOpen(newOpen);
|
|
36
|
+
},
|
|
37
|
+
[setOpen],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<SearchContext.Provider value={{open, setOpen: handleSetOpen, searchValue, setSearchValue}}>
|
|
42
|
+
<CommandPrimitive data-slot="search" shouldFilter={shouldFilter}>
|
|
43
|
+
{children}
|
|
44
|
+
</CommandPrimitive>
|
|
45
|
+
</SearchContext.Provider>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './select';
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {Kbd} from '../kbd';
|
|
3
|
+
import {
|
|
4
|
+
Select,
|
|
5
|
+
SelectContent,
|
|
6
|
+
SelectGroup,
|
|
7
|
+
SelectItem,
|
|
8
|
+
SelectLabel,
|
|
9
|
+
SelectSeparator,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from './select';
|
|
13
|
+
|
|
14
|
+
const meta = {
|
|
15
|
+
title: 'Components/Select',
|
|
16
|
+
component: Select,
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
} satisfies Meta<typeof Select>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<Select>
|
|
27
|
+
<SelectTrigger className="w-200">
|
|
28
|
+
<SelectValue placeholder="Select an option" />
|
|
29
|
+
</SelectTrigger>
|
|
30
|
+
<SelectContent>
|
|
31
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
32
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
33
|
+
<SelectItem value="option3">Option 3</SelectItem>
|
|
34
|
+
</SelectContent>
|
|
35
|
+
</Select>
|
|
36
|
+
),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const WithGroups: Story = {
|
|
40
|
+
render: () => (
|
|
41
|
+
<Select defaultValue="typescript">
|
|
42
|
+
<SelectTrigger className="w-280">
|
|
43
|
+
<SelectValue placeholder="Select a technology" />
|
|
44
|
+
</SelectTrigger>
|
|
45
|
+
<SelectContent>
|
|
46
|
+
<SelectGroup>
|
|
47
|
+
<SelectLabel>Frontend</SelectLabel>
|
|
48
|
+
<SelectItem value="react">React</SelectItem>
|
|
49
|
+
<SelectItem value="vue">Vue</SelectItem>
|
|
50
|
+
<SelectItem value="angular">Angular</SelectItem>
|
|
51
|
+
<SelectItem value="svelte">Svelte</SelectItem>
|
|
52
|
+
</SelectGroup>
|
|
53
|
+
<SelectSeparator />
|
|
54
|
+
<SelectGroup>
|
|
55
|
+
<SelectLabel>Backend</SelectLabel>
|
|
56
|
+
<SelectItem value="nodejs">Node.js</SelectItem>
|
|
57
|
+
<SelectItem value="python">Python</SelectItem>
|
|
58
|
+
<SelectItem value="ruby">Ruby</SelectItem>
|
|
59
|
+
<SelectItem value="go">Go</SelectItem>
|
|
60
|
+
</SelectGroup>
|
|
61
|
+
<SelectSeparator />
|
|
62
|
+
<SelectGroup>
|
|
63
|
+
<SelectLabel>Languages</SelectLabel>
|
|
64
|
+
<SelectItem value="typescript">TypeScript</SelectItem>
|
|
65
|
+
<SelectItem value="javascript">JavaScript</SelectItem>
|
|
66
|
+
<SelectItem value="rust">Rust</SelectItem>
|
|
67
|
+
</SelectGroup>
|
|
68
|
+
</SelectContent>
|
|
69
|
+
</Select>
|
|
70
|
+
),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const WithIcons: Story = {
|
|
74
|
+
render: () => (
|
|
75
|
+
<div className="flex flex-col gap-12">
|
|
76
|
+
<Select defaultValue="active">
|
|
77
|
+
<SelectTrigger className="w-200">
|
|
78
|
+
<SelectValue placeholder="Select status" />
|
|
79
|
+
</SelectTrigger>
|
|
80
|
+
<SelectContent>
|
|
81
|
+
<SelectItem value="active" icon="checkboxCircleLine">
|
|
82
|
+
Active
|
|
83
|
+
</SelectItem>
|
|
84
|
+
<SelectItem value="pending" icon="timeLine">
|
|
85
|
+
Pending
|
|
86
|
+
</SelectItem>
|
|
87
|
+
<SelectItem value="inactive" icon="closeLine">
|
|
88
|
+
Inactive
|
|
89
|
+
</SelectItem>
|
|
90
|
+
</SelectContent>
|
|
91
|
+
</Select>
|
|
92
|
+
|
|
93
|
+
<Select defaultValue="medium">
|
|
94
|
+
<SelectTrigger className="w-200">
|
|
95
|
+
<SelectValue placeholder="Select priority" />
|
|
96
|
+
</SelectTrigger>
|
|
97
|
+
<SelectContent>
|
|
98
|
+
<SelectItem value="high" icon="arrowUpLine">
|
|
99
|
+
High
|
|
100
|
+
</SelectItem>
|
|
101
|
+
<SelectItem value="medium" icon="equalLine">
|
|
102
|
+
Medium
|
|
103
|
+
</SelectItem>
|
|
104
|
+
<SelectItem value="low" icon="arrowDownLine">
|
|
105
|
+
Low
|
|
106
|
+
</SelectItem>
|
|
107
|
+
</SelectContent>
|
|
108
|
+
</Select>
|
|
109
|
+
</div>
|
|
110
|
+
),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const Sizes: Story = {
|
|
114
|
+
render: () => (
|
|
115
|
+
<div className="flex flex-col gap-12">
|
|
116
|
+
<Select>
|
|
117
|
+
<SelectTrigger size="small" className="w-200">
|
|
118
|
+
<SelectValue placeholder="Small" />
|
|
119
|
+
</SelectTrigger>
|
|
120
|
+
<SelectContent>
|
|
121
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
122
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
123
|
+
</SelectContent>
|
|
124
|
+
</Select>
|
|
125
|
+
|
|
126
|
+
<Select>
|
|
127
|
+
<SelectTrigger size="base" className="w-200">
|
|
128
|
+
<SelectValue placeholder="Base (default)" />
|
|
129
|
+
</SelectTrigger>
|
|
130
|
+
<SelectContent>
|
|
131
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
132
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
133
|
+
</SelectContent>
|
|
134
|
+
</Select>
|
|
135
|
+
</div>
|
|
136
|
+
),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const Variants: Story = {
|
|
140
|
+
render: () => (
|
|
141
|
+
<div className="flex flex-col gap-12">
|
|
142
|
+
<Select>
|
|
143
|
+
<SelectTrigger variant="base" className="w-200">
|
|
144
|
+
<SelectValue placeholder="Base variant" />
|
|
145
|
+
</SelectTrigger>
|
|
146
|
+
<SelectContent>
|
|
147
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
148
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
149
|
+
</SelectContent>
|
|
150
|
+
</Select>
|
|
151
|
+
|
|
152
|
+
<Select>
|
|
153
|
+
<SelectTrigger variant="component" className="w-200">
|
|
154
|
+
<SelectValue placeholder="Component variant" />
|
|
155
|
+
</SelectTrigger>
|
|
156
|
+
<SelectContent>
|
|
157
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
158
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
159
|
+
</SelectContent>
|
|
160
|
+
</Select>
|
|
161
|
+
</div>
|
|
162
|
+
),
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const TimeSelector: Story = {
|
|
166
|
+
render: () => (
|
|
167
|
+
<Select defaultValue="2days">
|
|
168
|
+
<SelectTrigger className="w-280">
|
|
169
|
+
<div className="flex items-center gap-8 flex-1 min-w-0">
|
|
170
|
+
<SelectValue placeholder="Select time range" />
|
|
171
|
+
</div>
|
|
172
|
+
</SelectTrigger>
|
|
173
|
+
<SelectContent>
|
|
174
|
+
<SelectItem value="1hour">
|
|
175
|
+
<div className="flex items-center gap-8">
|
|
176
|
+
<Kbd className="h-16">1h</Kbd>
|
|
177
|
+
<span>Past 1 Hour</span>
|
|
178
|
+
</div>
|
|
179
|
+
</SelectItem>
|
|
180
|
+
<SelectItem value="1day">
|
|
181
|
+
<div className="flex items-center gap-8">
|
|
182
|
+
<Kbd className="h-16">1d</Kbd>
|
|
183
|
+
<span>Past 1 Day</span>
|
|
184
|
+
</div>
|
|
185
|
+
</SelectItem>
|
|
186
|
+
<SelectItem value="2days">
|
|
187
|
+
<div className="flex items-center gap-8">
|
|
188
|
+
<Kbd className="h-16">2d</Kbd>
|
|
189
|
+
<span>Past 2 Days</span>
|
|
190
|
+
</div>
|
|
191
|
+
</SelectItem>
|
|
192
|
+
<SelectItem value="7days">
|
|
193
|
+
<div className="flex items-center gap-8">
|
|
194
|
+
<Kbd className="h-16">7d</Kbd>
|
|
195
|
+
<span>Past 7 Days</span>
|
|
196
|
+
</div>
|
|
197
|
+
</SelectItem>
|
|
198
|
+
<SelectItem value="30days">
|
|
199
|
+
<div className="flex items-center gap-8">
|
|
200
|
+
<Kbd className="h-16">30d</Kbd>
|
|
201
|
+
<span>Past 30 Days</span>
|
|
202
|
+
</div>
|
|
203
|
+
</SelectItem>
|
|
204
|
+
</SelectContent>
|
|
205
|
+
</Select>
|
|
206
|
+
),
|
|
207
|
+
};
|