@instructure/emotion 8.9.2-snapshot.2 → 8.9.2-snapshot.9
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/es/EmotionThemeProvider/index.js +3 -3
- package/es/EmotionTypes.js +1 -0
- package/es/getComponentThemeOverride.js +16 -4
- package/es/index.js +2 -2
- package/es/styleUtils/ThemeablePropTypes.js +5 -5
- package/es/styleUtils/bidirectionalPolyfill.js +8 -5
- package/es/useTheme.js +6 -3
- package/es/withStyle.js +10 -8
- package/lib/EmotionThemeProvider/index.js +4 -4
- package/lib/EmotionTypes.js +1 -0
- package/lib/getComponentThemeOverride.js +16 -5
- package/lib/index.js +51 -26
- package/lib/styleUtils/ThemeablePropTypes.js +5 -5
- package/lib/styleUtils/bidirectionalPolyfill.js +7 -5
- package/lib/useTheme.js +4 -2
- package/lib/withStyle.js +11 -9
- package/package.json +10 -10
- package/src/EmotionThemeProvider/index.tsx +11 -22
- package/src/EmotionTypes.ts +89 -0
- package/src/getComponentThemeOverride.ts +33 -11
- package/src/index.ts +23 -2
- package/src/styleUtils/ThemeablePropTypes.ts +36 -12
- package/src/styleUtils/ThemeablePropValues.ts +1 -1
- package/src/styleUtils/bidirectionalPolyfill.ts +29 -10
- package/src/styleUtils/getShorthandPropValue.ts +1 -0
- package/src/styleUtils/makeThemeVars.ts +5 -5
- package/src/styleUtils/mirrorShorthandCorners.ts +1 -0
- package/src/styleUtils/mirrorShorthandEdges.ts +1 -0
- package/src/useTheme.ts +7 -2
- package/src/withStyle.tsx +88 -18
- package/types/EmotionThemeProvider/index.d.ts +1 -15
- package/types/EmotionThemeProvider/index.d.ts.map +1 -1
- package/types/EmotionTypes.d.ts +29 -0
- package/types/EmotionTypes.d.ts.map +1 -0
- package/types/getComponentThemeOverride.d.ts +14 -2
- package/types/getComponentThemeOverride.d.ts.map +1 -1
- package/types/index.d.ts +5 -2
- package/types/index.d.ts.map +1 -1
- package/types/styleUtils/ThemeablePropTypes.d.ts +8 -6
- package/types/styleUtils/ThemeablePropTypes.d.ts.map +1 -1
- package/types/styleUtils/ThemeablePropValues.d.ts +1 -1
- package/types/styleUtils/ThemeablePropValues.d.ts.map +1 -1
- package/types/styleUtils/bidirectionalPolyfill.d.ts +5 -1
- package/types/styleUtils/bidirectionalPolyfill.d.ts.map +1 -1
- package/types/styleUtils/getShorthandPropValue.d.ts.map +1 -1
- package/types/styleUtils/makeThemeVars.d.ts +4 -5
- package/types/styleUtils/makeThemeVars.d.ts.map +1 -1
- package/types/styleUtils/mirrorShorthandCorners.d.ts.map +1 -1
- package/types/styleUtils/mirrorShorthandEdges.d.ts.map +1 -1
- package/types/useTheme.d.ts +4 -1
- package/types/useTheme.d.ts.map +1 -1
- package/types/withStyle.d.ts +11 -5
- package/types/withStyle.d.ts.map +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
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 type {
|
|
26
|
+
BaseTheme,
|
|
27
|
+
ComponentTheme,
|
|
28
|
+
ComponentThemeMap,
|
|
29
|
+
DeepPartial
|
|
30
|
+
} from '@instructure/shared-types'
|
|
31
|
+
|
|
32
|
+
type PartialTheme = DeepPartial<Omit<BaseTheme, 'key'>>
|
|
33
|
+
|
|
34
|
+
type ComponentOverride =
|
|
35
|
+
| DeepPartial<ComponentThemeMap>
|
|
36
|
+
// this is needed for user defined components which we can't possibly type
|
|
37
|
+
| { [otherComponent: string]: ComponentTheme }
|
|
38
|
+
|
|
39
|
+
type SpecificThemeOverride = {
|
|
40
|
+
[key: string]: PartialTheme | { componentOverrides?: ComponentOverride }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type ThemeOverride = PartialTheme | SpecificThemeOverride
|
|
44
|
+
|
|
45
|
+
type Overrides = {
|
|
46
|
+
themeOverrides?: ThemeOverride
|
|
47
|
+
componentOverrides?: ComponentOverride
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type ThemeOrOverride = BaseTheme | PartialTheme | Overrides
|
|
51
|
+
|
|
52
|
+
type Props = Record<string, unknown>
|
|
53
|
+
type State = Record<string, unknown>
|
|
54
|
+
|
|
55
|
+
type GenerateComponentTheme = (
|
|
56
|
+
theme: BaseTheme | PartialTheme
|
|
57
|
+
) => ComponentTheme
|
|
58
|
+
|
|
59
|
+
type GenerateStyle = (
|
|
60
|
+
componentTheme: ComponentTheme,
|
|
61
|
+
props: Props,
|
|
62
|
+
state?: State
|
|
63
|
+
) => StyleObject
|
|
64
|
+
|
|
65
|
+
type ComponentStyle<Keys extends string = string> = Record<
|
|
66
|
+
Keys,
|
|
67
|
+
StyleObject | string | number | undefined
|
|
68
|
+
>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Style object returned by the generateStyle method of the components
|
|
72
|
+
*/
|
|
73
|
+
export interface StyleObject {
|
|
74
|
+
[key: string]: StyleObject | string | number | undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type {
|
|
78
|
+
ThemeOrOverride,
|
|
79
|
+
Overrides,
|
|
80
|
+
ComponentOverride,
|
|
81
|
+
SpecificThemeOverride,
|
|
82
|
+
ThemeOverride,
|
|
83
|
+
PartialTheme,
|
|
84
|
+
Props,
|
|
85
|
+
State,
|
|
86
|
+
GenerateComponentTheme,
|
|
87
|
+
GenerateStyle,
|
|
88
|
+
ComponentStyle
|
|
89
|
+
}
|
|
@@ -22,6 +22,16 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
import type {
|
|
26
|
+
ThemeOrOverride,
|
|
27
|
+
Overrides,
|
|
28
|
+
ComponentOverride
|
|
29
|
+
} from './EmotionTypes'
|
|
30
|
+
import type { ComponentTheme } from '@instructure/shared-types'
|
|
31
|
+
import type { WithStyleProps } from './withStyle'
|
|
32
|
+
|
|
33
|
+
type ComponentName = keyof ComponentOverride | undefined
|
|
34
|
+
|
|
25
35
|
/**
|
|
26
36
|
* ---
|
|
27
37
|
* private: true
|
|
@@ -30,19 +40,31 @@
|
|
|
30
40
|
* based on every possible override there is.
|
|
31
41
|
|
|
32
42
|
* @param {object} theme - Theme object
|
|
33
|
-
* @param {*}
|
|
43
|
+
* @param {*} displayName - Name of the component
|
|
44
|
+
* @param {*} componentId - componentId of the component
|
|
34
45
|
* @param {*} props - The component's props object
|
|
35
46
|
* @returns {object} The calculated theme override object
|
|
36
47
|
*/
|
|
37
|
-
|
|
38
|
-
theme:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
const getComponentThemeOverride = (
|
|
49
|
+
theme: ThemeOrOverride,
|
|
50
|
+
displayName: string,
|
|
51
|
+
componentId?: string,
|
|
52
|
+
props?: { [k: string]: unknown } & WithStyleProps
|
|
53
|
+
): ComponentTheme => {
|
|
54
|
+
let componentOverride: ComponentTheme = {}
|
|
55
|
+
const overrides = (theme as Overrides).componentOverrides
|
|
56
|
+
const name = displayName as ComponentName
|
|
57
|
+
const id = componentId as ComponentName
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
if (overrides) {
|
|
60
|
+
componentOverride = (name && overrides[name]) || (id && overrides[id]) || {}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
...componentOverride,
|
|
65
|
+
...(props?.themeOverride ?? {})
|
|
66
|
+
}
|
|
48
67
|
}
|
|
68
|
+
|
|
69
|
+
export default getComponentThemeOverride
|
|
70
|
+
export { getComponentThemeOverride }
|
package/src/index.ts
CHANGED
|
@@ -26,5 +26,26 @@
|
|
|
26
26
|
export * from '@emotion/react'
|
|
27
27
|
|
|
28
28
|
export { EmotionThemeProvider } from './EmotionThemeProvider'
|
|
29
|
-
export
|
|
30
|
-
export
|
|
29
|
+
export { withStyle } from './withStyle'
|
|
30
|
+
export {
|
|
31
|
+
ThemeablePropValues,
|
|
32
|
+
ThemeablePropTypes,
|
|
33
|
+
makeThemeVars,
|
|
34
|
+
getShorthandPropValue,
|
|
35
|
+
mirrorShorthandCorners,
|
|
36
|
+
mirrorShorthandEdges
|
|
37
|
+
} from './styleUtils'
|
|
38
|
+
|
|
39
|
+
export type { ComponentStyle } from './EmotionTypes'
|
|
40
|
+
export type { WithStyleProps } from './withStyle'
|
|
41
|
+
export type {
|
|
42
|
+
SpacingValues,
|
|
43
|
+
Spacing,
|
|
44
|
+
Shadow,
|
|
45
|
+
Stacking,
|
|
46
|
+
Background,
|
|
47
|
+
BorderRadiiValues,
|
|
48
|
+
BorderRadii,
|
|
49
|
+
BorderWidthValues,
|
|
50
|
+
BorderWidth
|
|
51
|
+
} from './styleUtils'
|
|
@@ -25,6 +25,14 @@
|
|
|
25
25
|
import PropTypes from 'prop-types'
|
|
26
26
|
|
|
27
27
|
import { ThemeablePropValues } from './ThemeablePropValues'
|
|
28
|
+
import type {
|
|
29
|
+
BorderRadiiValues,
|
|
30
|
+
BorderRadii,
|
|
31
|
+
BorderWidthValues,
|
|
32
|
+
BorderWidth,
|
|
33
|
+
SpacingValues,
|
|
34
|
+
Spacing
|
|
35
|
+
} from './ThemeablePropValues'
|
|
28
36
|
|
|
29
37
|
const {
|
|
30
38
|
SHADOW_TYPES,
|
|
@@ -53,24 +61,38 @@ const ThemeablePropTypes = {
|
|
|
53
61
|
spacing: shorthandPropType(Object.values(SPACING))
|
|
54
62
|
}
|
|
55
63
|
|
|
56
|
-
|
|
64
|
+
type ValueKeys =
|
|
65
|
+
| BorderWidthValues[]
|
|
66
|
+
| BorderRadiiValues[]
|
|
67
|
+
| SpacingValues[]
|
|
68
|
+
| string[]
|
|
69
|
+
|
|
70
|
+
function shorthandPropType<V extends ValueKeys>(
|
|
71
|
+
validValues: V
|
|
72
|
+
): PropTypes.Validator<
|
|
73
|
+
V extends BorderWidthValues[]
|
|
74
|
+
? BorderWidth
|
|
75
|
+
: V extends BorderRadiiValues[]
|
|
76
|
+
? BorderRadii
|
|
77
|
+
: V extends SpacingValues[]
|
|
78
|
+
? Spacing
|
|
79
|
+
: string[]
|
|
80
|
+
> {
|
|
57
81
|
return function (
|
|
58
|
-
props:
|
|
59
|
-
propName:
|
|
60
|
-
componentName:
|
|
61
|
-
location:
|
|
62
|
-
)
|
|
82
|
+
props: Record<string, unknown>,
|
|
83
|
+
propName: string,
|
|
84
|
+
componentName: string,
|
|
85
|
+
location: string
|
|
86
|
+
) {
|
|
63
87
|
const propValue = props[propName]
|
|
64
88
|
|
|
65
89
|
if (typeof propValue === 'undefined') {
|
|
66
|
-
return
|
|
90
|
+
return null
|
|
67
91
|
}
|
|
68
92
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (propValueType !== 'string') {
|
|
93
|
+
if (typeof propValue !== 'string') {
|
|
72
94
|
return new Error(
|
|
73
|
-
`Invalid ${location} \`${propName}\` of type \`${
|
|
95
|
+
`Invalid ${location} \`${propName}\` of type \`${typeof propValue}\` supplied to \`${componentName}\`, expected ` +
|
|
74
96
|
`a string.`
|
|
75
97
|
)
|
|
76
98
|
}
|
|
@@ -79,7 +101,7 @@ function shorthandPropType(validValues: any) {
|
|
|
79
101
|
const valuesLength = propValues.length
|
|
80
102
|
if (valuesLength > 0 && valuesLength < 5) {
|
|
81
103
|
for (let i = 0; i < valuesLength; i++) {
|
|
82
|
-
const valueIndex = validValues.indexOf(propValues[i])
|
|
104
|
+
const valueIndex = (validValues as string[]).indexOf(propValues[i])
|
|
83
105
|
if (valueIndex === -1) {
|
|
84
106
|
return new Error(
|
|
85
107
|
`Invalid ${location} \`${propName}\` \`${propValues[i]}\` supplied to \`${componentName}\`, expected ` +
|
|
@@ -95,6 +117,8 @@ function shorthandPropType(validValues: any) {
|
|
|
95
117
|
)}\`.`
|
|
96
118
|
)
|
|
97
119
|
}
|
|
120
|
+
|
|
121
|
+
return null
|
|
98
122
|
}
|
|
99
123
|
}
|
|
100
124
|
|
|
@@ -22,8 +22,12 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { consoleLog as log } from '@instructure/console'
|
|
26
25
|
import { isObject } from 'lodash'
|
|
26
|
+
import { consoleLog as log } from '@instructure/console'
|
|
27
|
+
|
|
28
|
+
import type { StyleObject } from '../EmotionTypes'
|
|
29
|
+
|
|
30
|
+
type Direction = 'ltr' | 'rtl'
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
33
|
* ---
|
|
@@ -68,8 +72,11 @@ const SUPPORT_PROPS = [
|
|
|
68
72
|
]
|
|
69
73
|
|
|
70
74
|
function processProps(
|
|
71
|
-
{
|
|
72
|
-
|
|
75
|
+
{
|
|
76
|
+
originalProp,
|
|
77
|
+
originalValue
|
|
78
|
+
}: { originalProp: string; originalValue: string | number },
|
|
79
|
+
textDirection: Direction
|
|
73
80
|
) {
|
|
74
81
|
const isLtr = textDirection === 'ltr'
|
|
75
82
|
|
|
@@ -82,7 +89,7 @@ function processProps(
|
|
|
82
89
|
case 'float':
|
|
83
90
|
case 'clear':
|
|
84
91
|
case 'textAlign':
|
|
85
|
-
if (['start', 'end'].indexOf(value) !== -1) {
|
|
92
|
+
if (['start', 'end'].indexOf(value as string) !== -1) {
|
|
86
93
|
if (value === 'start') {
|
|
87
94
|
value = start.toLowerCase()
|
|
88
95
|
} else {
|
|
@@ -155,12 +162,15 @@ function processProps(
|
|
|
155
162
|
return { prop, value }
|
|
156
163
|
}
|
|
157
164
|
|
|
158
|
-
const isSupportedProps = (prop:
|
|
165
|
+
const isSupportedProps = (prop: string) => SUPPORT_PROPS.indexOf(prop) > -1
|
|
159
166
|
|
|
160
|
-
const processStyleProps = (
|
|
167
|
+
const processStyleProps = (
|
|
168
|
+
propsObj: StyleObject | string | number | undefined,
|
|
169
|
+
dir: Direction
|
|
170
|
+
): StyleObject | string | number | undefined =>
|
|
161
171
|
isObject(propsObj)
|
|
162
172
|
? Object.entries(propsObj).reduce(
|
|
163
|
-
(accumulator
|
|
173
|
+
(accumulator, [originalProp, originalValue]) => {
|
|
164
174
|
if (isObject(originalValue)) {
|
|
165
175
|
return {
|
|
166
176
|
...accumulator,
|
|
@@ -168,7 +178,10 @@ const processStyleProps = (propsObj: any, dir: any): any =>
|
|
|
168
178
|
}
|
|
169
179
|
}
|
|
170
180
|
|
|
171
|
-
if (
|
|
181
|
+
if (
|
|
182
|
+
isSupportedProps(originalProp) &&
|
|
183
|
+
typeof originalValue !== 'undefined'
|
|
184
|
+
) {
|
|
172
185
|
const { prop, value } = processProps(
|
|
173
186
|
{ originalProp, originalValue },
|
|
174
187
|
|
|
@@ -184,11 +197,17 @@ const processStyleProps = (propsObj: any, dir: any): any =>
|
|
|
184
197
|
)
|
|
185
198
|
: propsObj
|
|
186
199
|
|
|
187
|
-
|
|
200
|
+
const bidirectionalPolyfill = <S extends StyleObject>(
|
|
201
|
+
styles: S,
|
|
202
|
+
dir: Direction
|
|
203
|
+
) =>
|
|
188
204
|
Object.entries(styles).reduce(
|
|
189
205
|
(accumulator, [style, props]) => ({
|
|
190
206
|
...accumulator,
|
|
191
207
|
[style]: processStyleProps(props, dir)
|
|
192
208
|
}),
|
|
193
209
|
{}
|
|
194
|
-
)
|
|
210
|
+
) as S
|
|
211
|
+
|
|
212
|
+
export default bidirectionalPolyfill
|
|
213
|
+
export { bidirectionalPolyfill }
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { camelize } from '@instructure/ui-utils'
|
|
26
|
-
import { BaseTheme } from '@instructure/shared-types'
|
|
27
26
|
|
|
28
|
-
type
|
|
29
|
-
|
|
27
|
+
import type { BaseTheme, BaseThemeVariables } from '@instructure/shared-types'
|
|
28
|
+
|
|
29
|
+
type ThemeVarGroup = BaseThemeVariables[keyof BaseThemeVariables]
|
|
30
30
|
type PrefixedThemeVars<
|
|
31
31
|
P extends string,
|
|
32
|
-
Variables extends Partial<
|
|
32
|
+
Variables extends Partial<ThemeVarGroup>
|
|
33
33
|
> = Variables extends Record<infer R, any>
|
|
34
34
|
? Record<
|
|
35
35
|
`${P}${R extends string ? Capitalize<R> : string}`,
|
|
@@ -48,7 +48,7 @@ type PrefixedThemeVars<
|
|
|
48
48
|
* @param {Object} vars - an object
|
|
49
49
|
* @returns {Object} a modified object with prefixed keys
|
|
50
50
|
*/
|
|
51
|
-
function makeThemeVars<P extends string, V extends Partial<
|
|
51
|
+
function makeThemeVars<P extends string, V extends Partial<ThemeVarGroup>>(
|
|
52
52
|
prefix: P,
|
|
53
53
|
vars: V
|
|
54
54
|
) {
|
package/src/useTheme.ts
CHANGED
|
@@ -26,6 +26,8 @@ import { useTheme as useEmotionTheme } from '@emotion/react'
|
|
|
26
26
|
import { canvas } from '@instructure/ui-themes'
|
|
27
27
|
import { isEmpty } from '@instructure/ui-utils'
|
|
28
28
|
|
|
29
|
+
import type { ThemeOrOverride } from './EmotionTypes'
|
|
30
|
+
|
|
29
31
|
/**
|
|
30
32
|
* ---
|
|
31
33
|
* private: true
|
|
@@ -34,8 +36,8 @@ import { isEmpty } from '@instructure/ui-utils'
|
|
|
34
36
|
* If there is no theme provided to the Context it will return the default `canvas` theme.
|
|
35
37
|
* @returns {object} the theme object
|
|
36
38
|
*/
|
|
37
|
-
|
|
38
|
-
let theme = useEmotionTheme()
|
|
39
|
+
const useTheme = () => {
|
|
40
|
+
let theme = useEmotionTheme() as ThemeOrOverride
|
|
39
41
|
// TODO type theme properly, then this cast might not be needed.
|
|
40
42
|
if (isEmpty(theme as Record<string, unknown>)) {
|
|
41
43
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -47,3 +49,6 @@ export const useTheme = () => {
|
|
|
47
49
|
}
|
|
48
50
|
return theme
|
|
49
51
|
}
|
|
52
|
+
|
|
53
|
+
export default useTheme
|
|
54
|
+
export { useTheme }
|
package/src/withStyle.tsx
CHANGED
|
@@ -22,20 +22,59 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import React, {
|
|
26
|
-
import {
|
|
25
|
+
import React, { ComponentClass, forwardRef, useState } from 'react'
|
|
26
|
+
import type {
|
|
27
|
+
ForwardRefExoticComponent,
|
|
28
|
+
PropsWithoutRef,
|
|
29
|
+
RefAttributes
|
|
30
|
+
} from 'react'
|
|
31
|
+
|
|
27
32
|
import { isEqual } from 'lodash'
|
|
28
33
|
import hoistNonReactStatics from 'hoist-non-react-statics'
|
|
34
|
+
|
|
35
|
+
import { decorator } from '@instructure/ui-decorator'
|
|
29
36
|
import { useTextDirectionContext } from '@instructure/ui-i18n'
|
|
30
37
|
import { bidirectionalPolyfill } from './styleUtils/bidirectionalPolyfill'
|
|
38
|
+
|
|
31
39
|
import { getComponentThemeOverride } from './getComponentThemeOverride'
|
|
32
40
|
import { useTheme } from './useTheme'
|
|
33
|
-
import type { CSSObject } from '@emotion/react'
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
import type { BaseTheme, ComponentTheme } from '@instructure/shared-types'
|
|
43
|
+
import type {
|
|
44
|
+
ComponentStyle,
|
|
45
|
+
ComponentOverride,
|
|
46
|
+
GenerateComponentTheme,
|
|
47
|
+
GenerateStyle,
|
|
48
|
+
Props
|
|
49
|
+
} from './EmotionTypes'
|
|
50
|
+
|
|
51
|
+
type ComponentName = keyof ComponentOverride
|
|
52
|
+
|
|
53
|
+
interface WithStyleComponent extends ComponentClass<any, any> {
|
|
54
|
+
componentId?: ComponentName
|
|
55
|
+
allowedProps?: string[]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
type WithStylePrivateProps<
|
|
59
|
+
Style extends ComponentStyle | null = ComponentStyle
|
|
60
|
+
> = Style extends null
|
|
61
|
+
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
62
|
+
{}
|
|
63
|
+
: {
|
|
64
|
+
styles?: Style
|
|
65
|
+
makeStyles?: (extraArgs?: Record<string, unknown>) => void
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type ThemeOverrideProp<Theme extends ComponentTheme | null = ComponentTheme> = {
|
|
69
|
+
themeOverride?: Partial<Theme>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
type WithStyleProps<
|
|
73
|
+
Theme extends ComponentTheme | null = ComponentTheme,
|
|
74
|
+
Style extends ComponentStyle | null = ComponentStyle
|
|
75
|
+
> = Theme extends null
|
|
76
|
+
? WithStylePrivateProps<Style>
|
|
77
|
+
: WithStylePrivateProps<Style> & ThemeOverrideProp<Theme>
|
|
39
78
|
|
|
40
79
|
/**
|
|
41
80
|
* ---
|
|
@@ -106,36 +145,56 @@ export type WithStyleProps = Partial<{
|
|
|
106
145
|
* @returns {ReactElement} The decorated WithStyle Component
|
|
107
146
|
*/
|
|
108
147
|
const withStyle = decorator(
|
|
109
|
-
(
|
|
148
|
+
(
|
|
149
|
+
ComposedComponent: WithStyleComponent,
|
|
150
|
+
generateStyle: GenerateStyle,
|
|
151
|
+
generateComponentTheme: GenerateComponentTheme
|
|
152
|
+
) => {
|
|
110
153
|
const displayName = ComposedComponent.displayName || ComposedComponent.name
|
|
111
154
|
|
|
112
|
-
const WithStyle
|
|
155
|
+
const WithStyle: ForwardRefExoticComponent<
|
|
156
|
+
PropsWithoutRef<Props> & RefAttributes<any>
|
|
157
|
+
> & {
|
|
158
|
+
generateComponentTheme?: GenerateComponentTheme
|
|
159
|
+
allowedProps?: string[]
|
|
160
|
+
} = forwardRef((props, ref) => {
|
|
113
161
|
const theme = useTheme()
|
|
114
162
|
const dir = useTextDirectionContext()
|
|
115
|
-
|
|
163
|
+
|
|
164
|
+
const componentProps: Props = {
|
|
116
165
|
...ComposedComponent.defaultProps,
|
|
117
166
|
...props
|
|
118
167
|
}
|
|
168
|
+
|
|
119
169
|
const themeOverride = getComponentThemeOverride(
|
|
120
170
|
theme,
|
|
121
|
-
|
|
171
|
+
displayName,
|
|
172
|
+
ComposedComponent.componentId,
|
|
122
173
|
componentProps
|
|
123
174
|
)
|
|
124
|
-
|
|
175
|
+
|
|
176
|
+
const componentTheme: ComponentTheme =
|
|
125
177
|
typeof generateComponentTheme === 'function'
|
|
126
|
-
? {
|
|
178
|
+
? {
|
|
179
|
+
...generateComponentTheme(theme as BaseTheme),
|
|
180
|
+
...themeOverride
|
|
181
|
+
}
|
|
127
182
|
: {}
|
|
183
|
+
|
|
128
184
|
const [styles, setStyles] = useState(
|
|
129
185
|
generateStyle
|
|
130
186
|
? bidirectionalPolyfill(
|
|
131
187
|
generateStyle(componentTheme, componentProps, {}),
|
|
188
|
+
// @ts-expect-error TODO: this shouldn't be "auto" (INSTUI-3241)
|
|
132
189
|
dir
|
|
133
190
|
)
|
|
134
191
|
: {}
|
|
135
192
|
)
|
|
136
|
-
|
|
193
|
+
|
|
194
|
+
const makeStyleHandler: WithStyleProps['makeStyles'] = (extraArgs) => {
|
|
137
195
|
const calculatedStyles = bidirectionalPolyfill(
|
|
138
|
-
generateStyle(componentTheme, componentProps,
|
|
196
|
+
generateStyle(componentTheme, componentProps, extraArgs),
|
|
197
|
+
// @ts-expect-error TODO: this shouldn't be "auto" (INSTUI-3241)
|
|
139
198
|
dir
|
|
140
199
|
)
|
|
141
200
|
if (!isEqual(calculatedStyles, styles)) {
|
|
@@ -152,14 +211,21 @@ const withStyle = decorator(
|
|
|
152
211
|
/>
|
|
153
212
|
)
|
|
154
213
|
})
|
|
214
|
+
|
|
155
215
|
hoistNonReactStatics(WithStyle, ComposedComponent)
|
|
156
|
-
|
|
216
|
+
|
|
217
|
+
// we have to pass these on, because sometimes users
|
|
157
218
|
// access propTypes of the component in other components
|
|
158
|
-
//
|
|
219
|
+
// eslint-disable-next-line react/forbid-foreign-prop-types
|
|
159
220
|
WithStyle.propTypes = ComposedComponent.propTypes
|
|
160
221
|
WithStyle.defaultProps = ComposedComponent.defaultProps
|
|
222
|
+
|
|
223
|
+
// These static fields exist on InstUI components
|
|
224
|
+
WithStyle.allowedProps = ComposedComponent.allowedProps
|
|
225
|
+
|
|
161
226
|
// we are exposing the theme generator for the docs generation
|
|
162
|
-
|
|
227
|
+
WithStyle.generateComponentTheme = generateComponentTheme
|
|
228
|
+
|
|
163
229
|
// we have to add defaults to makeStyles and styles added by this decorator
|
|
164
230
|
// eslint-disable-next-line no-param-reassign
|
|
165
231
|
ComposedComponent.defaultProps = {
|
|
@@ -167,11 +233,15 @@ const withStyle = decorator(
|
|
|
167
233
|
makeStyles: () => {},
|
|
168
234
|
styles: {}
|
|
169
235
|
}
|
|
236
|
+
|
|
170
237
|
if (process.env.NODE_ENV !== 'production') {
|
|
171
238
|
WithStyle.displayName = `WithStyle(${displayName})`
|
|
172
239
|
}
|
|
240
|
+
|
|
173
241
|
return WithStyle
|
|
174
242
|
}
|
|
175
243
|
)
|
|
244
|
+
|
|
176
245
|
export default withStyle
|
|
177
246
|
export { withStyle }
|
|
247
|
+
export type { WithStyleProps }
|
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
declare type PartialTheme = DeepPartial<Omit<BaseTheme, 'key'>>;
|
|
4
|
-
declare type ComponentOverride = DeepPartial<ComponentThemeMap> | {
|
|
5
|
-
[otherComponent: string]: Record<string, unknown>;
|
|
6
|
-
};
|
|
7
|
-
declare type ThemeOverride = PartialTheme | {
|
|
8
|
-
[key: string]: PartialTheme | {
|
|
9
|
-
componentOverrides?: ComponentOverride;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
declare type Overrides = {
|
|
13
|
-
themeOverrides?: ThemeOverride;
|
|
14
|
-
componentOverrides?: ComponentOverride;
|
|
15
|
-
};
|
|
16
|
-
declare type ThemeOrOverride = BaseTheme | PartialTheme | Overrides;
|
|
2
|
+
import type { ThemeOrOverride } from '../EmotionTypes';
|
|
17
3
|
declare type ThemeProviderProps = {
|
|
18
4
|
theme: ThemeOrOverride;
|
|
19
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/EmotionThemeProvider/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/EmotionThemeProvider/index.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,iBAAiB,CAAA;AAExB,aAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,eAAe,CAAA;CACvB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,iBAAS,oBAAoB,CAAC,EAC5B,QAAQ,EACR,KAAK,EACN,EAAE,KAAK,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,eAE7C;AA6CD,eAAe,oBAAoB,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { BaseTheme, ComponentTheme, ComponentThemeMap, DeepPartial } from '@instructure/shared-types';
|
|
2
|
+
declare type PartialTheme = DeepPartial<Omit<BaseTheme, 'key'>>;
|
|
3
|
+
declare type ComponentOverride = DeepPartial<ComponentThemeMap> | {
|
|
4
|
+
[otherComponent: string]: ComponentTheme;
|
|
5
|
+
};
|
|
6
|
+
declare type SpecificThemeOverride = {
|
|
7
|
+
[key: string]: PartialTheme | {
|
|
8
|
+
componentOverrides?: ComponentOverride;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
declare type ThemeOverride = PartialTheme | SpecificThemeOverride;
|
|
12
|
+
declare type Overrides = {
|
|
13
|
+
themeOverrides?: ThemeOverride;
|
|
14
|
+
componentOverrides?: ComponentOverride;
|
|
15
|
+
};
|
|
16
|
+
declare type ThemeOrOverride = BaseTheme | PartialTheme | Overrides;
|
|
17
|
+
declare type Props = Record<string, unknown>;
|
|
18
|
+
declare type State = Record<string, unknown>;
|
|
19
|
+
declare type GenerateComponentTheme = (theme: BaseTheme | PartialTheme) => ComponentTheme;
|
|
20
|
+
declare type GenerateStyle = (componentTheme: ComponentTheme, props: Props, state?: State) => StyleObject;
|
|
21
|
+
declare type ComponentStyle<Keys extends string = string> = Record<Keys, StyleObject | string | number | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Style object returned by the generateStyle method of the components
|
|
24
|
+
*/
|
|
25
|
+
export interface StyleObject {
|
|
26
|
+
[key: string]: StyleObject | string | number | undefined;
|
|
27
|
+
}
|
|
28
|
+
export type { ThemeOrOverride, Overrides, ComponentOverride, SpecificThemeOverride, ThemeOverride, PartialTheme, Props, State, GenerateComponentTheme, GenerateStyle, ComponentStyle };
|
|
29
|
+
//# sourceMappingURL=EmotionTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmotionTypes.d.ts","sourceRoot":"","sources":["../src/EmotionTypes.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,WAAW,EACZ,MAAM,2BAA2B,CAAA;AAElC,aAAK,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;AAEvD,aAAK,iBAAiB,GAClB,WAAW,CAAC,iBAAiB,CAAC,GAE9B;IAAE,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc,CAAA;CAAE,CAAA;AAEhD,aAAK,qBAAqB,GAAG;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG;QAAE,kBAAkB,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAA;CACzE,CAAA;AAED,aAAK,aAAa,GAAG,YAAY,GAAG,qBAAqB,CAAA;AAEzD,aAAK,SAAS,GAAG;IACf,cAAc,CAAC,EAAE,aAAa,CAAA;IAC9B,kBAAkB,CAAC,EAAE,iBAAiB,CAAA;CACvC,CAAA;AAED,aAAK,eAAe,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAA;AAE3D,aAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACpC,aAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEpC,aAAK,sBAAsB,GAAG,CAC5B,KAAK,EAAE,SAAS,GAAG,YAAY,KAC5B,cAAc,CAAA;AAEnB,aAAK,aAAa,GAAG,CACnB,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,KAAK,EACZ,KAAK,CAAC,EAAE,KAAK,KACV,WAAW,CAAA;AAEhB,aAAK,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,CACxD,IAAI,EACJ,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAC1C,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CACzD;AAED,YAAY,EACV,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,KAAK,EACL,KAAK,EACL,sBAAsB,EACtB,aAAa,EACb,cAAc,EACf,CAAA"}
|