@okta/odyssey-react-mui 1.36.0 → 1.37.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 (83) hide show
  1. package/README.md +8 -3
  2. package/dist/cjs/Pagination/Pagination.cjs +1 -1
  3. package/dist/cjs/Pagination/Pagination.cjs.map +1 -1
  4. package/dist/cjs/Pagination/usePagination.cjs +3 -1
  5. package/dist/cjs/Pagination/usePagination.cjs.map +1 -1
  6. package/dist/cjs/labs/DataView/TableLayoutContent.cjs +3 -3
  7. package/dist/cjs/labs/DataView/TableLayoutContent.cjs.map +1 -1
  8. package/dist/cjs/labs/PageTemplate/DocumentationLink.cjs +41 -0
  9. package/dist/cjs/labs/PageTemplate/DocumentationLink.cjs.map +1 -0
  10. package/dist/cjs/labs/PageTemplate/PageTemplate.cjs +22 -8
  11. package/dist/cjs/labs/PageTemplate/PageTemplate.cjs.map +1 -1
  12. package/dist/cjs/properties/ts/odyssey-react-mui.cjs +1 -0
  13. package/dist/cjs/properties/ts/odyssey-react-mui.cjs.map +1 -1
  14. package/dist/cjs/ui-shell/InnerAppContainer.cjs +1 -0
  15. package/dist/cjs/ui-shell/InnerAppContainer.cjs.map +1 -1
  16. package/dist/cjs/ui-shell/NarrowUiShellContent.cjs +3 -3
  17. package/dist/cjs/ui-shell/NarrowUiShellContent.cjs.map +1 -1
  18. package/dist/cjs/ui-shell/SideNav/SideNav.cjs +67 -51
  19. package/dist/cjs/ui-shell/SideNav/SideNav.cjs.map +1 -1
  20. package/dist/cjs/ui-shell/SideNav/types.cjs.map +1 -1
  21. package/dist/cjs/ui-shell/WideUiShellContent.cjs +0 -1
  22. package/dist/cjs/ui-shell/WideUiShellContent.cjs.map +1 -1
  23. package/dist/cjs/ui-shell/renderUiShell.cjs +12 -0
  24. package/dist/cjs/ui-shell/renderUiShell.cjs.map +1 -1
  25. package/dist/cjs/web-component/odysseyWebComponentVersion.generated.cjs +19 -0
  26. package/dist/cjs/web-component/odysseyWebComponentVersion.generated.cjs.map +1 -0
  27. package/dist/cjs/web-component/renderReactInWebComponent.cjs +53 -19
  28. package/dist/cjs/web-component/renderReactInWebComponent.cjs.map +1 -1
  29. package/dist/esm/Pagination/Pagination.js +1 -1
  30. package/dist/esm/Pagination/Pagination.js.map +1 -1
  31. package/dist/esm/Pagination/usePagination.js +3 -1
  32. package/dist/esm/Pagination/usePagination.js.map +1 -1
  33. package/dist/esm/labs/DataView/TableLayoutContent.js +3 -3
  34. package/dist/esm/labs/DataView/TableLayoutContent.js.map +1 -1
  35. package/dist/esm/labs/PageTemplate/DocumentationLink.js +35 -0
  36. package/dist/esm/labs/PageTemplate/DocumentationLink.js.map +1 -0
  37. package/dist/esm/labs/PageTemplate/PageTemplate.js +22 -8
  38. package/dist/esm/labs/PageTemplate/PageTemplate.js.map +1 -1
  39. package/dist/esm/properties/ts/odyssey-react-mui.js +1 -0
  40. package/dist/esm/properties/ts/odyssey-react-mui.js.map +1 -1
  41. package/dist/esm/ui-shell/InnerAppContainer.js +1 -0
  42. package/dist/esm/ui-shell/InnerAppContainer.js.map +1 -1
  43. package/dist/esm/ui-shell/NarrowUiShellContent.js +3 -3
  44. package/dist/esm/ui-shell/NarrowUiShellContent.js.map +1 -1
  45. package/dist/esm/ui-shell/SideNav/SideNav.js +67 -51
  46. package/dist/esm/ui-shell/SideNav/SideNav.js.map +1 -1
  47. package/dist/esm/ui-shell/SideNav/types.js.map +1 -1
  48. package/dist/esm/ui-shell/WideUiShellContent.js +0 -1
  49. package/dist/esm/ui-shell/WideUiShellContent.js.map +1 -1
  50. package/dist/esm/ui-shell/renderUiShell.js +12 -0
  51. package/dist/esm/ui-shell/renderUiShell.js.map +1 -1
  52. package/dist/esm/web-component/odysseyWebComponentVersion.generated.js +12 -0
  53. package/dist/esm/web-component/odysseyWebComponentVersion.generated.js.map +1 -0
  54. package/dist/esm/web-component/renderReactInWebComponent.js +49 -17
  55. package/dist/esm/web-component/renderReactInWebComponent.js.map +1 -1
  56. package/dist/index.cjs +1 -1
  57. package/dist/index.mjs +1 -1
  58. package/dist/index.scss +1 -1
  59. package/dist/tsconfig.production.tsbuildinfo +1 -1
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/dist/types/OdysseyTranslationProvider.d.ts +1 -1
  62. package/dist/types/OdysseyTranslationProvider.d.ts.map +1 -1
  63. package/dist/types/Pagination/usePagination.d.ts.map +1 -1
  64. package/dist/types/i18n.d.ts +1 -0
  65. package/dist/types/i18n.d.ts.map +1 -1
  66. package/dist/types/labs/PageTemplate/DocumentationLink.d.ts +34 -0
  67. package/dist/types/labs/PageTemplate/DocumentationLink.d.ts.map +1 -0
  68. package/dist/types/labs/PageTemplate/PageTemplate.d.ts.map +1 -1
  69. package/dist/types/properties/ts/odyssey-react-mui.d.ts +1 -0
  70. package/dist/types/properties/ts/odyssey-react-mui.d.ts.map +1 -1
  71. package/dist/types/ui-shell/InnerAppContainer.d.ts.map +1 -1
  72. package/dist/types/ui-shell/NarrowUiShellContent.d.ts.map +1 -1
  73. package/dist/types/ui-shell/SideNav/SideNav.d.ts.map +1 -1
  74. package/dist/types/ui-shell/SideNav/types.d.ts +13 -4
  75. package/dist/types/ui-shell/SideNav/types.d.ts.map +1 -1
  76. package/dist/types/ui-shell/WideUiShellContent.d.ts.map +1 -1
  77. package/dist/types/ui-shell/renderUiShell.d.ts +20 -5
  78. package/dist/types/ui-shell/renderUiShell.d.ts.map +1 -1
  79. package/dist/types/web-component/odysseyWebComponentVersion.generated.d.ts +19 -0
  80. package/dist/types/web-component/odysseyWebComponentVersion.generated.d.ts.map +1 -0
  81. package/dist/types/web-component/renderReactInWebComponent.d.ts +29 -7
  82. package/dist/types/web-component/renderReactInWebComponent.d.ts.map +1 -1
  83. package/package.json +5 -4
@@ -10,29 +10,46 @@
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import version from "./odysseyWebComponentVersion.generated.js";
13
14
  import { createReactRootElements } from "./createReactRootElements.js";
14
- export const reactWebComponentElementName = "odyssey-react-web-component";
15
+ export const webComponentDataAttributeName = "data-odyssey-react-web-component";
16
+ export const versionedWebComponentName = `odyssey-react-web-component-${version}`.toLowerCase();
15
17
  const SsrFriendlyHtmlElementClass = "HTMLElement" in globalThis ? HTMLElement : class {};
16
- export class ReactInWebComponentElement extends SsrFriendlyHtmlElementClass {
18
+ export class WebComponentClass extends SsrFriendlyHtmlElementClass {
19
+ #getReactComponent = null;
20
+ #reactRootElements;
21
+ elementName = this.localName;
17
22
  reactRootPromise = Promise.resolve(null);
18
- constructor(getReactComponent) {
23
+ constructor() {
19
24
  super();
20
- this.getReactComponent = getReactComponent;
21
- this.reactRootElements = createReactRootElements();
22
- const styleElement = document.createElement("style");
25
+ this.#reactRootElements = createReactRootElements();
26
+ const {
27
+ appRootElement,
28
+ stylesRootElement
29
+ } = this.#reactRootElements;
23
30
  const shadowRoot = this.attachShadow({
24
31
  mode: "open"
25
32
  });
26
- styleElement.innerHTML = `
33
+ shadowRoot.appendChild(stylesRootElement);
34
+ shadowRoot.appendChild(appRootElement);
35
+ const styleHostElement = document.createElement("style");
36
+ styleHostElement.setAttribute("nonce", window.cspNonce);
37
+ styleHostElement.innerHTML = `
27
38
  :host {
28
39
  all: initial;
29
40
  contain: content;
30
41
  }
31
42
  `;
32
- styleElement.setAttribute("nonce", window.cspNonce);
33
- this.reactRootElements.stylesRootElement.appendChild(styleElement);
34
- shadowRoot.appendChild(this.reactRootElements.stylesRootElement);
35
- shadowRoot.appendChild(this.reactRootElements.appRootElement);
43
+ stylesRootElement.appendChild(styleHostElement);
44
+ }
45
+ setGetReactComponent(getReactComponent) {
46
+ this.reactRootPromise = this.reactRootPromise.then(reactRoot => {
47
+ this.#getReactComponent = getReactComponent;
48
+ if (reactRoot) {
49
+ reactRoot.render(this.#getReactComponent(this.#reactRootElements));
50
+ } else {}
51
+ return reactRoot;
52
+ });
36
53
  }
37
54
  connectedCallback() {
38
55
  this.reactRootPromise = this.reactRootPromise.then(reactRoot => {
@@ -41,9 +58,11 @@ export class ReactInWebComponentElement extends SsrFriendlyHtmlElementClass {
41
58
  }
42
59
  return import("react-dom/client").then(({
43
60
  createRoot
44
- }) => createRoot(this.reactRootElements.appRootElement));
61
+ }) => createRoot(this.#reactRootElements.appRootElement));
45
62
  }).then(reactRoot => {
46
- reactRoot.render(this.getReactComponent(this.reactRootElements));
63
+ if (!this.#getReactComponent) {} else {
64
+ reactRoot.render(this.#getReactComponent(this.#reactRootElements));
65
+ }
47
66
  return reactRoot;
48
67
  });
49
68
  }
@@ -57,16 +76,29 @@ export class ReactInWebComponentElement extends SsrFriendlyHtmlElementClass {
57
76
  });
58
77
  }
59
78
  }
60
- if ("customElements" in globalThis && !customElements.get(reactWebComponentElementName)) {
61
- customElements.define(reactWebComponentElementName, ReactInWebComponentElement);
62
- }
79
+ export const getReactWebComponent = ({
80
+ webComponentName = versionedWebComponentName,
81
+ getReactComponent
82
+ }) => {
83
+ if (!customElements.get(webComponentName)) {
84
+ customElements.define(webComponentName, WebComponentClass);
85
+ }
86
+ const element = document.createElement(webComponentName);
87
+ element.setAttribute(webComponentDataAttributeName, "");
88
+ element.setGetReactComponent(getReactComponent);
89
+ return element;
90
+ };
63
91
  export const renderReactInWebComponent = ({
92
+ webComponentName,
64
93
  getReactComponent,
65
94
  webComponentChildren,
66
95
  webComponentParentElement,
67
96
  webComponentRootElement
68
97
  }) => {
69
- const reactElement = new ReactInWebComponentElement(getReactComponent);
98
+ const reactElement = getReactWebComponent({
99
+ getReactComponent,
100
+ webComponentName
101
+ });
70
102
  if (webComponentChildren) {
71
103
  (Array.isArray(webComponentChildren) ? webComponentChildren : [webComponentChildren]).forEach(webComponentChild => {
72
104
  reactElement.appendChild(webComponentChild);
@@ -1 +1 @@
1
- {"version":3,"file":"renderReactInWebComponent.js","names":["createReactRootElements","reactWebComponentElementName","SsrFriendlyHtmlElementClass","globalThis","HTMLElement","ReactInWebComponentElement","reactRootPromise","Promise","resolve","constructor","getReactComponent","reactRootElements","styleElement","document","createElement","shadowRoot","attachShadow","mode","innerHTML","setAttribute","window","cspNonce","stylesRootElement","appendChild","appRootElement","connectedCallback","then","reactRoot","Error","createRoot","render","disconnectedCallback","unmount","customElements","get","define","renderReactInWebComponent","webComponentChildren","webComponentParentElement","webComponentRootElement","reactElement","Array","isArray","forEach","webComponentChild"],"sources":["../../../src/web-component/renderReactInWebComponent.ts"],"sourcesContent":["/*!\n * Copyright (c) 2024-present, Okta, Inc. and/or its affiliates. All rights reserved.\n * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the \"License.\")\n *\n * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *\n * See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport { type ReactNode } from \"react\";\nimport type { Root } from \"react-dom/client\";\n\nimport {\n createReactRootElements,\n type ReactRootElements,\n} from \"./createReactRootElements.js\";\n\nexport const reactWebComponentElementName = \"odyssey-react-web-component\";\n\nexport type GetReactComponentInWebComponent = (\n reactRootElements: ReactRootElements,\n) => ReactNode;\n\nconst SsrFriendlyHtmlElementClass =\n \"HTMLElement\" in globalThis\n ? HTMLElement\n : (class {} as unknown as typeof globalThis.HTMLElement);\n\nexport class ReactInWebComponentElement extends SsrFriendlyHtmlElementClass {\n getReactComponent: GetReactComponentInWebComponent;\n reactRootElements: ReactRootElements;\n reactRootPromise: Promise<Root | null> = Promise.resolve(null);\n\n constructor(getReactComponent: GetReactComponentInWebComponent) {\n super();\n\n this.getReactComponent = getReactComponent;\n this.reactRootElements = createReactRootElements();\n\n const styleElement = document.createElement(\"style\");\n const shadowRoot = this.attachShadow({ mode: \"open\" });\n\n styleElement.innerHTML = `\n :host {\n all: initial;\n contain: content;\n }\n `;\n\n styleElement.setAttribute(\"nonce\", window.cspNonce);\n\n this.reactRootElements.stylesRootElement.appendChild(styleElement);\n shadowRoot.appendChild(this.reactRootElements.stylesRootElement);\n shadowRoot.appendChild(this.reactRootElements.appRootElement);\n }\n\n connectedCallback() {\n this.reactRootPromise = this.reactRootPromise\n .then((reactRoot) => {\n if (reactRoot) {\n // Shouldn't ever happen\n throw new Error(\n `connectedCallback fired when reactRoot is already mounted.`,\n );\n }\n\n // Ensure react root is available before mounting\n // If we want to support React v17 in the future, we can use a try-catch on the import to grab the old `ReactDOM.render` function if `react-dom/client` errors. --Kevin Ghadyani\n return import(\"react-dom/client\").then(({ createRoot }) =>\n createRoot(this.reactRootElements.appRootElement),\n );\n })\n .then((reactRoot) => {\n reactRoot.render(this.getReactComponent(this.reactRootElements));\n return reactRoot;\n });\n }\n\n disconnectedCallback() {\n this.reactRootPromise = this.reactRootPromise.then((reactRoot) => {\n if (!reactRoot) {\n // Shouldn't ever happen\n throw new Error(\n `disconnectedCallback fired when reactRoot is already unmounted.`,\n );\n }\n\n reactRoot.unmount();\n // Set root to null. We don't want to attempt to render to a root that's already been unmounted.\n return null;\n });\n }\n}\n\nif (\n \"customElements\" in globalThis &&\n !customElements.get(reactWebComponentElementName)\n) {\n customElements.define(\n reactWebComponentElementName,\n ReactInWebComponentElement,\n );\n}\n\nexport type RenderReactInWebComponentProps = {\n /**\n * This is a callback function for rendering your React component or app in the Web Component.\n * It gives you access to the Shadow DOM elements if you need them for Odyssey, Emotion, or MUI.\n *\n * You will need to add `<slot>` elements if you want to pass child elements or components or React apps.\n * You can have multiple slots in your app if you add a `name` attribute to your `<slot>` elements.\n */\n getReactComponent: GetReactComponentInWebComponent;\n /**\n * One or more HTML elements that are going to render as `children` of the web component.\n * If your React component doesn't take children, this is unnecessary.\n *\n * Typically, a React app root element is passed, but it can include an array of other elements if there are multiple slots for children.\n *\n * You will need to have rendered `<slot>` elements in your React component or `children` won't show up.\n */\n webComponentChildren?: HTMLElement | HTMLElement[];\n} & (\n | {\n /**\n * The React app renders in the web component, but the web component needs to be rendered in the document.\n *\n * This is the element the web component is rendered into.\n */\n webComponentParentElement: HTMLElement;\n webComponentRootElement?: never;\n }\n | {\n webComponentParentElement?: HTMLElement;\n /**\n * @deprecated Use `webComponentParentElement` instead.\n */\n webComponentRootElement: HTMLElement;\n }\n);\n\n/**\n * Lets you render React apps or components in a Web Component.\n *\n * This is useful when global styles are causing conflicts with your React components.\n */\nexport const renderReactInWebComponent = ({\n getReactComponent,\n webComponentChildren,\n webComponentParentElement,\n webComponentRootElement,\n}: RenderReactInWebComponentProps) => {\n const reactElement = new ReactInWebComponentElement(getReactComponent);\n\n if (webComponentChildren) {\n (Array.isArray(webComponentChildren)\n ? webComponentChildren\n : [webComponentChildren]\n ).forEach((webComponentChild) => {\n reactElement.appendChild(webComponentChild);\n });\n }\n\n if (webComponentParentElement) {\n webComponentParentElement.appendChild(reactElement);\n }\n // Remove this condition when `webComponentRootElement` is no longer a prop.\n else if (webComponentRootElement) {\n webComponentRootElement.appendChild(reactElement);\n }\n\n return reactElement;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"renderReactInWebComponent.js","names":["version","createReactRootElements","webComponentDataAttributeName","versionedWebComponentName","toLowerCase","SsrFriendlyHtmlElementClass","globalThis","HTMLElement","WebComponentClass","getReactComponent","reactRootElements","elementName","localName","reactRootPromise","Promise","resolve","constructor","appRootElement","stylesRootElement","shadowRoot","attachShadow","mode","appendChild","styleHostElement","document","createElement","setAttribute","window","cspNonce","innerHTML","setGetReactComponent","then","reactRoot","render","connectedCallback","Error","createRoot","disconnectedCallback","unmount","getReactWebComponent","webComponentName","customElements","get","define","element","renderReactInWebComponent","webComponentChildren","webComponentParentElement","webComponentRootElement","reactElement","Array","isArray","forEach","webComponentChild"],"sources":["../../../src/web-component/renderReactInWebComponent.ts"],"sourcesContent":["/*!\n * Copyright (c) 2024-present, Okta, Inc. and/or its affiliates. All rights reserved.\n * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the \"License.\")\n *\n * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *\n * See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport { type ReactNode } from \"react\";\nimport type { Root } from \"react-dom/client\";\nimport version from \"./odysseyWebComponentVersion.generated.js\";\n\nimport {\n createReactRootElements,\n type ReactRootElements,\n} from \"./createReactRootElements.js\";\n\ninterface GetReactWebComponentOptions {\n webComponentName?: string;\n getReactComponent: (reactRootElements: ReactRootElements) => ReactNode;\n}\n\n// Used by selenium when selecting for odyssey web components regardless of their name.\nexport const webComponentDataAttributeName = \"data-odyssey-react-web-component\";\n\n// Unique name to avoid multiple versions of odyssey overwriting each other's implementations\nexport const versionedWebComponentName =\n `odyssey-react-web-component-${version}`.toLowerCase();\n\nconst SsrFriendlyHtmlElementClass =\n \"HTMLElement\" in globalThis\n ? HTMLElement\n : (class {} as unknown as typeof globalThis.HTMLElement);\n\nexport class WebComponentClass extends SsrFriendlyHtmlElementClass {\n #getReactComponent: GetReactComponentInWebComponent | null = null;\n readonly #reactRootElements: ReactRootElements;\n public readonly elementName: string = this.localName;\n // public for testing\n public reactRootPromise: Promise<Root | null> = Promise.resolve(null);\n\n constructor() {\n super();\n\n this.#reactRootElements = createReactRootElements();\n const { appRootElement, stylesRootElement } = this.#reactRootElements;\n\n const shadowRoot = this.attachShadow({ mode: \"open\" });\n shadowRoot.appendChild(stylesRootElement);\n shadowRoot.appendChild(appRootElement);\n\n const styleHostElement = document.createElement(\"style\");\n styleHostElement.setAttribute(\"nonce\", window.cspNonce);\n styleHostElement.innerHTML = `\n :host {\n all: initial;\n contain: content;\n }\n `;\n stylesRootElement.appendChild(styleHostElement);\n }\n\n /**\n * Provides the function used to initialize react content that is specific to this instance\n * of the web component, which is used later in the connectedCallback.\n *\n * Always set immediately after creation via document.createElement\n */\n setGetReactComponent(getReactComponent: GetReactComponentInWebComponent) {\n this.reactRootPromise = this.reactRootPromise.then((reactRoot) => {\n this.#getReactComponent = getReactComponent;\n if (reactRoot) {\n // connectedCallback has already been fired. Need to mount this content to the existing root\n reactRoot.render(this.#getReactComponent(this.#reactRootElements));\n } else {\n // Nothing to do. Content will be mounted when connectedCallback is called\n }\n\n return reactRoot;\n });\n }\n\n connectedCallback() {\n this.reactRootPromise = this.reactRootPromise\n .then((reactRoot) => {\n if (reactRoot) {\n // Shouldn't ever happen. connected and disconnected should never be called out of order\n throw new Error(\n `connectedCallback fired when reactRoot is already mounted.`,\n );\n }\n\n // Ensure react root is available before mounting\n // If we want to support React v17 in the future, we can use a try-catch on the import to grab the old `ReactDOM.render` function if `react-dom/client` errors. --Kevin Ghadyani\n return import(\"react-dom/client\").then(({ createRoot }) =>\n createRoot(this.#reactRootElements.appRootElement),\n );\n })\n .then((reactRoot) => {\n if (!this.#getReactComponent) {\n // getReactComponent hasn't been set yet. Content will be mounted once it's set.\n } else {\n reactRoot.render(this.#getReactComponent(this.#reactRootElements));\n }\n return reactRoot;\n });\n }\n\n disconnectedCallback() {\n this.reactRootPromise = this.reactRootPromise.then((reactRoot) => {\n if (!reactRoot) {\n // Shouldn't ever happen\n throw new Error(\n `disconnectedCallback fired when reactRoot is already unmounted.`,\n );\n }\n\n reactRoot.unmount();\n // Set root to null. We don't want to attempt to render to a root that's already been unmounted.\n return null;\n });\n }\n}\n\n/**\n * Returns a constructed web component which manages it's own shadow dom and react dom roots\n * A custom name can be specified, otherwise a default is provided\n */\nexport const getReactWebComponent = ({\n webComponentName = versionedWebComponentName,\n getReactComponent,\n}: GetReactWebComponentOptions) => {\n // This name hasn't been defined yet. Add a definition for it before constructing one.\n if (!customElements.get(webComponentName)) {\n customElements.define(webComponentName, WebComponentClass);\n }\n\n const element = document.createElement(webComponentName) as InstanceType<\n typeof WebComponentClass\n >;\n // Set selenium attribute so this can be selected\n element.setAttribute(webComponentDataAttributeName, \"\");\n // function used for creating react content\n element.setGetReactComponent(getReactComponent);\n return element;\n};\n\nexport type GetReactComponentInWebComponent = (\n reactRootElements: ReactRootElements,\n) => ReactNode;\n\nexport type RenderReactInWebComponentProps = {\n /**\n * Optional name given to this web component.\n * Defaults to a 'odyssey-react-wc-' plus the current odyssey version\n */\n webComponentName?: string;\n /**\n * This is a callback function for rendering your React component or app in the Web Component.\n * It gives you access to the Shadow DOM elements if you need them for Odyssey, Emotion, or MUI.\n *\n * You will need to add `<slot>` elements if you want to pass child elements or components or React apps.\n * You can have multiple slots in your app if you add a `name` attribute to your `<slot>` elements.\n */\n getReactComponent: GetReactComponentInWebComponent;\n /**\n * One or more HTML elements that are going to render as `children` of the web component.\n * If your React component doesn't take children, this is unnecessary.\n *\n * Typically, a React app root element is passed, but it can include an array of other elements if there are multiple slots for children.\n *\n * You will need to have rendered `<slot>` elements in your React component or `children` won't show up.\n */\n webComponentChildren?: HTMLElement | HTMLElement[];\n} & (\n | {\n /**\n * The React app renders in the web component, but the web component needs to be rendered in the document.\n *\n * This is the element the web component is rendered into.\n */\n webComponentParentElement: HTMLElement;\n webComponentRootElement?: never;\n }\n | {\n webComponentParentElement?: HTMLElement;\n /**\n * @deprecated Use `webComponentParentElement` instead.\n */\n webComponentRootElement: HTMLElement;\n }\n);\n\n/**\n * Lets you render React apps or components in a Web Component.\n *\n * This is useful when global styles are causing conflicts with your React components.\n */\nexport const renderReactInWebComponent = ({\n webComponentName,\n getReactComponent,\n webComponentChildren,\n webComponentParentElement,\n webComponentRootElement,\n}: RenderReactInWebComponentProps) => {\n const reactElement = getReactWebComponent({\n getReactComponent,\n webComponentName,\n });\n\n if (webComponentChildren) {\n (Array.isArray(webComponentChildren)\n ? webComponentChildren\n : [webComponentChildren]\n ).forEach((webComponentChild) => {\n reactElement.appendChild(webComponentChild);\n });\n }\n\n if (webComponentParentElement) {\n webComponentParentElement.appendChild(reactElement);\n }\n // Remove this condition when `webComponentRootElement` is no longer a prop.\n else if (webComponentRootElement) {\n webComponentRootElement.appendChild(reactElement);\n }\n\n return reactElement;\n};\n"],"mappings":"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","ignoreList":[]}
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 24 Apr 2025 19:05:52 GMT
3
+ * Generated on Thu, 15 May 2025 19:38:54 GMT
4
4
  */
5
5
 
6
6
  module.exports = {
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 24 Apr 2025 19:05:52 GMT
3
+ * Generated on Thu, 15 May 2025 19:38:54 GMT
4
4
  */
5
5
 
6
6
  export const BorderColorControl = "#8d8d8d";
package/dist/index.scss CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  * Do not edit directly
4
- * Generated on Thu, 24 Apr 2025 19:05:52 GMT
4
+ * Generated on Thu, 15 May 2025 19:38:54 GMT
5
5
  */
6
6
 
7
7
  $border-color-control: #8d8d8d !default;