@instructure/emotion 8.18.1-snapshot.3 → 8.19.1-snapshot.1
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 +6 -0
- package/README.md +40 -1
- package/es/InstUISettingsProvider/index.js +16 -23
- package/es/getComponentThemeOverride.js +22 -9
- package/es/withStyle.js +15 -7
- package/lib/InstUISettingsProvider/index.js +19 -23
- package/lib/getComponentThemeOverride.js +22 -9
- package/lib/withStyle.js +15 -7
- package/package.json +11 -11
- package/src/EmotionThemeProvider/README.md +12 -1
- package/src/InstUISettingsProvider/README.md +110 -0
- package/src/InstUISettingsProvider/index.tsx +39 -26
- package/src/getComponentThemeOverride.ts +29 -9
- package/src/withStyle.tsx +23 -13
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/InstUISettingsProvider/index.d.ts +25 -21
- package/types/InstUISettingsProvider/index.d.ts.map +1 -1
- package/types/getComponentThemeOverride.d.ts +4 -3
- package/types/getComponentThemeOverride.d.ts.map +1 -1
- package/types/withStyle.d.ts +13 -6
- package/types/withStyle.d.ts.map +1 -1
|
@@ -23,35 +23,45 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import React, { useContext } from 'react'
|
|
26
|
-
import
|
|
26
|
+
import PropTypes from 'prop-types'
|
|
27
27
|
import { ThemeProvider } from '@emotion/react'
|
|
28
|
-
|
|
29
|
-
import {
|
|
28
|
+
|
|
29
|
+
import { TextDirectionContext } from '@instructure/ui-i18n'
|
|
30
30
|
import { DeterministicIdContextProvider } from '@instructure/ui-react-utils'
|
|
31
|
+
|
|
32
|
+
import { getTheme } from '../EmotionThemeProvider'
|
|
33
|
+
|
|
34
|
+
import type { ThemeOrOverride } from '../EmotionTypes'
|
|
31
35
|
import type { DeterministicIdProviderValue } from '@instructure/ui-react-utils'
|
|
32
36
|
|
|
33
37
|
type InstUIProviderProps = {
|
|
38
|
+
children?: React.ReactNode
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A full theme or an override object
|
|
42
|
+
*/
|
|
34
43
|
theme?: ThemeOrOverride
|
|
35
|
-
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The text direction to use in the descendants. If not provided, it uses the following in this priority order:
|
|
47
|
+
* - The value given in a parent `TextDirectionContext`
|
|
48
|
+
* - The `dir` prop of `document.documentElement` or its `direction` CSS prop
|
|
49
|
+
* - The default `ltr`
|
|
50
|
+
*/
|
|
51
|
+
dir?: 'ltr' | 'rtl'
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) which keeps track of specific InstUI components. (generally this is used for deterministic id generation for [SSR](/#server-side-rendering))
|
|
55
|
+
*/
|
|
36
56
|
instanceCounterMap?: DeterministicIdProviderValue
|
|
37
57
|
}
|
|
38
58
|
|
|
39
|
-
/**
|
|
40
|
-
* @typedef InstUISettingsProviderSettings
|
|
41
|
-
* @type {object}
|
|
42
|
-
* @property {string} theme - A full theme or an override object
|
|
43
|
-
* @property {string} dir - The text direction to use in the descendants. If not
|
|
44
|
-
* given it uses the following in this priority order:
|
|
45
|
-
* - The value given in a parent `TextDirectionContext`
|
|
46
|
-
* - The `dir` prop of `document.documentElement` or its `direction` CSS prop
|
|
47
|
-
* - `ltr`
|
|
48
|
-
* @property {Map<string, number>} instanceCounterMap - a Map to keep track of instances
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
59
|
/**
|
|
52
60
|
* ---
|
|
53
61
|
* category: components/utilities
|
|
54
62
|
* ---
|
|
63
|
+
* @module InstUISettingsProvider
|
|
64
|
+
* @tsProps
|
|
55
65
|
*
|
|
56
66
|
* Wrapper for emotion js's [ThemeProvider](https://emotion.sh/docs/theming#themeprovider-reactcomponenttype).
|
|
57
67
|
*
|
|
@@ -101,24 +111,19 @@ type InstUIProviderProps = {
|
|
|
101
111
|
* //read our [SSR](/#server-side-rendering) guide
|
|
102
112
|
* const counter = generateInstanceCounterMap()
|
|
103
113
|
* counter.set("Alert", 5)
|
|
104
|
-
* <InstUISettingsProvider instanceCounterMap={counter}
|
|
114
|
+
* <InstUISettingsProvider instanceCounterMap={counter}>
|
|
105
115
|
* //this Alert's rendered DOM Node will have [id="Alert_5"] on it
|
|
106
116
|
* <Alert>Test!</Alert>
|
|
107
117
|
* </InstUISettingsProvider>
|
|
108
118
|
* </InstUISettingsProvider>
|
|
109
119
|
* ```
|
|
110
|
-
*
|
|
111
|
-
* @module InstUISettingsProvider
|
|
112
|
-
*
|
|
113
|
-
* @param {InstUISettingsProviderSettings} settings - A settings object
|
|
114
|
-
* @returns {ReactElement} The settings provider
|
|
115
120
|
*/
|
|
116
121
|
function InstUISettingsProvider({
|
|
117
122
|
children,
|
|
118
123
|
theme = {},
|
|
119
124
|
dir,
|
|
120
125
|
instanceCounterMap
|
|
121
|
-
}:
|
|
126
|
+
}: InstUIProviderProps) {
|
|
122
127
|
const finalDir = dir || useContext(TextDirectionContext)
|
|
123
128
|
|
|
124
129
|
if (process.env.NODE_ENV !== 'production' && finalDir === 'auto') {
|
|
@@ -138,10 +143,18 @@ function InstUISettingsProvider({
|
|
|
138
143
|
)
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
InstUISettingsProvider.propTypes = {
|
|
147
|
+
/* eslint-disable react/require-default-props */
|
|
148
|
+
children: PropTypes.node,
|
|
149
|
+
theme: PropTypes.object,
|
|
150
|
+
dir: PropTypes.oneOf(['ltr', 'rtl']),
|
|
151
|
+
instanceCounterMap: PropTypes.instanceOf(Map)
|
|
152
|
+
/* eslint-enable react/require-default-props */
|
|
153
|
+
}
|
|
154
|
+
|
|
141
155
|
InstUISettingsProvider.defaultProps = {
|
|
142
|
-
theme: {}
|
|
143
|
-
dir: undefined,
|
|
144
|
-
instanceCounterMap: undefined
|
|
156
|
+
theme: {}
|
|
145
157
|
}
|
|
158
|
+
|
|
146
159
|
export default InstUISettingsProvider
|
|
147
160
|
export { InstUISettingsProvider }
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
Overrides,
|
|
28
28
|
ComponentOverride
|
|
29
29
|
} from './EmotionTypes'
|
|
30
|
-
import type { ComponentTheme } from '@instructure/shared-types'
|
|
30
|
+
import type { BaseTheme, ComponentTheme } from '@instructure/shared-types'
|
|
31
31
|
import type { WithStyleProps } from './withStyle'
|
|
32
32
|
|
|
33
33
|
type ComponentName = keyof ComponentOverride | undefined
|
|
@@ -43,26 +43,46 @@ type ComponentName = keyof ComponentOverride | undefined
|
|
|
43
43
|
* @param {*} displayName - Name of the component
|
|
44
44
|
* @param {*} componentId - componentId of the component
|
|
45
45
|
* @param {*} props - The component's props object
|
|
46
|
+
* @param {*} componentTheme - The component's default theme
|
|
46
47
|
* @returns {object} The calculated theme override object
|
|
47
48
|
*/
|
|
48
49
|
const getComponentThemeOverride = (
|
|
49
50
|
theme: ThemeOrOverride,
|
|
50
51
|
displayName: string,
|
|
51
52
|
componentId?: string,
|
|
52
|
-
props?: { [k: string]: unknown } & WithStyleProps
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const overrides = (theme as Overrides).componentOverrides
|
|
53
|
+
props?: { [k: string]: unknown } & WithStyleProps,
|
|
54
|
+
componentTheme?: ComponentTheme
|
|
55
|
+
): Partial<ComponentTheme> => {
|
|
56
56
|
const name = displayName as ComponentName
|
|
57
57
|
const id = componentId as ComponentName
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const { themeOverride } = props as WithStyleProps
|
|
60
|
+
const { componentOverrides } = theme as Overrides
|
|
61
|
+
|
|
62
|
+
let overridesFromTheme: Partial<ComponentTheme> = {}
|
|
63
|
+
let overrideFromComponent: Partial<ComponentTheme> = {}
|
|
64
|
+
|
|
65
|
+
if (componentOverrides) {
|
|
66
|
+
overridesFromTheme =
|
|
67
|
+
(name && componentOverrides[name]) || (id && componentOverrides[id]) || {}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (themeOverride) {
|
|
71
|
+
if (typeof themeOverride === 'function') {
|
|
72
|
+
overrideFromComponent = themeOverride(
|
|
73
|
+
componentTheme || {},
|
|
74
|
+
// the `theme` technically could be a partial theme / override object too,
|
|
75
|
+
// but we want to display all possible options
|
|
76
|
+
theme as BaseTheme
|
|
77
|
+
)
|
|
78
|
+
} else {
|
|
79
|
+
overrideFromComponent = themeOverride
|
|
80
|
+
}
|
|
61
81
|
}
|
|
62
82
|
|
|
63
83
|
return {
|
|
64
|
-
...
|
|
65
|
-
...
|
|
84
|
+
...overridesFromTheme,
|
|
85
|
+
...overrideFromComponent
|
|
66
86
|
}
|
|
67
87
|
}
|
|
68
88
|
|
package/src/withStyle.tsx
CHANGED
|
@@ -68,7 +68,9 @@ type WithStylePrivateProps<
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
type ThemeOverrideProp<Theme extends ComponentTheme | null = ComponentTheme> = {
|
|
71
|
-
themeOverride?:
|
|
71
|
+
themeOverride?:
|
|
72
|
+
| Partial<Theme>
|
|
73
|
+
| ((componentTheme: Theme, currentTheme: BaseTheme) => Partial<Theme>)
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
type WithStyleProps<
|
|
@@ -90,7 +92,7 @@ const defaultValues = {
|
|
|
90
92
|
*
|
|
91
93
|
* A decorator or higher order component that makes a component themeable.
|
|
92
94
|
*
|
|
93
|
-
* It adds a `makeStyles` function and the generated `styles` object to the decorated Component's props.
|
|
95
|
+
* It adds a `makeStyles` function and the generated `styles` object to the decorated Component's props. If it has an own theme, it also adds the `themeOverride` prop to the component.
|
|
94
96
|
*
|
|
95
97
|
* As a HOC:
|
|
96
98
|
*
|
|
@@ -99,7 +101,6 @@ const defaultValues = {
|
|
|
99
101
|
* import generateStyle from './styles'
|
|
100
102
|
* import generateComponentTheme from './theme'
|
|
101
103
|
*
|
|
102
|
-
*
|
|
103
104
|
* export default withStyle(generateStyle, generateComponentTheme)(ExampleComponent)
|
|
104
105
|
* ```
|
|
105
106
|
*
|
|
@@ -112,10 +113,12 @@ const defaultValues = {
|
|
|
112
113
|
* [InstUISettingsProvider](#InstUISettingsProvider) component, and/or set
|
|
113
114
|
* explicitly via its `themeOverride` prop.
|
|
114
115
|
*
|
|
115
|
-
* InstUISettingsProvider provides a theme object with
|
|
116
|
+
* InstUISettingsProvider provides a theme object with global theme variables (e.g. the [canvas theme](/#canvas)).
|
|
116
117
|
* These variables are mapped to the component's own variables in `theme.js` (see [@instructure/emotion](#emotion) package documentation for more info).
|
|
117
118
|
*
|
|
118
|
-
* With the `themeOverride` prop you can directly set/override the component theme variables declared in theme.js.
|
|
119
|
+
* With the `themeOverride` prop you can directly set/override the component theme variables declared in theme.js. It accepts an object or a function. The function has the component's theme and the currently active main theme as its parameter.
|
|
120
|
+
*
|
|
121
|
+
* See more about the overrides on the [Using theme overrides](/#using-theme-overrides) docs page.
|
|
119
122
|
*
|
|
120
123
|
* ```js
|
|
121
124
|
* // ExampleComponent/theme.js
|
|
@@ -142,6 +145,12 @@ const defaultValues = {
|
|
|
142
145
|
* }}>
|
|
143
146
|
* {// component theme override}
|
|
144
147
|
* <ExampleComponent themeOverride={{ hoverColor: '#eee' }} />
|
|
148
|
+
*
|
|
149
|
+
* {// component theme override with function}
|
|
150
|
+
* <ExampleComponent themeOverride={(componentTheme, currentTheme) => ({
|
|
151
|
+
* hoverBackground: componentTheme.background,
|
|
152
|
+
* activeBackground: currentTheme.colors.backgroundBrand
|
|
153
|
+
* })} />
|
|
145
154
|
* </InstUISettingsProvider>
|
|
146
155
|
* ```
|
|
147
156
|
*
|
|
@@ -181,26 +190,27 @@ const withStyle = decorator(
|
|
|
181
190
|
`Manually passing the "makeStyles" property is not allowed on the ${displayName} component. Styles are calculated by the @withStyle decorator.`
|
|
182
191
|
)
|
|
183
192
|
}
|
|
193
|
+
|
|
184
194
|
const componentProps: Props = {
|
|
185
195
|
...ComposedComponent.defaultProps,
|
|
186
196
|
...props,
|
|
187
197
|
...defaultValues
|
|
188
198
|
}
|
|
189
199
|
|
|
200
|
+
let componentTheme: ComponentTheme =
|
|
201
|
+
typeof generateComponentTheme === 'function'
|
|
202
|
+
? generateComponentTheme(theme as BaseTheme)
|
|
203
|
+
: {}
|
|
204
|
+
|
|
190
205
|
const themeOverride = getComponentThemeOverride(
|
|
191
206
|
theme,
|
|
192
207
|
displayName,
|
|
193
208
|
ComposedComponent.componentId,
|
|
194
|
-
componentProps
|
|
209
|
+
componentProps,
|
|
210
|
+
componentTheme
|
|
195
211
|
)
|
|
196
212
|
|
|
197
|
-
|
|
198
|
-
typeof generateComponentTheme === 'function'
|
|
199
|
-
? {
|
|
200
|
-
...generateComponentTheme(theme as BaseTheme),
|
|
201
|
-
...themeOverride
|
|
202
|
-
}
|
|
203
|
-
: {}
|
|
213
|
+
componentTheme = { ...componentTheme, ...themeOverride }
|
|
204
214
|
|
|
205
215
|
const [styles, setStyles] = useState(
|
|
206
216
|
generateStyle ? generateStyle(componentTheme, componentProps, {}) : {}
|