Skip to content

Commit b773a30

Browse files
committed
docs(Overview): Add page to preview all components
1 parent cb78c65 commit b773a30

1 file changed

Lines changed: 252 additions & 0 deletions

File tree

docs/src/overview.stories.tsx

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import { useState } from "react"
2+
3+
import type { Meta, StoryObj } from "@storybook/react-vite"
4+
import {
5+
Button,
6+
Calendar,
7+
Card,
8+
Checklist,
9+
ContextInfo,
10+
DateInput,
11+
FileInput,
12+
IconButton,
13+
List,
14+
Toggle,
15+
TimeInput,
16+
Spinner,
17+
TextInput,
18+
Masonry,
19+
vstack,
20+
hstack,
21+
TextArea,
22+
HoldButton,
23+
Slider,
24+
} from "boring-blocks"
25+
import {
26+
GripHorizontalIcon,
27+
HelpCircleIcon,
28+
HandGrabIcon,
29+
HandIcon,
30+
} from "boring-blocks/icons"
31+
import { cn } from "boring-blocks/utils"
32+
33+
import { useDarkMode } from "../.storybook/addons/dark-mode"
34+
import { darkMode } from "../.storybook/addons/dark-mode/darkMode"
35+
import { useThemeOptions } from "../.storybook/addons/theme-options"
36+
import { themeOptions } from "../.storybook/addons/theme-options/theme-options"
37+
38+
const meta = { title: "Overview" } satisfies Meta
39+
40+
export default meta
41+
type Story = StoryObj<typeof meta>
42+
43+
const ChecklistCard = () => (
44+
<Card className="p-2 pt-1">
45+
<Checklist
46+
title="ToDos"
47+
onChange={() => null}
48+
items={[
49+
{ id: "1", checked: true, label: "Create components" },
50+
{ id: "2", checked: false, label: "Write documentation" },
51+
{ id: "3", checked: false, label: "Review code" },
52+
]}
53+
/>
54+
</Card>
55+
)
56+
57+
const LoginCard = () => {
58+
const [password, setPassword] = useState("")
59+
return (
60+
<Card title="Login" description="Send me your credentials. Please? :)">
61+
<IconButton
62+
title="Open Help"
63+
icon={HelpCircleIcon}
64+
size="sm"
65+
className="absolute top-1 right-1"
66+
/>
67+
68+
<div className={vstack({ gap: 4 })}>
69+
<TextInput placeholder="Username" />
70+
<TextInput
71+
type="password"
72+
placeholder="Password"
73+
value={password}
74+
onChange={setPassword}
75+
/>
76+
77+
<div className="flex gap-4 *:flex-1">
78+
<Button look="ghost">Cancel</Button>
79+
<Button look="key">Send</Button>
80+
</div>
81+
</div>
82+
</Card>
83+
)
84+
}
85+
86+
const SettingsCard = () => {
87+
const theme = useThemeOptions()
88+
const dark = useDarkMode()
89+
return (
90+
<Card title="Settings" description="Change the colors of components.">
91+
<div className={cn(vstack({ gap: 2 }))}>
92+
<Toggle
93+
label="Dark mode"
94+
checked={dark}
95+
onChange={dark => darkMode.set(dark)}
96+
/>
97+
<Toggle
98+
label="Colored base colors"
99+
checked={theme.colored}
100+
onChange={colored => themeOptions.set(prev => ({ ...prev, colored }))}
101+
/>
102+
<Slider
103+
label="Corner Radius"
104+
unit="px"
105+
value={theme.radius}
106+
onChange={radius => themeOptions.set(prev => ({ ...prev, radius }))}
107+
min={0}
108+
max={16}
109+
/>
110+
<div>
111+
<HoldButton
112+
look="destructive"
113+
onClick={() => {
114+
darkMode.set(darkMode.defaultValue)
115+
themeOptions.set(themeOptions.defaultValue)
116+
}}
117+
captions={{
118+
idle: "Hold to reset",
119+
holding: "About to reset...",
120+
triggered: "Theme was reset",
121+
}}
122+
/>
123+
</div>
124+
</div>
125+
</Card>
126+
)
127+
}
128+
129+
const DataCard = () => (
130+
<Card title="File Upload" description="Upload your files to secure them.">
131+
<FileInput className="w-full" />
132+
<span className="text-xs text-text-muted">
133+
There is no data protection tho...
134+
</span>
135+
</Card>
136+
)
137+
138+
const MeetingCard = () => (
139+
<Card title="Schedule Meeting">
140+
<div className={cn(vstack({ gap: 2 }))}>
141+
<TextInput placeholder="Title" />
142+
<div className={hstack({ gap: 2, align: "center" })}>
143+
<DateInput className="flex-1" />
144+
<TimeInput className="flex-1" />
145+
{" – "}
146+
<TimeInput className="flex-1" />
147+
</div>
148+
<TextArea
149+
placeholder="Description"
150+
autoGrow={{ minLines: 5, maxLines: 10 }}
151+
/>
152+
</div>
153+
</Card>
154+
)
155+
156+
const CalendarCard = () => (
157+
<Card title="Calendar" description="Select a date you like.">
158+
<div className="grid place-items-center">
159+
<Calendar />
160+
</div>
161+
</Card>
162+
)
163+
164+
const SearchCard = () => (
165+
<Card title="Search">
166+
<TextInput
167+
type="search"
168+
placeholder="Search"
169+
value="Bliblablub"
170+
className="mb-4"
171+
/>
172+
<ContextInfo label="No matching data" />
173+
</Card>
174+
)
175+
176+
const Item = ({ name }: { name: string }) => {
177+
const [hold, setHold] = useState(false)
178+
return (
179+
<List.Item>
180+
<IconButton
181+
title="Sort"
182+
hideTitle
183+
onClick={() => null}
184+
icon={GripHorizontalIcon}
185+
iconColor="gentle"
186+
className="cursor-grab active:cursor-grabbing"
187+
/>
188+
<List.Label label={name} />
189+
<List.Action
190+
icon={hold ? HandGrabIcon : HandIcon}
191+
title="Pet"
192+
onClick={() => null}
193+
onPointerDown={() => setHold(true)}
194+
onPointerUp={() => setHold(false)}
195+
/>
196+
</List.Item>
197+
)
198+
}
199+
200+
const TeamCard = () => (
201+
<Card title="My Team">
202+
<List.Group>
203+
{["Banette", "Mimikyu", "Mareanie", "Swanna", "Golduck", "Leafeon"].map(
204+
item => (
205+
<Item key={item} name={item} />
206+
)
207+
)}
208+
</List.Group>
209+
</Card>
210+
)
211+
212+
const LoadingCard = () => (
213+
<Card title="Loading More...">
214+
<Spinner size="xl" centered />
215+
</Card>
216+
)
217+
218+
export const Overview: Story = {
219+
render: () => (
220+
<div className="[*:has(&)]:bg-background-page!">
221+
<Masonry.Grid minColumnWidth={270} gap={16}>
222+
<Masonry.Item>
223+
<ChecklistCard />
224+
</Masonry.Item>
225+
<Masonry.Item>
226+
<LoginCard />
227+
</Masonry.Item>
228+
<Masonry.Item>
229+
<SettingsCard />
230+
</Masonry.Item>
231+
<Masonry.Item>
232+
<DataCard />
233+
</Masonry.Item>
234+
<Masonry.Item>
235+
<MeetingCard />
236+
</Masonry.Item>
237+
<Masonry.Item>
238+
<SearchCard />
239+
</Masonry.Item>
240+
<Masonry.Item>
241+
<CalendarCard />
242+
</Masonry.Item>
243+
<Masonry.Item>
244+
<TeamCard />
245+
</Masonry.Item>
246+
<Masonry.Item>
247+
<LoadingCard />
248+
</Masonry.Item>
249+
</Masonry.Grid>
250+
</div>
251+
),
252+
}

0 commit comments

Comments
 (0)