Skip to content

Commit acb181e

Browse files
authored
chore: update typography story (#1724)
1 parent 3d4b0a1 commit acb181e

File tree

2 files changed

+160
-61
lines changed

2 files changed

+160
-61
lines changed

.changeset/tidy-tools-send.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@launchpad-ui/tokens": patch
3+
---
4+
5+
Update typography story
Lines changed: 155 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,163 @@
11
import { vars } from '@launchpad-ui/vars';
22

3+
import { Button } from '../../components/src/Button';
4+
import { ToastRegion, toastQueue } from '../../components/src/Toast';
5+
import { Tooltip, TooltipTrigger } from '../../components/src/Tooltip';
6+
37
export default {
48
title: 'Tokens/Typography',
59
};
610

11+
const flatten = (obj: Record<string, unknown>, prefix = ''): Record<string, string> => {
12+
const result: Record<string, string> = {};
13+
14+
for (const [key, value] of Object.entries(obj)) {
15+
const newKey = prefix ? `${prefix}-${key}` : key;
16+
17+
if (typeof value === 'string') {
18+
result[newKey] = value;
19+
} else if (typeof value === 'object' && value !== null) {
20+
Object.assign(result, flatten(value as Record<string, unknown>, newKey));
21+
}
22+
}
23+
24+
return result;
25+
};
26+
27+
const getDisplayText = (key: string) => {
28+
const parts = key.split('-');
29+
30+
const category = parts[0]; // heading, body, etc.
31+
const size = parts[1]; // 1, 2, etc.
32+
const weight = parts[2]; // medium, semibold, etc.
33+
34+
if (weight) {
35+
return `${category.charAt(0).toUpperCase() + category.slice(1)} ${size} - ${weight.charAt(0).toUpperCase() + weight.slice(1)}`;
36+
}
37+
if (category === 'display') {
38+
return `Display ${size}`;
39+
}
40+
41+
return key;
42+
};
43+
44+
const getSemanticElement = (token: string, font: string) => {
45+
const parts = token.split('-');
46+
const category = parts[0]; // heading, body, etc.
47+
const size = parts[1]; // 1, 2, etc.
48+
49+
console.log({ category, token });
50+
51+
switch (category) {
52+
case 'display':
53+
return {
54+
element: 'div',
55+
render: (text: string) => <div style={{ font }}>{text}</div>,
56+
};
57+
case 'heading':
58+
if (size === '1') {
59+
return {
60+
element: 'h1',
61+
render: (text: string) => <h1 style={{ font }}>{text}</h1>,
62+
};
63+
}
64+
if (size === '2') {
65+
return {
66+
element: 'h2',
67+
render: (text: string) => <h2 style={{ font }}>{text}</h2>,
68+
};
69+
}
70+
if (size === '3') {
71+
return {
72+
element: 'h3',
73+
render: (text: string) => <h3 style={{ font }}>{text}</h3>,
74+
};
75+
}
76+
return {
77+
element: 'div',
78+
render: (text: string) => <div style={{ font }}>{text}</div>,
79+
};
80+
case 'body':
81+
case 'small':
82+
return {
83+
element: 'span',
84+
render: (text: string) => <span style={{ font }}>{text}</span>,
85+
};
86+
case 'label':
87+
return {
88+
element: 'label',
89+
render: (text: string) => <label style={{ font }}>{text}</label>,
90+
};
91+
case 'code':
92+
return {
93+
element: 'code',
94+
render: (text: string) => <code style={{ font }}>{text}</code>,
95+
};
96+
default:
97+
return {
98+
element: 'div',
99+
render: (text: string) => <div style={{ font }}>{text}</div>,
100+
};
101+
}
102+
};
103+
104+
const TokenTable = ({ tokens }: { tokens: Record<string, string> }) => {
105+
return (
106+
<>
107+
<table style={{ borderCollapse: 'separate', borderSpacing: '20px 0', width: '100%' }}>
108+
<thead>
109+
<tr>
110+
<th style={{ textAlign: 'left' }}>Sample</th>
111+
<th style={{ textAlign: 'left' }}>Name</th>
112+
</tr>
113+
</thead>
114+
<tbody>
115+
{Object.entries(tokens).map(([key, value]) => {
116+
const cssVar = `--lp-text-${key}`;
117+
const { element, render } = getSemanticElement(key, value);
118+
119+
return (
120+
<tr key={key}>
121+
<td
122+
style={{
123+
paddingRight: vars.spacing[600],
124+
paddingTop: vars.spacing[300],
125+
paddingBottom: vars.spacing[300],
126+
}}
127+
>
128+
{render(getDisplayText(key))}
129+
</td>
130+
<td
131+
style={{
132+
paddingRight: vars.spacing[600],
133+
paddingTop: vars.spacing[300],
134+
paddingBottom: vars.spacing[300],
135+
}}
136+
>
137+
<TooltipTrigger>
138+
<Button
139+
onPress={() => {
140+
navigator.clipboard.writeText(`<${element} style="font: ${value}" />`);
141+
toastQueue.add({ title: 'Copied!', status: 'success' });
142+
}}
143+
style={{ font: 'var(--lp-text-code-1-regular)' }}
144+
variant="minimal"
145+
>
146+
{cssVar}
147+
</Button>
148+
<Tooltip placement="bottom">Copy to clipboard</Tooltip>
149+
</TooltipTrigger>
150+
</td>
151+
</tr>
152+
);
153+
})}
154+
</tbody>
155+
</table>
156+
<ToastRegion />
157+
</>
158+
);
159+
};
160+
7161
export const Typography = {
8-
render: () => {
9-
return (
10-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[900] }}>
11-
<div style={{ font: vars.text.display[1] }}>Display 1</div>
12-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
13-
<h1 style={{ font: vars.text.heading[1].medium }}>Heading 1 - Medium</h1>
14-
<h1 style={{ font: vars.text.heading[1].semibold }}>Heading 1 - SemiBold</h1>
15-
<h1 style={{ font: vars.text.heading[1].extrabold }}>Heading 1 - ExtraBold</h1>
16-
</div>
17-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
18-
<h2 style={{ font: vars.text.heading[2].medium }}>Heading 2 - Medium</h2>
19-
<h2 style={{ font: vars.text.heading[2].semibold }}>Heading 2 - SemiBold</h2>
20-
<h2 style={{ font: vars.text.heading[2].extrabold }}>Heading 2 - ExtraBold</h2>
21-
</div>
22-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
23-
<h3 style={{ font: vars.text.heading[3].medium }}>Heading 3 - Medium</h3>
24-
<h3 style={{ font: vars.text.heading[3].semibold }}>Heading 3 - SemiBold</h3>
25-
<h3 style={{ font: vars.text.heading[3].extrabold }}>Heading 3 - ExtraBold</h3>
26-
</div>
27-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
28-
<span style={{ font: vars.text.body[1].regular }}>Body 1 - Regular</span>
29-
<span style={{ font: vars.text.body[1].semibold }}>Body 1 - SemiBold</span>
30-
<span style={{ font: vars.text.body[1].extrabold }}>Body 1 - ExtraBold</span>
31-
</div>
32-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
33-
<span style={{ font: vars.text.body[2].regular }}>Body 2 - Regular</span>
34-
<span style={{ font: vars.text.body[2].semibold }}>Body 2 - SemiBold</span>
35-
<span style={{ font: vars.text.body[2].extrabold }}>Body 2 - ExtraBold</span>
36-
</div>
37-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
38-
<span style={{ font: vars.text.small[1].regular }}>Small 1 - Regular</span>
39-
<span style={{ font: vars.text.small[1].medium }}>Small 1 - Medium</span>
40-
<span style={{ font: vars.text.small[1].semibold }}>Small 1 - SemiBold</span>
41-
</div>
42-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
43-
<label style={{ font: vars.text.label[1].regular, display: 'block' }}>
44-
Label 1 - Regular
45-
</label>
46-
<label style={{ font: vars.text.label[1].medium, display: 'block' }}>
47-
Label 1 - Medium
48-
</label>
49-
</div>
50-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
51-
<label style={{ font: vars.text.label[2].regular, display: 'block' }}>
52-
Label 2 - Regular
53-
</label>
54-
<label style={{ font: vars.text.label[2].medium, display: 'block' }}>
55-
Label 2 - Medium
56-
</label>
57-
</div>
58-
<div style={{ display: 'flex', flexDirection: 'column', gap: vars.spacing[600] }}>
59-
<code style={{ font: vars.text.code[1].regular, display: 'block' }}>
60-
Code 1 - Regular
61-
</code>
62-
<code style={{ font: vars.text.code[2].regular, display: 'block' }}>
63-
Code 2 - Regular
64-
</code>
65-
</div>
66-
</div>
67-
);
68-
},
162+
render: () => <TokenTable tokens={flatten(vars.text)} />,
69163
};

0 commit comments

Comments
 (0)