1 | "use strict";
|
2 |
|
3 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4 |
|
5 | Object.defineProperty(exports, "__esModule", {
|
6 | value: true
|
7 | });
|
8 | exports.getRegistry = getRegistry;
|
9 | exports.clearRegistry = clearRegistry;
|
10 | exports.setRegistry = setRegistry;
|
11 | exports.generateComponentTheme = generateComponentTheme;
|
12 | exports.generateTheme = generateTheme;
|
13 | exports.getRegisteredThemes = getRegisteredThemes;
|
14 | exports.registerComponentTheme = registerComponentTheme;
|
15 | exports.registerTheme = registerTheme;
|
16 | exports.mountComponentStyles = mountComponentStyles;
|
17 | exports.flushComponentStyles = flushComponentStyles;
|
18 | exports.ThemeRegistry = exports.default = void 0;
|
19 |
|
20 | var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
21 |
|
22 | var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
23 |
|
24 | var _console = require("@instructure/console");
|
25 |
|
26 | var _mergeDeep = require("@instructure/ui-utils/lib/mergeDeep.js");
|
27 |
|
28 | var _isEmpty = require("@instructure/ui-utils/lib/isEmpty.js");
|
29 |
|
30 | var _StyleSheet = require("@instructure/ui-stylesheet/lib/StyleSheet.js");
|
31 |
|
32 | var _uid = require("@instructure/uid");
|
33 |
|
34 | var _getCssText = require("./getCssText.js");
|
35 |
|
36 | var _transformCss = require("./transformCss.js");
|
37 |
|
38 | var DEFAULT_THEME_KEY = '@@themeableDefaultTheme';
|
39 | var GLOBAL_THEME_REGISTRY = 'GLOBAL_THEME_REGISTRY';
|
40 |
|
41 | if (global[GLOBAL_THEME_REGISTRY]) {
|
42 |
|
43 | ( 0, _console.error)(false, "[themeable] A theme registry has already been initialized. Ensure that you are importing only one copy of '@instructure/ui-themeable'.");
|
44 |
|
45 | setRegistry(validateRegistry(global[GLOBAL_THEME_REGISTRY]));
|
46 | } else {
|
47 |
|
48 | clearRegistry();
|
49 | }
|
50 |
|
51 | function makeRegistry() {
|
52 | return {
|
53 | styleSheet: _StyleSheet.StyleSheet,
|
54 | defaultThemeKey: null,
|
55 | components: (0, _defineProperty2.default)({}, DEFAULT_THEME_KEY, {}),
|
56 | themes: {},
|
57 | registered: []
|
58 |
|
59 | };
|
60 | }
|
61 |
|
62 | function validateRegistry(registry) {
|
63 | var defaultRegistry = makeRegistry();
|
64 |
|
65 | if (typeof registry === 'undefined') {
|
66 | return defaultRegistry;
|
67 | }
|
68 |
|
69 | var valid = true;
|
70 | Object.keys(defaultRegistry).forEach(function (key) {
|
71 | if (typeof registry[key] === 'undefined') {
|
72 | valid = false;
|
73 | }
|
74 | });
|
75 |
|
76 |
|
77 | ( 0, _console.error)(valid, '[themeable] Invalid global theme registry!');
|
78 | return registry;
|
79 | }
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 | function getRegistry() {
|
87 | return global[GLOBAL_THEME_REGISTRY];
|
88 | }
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | function setRegistry(registry) {
|
95 | global[GLOBAL_THEME_REGISTRY] = registry;
|
96 | }
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | function clearRegistry() {
|
103 | setRegistry(makeRegistry());
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | function getDefaultThemeKey() {
|
112 | var _getRegistry = getRegistry(),
|
113 | defaultThemeKey = _getRegistry.defaultThemeKey,
|
114 | registered = _getRegistry.registered;
|
115 |
|
116 | return defaultThemeKey || registered[registered.length - 1] || DEFAULT_THEME_KEY;
|
117 | }
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | function setDefaultTheme(themeKey, overrides) {
|
126 | var registry = getRegistry();
|
127 | var theme = registry.themes[themeKey];
|
128 |
|
129 | if (!theme) {
|
130 | if (themeKey !== DEFAULT_THEME_KEY) {
|
131 |
|
132 | ( 0, _console.error)(theme, "[themeable] Could not find theme: '".concat(themeKey, "' in the registry."));
|
133 | }
|
134 |
|
135 | theme = {};
|
136 | }
|
137 |
|
138 | registry.defaultThemeKey = themeKey;
|
139 | registry.overrides = overrides;
|
140 | return theme;
|
141 | }
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 | function makeTheme(_ref) {
|
151 | var key = _ref.key,
|
152 | variables = _ref.variables,
|
153 | a11y = _ref.a11y,
|
154 | immutable = _ref.immutable,
|
155 | description = _ref.description;
|
156 | var themeKey = key || (0, _uid.uid)();
|
157 | return {
|
158 | key: themeKey,
|
159 | immutable: immutable,
|
160 | variables: (0, _objectSpread2.default)({}, variables),
|
161 | description: description,
|
162 | use: function use() {
|
163 | var _ref2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {},
|
164 | accessible = _ref2.accessible,
|
165 | overrides = _ref2.overrides;
|
166 |
|
167 | if (accessible) {
|
168 |
|
169 | ( 0, _console.warn)(a11y && a11y.key, "[themeable] No accessible theme provided for ".concat(themeKey, "."));
|
170 |
|
171 | if (a11y && a11y.key) {
|
172 | setDefaultTheme(a11y.key);
|
173 | }
|
174 | } else {
|
175 | setDefaultTheme(themeKey, overrides);
|
176 | }
|
177 | }
|
178 | };
|
179 | }
|
180 |
|
181 | function registerTheme(theme) {
|
182 | var registry = getRegistry();
|
183 | var registeredTheme;
|
184 |
|
185 | if (theme.key && registry.themes[theme.key]) {
|
186 | registeredTheme = registry.themes[theme.key];
|
187 | } else {
|
188 | registeredTheme = makeTheme(theme);
|
189 | registry.themes[registeredTheme.key] = registeredTheme;
|
190 | registry.registered.push(registeredTheme.key);
|
191 | }
|
192 |
|
193 | return registeredTheme;
|
194 | }
|
195 |
|
196 | function getRegisteredTheme(themeKey) {
|
197 | var defaultTheme = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
198 | if (!themeKey) return defaultTheme;
|
199 | var theme = getRegistry().themes[themeKey];
|
200 |
|
201 | if (theme) {
|
202 | return theme;
|
203 | } else {
|
204 | if (themeKey !== DEFAULT_THEME_KEY) {
|
205 |
|
206 | ( 0, _console.error)(theme, "[themeable] Could not find theme: '".concat(themeKey, "' in the registry."));
|
207 | }
|
208 |
|
209 | return defaultTheme;
|
210 | }
|
211 | }
|
212 |
|
213 | function getVariablesWithOverrides(themeKey, overrides) {
|
214 | var theme = getRegisteredTheme(themeKey);
|
215 | var variables = theme.variables || {};
|
216 | var overridesIsEmpty = (0, _isEmpty.isEmpty)(overrides);
|
217 |
|
218 | if (!overridesIsEmpty && theme.immutable) {
|
219 |
|
220 | ( 0, _console.warn)(false, "[themeable] Theme, '".concat(theme.key, "', is immutable. Cannot apply overrides: ").concat(JSON.stringify(overrides)));
|
221 | return variables;
|
222 | }
|
223 |
|
224 | var variablesIsEmpty = (0, _isEmpty.isEmpty)(variables);
|
225 | if (!variablesIsEmpty && !overridesIsEmpty) return (0, _mergeDeep.mergeDeep)(variables, overrides);
|
226 | if (variablesIsEmpty) return overrides || {};
|
227 | return variables;
|
228 | }
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | function mergeWithDefaultThemeVariables(themeKey, overrides) {
|
239 | var variables;
|
240 |
|
241 | if (themeKey) {
|
242 | variables = getVariablesWithOverrides(themeKey, overrides);
|
243 | } else {
|
244 |
|
245 | var defaultOverrides = getRegistry().overrides;
|
246 | var defaultOverridesIsEmpty = (0, _isEmpty.isEmpty)(defaultOverrides);
|
247 |
|
248 | if (!defaultOverridesIsEmpty && !(0, _isEmpty.isEmpty)(overrides)) {
|
249 | variables = (0, _mergeDeep.mergeDeep)(defaultOverrides, overrides);
|
250 | } else if (defaultOverridesIsEmpty) {
|
251 | variables = overrides;
|
252 | } else {
|
253 | variables = defaultOverrides;
|
254 | }
|
255 | }
|
256 |
|
257 | return getVariablesWithOverrides(getDefaultThemeKey(), variables);
|
258 | }
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 | function makeComponentTheme(componentThemeFunction, themeKey) {
|
270 | return function (variables) {
|
271 | var theme = {};
|
272 |
|
273 | if (typeof componentThemeFunction === 'function') {
|
274 | theme = componentThemeFunction(variables);
|
275 | }
|
276 |
|
277 |
|
278 |
|
279 | var defaultComponentTheme = {};
|
280 |
|
281 | if (typeof componentThemeFunction[themeKey] === 'function') {
|
282 | defaultComponentTheme = componentThemeFunction[themeKey](variables);
|
283 | }
|
284 |
|
285 | if (!(0, _isEmpty.isEmpty)(defaultComponentTheme) && !(0, _isEmpty.isEmpty)(theme)) {
|
286 | theme = (0, _objectSpread2.default)({}, theme, {}, defaultComponentTheme);
|
287 | } else if ((0, _isEmpty.isEmpty)(theme)) {
|
288 | theme = defaultComponentTheme;
|
289 | }
|
290 |
|
291 | return theme;
|
292 | };
|
293 | }
|
294 |
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 | function registerComponentTheme(componentKey, componentThemeFunction) {
|
303 | var _getRegistry2 = getRegistry(),
|
304 | components = _getRegistry2.components;
|
305 |
|
306 | if (typeof componentThemeFunction !== 'function') {
|
307 | return;
|
308 | }
|
309 |
|
310 | components[DEFAULT_THEME_KEY][componentKey] = componentThemeFunction;
|
311 | Object.keys(componentThemeFunction).forEach(function (themeKey) {
|
312 |
|
313 | if (!components.hasOwnProperty(themeKey)) {
|
314 | components[themeKey] = {};
|
315 | }
|
316 |
|
317 | components[themeKey][componentKey] = makeComponentTheme(componentThemeFunction, themeKey);
|
318 | });
|
319 | }
|
320 |
|
321 | function getRegisteredComponents(themeKey) {
|
322 | var _getRegistry3 = getRegistry(),
|
323 | components = _getRegistry3.components;
|
324 |
|
325 | var t = themeKey || getDefaultThemeKey();
|
326 |
|
327 | return (0, _objectSpread2.default)({}, components[DEFAULT_THEME_KEY], {}, components[t]);
|
328 | }
|
329 |
|
330 | function getRegisteredComponent(themeKey, componentKey) {
|
331 | var _getRegistry4 = getRegistry(),
|
332 | components = _getRegistry4.components;
|
333 |
|
334 | return components[themeKey] && components[themeKey][componentKey] || components[DEFAULT_THEME_KEY][componentKey];
|
335 | }
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 | function generateTheme(themeKey, overrides) {
|
347 | var registry = getRegistry();
|
348 |
|
349 |
|
350 | ( 0, _console.error)(registry.registered.length > 0, '[themeable] No themes have been registered. ' + 'Import a theme from @instructure/ui-themes or register a custom theme with registerTheme ' + '(see @instructure/ui-themeable).');
|
351 | var components = getRegisteredComponents(themeKey);
|
352 | var theme = {};
|
353 | var variables = mergeWithDefaultThemeVariables(themeKey, overrides);
|
354 |
|
355 | if ((0, _isEmpty.isEmpty)(variables)) {
|
356 | return;
|
357 | }
|
358 |
|
359 | Object.getOwnPropertySymbols(components).forEach(function (componentKey) {
|
360 | theme[componentKey] = components[componentKey](variables);
|
361 | });
|
362 | return theme;
|
363 | }
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 | function generateComponentTheme(componentKey, themeKey, overrides) {
|
376 | var t = themeKey || getDefaultThemeKey();
|
377 | var theme = getRegisteredTheme(t);
|
378 | var componentTheme = {};
|
379 | var cachedComponentTheme = theme[componentKey];
|
380 |
|
381 | if (cachedComponentTheme) {
|
382 |
|
383 | componentTheme = cachedComponentTheme;
|
384 | } else {
|
385 | var variables = (0, _objectSpread2.default)({
|
386 | borders: {},
|
387 | breakpoints: {},
|
388 | colors: {},
|
389 | forms: {},
|
390 | media: {},
|
391 | shadows: {},
|
392 | spacing: {},
|
393 | stacking: {},
|
394 | transitions: {},
|
395 | typography: {}
|
396 | }, mergeWithDefaultThemeVariables(themeKey));
|
397 | var componentThemeFunction = getRegisteredComponent(t, componentKey);
|
398 |
|
399 | if (typeof componentThemeFunction === 'function') {
|
400 | try {
|
401 | componentTheme = componentThemeFunction(variables);
|
402 | } catch (e) {
|
403 |
|
404 | ( 0, _console.error)(false, "[themeable] ".concat(e));
|
405 | }
|
406 | }
|
407 | }
|
408 |
|
409 | if ((0, _isEmpty.isEmpty)(overrides)) {
|
410 | return theme[componentKey] = componentTheme;
|
411 | } else if (theme.immutable) {
|
412 |
|
413 | ( 0, _console.warn)(false, "[themeable] Theme '".concat(t, "' is immutable. Cannot apply overrides for '").concat(componentKey.toString(), "': ").concat(JSON.stringify(overrides)));
|
414 | return componentTheme;
|
415 | } else if ((0, _isEmpty.isEmpty)(componentTheme)) {
|
416 | return overrides;
|
417 | } else {
|
418 | return (0, _objectSpread2.default)({}, componentTheme, {}, overrides);
|
419 | }
|
420 | }
|
421 |
|
422 | function getRegisteredThemes() {
|
423 | return getRegistry().themes;
|
424 | }
|
425 |
|
426 | function mountComponentStyles(template, defaultTheme, componentId) {
|
427 | var _getRegistry5 = getRegistry(),
|
428 | styleSheet = _getRegistry5.styleSheet;
|
429 |
|
430 | if (styleSheet && !styleSheet.mounted(componentId)) {
|
431 | var cssText = (0, _getCssText.getCssText)(template, defaultTheme, componentId);
|
432 | styleSheet.mount(componentId, (0, _transformCss.toRules)(cssText));
|
433 | }
|
434 | }
|
435 |
|
436 | function flushComponentStyles() {
|
437 | var _getRegistry6 = getRegistry(),
|
438 | styleSheet = _getRegistry6.styleSheet;
|
439 |
|
440 | styleSheet && styleSheet.flush();
|
441 | }
|
442 |
|
443 | var ThemeRegistry = {
|
444 | getRegistry: getRegistry,
|
445 | clearRegistry: clearRegistry,
|
446 | setRegistry: setRegistry,
|
447 | generateComponentTheme: generateComponentTheme,
|
448 | generateTheme: generateTheme,
|
449 | getRegisteredThemes: getRegisteredThemes,
|
450 | registerComponentTheme: registerComponentTheme,
|
451 | registerTheme: registerTheme,
|
452 | mountComponentStyles: mountComponentStyles,
|
453 | flushComponentStyles: flushComponentStyles
|
454 | };
|
455 | exports.ThemeRegistry = ThemeRegistry;
|
456 | var _default = ThemeRegistry;
|
457 | exports.default = _default; |
\ | No newline at end of file |