@atlaskit/app-provider 3.2.10 → 3.3.0

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/app-provider.js +4 -6
  3. package/dist/cjs/context.js +16 -0
  4. package/dist/cjs/index.js +12 -9
  5. package/dist/cjs/theme-provider/context/color-mode.js +16 -0
  6. package/dist/cjs/theme-provider/context/inside-theme-provider.js +11 -0
  7. package/dist/cjs/theme-provider/context/theme.js +16 -0
  8. package/dist/cjs/theme-provider/hooks/use-color-mode-for-migration.js +19 -0
  9. package/dist/cjs/theme-provider/hooks/use-color-mode.js +41 -0
  10. package/dist/cjs/theme-provider/hooks/use-is-inside-theme-provider.js +17 -0
  11. package/dist/cjs/theme-provider/hooks/use-set-color-mode.js +20 -0
  12. package/dist/cjs/theme-provider/hooks/use-set-theme.js +20 -0
  13. package/dist/cjs/theme-provider/hooks/use-theme.js +35 -0
  14. package/dist/cjs/theme-provider/index.js +221 -0
  15. package/dist/cjs/theme-provider/utils/is-theme-mounted.js +21 -0
  16. package/dist/cjs/theme-provider/utils/load-and-mount-themes.js +130 -0
  17. package/dist/es2019/app-provider.js +3 -3
  18. package/dist/es2019/context.js +11 -0
  19. package/dist/es2019/index.js +10 -1
  20. package/dist/es2019/theme-provider/context/color-mode.js +10 -0
  21. package/dist/es2019/theme-provider/context/inside-theme-provider.js +6 -0
  22. package/dist/es2019/theme-provider/context/theme.js +10 -0
  23. package/dist/es2019/theme-provider/hooks/use-color-mode-for-migration.js +14 -0
  24. package/dist/es2019/theme-provider/hooks/use-color-mode.js +29 -0
  25. package/dist/es2019/theme-provider/hooks/use-is-inside-theme-provider.js +12 -0
  26. package/dist/es2019/theme-provider/hooks/use-set-color-mode.js +15 -0
  27. package/dist/es2019/theme-provider/hooks/use-set-theme.js +15 -0
  28. package/dist/es2019/theme-provider/hooks/use-theme.js +23 -0
  29. package/dist/es2019/theme-provider/index.js +170 -0
  30. package/dist/es2019/theme-provider/utils/is-theme-mounted.js +16 -0
  31. package/dist/es2019/theme-provider/utils/load-and-mount-themes.js +47 -0
  32. package/dist/esm/app-provider.js +3 -3
  33. package/dist/esm/context.js +11 -0
  34. package/dist/esm/index.js +10 -1
  35. package/dist/esm/theme-provider/context/color-mode.js +10 -0
  36. package/dist/esm/theme-provider/context/inside-theme-provider.js +6 -0
  37. package/dist/esm/theme-provider/context/theme.js +10 -0
  38. package/dist/esm/theme-provider/hooks/use-color-mode-for-migration.js +14 -0
  39. package/dist/esm/theme-provider/hooks/use-color-mode.js +35 -0
  40. package/dist/esm/theme-provider/hooks/use-is-inside-theme-provider.js +12 -0
  41. package/dist/esm/theme-provider/hooks/use-set-color-mode.js +15 -0
  42. package/dist/esm/theme-provider/hooks/use-set-theme.js +15 -0
  43. package/dist/esm/theme-provider/hooks/use-theme.js +29 -0
  44. package/dist/esm/theme-provider/index.js +212 -0
  45. package/dist/esm/theme-provider/utils/is-theme-mounted.js +16 -0
  46. package/dist/esm/theme-provider/utils/load-and-mount-themes.js +123 -0
  47. package/dist/types/app-provider.d.ts +3 -2
  48. package/dist/types/context.d.ts +7 -0
  49. package/dist/types/index.d.ts +7 -2
  50. package/dist/types/theme-provider/context/color-mode.d.ts +10 -0
  51. package/dist/types/theme-provider/context/inside-theme-provider.d.ts +4 -0
  52. package/dist/types/theme-provider/context/theme.d.ts +10 -0
  53. package/dist/types/theme-provider/hooks/use-color-mode-for-migration.d.ts +9 -0
  54. package/dist/types/theme-provider/hooks/use-color-mode.d.ts +7 -0
  55. package/dist/types/theme-provider/hooks/use-is-inside-theme-provider.d.ts +6 -0
  56. package/dist/types/theme-provider/hooks/use-set-color-mode.d.ts +7 -0
  57. package/dist/types/theme-provider/hooks/use-set-theme.d.ts +7 -0
  58. package/dist/types/theme-provider/hooks/use-theme.d.ts +7 -0
  59. package/dist/types/theme-provider/index.d.ts +19 -0
  60. package/dist/types/theme-provider/utils/is-theme-mounted.d.ts +8 -0
  61. package/dist/types/theme-provider/utils/load-and-mount-themes.d.ts +2 -0
  62. package/dist/types-ts4.5/app-provider.d.ts +3 -2
  63. package/dist/types-ts4.5/context.d.ts +7 -0
  64. package/dist/types-ts4.5/index.d.ts +7 -2
  65. package/dist/types-ts4.5/theme-provider/context/color-mode.d.ts +10 -0
  66. package/dist/types-ts4.5/theme-provider/context/inside-theme-provider.d.ts +4 -0
  67. package/dist/types-ts4.5/theme-provider/context/theme.d.ts +10 -0
  68. package/dist/types-ts4.5/theme-provider/hooks/use-color-mode-for-migration.d.ts +9 -0
  69. package/dist/types-ts4.5/theme-provider/hooks/use-color-mode.d.ts +7 -0
  70. package/dist/types-ts4.5/theme-provider/hooks/use-is-inside-theme-provider.d.ts +6 -0
  71. package/dist/types-ts4.5/theme-provider/hooks/use-set-color-mode.d.ts +7 -0
  72. package/dist/types-ts4.5/theme-provider/hooks/use-set-theme.d.ts +7 -0
  73. package/dist/types-ts4.5/theme-provider/hooks/use-theme.d.ts +7 -0
  74. package/dist/types-ts4.5/theme-provider/index.d.ts +19 -0
  75. package/dist/types-ts4.5/theme-provider/utils/is-theme-mounted.d.ts +8 -0
  76. package/dist/types-ts4.5/theme-provider/utils/load-and-mount-themes.d.ts +2 -0
  77. package/package.json +10 -5
  78. package/dist/cjs/theme-provider.js +0 -286
  79. package/dist/es2019/theme-provider.js +0 -216
  80. package/dist/esm/theme-provider.js +0 -272
  81. package/dist/types/theme-provider.d.ts +0 -55
  82. package/dist/types-ts4.5/theme-provider.d.ts +0 -55
  83. /package/dist/cjs/{theme-provider.compiled.css → theme-provider/index.compiled.css} +0 -0
  84. /package/dist/es2019/{theme-provider.compiled.css → theme-provider/index.compiled.css} +0 -0
  85. /package/dist/esm/{theme-provider.compiled.css → theme-provider/index.compiled.css} +0 -0
@@ -0,0 +1,10 @@
1
+ import type { ThemeColorModes } from '@atlaskit/tokens';
2
+ export type ReconciledColorMode = Exclude<ThemeColorModes, 'auto'>;
3
+ /**
4
+ * __Color mode context__
5
+ */
6
+ export declare const ColorModeContext: import("react").Context<ReconciledColorMode | undefined>;
7
+ /**
8
+ * __Set color mode context__
9
+ */
10
+ export declare const SetColorModeContext: import("react").Context<((value: ThemeColorModes) => void) | undefined>;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * __Inside theme provider context__
3
+ */
4
+ export declare const InsideThemeProviderContext: import("react").Context<boolean>;
@@ -0,0 +1,10 @@
1
+ import type { ThemeState } from '@atlaskit/tokens';
2
+ export type Theme = Omit<ThemeState, 'colorMode' | 'contrastMode'>;
3
+ /**
4
+ * __Theme context__
5
+ */
6
+ export declare const ThemeContext: import("react").Context<Theme | undefined>;
7
+ /**
8
+ * __Set theme context__
9
+ */
10
+ export declare const SetThemeContext: import("react").Context<((value: Partial<Theme>) => void) | undefined>;
@@ -0,0 +1,9 @@
1
+ import { type ReconciledColorMode } from '../context/color-mode';
2
+ /**
3
+ * __UNSAFE_useColorModeForMigration()__
4
+ *
5
+ * Returns the current color mode when inside the app provider.
6
+ * Unlike useColorMode, this utility returns undefined, instead of throwing an error, when the app provider is missing.
7
+ * This allows it to be used by components that need to operate with and without an app provider.
8
+ */
9
+ export declare function UNSAFE_useColorModeForMigration(): ReconciledColorMode | undefined;
@@ -0,0 +1,7 @@
1
+ import { type ReconciledColorMode } from '../context/color-mode';
2
+ /**
3
+ * __useColorMode()__
4
+ *
5
+ * Returns the current color mode when inside the app provider.
6
+ */
7
+ export declare function useColorMode(): ReconciledColorMode;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * __useIsInsideThemeProvider()__
3
+ *
4
+ * Returns true if the current component is inside a ThemeProvider.
5
+ */
6
+ export declare const useIsInsideThemeProvider: () => boolean;
@@ -0,0 +1,7 @@
1
+ import type { ThemeColorModes } from '@atlaskit/tokens';
2
+ /**
3
+ * __useSetColorMode()__
4
+ *
5
+ * Returns the color mode setter when inside the app provider.
6
+ */
7
+ export declare function useSetColorMode(): (value: ThemeColorModes) => void;
@@ -0,0 +1,7 @@
1
+ import { type Theme } from '../context/theme';
2
+ /**
3
+ * __useSetTheme()__
4
+ *
5
+ * Returns the theme setter when inside the app provider.
6
+ */
7
+ export declare function useSetTheme(): (value: Partial<Theme>) => void;
@@ -0,0 +1,7 @@
1
+ import { type Theme } from '../context/theme';
2
+ /**
3
+ * __useTheme()__
4
+ *
5
+ * Returns the current theme settings when inside the app provider.
6
+ */
7
+ export declare function useTheme(): Partial<Theme>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import React from 'react';
6
+ import { type ThemeColorModes } from '@atlaskit/tokens';
7
+ import { type Theme } from './context/theme';
8
+ export interface ThemeProviderProps {
9
+ defaultColorMode?: ThemeColorModes;
10
+ defaultTheme?: Partial<Theme>;
11
+ children: React.ReactNode;
12
+ }
13
+ /**
14
+ * __Theme provider__
15
+ *
16
+ * Provides global theming configuration.
17
+ */
18
+ declare function ThemeProvider({ children, defaultColorMode, defaultTheme }: ThemeProviderProps): JSX.Element;
19
+ export default ThemeProvider;
@@ -0,0 +1,8 @@
1
+ import { type ThemeIds } from '@atlaskit/tokens';
2
+ /**
3
+ * Checks if a theme is mounted in the document head.
4
+ *
5
+ * Eventually this won't be necessary as we'll utilise AppProvider context
6
+ * to track theme loading.
7
+ */
8
+ export declare function isThemeMounted(themeId: ThemeIds): false | Element | null;
@@ -0,0 +1,2 @@
1
+ import { type ThemeState } from '@atlaskit/tokens';
2
+ export declare const loadAndMountThemes: (themeState: Partial<ThemeState>) => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/app-provider",
3
- "version": "3.2.10",
3
+ "version": "3.3.0",
4
4
  "description": "A top level provider for the Design System.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,9 +35,10 @@
35
35
  ],
36
36
  "atlaskit:src": "src/index.tsx",
37
37
  "dependencies": {
38
+ "@atlaskit/browser-apis": "^0.0.1",
38
39
  "@atlaskit/css": "^0.19.0",
39
40
  "@atlaskit/platform-feature-flags": "^1.1.0",
40
- "@atlaskit/tokens": "^9.0.0",
41
+ "@atlaskit/tokens": "^9.1.0",
41
42
  "@babel/runtime": "^7.0.0",
42
43
  "bind-event-listener": "^3.0.0"
43
44
  },
@@ -46,16 +47,20 @@
46
47
  },
47
48
  "devDependencies": {
48
49
  "@af/visual-regression": "workspace:^",
49
- "@atlaskit/dropdown-menu": "^16.3.0",
50
+ "@atlaskit/dropdown-menu": "^16.4.0",
50
51
  "@atlaskit/primitives": "^17.0.0",
52
+ "@atlassian/feature-flags-test-utils": "^1.0.0",
51
53
  "@atlassian/ssr-tests": "workspace:^",
52
- "@testing-library/react": "^13.4.0",
54
+ "@testing-library/react": "^16.3.0",
53
55
  "@testing-library/user-event": "^14.4.3",
54
56
  "react-dom": "^18.2.0",
55
57
  "react-resource-router": "^0.20.0"
56
58
  },
57
59
  "platform-feature-flags": {
58
- "platform-static-theme-loading": {
60
+ "platform_dst_subtree_theming": {
61
+ "type": "boolean"
62
+ },
63
+ "platform_increased-contrast-themes": {
59
64
  "type": "boolean"
60
65
  }
61
66
  },
@@ -1,286 +0,0 @@
1
- /* theme-provider.tsx generated by @compiled/babel-plugin v0.38.1 */
2
- "use strict";
3
-
4
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
- var _typeof = require("@babel/runtime/helpers/typeof");
6
- Object.defineProperty(exports, "__esModule", {
7
- value: true
8
- });
9
- exports.UNSAFE_useColorModeForMigration = UNSAFE_useColorModeForMigration;
10
- exports.default = void 0;
11
- exports.useColorMode = useColorMode;
12
- exports.useSetColorMode = useSetColorMode;
13
- exports.useSetTheme = useSetTheme;
14
- exports.useTheme = useTheme;
15
- require("./theme-provider.compiled.css");
16
- var _runtime = require("@compiled/react/runtime");
17
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
18
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
19
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
20
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
21
- var _react = _interopRequireWildcard(require("react"));
22
- var _bindEventListener = require("bind-event-listener");
23
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
24
- var _tokens = require("@atlaskit/tokens");
25
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
26
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
27
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
28
- var defaultThemeSettings = function defaultThemeSettings() {
29
- return {
30
- dark: 'dark',
31
- light: 'light',
32
- spacing: 'spacing',
33
- typography: 'typography'
34
- };
35
- };
36
- var ColorModeContext = /*#__PURE__*/(0, _react.createContext)(undefined);
37
- var SetColorModeContext = /*#__PURE__*/(0, _react.createContext)(undefined);
38
- var ThemeContext = /*#__PURE__*/(0, _react.createContext)(undefined);
39
- var SetThemeContext = /*#__PURE__*/(0, _react.createContext)(undefined);
40
-
41
- /**
42
- * __UNSAFE_useColorModeForMigration()__
43
- *
44
- * Returns the current color mode when inside the app provider.
45
- * Unlike useColorMode, this utility returns undefined, instead of throwing an error, when the app provider is missing.
46
- * This allows it to be used by components that need to operate with and without an app provider.
47
- */
48
- function UNSAFE_useColorModeForMigration() {
49
- var value = (0, _react.useContext)(ColorModeContext);
50
- return value;
51
- }
52
-
53
- /**
54
- * __useColorMode()__
55
- *
56
- * Returns the current color mode when inside the app provider.
57
- */
58
- function useColorMode() {
59
- var value = (0, _react.useContext)(ColorModeContext);
60
- var _getGlobalTheme = (0, _tokens.getGlobalTheme)(),
61
- colorMode = _getGlobalTheme.colorMode;
62
- var _useState = (0, _react.useState)(colorMode || 'light'),
63
- _useState2 = (0, _slicedToArray2.default)(_useState, 2),
64
- resolvedColorMode = _useState2[0],
65
- setResolvedColorMode = _useState2[1];
66
- (0, _react.useEffect)(function () {
67
- // We are using theme from context so no need to reference the DOM
68
- if (value) {
69
- return;
70
- }
71
- var observer = new _tokens.ThemeMutationObserver(function (theme) {
72
- setResolvedColorMode(theme.colorMode || 'light');
73
- });
74
- observer.observe();
75
- return function () {
76
- return observer.disconnect();
77
- };
78
- }, [value]);
79
- return value ? value : resolvedColorMode;
80
- }
81
-
82
- /**
83
- * __useSetColorMode()__
84
- *
85
- * Returns the color mode setter when inside the app provider.
86
- */
87
- function useSetColorMode() {
88
- var value = (0, _react.useContext)(SetColorModeContext);
89
- if (!value) {
90
- throw new Error('useSetColorMode must be used within AppProvider.');
91
- }
92
- return value;
93
- }
94
-
95
- /**
96
- * __useTheme()__
97
- *
98
- * Returns the current theme settings when inside the app provider.
99
- */
100
- function useTheme() {
101
- var theme = (0, _react.useContext)(ThemeContext);
102
- var _useState3 = (0, _react.useState)(theme || (0, _tokens.getGlobalTheme)()),
103
- _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
104
- resolvedTheme = _useState4[0],
105
- setResolvedTheme = _useState4[1];
106
- (0, _react.useEffect)(function () {
107
- // We are using theme from context so no need to reference the DOM
108
- if (theme) {
109
- return;
110
- }
111
- var observer = new _tokens.ThemeMutationObserver(setResolvedTheme);
112
- observer.observe();
113
- return function () {
114
- return observer.disconnect();
115
- };
116
- }, [theme]);
117
- return theme ? theme : resolvedTheme;
118
- }
119
-
120
- /**
121
- * __useSetTheme()__
122
- *
123
- * Returns the theme setter when inside the app provider.
124
- */
125
- function useSetTheme() {
126
- var value = (0, _react.useContext)(SetThemeContext);
127
- if (!value) {
128
- throw new Error('useSetTheme must be used within AppProvider.');
129
- }
130
- return value;
131
- }
132
- var isMatchMediaAvailable = typeof window !== 'undefined' && 'matchMedia' in window;
133
- var prefersDarkModeMql = isMatchMediaAvailable ? window.matchMedia('(prefers-color-scheme: dark)') : undefined;
134
-
135
- // TODO: currently 'auto' color mode will always return 'light' in SSR.
136
- // Additional work required: https://product-fabric.atlassian.net/browse/DSP-9781
137
- function getReconciledColorMode(colorMode) {
138
- if (colorMode === 'auto') {
139
- return prefersDarkModeMql !== null && prefersDarkModeMql !== void 0 && prefersDarkModeMql.matches ? 'dark' : 'light';
140
- }
141
- return colorMode;
142
- }
143
- var contentStyles = {
144
- body: "_1e0c1bgi"
145
- };
146
- /**
147
- * __Theme provider__
148
- *
149
- * Provides global theming configuration.
150
- *
151
- * @internal
152
- */
153
- function ThemeProvider(_ref) {
154
- var children = _ref.children,
155
- defaultColorMode = _ref.defaultColorMode,
156
- defaultTheme = _ref.defaultTheme;
157
- var _useState5 = (0, _react.useState)(defaultColorMode),
158
- _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
159
- chosenColorMode = _useState6[0],
160
- setChosenColorMode = _useState6[1];
161
- var _useState7 = (0, _react.useState)(getReconciledColorMode(defaultColorMode)),
162
- _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
163
- reconciledColorMode = _useState8[0],
164
- setReconciledColorMode = _useState8[1];
165
- var _useState9 = (0, _react.useState)(function () {
166
- return _objectSpread(_objectSpread({}, defaultThemeSettings()), defaultTheme);
167
- }),
168
- _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
169
- theme = _useState0[0],
170
- setTheme = _useState0[1];
171
- var setColorMode = (0, _react.useCallback)(function (colorMode) {
172
- setChosenColorMode(colorMode);
173
- setReconciledColorMode(getReconciledColorMode(colorMode));
174
- }, []);
175
- var setPartialTheme = (0, _react.useCallback)(function (nextTheme) {
176
- setTheme(function (theme) {
177
- return _objectSpread(_objectSpread({}, theme), nextTheme);
178
- });
179
- }, []);
180
- var lastSetGlobalThemePromiseRef = (0, _react.useRef)(null);
181
- (0, _react.useEffect)(function () {
182
- // If fg enabled avoid mounting themes
183
- if ((0, _platformFeatureFlags.fg)('platform-static-theme-loading')) {
184
- return;
185
- }
186
-
187
- /**
188
- * We need to wait for any previous `setGlobalTheme` calls to finish before calling it again.
189
- * This is to prevent race conditions as `setGlobalTheme` is async and mutates the DOM (e.g. sets the
190
- * `data-color-mode` attribute on the root element).
191
- *
192
- * Since we can't safely abort the `setGlobalTheme` execution, we need to wait for it to properly finish before
193
- * applying the new theme.
194
- *
195
- * Without this, we can end up in the following scenario:
196
- * 1. app loads with the default 'light' theme, kicking off `setGlobalTheme`
197
- * 2. app switches to 'dark' theme after retrieving value persisted in local storage, calling `setGlobalTheme` again
198
- * 3. `setGlobalTheme` function execution for `dark` finishes before the initial `light` execution
199
- * 4. `setGlobalTheme` function execution for `light` then finishes, resulting in the 'light' theme being applied.
200
- */
201
- var cleanupLastFnCall = /*#__PURE__*/function () {
202
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
203
- var unbindFn;
204
- return _regenerator.default.wrap(function _callee$(_context) {
205
- while (1) switch (_context.prev = _context.next) {
206
- case 0:
207
- if (!lastSetGlobalThemePromiseRef.current) {
208
- _context.next = 6;
209
- break;
210
- }
211
- _context.next = 3;
212
- return lastSetGlobalThemePromiseRef.current;
213
- case 3:
214
- unbindFn = _context.sent;
215
- unbindFn();
216
- lastSetGlobalThemePromiseRef.current = null;
217
- case 6:
218
- case "end":
219
- return _context.stop();
220
- }
221
- }, _callee);
222
- }));
223
- return function cleanupLastFnCall() {
224
- return _ref2.apply(this, arguments);
225
- };
226
- }();
227
- var safelySetGlobalTheme = /*#__PURE__*/function () {
228
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
229
- var promise;
230
- return _regenerator.default.wrap(function _callee2$(_context2) {
231
- while (1) switch (_context2.prev = _context2.next) {
232
- case 0:
233
- _context2.next = 2;
234
- return cleanupLastFnCall();
235
- case 2:
236
- promise = (0, _tokens.setGlobalTheme)(_objectSpread(_objectSpread({}, theme), {}, {
237
- colorMode: reconciledColorMode
238
- }));
239
- lastSetGlobalThemePromiseRef.current = promise;
240
- case 4:
241
- case "end":
242
- return _context2.stop();
243
- }
244
- }, _callee2);
245
- }));
246
- return function safelySetGlobalTheme() {
247
- return _ref3.apply(this, arguments);
248
- };
249
- }();
250
- safelySetGlobalTheme();
251
- return function cleanup() {
252
- cleanupLastFnCall();
253
- };
254
- }, [theme, reconciledColorMode]);
255
- (0, _react.useEffect)(function () {
256
- if (!prefersDarkModeMql) {
257
- return;
258
- }
259
- var unbindListener = (0, _bindEventListener.bind)(prefersDarkModeMql, {
260
- type: 'change',
261
- listener: function listener(event) {
262
- if (chosenColorMode === 'auto') {
263
- setReconciledColorMode(event.matches ? 'dark' : 'light');
264
- }
265
- }
266
- });
267
- return unbindListener;
268
- }, [chosenColorMode]);
269
- var attrs = (0, _tokens.getThemeHtmlAttrs)(_objectSpread(_objectSpread({}, theme), {}, {
270
- colorMode: reconciledColorMode
271
- }));
272
- return /*#__PURE__*/_react.default.createElement(ColorModeContext.Provider, {
273
- value: reconciledColorMode
274
- }, /*#__PURE__*/_react.default.createElement(SetColorModeContext.Provider, {
275
- value: setColorMode
276
- }, /*#__PURE__*/_react.default.createElement(ThemeContext.Provider, {
277
- value: theme
278
- }, /*#__PURE__*/_react.default.createElement(SetThemeContext.Provider, {
279
- value: setPartialTheme
280
- }, (0, _platformFeatureFlags.fg)('platform-static-theme-loading') ? /*#__PURE__*/_react.default.createElement("div", {
281
- "data-theme": attrs['data-theme'],
282
- "data-color-mode": attrs['data-color-mode'],
283
- className: (0, _runtime.ax)([contentStyles.body])
284
- }, children) : children))));
285
- }
286
- var _default = exports.default = ThemeProvider;
@@ -1,216 +0,0 @@
1
- /* theme-provider.tsx generated by @compiled/babel-plugin v0.38.1 */
2
- import "./theme-provider.compiled.css";
3
- import { ax, ix } from "@compiled/react/runtime";
4
- import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
5
- import { bind } from 'bind-event-listener';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
- import { getGlobalTheme, getThemeHtmlAttrs, setGlobalTheme, ThemeMutationObserver } from '@atlaskit/tokens';
8
- const defaultThemeSettings = () => ({
9
- dark: 'dark',
10
- light: 'light',
11
- spacing: 'spacing',
12
- typography: 'typography'
13
- });
14
- const ColorModeContext = /*#__PURE__*/createContext(undefined);
15
- const SetColorModeContext = /*#__PURE__*/createContext(undefined);
16
- const ThemeContext = /*#__PURE__*/createContext(undefined);
17
- const SetThemeContext = /*#__PURE__*/createContext(undefined);
18
-
19
- /**
20
- * __UNSAFE_useColorModeForMigration()__
21
- *
22
- * Returns the current color mode when inside the app provider.
23
- * Unlike useColorMode, this utility returns undefined, instead of throwing an error, when the app provider is missing.
24
- * This allows it to be used by components that need to operate with and without an app provider.
25
- */
26
- export function UNSAFE_useColorModeForMigration() {
27
- const value = useContext(ColorModeContext);
28
- return value;
29
- }
30
-
31
- /**
32
- * __useColorMode()__
33
- *
34
- * Returns the current color mode when inside the app provider.
35
- */
36
- export function useColorMode() {
37
- const value = useContext(ColorModeContext);
38
- const {
39
- colorMode
40
- } = getGlobalTheme();
41
- const [resolvedColorMode, setResolvedColorMode] = useState(colorMode || 'light');
42
- useEffect(() => {
43
- // We are using theme from context so no need to reference the DOM
44
- if (value) {
45
- return;
46
- }
47
- const observer = new ThemeMutationObserver(theme => {
48
- setResolvedColorMode(theme.colorMode || 'light');
49
- });
50
- observer.observe();
51
- return () => observer.disconnect();
52
- }, [value]);
53
- return value ? value : resolvedColorMode;
54
- }
55
-
56
- /**
57
- * __useSetColorMode()__
58
- *
59
- * Returns the color mode setter when inside the app provider.
60
- */
61
- export function useSetColorMode() {
62
- const value = useContext(SetColorModeContext);
63
- if (!value) {
64
- throw new Error('useSetColorMode must be used within AppProvider.');
65
- }
66
- return value;
67
- }
68
-
69
- /**
70
- * __useTheme()__
71
- *
72
- * Returns the current theme settings when inside the app provider.
73
- */
74
- export function useTheme() {
75
- const theme = useContext(ThemeContext);
76
- const [resolvedTheme, setResolvedTheme] = useState(theme || getGlobalTheme());
77
- useEffect(() => {
78
- // We are using theme from context so no need to reference the DOM
79
- if (theme) {
80
- return;
81
- }
82
- const observer = new ThemeMutationObserver(setResolvedTheme);
83
- observer.observe();
84
- return () => observer.disconnect();
85
- }, [theme]);
86
- return theme ? theme : resolvedTheme;
87
- }
88
-
89
- /**
90
- * __useSetTheme()__
91
- *
92
- * Returns the theme setter when inside the app provider.
93
- */
94
- export function useSetTheme() {
95
- const value = useContext(SetThemeContext);
96
- if (!value) {
97
- throw new Error('useSetTheme must be used within AppProvider.');
98
- }
99
- return value;
100
- }
101
- const isMatchMediaAvailable = typeof window !== 'undefined' && 'matchMedia' in window;
102
- const prefersDarkModeMql = isMatchMediaAvailable ? window.matchMedia('(prefers-color-scheme: dark)') : undefined;
103
-
104
- // TODO: currently 'auto' color mode will always return 'light' in SSR.
105
- // Additional work required: https://product-fabric.atlassian.net/browse/DSP-9781
106
- function getReconciledColorMode(colorMode) {
107
- if (colorMode === 'auto') {
108
- return prefersDarkModeMql !== null && prefersDarkModeMql !== void 0 && prefersDarkModeMql.matches ? 'dark' : 'light';
109
- }
110
- return colorMode;
111
- }
112
- const contentStyles = {
113
- body: "_1e0c1bgi"
114
- };
115
- /**
116
- * __Theme provider__
117
- *
118
- * Provides global theming configuration.
119
- *
120
- * @internal
121
- */
122
- function ThemeProvider({
123
- children,
124
- defaultColorMode,
125
- defaultTheme
126
- }) {
127
- const [chosenColorMode, setChosenColorMode] = useState(defaultColorMode);
128
- const [reconciledColorMode, setReconciledColorMode] = useState(getReconciledColorMode(defaultColorMode));
129
- const [theme, setTheme] = useState(() => ({
130
- ...defaultThemeSettings(),
131
- ...defaultTheme
132
- }));
133
- const setColorMode = useCallback(colorMode => {
134
- setChosenColorMode(colorMode);
135
- setReconciledColorMode(getReconciledColorMode(colorMode));
136
- }, []);
137
- const setPartialTheme = useCallback(nextTheme => {
138
- setTheme(theme => ({
139
- ...theme,
140
- ...nextTheme
141
- }));
142
- }, []);
143
- const lastSetGlobalThemePromiseRef = useRef(null);
144
- useEffect(() => {
145
- // If fg enabled avoid mounting themes
146
- if (fg('platform-static-theme-loading')) {
147
- return;
148
- }
149
-
150
- /**
151
- * We need to wait for any previous `setGlobalTheme` calls to finish before calling it again.
152
- * This is to prevent race conditions as `setGlobalTheme` is async and mutates the DOM (e.g. sets the
153
- * `data-color-mode` attribute on the root element).
154
- *
155
- * Since we can't safely abort the `setGlobalTheme` execution, we need to wait for it to properly finish before
156
- * applying the new theme.
157
- *
158
- * Without this, we can end up in the following scenario:
159
- * 1. app loads with the default 'light' theme, kicking off `setGlobalTheme`
160
- * 2. app switches to 'dark' theme after retrieving value persisted in local storage, calling `setGlobalTheme` again
161
- * 3. `setGlobalTheme` function execution for `dark` finishes before the initial `light` execution
162
- * 4. `setGlobalTheme` function execution for `light` then finishes, resulting in the 'light' theme being applied.
163
- */
164
- const cleanupLastFnCall = async () => {
165
- if (lastSetGlobalThemePromiseRef.current) {
166
- const unbindFn = await lastSetGlobalThemePromiseRef.current;
167
- unbindFn();
168
- lastSetGlobalThemePromiseRef.current = null;
169
- }
170
- };
171
- const safelySetGlobalTheme = async () => {
172
- await cleanupLastFnCall();
173
- const promise = setGlobalTheme({
174
- ...theme,
175
- colorMode: reconciledColorMode
176
- });
177
- lastSetGlobalThemePromiseRef.current = promise;
178
- };
179
- safelySetGlobalTheme();
180
- return function cleanup() {
181
- cleanupLastFnCall();
182
- };
183
- }, [theme, reconciledColorMode]);
184
- useEffect(() => {
185
- if (!prefersDarkModeMql) {
186
- return;
187
- }
188
- const unbindListener = bind(prefersDarkModeMql, {
189
- type: 'change',
190
- listener: event => {
191
- if (chosenColorMode === 'auto') {
192
- setReconciledColorMode(event.matches ? 'dark' : 'light');
193
- }
194
- }
195
- });
196
- return unbindListener;
197
- }, [chosenColorMode]);
198
- const attrs = getThemeHtmlAttrs({
199
- ...theme,
200
- colorMode: reconciledColorMode
201
- });
202
- return /*#__PURE__*/React.createElement(ColorModeContext.Provider, {
203
- value: reconciledColorMode
204
- }, /*#__PURE__*/React.createElement(SetColorModeContext.Provider, {
205
- value: setColorMode
206
- }, /*#__PURE__*/React.createElement(ThemeContext.Provider, {
207
- value: theme
208
- }, /*#__PURE__*/React.createElement(SetThemeContext.Provider, {
209
- value: setPartialTheme
210
- }, fg('platform-static-theme-loading') ? /*#__PURE__*/React.createElement("div", {
211
- "data-theme": attrs['data-theme'],
212
- "data-color-mode": attrs['data-color-mode'],
213
- className: ax([contentStyles.body])
214
- }, children) : children))));
215
- }
216
- export default ThemeProvider;