@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 CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [8.19.0](https://github.com/instructure/instructure-ui/compare/v8.18.0...v8.19.0) (2022-03-16)
7
+
8
+ ### Features
9
+
10
+ - **emotion:** themeOverride prop to accept function ([505f0bf](https://github.com/instructure/instructure-ui/commit/505f0bfad12aaa4f3d1607a85409f5541246e879))
11
+
6
12
  # [8.18.0](https://github.com/instructure/instructure-ui/compare/v8.17.0...v8.18.0) (2022-02-23)
7
13
 
8
14
  **Note:** Version bump only for package @instructure/emotion
package/README.md CHANGED
@@ -83,7 +83,46 @@ export default Button
83
83
 
84
84
  Themeable components inject their themed styles into the document when they are mounted.
85
85
 
86
- A themeable component’s theme can be configured by wrapping it in an [InstUISettingsProvider](#InstUISettingsProvider) component, and/or set explicitly via its `themeOverride` prop (see [withStyle](#withStyle/#applying-themes) documentation).
86
+ A themeable component’s theme can be configured by wrapping it in an [InstUISettingsProvider](#InstUISettingsProvider) component, and/or set explicitly via its `themeOverride` prop.
87
+
88
+ #### themeOverride prop
89
+
90
+ The themeable components accept a `themeOverride` prop which let's you override it's component theme object. It accepts an override object or a function, which has the current `componentTheme` as its parameter.
91
+
92
+ **See more on the [withStyle](#withStyle/#applying-themes) and [Using theme overrides](/#using-theme-overrides) doc pages for more info.**
93
+
94
+ ```js
95
+ ---
96
+ example: true
97
+ ---
98
+ <div>
99
+ <Button color='primary' themeOverride={{ primaryBackground: "purple" }}>
100
+ Button
101
+ </Button>
102
+ <Button
103
+ color='primary'
104
+ margin="0 0 0 small"
105
+ themeOverride={(componentTheme) => ({
106
+ primaryBackground: componentTheme.successBackground,
107
+ primaryBorderColor: componentTheme.successBorderColor
108
+ })}
109
+ >
110
+ Button
111
+ </Button>
112
+ <Button
113
+ color='primary'
114
+ margin="0 0 0 small"
115
+ themeOverride={(_componentTheme, currentTheme) => ({
116
+ primaryBackground: currentTheme.colors.backgroundWarning,
117
+ primaryBorderColor: currentTheme.colors.backgroundLightest,
118
+ borderWidth: currentTheme.borders.widthLarge,
119
+ borderStyle: 'dashed'
120
+ })}
121
+ >
122
+ Button
123
+ </Button>
124
+ </div>
125
+ ```
87
126
 
88
127
  #### InstUISettingsProvider
89
128
 
@@ -22,27 +22,18 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
  import React, { useContext } from 'react';
25
- import { TextDirectionContext } from '@instructure/ui-i18n';
25
+ import PropTypes from 'prop-types';
26
26
  import { ThemeProvider } from '@emotion/react';
27
- import { getTheme } from '../EmotionThemeProvider';
27
+ import { TextDirectionContext } from '@instructure/ui-i18n';
28
28
  import { DeterministicIdContextProvider } from '@instructure/ui-react-utils';
29
-
30
- /**
31
- * @typedef InstUISettingsProviderSettings
32
- * @type {object}
33
- * @property {string} theme - A full theme or an override object
34
- * @property {string} dir - The text direction to use in the descendants. If not
35
- * given it uses the following in this priority order:
36
- * - The value given in a parent `TextDirectionContext`
37
- * - The `dir` prop of `document.documentElement` or its `direction` CSS prop
38
- * - `ltr`
39
- * @property {Map<string, number>} instanceCounterMap - a Map to keep track of instances
40
- */
29
+ import { getTheme } from '../EmotionThemeProvider';
41
30
 
42
31
  /**
43
32
  * ---
44
33
  * category: components/utilities
45
34
  * ---
35
+ * @module InstUISettingsProvider
36
+ * @tsProps
46
37
  *
47
38
  * Wrapper for emotion js's [ThemeProvider](https://emotion.sh/docs/theming#themeprovider-reactcomponenttype).
48
39
  *
@@ -92,17 +83,12 @@ import { DeterministicIdContextProvider } from '@instructure/ui-react-utils';
92
83
  * //read our [SSR](/#server-side-rendering) guide
93
84
  * const counter = generateInstanceCounterMap()
94
85
  * counter.set("Alert", 5)
95
- * <InstUISettingsProvider instanceCounterMap={counter}
86
+ * <InstUISettingsProvider instanceCounterMap={counter}>
96
87
  * //this Alert's rendered DOM Node will have [id="Alert_5"] on it
97
88
  * <Alert>Test!</Alert>
98
89
  * </InstUISettingsProvider>
99
90
  * </InstUISettingsProvider>
100
91
  * ```
101
- *
102
- * @module InstUISettingsProvider
103
- *
104
- * @param {InstUISettingsProviderSettings} settings - A settings object
105
- * @returns {ReactElement} The settings provider
106
92
  */
107
93
  function InstUISettingsProvider(_ref) {
108
94
  let children = _ref.children,
@@ -123,10 +109,17 @@ function InstUISettingsProvider(_ref) {
123
109
  }, children)));
124
110
  }
125
111
 
112
+ InstUISettingsProvider.propTypes = {
113
+ /* eslint-disable react/require-default-props */
114
+ children: PropTypes.node,
115
+ theme: PropTypes.object,
116
+ dir: PropTypes.oneOf(['ltr', 'rtl']),
117
+ instanceCounterMap: PropTypes.instanceOf(Map)
118
+ /* eslint-enable react/require-default-props */
119
+
120
+ };
126
121
  InstUISettingsProvider.defaultProps = {
127
- theme: {},
128
- dir: void 0,
129
- instanceCounterMap: void 0
122
+ theme: {}
130
123
  };
131
124
  export default InstUISettingsProvider;
132
125
  export { InstUISettingsProvider };
@@ -33,22 +33,35 @@
33
33
  * @param {*} displayName - Name of the component
34
34
  * @param {*} componentId - componentId of the component
35
35
  * @param {*} props - The component's props object
36
+ * @param {*} componentTheme - The component's default theme
36
37
  * @returns {object} The calculated theme override object
37
38
  */
38
- const getComponentThemeOverride = (theme, displayName, componentId, props) => {
39
- var _props$themeOverride;
40
-
41
- let componentOverride = {};
42
- const overrides = theme.componentOverrides;
39
+ const getComponentThemeOverride = (theme, displayName, componentId, props, componentTheme) => {
43
40
  const name = displayName;
44
41
  const id = componentId;
42
+ const _ref = props,
43
+ themeOverride = _ref.themeOverride;
44
+ const _ref2 = theme,
45
+ componentOverrides = _ref2.componentOverrides;
46
+ let overridesFromTheme = {};
47
+ let overrideFromComponent = {};
48
+
49
+ if (componentOverrides) {
50
+ overridesFromTheme = name && componentOverrides[name] || id && componentOverrides[id] || {};
51
+ }
45
52
 
46
- if (overrides) {
47
- componentOverride = name && overrides[name] || id && overrides[id] || {};
53
+ if (themeOverride) {
54
+ if (typeof themeOverride === 'function') {
55
+ overrideFromComponent = themeOverride(componentTheme || {}, // the `theme` technically could be a partial theme / override object too,
56
+ // but we want to display all possible options
57
+ theme);
58
+ } else {
59
+ overrideFromComponent = themeOverride;
60
+ }
48
61
  }
49
62
 
50
- return { ...componentOverride,
51
- ...((_props$themeOverride = props === null || props === void 0 ? void 0 : props.themeOverride) !== null && _props$themeOverride !== void 0 ? _props$themeOverride : {})
63
+ return { ...overridesFromTheme,
64
+ ...overrideFromComponent
52
65
  };
53
66
  };
54
67
 
package/es/withStyle.js CHANGED
@@ -41,7 +41,7 @@ const defaultValues = {
41
41
  *
42
42
  * A decorator or higher order component that makes a component themeable.
43
43
  *
44
- * It adds a `makeStyles` function and the generated `styles` object to the decorated Component's props.
44
+ * 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.
45
45
  *
46
46
  * As a HOC:
47
47
  *
@@ -50,7 +50,6 @@ const defaultValues = {
50
50
  * import generateStyle from './styles'
51
51
  * import generateComponentTheme from './theme'
52
52
  *
53
- *
54
53
  * export default withStyle(generateStyle, generateComponentTheme)(ExampleComponent)
55
54
  * ```
56
55
  *
@@ -63,10 +62,12 @@ const defaultValues = {
63
62
  * [InstUISettingsProvider](#InstUISettingsProvider) component, and/or set
64
63
  * explicitly via its `themeOverride` prop.
65
64
  *
66
- * InstUISettingsProvider provides a theme object with [global theme variables](#canvas).
65
+ * InstUISettingsProvider provides a theme object with global theme variables (e.g. the [canvas theme](/#canvas)).
67
66
  * These variables are mapped to the component's own variables in `theme.js` (see [@instructure/emotion](#emotion) package documentation for more info).
68
67
  *
69
- * With the `themeOverride` prop you can directly set/override the component theme variables declared in theme.js.
68
+ * 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.
69
+ *
70
+ * See more about the overrides on the [Using theme overrides](/#using-theme-overrides) docs page.
70
71
  *
71
72
  * ```js
72
73
  * // ExampleComponent/theme.js
@@ -93,6 +94,12 @@ const defaultValues = {
93
94
  * }}>
94
95
  * {// component theme override}
95
96
  * <ExampleComponent themeOverride={{ hoverColor: '#eee' }} />
97
+ *
98
+ * {// component theme override with function}
99
+ * <ExampleComponent themeOverride={(componentTheme, currentTheme) => ({
100
+ * hoverBackground: componentTheme.background,
101
+ * activeBackground: currentTheme.colors.backgroundBrand
102
+ * })} />
96
103
  * </InstUISettingsProvider>
97
104
  * ```
98
105
  *
@@ -120,10 +127,11 @@ const withStyle = decorator((ComposedComponent, generateStyle, generateComponent
120
127
  ...props,
121
128
  ...defaultValues
122
129
  };
123
- const themeOverride = getComponentThemeOverride(theme, displayName, ComposedComponent.componentId, componentProps);
124
- const componentTheme = typeof generateComponentTheme === 'function' ? { ...generateComponentTheme(theme),
130
+ let componentTheme = typeof generateComponentTheme === 'function' ? generateComponentTheme(theme) : {};
131
+ const themeOverride = getComponentThemeOverride(theme, displayName, ComposedComponent.componentId, componentProps, componentTheme);
132
+ componentTheme = { ...componentTheme,
125
133
  ...themeOverride
126
- } : {};
134
+ };
127
135
 
128
136
  const _useState = useState(generateStyle ? generateStyle(componentTheme, componentProps, {}) : {}),
129
137
  _useState2 = _slicedToArray(_useState, 2),
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
3
5
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
6
 
5
7
  Object.defineProperty(exports, "__esModule", {
@@ -10,14 +12,16 @@ exports.default = void 0;
10
12
 
11
13
  var _react = _interopRequireWildcard(require("react"));
12
14
 
13
- var _TextDirectionContext = require("@instructure/ui-i18n/lib/TextDirectionContext.js");
15
+ var _propTypes = _interopRequireDefault(require("prop-types"));
14
16
 
15
17
  var _react2 = require("@emotion/react");
16
18
 
17
- var _EmotionThemeProvider = require("../EmotionThemeProvider");
19
+ var _TextDirectionContext = require("@instructure/ui-i18n/lib/TextDirectionContext.js");
18
20
 
19
21
  var _uiReactUtils = require("@instructure/ui-react-utils");
20
22
 
23
+ var _EmotionThemeProvider = require("../EmotionThemeProvider");
24
+
21
25
  /*
22
26
  * The MIT License (MIT)
23
27
  *
@@ -42,22 +46,12 @@ var _uiReactUtils = require("@instructure/ui-react-utils");
42
46
  * SOFTWARE.
43
47
  */
44
48
 
45
- /**
46
- * @typedef InstUISettingsProviderSettings
47
- * @type {object}
48
- * @property {string} theme - A full theme or an override object
49
- * @property {string} dir - The text direction to use in the descendants. If not
50
- * given it uses the following in this priority order:
51
- * - The value given in a parent `TextDirectionContext`
52
- * - The `dir` prop of `document.documentElement` or its `direction` CSS prop
53
- * - `ltr`
54
- * @property {Map<string, number>} instanceCounterMap - a Map to keep track of instances
55
- */
56
-
57
49
  /**
58
50
  * ---
59
51
  * category: components/utilities
60
52
  * ---
53
+ * @module InstUISettingsProvider
54
+ * @tsProps
61
55
  *
62
56
  * Wrapper for emotion js's [ThemeProvider](https://emotion.sh/docs/theming#themeprovider-reactcomponenttype).
63
57
  *
@@ -107,17 +101,12 @@ var _uiReactUtils = require("@instructure/ui-react-utils");
107
101
  * //read our [SSR](/#server-side-rendering) guide
108
102
  * const counter = generateInstanceCounterMap()
109
103
  * counter.set("Alert", 5)
110
- * <InstUISettingsProvider instanceCounterMap={counter}
104
+ * <InstUISettingsProvider instanceCounterMap={counter}>
111
105
  * //this Alert's rendered DOM Node will have [id="Alert_5"] on it
112
106
  * <Alert>Test!</Alert>
113
107
  * </InstUISettingsProvider>
114
108
  * </InstUISettingsProvider>
115
109
  * ```
116
- *
117
- * @module InstUISettingsProvider
118
- *
119
- * @param {InstUISettingsProviderSettings} settings - A settings object
120
- * @returns {ReactElement} The settings provider
121
110
  */
122
111
  function InstUISettingsProvider(_ref) {
123
112
  let children = _ref.children,
@@ -138,10 +127,17 @@ function InstUISettingsProvider(_ref) {
138
127
  }, children)));
139
128
  }
140
129
 
130
+ InstUISettingsProvider.propTypes = {
131
+ /* eslint-disable react/require-default-props */
132
+ children: _propTypes.default.node,
133
+ theme: _propTypes.default.object,
134
+ dir: _propTypes.default.oneOf(['ltr', 'rtl']),
135
+ instanceCounterMap: _propTypes.default.instanceOf(Map)
136
+ /* eslint-enable react/require-default-props */
137
+
138
+ };
141
139
  InstUISettingsProvider.defaultProps = {
142
- theme: {},
143
- dir: void 0,
144
- instanceCounterMap: void 0
140
+ theme: {}
145
141
  };
146
142
  var _default = InstUISettingsProvider;
147
143
  exports.default = _default;
@@ -40,22 +40,35 @@ exports.getComponentThemeOverride = exports.default = void 0;
40
40
  * @param {*} displayName - Name of the component
41
41
  * @param {*} componentId - componentId of the component
42
42
  * @param {*} props - The component's props object
43
+ * @param {*} componentTheme - The component's default theme
43
44
  * @returns {object} The calculated theme override object
44
45
  */
45
- const getComponentThemeOverride = (theme, displayName, componentId, props) => {
46
- var _props$themeOverride;
47
-
48
- let componentOverride = {};
49
- const overrides = theme.componentOverrides;
46
+ const getComponentThemeOverride = (theme, displayName, componentId, props, componentTheme) => {
50
47
  const name = displayName;
51
48
  const id = componentId;
49
+ const _ref = props,
50
+ themeOverride = _ref.themeOverride;
51
+ const _ref2 = theme,
52
+ componentOverrides = _ref2.componentOverrides;
53
+ let overridesFromTheme = {};
54
+ let overrideFromComponent = {};
55
+
56
+ if (componentOverrides) {
57
+ overridesFromTheme = name && componentOverrides[name] || id && componentOverrides[id] || {};
58
+ }
52
59
 
53
- if (overrides) {
54
- componentOverride = name && overrides[name] || id && overrides[id] || {};
60
+ if (themeOverride) {
61
+ if (typeof themeOverride === 'function') {
62
+ overrideFromComponent = themeOverride(componentTheme || {}, // the `theme` technically could be a partial theme / override object too,
63
+ // but we want to display all possible options
64
+ theme);
65
+ } else {
66
+ overrideFromComponent = themeOverride;
67
+ }
55
68
  }
56
69
 
57
- return { ...componentOverride,
58
- ...((_props$themeOverride = props === null || props === void 0 ? void 0 : props.themeOverride) !== null && _props$themeOverride !== void 0 ? _props$themeOverride : {})
70
+ return { ...overridesFromTheme,
71
+ ...overrideFromComponent
59
72
  };
60
73
  };
61
74
 
package/lib/withStyle.js CHANGED
@@ -59,7 +59,7 @@ const defaultValues = {
59
59
  *
60
60
  * A decorator or higher order component that makes a component themeable.
61
61
  *
62
- * It adds a `makeStyles` function and the generated `styles` object to the decorated Component's props.
62
+ * 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.
63
63
  *
64
64
  * As a HOC:
65
65
  *
@@ -68,7 +68,6 @@ const defaultValues = {
68
68
  * import generateStyle from './styles'
69
69
  * import generateComponentTheme from './theme'
70
70
  *
71
- *
72
71
  * export default withStyle(generateStyle, generateComponentTheme)(ExampleComponent)
73
72
  * ```
74
73
  *
@@ -81,10 +80,12 @@ const defaultValues = {
81
80
  * [InstUISettingsProvider](#InstUISettingsProvider) component, and/or set
82
81
  * explicitly via its `themeOverride` prop.
83
82
  *
84
- * InstUISettingsProvider provides a theme object with [global theme variables](#canvas).
83
+ * InstUISettingsProvider provides a theme object with global theme variables (e.g. the [canvas theme](/#canvas)).
85
84
  * These variables are mapped to the component's own variables in `theme.js` (see [@instructure/emotion](#emotion) package documentation for more info).
86
85
  *
87
- * With the `themeOverride` prop you can directly set/override the component theme variables declared in theme.js.
86
+ * 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.
87
+ *
88
+ * See more about the overrides on the [Using theme overrides](/#using-theme-overrides) docs page.
88
89
  *
89
90
  * ```js
90
91
  * // ExampleComponent/theme.js
@@ -111,6 +112,12 @@ const defaultValues = {
111
112
  * }}>
112
113
  * {// component theme override}
113
114
  * <ExampleComponent themeOverride={{ hoverColor: '#eee' }} />
115
+ *
116
+ * {// component theme override with function}
117
+ * <ExampleComponent themeOverride={(componentTheme, currentTheme) => ({
118
+ * hoverBackground: componentTheme.background,
119
+ * activeBackground: currentTheme.colors.backgroundBrand
120
+ * })} />
114
121
  * </InstUISettingsProvider>
115
122
  * ```
116
123
  *
@@ -138,10 +145,11 @@ const withStyle = (0, _decorator.decorator)((ComposedComponent, generateStyle, g
138
145
  ...props,
139
146
  ...defaultValues
140
147
  };
141
- const themeOverride = (0, _getComponentThemeOverride.getComponentThemeOverride)(theme, displayName, ComposedComponent.componentId, componentProps);
142
- const componentTheme = typeof generateComponentTheme === 'function' ? { ...generateComponentTheme(theme),
148
+ let componentTheme = typeof generateComponentTheme === 'function' ? generateComponentTheme(theme) : {};
149
+ const themeOverride = (0, _getComponentThemeOverride.getComponentThemeOverride)(theme, displayName, ComposedComponent.componentId, componentProps, componentTheme);
150
+ componentTheme = { ...componentTheme,
143
151
  ...themeOverride
144
- } : {};
152
+ };
145
153
 
146
154
  const _useState = (0, _react.useState)(generateStyle ? generateStyle(componentTheme, componentProps, {}) : {}),
147
155
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/emotion",
3
- "version": "8.18.1-snapshot.3+c6a2ad87e",
3
+ "version": "8.19.1-snapshot.1+243eb1698",
4
4
  "description": "A UI component library made by Instructure Inc.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -25,21 +25,21 @@
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.13.10",
27
27
  "@emotion/react": "^11",
28
- "@instructure/console": "8.18.1-snapshot.3+c6a2ad87e",
29
- "@instructure/shared-types": "8.18.1-snapshot.3+c6a2ad87e",
30
- "@instructure/ui-decorator": "8.18.1-snapshot.3+c6a2ad87e",
31
- "@instructure/ui-i18n": "8.18.1-snapshot.3+c6a2ad87e",
32
- "@instructure/ui-react-utils": "8.18.1-snapshot.3+c6a2ad87e",
33
- "@instructure/ui-themes": "8.18.1-snapshot.3+c6a2ad87e",
34
- "@instructure/ui-utils": "8.18.1-snapshot.3+c6a2ad87e",
28
+ "@instructure/console": "8.19.1-snapshot.1+243eb1698",
29
+ "@instructure/shared-types": "8.19.1-snapshot.1+243eb1698",
30
+ "@instructure/ui-decorator": "8.19.1-snapshot.1+243eb1698",
31
+ "@instructure/ui-i18n": "8.19.1-snapshot.1+243eb1698",
32
+ "@instructure/ui-react-utils": "8.19.1-snapshot.1+243eb1698",
33
+ "@instructure/ui-themes": "8.19.1-snapshot.1+243eb1698",
34
+ "@instructure/ui-utils": "8.19.1-snapshot.1+243eb1698",
35
35
  "emotion-theming": "^11",
36
36
  "hoist-non-react-statics": "^3.3.2",
37
37
  "lodash": "^4",
38
38
  "prop-types": "^15"
39
39
  },
40
40
  "devDependencies": {
41
- "@instructure/ui-babel-preset": "8.18.1-snapshot.3+c6a2ad87e",
42
- "@instructure/ui-test-utils": "8.18.1-snapshot.3+c6a2ad87e",
41
+ "@instructure/ui-babel-preset": "8.19.1-snapshot.1+243eb1698",
42
+ "@instructure/ui-test-utils": "8.19.1-snapshot.1+243eb1698",
43
43
  "@types/lodash": "^4.14.171",
44
44
  "cpy-cli": "^3.1.1"
45
45
  },
@@ -50,5 +50,5 @@
50
50
  "access": "public"
51
51
  },
52
52
  "sideEffects": false,
53
- "gitHead": "c6a2ad87e2c3baae81798304250fbf9291057393"
53
+ "gitHead": "243eb169866e654e9aaaaaba4a96a6778c06ccdf"
54
54
  }
@@ -2,7 +2,18 @@
2
2
  describes: EmotionThemeProvider
3
3
  ---
4
4
 
5
- #### DEPRECATED. Please use [InstUISettingsProvider](#InstUISettingsProvider) instead. It has the same functionality and adds text direction configuration.
5
+ ```js
6
+ ---
7
+ embed: true
8
+ ---
9
+ <ToggleBlockquote
10
+ summary="DEPRECATED"
11
+ >
12
+ <ToggleBlockquote.Paragraph>
13
+ This component is depreacted. Please use <Link href="#InstUISettingsProvider">InstUISettingsProvider</Link> instead. It has the same functionality and adds additional configuration.
14
+ </ToggleBlockquote.Paragraph>
15
+ </ToggleBlockquote>
16
+ ```
6
17
 
7
18
  The `<EmotionThemeProvider/>` component provides a way to set the theme for our app or override the default theme properties for all themeable child components using the [withStyle](#withStyle) decorator.
8
19
 
@@ -0,0 +1,110 @@
1
+ ---
2
+ describes: InstUISettingsProvider
3
+ ---
4
+
5
+ The `<InstUISettingsProvider/>` component provides a way to add global configuration to our app. It can be used to apply and handle themes (for all themeable child components that use the [withStyle](#withStyle) decorator), setting the global text direction, etc.
6
+
7
+ Note that `<InstUISettingsProvider/>` components can be nested!
8
+
9
+ Table of Contents:
10
+
11
+ - [Theme management](/#InstUISettingsProvider/#theme-management)
12
+ - [Applying theme to the application](/#InstUISettingsProvider/#theme-management-applying-theme-to-the-application)
13
+ - [Nesting theme providers](/#InstUISettingsProvider/#theme-management-nesting-theme-providers)
14
+ - [Theme overrides](/#InstUISettingsProvider/#theme-management-theme-overrides)
15
+ - [Text direction management](/#InstUISettingsProvider/#text-direction-management)
16
+ - [Server Side Rendering support](/#InstUISettingsProvider/#server-side-rendering-support)
17
+ - [Properties](/#InstUISettingsProvider/#InstUISettingsProviderProperties)
18
+
19
+ ### Theme management
20
+
21
+ `<InstUISettingsProvider/>` is a wrapper for the [ThemeProvider](https://emotion.sh/docs/theming#themeprovider-reactcomponenttype) of Emotion library that we use under the hood for theming and applying css styles to our components.
22
+
23
+ #### Applying theme to the application
24
+
25
+ The `theme` prop applies the given theme. It handles either a full theme, or an overrides object. Theme properties will fall back to the parent theme, or the default `canvas` theme when they are not set.
26
+
27
+ To apply a theme to whole app, you need to import `<InstUISettingsProvider/>` and the theme you want to use from `@instructure/ui-themes` (or use your own compatible theme), and wrap your app in the theme provider.
28
+
29
+ ```js
30
+ import React from 'react'
31
+ import ReactDOM from 'react-dom'
32
+
33
+ import { instructure } from '@instructure/ui-themes'
34
+ import { InstUISettingsProvider } from '@instructure/emotion'
35
+
36
+ import { App } from './App'
37
+
38
+ ReactDOM.render(
39
+ <InstUISettingsProvider theme={instructure}>
40
+ <App />
41
+ </InstUISettingsProvider>,
42
+ document.getElementById('app')
43
+ )
44
+ ```
45
+
46
+ #### Nesting theme providers
47
+
48
+ ```js
49
+ <InstUISettingsProvider theme={canvas}>
50
+ <Heading>I should have "canvas" font family.</Heading>
51
+
52
+ <InstUISettingsProvider theme={instructure}>
53
+ <Heading>I should have "instructure" font family.</Heading>
54
+ </InstUISettingsProvider>
55
+ </InstUISettingsProvider>
56
+ ```
57
+
58
+ #### Theme overrides
59
+
60
+ There are multiple ways to override themes in InstUI. You can read about how these work on the dedicated docs page: [Using theme overrides](/#using-theme-overrides).
61
+
62
+ ### Text direction management
63
+
64
+ The `dir` prop sets the text direction for its descendants. It wraps its children in a [TextDirectionContext.Provider](/#TextDirectionContext), so that the text direction context can be consumed by child components that have implemented [textDirectionContextConsumer](#textDirectionContextConsumer).
65
+
66
+ If no `dir` prop is supplied, it will fall back to its parent context if it
67
+ exists. Otherwise, it queries for and uses the documentElement `dir` attribute and defaults to `ltr` if it is not found.
68
+
69
+ ```js
70
+ ---
71
+ example: true
72
+ ---
73
+ <InstUISettingsProvider dir="ltr">
74
+ <div>LTR text</div>
75
+ <Badge count={105} countUntil={100} margin="small medium 0 0">
76
+ <Button>LTR Badge</Button>
77
+ </Badge>
78
+
79
+ <InstUISettingsProvider dir="rtl">
80
+ <View as="div">
81
+ <div>Nested RTL text</div>
82
+ <Badge count={105} countUntil={100} margin="small medium 0 0">
83
+ <Button>Nested RTL Badge</Button>
84
+ </Badge>
85
+ </View>
86
+ </InstUISettingsProvider>
87
+
88
+ <div>LTR text</div>
89
+ <div>LTR text</div>
90
+ </InstUISettingsProvider>
91
+ ```
92
+
93
+ ### Server Side Rendering support
94
+
95
+ The `instanceCounterMap` prop is used for deterministic id generation. The prop accepts a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) (generated by the `generateInstanceCounterMap` util) that keeps the id-s of the components in sync on both the frontend and backend.
96
+
97
+ See more info on the [Server Side Rendering (SSR)](/#server-side-rendering) docs page.
98
+
99
+ ```jsx
100
+ import { InstUISettingsProvider } from '@instructure/emotion'
101
+ import { generateInstanceCounterMap } from '@instructure/ui-react-utils'
102
+
103
+ const counter = generateInstanceCounterMap()
104
+ counter.set('Alert', 5)
105
+
106
+ ;<InstUISettingsProvider instanceCounterMap={counter}>
107
+ // this Alert's rendered DOM Node will have [id="Alert_5"] on it
108
+ <Alert>Test!</Alert>
109
+ </InstUISettingsProvider>
110
+ ```