Skip to content

Commit 9d62a31

Browse files
committed
fix: Lit importmap improvement. Storybook button story.
1 parent 8f20bcd commit 9d62a31

18 files changed

Lines changed: 355 additions & 88 deletions

File tree

components/00-base/03-base/_base.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,14 @@ img.branding__logo {
4949
filter: brightness(0) invert(1);
5050
}
5151
}
52+
53+
// For Storybook
54+
.visually-hidden {
55+
clip: rect(0 0 0 0);
56+
clip-path: inset(50%);
57+
height: 1px;
58+
overflow: hidden;
59+
position: absolute;
60+
white-space: nowrap;
61+
width: 1px;
62+
}

components/01-atoms/button/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ This is the button component.
77

88
This component can be used within Experience Builder and other page builders
99
that support SDC. It can also be added to other components and theme templates.
10+
11+
## Status
12+
13+
Markup is complete. Styles and Storybook documentation are in progress and need to be finalized. Adjust this component to your needs. This component serves as example.
Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
1+
/**
2+
* @file button.scss
3+
* Styles for buttons
4+
*/
15
.button {
6+
--button-padding: 0.7em 1em;
7+
--button-font-size: var(--font-size-2xs, 0.875rem);
8+
--button-inline-gap: var(--space-sm, 8px);
9+
--button-bg: var(--color-button-primary-background, #186cd5);
10+
--button-color: var(--color-button-primary-color, #ffffff);
11+
--button-disabled-bg: var(--color-button-disabled-background, #94A3B8);
212
display: inline-flex;
3-
padding: var(--space-lg, 16px);
13+
min-width: max-content;
14+
max-width: 100%;
15+
padding: var(--button-padding);
416
align-items: center;
5-
gap: var(--space-sm, 8px);
17+
gap: var(--button-inline-gap);
18+
min-width: max-content;
19+
border: 0;
620
border-radius: var(--radius-xs, 3px);
7-
font-size: var(--font-size-3xs, 12px);
21+
font-size: var(--button-font-size);
822
text-transform: uppercase;
923
}
1024
.button--with-badge {
1125
position: relative;
1226
}
27+
.button__text {
28+
flex-shrink: 1;
29+
text-align: center;
30+
white-space: nowrap;
31+
}
32+
.button .button__icon {
33+
flex-shrink: 0;
34+
display: block;
35+
fill: currentColor;
36+
}
1337
.button--primary {
14-
color: var(--color-buttons-button-primary-color, #ffffff);
15-
background: var(--color-buttons-button-primary-background, #186cd5);
38+
color: var(--button-color);
39+
background: var(--button-bg);
1640
}
1741
.button--primary[disabled] {
18-
background: var(--color-buttons-button-disabled-background, #94A3B8);
42+
background: var(--button-disabled-bg);
43+
}
44+
.button--large {
45+
--button-font-size: var(--font-size-xs, 16px);
46+
}
47+
.button--small {
48+
--button-font-size: var(--font-size-3xs, 12px);
1949
}
Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,51 @@
1-
//
2-
// Button component.
3-
//
1+
/**
2+
* @file button.scss
3+
* Styles for buttons
4+
*/
45

56
.button {
6-
$root: &;
7+
8+
--button-padding: 0.7em 1em;
9+
--button-font-size: var(--font-size-2xs, 0.875rem);
10+
--button-inline-gap: var(--space-sm, 8px);
11+
--button-bg: var(--color-button-primary-background, #186cd5);
12+
--button-color: var(--color-button-primary-color, #ffffff);
13+
--button-disabled-bg: var(--color-button-disabled-background, #94A3B8);
714

815
display: inline-flex;
9-
padding: var(--space-lg, 16px);
16+
min-width: max-content;
17+
max-width: 100%;
18+
padding: var(--button-padding);
1019
align-items: center;
11-
gap: var(--space-sm, 8px);
20+
gap: var(--button-inline-gap);
21+
min-width: max-content;
22+
border: 0;
1223
border-radius: var(--radius-xs, 3px);
13-
font-size: var(--font-size-3xs, 12px);
24+
font-size: var(--button-font-size);
1425
text-transform: uppercase;
1526

1627
&--with-badge {
1728
position: relative;
1829
}
1930

31+
&__text {
32+
flex-shrink: 1;
33+
text-align: center;
34+
white-space: nowrap;
35+
}
36+
37+
.button__icon {
38+
flex-shrink: 0;
39+
display: block;
40+
fill: currentColor;
41+
}
42+
2043
&--primary {
21-
color: var(--color-buttons-button-primary-color, #ffffff);
22-
background: var(--color-buttons-button-primary-background, #186cd5);
44+
color: var(--button-color);
45+
background: var(--button-bg);
2346

2447
&[disabled] {
25-
background: var(--color-buttons-button-disabled-background, #94A3B8);
48+
background: var(--button-disabled-bg);
2649
}
2750
}
2851

@@ -32,14 +55,14 @@
3255

3356
// Size.
3457
&--large {
35-
//
58+
--button-font-size: var(--font-size-xs, 16px);
3659
}
3760

3861
&--regular {
3962
//
4063
}
4164

4265
&--small {
43-
//
66+
--button-font-size: var(--font-size-3xs, 12px);
4467
}
4568
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import React from 'react';
2+
import type { Meta, StoryObj } from '@storybook/react';
3+
import {
4+
Title,
5+
Primary,
6+
Controls,
7+
Stories,
8+
Source as StorybookSource,
9+
} from '@storybook/addon-docs/blocks';
10+
11+
import './button.css';
12+
import '../badge/badge.css';
13+
import '../icon/icon.css';
14+
import cssCode from './button.css?raw';
15+
import { getIconHtml } from '../icon/icon.helper';
16+
17+
type ButtonArgs = {
18+
type?: 'primary' | 'secondary' | 'tertiary';
19+
size?: 'small' | 'regular' | 'large';
20+
text: string;
21+
url?: string;
22+
icon?: 'download' | 'right-arrow' | 'heart';
23+
icon_only?: boolean;
24+
icon_placement?: 'before' | 'after';
25+
is_disabled?: boolean;
26+
is_new_window?: boolean;
27+
badge_content?: string;
28+
modifier_class?: string;
29+
};
30+
31+
const generateHtmlCode = (args: ButtonArgs) => {
32+
const isAnchor = !!args.url;
33+
const tag = isAnchor ? 'a' : 'button';
34+
const iconHtml = args.icon ? getIconHtml({
35+
symbol: args.icon,
36+
size: args.size,
37+
modifier_class: 'button__icon'
38+
}) : '';
39+
40+
const classes = [
41+
'button',
42+
`button--${args.type || 'primary'}`,
43+
`button--${args.size || 'regular'}`,
44+
args.icon_only ? 'button--icon-only' : '',
45+
args.badge_content ? 'button--with-badge' : '',
46+
args.modifier_class || '',
47+
].filter(Boolean).join(' ');
48+
49+
const textHtml = `<span class="${args.icon_only ? 'visually-hidden' : 'button__text'}">${args.text}</span>`;
50+
const content = args.icon_placement === 'after' ? `${textHtml}${iconHtml}` : `${iconHtml}${textHtml}`;
51+
52+
const attr = isAnchor
53+
? `href="${args.url}" ${args.is_new_window ? 'target="_blank" rel="noopener"' : ''}`
54+
: `type="button" ${args.is_disabled ? 'disabled' : ''}`;
55+
56+
return `
57+
<${tag} class="${classes}" ${attr}>
58+
${content}
59+
${args.badge_content ? `<span class="badge badge--corner badge--red">${args.badge_content}</span>` : ''}
60+
</${tag}>`.trim();
61+
};
62+
63+
const meta: Meta<ButtonArgs> = {
64+
title: 'Atoms/Button',
65+
render: (args) => (
66+
<div dangerouslySetInnerHTML={{ __html: generateHtmlCode(args) }} style={{ display: 'contents' }} />
67+
),
68+
parameters: {
69+
layout: 'centered',
70+
docs: {
71+
page: () => (
72+
<>
73+
<Title />
74+
<Primary />
75+
<Controls />
76+
<Stories />
77+
<div>
78+
<h3>Component CSS</h3>
79+
<StorybookSource
80+
code={cssCode}
81+
language="css"
82+
dark={true}
83+
/>
84+
</div>
85+
</>
86+
),
87+
source: {
88+
transform: (_input, storyContext) => generateHtmlCode(storyContext.args as ButtonArgs),
89+
language: 'html',
90+
format: true,
91+
},
92+
},
93+
},
94+
tags: ['autodocs'],
95+
argTypes: {
96+
type: { control: 'select', options: ['primary', 'secondary', 'tertiary'] },
97+
size: { control: 'select', options: ['small', 'regular', 'large'] },
98+
icon: { control: 'select', options: ['right-arrow', 'download', 'heart'] },
99+
icon_placement: { control: 'inline-radio', options: ['before', 'after'] },
100+
is_disabled: { control: 'boolean' },
101+
icon_only: { control: 'boolean' },
102+
badge_content: { control: 'text' },
103+
},
104+
};
105+
106+
export default meta;
107+
108+
type Story = StoryObj<ButtonArgs>;
109+
110+
export const PrimaryDefault: Story = {
111+
args: {
112+
type: 'primary',
113+
text: 'Order item',
114+
icon: 'right-arrow',
115+
icon_placement: 'before',
116+
},
117+
};
118+
119+
export const WithIcon: Story = {
120+
args: {
121+
...PrimaryDefault.args,
122+
icon: 'heart',
123+
text: 'Like',
124+
},
125+
};
126+
127+
export const LinkButton: Story = {
128+
args: {
129+
type: 'secondary',
130+
text: 'Download PDF',
131+
url: 'https://example.com/spec.pdf',
132+
is_new_window: true,
133+
icon: 'download',
134+
},
135+
};

components/01-atoms/button/button.twig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@
4848
{% endset %}
4949

5050
{% set text_markup %}
51-
{% if icon_only %}
52-
<span class="visually-hidden">{{ text }}</span>
53-
{% else %}
54-
{{ text }}
55-
{% endif %}
51+
{% if icon_only %}
52+
<span class="visually-hidden">{{ text }}</span>
53+
{% else %}
54+
{{ text }}
55+
{% endif %}
5656
{% endset %}
5757

5858
{% if icon_placement == 'before' %}

components/01-atoms/heading/heading.stories.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import React from 'react';
22
import type { Meta, StoryObj } from '@storybook/react';
33
import {
44
Title,
5-
Subtitle,
6-
Description,
75
Primary,
86
Controls,
97
Stories,
@@ -35,22 +33,19 @@ const generateHtmlCode = (args: HeadingArgs) => {
3533
: '';
3634
};
3735

38-
// React template
3936
const Template = (args: HeadingArgs) => (
4037
<div dangerouslySetInnerHTML={{ __html: generateHtmlCode(args) }} />
4138
);
4239

4340
const meta: Meta<HeadingArgs> = {
44-
title: 'Components/Heading',
41+
title: 'Atoms/Heading',
4542
render: Template,
4643
parameters: {
4744
layout: 'centered',
4845
docs: {
4946
page: () => (
5047
<>
5148
<Title />
52-
<Subtitle />
53-
<Description />
5449
<Primary />
5550
<Controls />
5651
<Stories />

components/01-atoms/icon/README.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ This component renders SVG icons using the `<use>` element, referencing symbols
3434
modifier_class: 'custom-class'
3535
}, with_context = false) }}
3636
```
37-
## Available Symbols
38-
* `download`
39-
* `left-arrow`
40-
* `right-arrow`
41-
* `upper-right-arrow`
42-
* `chevron-down`
43-
* `close`
44-
* `menu`
37+
## Tools
38+
The `icon.helper.ts` utility serves as a central registry that maps SVG icons to unique identifiers, allowing them to be dynamically injected into components.
39+
Look at `components/01-atoms/button/button.stories.tsx`

0 commit comments

Comments
 (0)