Skip to content

Commit 8ff53fb

Browse files
authored
Merge pull request #622 from vhrmo/storybook
Enhancement(Add Storybook)
2 parents 2c00ff4 + 05cf085 commit 8ff53fb

File tree

13 files changed

+488
-18
lines changed

13 files changed

+488
-18
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ node_modules/
2828
# Ignore lock
2929
yarn.lock
3030

31-
#dist/
31+
#dist/
32+
*storybook.log

.storybook/main.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { StorybookConfig } from '@storybook/html-vite';
2+
3+
const config: StorybookConfig = {
4+
"stories": [
5+
"../components/**/*.mdx",
6+
"../components/**/*.stories.@(js|jsx|mjs|ts|tsx)",
7+
],
8+
"addons": [
9+
{
10+
name: '@storybook/addon-essentials',
11+
options: {
12+
backgrounds: false, // 👈 disable the backgrounds addon to avoid confusing it with themes
13+
},
14+
},
15+
"@storybook/addon-interactions",
16+
"@storybook/addon-themes"
17+
],
18+
"framework": {
19+
"name": "@storybook/html-vite",
20+
"options": {}
21+
}
22+
};
23+
export default config;

.storybook/material-icons.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@import '@fontsource/material-icons';
2+
3+
/* Font source only provides @font-face, so we need this class definition here */
4+
.material-icons {
5+
font-family: 'Material Icons';
6+
font-weight: normal;
7+
font-style: normal;
8+
font-size: 24px;
9+
line-height: 1;
10+
letter-spacing: normal;
11+
text-transform: none;
12+
display: inline-block;
13+
white-space: nowrap;
14+
word-wrap: normal;
15+
direction: ltr;
16+
-webkit-font-feature-settings: 'liga';
17+
-webkit-font-smoothing: antialiased;
18+
}

.storybook/preview.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { Preview } from '@storybook/html'
2+
import { withThemeByDataAttribute } from '@storybook/addon-themes';
3+
4+
import './material-icons.css';
5+
import '../sass/materialize.scss';
6+
7+
const preview: Preview = {
8+
decorators: [
9+
// Decorator to be able to switch between light and dark themes
10+
withThemeByDataAttribute({
11+
themes: {
12+
light: 'light',
13+
dark: 'dark',
14+
},
15+
defaultTheme: 'light',
16+
attributeName: 'theme',
17+
}),
18+
],
19+
parameters: {
20+
docs: {
21+
toc: true, // Enables the table of contents in auto generated docs
22+
},
23+
actions: {argTypesRegex: "^on[A-Z].*"},
24+
controls: {
25+
matchers: {
26+
color: /(background|color)$/i,
27+
date: /Date$/i,
28+
},
29+
},
30+
},
31+
};
32+
33+
export default preview;

components/buttons/_buttons.scss

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
@use '../../sass/mixins.module.scss' as *;
22
@use '../../sass/variables' as *;
33

4-
:root {
5-
--btn-height: 40px;
6-
--btn-font-size-icon: 16px;
7-
--btn-padding: 24px;
8-
--btn-padding-icon: 16px;
9-
--btn-gap-icon: 8px;
10-
--btn-border-radius: 4px;
11-
--btn-font-size: 14px;
4+
@at-root {
5+
:root {
6+
--btn-height: 40px;
7+
--btn-font-size-icon: 16px;
8+
--btn-padding: 24px;
9+
--btn-padding-icon: 16px;
10+
--btn-gap-icon: 8px;
11+
--btn-border-radius: 4px;
12+
--btn-font-size: 14px;
13+
}
1214
}
1315

1416
.btn, .btn-floating, .btn-large, .btn-small, .btn-flat {
@@ -88,6 +90,7 @@
8890
// padding: 16px !important;
8991
// padding-right: 24px !important; /* only with icon */
9092
// gap: 8px;
93+
@extend .btn;
9194
width: $button-floating-size;
9295
height: $button-floating-size;
9396
color: var(--md-sys-color-on-primary-container);
@@ -104,6 +107,7 @@
104107
transition: background-color .3s;
105108
cursor: pointer;
106109
vertical-align: middle;
110+
text-align: center;
107111

108112
&:hover {
109113
@extend .z-depth-1-half;
@@ -157,7 +161,7 @@
157161
}
158162

159163
i {
160-
color: $button-floating-color;
164+
color: currentColor;
161165
font-size: 1.6rem;
162166
width: inherit;
163167
display: inline-block;

components/buttons/buttons.stories.ts

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import type { Meta, StoryObj } from '@storybook/html';
2+
3+
export default {
4+
title: 'Components/Buttons',
5+
6+
} satisfies Meta;
7+
8+
9+
const BTN_SIZES = {
10+
'Small': ['btn-small'],
11+
'Small disabled': ['btn-small', 'disabled'],
12+
'Normal': [],
13+
'Normal disabled': ['disabled'],
14+
'Large': ['btn-large'],
15+
'Large disabled': ['btn-large', 'disabled'],
16+
};
17+
18+
const BTN_STYLES = {
19+
'Default': [], // uncomment this to see the default button when no filled/tonal/outlined/text is set
20+
'Filled': ['filled'],
21+
'Tonal': ['tonal'],
22+
'Outlined': ['outlined'],
23+
'Text': ['text']
24+
};
25+
26+
27+
export const Basic: StoryObj = {
28+
render(args) {
29+
const table = document.createElement('table');
30+
const headerRow = table.insertRow();
31+
headerRow.insertCell();
32+
for (const size in BTN_SIZES) {
33+
const cell = headerRow.insertCell();
34+
cell.innerText = size;
35+
}
36+
for (const btnStype in BTN_STYLES) {
37+
const row = table.insertRow();
38+
const cell = row.insertCell();
39+
cell.innerText = btnStype;
40+
for (const size in BTN_SIZES) {
41+
const cell = row.insertCell();
42+
const classes = [...BTN_STYLES[btnStype], ...BTN_SIZES[size], ...args.classes?? [] ];
43+
const disabled = classes.includes('disabled') ? 'disabled="disabled"' : '';
44+
let iconHtml = '';
45+
if (args.icon) {
46+
iconHtml = `<i class="material-icons">${args.icon}</i>`;
47+
} else if (args.iconLeft) {
48+
classes.push('icon-left');
49+
iconHtml = `<i class="material-icons">${args.iconLeft}</i>`;
50+
} else if (args.iconRight) {
51+
classes.push('icon-right');
52+
iconHtml = `<i class="material-icons">${args.iconRight}</i>`;
53+
}
54+
// TODO - why is anchor tag used in docs rather than button tag?
55+
cell.innerHTML = `
56+
<button ${disabled} class="${classes.join(' ')}">
57+
${args.label}${iconHtml}
58+
</button>
59+
`;
60+
}
61+
}
62+
return table;
63+
},
64+
args: {
65+
label: 'Button',
66+
classes: ['btn']
67+
}
68+
};
69+
70+
export const Elevated: StoryObj = {
71+
...Basic,
72+
args: {
73+
label: 'Button',
74+
classes: ['btn', 'elevated']
75+
}
76+
};
77+
78+
export const FloatingWithText: StoryObj = {
79+
...Basic,
80+
args: {
81+
label: 'B',
82+
classes: ['btn-floating']
83+
}
84+
};
85+
86+
export const FloatingWithIcon: StoryObj = {
87+
...Basic,
88+
args: {
89+
label: '',
90+
icon: 'edit',
91+
classes: ['btn-floating']
92+
}
93+
};
94+
95+
export const IconLeft: StoryObj = {
96+
...Basic,
97+
args: {
98+
label: 'Button',
99+
iconLeft: 'cloud',
100+
classes: ['btn']
101+
}
102+
};
103+
104+
export const IconRight: StoryObj = {
105+
...Basic,
106+
args: {
107+
label: 'Submit',
108+
iconRight: 'send',
109+
classes: ['btn']
110+
111+
}
112+
};
113+
114+
115+
export const FloatingActionButton: StoryObj = {
116+
render() {
117+
return `
118+
<div class="fixed-action-btn">
119+
<a class="btn-floating btn-large red">
120+
<i class="large material-icons">mode_edit</i>
121+
</a>
122+
<ul>
123+
<li><a class="btn-floating red"><i class="material-icons">insert_chart</i></a></li>
124+
<li><a class="btn-floating yellow darken-1"><i class="material-icons">format_quote</i></a></li>
125+
<li><a class="btn-floating green"><i class="material-icons">publish</i></a></li>
126+
<li><a class="btn-floating blue"><i class="material-icons">attach_file</i></a></li>
127+
</ul>
128+
</div>
129+
130+
<div class="fixed-action-btn horizontal">
131+
<a class="btn-floating btn-large red">
132+
<i class="large material-icons">mode_edit</i>
133+
</a>
134+
<ul>
135+
<li><a class="btn-floating red"><i class="material-icons">insert_chart</i></a></li>
136+
<li><a class="btn-floating yellow darken-1"><i class="material-icons">format_quote</i></a></li>
137+
<li><a class="btn-floating green"><i class="material-icons">publish</i></a></li>
138+
<li><a class="btn-floating blue"><i class="material-icons">attach_file</i></a></li>
139+
</ul>
140+
</div>
141+
142+
<div class="fixed-action-btn click-to-toggle">
143+
<a class="btn-floating btn-large red">
144+
<i class="large material-icons">mode_edit</i>
145+
</a>
146+
<ul>
147+
<li><a class="btn-floating red"><i class="material-icons">insert_chart</i></a></li>
148+
<li><a class="btn-floating yellow darken-1"><i class="material-icons">format_quote</i></a></li>
149+
<li><a class="btn-floating green"><i class="material-icons">publish</i></a></li>
150+
<li><a class="btn-floating blue"><i class="material-icons">attach_file</i></a></li>
151+
</ul>
152+
</div>
153+
`;
154+
},
155+
}

components/checkbox/checkbox.mdx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {Story, Meta, Source, Controls, Markdown, Primary} from '@storybook/blocks';
2+
3+
import * as stories from './checkbox.stories';
4+
5+
<Meta of={stories}/>
6+
7+
# Checkboxes
8+
9+
Use checkboxes when looking for yes or no answers. The `for` attribute is necessary to bind our custom checkbox with the input.
10+
Add the input's `id` as the value of the `for` attribute of the label.
11+
12+
## Default
13+
14+
<Story of={stories.Default} />
15+
<Source of={stories.Default} format="dedent"/>
16+
17+
## Filled-in Checkbox
18+
19+
<Story of={stories.FilledIn} />
20+
<Source of={stories.FilledIn} format="dedent"/>
21+
22+
## Indeterminate Checkbox
23+
24+
<Story of={stories.Indeterminate} />
25+
<Source of={stories.Indeterminate} format="dedent"/>
26+
27+

0 commit comments

Comments
 (0)