@okta/odyssey-react-mui 1.27.0 → 1.28.1

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 (221) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/{Button.js → Buttons/BaseButton.js} +11 -10
  3. package/dist/Buttons/BaseButton.js.map +1 -0
  4. package/dist/{MenuButton.js → Buttons/BaseMenuButton.js} +30 -10
  5. package/dist/Buttons/BaseMenuButton.js.map +1 -0
  6. package/dist/Buttons/Button.js +24 -0
  7. package/dist/Buttons/Button.js.map +1 -0
  8. package/dist/Buttons/ButtonContext.js.map +1 -0
  9. package/dist/Buttons/MenuButton.js +25 -0
  10. package/dist/Buttons/MenuButton.js.map +1 -0
  11. package/dist/Buttons/MenuContext.js.map +1 -0
  12. package/dist/Buttons/MenuItem.js.map +1 -0
  13. package/dist/Buttons/index.js +18 -0
  14. package/dist/Buttons/index.js.map +1 -0
  15. package/dist/Card.js +1 -2
  16. package/dist/Card.js.map +1 -1
  17. package/dist/DataTable/DataTable.js +1 -2
  18. package/dist/DataTable/DataTable.js.map +1 -1
  19. package/dist/DataTable/DataTableRowActions.js +1 -2
  20. package/dist/DataTable/DataTableRowActions.js.map +1 -1
  21. package/dist/DataTable/DataTableSettings.js +1 -2
  22. package/dist/DataTable/DataTableSettings.js.map +1 -1
  23. package/dist/Dialog.js +1 -1
  24. package/dist/Dialog.js.map +1 -1
  25. package/dist/Drawer.js +1 -1
  26. package/dist/Drawer.js.map +1 -1
  27. package/dist/FileUploader/FileUploader.js +1 -1
  28. package/dist/FileUploader/FileUploader.js.map +1 -1
  29. package/dist/Form.js.map +1 -1
  30. package/dist/Pagination/Pagination.js +1 -1
  31. package/dist/Pagination/Pagination.js.map +1 -1
  32. package/dist/Toast.js +1 -1
  33. package/dist/Toast.js.map +1 -1
  34. package/dist/index.js +1 -3
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.scss +1 -1
  37. package/dist/labs/AppSwitcher/AppSwitcher.js +76 -0
  38. package/dist/labs/AppSwitcher/AppSwitcher.js.map +1 -0
  39. package/dist/labs/AppSwitcher/AppSwitcherApp.js +112 -0
  40. package/dist/labs/AppSwitcher/AppSwitcherApp.js.map +1 -0
  41. package/dist/labs/{SideNav → AppSwitcher}/OktaAura.js +16 -3
  42. package/dist/labs/AppSwitcher/OktaAura.js.map +1 -0
  43. package/dist/labs/AppSwitcher/index.js +13 -0
  44. package/dist/labs/AppSwitcher/index.js.map +1 -0
  45. package/dist/labs/AppTile.js +102 -65
  46. package/dist/labs/AppTile.js.map +1 -1
  47. package/dist/labs/DataFilters.js +1 -1
  48. package/dist/labs/DataFilters.js.map +1 -1
  49. package/dist/labs/DataTable.js.map +1 -1
  50. package/dist/labs/DataTablePagination.js +1 -1
  51. package/dist/labs/DataTablePagination.js.map +1 -1
  52. package/dist/labs/DataView/BulkActionsMenu.js +1 -2
  53. package/dist/labs/DataView/BulkActionsMenu.js.map +1 -1
  54. package/dist/labs/DataView/DataCard.js +53 -42
  55. package/dist/labs/DataView/DataCard.js.map +1 -1
  56. package/dist/labs/DataView/DataView.js +1 -1
  57. package/dist/labs/DataView/DataView.js.map +1 -1
  58. package/dist/labs/DataView/LayoutSwitcher.js +1 -2
  59. package/dist/labs/DataView/LayoutSwitcher.js.map +1 -1
  60. package/dist/labs/DataView/RowActions.js +1 -1
  61. package/dist/labs/DataView/RowActions.js.map +1 -1
  62. package/dist/labs/DataView/TableLayoutContent.js +1 -2
  63. package/dist/labs/DataView/TableLayoutContent.js.map +1 -1
  64. package/dist/labs/DataView/TableSettings.js +1 -2
  65. package/dist/labs/DataView/TableSettings.js.map +1 -1
  66. package/dist/labs/DatePicker.js +1 -1
  67. package/dist/labs/DatePicker.js.map +1 -1
  68. package/dist/labs/SideNav/SideNav.js +5 -4
  69. package/dist/labs/SideNav/SideNav.js.map +1 -1
  70. package/dist/labs/TopNav/UserProfile.js +16 -3
  71. package/dist/labs/TopNav/UserProfile.js.map +1 -1
  72. package/dist/labs/TopNav/UserProfileMenuButton.js +41 -0
  73. package/dist/labs/TopNav/UserProfileMenuButton.js.map +1 -0
  74. package/dist/labs/TopNav/index.js +1 -0
  75. package/dist/labs/TopNav/index.js.map +1 -1
  76. package/dist/labs/UiShell/UiShell.js +6 -5
  77. package/dist/labs/UiShell/UiShell.js.map +1 -1
  78. package/dist/labs/UiShell/UiShellContent.js +53 -13
  79. package/dist/labs/UiShell/UiShellContent.js.map +1 -1
  80. package/dist/labs/UiShell/renderUiShell.js +4 -0
  81. package/dist/labs/UiShell/renderUiShell.js.map +1 -1
  82. package/dist/labs/index.js +1 -0
  83. package/dist/labs/index.js.map +1 -1
  84. package/dist/src/{Button.d.ts → Buttons/BaseButton.d.ts} +12 -34
  85. package/dist/src/Buttons/BaseButton.d.ts.map +1 -0
  86. package/dist/src/{MenuButton.d.ts → Buttons/BaseMenuButton.d.ts} +37 -14
  87. package/dist/src/Buttons/BaseMenuButton.d.ts.map +1 -0
  88. package/dist/src/Buttons/Button.d.ts +16 -0
  89. package/dist/src/Buttons/Button.d.ts.map +1 -0
  90. package/dist/src/Buttons/ButtonContext.d.ts.map +1 -0
  91. package/dist/src/Buttons/MenuButton.d.ts +17 -0
  92. package/dist/src/Buttons/MenuButton.d.ts.map +1 -0
  93. package/dist/src/Buttons/MenuContext.d.ts.map +1 -0
  94. package/dist/src/{MenuItem.d.ts → Buttons/MenuItem.d.ts} +1 -1
  95. package/dist/src/Buttons/MenuItem.d.ts.map +1 -0
  96. package/dist/src/Buttons/index.d.ts +18 -0
  97. package/dist/src/Buttons/index.d.ts.map +1 -0
  98. package/dist/src/Card.d.ts +1 -2
  99. package/dist/src/Card.d.ts.map +1 -1
  100. package/dist/src/DataTable/DataTable.d.ts +1 -1
  101. package/dist/src/DataTable/DataTable.d.ts.map +1 -1
  102. package/dist/src/DataTable/DataTableRowActions.d.ts +1 -2
  103. package/dist/src/DataTable/DataTableRowActions.d.ts.map +1 -1
  104. package/dist/src/DataTable/DataTableSettings.d.ts.map +1 -1
  105. package/dist/src/Dialog.d.ts +1 -1
  106. package/dist/src/Dialog.d.ts.map +1 -1
  107. package/dist/src/Drawer.d.ts +1 -1
  108. package/dist/src/Drawer.d.ts.map +1 -1
  109. package/dist/src/Form.d.ts +1 -1
  110. package/dist/src/Form.d.ts.map +1 -1
  111. package/dist/src/index.d.ts +1 -3
  112. package/dist/src/index.d.ts.map +1 -1
  113. package/dist/src/labs/AppSwitcher/AppSwitcher.d.ts +20 -0
  114. package/dist/src/labs/AppSwitcher/AppSwitcher.d.ts.map +1 -0
  115. package/dist/src/labs/AppSwitcher/AppSwitcherApp.d.ts +24 -0
  116. package/dist/src/labs/AppSwitcher/AppSwitcherApp.d.ts.map +1 -0
  117. package/dist/src/labs/AppSwitcher/OktaAura.d.ts.map +1 -0
  118. package/dist/src/labs/AppSwitcher/index.d.ts +13 -0
  119. package/dist/src/labs/AppSwitcher/index.d.ts.map +1 -0
  120. package/dist/src/labs/AppTile.d.ts +6 -4
  121. package/dist/src/labs/AppTile.d.ts.map +1 -1
  122. package/dist/src/labs/DataTable.d.ts +1 -1
  123. package/dist/src/labs/DataTable.d.ts.map +1 -1
  124. package/dist/src/labs/DataView/BulkActionsMenu.d.ts.map +1 -1
  125. package/dist/src/labs/DataView/DataCard.d.ts +1 -2
  126. package/dist/src/labs/DataView/DataCard.d.ts.map +1 -1
  127. package/dist/src/labs/DataView/LayoutSwitcher.d.ts.map +1 -1
  128. package/dist/src/labs/DataView/RowActions.d.ts +1 -2
  129. package/dist/src/labs/DataView/RowActions.d.ts.map +1 -1
  130. package/dist/src/labs/DataView/TableLayoutContent.d.ts.map +1 -1
  131. package/dist/src/labs/DataView/TableSettings.d.ts.map +1 -1
  132. package/dist/src/labs/SideNav/SideNav.d.ts.map +1 -1
  133. package/dist/src/labs/TopNav/UserProfile.d.ts +5 -1
  134. package/dist/src/labs/TopNav/UserProfile.d.ts.map +1 -1
  135. package/dist/src/labs/TopNav/UserProfileMenuButton.d.ts +17 -0
  136. package/dist/src/labs/TopNav/UserProfileMenuButton.d.ts.map +1 -0
  137. package/dist/src/labs/TopNav/index.d.ts +1 -0
  138. package/dist/src/labs/TopNav/index.d.ts.map +1 -1
  139. package/dist/src/labs/UiShell/UiShell.d.ts +2 -2
  140. package/dist/src/labs/UiShell/UiShell.d.ts.map +1 -1
  141. package/dist/src/labs/UiShell/UiShellContent.d.ts +19 -2
  142. package/dist/src/labs/UiShell/UiShellContent.d.ts.map +1 -1
  143. package/dist/src/labs/UiShell/renderUiShell.d.ts +2 -2
  144. package/dist/src/labs/UiShell/renderUiShell.d.ts.map +1 -1
  145. package/dist/src/labs/index.d.ts +1 -0
  146. package/dist/src/labs/index.d.ts.map +1 -1
  147. package/dist/src/theme/components.d.ts.map +1 -1
  148. package/dist/src/web-component/renderReactInWebComponent.d.ts +2 -2
  149. package/dist/src/web-component/renderReactInWebComponent.d.ts.map +1 -1
  150. package/dist/theme/components.js +25 -27
  151. package/dist/theme/components.js.map +1 -1
  152. package/dist/tsconfig.production.tsbuildinfo +1 -1
  153. package/dist/web-component/renderReactInWebComponent.js +6 -7
  154. package/dist/web-component/renderReactInWebComponent.js.map +1 -1
  155. package/package.json +3 -3
  156. package/src/{Button.tsx → Buttons/BaseButton.tsx} +48 -68
  157. package/src/{MenuButton.tsx → Buttons/BaseMenuButton.tsx} +94 -32
  158. package/src/Buttons/Button.tsx +30 -0
  159. package/src/Buttons/MenuButton.tsx +35 -0
  160. package/src/{MenuItem.tsx → Buttons/MenuItem.tsx} +1 -1
  161. package/src/Buttons/index.ts +22 -0
  162. package/src/Card.tsx +1 -3
  163. package/src/DataTable/DataTable.tsx +1 -2
  164. package/src/DataTable/DataTableRowActions.tsx +1 -3
  165. package/src/DataTable/DataTableSettings.tsx +1 -2
  166. package/src/Dialog.tsx +1 -1
  167. package/src/Drawer.tsx +1 -1
  168. package/src/FileUploader/FileUploader.tsx +1 -1
  169. package/src/Form.tsx +1 -1
  170. package/src/Pagination/Pagination.test.tsx +58 -36
  171. package/src/Pagination/Pagination.tsx +1 -1
  172. package/src/Toast.tsx +1 -1
  173. package/src/index.ts +1 -3
  174. package/src/labs/AppSwitcher/AppSwitcher.tsx +94 -0
  175. package/src/labs/AppSwitcher/AppSwitcherApp.tsx +146 -0
  176. package/src/labs/{SideNav → AppSwitcher}/OktaAura.tsx +19 -4
  177. package/src/labs/AppSwitcher/index.ts +13 -0
  178. package/src/labs/AppTile.tsx +171 -85
  179. package/src/labs/DataFilters.tsx +1 -1
  180. package/src/labs/DataTable.tsx +1 -1
  181. package/src/labs/DataTablePagination.tsx +1 -1
  182. package/src/labs/DataView/BulkActionsMenu.tsx +1 -2
  183. package/src/labs/DataView/DataCard.tsx +56 -31
  184. package/src/labs/DataView/DataView.tsx +1 -1
  185. package/src/labs/DataView/LayoutSwitcher.tsx +1 -2
  186. package/src/labs/DataView/RowActions.tsx +1 -3
  187. package/src/labs/DataView/TableLayoutContent.tsx +1 -2
  188. package/src/labs/DataView/TableSettings.tsx +1 -2
  189. package/src/labs/DatePicker.tsx +1 -1
  190. package/src/labs/SideNav/SideNav.tsx +10 -4
  191. package/src/labs/TopNav/UserProfile.tsx +26 -2
  192. package/src/labs/TopNav/UserProfileMenuButton.tsx +57 -0
  193. package/src/labs/TopNav/index.ts +1 -0
  194. package/src/labs/UiShell/UiShell.test.tsx +23 -38
  195. package/src/labs/UiShell/UiShell.tsx +14 -6
  196. package/src/labs/UiShell/UiShellContent.tsx +85 -16
  197. package/src/labs/UiShell/renderUiShell.test.tsx +21 -15
  198. package/src/labs/UiShell/renderUiShell.tsx +8 -1
  199. package/src/labs/index.ts +1 -0
  200. package/src/theme/components.tsx +25 -28
  201. package/src/web-component/renderReactInWebComponent.ts +10 -5
  202. package/dist/Button.js.map +0 -1
  203. package/dist/ButtonContext.js.map +0 -1
  204. package/dist/MenuButton.js.map +0 -1
  205. package/dist/MenuContext.js.map +0 -1
  206. package/dist/MenuItem.js.map +0 -1
  207. package/dist/labs/SideNav/OktaAura.js.map +0 -1
  208. package/dist/src/Button.d.ts.map +0 -1
  209. package/dist/src/ButtonContext.d.ts.map +0 -1
  210. package/dist/src/MenuButton.d.ts.map +0 -1
  211. package/dist/src/MenuContext.d.ts.map +0 -1
  212. package/dist/src/MenuItem.d.ts.map +0 -1
  213. package/dist/src/labs/SideNav/OktaAura.d.ts.map +0 -1
  214. /package/dist/{ButtonContext.js → Buttons/ButtonContext.js} +0 -0
  215. /package/dist/{MenuContext.js → Buttons/MenuContext.js} +0 -0
  216. /package/dist/{MenuItem.js → Buttons/MenuItem.js} +0 -0
  217. /package/dist/src/{ButtonContext.d.ts → Buttons/ButtonContext.d.ts} +0 -0
  218. /package/dist/src/{MenuContext.d.ts → Buttons/MenuContext.d.ts} +0 -0
  219. /package/dist/src/labs/{SideNav → AppSwitcher}/OktaAura.d.ts +0 -0
  220. /package/src/{ButtonContext.tsx → Buttons/ButtonContext.tsx} +0 -0
  221. /package/src/{MenuContext.ts → Buttons/MenuContext.ts} +0 -0
@@ -8,10 +8,7 @@
8
8
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
9
  *
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
- */
12
-
13
- import { createRoot } from "react-dom/client";
14
- export const createReactRootElements = () => {
11
+ */export const createReactRootElements = () => {
15
12
  const appRootElement = document.createElement("div");
16
13
  const stylesRootElement = document.createElement("div");
17
14
  appRootElement.style.setProperty("height", "inherit");
@@ -43,13 +40,15 @@ export class ReactInWebComponentElement extends HTMLElement {
43
40
  this.reactRootElements.stylesRootElement.appendChild(styleElement);
44
41
  shadowRoot.appendChild(this.reactRootElements.stylesRootElement);
45
42
  shadowRoot.appendChild(this.reactRootElements.appRootElement);
46
- this.reactRoot = createRoot(this.reactRootElements.appRootElement);
43
+ this.reactRootPromise = import("react-dom/client").then(({
44
+ createRoot
45
+ }) => createRoot(this.reactRootElements.appRootElement));
47
46
  }
48
47
  connectedCallback() {
49
- this.reactRoot.render(this.getReactComponent(this.reactRootElements));
48
+ this.reactRootPromise.then(reactRoot => reactRoot.render(this.getReactComponent(this.reactRootElements)));
50
49
  }
51
50
  disconnectedCallback() {
52
- this.reactRoot.unmount();
51
+ this.reactRootPromise.then(reactRoot => reactRoot.unmount());
53
52
  }
54
53
  }
55
54
  if (!customElements.get(reactWebComponentElementName)) {
@@ -1 +1 @@
1
- {"version":3,"file":"renderReactInWebComponent.js","names":["createRoot","createReactRootElements","appRootElement","document","createElement","stylesRootElement","style","setProperty","setAttribute","window","cspNonce","reactWebComponentElementName","ReactInWebComponentElement","HTMLElement","constructor","getReactComponent","reactRootElements","styleElement","shadowRoot","attachShadow","mode","innerHTML","appendChild","reactRoot","connectedCallback","render","disconnectedCallback","unmount","customElements","get","define","renderReactInWebComponent","webComponentChildren","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 { createRoot, type Root } from \"react-dom/client\";\n\n/**\n * Creates elements for a Shadow DOM that Odyssey will render into.\n * The Emotion root is for `<style>` tags and the app root is for an app to render into.\n * These are bare elements that\n */\nexport const createReactRootElements = () => {\n const appRootElement = document.createElement(\"div\");\n const stylesRootElement = document.createElement(\"div\");\n\n // This `div` may cause layout issues unless it inherits the parent's height.\n appRootElement.style.setProperty(\"height\", \"inherit\");\n\n appRootElement.setAttribute(\"id\", \"app-root\");\n stylesRootElement.setAttribute(\"id\", \"style-root\");\n stylesRootElement.setAttribute(\"nonce\", window.cspNonce);\n\n return {\n /**\n * The element your React root component renders into.\n * React has to render or portal somewhere, and this element can be used for that root element.\n *\n * In the case of a web component, there is no defined root element, so you have to define it yourself.\n */\n appRootElement,\n /**\n * In React apps, your styles typically go in `document.head`, but you may want to render them somewhere else.\n *\n * Specifically when rendering in a web component, there is no `<head>`, so you have to create a spot for styles to render.\n */\n stylesRootElement,\n };\n};\n\nexport type ReactRootElements = ReturnType<typeof createReactRootElements>;\n\nexport const reactWebComponentElementName = \"odyssey-react-web-component\";\n\nexport type GetReactComponentInWebComponent = (\n reactRootElements: ReactRootElements,\n) => ReactNode;\n\nexport class ReactInWebComponentElement extends HTMLElement {\n getReactComponent: GetReactComponentInWebComponent;\n reactRoot: Root;\n reactRootElements: ReactRootElements;\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 this.reactRoot = createRoot(this.reactRootElements.appRootElement);\n }\n\n connectedCallback() {\n this.reactRoot.render(this.getReactComponent(this.reactRootElements));\n }\n\n disconnectedCallback() {\n this.reactRoot.unmount();\n }\n}\n\nif (!customElements.get(reactWebComponentElementName)) {\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 * You 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 webComponentRootElement: HTMLElement;\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 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 webComponentRootElement.appendChild(reactElement);\n\n return reactElement;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,UAAU,QAAmB,kBAAkB;AAOxD,OAAO,MAAMC,uBAAuB,GAAGA,CAAA,KAAM;EAC3C,MAAMC,cAAc,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;EACpD,MAAMC,iBAAiB,GAAGF,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;EAGvDF,cAAc,CAACI,KAAK,CAACC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC;EAErDL,cAAc,CAACM,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC;EAC7CH,iBAAiB,CAACG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC;EAClDH,iBAAiB,CAACG,YAAY,CAAC,OAAO,EAAEC,MAAM,CAACC,QAAQ,CAAC;EAExD,OAAO;IAOLR,cAAc;IAMdG;EACF,CAAC;AACH,CAAC;AAID,OAAO,MAAMM,4BAA4B,GAAG,6BAA6B;AAMzE,OAAO,MAAMC,0BAA0B,SAASC,WAAW,CAAC;EAK1DC,WAAWA,CAACC,iBAAkD,EAAE;IAC9D,KAAK,CAAC,CAAC;IAEP,IAAI,CAACA,iBAAiB,GAAGA,iBAAiB;IAC1C,IAAI,CAACC,iBAAiB,GAAGf,uBAAuB,CAAC,CAAC;IAElD,MAAMgB,YAAY,GAAGd,QAAQ,CAACC,aAAa,CAAC,OAAO,CAAC;IACpD,MAAMc,UAAU,GAAG,IAAI,CAACC,YAAY,CAAC;MAAEC,IAAI,EAAE;IAAO,CAAC,CAAC;IAEtDH,YAAY,CAACI,SAAS,GAAI;AAC9B;AACA;AACA;AACA;AACA,KAAK;IAEDJ,YAAY,CAACT,YAAY,CAAC,OAAO,EAAEC,MAAM,CAACC,QAAQ,CAAC;IAEnD,IAAI,CAACM,iBAAiB,CAACX,iBAAiB,CAACiB,WAAW,CAACL,YAAY,CAAC;IAClEC,UAAU,CAACI,WAAW,CAAC,IAAI,CAACN,iBAAiB,CAACX,iBAAiB,CAAC;IAChEa,UAAU,CAACI,WAAW,CAAC,IAAI,CAACN,iBAAiB,CAACd,cAAc,CAAC;IAE7D,IAAI,CAACqB,SAAS,GAAGvB,UAAU,CAAC,IAAI,CAACgB,iBAAiB,CAACd,cAAc,CAAC;EACpE;EAEAsB,iBAAiBA,CAAA,EAAG;IAClB,IAAI,CAACD,SAAS,CAACE,MAAM,CAAC,IAAI,CAACV,iBAAiB,CAAC,IAAI,CAACC,iBAAiB,CAAC,CAAC;EACvE;EAEAU,oBAAoBA,CAAA,EAAG;IACrB,IAAI,CAACH,SAAS,CAACI,OAAO,CAAC,CAAC;EAC1B;AACF;AAEA,IAAI,CAACC,cAAc,CAACC,GAAG,CAAClB,4BAA4B,CAAC,EAAE;EACrDiB,cAAc,CAACE,MAAM,CACnBnB,4BAA4B,EAC5BC,0BACF,CAAC;AACH;AAiCA,OAAO,MAAMmB,yBAAyB,GAAGA,CAAC;EACxChB,iBAAiB;EACjBiB,oBAAoB;EACpBC;AAC8B,CAAC,KAAK;EACpC,MAAMC,YAAY,GAAG,IAAItB,0BAA0B,CAACG,iBAAiB,CAAC;EAEtE,IAAIiB,oBAAoB,EAAE;IACxB,CAACG,KAAK,CAACC,OAAO,CAACJ,oBAAoB,CAAC,GAChCA,oBAAoB,GACpB,CAACA,oBAAoB,CAAC,EACxBK,OAAO,CAAEC,iBAAiB,IAAK;MAC/BJ,YAAY,CAACZ,WAAW,CAACgB,iBAAiB,CAAC;IAC7C,CAAC,CAAC;EACJ;EAEAL,uBAAuB,CAACX,WAAW,CAACY,YAAY,CAAC;EAEjD,OAAOA,YAAY;AACrB,CAAC"}
1
+ {"version":3,"file":"renderReactInWebComponent.js","names":["createReactRootElements","appRootElement","document","createElement","stylesRootElement","style","setProperty","setAttribute","window","cspNonce","reactWebComponentElementName","ReactInWebComponentElement","HTMLElement","constructor","getReactComponent","reactRootElements","styleElement","shadowRoot","attachShadow","mode","innerHTML","appendChild","reactRootPromise","then","createRoot","connectedCallback","reactRoot","render","disconnectedCallback","unmount","customElements","get","define","renderReactInWebComponent","webComponentChildren","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\n/**\n * Creates elements for a Shadow DOM that Odyssey will render into.\n * The Emotion root is for `<style>` tags and the app root is for an app to render into.\n * These are bare elements that\n */\nexport const createReactRootElements = () => {\n const appRootElement = document.createElement(\"div\");\n const stylesRootElement = document.createElement(\"div\");\n\n // This `div` may cause layout issues unless it inherits the parent's height.\n appRootElement.style.setProperty(\"height\", \"inherit\");\n\n appRootElement.setAttribute(\"id\", \"app-root\");\n stylesRootElement.setAttribute(\"id\", \"style-root\");\n stylesRootElement.setAttribute(\"nonce\", window.cspNonce);\n\n return {\n /**\n * The element your React root component renders into.\n * React has to render or portal somewhere, and this element can be used for that root element.\n *\n * In the case of a web component, there is no defined root element, so you have to define it yourself.\n */\n appRootElement,\n /**\n * In React apps, your styles typically go in `document.head`, but you may want to render them somewhere else.\n *\n * Specifically when rendering in a web component, there is no `<head>`, so you have to create a spot for styles to render.\n */\n stylesRootElement,\n };\n};\n\nexport type ReactRootElements = ReturnType<typeof createReactRootElements>;\n\nexport const reactWebComponentElementName = \"odyssey-react-web-component\";\n\nexport type GetReactComponentInWebComponent = (\n reactRootElements: ReactRootElements,\n) => ReactNode;\n\nexport class ReactInWebComponentElement extends HTMLElement {\n getReactComponent: GetReactComponentInWebComponent;\n reactRootElements: ReactRootElements;\n reactRootPromise: Promise<Root>;\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 // 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 this.reactRootPromise = import(\"react-dom/client\").then(({ createRoot }) =>\n createRoot(this.reactRootElements.appRootElement),\n );\n }\n\n connectedCallback() {\n this.reactRootPromise.then((reactRoot) =>\n reactRoot.render(this.getReactComponent(this.reactRootElements)),\n );\n }\n\n disconnectedCallback() {\n this.reactRootPromise.then((reactRoot) => reactRoot.unmount());\n }\n}\n\nif (!customElements.get(reactWebComponentElementName)) {\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 * You 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 webComponentRootElement: HTMLElement;\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 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 webComponentRootElement.appendChild(reactElement);\n\n return reactElement;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okta/odyssey-react-mui",
3
- "version": "1.27.0",
3
+ "version": "1.28.1",
4
4
  "description": "React MUI components for Odyssey, Okta's design system",
5
5
  "author": "Okta, Inc.",
6
6
  "license": "Apache-2.0",
@@ -61,7 +61,7 @@
61
61
  "@mui/system": "^5.15.9",
62
62
  "@mui/utils": "^5.15.9",
63
63
  "@mui/x-date-pickers": "^7.2.0",
64
- "@okta/odyssey-design-tokens": "^1.27.0",
64
+ "@okta/odyssey-design-tokens": "^1.28.1",
65
65
  "@types/luxon": "^3.4.2",
66
66
  "date-fns": "^2.30.0",
67
67
  "dom-accessibility-api": "^0.7.0",
@@ -77,5 +77,5 @@
77
77
  "react": "^18.2.0",
78
78
  "react-dom": "^18.2.0"
79
79
  },
80
- "gitHead": "929b26fa0b7821e97b67b218cbcfd23e75b3ea1e"
80
+ "gitHead": "114892c4072f9dc963e3dab57ee7fc6e3e9acfdd"
81
81
  }
@@ -16,21 +16,22 @@ import {
16
16
  HTMLAttributes,
17
17
  memo,
18
18
  ReactElement,
19
+ ReactNode,
19
20
  useCallback,
20
21
  useImperativeHandle,
21
22
  useMemo,
22
23
  useRef,
23
24
  } from "react";
24
25
 
25
- import { useButton } from "./ButtonContext";
26
- import type { HtmlProps } from "./HtmlProps";
27
- import { FocusHandle } from "./inputUtils";
26
+ import { useButton } from "../Buttons";
27
+ import type { HtmlProps } from "../HtmlProps";
28
+ import { FocusHandle } from "../inputUtils";
28
29
  import {
29
30
  MuiPropsContext,
30
31
  MuiPropsContextType,
31
32
  useMuiProps,
32
- } from "./MuiPropsContext";
33
- import { Tooltip } from "./Tooltip";
33
+ } from "../MuiPropsContext";
34
+ import { Tooltip } from "../Tooltip";
34
35
 
35
36
  export const buttonSizeValues = ["small", "medium", "large"] as const;
36
37
  export const buttonTypeValues = ["button", "submit", "reset"] as const;
@@ -43,7 +44,7 @@ export const buttonVariantValues = [
43
44
  "floatingAction",
44
45
  ] as const;
45
46
 
46
- export type ButtonProps = {
47
+ export type BaseButtonProps = {
47
48
  /**
48
49
  * The ref forwarded to the Button
49
50
  */
@@ -85,64 +86,41 @@ export type ButtonProps = {
85
86
  * The click event handler for the Button
86
87
  */
87
88
  onClick?: MuiButtonProps["onClick"];
88
- } & (
89
- | {
90
- /**
91
- * The icon element to display at the end of the Button
92
- */
93
- endIcon?: ReactElement;
94
- /**
95
- * The text content of the Button
96
- */
97
- label: string;
98
- /**
99
- * The icon element to display at the start of the Button
100
- */
101
- startIcon?: ReactElement;
102
- }
103
- | {
104
- /**
105
- * The icon element to display at the end of the Button
106
- */
107
- endIcon?: ReactElement;
108
- /**
109
- * The text content of the Button
110
- */
111
- label?: string | "" | undefined;
112
- /**
113
- * The icon element to display at the start of the Button
114
- */
115
- startIcon: ReactElement;
116
- }
117
- | {
118
- /**
119
- * The icon element to display at the end of the Button
120
- */
121
- endIcon: ReactElement;
122
- /**
123
- * The text content of the Button
124
- */
125
- label?: never;
126
- /**
127
- * The icon element to display at the start of the Button
128
- */
129
- startIcon?: ReactElement;
130
- }
131
- ) &
132
- Pick<
133
- HtmlProps,
134
- | "ariaControls"
135
- | "ariaDescribedBy"
136
- | "ariaExpanded"
137
- | "ariaHasPopup"
138
- | "ariaLabel"
139
- | "ariaLabelledBy"
140
- | "tabIndex"
141
- | "testId"
142
- | "translate"
143
- >;
89
+ /**
90
+ * The contents of the button. Only available internal to Odyssey here in BaseButton. If set, label is ignored.
91
+ */
92
+ children?: ReactNode;
93
+ /**
94
+ * The icon element to display at the end of the Button
95
+ */
96
+ endIcon?: ReactElement;
97
+ /**
98
+ * The text content of the Button
99
+ */
100
+ label?: string;
101
+ /**
102
+ * The icon element to display at the start of the Button
103
+ */
104
+ startIcon?: ReactElement;
105
+ };
106
+
107
+ // These are split and exported separately from the above because wrappers of this (e.g. Button) will
108
+ // want to omit children, which they cannot do from the combined union type. Instead, they should
109
+ // omit from BaseButtonProps, then union with the AdditionalBaseButtonProps (as seen in Button)
110
+ export type AdditionalBaseButtonProps = Pick<
111
+ HtmlProps,
112
+ | "ariaControls"
113
+ | "ariaDescribedBy"
114
+ | "ariaExpanded"
115
+ | "ariaHasPopup"
116
+ | "ariaLabel"
117
+ | "ariaLabelledBy"
118
+ | "tabIndex"
119
+ | "testId"
120
+ | "translate"
121
+ >;
144
122
 
145
- const Button = ({
123
+ const BaseButton = ({
146
124
  ariaControls,
147
125
  ariaDescribedBy,
148
126
  ariaExpanded,
@@ -156,6 +134,7 @@ const Button = ({
156
134
  isDisabled,
157
135
  isFullWidth: isFullWidthProp,
158
136
  label = "",
137
+ children,
159
138
  onClick,
160
139
  size = "medium",
161
140
  startIcon,
@@ -165,7 +144,7 @@ const Button = ({
165
144
  translate,
166
145
  type = "button",
167
146
  variant: variantProp,
168
- }: ButtonProps) => {
147
+ }: BaseButtonProps & AdditionalBaseButtonProps) => {
169
148
  const muiProps = useMuiProps();
170
149
 
171
150
  // We're deprecating the "tertiary" variant, so map it to
@@ -225,7 +204,7 @@ const Button = ({
225
204
  type={type}
226
205
  variant={variant}
227
206
  >
228
- {label}
207
+ {children ?? label}
229
208
  </MuiButton>
230
209
  );
231
210
  },
@@ -242,6 +221,7 @@ const Button = ({
242
221
  isDisabled,
243
222
  isFullWidth,
244
223
  label,
224
+ children,
245
225
  onClick,
246
226
  size,
247
227
  startIcon,
@@ -264,7 +244,7 @@ const Button = ({
264
244
  return renderButton(muiProps);
265
245
  };
266
246
 
267
- const MemoizedButton = memo(Button);
268
- MemoizedButton.displayName = "Button";
247
+ const MemoizedBaseButton = memo(BaseButton);
248
+ MemoizedBaseButton.displayName = "BaseButton";
269
249
 
270
- export { MemoizedButton as Button };
250
+ export { MemoizedBaseButton as BaseButton };
@@ -18,18 +18,28 @@ import {
18
18
  useState,
19
19
  ReactNode,
20
20
  } from "react";
21
- import { Menu as MuiMenu, PopoverOrigin } from "@mui/material";
21
+ import {
22
+ Menu as MuiMenu,
23
+ Popover as MuiPopover,
24
+ PopoverOrigin,
25
+ } from "@mui/material";
22
26
 
23
- import { Button, buttonSizeValues, buttonVariantValues, useUniqueId } from "./";
24
- import { ChevronDownIcon, MoreIcon } from "./icons.generated";
25
- import { FieldComponentProps } from "./FieldComponentProps";
27
+ import { useOdysseyDesignTokens } from "../OdysseyDesignTokensContext";
28
+ import { Box, buttonSizeValues, buttonVariantValues, useUniqueId } from "..";
29
+ import { BaseButton } from "./BaseButton";
30
+ import { ChevronDownIcon, MoreIcon } from "../icons.generated";
31
+ import { FieldComponentProps } from "../FieldComponentProps";
26
32
  import { MenuContext, MenuContextType } from "./MenuContext";
27
- import { NullElement } from "./NullElement";
28
- import type { HtmlProps } from "./HtmlProps";
33
+ import { NullElement } from "../NullElement";
34
+ import type { HtmlProps } from "../HtmlProps";
29
35
 
30
36
  export const menuAlignmentValues = ["left", "right"] as const;
31
37
 
32
- export type MenuButtonProps = {
38
+ export type BaseMenuButtonProps = {
39
+ /**
40
+ * The button children for the triggering Button. Only available internal to Odyssey here in BaseMenuButton. If set, buttonLabel is ignored.
41
+ */
42
+ buttonChildren?: ReactNode;
33
43
  /**
34
44
  * The label on the triggering Button
35
45
  */
@@ -38,14 +48,14 @@ export type MenuButtonProps = {
38
48
  * The variant of the triggering Button
39
49
  */
40
50
  buttonVariant?: (typeof buttonVariantValues)[number];
41
- /**
42
- * The <MenuItem> components within the Menu.
43
- */
44
- children: ReactNode | NullElement;
45
51
  /**
46
52
  * The end Icon on the trigggering Button
47
53
  */
48
54
  endIcon?: ReactElement;
55
+ /**
56
+ * Whether to omit the endIcon if not set (rather than use a default value for it based on overflow)
57
+ */
58
+ omitEndIcon?: boolean;
49
59
  /**
50
60
  * The id of the Button
51
61
  */
@@ -71,7 +81,12 @@ export type MenuButtonProps = {
71
81
  * The tooltip text for the Button if it's icon-only
72
82
  */
73
83
  tooltipText?: string;
74
- } & Pick<
84
+ };
85
+
86
+ // These are split and exported separately from the above because wrappers of this (e.g. MenuButton) will
87
+ // want to omit buttonChildren, which they cannot do from the combined union type. Instead, they should
88
+ // omit from BaseMenuButtonProps, then union with the AdditionalBaseMenuButtonProps (as seen in MenuButton)
89
+ export type AdditionalBaseMenuButtonProps = Pick<
75
90
  HtmlProps,
76
91
  "ariaDescribedBy" | "ariaLabel" | "ariaLabelledBy" | "testId" | "translate"
77
92
  > &
@@ -86,26 +101,52 @@ export type MenuButtonProps = {
86
101
  Partial<Pick<HtmlProps, "ariaLabelledBy">> & {
87
102
  buttonLabel?: undefined | "";
88
103
  })
104
+ ) &
105
+ (
106
+ | {
107
+ /**
108
+ * The <MenuItem> components within the Menu.
109
+ */
110
+ children: ReactNode | NullElement;
111
+ /**
112
+ * popoverConten is disallowed if children are present
113
+ */
114
+ popoverContent?: never;
115
+ }
116
+ | {
117
+ /**
118
+ * children is disallowed if popoverContent is present
119
+ */
120
+ children?: never;
121
+ /**
122
+ * The content for the popover that is triggered on click.
123
+ */
124
+ popoverContent: ReactNode | NullElement;
125
+ }
89
126
  );
90
127
 
91
- const MenuButton = ({
128
+ const BaseMenuButton = ({
92
129
  ariaLabel,
93
130
  ariaLabelledBy,
94
131
  ariaDescribedBy,
132
+ buttonChildren,
95
133
  buttonLabel = "",
96
134
  buttonVariant = "secondary",
97
135
  children,
136
+ popoverContent,
98
137
  shouldCloseOnSelect = true,
99
138
  endIcon: endIconProp,
100
139
  id: idOverride,
101
140
  isDisabled,
102
141
  isOverflow,
103
142
  menuAlignment = "left",
143
+ omitEndIcon = false,
104
144
  size,
105
145
  testId,
106
146
  tooltipText,
107
147
  translate,
108
- }: MenuButtonProps) => {
148
+ }: BaseMenuButtonProps & AdditionalBaseMenuButtonProps) => {
149
+ const odysseyDesignTokens = useOdysseyDesignTokens();
109
150
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
110
151
 
111
152
  const isOpen = Boolean(anchorEl);
@@ -134,7 +175,7 @@ const MenuButton = ({
134
175
  [closeMenu, openMenu, shouldCloseOnSelect],
135
176
  );
136
177
 
137
- const endIcon = endIconProp ? (
178
+ const endIcon = omitEndIcon ? undefined : endIconProp ? (
138
179
  endIconProp
139
180
  ) : isOverflow ? (
140
181
  <MoreIcon />
@@ -162,7 +203,7 @@ const MenuButton = ({
162
203
 
163
204
  return (
164
205
  <div>
165
- <Button
206
+ <BaseButton
166
207
  ariaControls={isOpen ? `${uniqueId}-menu` : undefined}
167
208
  ariaExpanded={isOpen ? "true" : undefined}
168
209
  ariaHasPopup="true"
@@ -174,6 +215,7 @@ const MenuButton = ({
174
215
  id={`${uniqueId}-button`}
175
216
  isDisabled={isDisabled}
176
217
  label={buttonLabel}
218
+ children={buttonChildren}
177
219
  onClick={openMenu}
178
220
  size={size}
179
221
  tooltipText={tooltipText}
@@ -181,24 +223,44 @@ const MenuButton = ({
181
223
  variant={buttonVariant}
182
224
  />
183
225
 
184
- <MuiMenu
185
- anchorOrigin={anchorOrigin}
186
- transformOrigin={transformOrigin}
187
- anchorEl={anchorEl}
188
- id={`${uniqueId}-menu`}
189
- MenuListProps={menuListProps}
190
- onClose={closeMenu}
191
- open={isOpen}
192
- >
193
- <MenuContext.Provider value={providerValue}>
194
- {children}
195
- </MenuContext.Provider>
196
- </MuiMenu>
226
+ {children && (
227
+ <MuiMenu
228
+ anchorOrigin={anchorOrigin}
229
+ transformOrigin={transformOrigin}
230
+ anchorEl={anchorEl}
231
+ id={`${uniqueId}-menu`}
232
+ MenuListProps={menuListProps}
233
+ onClose={closeMenu}
234
+ open={isOpen}
235
+ >
236
+ <MenuContext.Provider value={providerValue}>
237
+ {children}
238
+ </MenuContext.Provider>
239
+ </MuiMenu>
240
+ )}
241
+
242
+ {popoverContent && (
243
+ <MuiPopover
244
+ open={isOpen}
245
+ anchorEl={anchorEl}
246
+ onClose={closeMenu}
247
+ anchorOrigin={anchorOrigin}
248
+ transformOrigin={transformOrigin}
249
+ >
250
+ <Box
251
+ sx={{
252
+ padding: odysseyDesignTokens.Spacing4,
253
+ }}
254
+ >
255
+ {popoverContent}
256
+ </Box>
257
+ </MuiPopover>
258
+ )}
197
259
  </div>
198
260
  );
199
261
  };
200
262
 
201
- const MemoizedMenuButton = memo(MenuButton);
202
- MemoizedMenuButton.displayName = "MenuButton";
263
+ const MemoizedBaseMenuButton = memo(BaseMenuButton);
264
+ MemoizedBaseMenuButton.displayName = "BaseMenuButton";
203
265
 
204
- export { MemoizedMenuButton as MenuButton };
266
+ export { MemoizedBaseMenuButton as BaseMenuButton };
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
3
+ * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4
+ *
5
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6
+ * Unless required by applicable law or agreed to in writing, software
7
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
+ *
10
+ * See the License for the specific language governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { memo } from "react";
14
+ import {
15
+ AdditionalBaseButtonProps,
16
+ BaseButton,
17
+ BaseButtonProps,
18
+ } from "./BaseButton";
19
+
20
+ export type ButtonProps = Omit<BaseButtonProps, "children"> &
21
+ AdditionalBaseButtonProps;
22
+
23
+ const Button = (props: ButtonProps) => {
24
+ return <BaseButton {...props} />;
25
+ };
26
+
27
+ const MemoizedButton = memo(Button);
28
+ MemoizedButton.displayName = "Button";
29
+
30
+ export { MemoizedButton as Button };
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
3
+ * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4
+ *
5
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6
+ * Unless required by applicable law or agreed to in writing, software
7
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
+ *
10
+ * See the License for the specific language governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { memo } from "react";
14
+ import {
15
+ AdditionalBaseMenuButtonProps,
16
+ BaseMenuButton,
17
+ BaseMenuButtonProps,
18
+ } from "./BaseMenuButton";
19
+
20
+ export const menuAlignmentValues = ["left", "right"] as const;
21
+
22
+ export type MenuButtonProps = Omit<
23
+ BaseMenuButtonProps,
24
+ "buttonChildren" | "omitEndIcon"
25
+ > &
26
+ AdditionalBaseMenuButtonProps;
27
+
28
+ const MenuButton = (props: MenuButtonProps) => {
29
+ return <BaseMenuButton {...props} />;
30
+ };
31
+
32
+ const MemoizedMenuButton = memo(MenuButton);
33
+ MemoizedMenuButton.displayName = "MenuButton";
34
+
35
+ export { MemoizedMenuButton as MenuButton };
@@ -18,7 +18,7 @@ import { menuItemClasses } from "@mui/material/MenuItem";
18
18
  import { memo, useCallback, useContext, type ReactNode } from "react";
19
19
 
20
20
  import { MenuContext } from "./MenuContext";
21
- import type { HtmlProps } from "./HtmlProps";
21
+ import type { HtmlProps } from "../HtmlProps";
22
22
 
23
23
  export type MenuItemProps = {
24
24
  /**
@@ -0,0 +1,22 @@
1
+ /*!
2
+ * Copyright (c) 2024-present, Okta, Inc. and/or its affiliates. All rights reserved.
3
+ * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4
+ *
5
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6
+ * Unless required by applicable law or agreed to in writing, software
7
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
+ *
10
+ * See the License for the specific language governing permissions and limitations under the License.
11
+ */
12
+
13
+ export {
14
+ buttonSizeValues,
15
+ buttonTypeValues,
16
+ buttonVariantValues,
17
+ } from "./BaseButton";
18
+ export * from "./Button";
19
+ export * from "./ButtonContext";
20
+ export { menuAlignmentValues } from "./BaseMenuButton";
21
+ export * from "./MenuButton";
22
+ export * from "./MenuItem";
package/src/Card.tsx CHANGED
@@ -24,10 +24,8 @@ import {
24
24
  } from "@mui/material";
25
25
  import styled from "@emotion/styled";
26
26
 
27
- import { Button } from "./Button";
28
- import { ButtonContext } from "./ButtonContext";
27
+ import { Button, ButtonContext, MenuButton, MenuButtonProps } from "./Buttons";
29
28
  import { MoreIcon } from "./icons.generated";
30
- import { MenuButton, MenuButtonProps } from "./MenuButton";
31
29
  import {
32
30
  DesignTokens,
33
31
  useOdysseyDesignTokens,
@@ -51,7 +51,6 @@ import {
51
51
  } from "./DataTableRowActions";
52
52
  import { useRowReordering } from "./useRowReordering";
53
53
  import { DataTableSettings } from "./DataTableSettings";
54
- import { MenuButton, MenuButtonProps } from "../MenuButton";
55
54
  import { Box } from "../Box";
56
55
  import { DataTableRowSelectionState, DataTableRowData } from ".";
57
56
  import {
@@ -61,7 +60,7 @@ import {
61
60
  import { useScrollIndication } from "./useScrollIndication";
62
61
  import styled from "@emotion/styled";
63
62
  import { EmptyState } from "../EmptyState";
64
- import { Button } from "../Button";
63
+ import { Button, MenuButton, MenuButtonProps } from "../Buttons";
65
64
  import { Callout } from "../Callout";
66
65
 
67
66
  export type DataTableColumn<T extends DataTableRowData> = MRT_ColumnDef<T> & {
@@ -12,10 +12,8 @@
12
12
 
13
13
  import { MRT_Row, MRT_RowData } from "material-react-table";
14
14
  import { Fragment, ReactElement, memo, useCallback } from "react";
15
- import { Button } from "../Button";
16
- import { MenuItem } from "../MenuItem";
15
+ import { Button, MenuButton, MenuButtonProps, MenuItem } from "../Buttons";
17
16
  import { Box as MuiBox } from "@mui/material";
18
- import { MenuButton, MenuButtonProps } from "../MenuButton";
19
17
  import {
20
18
  ArrowBottomIcon,
21
19
  ArrowDownIcon,
@@ -12,8 +12,7 @@
12
12
 
13
13
  import { Dispatch, SetStateAction, memo, useCallback, useMemo } from "react";
14
14
  import { Checkbox as MuiCheckbox } from "@mui/material";
15
- import { MenuButton } from "../MenuButton";
16
- import { MenuItem } from "../MenuItem";
15
+ import { MenuButton, MenuItem } from "../Buttons";
17
16
  import { ListIcon, ShowIcon } from "../icons.generated";
18
17
  import { densityValues } from "./constants";
19
18
  import { DataTableProps } from "./DataTable";
package/src/Dialog.tsx CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  DialogContentText,
19
19
  DialogActions,
20
20
  } from "@mui/material";
21
- import { Button } from "./Button";
21
+ import { Button } from "./Buttons";
22
22
  import { CloseIcon } from "./icons.generated";
23
23
  import {
24
24
  cloneElement,
package/src/Drawer.tsx CHANGED
@@ -24,7 +24,7 @@ import { Drawer as MuiDrawer } from "@mui/material";
24
24
  import styled from "@emotion/styled";
25
25
  import { useTranslation } from "react-i18next";
26
26
 
27
- import { Button } from "./Button";
27
+ import { Button } from "./Buttons";
28
28
  import { CloseIcon } from "./icons.generated";
29
29
  import {
30
30
  DesignTokens,