Skip to content

Commit a09fa0f

Browse files
committed
feat(many): add new Typography tokens and update text and heading
Closes: INSTUI-4403
1 parent 07c9443 commit a09fa0f

File tree

15 files changed

+515
-61
lines changed

15 files changed

+515
-61
lines changed

docs/guides/typography-system.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: Typography
3+
category: Guides
4+
order: 8
5+
---
6+
7+
# Typography
8+
9+
InstUI provides various typography tokens on theme and component level as well.
10+
11+
## Typography components
12+
13+
Your every text-based need should be covered by one of our two typography components, namely `<Text>` and `<Heading>`.
14+
These components have a `variant` prop with a handful of semantic values to choose from. These values describe multiple aspects of the text, such as `font-weight`, `font-size`, `line-height` and for `<Heading>` the DOM element that should be rendered, (i.e.:`<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`).
15+
16+
While you can set all these properties separately as well, our strong recommendation is to use the variant with semantic values and only deviate from it in cases absolutely necessary.
17+
18+
## <Text>
19+
20+
Here is the list of semantic variant values and what they do in `<Text>`
21+
22+
This is always rendered as `<span>`
23+
24+
The values (e.g.:`weightRegular`) are from the currently used theme's typography sections, for example:
25+
[Canvas Theme](https://instructure.design/#canvas)
26+
27+
| variant | fontStyle | weight | size | lineHeight |
28+
| ------------------ | --------- | --------------- | ------------------ | ------------- |
29+
| descriptionPage | normal | weightRegular | descriptionPage | lineHeight150 |
30+
| descriptionSection | normal | weightRegular | descriptionSection | lineHeight150 |
31+
| content | normal | weightRegular | content | lineHeight150 |
32+
| contentImportant | normal | weightImportant | content | lineHeight150 |
33+
| contentQuote | normal | weightRegular | content | lineHeight150 |
34+
| contentSmall | normal | weightRegular | contentSmall | lineHeight150 |
35+
| legend | normal | weightRegular | legend | lineHeight150 |
36+
37+
## <Heading>
38+
39+
Here is the list of semantic variant values and how are they rendered in `<Heading>`
40+
41+
| variant | dom element |
42+
| ---------------- | ----------- |
43+
| titlePageDesktop | h1 |
44+
| titlePageMobile | h1 |
45+
| titleSection | h2 |
46+
| titleCardSection | h2 |
47+
| titleModule | h3 |
48+
| titleCardLarge | h4 |
49+
| titleCardRegular | h4 |
50+
| titleCardMini | h4 |
51+
| label | h5 |
52+
| labelInline | h5 |
53+
54+
## Legacy values
55+
56+
For compatibility reasons we still provide the legacy typography tokens (xxLarge, medium, etc.) so updating InstUI is easier but these tokens shouldn't be used when creating new screens. The following tokens are deprecated from the `themes`, more specifically from `theme.typography`
57+
58+
Deprecated theme tokens:
59+
60+
- fontSizeXSmall
61+
- fontSizeSmall
62+
- fontSizeMedium
63+
- fontSizeLarge
64+
- fontSizeXLarge
65+
- fontSizeXXLarge
66+
- fontWeightLight
67+
- fontWeightNormal
68+
- fontWeightBold
69+
- lineHeight
70+
- lineHeightFit
71+
- lineHeightCondensed
72+
- lineHeightDouble
73+
- letterSpacingNormal

packages/shared-types/src/BaseTheme.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ type Typography = {
111111
letterSpacingNormal: number | 0
112112
letterSpacingCondensed: string | 0
113113
letterSpacingExpanded: string | 0
114+
115+
titlePageDesktop: string
116+
titlePageMobile: string
117+
titleSection: string
118+
titleModule: string
119+
titleCardLarge: string
120+
titleCardRegular: string
121+
titleCardMini: string
122+
descriptionPage: string
123+
descriptionSection: string
124+
label: string
125+
content: string
126+
contentSmall: string
127+
legend: string
128+
129+
lineHeight100: number
130+
lineHeight125: number
131+
lineHeight150: number
132+
weightRegular: number
133+
weightImportant: number
114134
}
115135

116136
type Size = {

packages/shared-types/src/ComponentThemeVariables.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ export type GridTheme = {
603603
spacingLarge: Spacing['large']
604604
} & Media
605605

606-
export type HeadingTheme = {
606+
export type HeadingTheme = Typography & {
607607
lineHeight: Typography['lineHeightCondensed']
608608
h1FontSize: Typography['fontSizeXXLarge']
609609
h1FontWeight: Typography['fontWeightBold']

packages/ui-heading/src/Heading/README.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,31 @@ describes: Heading
44

55
Heading is a component for creating typographic headings.
66

7+
## Variant
8+
9+
Variant takes care of - almost - all use-cases when it comes hedings on pages. Their name reflects the places they meant to be used. It sets the `level` prop and takes care of the style of the heading
10+
We recommend using `variants` instead of the `level` (and `as`) props.
11+
12+
NOTE: when `variant` is set, `level` and `as` props are ignored
13+
14+
```js
15+
---
16+
type: example
17+
---
18+
<div>
19+
<Heading variant="titlePageDesktop"> titlePageDesktop </Heading><br/>
20+
<Heading variant="titlePageMobile"> titlePageMobile </Heading><br/>
21+
<Heading variant="titleSection"> titleSection </Heading><br/>
22+
<Heading variant="titleCardSection"> titleCardSection </Heading><br/>
23+
<Heading variant="titleModule"> titleModule </Heading><br/>
24+
<Heading variant="titleCardLarge"> titleCardLarge </Heading><br/>
25+
<Heading variant="titleCardRegular"> titleCardRegular </Heading><br/>
26+
<Heading variant="titleCardMini"> titleCardMini </Heading><br/>
27+
<Heading variant="label"> label </Heading><br/>
28+
<Heading variant="labelInline"> labelInline </Heading><br/>
29+
</div>
30+
```
31+
732
```js
833
---
934
type: example
@@ -24,11 +49,7 @@ type: example
2449
---
2550
<div>
2651
<Heading level="h1" as="h2" margin="0 0 x-small">Heading level One</Heading>
27-
<Heading level="h2" as="h1" margin="0 0 x-small">Heading level Two</Heading>
28-
<Heading level="h3" margin="0 0 x-small">Heading level Three</Heading>
29-
<Heading level="h4" margin="0 0 x-small">Heading level Four</Heading>
30-
<Heading level="h5" margin="0 0 x-small">Heading level Five</Heading>
31-
<Heading level="reset" as="h2">Heading level reset as a Two</Heading>
52+
3253
</div>
3354
```
3455

packages/ui-heading/src/Heading/__examples__/Heading.examples.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,18 @@ import type { StoryConfig } from '@instructure/ui-test-utils'
2626
import type { HeadingProps } from '../props'
2727

2828
export default {
29-
sectionProp: 'level',
29+
sectionProp: 'variant',
3030
propValues: {
3131
color: [
3232
'primary',
3333
'secondary',
3434
'primary-inverse',
3535
'secondary-inverse',
3636
'inherit'
37-
]
37+
],
38+
39+
level: [undefined],
40+
as: [undefined]
3841
},
3942
getComponentProps: () => {
4043
return {

packages/ui-heading/src/Heading/index.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ import generateComponentTheme from './theme'
3636
import { propTypes, allowedProps } from './props'
3737
import type { HeadingProps } from './props'
3838

39+
const variantLevels: Record<
40+
NonNullable<HeadingProps['variant']>,
41+
'h1' | 'h2' | 'h3' | 'h4' | 'h5'
42+
> = {
43+
titlePageDesktop: 'h1',
44+
titlePageMobile: 'h1',
45+
titleSection: 'h2',
46+
titleCardSection: 'h2',
47+
titleModule: 'h3',
48+
titleCardLarge: 'h4',
49+
titleCardRegular: 'h4',
50+
titleCardMini: 'h4',
51+
label: 'h5',
52+
labelInline: 'h5'
53+
}
54+
3955
/**
4056
---
4157
category: components
@@ -67,12 +83,26 @@ class Heading extends Component<HeadingProps> {
6783
}
6884
}
6985

86+
checkProps() {
87+
const { variant, level, as } = this.props
88+
if (variant) {
89+
if (level) {
90+
console.warn("[Heading]: Don't use 'level' with 'variant' ")
91+
}
92+
if (as) {
93+
console.warn("[Heading]: Don't use 'as' with 'variant' ")
94+
}
95+
}
96+
}
97+
7098
componentDidMount() {
7199
this.props.makeStyles?.()
100+
this.checkProps()
72101
}
73102

74103
componentDidUpdate() {
75104
this.props.makeStyles?.()
105+
this.checkProps()
76106
}
77107

78108
render() {
@@ -84,10 +114,16 @@ class Heading extends Component<HeadingProps> {
84114
margin,
85115
elementRef,
86116
makeStyles,
117+
variant,
87118
...props
88119
} = this.props
89120

90-
const ElementType = getElementType(Heading, this.props, () => {
121+
const propsForGetElementType = variant ? {} : this.props
122+
123+
const ElementType = getElementType(Heading, propsForGetElementType, () => {
124+
if (variant) {
125+
return variantLevels[variant]
126+
}
91127
if (level === 'reset') {
92128
return 'span'
93129
} else {

packages/ui-heading/src/Heading/props.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ type HeadingOwnProps = {
7878
* Provides a ref to the underlying HTML element
7979
*/
8080
elementRef?: (element: Element | null) => void
81+
/**
82+
* Sets style and level at once. The as property will be the same as the level.
83+
* NOTE: this is the recommended way of setting the appearance, instead of level
84+
*/
85+
variant?:
86+
| 'titlePageDesktop'
87+
| 'titlePageMobile'
88+
| 'titleSection'
89+
| 'titleCardSection'
90+
| 'titleModule'
91+
| 'titleCardLarge'
92+
| 'titleCardRegular'
93+
| 'titleCardMini'
94+
| 'label'
95+
| 'labelInline'
8196
}
8297

8398
type PropKeys = keyof HeadingOwnProps
@@ -103,7 +118,19 @@ const propTypes: PropValidators<PropKeys> = {
103118
level: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'reset']),
104119
as: PropTypes.elementType,
105120
margin: ThemeablePropTypes.spacing,
106-
elementRef: PropTypes.func
121+
elementRef: PropTypes.func,
122+
variant: PropTypes.oneOf([
123+
'titlePageDesktop',
124+
'titlePageMobile',
125+
'titleSection',
126+
'titleCardSection',
127+
'titleModule',
128+
'titleCardLarge',
129+
'titleCardRegular',
130+
'titleCardMini',
131+
'label',
132+
'labelInline'
133+
])
107134
}
108135

109136
const allowedProps: AllowedPropKeys = [
@@ -113,7 +140,8 @@ const allowedProps: AllowedPropKeys = [
113140
'level',
114141
'as',
115142
'margin',
116-
'elementRef'
143+
'elementRef',
144+
'variant'
117145
]
118146

119147
export type { HeadingProps, HeadingStyle }

packages/ui-heading/src/Heading/styles.ts

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,70 @@ const generateStyle = (
3939
componentTheme: HeadingTheme,
4040
props: HeadingProps
4141
): HeadingStyle => {
42-
const { level, color, border } = props
42+
const { level, color, border, variant } = props
43+
44+
const variants: Record<NonNullable<HeadingProps['variant']>, object> = {
45+
titlePageDesktop: {
46+
fontStyle: 'normal',
47+
fontWeight: componentTheme.weightImportant,
48+
fontSize: componentTheme.titlePageDesktop,
49+
lineHeight: componentTheme.lineHeight125
50+
},
51+
titlePageMobile: {
52+
fontStyle: 'normal',
53+
fontWeight: componentTheme.weightImportant,
54+
fontSize: componentTheme.titlePageMobile,
55+
lineHeight: componentTheme.lineHeight125
56+
},
57+
titleSection: {
58+
fontStyle: 'normal',
59+
fontWeight: componentTheme.weightImportant,
60+
fontSize: componentTheme.titleSection,
61+
lineHeight: componentTheme.lineHeight125
62+
},
63+
titleCardSection: {
64+
fontStyle: 'normal',
65+
fontWeight: componentTheme.weightImportant,
66+
fontSize: componentTheme.titleSection,
67+
lineHeight: componentTheme.lineHeight125
68+
},
69+
titleModule: {
70+
fontStyle: 'normal',
71+
fontWeight: componentTheme.weightImportant,
72+
fontSize: componentTheme.titleModule,
73+
lineHeight: componentTheme.lineHeight125
74+
},
75+
titleCardLarge: {
76+
fontStyle: 'normal',
77+
fontWeight: componentTheme.weightImportant,
78+
fontSize: componentTheme.titleCardLarge,
79+
lineHeight: componentTheme.lineHeight125
80+
},
81+
titleCardRegular: {
82+
fontStyle: 'normal',
83+
fontWeight: componentTheme.weightImportant,
84+
fontSize: componentTheme.titleCardRegular,
85+
lineHeight: componentTheme.lineHeight125
86+
},
87+
titleCardMini: {
88+
fontStyle: 'normal',
89+
fontWeight: componentTheme.weightImportant,
90+
fontSize: componentTheme.titleCardMini,
91+
lineHeight: componentTheme.lineHeight125
92+
},
93+
label: {
94+
fontStyle: 'normal',
95+
fontWeight: componentTheme.weightImportant,
96+
fontSize: componentTheme.label,
97+
lineHeight: componentTheme.lineHeight125
98+
},
99+
labelInline: {
100+
fontStyle: 'normal',
101+
fontWeight: componentTheme.weightImportant,
102+
fontSize: componentTheme.label,
103+
lineHeight: componentTheme.lineHeight150
104+
}
105+
}
43106

44107
const levelStyles = {
45108
h1: {
@@ -125,7 +188,7 @@ const generateStyle = (
125188
'&:is(input)[type]': inputStyles,
126189
'&:-webkit-any(input)[type]': inputStyles,
127190

128-
...levelStyles[level!],
191+
...(variant ? variants[variant] : levelStyles[level!]),
129192
...colorStyles[color!],
130193
...borderStyles[border!]
131194
}

packages/ui-heading/src/Heading/theme.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const generateComponentTheme = (theme: Theme): HeadingTheme => {
5050
}
5151

5252
const componentVariables: HeadingTheme = {
53+
...typography,
54+
5355
lineHeight: typography?.lineHeightCondensed,
5456

5557
h1FontSize: typography?.fontSizeXXLarge,

0 commit comments

Comments
 (0)