Skip to content

Commit 7e25474

Browse files
committed
feat: Typo
1 parent d88e960 commit 7e25474

File tree

4 files changed

+209
-1
lines changed

4 files changed

+209
-1
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Typo, TypoVariant } from '@solved-ac/ui-react'
2+
import { ComponentMeta, ComponentStory } from '@storybook/react'
3+
import React from 'react'
4+
5+
export default {
6+
title: 'Typo',
7+
component: Typo,
8+
argTypes: {
9+
children: {
10+
control: 'text',
11+
description: 'The text to display',
12+
},
13+
variant: {
14+
control: {
15+
type: 'select',
16+
options: ['description', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
17+
},
18+
description: 'The variant of the text',
19+
},
20+
size: {
21+
control: {
22+
type: 'select',
23+
options: ['normal', 'small', 'smaller'],
24+
},
25+
description: 'The size of the text',
26+
},
27+
as: {
28+
control: { type: 'select', options: ['div', 'span', 'button', 'a'] },
29+
description: 'The element to render the card as',
30+
},
31+
},
32+
} as ComponentMeta<typeof Typo>
33+
34+
const Template: ComponentStory<typeof Typo> = (args) => <Typo {...args} />
35+
36+
export const Default = Template.bind({})
37+
Default.args = {
38+
children: 'Typography',
39+
}
40+
41+
const generateVariantTemplate = (
42+
variant: TypoVariant | TypoVariant[],
43+
text?: string
44+
) => {
45+
const GeneratedTemplate = Template.bind({})
46+
GeneratedTemplate.args = {
47+
children: text
48+
? `Typography — ${variant}${text}`
49+
: `Typography — ${variant}`,
50+
variant,
51+
}
52+
return GeneratedTemplate
53+
}
54+
55+
export const Description = generateVariantTemplate('description')
56+
export const Heading1 = generateVariantTemplate('h1')
57+
export const Heading2 = generateVariantTemplate('h2')
58+
export const Heading3 = generateVariantTemplate('h3')
59+
export const Heading4 = generateVariantTemplate('h4')
60+
export const Heading5 = generateVariantTemplate('h5')
61+
export const Small = generateVariantTemplate('small')
62+
export const Smaller = generateVariantTemplate('smaller')
63+
export const Tabular = generateVariantTemplate('tabular', '$8,481.00')
64+
export const Readable = generateVariantTemplate('readable', 'i1Il0O3469')
65+
export const MultipleVariants = generateVariantTemplate([
66+
'small',
67+
'description',
68+
])

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@solved-ac/ui-react",
3-
"version": "0.0.1-alpha.24",
3+
"version": "0.0.1-alpha.25",
44
"description": "React component library used by solved.ac",
55
"author": "shiftpsh",
66
"license": "MIT",

src/components/Typo.tsx

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React, { ElementType } from 'react'
2+
import styled, { css } from 'styled-components'
3+
import {
4+
PolymorphicProps,
5+
PolymorphicRef
6+
} from '../types/PolymorphicElementProps'
7+
8+
const variants = {
9+
default: css``,
10+
description: css`
11+
color: ${({ theme }) => theme.color.text.secondary.main};
12+
`,
13+
h1: css`
14+
display: block;
15+
font-weight: 800;
16+
font-size: 2em;
17+
letter-spacing: -0.04ch;
18+
margin-block-start: 0.67em;
19+
margin-block-end: 0.67em;
20+
margin-inline-start: 0px;
21+
margin-inline-end: 0px;
22+
`,
23+
h2: css`
24+
display: block;
25+
font-weight: 800;
26+
font-size: 1.5em;
27+
letter-spacing: -0.02ch;
28+
margin-block-start: 0.83em;
29+
margin-block-end: 0.83em;
30+
margin-inline-start: 0px;
31+
margin-inline-end: 0px;
32+
`,
33+
h3: css`
34+
display: block;
35+
font-weight: 800;
36+
font-size: 1.2em;
37+
margin-block-start: 1em;
38+
margin-block-end: 1em;
39+
margin-inline-start: 0px;
40+
margin-inline-end: 0px;
41+
`,
42+
h4: css`
43+
display: block;
44+
font-weight: 800;
45+
font-size: 1em;
46+
letter-spacing: 0.02ch;
47+
margin-block-start: 1em;
48+
margin-block-end: 1em;
49+
margin-inline-start: 0px;
50+
margin-inline-end: 0px;
51+
`,
52+
h5: css`
53+
display: block;
54+
font-weight: 700;
55+
font-size: 1em;
56+
letter-spacing: 0.02ch;
57+
margin-block-start: 1em;
58+
margin-block-end: 1em;
59+
margin-inline-start: 0px;
60+
margin-inline-end: 0px;
61+
`,
62+
h6: css`
63+
display: block;
64+
font-weight: 600;
65+
font-size: 1em;
66+
letter-spacing: 0.02ch;
67+
margin-block-start: 1em;
68+
margin-block-end: 1em;
69+
margin-inline-start: 0px;
70+
margin-inline-end: 0px;
71+
`,
72+
small: css`
73+
font-size: small;
74+
`,
75+
smaller: css`
76+
font-size: smaller;
77+
`,
78+
tabular: css`
79+
font-feature-settings: 'tnum';
80+
`,
81+
readable: css`
82+
font-feature-settings: 'ss06', 'zero';
83+
`,
84+
'no-ligatures': css`
85+
font-variant-ligatures: none;
86+
`,
87+
} as const
88+
89+
export type TypoVariant = keyof typeof variants
90+
91+
const asMap = {
92+
h1: 'h1',
93+
h2: 'h2',
94+
h3: 'h3',
95+
h4: 'h4',
96+
h5: 'h5',
97+
h6: 'h6',
98+
small: 'small',
99+
smaller: 'small',
100+
} as const
101+
102+
interface TypoContainerProps {
103+
variant: TypoVariant | TypoVariant[]
104+
}
105+
106+
const TypoContainer = styled.span<TypoContainerProps>`
107+
${({ variant }) =>
108+
typeof variant === 'string'
109+
? variants[variant]
110+
: variant.map((v) => variants[v])}
111+
`
112+
113+
export type TypoProps<T extends ElementType = 'span'> = {
114+
variant?: TypoVariant | TypoVariant[]
115+
} & PolymorphicProps<T>
116+
117+
const firstVariant = (
118+
variant?: TypoVariant | TypoVariant[]
119+
): TypoVariant | undefined => {
120+
if (typeof variant === 'string') return variant
121+
if (Array.isArray(variant) && variant.length > 0) return variant[0]
122+
return undefined
123+
}
124+
125+
export const Typo = React.forwardRef(
126+
<T extends ElementType>(
127+
props: TypoProps<T>,
128+
ref?: PolymorphicRef<T>
129+
): JSX.Element => {
130+
const { variant = [], as, ...rest } = props
131+
132+
const calculatedAs =
133+
as || asMap[firstVariant(variant) ?? 'default'] || 'span'
134+
135+
return (
136+
<TypoContainer ref={ref} as={calculatedAs} variant={variant} {...rest} />
137+
)
138+
}
139+
)

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export * from './PaginationItem'
1111
export * from './Space'
1212
export * from './Tab'
1313
export * from './Tabs'
14+
export * from './Typo'
1415

0 commit comments

Comments
 (0)