Devup UI provides a powerful typography system that supports static styles, responsive typography, and theme integration.
Define typography styles in devup.json:
1{ 2 "theme": { 3 "typography": { 4 "h1": { 5 "fontFamily": "Pretendard", 6 "fontSize": "48px", 7 "fontWeight": 800, 8 "lineHeight": 1.2, 9 "letterSpacing": "-0.02em" 10 }, 11 "h2": { 12 "fontFamily": "Pretendard", 13 "fontSize": "36px", 14 "fontWeight": 700, 15 "lineHeight": 1.3, 16 "letterSpacing": "-0.02em" 17 }, 18 "body": { 19 "fontFamily": "Pretendard", 20 "fontSize": "16px", 21 "fontWeight": 400, 22 "lineHeight": 1.5 23 }, 24 "caption": { 25 "fontFamily": "Pretendard", 26 "fontSize": "14px", 27 "fontWeight": 400, 28 "lineHeight": 1.4 29 } 30 } 31 } 32}1{ 2 "theme": { 3 "typography": { 4 "h1": { 5 "fontFamily": "Pretendard", 6 "fontSize": "48px", 7 "fontWeight": 800, 8 "lineHeight": 1.2, 9 "letterSpacing": "-0.02em" 10 }, 11 "h2": { 12 "fontFamily": "Pretendard", 13 "fontSize": "36px", 14 "fontWeight": 700, 15 "lineHeight": 1.3, 16 "letterSpacing": "-0.02em" 17 }, 18 "body": { 19 "fontFamily": "Pretendard", 20 "fontSize": "16px", 21 "fontWeight": 400, 22 "lineHeight": 1.5 23 }, 24 "caption": { 25 "fontFamily": "Pretendard", 26 "fontSize": "14px", 27 "fontWeight": 400, 28 "lineHeight": 1.4 29 } 30 } 31 } 32}
Use typography with the typography prop:
1const h1Example = <Text typography="$h1">Heading 1</Text> 2const h2Example = <Text typography="$h2">Heading 2</Text> 3const bodyExample = <Text typography="$body">Body text</Text> 4const captionExample = <Text typography="$caption">Caption text</Text>1const h1Example = <Text typography="$h1">Heading 1</Text> 2const h2Example = <Text typography="$h2">Heading 2</Text> 3const bodyExample = <Text typography="$body">Body text</Text> 4const captionExample = <Text typography="$caption">Caption text</Text>
Each typography style can include:
| Property | Description | Example |
|---|---|---|
fontFamily | Font family name | "Pretendard" |
fontSize | Font size | "16px" |
fontWeight | Font weight (number or string) |
|
fontStyle | Font style |
|
lineHeight | Line height (number or string) |
|
letterSpacing | Letter spacing | "-0.02em" |
textTransform | Text transformation | "uppercase" |
Define responsive typography using arrays. Each index corresponds to a breakpoint:
1{ 2 "theme": { 3 "typography": { 4 "h1": [ 5 { 6 "fontFamily": "Pretendard", 7 "fontSize": "32px", 8 "fontWeight": 800, 9 "lineHeight": 1.2 10 }, 11 null, 12 null, 13 null, 14 { 15 "fontFamily": "Pretendard", 16 "fontSize": "48px", 17 "fontWeight": 800, 18 "lineHeight": 1.2 19 } 20 ] 21 } 22 } 23}1{ 2 "theme": { 3 "typography": { 4 "h1": [ 5 { 6 "fontFamily": "Pretendard", 7 "fontSize": "32px", 8 "fontWeight": 800, 9 "lineHeight": 1.2 10 }, 11 null, 12 null, 13 null, 14 { 15 "fontFamily": "Pretendard", 16 "fontSize": "48px", 17 "fontWeight": 800, 18 "lineHeight": 1.2 19 } 20 ] 21 } 22 } 23}
The breakpoints are:
0px (mobile)480px768px1024px1280px (desktop)1640pxUse null to skip a breakpoint and inherit from the previous value.
Here's a recommended typography scale:
1{ 2 "theme": { 3 "typography": { 4 "h1": [ 5 { 6 "fontFamily": "Pretendard", 7 "fontSize": "32px", 8 "fontWeight": 800, 9 "lineHeight": 1.2, 10 "letterSpacing": "-0.03em" 11 }, 12 null, 13 null, 14 null, 15 { 16 "fontFamily": "Pretendard", 17 "fontSize": "48px", 18 "fontWeight": 800, 19 "lineHeight": 1.2, 20 "letterSpacing": "-0.03em" 21 } 22 ], 23 "h2": [ 24 { 25 "fontFamily": "Pretendard", 26 "fontSize": "28px", 27 "fontWeight": 700, 28 "lineHeight": 1.3 29 }, 30 null, 31 null, 32 null, 33 { 34 "fontFamily": "Pretendard", 35 "fontSize": "36px", 36 "fontWeight": 700, 37 "lineHeight": 1.3 38 } 39 ], 40 "h3": [ 41 { 42 "fontFamily": "Pretendard", 43 "fontSize": "24px", 44 "fontWeight": 600, 45 "lineHeight": 1.3 46 }, 47 null, 48 null, 49 null, 50 { 51 "fontFamily": "Pretendard", 52 "fontSize": "28px", 53 "fontWeight": 600, 54 "lineHeight": 1.3 55 } 56 ], 57 "body": { 58 "fontFamily": "Pretendard", 59 "fontSize": "16px", 60 "fontWeight": 400, 61 "lineHeight": 1.5 62 }, 63 "bodyBold": { 64 "fontFamily": "Pretendard", 65 "fontSize": "16px", 66 "fontWeight": 700, 67 "lineHeight": 1.5 68 }, 69 "caption": { 70 "fontFamily": "Pretendard", 71 "fontSize": "14px", 72 "fontWeight": 400, 73 "lineHeight": 1.4 74 }, 75 "small": { 76 "fontFamily": "Pretendard", 77 "fontSize": "12px", 78 "fontWeight": 400, 79 "lineHeight": 1.4 80 }, 81 "buttonL": { 82 "fontFamily": "Pretendard", 83 "fontSize": "18px", 84 "fontWeight": 600, 85 "lineHeight": 1.3 86 }, 87 "buttonM": { 88 "fontFamily": "Pretendard", 89 "fontSize": "16px", 90 "fontWeight": 600, 91 "lineHeight": 1.3 92 }, 93 "buttonS": { 94 "fontFamily": "Pretendard", 95 "fontSize": "14px", 96 "fontWeight": 600, 97 "lineHeight": 1.3 98 } 99 } 100 } 101}1{ 2 "theme": { 3 "typography": { 4 "h1": [ 5 { 6 "fontFamily": "Pretendard", 7 "fontSize": "32px", 8 "fontWeight": 800, 9 "lineHeight": 1.2, 10 "letterSpacing": "-0.03em" 11 }, 12 null, 13 null, 14 null, 15 { 16 "fontFamily": "Pretendard", 17 "fontSize": "48px", 18 "fontWeight": 800, 19 "lineHeight": 1.2, 20 "letterSpacing": "-0.03em" 21 } 22 ], 23 "h2": [ 24 { 25 "fontFamily": "Pretendard", 26 "fontSize": "28px", 27 "fontWeight": 700, 28 "lineHeight": 1.3 29 }, 30 null, 31 null, 32 null, 33 { 34 "fontFamily": "Pretendard", 35 "fontSize": "36px", 36 "fontWeight": 700, 37 "lineHeight": 1.3 38 } 39 ], 40 "h3": [ 41 { 42 "fontFamily": "Pretendard", 43 "fontSize": "24px", 44 "fontWeight": 600, 45 "lineHeight": 1.3 46 }, 47 null, 48 null, 49 null, 50 { 51 "fontFamily": "Pretendard", 52 "fontSize": "28px", 53 "fontWeight": 600, 54 "lineHeight": 1.3 55 } 56 ], 57 "body": { 58 "fontFamily": "Pretendard", 59 "fontSize": "16px", 60 "fontWeight": 400, 61 "lineHeight": 1.5 62 }, 63 "bodyBold": { 64 "fontFamily": "Pretendard", 65 "fontSize": "16px", 66 "fontWeight": 700, 67 "lineHeight": 1.5 68 }, 69 "caption": { 70 "fontFamily": "Pretendard", 71 "fontSize": "14px", 72 "fontWeight": 400, 73 "lineHeight": 1.4 74 }, 75 "small": { 76 "fontFamily": "Pretendard", 77 "fontSize": "12px", 78 "fontWeight": 400, 79 "lineHeight": 1.4 80 }, 81 "buttonL": { 82 "fontFamily": "Pretendard", 83 "fontSize": "18px", 84 "fontWeight": 600, 85 "lineHeight": 1.3 86 }, 87 "buttonM": { 88 "fontFamily": "Pretendard", 89 "fontSize": "16px", 90 "fontWeight": 600, 91 "lineHeight": 1.3 92 }, 93 "buttonS": { 94 "fontFamily": "Pretendard", 95 "fontSize": "14px", 96 "fontWeight": 600, 97 "lineHeight": 1.3 98 } 99 } 100 } 101}
1// With Text component 2const titleExample = <Text typography="$h1">Main Title</Text> 3const bodyExample = <Text typography="$body">Paragraph text goes here.</Text> 4 5// With Box component 6const boxExample = <Box typography="$caption">Caption in a box</Box>1// With Text component 2const titleExample = <Text typography="$h1">Main Title</Text> 3const bodyExample = <Text typography="$body">Paragraph text goes here.</Text> 4 5// With Box component 6const boxExample = <Box typography="$caption">Caption in a box</Box>
1// With styled components 2const Title = styled('h1', { 3 typography: '$h1', 4 color: '$text', 5})1// With styled components 2const Title = styled('h1', { 3 typography: '$h1', 4 color: '$text', 5})
Typography can be combined with other style props:
1const example = ( 2 <Text color="$primary" mb={4} textAlign="center" typography="$h1"> 3 Centered Title 4 </Text> 5)1const example = ( 2 <Text color="$primary" mb={4} textAlign="center" typography="$h1"> 3 Centered Title 4 </Text> 5)
Typography tokens are fully type-safe:
1// TypeScript autocomplete shows: $h1, $h2, $body, etc. 2const example = <Text typography="$" /> 3 4// Invalid tokens show TypeScript errors 5const invalidExample = <Text typography="$invalid" /> // Error!1// TypeScript autocomplete shows: $h1, $h2, $body, etc. 2const example = <Text typography="$" /> 3 4// Invalid tokens show TypeScript errors 5const invalidExample = <Text typography="$invalid" /> // Error!