@edx/frontend-platform 8.2.1 → 8.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.
- package/config.js +37 -1
- package/config.js.map +1 -1
- package/package.json +6 -4
- package/react/AppProvider.js +24 -5
- package/react/AppProvider.js.map +1 -1
- package/react/constants.js +4 -0
- package/react/constants.js.map +1 -0
- package/react/hooks/index.js +3 -0
- package/react/hooks/index.js.map +1 -0
- package/react/hooks/paragon/index.js +3 -0
- package/react/hooks/paragon/index.js.map +1 -0
- package/react/hooks/paragon/useParagonTheme.js +192 -0
- package/react/hooks/paragon/useParagonTheme.js.map +1 -0
- package/react/hooks/paragon/useParagonThemeCore.js +148 -0
- package/react/hooks/paragon/useParagonThemeCore.js.map +1 -0
- package/react/hooks/paragon/useParagonThemeUrls.js +180 -0
- package/react/hooks/paragon/useParagonThemeUrls.js.map +1 -0
- package/react/hooks/paragon/useParagonThemeVariants.js +216 -0
- package/react/hooks/paragon/useParagonThemeVariants.js.map +1 -0
- package/react/hooks/paragon/useTrackColorSchemeChoice.js +36 -0
- package/react/hooks/paragon/useTrackColorSchemeChoice.js.map +1 -0
- package/react/hooks/paragon/utils.js +27 -0
- package/react/hooks/paragon/utils.js.map +1 -0
- package/react/hooks/useAppEvent.js +24 -0
- package/react/hooks/useAppEvent.js.map +1 -0
- package/react/reducers.js +44 -0
- package/react/reducers.js.map +1 -0
- package/react/hooks.js +0 -54
- package/react/hooks.js.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import { useEffect, useState } from 'react';
|
|
8
|
+
import { logError, logInfo } from '../../../logging';
|
|
9
|
+
import { fallbackThemeUrl, removeExistingLinks } from './utils';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Custom React hook that manages the loading and updating of the core Paragon theme CSS and the brand override
|
|
13
|
+
* theme CSS. It ensures that the core theme CSS (both default and brand override) is added to the document
|
|
14
|
+
* `<head>` as `<link>` elements.
|
|
15
|
+
*
|
|
16
|
+
* The function logs and handles fallback logic in case the core theme fails to load.
|
|
17
|
+
*
|
|
18
|
+
* @memberof module:React
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} args - The arguments object containing theme and callback information.
|
|
21
|
+
* @param {Object} args.themeCore - The core theme configuration.
|
|
22
|
+
* @param {string} args.themeCore.urls.default - The URL to the default core theme CSS.
|
|
23
|
+
* @param {string} [args.themeCore.urls.brandOverride] - The URL to the brand override theme CSS (optional).
|
|
24
|
+
* @param {Function} args.onComplete - A callback function that is called once both the core Paragon (default)
|
|
25
|
+
* theme and brand override theme (if provided) are complete.
|
|
26
|
+
*/
|
|
27
|
+
var useParagonThemeCore = function useParagonThemeCore(_ref) {
|
|
28
|
+
var themeCore = _ref.themeCore,
|
|
29
|
+
onComplete = _ref.onComplete;
|
|
30
|
+
var _useState = useState(false),
|
|
31
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
32
|
+
isParagonThemeCoreComplete = _useState2[0],
|
|
33
|
+
setIsParagonThemeCoreComplete = _useState2[1];
|
|
34
|
+
var _useState3 = useState(false),
|
|
35
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
36
|
+
isBrandThemeCoreComplete = _useState4[0],
|
|
37
|
+
setIsBrandThemeCoreComplete = _useState4[1];
|
|
38
|
+
useEffect(function () {
|
|
39
|
+
// Call `onComplete` once both the paragon and brand theme core are complete.
|
|
40
|
+
if (isParagonThemeCoreComplete && isBrandThemeCoreComplete) {
|
|
41
|
+
onComplete();
|
|
42
|
+
}
|
|
43
|
+
}, [isParagonThemeCoreComplete, isBrandThemeCoreComplete, onComplete]);
|
|
44
|
+
useEffect(function () {
|
|
45
|
+
// If there is no config for the core theme url, do nothing.
|
|
46
|
+
if (!(themeCore !== null && themeCore !== void 0 && themeCore.urls)) {
|
|
47
|
+
setIsParagonThemeCoreComplete(true);
|
|
48
|
+
setIsBrandThemeCoreComplete(true);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
var existingCoreThemeLink = document.head.querySelector("link[href='".concat(themeCore.urls["default"], "']"));
|
|
52
|
+
var brandCoreLink = document.head.querySelector("link[href='".concat(themeCore.urls.brandOverride, "']"));
|
|
53
|
+
if (existingCoreThemeLink) {
|
|
54
|
+
existingCoreThemeLink.rel = 'stylesheet';
|
|
55
|
+
existingCoreThemeLink.removeAttribute('as');
|
|
56
|
+
existingCoreThemeLink.dataset.paragonThemeCore = true;
|
|
57
|
+
if (brandCoreLink) {
|
|
58
|
+
brandCoreLink.rel = 'stylesheet';
|
|
59
|
+
brandCoreLink.removeAttribute('as');
|
|
60
|
+
brandCoreLink.dataset.brandThemeCore = true;
|
|
61
|
+
}
|
|
62
|
+
setIsParagonThemeCoreComplete(true);
|
|
63
|
+
setIsBrandThemeCoreComplete(true);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
var getParagonThemeCoreLink = function getParagonThemeCoreLink() {
|
|
67
|
+
return document.head.querySelector('link[data-paragon-theme-core="true"]');
|
|
68
|
+
};
|
|
69
|
+
var getExistingCoreThemeLinks = function getExistingCoreThemeLinks(isBrandOverride) {
|
|
70
|
+
var coreThemeLinkSelector = "link[data-".concat(isBrandOverride ? 'brand' : 'paragon', "-theme-core=\"true\"]");
|
|
71
|
+
return document.head.querySelectorAll(coreThemeLinkSelector);
|
|
72
|
+
};
|
|
73
|
+
var _createCoreThemeLink = function createCoreThemeLink(url) {
|
|
74
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
75
|
+
_ref2$isFallbackTheme = _ref2.isFallbackThemeUrl,
|
|
76
|
+
isFallbackThemeUrl = _ref2$isFallbackTheme === void 0 ? false : _ref2$isFallbackTheme,
|
|
77
|
+
_ref2$isBrandOverride = _ref2.isBrandOverride,
|
|
78
|
+
isBrandOverride = _ref2$isBrandOverride === void 0 ? false : _ref2$isBrandOverride;
|
|
79
|
+
var coreThemeLink = document.createElement('link');
|
|
80
|
+
coreThemeLink.href = url;
|
|
81
|
+
coreThemeLink.rel = 'stylesheet';
|
|
82
|
+
if (isBrandOverride) {
|
|
83
|
+
coreThemeLink.dataset.brandThemeCore = true;
|
|
84
|
+
} else {
|
|
85
|
+
coreThemeLink.dataset.paragonThemeCore = true;
|
|
86
|
+
}
|
|
87
|
+
coreThemeLink.onload = function () {
|
|
88
|
+
if (isBrandOverride) {
|
|
89
|
+
setIsBrandThemeCoreComplete(true);
|
|
90
|
+
} else {
|
|
91
|
+
setIsParagonThemeCoreComplete(true);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
coreThemeLink.onerror = function () {
|
|
95
|
+
var _PARAGON_THEME$parago, _PARAGON_THEME;
|
|
96
|
+
if (isFallbackThemeUrl) {
|
|
97
|
+
logError('Could not load core theme fallback URL. Aborting.');
|
|
98
|
+
if (isBrandOverride) {
|
|
99
|
+
setIsBrandThemeCoreComplete(true);
|
|
100
|
+
} else {
|
|
101
|
+
setIsParagonThemeCoreComplete(true);
|
|
102
|
+
}
|
|
103
|
+
var otherExistingLinks = getExistingCoreThemeLinks(isBrandOverride);
|
|
104
|
+
removeExistingLinks(otherExistingLinks);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
var paragonThemeAccessor = isBrandOverride ? 'brand' : 'paragon';
|
|
108
|
+
var core = (_PARAGON_THEME$parago = (_PARAGON_THEME = PARAGON_THEME) === null || _PARAGON_THEME === void 0 || (_PARAGON_THEME = _PARAGON_THEME[paragonThemeAccessor]) === null || _PARAGON_THEME === void 0 || (_PARAGON_THEME = _PARAGON_THEME.themeUrls) === null || _PARAGON_THEME === void 0 ? void 0 : _PARAGON_THEME.core) !== null && _PARAGON_THEME$parago !== void 0 ? _PARAGON_THEME$parago : null;
|
|
109
|
+
if (core) {
|
|
110
|
+
var coreThemeFallbackUrl = fallbackThemeUrl(core.fileName);
|
|
111
|
+
logInfo("Could not load core theme CSS from ".concat(url, ". Falling back to locally installed core theme CSS: ").concat(coreThemeFallbackUrl));
|
|
112
|
+
coreThemeLink = _createCoreThemeLink(coreThemeFallbackUrl, {
|
|
113
|
+
isFallbackThemeUrl: true,
|
|
114
|
+
isBrandOverride: isBrandOverride
|
|
115
|
+
});
|
|
116
|
+
var _otherExistingLinks = getExistingCoreThemeLinks(isBrandOverride);
|
|
117
|
+
removeExistingLinks(_otherExistingLinks);
|
|
118
|
+
var foundParagonThemeCoreLink = getParagonThemeCoreLink();
|
|
119
|
+
if (foundParagonThemeCoreLink) {
|
|
120
|
+
foundParagonThemeCoreLink.insertAdjacentElement('afterend', coreThemeLink);
|
|
121
|
+
} else {
|
|
122
|
+
document.head.insertAdjacentElement('afterbegin', coreThemeLink);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
logError("Failed to load core theme CSS from ".concat(url, " or fallback URL. Aborting."));
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
return coreThemeLink;
|
|
129
|
+
};
|
|
130
|
+
var paragonCoreThemeLink = _createCoreThemeLink(themeCore.urls["default"]);
|
|
131
|
+
document.head.insertAdjacentElement('afterbegin', paragonCoreThemeLink);
|
|
132
|
+
if (themeCore.urls.brandOverride) {
|
|
133
|
+
var brandCoreThemeLink = _createCoreThemeLink(themeCore.urls.brandOverride, {
|
|
134
|
+
isBrandOverride: true
|
|
135
|
+
});
|
|
136
|
+
var foundParagonThemeCoreLink = getParagonThemeCoreLink();
|
|
137
|
+
if (foundParagonThemeCoreLink) {
|
|
138
|
+
foundParagonThemeCoreLink.insertAdjacentElement('afterend', brandCoreThemeLink);
|
|
139
|
+
} else {
|
|
140
|
+
document.head.insertAdjacentElement('afterbegin', brandCoreThemeLink);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
setIsBrandThemeCoreComplete(true);
|
|
144
|
+
}
|
|
145
|
+
}, [themeCore === null || themeCore === void 0 ? void 0 : themeCore.urls, onComplete]);
|
|
146
|
+
};
|
|
147
|
+
export default useParagonThemeCore;
|
|
148
|
+
//# sourceMappingURL=useParagonThemeCore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParagonThemeCore.js","names":["useEffect","useState","logError","logInfo","fallbackThemeUrl","removeExistingLinks","useParagonThemeCore","_ref","themeCore","onComplete","_useState","_useState2","_slicedToArray","isParagonThemeCoreComplete","setIsParagonThemeCoreComplete","_useState3","_useState4","isBrandThemeCoreComplete","setIsBrandThemeCoreComplete","urls","existingCoreThemeLink","document","head","querySelector","concat","brandCoreLink","brandOverride","rel","removeAttribute","dataset","paragonThemeCore","brandThemeCore","getParagonThemeCoreLink","getExistingCoreThemeLinks","isBrandOverride","coreThemeLinkSelector","querySelectorAll","createCoreThemeLink","url","_ref2","arguments","length","undefined","_ref2$isFallbackTheme","isFallbackThemeUrl","_ref2$isBrandOverride","coreThemeLink","createElement","href","onload","onerror","_PARAGON_THEME$parago","_PARAGON_THEME","otherExistingLinks","paragonThemeAccessor","core","PARAGON_THEME","themeUrls","coreThemeFallbackUrl","fileName","foundParagonThemeCoreLink","insertAdjacentElement","paragonCoreThemeLink","brandCoreThemeLink"],"sources":["../../../../src/react/hooks/paragon/useParagonThemeCore.js"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { logError, logInfo } from '../../../logging';\nimport { fallbackThemeUrl, removeExistingLinks } from './utils';\n\n/**\n * Custom React hook that manages the loading and updating of the core Paragon theme CSS and the brand override\n * theme CSS. It ensures that the core theme CSS (both default and brand override) is added to the document\n * `<head>` as `<link>` elements.\n *\n * The function logs and handles fallback logic in case the core theme fails to load.\n *\n * @memberof module:React\n *\n * @param {Object} args - The arguments object containing theme and callback information.\n * @param {Object} args.themeCore - The core theme configuration.\n * @param {string} args.themeCore.urls.default - The URL to the default core theme CSS.\n * @param {string} [args.themeCore.urls.brandOverride] - The URL to the brand override theme CSS (optional).\n * @param {Function} args.onComplete - A callback function that is called once both the core Paragon (default)\n * theme and brand override theme (if provided) are complete.\n */\nconst useParagonThemeCore = ({\n themeCore,\n onComplete,\n}) => {\n const [isParagonThemeCoreComplete, setIsParagonThemeCoreComplete] = useState(false);\n const [isBrandThemeCoreComplete, setIsBrandThemeCoreComplete] = useState(false);\n\n useEffect(() => {\n // Call `onComplete` once both the paragon and brand theme core are complete.\n if (isParagonThemeCoreComplete && isBrandThemeCoreComplete) {\n onComplete();\n }\n }, [isParagonThemeCoreComplete, isBrandThemeCoreComplete, onComplete]);\n\n useEffect(() => {\n // If there is no config for the core theme url, do nothing.\n if (!themeCore?.urls) {\n setIsParagonThemeCoreComplete(true);\n setIsBrandThemeCoreComplete(true);\n return;\n }\n\n const existingCoreThemeLink = document.head.querySelector(`link[href='${themeCore.urls.default}']`);\n const brandCoreLink = document.head.querySelector(`link[href='${themeCore.urls.brandOverride}']`);\n\n if (existingCoreThemeLink) {\n existingCoreThemeLink.rel = 'stylesheet';\n existingCoreThemeLink.removeAttribute('as');\n existingCoreThemeLink.dataset.paragonThemeCore = true;\n if (brandCoreLink) {\n brandCoreLink.rel = 'stylesheet';\n brandCoreLink.removeAttribute('as');\n brandCoreLink.dataset.brandThemeCore = true;\n }\n setIsParagonThemeCoreComplete(true);\n setIsBrandThemeCoreComplete(true);\n return;\n }\n\n const getParagonThemeCoreLink = () => document.head.querySelector('link[data-paragon-theme-core=\"true\"]');\n const getExistingCoreThemeLinks = (isBrandOverride) => {\n const coreThemeLinkSelector = `link[data-${isBrandOverride ? 'brand' : 'paragon'}-theme-core=\"true\"]`;\n return document.head.querySelectorAll(coreThemeLinkSelector);\n };\n\n const createCoreThemeLink = (\n url,\n {\n isFallbackThemeUrl = false,\n isBrandOverride = false,\n } = {},\n ) => {\n let coreThemeLink = document.createElement('link');\n coreThemeLink.href = url;\n coreThemeLink.rel = 'stylesheet';\n if (isBrandOverride) {\n coreThemeLink.dataset.brandThemeCore = true;\n } else {\n coreThemeLink.dataset.paragonThemeCore = true;\n }\n coreThemeLink.onload = () => {\n if (isBrandOverride) {\n setIsBrandThemeCoreComplete(true);\n } else {\n setIsParagonThemeCoreComplete(true);\n }\n };\n coreThemeLink.onerror = () => {\n if (isFallbackThemeUrl) {\n logError('Could not load core theme fallback URL. Aborting.');\n if (isBrandOverride) {\n setIsBrandThemeCoreComplete(true);\n } else {\n setIsParagonThemeCoreComplete(true);\n }\n const otherExistingLinks = getExistingCoreThemeLinks(isBrandOverride);\n removeExistingLinks(otherExistingLinks);\n return;\n }\n const paragonThemeAccessor = isBrandOverride ? 'brand' : 'paragon';\n const core = PARAGON_THEME?.[paragonThemeAccessor]?.themeUrls?.core ?? null;\n if (core) {\n const coreThemeFallbackUrl = fallbackThemeUrl(core.fileName);\n logInfo(`Could not load core theme CSS from ${url}. Falling back to locally installed core theme CSS: ${coreThemeFallbackUrl}`);\n coreThemeLink = createCoreThemeLink(coreThemeFallbackUrl, { isFallbackThemeUrl: true, isBrandOverride });\n const otherExistingLinks = getExistingCoreThemeLinks(isBrandOverride);\n removeExistingLinks(otherExistingLinks);\n const foundParagonThemeCoreLink = getParagonThemeCoreLink();\n if (foundParagonThemeCoreLink) {\n foundParagonThemeCoreLink.insertAdjacentElement(\n 'afterend',\n coreThemeLink,\n );\n } else {\n document.head.insertAdjacentElement(\n 'afterbegin',\n coreThemeLink,\n );\n }\n } else {\n logError(`Failed to load core theme CSS from ${url} or fallback URL. Aborting.`);\n }\n };\n return coreThemeLink;\n };\n\n const paragonCoreThemeLink = createCoreThemeLink(themeCore.urls.default);\n document.head.insertAdjacentElement(\n 'afterbegin',\n paragonCoreThemeLink,\n );\n\n if (themeCore.urls.brandOverride) {\n const brandCoreThemeLink = createCoreThemeLink(themeCore.urls.brandOverride, { isBrandOverride: true });\n const foundParagonThemeCoreLink = getParagonThemeCoreLink();\n if (foundParagonThemeCoreLink) {\n foundParagonThemeCoreLink.insertAdjacentElement(\n 'afterend',\n brandCoreThemeLink,\n );\n } else {\n document.head.insertAdjacentElement(\n 'afterbegin',\n brandCoreThemeLink,\n );\n }\n } else {\n setIsBrandThemeCoreComplete(true);\n }\n }, [themeCore?.urls, onComplete]);\n};\n\nexport default useParagonThemeCore;\n"],"mappings":";;;;;;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAE3C,SAASC,QAAQ,EAAEC,OAAO,QAAQ,kBAAkB;AACpD,SAASC,gBAAgB,EAAEC,mBAAmB,QAAQ,SAAS;;AAE/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAAC,IAAA,EAGnB;EAAA,IAFJC,SAAS,GAAAD,IAAA,CAATC,SAAS;IACTC,UAAU,GAAAF,IAAA,CAAVE,UAAU;EAEV,IAAAC,SAAA,GAAoET,QAAQ,CAAC,KAAK,CAAC;IAAAU,UAAA,GAAAC,cAAA,CAAAF,SAAA;IAA5EG,0BAA0B,GAAAF,UAAA;IAAEG,6BAA6B,GAAAH,UAAA;EAChE,IAAAI,UAAA,GAAgEd,QAAQ,CAAC,KAAK,CAAC;IAAAe,UAAA,GAAAJ,cAAA,CAAAG,UAAA;IAAxEE,wBAAwB,GAAAD,UAAA;IAAEE,2BAA2B,GAAAF,UAAA;EAE5DhB,SAAS,CAAC,YAAM;IACd;IACA,IAAIa,0BAA0B,IAAII,wBAAwB,EAAE;MAC1DR,UAAU,CAAC,CAAC;IACd;EACF,CAAC,EAAE,CAACI,0BAA0B,EAAEI,wBAAwB,EAAER,UAAU,CAAC,CAAC;EAEtET,SAAS,CAAC,YAAM;IACd;IACA,IAAI,EAACQ,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEW,IAAI,GAAE;MACpBL,6BAA6B,CAAC,IAAI,CAAC;MACnCI,2BAA2B,CAAC,IAAI,CAAC;MACjC;IACF;IAEA,IAAME,qBAAqB,GAAGC,QAAQ,CAACC,IAAI,CAACC,aAAa,eAAAC,MAAA,CAAehB,SAAS,CAACW,IAAI,WAAQ,OAAI,CAAC;IACnG,IAAMM,aAAa,GAAGJ,QAAQ,CAACC,IAAI,CAACC,aAAa,eAAAC,MAAA,CAAehB,SAAS,CAACW,IAAI,CAACO,aAAa,OAAI,CAAC;IAEjG,IAAIN,qBAAqB,EAAE;MACzBA,qBAAqB,CAACO,GAAG,GAAG,YAAY;MACxCP,qBAAqB,CAACQ,eAAe,CAAC,IAAI,CAAC;MAC3CR,qBAAqB,CAACS,OAAO,CAACC,gBAAgB,GAAG,IAAI;MACrD,IAAIL,aAAa,EAAE;QACjBA,aAAa,CAACE,GAAG,GAAG,YAAY;QAChCF,aAAa,CAACG,eAAe,CAAC,IAAI,CAAC;QACnCH,aAAa,CAACI,OAAO,CAACE,cAAc,GAAG,IAAI;MAC7C;MACAjB,6BAA6B,CAAC,IAAI,CAAC;MACnCI,2BAA2B,CAAC,IAAI,CAAC;MACjC;IACF;IAEA,IAAMc,uBAAuB,GAAG,SAA1BA,uBAAuBA,CAAA;MAAA,OAASX,QAAQ,CAACC,IAAI,CAACC,aAAa,CAAC,sCAAsC,CAAC;IAAA;IACzG,IAAMU,yBAAyB,GAAG,SAA5BA,yBAAyBA,CAAIC,eAAe,EAAK;MACrD,IAAMC,qBAAqB,gBAAAX,MAAA,CAAgBU,eAAe,GAAG,OAAO,GAAG,SAAS,0BAAqB;MACrG,OAAOb,QAAQ,CAACC,IAAI,CAACc,gBAAgB,CAACD,qBAAqB,CAAC;IAC9D,CAAC;IAED,IAAME,oBAAmB,GAAG,SAAtBA,mBAAmBA,CACvBC,GAAG,EAKA;MAAA,IAAAC,KAAA,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MADC,CAAC,CAAC;QAAAG,qBAAA,GAAAJ,KAAA,CAFJK,kBAAkB;QAAlBA,kBAAkB,GAAAD,qBAAA,cAAG,KAAK,GAAAA,qBAAA;QAAAE,qBAAA,GAAAN,KAAA,CAC1BL,eAAe;QAAfA,eAAe,GAAAW,qBAAA,cAAG,KAAK,GAAAA,qBAAA;MAGzB,IAAIC,aAAa,GAAGzB,QAAQ,CAAC0B,aAAa,CAAC,MAAM,CAAC;MAClDD,aAAa,CAACE,IAAI,GAAGV,GAAG;MACxBQ,aAAa,CAACnB,GAAG,GAAG,YAAY;MAChC,IAAIO,eAAe,EAAE;QACnBY,aAAa,CAACjB,OAAO,CAACE,cAAc,GAAG,IAAI;MAC7C,CAAC,MAAM;QACLe,aAAa,CAACjB,OAAO,CAACC,gBAAgB,GAAG,IAAI;MAC/C;MACAgB,aAAa,CAACG,MAAM,GAAG,YAAM;QAC3B,IAAIf,eAAe,EAAE;UACnBhB,2BAA2B,CAAC,IAAI,CAAC;QACnC,CAAC,MAAM;UACLJ,6BAA6B,CAAC,IAAI,CAAC;QACrC;MACF,CAAC;MACDgC,aAAa,CAACI,OAAO,GAAG,YAAM;QAAA,IAAAC,qBAAA,EAAAC,cAAA;QAC5B,IAAIR,kBAAkB,EAAE;UACtB1C,QAAQ,CAAC,mDAAmD,CAAC;UAC7D,IAAIgC,eAAe,EAAE;YACnBhB,2BAA2B,CAAC,IAAI,CAAC;UACnC,CAAC,MAAM;YACLJ,6BAA6B,CAAC,IAAI,CAAC;UACrC;UACA,IAAMuC,kBAAkB,GAAGpB,yBAAyB,CAACC,eAAe,CAAC;UACrE7B,mBAAmB,CAACgD,kBAAkB,CAAC;UACvC;QACF;QACA,IAAMC,oBAAoB,GAAGpB,eAAe,GAAG,OAAO,GAAG,SAAS;QAClE,IAAMqB,IAAI,IAAAJ,qBAAA,IAAAC,cAAA,GAAGI,aAAa,cAAAJ,cAAA,gBAAAA,cAAA,GAAbA,cAAA,CAAgBE,oBAAoB,CAAC,cAAAF,cAAA,gBAAAA,cAAA,GAArCA,cAAA,CAAuCK,SAAS,cAAAL,cAAA,uBAAhDA,cAAA,CAAkDG,IAAI,cAAAJ,qBAAA,cAAAA,qBAAA,GAAI,IAAI;QAC3E,IAAII,IAAI,EAAE;UACR,IAAMG,oBAAoB,GAAGtD,gBAAgB,CAACmD,IAAI,CAACI,QAAQ,CAAC;UAC5DxD,OAAO,uCAAAqB,MAAA,CAAuCc,GAAG,0DAAAd,MAAA,CAAuDkC,oBAAoB,CAAE,CAAC;UAC/HZ,aAAa,GAAGT,oBAAmB,CAACqB,oBAAoB,EAAE;YAAEd,kBAAkB,EAAE,IAAI;YAAEV,eAAe,EAAfA;UAAgB,CAAC,CAAC;UACxG,IAAMmB,mBAAkB,GAAGpB,yBAAyB,CAACC,eAAe,CAAC;UACrE7B,mBAAmB,CAACgD,mBAAkB,CAAC;UACvC,IAAMO,yBAAyB,GAAG5B,uBAAuB,CAAC,CAAC;UAC3D,IAAI4B,yBAAyB,EAAE;YAC7BA,yBAAyB,CAACC,qBAAqB,CAC7C,UAAU,EACVf,aACF,CAAC;UACH,CAAC,MAAM;YACLzB,QAAQ,CAACC,IAAI,CAACuC,qBAAqB,CACjC,YAAY,EACZf,aACF,CAAC;UACH;QACF,CAAC,MAAM;UACL5C,QAAQ,uCAAAsB,MAAA,CAAuCc,GAAG,gCAA6B,CAAC;QAClF;MACF,CAAC;MACD,OAAOQ,aAAa;IACtB,CAAC;IAED,IAAMgB,oBAAoB,GAAGzB,oBAAmB,CAAC7B,SAAS,CAACW,IAAI,WAAQ,CAAC;IACxEE,QAAQ,CAACC,IAAI,CAACuC,qBAAqB,CACjC,YAAY,EACZC,oBACF,CAAC;IAED,IAAItD,SAAS,CAACW,IAAI,CAACO,aAAa,EAAE;MAChC,IAAMqC,kBAAkB,GAAG1B,oBAAmB,CAAC7B,SAAS,CAACW,IAAI,CAACO,aAAa,EAAE;QAAEQ,eAAe,EAAE;MAAK,CAAC,CAAC;MACvG,IAAM0B,yBAAyB,GAAG5B,uBAAuB,CAAC,CAAC;MAC3D,IAAI4B,yBAAyB,EAAE;QAC7BA,yBAAyB,CAACC,qBAAqB,CAC7C,UAAU,EACVE,kBACF,CAAC;MACH,CAAC,MAAM;QACL1C,QAAQ,CAACC,IAAI,CAACuC,qBAAqB,CACjC,YAAY,EACZE,kBACF,CAAC;MACH;IACF,CAAC,MAAM;MACL7C,2BAA2B,CAAC,IAAI,CAAC;IACnC;EACF,CAAC,EAAE,CAACV,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAEW,IAAI,EAAEV,UAAU,CAAC,CAAC;AACnC,CAAC;AAED,eAAeH,mBAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
var _excluded = ["fileName"];
|
|
2
|
+
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; }
|
|
3
|
+
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) { _defineProperty(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; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
8
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
9
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
10
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
11
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
12
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
13
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
14
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
15
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
16
|
+
import { useMemo } from 'react';
|
|
17
|
+
import { fallbackThemeUrl, isEmptyObject } from './utils';
|
|
18
|
+
import { getConfig } from '../../../config';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Replaces a wildcard in the URL string with a provided local version string.
|
|
22
|
+
* This is typically used to substitute a version placeholder (e.g., `$paragonVersion`)
|
|
23
|
+
* in URLs with actual version values.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} args - The arguments object for version substitution.
|
|
26
|
+
* @param {string} args.url - The URL string that may contain a wildcard keyword (e.g., `$paragonVersion`).
|
|
27
|
+
* @param {string} args.wildcardKeyword - The keyword (e.g., `$paragonVersion`) in the URL to be replaced
|
|
28
|
+
* with the local version.
|
|
29
|
+
* @param {string} args.localVersion - The local version string to replace the wildcard with.
|
|
30
|
+
*
|
|
31
|
+
* @returns {string} The URL with the wildcard keyword replaced by the provided version string.
|
|
32
|
+
* If the conditions are not met (e.g., missing URL or version), the original URL is returned.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* const url = 'https://cdn.example.com/$paragonVersion/theme.css';
|
|
36
|
+
* const version = '1.0.0';
|
|
37
|
+
* const updatedUrl = handleVersionSubstitution({ url, wildcardKeyword: '$paragonVersion', localVersion: version });
|
|
38
|
+
* console.log(updatedUrl); // Outputs: 'https://cdn.example.com/1.0.0/theme.css'
|
|
39
|
+
*/
|
|
40
|
+
export var handleVersionSubstitution = function handleVersionSubstitution(_ref) {
|
|
41
|
+
var url = _ref.url,
|
|
42
|
+
wildcardKeyword = _ref.wildcardKeyword,
|
|
43
|
+
localVersion = _ref.localVersion;
|
|
44
|
+
if (!url || !url.includes(wildcardKeyword) || !localVersion) {
|
|
45
|
+
return url;
|
|
46
|
+
}
|
|
47
|
+
return url.replaceAll(wildcardKeyword, localVersion);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Custom React hook that retrieves the Paragon theme URLs, including the core theme CSS and any theme variants.
|
|
52
|
+
* It supports version substitution for the Paragon and brand versions and returns a structured object containing
|
|
53
|
+
* the URLs. The hook also handles fallback scenarios when the URLs are unavailable in the configuration or when
|
|
54
|
+
* version substitution is required.
|
|
55
|
+
*
|
|
56
|
+
* @returns {Object|undefined} An object containing:
|
|
57
|
+
* - `core`: The core theme URLs (including default and brand override).
|
|
58
|
+
* - `defaults`: Any default theme variants.
|
|
59
|
+
* - `variants`: The URLs for any additional theme variants (default and brand override).
|
|
60
|
+
*
|
|
61
|
+
* If the required URLs are not available or cannot be determined, `undefined` is returned.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const themeUrls = useParagonThemeUrls();
|
|
65
|
+
* if (themeUrls) {
|
|
66
|
+
* console.log(themeUrls.core.urls.default); // Outputs the URL of the core theme CSS
|
|
67
|
+
* console.log(themeUrls.variants['dark'].urls.default); // Outputs the URL of the dark theme variant CSS
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
var useParagonThemeUrls = function useParagonThemeUrls() {
|
|
72
|
+
return useMemo(function () {
|
|
73
|
+
var _paragonThemeUrls$cor, _paragonThemeUrls$cor2, _paragonThemeUrls$cor3, _PARAGON_THEME, _PARAGON_THEME2;
|
|
74
|
+
var _getConfig = getConfig(),
|
|
75
|
+
paragonThemeUrls = _getConfig.PARAGON_THEME_URLS;
|
|
76
|
+
if (!paragonThemeUrls) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
var paragonCoreCssUrl = _typeof(paragonThemeUrls === null || paragonThemeUrls === void 0 || (_paragonThemeUrls$cor = paragonThemeUrls.core) === null || _paragonThemeUrls$cor === void 0 ? void 0 : _paragonThemeUrls$cor.urls) === 'object' ? paragonThemeUrls.core.urls["default"] : paragonThemeUrls === null || paragonThemeUrls === void 0 || (_paragonThemeUrls$cor2 = paragonThemeUrls.core) === null || _paragonThemeUrls$cor2 === void 0 ? void 0 : _paragonThemeUrls$cor2.url;
|
|
80
|
+
var brandCoreCssUrl = _typeof(paragonThemeUrls === null || paragonThemeUrls === void 0 || (_paragonThemeUrls$cor3 = paragonThemeUrls.core) === null || _paragonThemeUrls$cor3 === void 0 ? void 0 : _paragonThemeUrls$cor3.urls) === 'object' ? paragonThemeUrls.core.urls.brandOverride : undefined;
|
|
81
|
+
var defaultThemeVariants = paragonThemeUrls.defaults;
|
|
82
|
+
|
|
83
|
+
// Local versions of @openedx/paragon and @edx/brand
|
|
84
|
+
// these are only used when passed into handleVersionSubstitution
|
|
85
|
+
// which does not attempt substitution using falsy value
|
|
86
|
+
var localParagonVersion = (_PARAGON_THEME = PARAGON_THEME) === null || _PARAGON_THEME === void 0 || (_PARAGON_THEME = _PARAGON_THEME.paragon) === null || _PARAGON_THEME === void 0 ? void 0 : _PARAGON_THEME.version;
|
|
87
|
+
var localBrandVersion = (_PARAGON_THEME2 = PARAGON_THEME) === null || _PARAGON_THEME2 === void 0 || (_PARAGON_THEME2 = _PARAGON_THEME2.brand) === null || _PARAGON_THEME2 === void 0 ? void 0 : _PARAGON_THEME2.version;
|
|
88
|
+
var coreCss = {
|
|
89
|
+
"default": handleVersionSubstitution({
|
|
90
|
+
url: paragonCoreCssUrl,
|
|
91
|
+
wildcardKeyword: '$paragonVersion',
|
|
92
|
+
localVersion: localParagonVersion
|
|
93
|
+
}),
|
|
94
|
+
brandOverride: handleVersionSubstitution({
|
|
95
|
+
url: brandCoreCssUrl,
|
|
96
|
+
wildcardKeyword: '$brandVersion',
|
|
97
|
+
localVersion: localBrandVersion
|
|
98
|
+
})
|
|
99
|
+
};
|
|
100
|
+
var themeVariantsCss = {};
|
|
101
|
+
var themeVariantsEntries = Object.entries(paragonThemeUrls.variants || {});
|
|
102
|
+
themeVariantsEntries.forEach(function (_ref2) {
|
|
103
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
104
|
+
themeVariant = _ref3[0],
|
|
105
|
+
_ref3$ = _ref3[1],
|
|
106
|
+
url = _ref3$.url,
|
|
107
|
+
urls = _ref3$.urls;
|
|
108
|
+
var themeVariantMetadata = {
|
|
109
|
+
urls: null
|
|
110
|
+
};
|
|
111
|
+
if (url) {
|
|
112
|
+
themeVariantMetadata.urls = {
|
|
113
|
+
"default": handleVersionSubstitution({
|
|
114
|
+
url: url,
|
|
115
|
+
wildcardKeyword: '$paragonVersion',
|
|
116
|
+
localVersion: localParagonVersion
|
|
117
|
+
})
|
|
118
|
+
};
|
|
119
|
+
} else {
|
|
120
|
+
themeVariantMetadata.urls = {
|
|
121
|
+
"default": handleVersionSubstitution({
|
|
122
|
+
url: urls["default"],
|
|
123
|
+
wildcardKeyword: '$paragonVersion',
|
|
124
|
+
localVersion: localParagonVersion
|
|
125
|
+
}),
|
|
126
|
+
brandOverride: handleVersionSubstitution({
|
|
127
|
+
url: urls.brandOverride,
|
|
128
|
+
wildcardKeyword: '$brandVersion',
|
|
129
|
+
localVersion: localBrandVersion
|
|
130
|
+
})
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
themeVariantsCss[themeVariant] = themeVariantMetadata;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// If we don't have the core default or any theme variants, use the PARAGON_THEME
|
|
137
|
+
if (!coreCss["default"] || isEmptyObject(themeVariantsCss) || isEmptyObject(defaultThemeVariants)) {
|
|
138
|
+
var _PARAGON_THEME$parago, _PARAGON_THEME$parago2, _PARAGON_THEME$parago3;
|
|
139
|
+
var localCoreUrl = (_PARAGON_THEME$parago = PARAGON_THEME.paragon) === null || _PARAGON_THEME$parago === void 0 || (_PARAGON_THEME$parago = _PARAGON_THEME$parago.themeUrls) === null || _PARAGON_THEME$parago === void 0 ? void 0 : _PARAGON_THEME$parago.core;
|
|
140
|
+
var localThemeVariants = (_PARAGON_THEME$parago2 = PARAGON_THEME.paragon) === null || _PARAGON_THEME$parago2 === void 0 || (_PARAGON_THEME$parago2 = _PARAGON_THEME$parago2.themeUrls) === null || _PARAGON_THEME$parago2 === void 0 ? void 0 : _PARAGON_THEME$parago2.variants;
|
|
141
|
+
var localDefaultThemeVariants = (_PARAGON_THEME$parago3 = PARAGON_THEME.paragon) === null || _PARAGON_THEME$parago3 === void 0 || (_PARAGON_THEME$parago3 = _PARAGON_THEME$parago3.themeUrls) === null || _PARAGON_THEME$parago3 === void 0 ? void 0 : _PARAGON_THEME$parago3.defaults;
|
|
142
|
+
if (isEmptyObject(localCoreUrl) || isEmptyObject(localThemeVariants)) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
if (!coreCss["default"]) {
|
|
146
|
+
coreCss["default"] = fallbackThemeUrl(localCoreUrl === null || localCoreUrl === void 0 ? void 0 : localCoreUrl.fileName);
|
|
147
|
+
}
|
|
148
|
+
if (isEmptyObject(themeVariantsCss)) {
|
|
149
|
+
Object.entries(localThemeVariants).forEach(function (_ref5) {
|
|
150
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
151
|
+
themeVariant = _ref6[0],
|
|
152
|
+
_ref4 = _ref6[1];
|
|
153
|
+
var fileName = _ref4.fileName,
|
|
154
|
+
rest = _objectWithoutProperties(_ref4, _excluded);
|
|
155
|
+
themeVariantsCss[themeVariant] = {
|
|
156
|
+
urls: _objectSpread({
|
|
157
|
+
"default": fallbackThemeUrl(fileName)
|
|
158
|
+
}, rest.urls)
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
core: {
|
|
164
|
+
urls: coreCss
|
|
165
|
+
},
|
|
166
|
+
defaults: defaultThemeVariants || localDefaultThemeVariants,
|
|
167
|
+
variants: themeVariantsCss
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
core: {
|
|
172
|
+
urls: coreCss
|
|
173
|
+
},
|
|
174
|
+
defaults: defaultThemeVariants,
|
|
175
|
+
variants: themeVariantsCss
|
|
176
|
+
};
|
|
177
|
+
}, []);
|
|
178
|
+
};
|
|
179
|
+
export default useParagonThemeUrls;
|
|
180
|
+
//# sourceMappingURL=useParagonThemeUrls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParagonThemeUrls.js","names":["useMemo","fallbackThemeUrl","isEmptyObject","getConfig","handleVersionSubstitution","_ref","url","wildcardKeyword","localVersion","includes","replaceAll","useParagonThemeUrls","_paragonThemeUrls$cor","_paragonThemeUrls$cor2","_paragonThemeUrls$cor3","_PARAGON_THEME","_PARAGON_THEME2","_getConfig","paragonThemeUrls","PARAGON_THEME_URLS","undefined","paragonCoreCssUrl","_typeof","core","urls","brandCoreCssUrl","brandOverride","defaultThemeVariants","defaults","localParagonVersion","PARAGON_THEME","paragon","version","localBrandVersion","brand","coreCss","themeVariantsCss","themeVariantsEntries","Object","entries","variants","forEach","_ref2","_ref3","_slicedToArray","themeVariant","_ref3$","themeVariantMetadata","_PARAGON_THEME$parago","_PARAGON_THEME$parago2","_PARAGON_THEME$parago3","localCoreUrl","themeUrls","localThemeVariants","localDefaultThemeVariants","fileName","_ref5","_ref6","_ref4","rest","_objectWithoutProperties","_excluded","_objectSpread"],"sources":["../../../../src/react/hooks/paragon/useParagonThemeUrls.js"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { fallbackThemeUrl, isEmptyObject } from './utils';\nimport { getConfig } from '../../../config';\n\n/**\n * Replaces a wildcard in the URL string with a provided local version string.\n * This is typically used to substitute a version placeholder (e.g., `$paragonVersion`)\n * in URLs with actual version values.\n *\n * @param {Object} args - The arguments object for version substitution.\n * @param {string} args.url - The URL string that may contain a wildcard keyword (e.g., `$paragonVersion`).\n * @param {string} args.wildcardKeyword - The keyword (e.g., `$paragonVersion`) in the URL to be replaced\n * with the local version.\n * @param {string} args.localVersion - The local version string to replace the wildcard with.\n *\n * @returns {string} The URL with the wildcard keyword replaced by the provided version string.\n * If the conditions are not met (e.g., missing URL or version), the original URL is returned.\n *\n * @example\n * const url = 'https://cdn.example.com/$paragonVersion/theme.css';\n * const version = '1.0.0';\n * const updatedUrl = handleVersionSubstitution({ url, wildcardKeyword: '$paragonVersion', localVersion: version });\n * console.log(updatedUrl); // Outputs: 'https://cdn.example.com/1.0.0/theme.css'\n */\nexport const handleVersionSubstitution = ({ url, wildcardKeyword, localVersion }) => {\n if (!url || !url.includes(wildcardKeyword) || !localVersion) {\n return url;\n }\n return url.replaceAll(wildcardKeyword, localVersion);\n};\n\n/**\n * Custom React hook that retrieves the Paragon theme URLs, including the core theme CSS and any theme variants.\n * It supports version substitution for the Paragon and brand versions and returns a structured object containing\n * the URLs. The hook also handles fallback scenarios when the URLs are unavailable in the configuration or when\n * version substitution is required.\n *\n * @returns {Object|undefined} An object containing:\n * - `core`: The core theme URLs (including default and brand override).\n * - `defaults`: Any default theme variants.\n * - `variants`: The URLs for any additional theme variants (default and brand override).\n *\n * If the required URLs are not available or cannot be determined, `undefined` is returned.\n *\n * @example\n * const themeUrls = useParagonThemeUrls();\n * if (themeUrls) {\n * console.log(themeUrls.core.urls.default); // Outputs the URL of the core theme CSS\n * console.log(themeUrls.variants['dark'].urls.default); // Outputs the URL of the dark theme variant CSS\n * }\n *\n */\nconst useParagonThemeUrls = () => useMemo(() => {\n const { PARAGON_THEME_URLS: paragonThemeUrls } = getConfig();\n if (!paragonThemeUrls) {\n return undefined;\n }\n\n const paragonCoreCssUrl = typeof paragonThemeUrls?.core?.urls === 'object' ? paragonThemeUrls.core.urls.default : paragonThemeUrls?.core?.url;\n const brandCoreCssUrl = typeof paragonThemeUrls?.core?.urls === 'object' ? paragonThemeUrls.core.urls.brandOverride : undefined;\n const defaultThemeVariants = paragonThemeUrls.defaults;\n\n // Local versions of @openedx/paragon and @edx/brand\n // these are only used when passed into handleVersionSubstitution\n // which does not attempt substitution using falsy value\n const localParagonVersion = PARAGON_THEME?.paragon?.version;\n const localBrandVersion = PARAGON_THEME?.brand?.version;\n\n const coreCss = {\n default: handleVersionSubstitution({ url: paragonCoreCssUrl, wildcardKeyword: '$paragonVersion', localVersion: localParagonVersion }),\n brandOverride: handleVersionSubstitution({ url: brandCoreCssUrl, wildcardKeyword: '$brandVersion', localVersion: localBrandVersion }),\n };\n const themeVariantsCss = {};\n const themeVariantsEntries = Object.entries(paragonThemeUrls.variants || {});\n themeVariantsEntries.forEach(([themeVariant, { url, urls }]) => {\n const themeVariantMetadata = { urls: null };\n if (url) {\n themeVariantMetadata.urls = {\n default: handleVersionSubstitution({\n url,\n wildcardKeyword: '$paragonVersion',\n localVersion: localParagonVersion,\n }),\n };\n } else {\n themeVariantMetadata.urls = {\n default: handleVersionSubstitution({\n url: urls.default,\n wildcardKeyword: '$paragonVersion',\n localVersion: localParagonVersion,\n }),\n brandOverride: handleVersionSubstitution({\n url: urls.brandOverride,\n wildcardKeyword: '$brandVersion',\n localVersion: localBrandVersion,\n }),\n };\n }\n themeVariantsCss[themeVariant] = themeVariantMetadata;\n });\n\n // If we don't have the core default or any theme variants, use the PARAGON_THEME\n if (!coreCss.default || isEmptyObject(themeVariantsCss) || isEmptyObject(defaultThemeVariants)) {\n const localCoreUrl = PARAGON_THEME.paragon?.themeUrls?.core;\n const localThemeVariants = PARAGON_THEME.paragon?.themeUrls?.variants;\n const localDefaultThemeVariants = PARAGON_THEME.paragon?.themeUrls?.defaults;\n\n if (isEmptyObject(localCoreUrl) || isEmptyObject(localThemeVariants)) {\n return undefined;\n }\n if (!coreCss.default) {\n coreCss.default = fallbackThemeUrl(localCoreUrl?.fileName);\n }\n\n if (isEmptyObject(themeVariantsCss)) {\n Object.entries(localThemeVariants).forEach(([themeVariant, { fileName, ...rest }]) => {\n themeVariantsCss[themeVariant] = {\n urls: { default: fallbackThemeUrl(fileName), ...rest.urls },\n };\n });\n }\n return {\n core: { urls: coreCss },\n defaults: defaultThemeVariants || localDefaultThemeVariants,\n variants: themeVariantsCss,\n };\n }\n\n return {\n core: { urls: coreCss },\n defaults: defaultThemeVariants,\n variants: themeVariantsCss,\n };\n}, []);\n\nexport default useParagonThemeUrls;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import { useEffect, useState } from 'react';
|
|
8
|
+
import { logError, logInfo } from '../../../logging';
|
|
9
|
+
import { fallbackThemeUrl, removeExistingLinks } from './utils';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A custom React hook that manages the loading of theme variant CSS files dynamically.
|
|
13
|
+
* Adds/updates a `<link>` element in the HTML document to load each theme variant's CSS, setting the
|
|
14
|
+
* non-current theme variants as "alternate" stylesheets. That is, the browser will download
|
|
15
|
+
* the CSS for the non-current theme variants, but at a lower priority than the current one.
|
|
16
|
+
* This ensures that if the theme variant is changed at runtime, the new theme's CSS will already be loaded.
|
|
17
|
+
*
|
|
18
|
+
* The hook also listens for changes in the system's preference and triggers the provided callback accordingly.
|
|
19
|
+
*
|
|
20
|
+
* @memberof module:React
|
|
21
|
+
* @param {object} args Configuration object for theme variants and related settings.
|
|
22
|
+
* @param {object} [args.themeVariants] An object containing the URLs for each supported theme variant,
|
|
23
|
+
* e.g.: `{ light: { url: 'https://path/to/light.css' } }`.
|
|
24
|
+
* @param {string} [args.currentThemeVariant] The currently applied theme variant, e.g.: `light`.
|
|
25
|
+
* @param {function} args.onComplete A callback function called when the theme variant(s) CSS is (are) complete.
|
|
26
|
+
* @param {function} [args.onDarkModeSystemPreferenceChange] A callback function that is triggered
|
|
27
|
+
* when the system's preference changes.
|
|
28
|
+
*/
|
|
29
|
+
var useParagonThemeVariants = function useParagonThemeVariants(_ref) {
|
|
30
|
+
var themeVariants = _ref.themeVariants,
|
|
31
|
+
currentThemeVariant = _ref.currentThemeVariant,
|
|
32
|
+
onComplete = _ref.onComplete,
|
|
33
|
+
onDarkModeSystemPreferenceChange = _ref.onDarkModeSystemPreferenceChange;
|
|
34
|
+
var _useState = useState(false),
|
|
35
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
36
|
+
isParagonThemeVariantComplete = _useState2[0],
|
|
37
|
+
setIsParagonThemeVariantComplete = _useState2[1];
|
|
38
|
+
var _useState3 = useState(false),
|
|
39
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
40
|
+
isBrandThemeVariantComplete = _useState4[0],
|
|
41
|
+
setIsBrandThemeVariantComplete = _useState4[1];
|
|
42
|
+
|
|
43
|
+
// Effect hook that listens for changes in the system's dark mode preference.
|
|
44
|
+
useEffect(function () {
|
|
45
|
+
var _window$matchMedia, _window;
|
|
46
|
+
var changeColorScheme = function changeColorScheme(colorSchemeQuery) {
|
|
47
|
+
onDarkModeSystemPreferenceChange(colorSchemeQuery.matches);
|
|
48
|
+
};
|
|
49
|
+
var colorSchemeQuery = (_window$matchMedia = (_window = window).matchMedia) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.call(_window, '(prefers-color-scheme: dark)');
|
|
50
|
+
if (colorSchemeQuery) {
|
|
51
|
+
colorSchemeQuery.addEventListener('change', changeColorScheme);
|
|
52
|
+
}
|
|
53
|
+
return function () {
|
|
54
|
+
if (colorSchemeQuery) {
|
|
55
|
+
colorSchemeQuery.removeEventListener('change', changeColorScheme);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}, [onDarkModeSystemPreferenceChange]);
|
|
59
|
+
|
|
60
|
+
// Effect hook to set the theme current variant on the HTML element.
|
|
61
|
+
useEffect(function () {
|
|
62
|
+
if (currentThemeVariant && themeVariants !== null && themeVariants !== void 0 && themeVariants[currentThemeVariant]) {
|
|
63
|
+
var htmlDataThemeVariantAttr = 'data-paragon-theme-variant';
|
|
64
|
+
document.querySelector('html').setAttribute(htmlDataThemeVariantAttr, currentThemeVariant);
|
|
65
|
+
return function () {
|
|
66
|
+
document.querySelector('html').removeAttribute(htmlDataThemeVariantAttr);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return function () {}; // Cleanup: no action needed when theme variant is not set
|
|
70
|
+
}, [themeVariants, currentThemeVariant]);
|
|
71
|
+
|
|
72
|
+
// Effect hook that calls `onComplete` when both paragon and brand theme variants are completed the processing.
|
|
73
|
+
useEffect(function () {
|
|
74
|
+
if (isParagonThemeVariantComplete && isBrandThemeVariantComplete) {
|
|
75
|
+
onComplete();
|
|
76
|
+
}
|
|
77
|
+
}, [isParagonThemeVariantComplete, isBrandThemeVariantComplete, onComplete]);
|
|
78
|
+
useEffect(function () {
|
|
79
|
+
if (!themeVariants) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Determines the value for the `rel` attribute for a given theme variant based
|
|
85
|
+
* on if its the currently applied variant.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} themeVariant The key representing a theme variant (e.g., `light`, `dark`).
|
|
88
|
+
* @returns {string} The value for the `rel` attribute, either 'stylesheet' or 'alternate stylesheet'.
|
|
89
|
+
*/
|
|
90
|
+
var generateStylesheetRelAttr = function generateStylesheetRelAttr(themeVariant) {
|
|
91
|
+
return currentThemeVariant === themeVariant ? 'stylesheet' : 'alternate stylesheet';
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Iterate over each theme variant URL and inject it into the HTML document, if it doesn't already exist.
|
|
95
|
+
Object.entries(themeVariants).forEach(function (_ref2) {
|
|
96
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
97
|
+
themeVariant = _ref3[0],
|
|
98
|
+
value = _ref3[1];
|
|
99
|
+
// If there is no config for the theme variant URL, set the theme variant to complete and continue.
|
|
100
|
+
if (!value.urls) {
|
|
101
|
+
setIsParagonThemeVariantComplete(true);
|
|
102
|
+
setIsBrandThemeVariantComplete(true);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
var getParagonThemeVariantLink = function getParagonThemeVariantLink() {
|
|
106
|
+
return document.head.querySelector("link[data-paragon-theme-variant='".concat(themeVariant, "']"));
|
|
107
|
+
};
|
|
108
|
+
var existingThemeVariantLink = document.head.querySelector("link[href='".concat(value.urls["default"], "']"));
|
|
109
|
+
var existingThemeVariantBrandLink = document.head.querySelector("link[href='".concat(value.urls.brandOverride, "']"));
|
|
110
|
+
var getExistingThemeVariantLinks = function getExistingThemeVariantLinks(isBrandOverride) {
|
|
111
|
+
var themeVariantLinkSelector = "link[data-".concat(isBrandOverride ? 'brand' : 'paragon', "-theme-variant='").concat(themeVariant, "']");
|
|
112
|
+
return document.head.querySelectorAll(themeVariantLinkSelector);
|
|
113
|
+
};
|
|
114
|
+
var _createThemeVariantLink = function createThemeVariantLink(url) {
|
|
115
|
+
var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
116
|
+
_ref4$isFallbackTheme = _ref4.isFallbackThemeUrl,
|
|
117
|
+
isFallbackThemeUrl = _ref4$isFallbackTheme === void 0 ? false : _ref4$isFallbackTheme,
|
|
118
|
+
_ref4$isBrandOverride = _ref4.isBrandOverride,
|
|
119
|
+
isBrandOverride = _ref4$isBrandOverride === void 0 ? false : _ref4$isBrandOverride;
|
|
120
|
+
var themeVariantLink = document.createElement('link');
|
|
121
|
+
themeVariantLink.href = url;
|
|
122
|
+
themeVariantLink.rel = generateStylesheetRelAttr(themeVariant);
|
|
123
|
+
if (isBrandOverride) {
|
|
124
|
+
themeVariantLink.dataset.brandThemeVariant = themeVariant;
|
|
125
|
+
} else {
|
|
126
|
+
themeVariantLink.dataset.paragonThemeVariant = themeVariant;
|
|
127
|
+
}
|
|
128
|
+
themeVariantLink.onload = function () {
|
|
129
|
+
if (themeVariant === currentThemeVariant) {
|
|
130
|
+
if (isBrandOverride) {
|
|
131
|
+
setIsBrandThemeVariantComplete(true);
|
|
132
|
+
} else {
|
|
133
|
+
setIsParagonThemeVariantComplete(true);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
themeVariantLink.onerror = function () {
|
|
138
|
+
var _PARAGON_THEME$parago, _PARAGON_THEME;
|
|
139
|
+
var paragonThemeAccessor = isBrandOverride ? 'brand' : 'paragon';
|
|
140
|
+
if (isFallbackThemeUrl) {
|
|
141
|
+
logError("Could not load theme variant (".concat(paragonThemeAccessor, " - ").concat(themeVariant, ") CSS from fallback URL. Aborting."));
|
|
142
|
+
if (isBrandOverride) {
|
|
143
|
+
setIsBrandThemeVariantComplete(true);
|
|
144
|
+
} else {
|
|
145
|
+
setIsParagonThemeVariantComplete(true);
|
|
146
|
+
}
|
|
147
|
+
var otherExistingLinks = getExistingThemeVariantLinks(isBrandOverride);
|
|
148
|
+
removeExistingLinks(otherExistingLinks);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
var variants = (_PARAGON_THEME$parago = (_PARAGON_THEME = PARAGON_THEME) === null || _PARAGON_THEME === void 0 || (_PARAGON_THEME = _PARAGON_THEME[paragonThemeAccessor]) === null || _PARAGON_THEME === void 0 || (_PARAGON_THEME = _PARAGON_THEME.themeUrls) === null || _PARAGON_THEME === void 0 ? void 0 : _PARAGON_THEME.variants) !== null && _PARAGON_THEME$parago !== void 0 ? _PARAGON_THEME$parago : {};
|
|
152
|
+
if (variants[themeVariant]) {
|
|
153
|
+
var themeVariantFallbackUrl = fallbackThemeUrl(variants[themeVariant].fileName);
|
|
154
|
+
logInfo("Failed to load theme variant (".concat(themeVariant, ") CSS from ").concat(isBrandOverride ? value.urls.brandOverride : value.urls["default"], ". Falling back to locally installed theme variant: ").concat(themeVariantFallbackUrl));
|
|
155
|
+
themeVariantLink = _createThemeVariantLink(themeVariantFallbackUrl, {
|
|
156
|
+
isFallbackThemeUrl: true,
|
|
157
|
+
isBrandOverride: isBrandOverride
|
|
158
|
+
});
|
|
159
|
+
var _otherExistingLinks = getExistingThemeVariantLinks(isBrandOverride);
|
|
160
|
+
removeExistingLinks(_otherExistingLinks);
|
|
161
|
+
var foundParagonThemeVariantLink = getParagonThemeVariantLink();
|
|
162
|
+
if (foundParagonThemeVariantLink) {
|
|
163
|
+
foundParagonThemeVariantLink.insertAdjacentElement('afterend', themeVariantLink);
|
|
164
|
+
} else {
|
|
165
|
+
document.head.insertAdjacentElement('afterbegin', themeVariantLink);
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
logError("Failed to load theme variant (".concat(themeVariant, ") CSS from ").concat(url, " and locally installed fallback URL is not available. Aborting."));
|
|
169
|
+
if (isBrandOverride) {
|
|
170
|
+
setIsBrandThemeVariantComplete(true);
|
|
171
|
+
} else {
|
|
172
|
+
setIsParagonThemeVariantComplete(true);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
return themeVariantLink;
|
|
177
|
+
};
|
|
178
|
+
var insertBrandThemeVariantLink = function insertBrandThemeVariantLink() {
|
|
179
|
+
var updatedStylesheetRel = generateStylesheetRelAttr(themeVariant);
|
|
180
|
+
if (existingThemeVariantBrandLink) {
|
|
181
|
+
existingThemeVariantBrandLink.rel = updatedStylesheetRel;
|
|
182
|
+
existingThemeVariantBrandLink.removeAttribute('as');
|
|
183
|
+
existingThemeVariantBrandLink.dataset.brandThemeVariant = themeVariant;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (value.urls.brandOverride) {
|
|
187
|
+
var brandThemeVariantLink = _createThemeVariantLink(value.urls.brandOverride, {
|
|
188
|
+
isBrandOverride: true
|
|
189
|
+
});
|
|
190
|
+
var foundParagonThemeVariantLink = getParagonThemeVariantLink();
|
|
191
|
+
if (foundParagonThemeVariantLink) {
|
|
192
|
+
foundParagonThemeVariantLink.insertAdjacentElement('afterend', brandThemeVariantLink);
|
|
193
|
+
} else {
|
|
194
|
+
document.head.insertAdjacentElement('afterbegin', brandThemeVariantLink);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
setIsBrandThemeVariantComplete(true);
|
|
198
|
+
};
|
|
199
|
+
if (!existingThemeVariantLink) {
|
|
200
|
+
var paragonThemeVariantLink = _createThemeVariantLink(value.urls["default"]);
|
|
201
|
+
document.head.insertAdjacentElement('afterbegin', paragonThemeVariantLink);
|
|
202
|
+
insertBrandThemeVariantLink(existingThemeVariantBrandLink);
|
|
203
|
+
} else {
|
|
204
|
+
var updatedStylesheetRel = generateStylesheetRelAttr(themeVariant);
|
|
205
|
+
existingThemeVariantLink.rel = updatedStylesheetRel;
|
|
206
|
+
existingThemeVariantLink.removeAttribute('as');
|
|
207
|
+
existingThemeVariantLink.dataset.paragonThemeVariant = themeVariant;
|
|
208
|
+
insertBrandThemeVariantLink(existingThemeVariantBrandLink);
|
|
209
|
+
}
|
|
210
|
+
setIsParagonThemeVariantComplete(true);
|
|
211
|
+
setIsBrandThemeVariantComplete(true);
|
|
212
|
+
});
|
|
213
|
+
}, [themeVariants, currentThemeVariant, onComplete]);
|
|
214
|
+
};
|
|
215
|
+
export default useParagonThemeVariants;
|
|
216
|
+
//# sourceMappingURL=useParagonThemeVariants.js.map
|