@instructure/ui-heading 11.6.0 → 11.6.1-snapshot-129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -304
- package/es/Heading/{index.js → v1/index.js} +2 -2
- package/es/Heading/v2/index.js +266 -0
- package/es/Heading/v2/props.js +26 -0
- package/es/Heading/v2/styles.js +273 -0
- package/es/{index.js → exports/a.js} +1 -1
- package/{src/index.ts → es/exports/b.js} +1 -3
- package/lib/Heading/{index.js → v1/index.js} +4 -4
- package/lib/Heading/v2/index.js +271 -0
- package/lib/Heading/v2/props.js +31 -0
- package/lib/Heading/v2/styles.js +279 -0
- package/lib/{index.js → exports/a.js} +2 -2
- package/lib/exports/b.js +12 -0
- package/package.json +39 -17
- package/src/Heading/{index.tsx → v1/index.tsx} +2 -2
- package/src/Heading/v2/README.md +158 -0
- package/src/Heading/v2/index.tsx +291 -0
- package/src/Heading/v2/props.ts +133 -0
- package/src/Heading/v2/styles.ts +273 -0
- package/src/exports/a.ts +26 -0
- package/src/exports/b.ts +26 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Heading/v1/index.d.ts.map +1 -0
- package/types/Heading/v1/props.d.ts.map +1 -0
- package/types/Heading/v1/styles.d.ts.map +1 -0
- package/types/Heading/v1/theme.d.ts.map +1 -0
- package/types/Heading/v2/index.d.ts +40 -0
- package/types/Heading/v2/index.d.ts.map +1 -0
- package/types/Heading/v2/props.d.ts +62 -0
- package/types/Heading/v2/props.d.ts.map +1 -0
- package/types/Heading/v2/styles.d.ts +14 -0
- package/types/Heading/v2/styles.d.ts.map +1 -0
- package/types/exports/a.d.ts +3 -0
- package/types/exports/a.d.ts.map +1 -0
- package/types/exports/b.d.ts +3 -0
- package/types/exports/b.d.ts.map +1 -0
- package/types/Heading/index.d.ts.map +0 -1
- package/types/Heading/props.d.ts.map +0 -1
- package/types/Heading/styles.d.ts.map +0 -1
- package/types/Heading/theme.d.ts.map +0 -1
- package/types/index.d.ts +0 -3
- package/types/index.d.ts.map +0 -1
- /package/es/Heading/{props.js → v1/props.js} +0 -0
- /package/es/Heading/{styles.js → v1/styles.js} +0 -0
- /package/es/Heading/{theme.js → v1/theme.js} +0 -0
- /package/lib/Heading/{props.js → v1/props.js} +0 -0
- /package/lib/Heading/{styles.js → v1/styles.js} +0 -0
- /package/lib/Heading/{theme.js → v1/theme.js} +0 -0
- /package/src/Heading/{README.md → v1/README.md} +0 -0
- /package/src/Heading/{props.ts → v1/props.ts} +0 -0
- /package/src/Heading/{styles.ts → v1/styles.ts} +0 -0
- /package/src/Heading/{theme.ts → v1/theme.ts} +0 -0
- /package/types/Heading/{index.d.ts → v1/index.d.ts} +0 -0
- /package/types/Heading/{props.d.ts → v1/props.d.ts} +0 -0
- /package/types/Heading/{styles.d.ts → v1/styles.d.ts} +0 -0
- /package/types/Heading/{theme.d.ts → v1/theme.d.ts} +0 -0
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
|
|
25
25
|
import { Component } from 'react'
|
|
26
26
|
|
|
27
|
-
import { View } from '@instructure/ui-view'
|
|
27
|
+
import { View } from '@instructure/ui-view/v11_6'
|
|
28
28
|
import { passthroughProps, callRenderProp } from '@instructure/ui-react-utils'
|
|
29
29
|
import { IconAiColoredSolid } from '@instructure/ui-icons'
|
|
30
30
|
|
|
31
|
-
import { withStyle } from '@instructure/emotion'
|
|
31
|
+
import { withStyleLegacy as withStyle } from '@instructure/emotion'
|
|
32
32
|
|
|
33
33
|
import generateStyle from './styles'
|
|
34
34
|
import generateComponentTheme from './theme'
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
describes: Heading
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Heading is a component for creating typographic headings.
|
|
6
|
+
|
|
7
|
+
### Variant
|
|
8
|
+
|
|
9
|
+
Variant covers almost all use cases for headings on pages. Their name reflects the places they meant to be used. It takes care of the style of the heading
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
---
|
|
13
|
+
type: embed
|
|
14
|
+
---
|
|
15
|
+
<Alert variant="info">
|
|
16
|
+
<List margin="0 0 medium">
|
|
17
|
+
<List.Item>For legacy reasons, each <code>variant</code> has a default <code>level</code> set. This is not the recommended way and will be removed in a later major release. Please always specify the <code>level</code>!</List.Item>
|
|
18
|
+
<List.Item>When <code>variant</code> is set the <code>as</code> prop is ignored</List.Item>
|
|
19
|
+
<List.Item>A11Y GUIDELINE: There can be only one <code>h1</code> tag in a page</List.Item>
|
|
20
|
+
<List.Item>A11Y GUIDELINE: <code>h</code> tags can not skip a level, so for example an <code>h1</code> followed by an <code>h3</code> not allowed</List.Item>
|
|
21
|
+
</List>
|
|
22
|
+
</Alert>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
---
|
|
27
|
+
type: example
|
|
28
|
+
---
|
|
29
|
+
<div>
|
|
30
|
+
<Heading variant="titlePageDesktop" level="h1"> titlePageDesktop </Heading><br/>
|
|
31
|
+
<Heading variant="titlePageMobile" level="h1"> titlePageMobile </Heading><br/>
|
|
32
|
+
<Heading variant="titleSection" level="h2"> titleSection </Heading><br/>
|
|
33
|
+
<Heading variant="titleCardSection" level="h2"> titleCardSection </Heading><br/>
|
|
34
|
+
<Heading variant="titleModule" level="h2"> titleModule </Heading><br/>
|
|
35
|
+
<Heading variant="titleCardLarge" level="h3"> titleCardLarge </Heading><br/>
|
|
36
|
+
<Heading variant="titleCardRegular" level="h3"> titleCardRegular </Heading><br/>
|
|
37
|
+
<Heading variant="titleCardMini" level="h4"> titleCardMini </Heading><br/>
|
|
38
|
+
<Heading variant="label" level="h5"> label </Heading><br/>
|
|
39
|
+
<Heading variant="labelInline" level="h6"> labelInline </Heading><br/>
|
|
40
|
+
</div>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### AI Heading
|
|
44
|
+
|
|
45
|
+
Pre-configured and with unique styles, the `ai-headings` are used for standardized, ai-related components.
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
---
|
|
49
|
+
type: example
|
|
50
|
+
---
|
|
51
|
+
<div style={{display: 'flex', flexDirection: 'column', gap: '24px'}}>
|
|
52
|
+
<Heading aiVariant="stacked" level="h2">Nutrition Facts</Heading>
|
|
53
|
+
<Heading aiVariant="horizontal" level="h3">Nutrition Facts</Heading>
|
|
54
|
+
<Heading aiVariant="iconOnly" level="h4">Nutrition Facts</Heading>
|
|
55
|
+
</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Heading level
|
|
59
|
+
|
|
60
|
+
What DOM element is output is determined in the following order:
|
|
61
|
+
|
|
62
|
+
1. (deprecated) If the variant prop is set, then the value of level prop. If variant is set but level is not, <h1>-<h6> based on the variant prop's value.
|
|
63
|
+
2. The value of the `as` prop
|
|
64
|
+
3. The value of the `level` prop
|
|
65
|
+
4. `<h2>`
|
|
66
|
+
|
|
67
|
+
The `variant` and `level` props sets its appearance in this order.
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
---
|
|
71
|
+
type: example
|
|
72
|
+
---
|
|
73
|
+
<div>
|
|
74
|
+
<Heading level="h1" as="h3" margin="0 0 x-small">This renders as <code><h3></code></Heading>
|
|
75
|
+
</div>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Heading colors
|
|
79
|
+
|
|
80
|
+
The default color is `primary`, but it can be set to `secondary`, `primary-on`, `secondary-on` or `inherit` via the `color` prop. Note there is an inverse option available as well: `primary-inverse` or `secondary-inverse` (_see inverse example below_).
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
---
|
|
84
|
+
type: example
|
|
85
|
+
---
|
|
86
|
+
<div >
|
|
87
|
+
<div style={{color: '#0084D1'}}>
|
|
88
|
+
<Heading color="inherit">I inherit my color via the CSS cascade</Heading>
|
|
89
|
+
</div>
|
|
90
|
+
<Heading color="primary">I am primary color (default)</Heading>
|
|
91
|
+
<Heading color="secondary">I am secondary color</Heading>
|
|
92
|
+
<View background="primary-inverse" as="div">
|
|
93
|
+
<Heading color="primary-inverse">I am primary-inverse color</Heading>
|
|
94
|
+
<Heading color="secondary-inverse">I am secondary-inverse color</Heading>
|
|
95
|
+
</View>
|
|
96
|
+
<View background="alert" as="div">
|
|
97
|
+
<Heading color="primary-on">I am primary-on color</Heading>
|
|
98
|
+
<Heading color="secondary-on">I am secondary-on color</Heading>
|
|
99
|
+
</View>
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Icons
|
|
104
|
+
|
|
105
|
+
With the `renderIcon` prop, an icon can be rendered before the text.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
---
|
|
109
|
+
type: example
|
|
110
|
+
---
|
|
111
|
+
<div>
|
|
112
|
+
<Heading renderIcon={<ShieldUserInstUIIcon/>}>I am heading with icon</Heading>
|
|
113
|
+
</div>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Heading borders
|
|
117
|
+
|
|
118
|
+
The default is no borders. However, using the `border` prop, you can
|
|
119
|
+
add either `top` or `bottom` borders to your heading.
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
---
|
|
123
|
+
type: example
|
|
124
|
+
---
|
|
125
|
+
<div>
|
|
126
|
+
<Heading margin="0 0 medium" border="bottom">I have a bottom border</Heading>
|
|
127
|
+
<Heading border="top">I have a top border</Heading>
|
|
128
|
+
</div>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Ellipsis text overflow
|
|
132
|
+
|
|
133
|
+
Use [TruncateText](TruncateText) if you need to constrain your
|
|
134
|
+
Heading to a single line (or certain number of lines).
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
---
|
|
138
|
+
type: example
|
|
139
|
+
---
|
|
140
|
+
<Heading level="h2">
|
|
141
|
+
<TruncateText>{lorem.paragraph()}</TruncateText>
|
|
142
|
+
</Heading>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Guidelines
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
---
|
|
149
|
+
type: embed
|
|
150
|
+
---
|
|
151
|
+
<Guidelines>
|
|
152
|
+
<Figure recommendation="a11y" title="Accessibility">
|
|
153
|
+
<Figure.Item>Each page should always contain one and only one H1</Figure.Item>
|
|
154
|
+
<Figure.Item>Headings should be used in logical order</Figure.Item>
|
|
155
|
+
<Figure.Item>Headings should not be used to format text</Figure.Item>
|
|
156
|
+
</Figure>
|
|
157
|
+
</Guidelines>
|
|
158
|
+
```
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { Component } from 'react'
|
|
26
|
+
|
|
27
|
+
import { View } from '@instructure/ui-view/latest'
|
|
28
|
+
import { passthroughProps } from '@instructure/ui-react-utils'
|
|
29
|
+
import { StarsInstUIIcon, renderIconWithProps } from '@instructure/ui-icons'
|
|
30
|
+
|
|
31
|
+
import { withStyle } from '@instructure/emotion'
|
|
32
|
+
|
|
33
|
+
import generateStyle from './styles'
|
|
34
|
+
|
|
35
|
+
import { allowedProps } from './props'
|
|
36
|
+
import type { HeadingProps } from './props'
|
|
37
|
+
import { AsElementType } from '@instructure/shared-types'
|
|
38
|
+
|
|
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
|
+
|
|
55
|
+
const variantToIconSize: Record<
|
|
56
|
+
NonNullable<HeadingProps['variant']>,
|
|
57
|
+
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
58
|
+
> = {
|
|
59
|
+
titlePageDesktop: '2xl',
|
|
60
|
+
titlePageMobile: 'xl',
|
|
61
|
+
titleSection: 'xl',
|
|
62
|
+
titleCardSection: 'xl',
|
|
63
|
+
titleModule: 'xl',
|
|
64
|
+
titleCardLarge: 'xl',
|
|
65
|
+
titleCardRegular: 'lg',
|
|
66
|
+
titleCardMini: 'md',
|
|
67
|
+
label: 'md',
|
|
68
|
+
labelInline: 'md'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const levelToIconSize: Record<
|
|
72
|
+
Exclude<HeadingProps['level'], 'reset' | undefined>,
|
|
73
|
+
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
74
|
+
> = {
|
|
75
|
+
h1: '2xl',
|
|
76
|
+
h2: 'xl',
|
|
77
|
+
h3: 'xl',
|
|
78
|
+
h4: 'lg',
|
|
79
|
+
h5: 'md',
|
|
80
|
+
h6: 'md'
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const variantToAIHorizontalIconSize: Record<
|
|
84
|
+
NonNullable<HeadingProps['variant']>,
|
|
85
|
+
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
86
|
+
> = {
|
|
87
|
+
titlePageDesktop: '2xl',
|
|
88
|
+
titlePageMobile: 'xl',
|
|
89
|
+
titleSection: 'xl',
|
|
90
|
+
titleCardSection: 'xl',
|
|
91
|
+
titleModule: 'md',
|
|
92
|
+
titleCardLarge: 'md',
|
|
93
|
+
titleCardRegular: 'md',
|
|
94
|
+
titleCardMini: 'xs',
|
|
95
|
+
label: 'xs',
|
|
96
|
+
labelInline: 'xs'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const levelToAIHorizontalIconSize: Record<
|
|
100
|
+
Exclude<HeadingProps['level'], 'reset' | undefined>,
|
|
101
|
+
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
102
|
+
> = {
|
|
103
|
+
h1: '2xl',
|
|
104
|
+
h2: 'lg',
|
|
105
|
+
h3: 'md',
|
|
106
|
+
h4: 'sm',
|
|
107
|
+
h5: 'xs',
|
|
108
|
+
h6: 'xs'
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
---
|
|
113
|
+
category: components
|
|
114
|
+
---
|
|
115
|
+
**/
|
|
116
|
+
@withStyle(generateStyle)
|
|
117
|
+
class Heading extends Component<HeadingProps> {
|
|
118
|
+
static readonly componentId = 'Heading'
|
|
119
|
+
|
|
120
|
+
static allowedProps = allowedProps
|
|
121
|
+
static defaultProps = {
|
|
122
|
+
children: null,
|
|
123
|
+
border: 'none',
|
|
124
|
+
color: 'primary'
|
|
125
|
+
} as const
|
|
126
|
+
|
|
127
|
+
ref: Element | null = null
|
|
128
|
+
|
|
129
|
+
handleRef = (el: Element | null) => {
|
|
130
|
+
const { elementRef } = this.props
|
|
131
|
+
|
|
132
|
+
this.ref = el
|
|
133
|
+
|
|
134
|
+
if (typeof elementRef === 'function') {
|
|
135
|
+
elementRef(el)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
checkProps() {
|
|
140
|
+
const { variant, as } = this.props
|
|
141
|
+
if (variant) {
|
|
142
|
+
if (as) {
|
|
143
|
+
console.warn("[Heading]: Don't use 'as' with 'variant' ")
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
componentDidMount() {
|
|
149
|
+
this.props.makeStyles?.()
|
|
150
|
+
this.checkProps()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
componentDidUpdate() {
|
|
154
|
+
this.props.makeStyles?.()
|
|
155
|
+
this.checkProps()
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
getIconSize(forAIHorizontal = false) {
|
|
159
|
+
const { variant, level, as } = this.props
|
|
160
|
+
|
|
161
|
+
if (variant) {
|
|
162
|
+
return forAIHorizontal
|
|
163
|
+
? variantToAIHorizontalIconSize[variant]
|
|
164
|
+
: variantToIconSize[variant]
|
|
165
|
+
}
|
|
166
|
+
if (level && level !== 'reset') {
|
|
167
|
+
return forAIHorizontal
|
|
168
|
+
? levelToAIHorizontalIconSize[level]
|
|
169
|
+
: levelToIconSize[level]
|
|
170
|
+
}
|
|
171
|
+
if (
|
|
172
|
+
as &&
|
|
173
|
+
typeof as === 'string' &&
|
|
174
|
+
['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(as)
|
|
175
|
+
) {
|
|
176
|
+
const asLevel = as as Exclude<HeadingProps['level'], 'reset' | undefined>
|
|
177
|
+
return forAIHorizontal
|
|
178
|
+
? levelToAIHorizontalIconSize[asLevel]
|
|
179
|
+
: levelToIconSize[asLevel]
|
|
180
|
+
}
|
|
181
|
+
return 'md'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
renderContent() {
|
|
185
|
+
const { children, renderIcon, aiVariant } = this.props
|
|
186
|
+
|
|
187
|
+
if (renderIcon && !aiVariant) {
|
|
188
|
+
return (
|
|
189
|
+
<span css={[this.props.styles?.withIcon]} aria-hidden="true">
|
|
190
|
+
{renderIconWithProps(renderIcon, this.getIconSize(), 'inherit')}
|
|
191
|
+
{children}
|
|
192
|
+
</span>
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
if (aiVariant === 'stacked') {
|
|
196
|
+
return (
|
|
197
|
+
<span css={[this.props.styles?.withIcon]} aria-hidden="true">
|
|
198
|
+
<span css={this.props.styles?.igniteAIStacked}>
|
|
199
|
+
<StarsInstUIIcon color="ai" size="sm" />
|
|
200
|
+
<span css={this.props.styles?.igniteAI}>IgniteAI</span>
|
|
201
|
+
</span>
|
|
202
|
+
{children}
|
|
203
|
+
</span>
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
if (aiVariant === 'horizontal') {
|
|
207
|
+
return (
|
|
208
|
+
<span css={this.props.styles?.withIcon} aria-hidden="true">
|
|
209
|
+
<span css={this.props.styles?.igniteAIHorizontal}>
|
|
210
|
+
<StarsInstUIIcon color="ai" size={this.getIconSize(true)} />
|
|
211
|
+
<span css={this.props.styles?.igniteAI}>IgniteAI</span>
|
|
212
|
+
</span>
|
|
213
|
+
{children}
|
|
214
|
+
</span>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
if (aiVariant === 'iconOnly') {
|
|
218
|
+
return (
|
|
219
|
+
<span css={this.props.styles?.withIcon} aria-hidden="true">
|
|
220
|
+
<StarsInstUIIcon color="ai" size={this.getIconSize(true)} />
|
|
221
|
+
{children}
|
|
222
|
+
</span>
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
return children
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
//overriding default screen reader functionality is needed to read spans in h tags correctly
|
|
229
|
+
getAriaLabel() {
|
|
230
|
+
const { aiVariant, children, renderIcon } = this.props
|
|
231
|
+
if (aiVariant === 'stacked' || aiVariant === 'horizontal') {
|
|
232
|
+
return `IgniteAI, ${children}`
|
|
233
|
+
}
|
|
234
|
+
if (aiVariant === 'iconOnly' || renderIcon) {
|
|
235
|
+
return `${children}`
|
|
236
|
+
}
|
|
237
|
+
return undefined
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
render() {
|
|
241
|
+
const {
|
|
242
|
+
border,
|
|
243
|
+
children,
|
|
244
|
+
color,
|
|
245
|
+
level,
|
|
246
|
+
margin,
|
|
247
|
+
elementRef,
|
|
248
|
+
makeStyles,
|
|
249
|
+
variant,
|
|
250
|
+
...props
|
|
251
|
+
} = this.props
|
|
252
|
+
|
|
253
|
+
let ElementType: AsElementType = 'h2'
|
|
254
|
+
if (variant) {
|
|
255
|
+
// TODO deprecated, remove. `variant` should not set DOM level
|
|
256
|
+
if (level) {
|
|
257
|
+
if (level === 'reset') {
|
|
258
|
+
ElementType = 'span'
|
|
259
|
+
} else {
|
|
260
|
+
ElementType = level
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
ElementType = variantLevels[variant]
|
|
264
|
+
}
|
|
265
|
+
} else if (props.as) {
|
|
266
|
+
ElementType = props.as
|
|
267
|
+
} else if (level) {
|
|
268
|
+
if (level === 'reset') {
|
|
269
|
+
ElementType = 'span'
|
|
270
|
+
} else {
|
|
271
|
+
ElementType = level
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return (
|
|
275
|
+
<View
|
|
276
|
+
aria-label={this.getAriaLabel()}
|
|
277
|
+
{...passthroughProps(props)}
|
|
278
|
+
css={this.props.styles?.heading}
|
|
279
|
+
as={ElementType}
|
|
280
|
+
elementRef={this.handleRef}
|
|
281
|
+
margin={margin}
|
|
282
|
+
data-cid="Heading"
|
|
283
|
+
>
|
|
284
|
+
{this.renderContent()}
|
|
285
|
+
</View>
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export default Heading
|
|
291
|
+
export { Heading }
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import React from 'react'
|
|
26
|
+
import type {
|
|
27
|
+
AsElementType,
|
|
28
|
+
HeadingTheme,
|
|
29
|
+
OtherHTMLAttributes,
|
|
30
|
+
Renderable
|
|
31
|
+
} from '@instructure/shared-types'
|
|
32
|
+
import type {
|
|
33
|
+
Spacing,
|
|
34
|
+
WithStyleProps,
|
|
35
|
+
ComponentStyle
|
|
36
|
+
} from '@instructure/emotion'
|
|
37
|
+
|
|
38
|
+
type HeadingLevel<U extends keyof React.JSX.IntrinsicElements> = U
|
|
39
|
+
|
|
40
|
+
type HeadingOwnProps = {
|
|
41
|
+
/**
|
|
42
|
+
* transforms heading into an `ai` variant
|
|
43
|
+
*/
|
|
44
|
+
aiVariant?: 'stacked' | 'horizontal' | 'iconOnly'
|
|
45
|
+
/**
|
|
46
|
+
* The text content of the Heading
|
|
47
|
+
*/
|
|
48
|
+
children?: React.ReactNode // TODO: childrenOrValue or is it even needed?
|
|
49
|
+
/**
|
|
50
|
+
* Add a top- or bottom-border to the Heading
|
|
51
|
+
*/
|
|
52
|
+
border?: 'none' | 'top' | 'bottom'
|
|
53
|
+
/**
|
|
54
|
+
* The font color to render, NOTE: `ai` color is deprecated. Use the `aiVariant` prop instead
|
|
55
|
+
*/
|
|
56
|
+
color?:
|
|
57
|
+
| 'primary'
|
|
58
|
+
| 'secondary'
|
|
59
|
+
| 'primary-inverse'
|
|
60
|
+
| 'secondary-inverse'
|
|
61
|
+
| 'inherit'
|
|
62
|
+
| 'primary-on'
|
|
63
|
+
| 'secondary-on'
|
|
64
|
+
| 'ai'
|
|
65
|
+
/**
|
|
66
|
+
* The level of the heading in the DOM: h1 is largest; h6 is smallest.
|
|
67
|
+
*/
|
|
68
|
+
level?: HeadingLevel<'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'> | 'reset'
|
|
69
|
+
/**
|
|
70
|
+
* What DOM element is output is determined in the following order:
|
|
71
|
+
* 1. (deprecated) If `variant` is set, then use the `level` prop, if that's
|
|
72
|
+
* not set use `<h1>`-`<h6>` based on the `variant` prop's value
|
|
73
|
+
* 2. The value of the `as` prop
|
|
74
|
+
* 3. The value of the `level` prop
|
|
75
|
+
* 4. `<h2>`
|
|
76
|
+
*/
|
|
77
|
+
as?: AsElementType
|
|
78
|
+
/**
|
|
79
|
+
* Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`,
|
|
80
|
+
* `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via
|
|
81
|
+
* familiar CSS-like shorthand. For example: `margin="small auto large"`.
|
|
82
|
+
*/
|
|
83
|
+
margin?: Spacing
|
|
84
|
+
/**
|
|
85
|
+
* Provides a ref to the underlying HTML element
|
|
86
|
+
*/
|
|
87
|
+
elementRef?: (element: Element | null) => void
|
|
88
|
+
/**
|
|
89
|
+
* An icon, or function that returns an icon that gets displayed before the text.
|
|
90
|
+
*/
|
|
91
|
+
renderIcon?: Renderable
|
|
92
|
+
/**
|
|
93
|
+
* Sets appearance of the heading. Will also set its heading level, if not
|
|
94
|
+
* specified by the `level` prop (deprecated, not recommended!)
|
|
95
|
+
*/
|
|
96
|
+
variant?:
|
|
97
|
+
| 'titlePageDesktop'
|
|
98
|
+
| 'titlePageMobile'
|
|
99
|
+
| 'titleSection'
|
|
100
|
+
| 'titleCardSection'
|
|
101
|
+
| 'titleModule'
|
|
102
|
+
| 'titleCardLarge'
|
|
103
|
+
| 'titleCardRegular'
|
|
104
|
+
| 'titleCardMini'
|
|
105
|
+
| 'label'
|
|
106
|
+
| 'labelInline'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
type PropKeys = keyof HeadingOwnProps
|
|
110
|
+
|
|
111
|
+
type AllowedPropKeys = Readonly<Array<PropKeys>>
|
|
112
|
+
|
|
113
|
+
type HeadingProps = HeadingOwnProps &
|
|
114
|
+
WithStyleProps<HeadingTheme, HeadingStyle> &
|
|
115
|
+
OtherHTMLAttributes<HeadingOwnProps>
|
|
116
|
+
|
|
117
|
+
type HeadingStyle = ComponentStyle<
|
|
118
|
+
'heading' | 'igniteAI' | 'igniteAIStacked' | 'igniteAIHorizontal' | 'withIcon'
|
|
119
|
+
>
|
|
120
|
+
const allowedProps: AllowedPropKeys = [
|
|
121
|
+
'aiVariant',
|
|
122
|
+
'border',
|
|
123
|
+
'children',
|
|
124
|
+
'color',
|
|
125
|
+
'level',
|
|
126
|
+
'as',
|
|
127
|
+
'margin',
|
|
128
|
+
'elementRef',
|
|
129
|
+
'variant'
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
export type { HeadingProps, HeadingStyle }
|
|
133
|
+
export { allowedProps }
|