@okta/odyssey-react-mui 1.9.0 → 1.9.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okta/odyssey-react-mui",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "React MUI components for Odyssey, Okta's design system",
5
5
  "author": "Okta, Inc.",
6
6
  "license": "Apache-2.0",
@@ -51,7 +51,7 @@
51
51
  "@mui/system": "^5.14.9",
52
52
  "@mui/utils": "^5.11.2",
53
53
  "@mui/x-date-pickers": "^5.0.15",
54
- "@okta/odyssey-design-tokens": "1.9.0",
54
+ "@okta/odyssey-design-tokens": "1.9.2",
55
55
  "date-fns": "^2.30.0",
56
56
  "i18next": "^23.5.1",
57
57
  "material-react-table": "^2.0.2",
@@ -63,5 +63,5 @@
63
63
  "react": ">=17 <19",
64
64
  "react-dom": ">=17 <19"
65
65
  },
66
- "gitHead": "dbcfcc17285a611b6d6ea641429e1a42ba62e105"
66
+ "gitHead": "5b660570860d7641b0392d30a0c1d6254df3ddef"
67
67
  }
@@ -17,51 +17,44 @@ declare global {
17
17
  }
18
18
 
19
19
  import createCache, { StylisPlugin } from "@emotion/cache";
20
- import { CacheProvider } from "@emotion/react";
21
- import { memo, ReactNode, useMemo } from "react";
22
-
20
+ import { memo, useMemo, ReactNode } from "react";
23
21
  import { useUniqueAlphabeticalId } from "./useUniqueAlphabeticalId";
22
+ import { CacheProvider } from "@emotion/react";
24
23
 
25
24
  export type OdysseyCacheProviderProps = {
26
25
  children: ReactNode;
26
+ nonce?: string;
27
+ /**
28
+ * Emotion caches styles into the style element.
29
+ * When enabling this prop, Emotion caches the styles at this element, rather than in <head>.
30
+ */
31
+ emotionRoot?: HTMLStyleElement;
27
32
  /**
28
33
  * Emotion renders into this HTML element.
29
34
  * When enabling this prop, Emotion renders at the top of this component rather than the bottom like it does in the HTML `<head>`.
30
35
  */
31
- nonce?: string;
32
- shadowDomElement?: HTMLDivElement;
36
+ shadowDomElement?: HTMLDivElement | HTMLElement;
33
37
  stylisPlugins?: StylisPlugin[];
34
38
  };
35
39
 
36
40
  const OdysseyCacheProvider = ({
37
41
  children,
42
+ emotionRoot,
38
43
  nonce,
39
- shadowDomElement,
40
44
  stylisPlugins,
41
45
  }: OdysseyCacheProviderProps) => {
42
46
  const uniqueAlphabeticalId = useUniqueAlphabeticalId();
43
47
 
44
- const emotionRootElement = useMemo(() => {
45
- const emotionRootElement = document.createElement("div");
46
-
47
- emotionRootElement.setAttribute("data-emotion-root", "data-emotion-root");
48
-
49
- shadowDomElement?.prepend?.(emotionRootElement);
50
-
51
- return emotionRootElement;
52
- }, [shadowDomElement]);
53
-
54
- const emotionCache = useMemo(
55
- () =>
56
- createCache({
57
- container: emotionRootElement,
58
- key: uniqueAlphabeticalId,
59
- nonce: nonce || window.cspNonce,
60
- prepend: Boolean(emotionRootElement),
61
- stylisPlugins,
62
- }),
63
- [emotionRootElement, nonce, stylisPlugins, uniqueAlphabeticalId]
64
- );
48
+ const emotionCache = useMemo(() => {
49
+ return createCache({
50
+ ...(emotionRoot && { container: emotionRoot }),
51
+ key: uniqueAlphabeticalId,
52
+ nonce: nonce ?? window.cspNonce,
53
+ prepend: true,
54
+ speedy: false, // <-- Needs to be set to false when shadow-dom is used!! https://github.com/emotion-js/emotion/issues/2053#issuecomment-713429122
55
+ ...(stylisPlugins && { stylisPlugins }),
56
+ });
57
+ }, [emotionRoot, nonce, stylisPlugins, uniqueAlphabeticalId]);
65
58
 
66
59
  return <CacheProvider value={emotionCache}>{children}</CacheProvider>;
67
60
  };
@@ -35,6 +35,7 @@ export type OdysseyProviderProps = OdysseyCacheProviderProps &
35
35
  const OdysseyProvider = ({
36
36
  children,
37
37
  designTokensOverride,
38
+ emotionRoot,
38
39
  shadowDomElement,
39
40
  languageCode,
40
41
  nonce,
@@ -44,13 +45,16 @@ const OdysseyProvider = ({
44
45
  }: OdysseyProviderProps) => (
45
46
  <OdysseyCacheProvider
46
47
  nonce={nonce}
48
+ emotionRoot={emotionRoot}
47
49
  shadowDomElement={shadowDomElement}
48
50
  stylisPlugins={stylisPlugins}
49
51
  >
50
52
  <OdysseyThemeProvider
51
53
  designTokensOverride={designTokensOverride}
54
+ emotionRoot={emotionRoot}
52
55
  shadowDomElement={shadowDomElement}
53
56
  themeOverride={themeOverride}
57
+ withCache={false}
54
58
  >
55
59
  <ScopedCssBaseline>
56
60
  <OdysseyTranslationProvider
@@ -21,19 +21,26 @@ import { deepmerge } from "@mui/utils";
21
21
  import { createOdysseyMuiTheme, DesignTokensOverride } from "./theme";
22
22
  import * as Tokens from "@okta/odyssey-design-tokens";
23
23
  import { OdysseyDesignTokensContext } from "./OdysseyDesignTokensContext";
24
+ import { CacheProvider } from "@emotion/react";
25
+ import createCache from "@emotion/cache";
26
+ import { useUniqueAlphabeticalId } from "./useUniqueAlphabeticalId";
24
27
 
25
28
  export type OdysseyThemeProviderProps = {
26
29
  children: ReactNode;
27
30
  designTokensOverride?: DesignTokensOverride;
28
- shadowDomElement?: HTMLDivElement;
31
+ emotionRoot?: HTMLStyleElement;
32
+ shadowDomElement?: HTMLDivElement | HTMLElement | undefined;
29
33
  themeOverride?: ThemeOptions;
34
+ withCache?: boolean;
30
35
  };
31
36
 
32
37
  const OdysseyThemeProvider = ({
33
38
  children,
34
39
  designTokensOverride,
40
+ emotionRoot,
35
41
  shadowDomElement,
36
42
  themeOverride,
43
+ withCache = true,
37
44
  }: OdysseyThemeProviderProps) => {
38
45
  const odysseyTokens = useMemo(
39
46
  () => ({ ...Tokens, ...designTokensOverride }),
@@ -53,6 +60,31 @@ const OdysseyThemeProvider = ({
53
60
  [odysseyTheme, themeOverride]
54
61
  );
55
62
 
63
+ const uniqueAlphabeticalId = useUniqueAlphabeticalId();
64
+
65
+ const cache = useMemo(
66
+ () =>
67
+ createCache({
68
+ ...(emotionRoot && { container: emotionRoot }),
69
+ key: uniqueAlphabeticalId,
70
+ prepend: true,
71
+ nonce: window.cspNonce,
72
+ speedy: false, // <-- Needs to be set to false when shadow-dom is used!! https://github.com/emotion-js/emotion/issues/2053#issuecomment-713429122
73
+ }),
74
+ [emotionRoot, uniqueAlphabeticalId]
75
+ );
76
+
77
+ if (withCache) {
78
+ return (
79
+ <CacheProvider value={cache}>
80
+ <MuiThemeProvider theme={customOdysseyTheme ?? odysseyTheme}>
81
+ <OdysseyDesignTokensContext.Provider value={odysseyTokens}>
82
+ {children}
83
+ </OdysseyDesignTokensContext.Provider>
84
+ </MuiThemeProvider>
85
+ </CacheProvider>
86
+ );
87
+ }
56
88
  return (
57
89
  <MuiThemeProvider theme={customOdysseyTheme ?? odysseyTheme}>
58
90
  <OdysseyDesignTokensContext.Provider value={odysseyTokens}>
@@ -10,12 +10,22 @@
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- export const createShadowRootElement = (containerElement: HTMLElement) => {
13
+ export const createShadowRootElement = (
14
+ containerElement: HTMLElement
15
+ ): [HTMLStyleElement, HTMLDivElement] => {
14
16
  const shadowRoot = containerElement.attachShadow({ mode: "open" });
15
17
 
18
+ // the element that styles will be cached into
19
+ const emotionRoot = document.createElement("style");
20
+ emotionRoot.setAttribute("id", "style-root");
21
+ emotionRoot.setAttribute("nonce", window.cspNonce);
22
+
23
+ // the element that emotion renders html into
16
24
  const shadowRootElement = document.createElement("div");
25
+ shadowRootElement.setAttribute("id", "shadow-root");
17
26
 
18
- shadowRoot.append(shadowRootElement);
27
+ shadowRoot.appendChild(emotionRoot);
28
+ shadowRoot.appendChild(shadowRootElement);
19
29
 
20
- return shadowRoot;
30
+ return [emotionRoot, shadowRootElement];
21
31
  };
@@ -53,7 +53,7 @@ export const components = ({
53
53
  shadowDomElement,
54
54
  }: {
55
55
  odysseyTokens: DesignTokens;
56
- shadowDomElement?: HTMLDivElement;
56
+ shadowDomElement?: HTMLElement;
57
57
  }): ThemeOptions["components"] => {
58
58
  return {
59
59
  MuiAccordion: {
@@ -32,7 +32,7 @@ export const createOdysseyMuiTheme = ({
32
32
  shadowDomElement,
33
33
  }: {
34
34
  odysseyTokens: DesignTokens;
35
- shadowDomElement?: HTMLDivElement;
35
+ shadowDomElement?: HTMLElement;
36
36
  }) =>
37
37
  createTheme({
38
38
  components: components({