@okta/odyssey-react-mui 1.24.1 → 1.26.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/CHANGELOG.md +21 -0
- package/dist/Autocomplete.js +30 -191
- package/dist/Autocomplete.js.map +1 -1
- package/dist/Box.js +2 -0
- package/dist/Box.js.map +1 -1
- package/dist/Card.js +1 -0
- package/dist/Card.js.map +1 -1
- package/dist/OdysseyDesignTokensContext.js +3 -2
- package/dist/OdysseyDesignTokensContext.js.map +1 -1
- package/dist/OdysseyProvider.js +22 -40
- package/dist/OdysseyProvider.js.map +1 -1
- package/dist/OdysseyThemeProvider.js +33 -12
- package/dist/OdysseyThemeProvider.js.map +1 -1
- package/dist/OdysseyTranslationProvider.types.js +1 -1
- package/dist/OdysseyTranslationProvider.types.js.map +1 -1
- package/dist/Pagination/Pagination.js +46 -14
- package/dist/Pagination/Pagination.js.map +1 -1
- package/dist/Select.js +10 -2
- package/dist/Select.js.map +1 -1
- package/dist/Surface.js +4 -1
- package/dist/Surface.js.map +1 -1
- package/dist/Tag.js +97 -47
- package/dist/Tag.js.map +1 -1
- package/dist/i18n.js +2 -0
- package/dist/i18n.js.map +1 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/index.scss +1 -1
- package/dist/labs/AppTile.js +137 -39
- package/dist/labs/AppTile.js.map +1 -1
- package/dist/labs/DataView/CardLayoutContent.js +7 -8
- package/dist/labs/DataView/CardLayoutContent.js.map +1 -1
- package/dist/labs/DataView/DataCard.js +96 -43
- package/dist/labs/DataView/DataCard.js.map +1 -1
- package/dist/labs/DataView/TableLayoutContent.js +3 -2
- package/dist/labs/DataView/TableLayoutContent.js.map +1 -1
- package/dist/labs/DataView/componentTypes.js.map +1 -1
- package/dist/labs/DataView/index.js.map +1 -1
- package/dist/labs/OdysseyPickers/ComposablePicker.js +113 -0
- package/dist/labs/OdysseyPickers/ComposablePicker.js.map +1 -0
- package/dist/labs/OdysseyPickers/Picker.js +261 -0
- package/dist/labs/OdysseyPickers/Picker.js.map +1 -0
- package/dist/labs/OdysseyPickers/PickerVirtualizationListBox.js +132 -0
- package/dist/labs/OdysseyPickers/PickerVirtualizationListBox.js.map +1 -0
- package/dist/labs/OdysseyPickers/PickerWithOptionAdornment.js +291 -0
- package/dist/labs/OdysseyPickers/PickerWithOptionAdornment.js.map +1 -0
- package/dist/{src/createShadowDomElements.d.ts → labs/OdysseyPickers/index.js} +4 -7
- package/dist/labs/OdysseyPickers/index.js.map +1 -0
- package/dist/labs/PageTemplate.js +14 -10
- package/dist/labs/PageTemplate.js.map +1 -1
- package/dist/labs/SideNav/CollapseIcon.js +11 -25
- package/dist/labs/SideNav/CollapseIcon.js.map +1 -1
- package/dist/labs/SideNav/HandleIcon.js +32 -0
- package/dist/labs/SideNav/HandleIcon.js.map +1 -0
- package/dist/labs/{NavAccordion.js → SideNav/NavAccordion.js} +35 -6
- package/dist/labs/SideNav/NavAccordion.js.map +1 -0
- package/dist/labs/SideNav/OktaAura.js +32 -0
- package/dist/labs/SideNav/OktaAura.js.map +1 -0
- package/dist/labs/SideNav/OktaLogo.js +6 -9
- package/dist/labs/SideNav/OktaLogo.js.map +1 -1
- package/dist/labs/SideNav/SideNav.js +239 -169
- package/dist/labs/SideNav/SideNav.js.map +1 -1
- package/dist/labs/SideNav/SideNavFooterContent.js +32 -18
- package/dist/labs/SideNav/SideNavFooterContent.js.map +1 -1
- package/dist/labs/SideNav/SideNavHeader.js +48 -37
- package/dist/labs/SideNav/SideNavHeader.js.map +1 -1
- package/dist/labs/SideNav/SideNavItemContent.js +100 -58
- package/dist/labs/SideNav/SideNavItemContent.js.map +1 -1
- package/dist/labs/SideNav/SideNavItemContentContext.js +19 -0
- package/dist/labs/SideNav/SideNavItemContentContext.js.map +1 -0
- package/dist/labs/SideNav/SideNavItemLinkContent.js +14 -13
- package/dist/labs/SideNav/SideNavItemLinkContent.js.map +1 -1
- package/dist/labs/SideNav/SideNavLogo.js +42 -0
- package/dist/labs/SideNav/SideNavLogo.js.map +1 -0
- package/dist/labs/SideNav/SideNavToggleButton.js +170 -0
- package/dist/labs/SideNav/SideNavToggleButton.js.map +1 -0
- package/dist/labs/SideNav/types.js.map +1 -1
- package/dist/labs/TopNav/TopNav.js +65 -0
- package/dist/labs/TopNav/TopNav.js.map +1 -0
- package/dist/labs/TopNav/TopNavLinksList.js +38 -0
- package/dist/labs/TopNav/TopNavLinksList.js.map +1 -0
- package/dist/labs/TopNav/TopNavListItem.js +132 -0
- package/dist/labs/TopNav/TopNavListItem.js.map +1 -0
- package/dist/labs/TopNav/UserProfile.js +65 -0
- package/dist/labs/TopNav/UserProfile.js.map +1 -0
- package/dist/labs/TopNav/index.js +14 -0
- package/dist/labs/TopNav/index.js.map +1 -0
- package/dist/labs/UiShell/UiShell.js +68 -0
- package/dist/labs/UiShell/UiShell.js.map +1 -0
- package/dist/labs/UiShell/UiShellContent.js +114 -0
- package/dist/labs/UiShell/UiShellContent.js.map +1 -0
- package/dist/labs/UiShell/bufferLatest.js +37 -0
- package/dist/labs/UiShell/bufferLatest.js.map +1 -0
- package/dist/labs/UiShell/createMessageBus.js +30 -0
- package/dist/labs/UiShell/createMessageBus.js.map +1 -0
- package/dist/labs/UiShell/createStore.js +24 -0
- package/dist/labs/UiShell/createStore.js.map +1 -0
- package/dist/labs/UiShell/index.js +15 -0
- package/dist/labs/UiShell/index.js.map +1 -0
- package/dist/labs/UiShell/renderUiShell.js +78 -0
- package/dist/labs/UiShell/renderUiShell.js.map +1 -0
- package/dist/labs/UiShell/useHasUiShell.js +22 -0
- package/dist/labs/UiShell/useHasUiShell.js.map +1 -0
- package/dist/labs/UiShell/useScrollState.js +41 -0
- package/dist/labs/UiShell/useScrollState.js.map +1 -0
- package/dist/labs/index.js +5 -3
- package/dist/labs/index.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui.js +7 -1
- package/dist/properties/ts/odyssey-react-mui.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_cs.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_cs.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_da.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_da.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_de.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_de.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_el.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_el.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_es.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_es.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_fi.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_fi.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_fr.js +5 -3
- package/dist/properties/ts/odyssey-react-mui_fr.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ht.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_ht.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_hu.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_hu.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_id.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_id.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_it.js +4 -2
- package/dist/properties/ts/odyssey-react-mui_it.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ja.js +9 -7
- package/dist/properties/ts/odyssey-react-mui_ja.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ko.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_ko.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ms.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_ms.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_nb.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_nb.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_nl_NL.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_nl_NL.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_pl.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_pl.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_pt_BR.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_pt_BR.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ro.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_ro.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_ru.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_ru.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_sv.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_sv.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_th.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_th.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_tr.js +4 -2
- package/dist/properties/ts/odyssey-react-mui_tr.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_uk.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_uk.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_vi.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_vi.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_zh_CN.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_zh_CN.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui_zh_TW.js +3 -1
- package/dist/properties/ts/odyssey-react-mui_zh_TW.js.map +1 -1
- package/dist/src/Autocomplete.d.ts +21 -22
- package/dist/src/Autocomplete.d.ts.map +1 -1
- package/dist/src/Box.d.ts +3 -1
- package/dist/src/Box.d.ts.map +1 -1
- package/dist/src/Card.d.ts.map +1 -1
- package/dist/src/OdysseyDesignTokensContext.d.ts +5 -4
- package/dist/src/OdysseyDesignTokensContext.d.ts.map +1 -1
- package/dist/src/OdysseyProvider.d.ts +1 -3
- package/dist/src/OdysseyProvider.d.ts.map +1 -1
- package/dist/src/OdysseyThemeProvider.d.ts +10 -4
- package/dist/src/OdysseyThemeProvider.d.ts.map +1 -1
- package/dist/src/OdysseyTranslationProvider.d.ts +1 -1
- package/dist/src/OdysseyTranslationProvider.d.ts.map +1 -1
- package/dist/src/OdysseyTranslationProvider.types.d.ts +1 -1
- package/dist/src/OdysseyTranslationProvider.types.d.ts.map +1 -1
- package/dist/src/Pagination/Pagination.d.ts +21 -7
- package/dist/src/Pagination/Pagination.d.ts.map +1 -1
- package/dist/src/Select.d.ts.map +1 -1
- package/dist/src/Surface.d.ts.map +1 -1
- package/dist/src/Tag.d.ts +5 -2
- package/dist/src/Tag.d.ts.map +1 -1
- package/dist/src/i18n.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/labs/AppTile.d.ts +3 -1
- package/dist/src/labs/AppTile.d.ts.map +1 -1
- package/dist/src/labs/DataView/CardLayoutContent.d.ts.map +1 -1
- package/dist/src/labs/DataView/DataCard.d.ts +9 -3
- package/dist/src/labs/DataView/DataCard.d.ts.map +1 -1
- package/dist/src/labs/DataView/TableLayoutContent.d.ts.map +1 -1
- package/dist/src/labs/DataView/componentTypes.d.ts +1 -1
- package/dist/src/labs/DataView/componentTypes.d.ts.map +1 -1
- package/dist/src/labs/DataView/index.d.ts +1 -0
- package/dist/src/labs/DataView/index.d.ts.map +1 -1
- package/dist/src/labs/OdysseyPickers/ComposablePicker.d.ts +33 -0
- package/dist/src/labs/OdysseyPickers/ComposablePicker.d.ts.map +1 -0
- package/dist/src/labs/OdysseyPickers/Picker.d.ts +98 -0
- package/dist/src/labs/OdysseyPickers/Picker.d.ts.map +1 -0
- package/dist/src/labs/OdysseyPickers/PickerVirtualizationListBox.d.ts +17 -0
- package/dist/src/labs/OdysseyPickers/PickerVirtualizationListBox.d.ts.map +1 -0
- package/dist/src/labs/OdysseyPickers/PickerWithOptionAdornment.d.ts +26 -0
- package/dist/src/labs/OdysseyPickers/PickerWithOptionAdornment.d.ts.map +1 -0
- package/dist/src/labs/OdysseyPickers/index.d.ts +15 -0
- package/dist/src/labs/OdysseyPickers/index.d.ts.map +1 -0
- package/dist/src/labs/PageTemplate.d.ts +1 -1
- package/dist/src/labs/PageTemplate.d.ts.map +1 -1
- package/dist/src/labs/SideNav/CollapseIcon.d.ts +1 -4
- package/dist/src/labs/SideNav/CollapseIcon.d.ts.map +1 -1
- package/dist/src/labs/SideNav/HandleIcon.d.ts +14 -0
- package/dist/src/labs/SideNav/HandleIcon.d.ts.map +1 -0
- package/dist/src/labs/{NavAccordion.d.ts → SideNav/NavAccordion.d.ts} +6 -2
- package/dist/src/labs/SideNav/NavAccordion.d.ts.map +1 -0
- package/dist/src/labs/SideNav/OktaAura.d.ts +14 -0
- package/dist/src/labs/SideNav/OktaAura.d.ts.map +1 -0
- package/dist/src/labs/SideNav/OktaLogo.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNav.d.ts +2 -1
- package/dist/src/labs/SideNav/SideNav.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNavFooterContent.d.ts +1 -1
- package/dist/src/labs/SideNav/SideNavFooterContent.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNavHeader.d.ts +12 -3
- package/dist/src/labs/SideNav/SideNavHeader.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNavItemContent.d.ts +2 -3
- package/dist/src/labs/SideNav/SideNavItemContent.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNavItemContentContext.d.ts +18 -0
- package/dist/src/labs/SideNav/SideNavItemContentContext.d.ts.map +1 -0
- package/dist/src/labs/SideNav/SideNavItemLinkContent.d.ts +1 -1
- package/dist/src/labs/SideNav/SideNavItemLinkContent.d.ts.map +1 -1
- package/dist/src/labs/SideNav/SideNavLogo.d.ts +15 -0
- package/dist/src/labs/SideNav/SideNavLogo.d.ts.map +1 -0
- package/dist/src/labs/SideNav/SideNavToggleButton.d.ts +38 -0
- package/dist/src/labs/SideNav/SideNavToggleButton.d.ts.map +1 -0
- package/dist/src/labs/SideNav/types.d.ts +67 -33
- package/dist/src/labs/SideNav/types.d.ts.map +1 -1
- package/dist/src/labs/TopNav/TopNav.d.ts +31 -0
- package/dist/src/labs/TopNav/TopNav.d.ts.map +1 -0
- package/dist/src/labs/TopNav/TopNavLinksList.d.ts +44 -0
- package/dist/src/labs/TopNav/TopNavLinksList.d.ts.map +1 -0
- package/dist/src/labs/TopNav/TopNavListItem.d.ts +42 -0
- package/dist/src/labs/TopNav/TopNavListItem.d.ts.map +1 -0
- package/dist/src/labs/TopNav/UserProfile.d.ts +29 -0
- package/dist/src/labs/TopNav/UserProfile.d.ts.map +1 -0
- package/dist/src/labs/TopNav/index.d.ts +14 -0
- package/dist/src/labs/TopNav/index.d.ts.map +1 -0
- package/dist/src/labs/UiShell/UiShell.d.ts +33 -0
- package/dist/src/labs/UiShell/UiShell.d.ts.map +1 -0
- package/dist/src/labs/UiShell/UiShellContent.d.ts +47 -0
- package/dist/src/labs/UiShell/UiShellContent.d.ts.map +1 -0
- package/dist/src/labs/UiShell/bufferLatest.d.ts +31 -0
- package/dist/src/labs/UiShell/bufferLatest.d.ts.map +1 -0
- package/dist/src/labs/UiShell/createMessageBus.d.ts +24 -0
- package/dist/src/labs/UiShell/createMessageBus.d.ts.map +1 -0
- package/dist/src/labs/UiShell/createStore.d.ts +22 -0
- package/dist/src/labs/UiShell/createStore.d.ts.map +1 -0
- package/dist/src/labs/UiShell/index.d.ts +16 -0
- package/dist/src/labs/UiShell/index.d.ts.map +1 -0
- package/dist/src/labs/UiShell/renderUiShell.d.ts +45 -0
- package/dist/src/labs/UiShell/renderUiShell.d.ts.map +1 -0
- package/dist/src/labs/UiShell/useHasUiShell.d.ts +13 -0
- package/dist/src/labs/UiShell/useHasUiShell.d.ts.map +1 -0
- package/dist/src/labs/UiShell/useScrollState.d.ts +16 -0
- package/dist/src/labs/UiShell/useScrollState.d.ts.map +1 -0
- package/dist/src/labs/index.d.ts +6 -2
- package/dist/src/labs/index.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui.d.ts +6 -0
- package/dist/src/properties/ts/odyssey-react-mui.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_cs.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_cs.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_da.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_da.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_de.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_de.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_el.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_el.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_es.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_es.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_fi.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_fi.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_fr.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_fr.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ht.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ht.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_hu.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_hu.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_id.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_id.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_it.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_it.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ja.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ja.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ko.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ko.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ms.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ms.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_nb.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_nb.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_nl_NL.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_nl_NL.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_pl.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_pl.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_pt_BR.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_pt_BR.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ro.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ro.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_ru.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_ru.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_sv.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_sv.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_th.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_th.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_tr.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_tr.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_uk.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_uk.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_vi.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_vi.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_zh_CN.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_zh_CN.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui_zh_TW.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui_zh_TW.d.ts.map +1 -1
- package/dist/src/test-selectors/querySelector.d.ts +2 -2
- package/dist/src/theme/components.d.ts +3 -1
- package/dist/src/theme/components.d.ts.map +1 -1
- package/dist/src/theme/createOdysseyMuiTheme.d.ts +3 -1
- package/dist/src/theme/createOdysseyMuiTheme.d.ts.map +1 -1
- package/dist/src/useAutocomplete.d.ts +29 -0
- package/dist/src/useAutocomplete.d.ts.map +1 -0
- package/dist/src/useContrastMode.d.ts +46 -0
- package/dist/src/useContrastMode.d.ts.map +1 -0
- package/dist/src/web-component/index.d.ts +14 -0
- package/dist/src/web-component/index.d.ts.map +1 -0
- package/dist/src/web-component/renderReactInWebComponent.d.ts +76 -0
- package/dist/src/web-component/renderReactInWebComponent.d.ts.map +1 -0
- package/dist/src/web-component/shadow-dom.d.ts +23 -0
- package/dist/src/web-component/shadow-dom.d.ts.map +1 -0
- package/dist/test-selectors/querySelector.js.map +1 -1
- package/dist/theme/components.js +41 -32
- package/dist/theme/components.js.map +1 -1
- package/dist/theme/createOdysseyMuiTheme.js +3 -0
- package/dist/theme/createOdysseyMuiTheme.js.map +1 -1
- package/dist/tsconfig.production.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/useAutocomplete.js +105 -0
- package/dist/useAutocomplete.js.map +1 -0
- package/dist/useContrastMode.js +93 -0
- package/dist/useContrastMode.js.map +1 -0
- package/dist/web-component/index.js +14 -0
- package/dist/web-component/index.js.map +1 -0
- package/dist/web-component/renderReactInWebComponent.js +72 -0
- package/dist/web-component/renderReactInWebComponent.js.map +1 -0
- package/dist/{createShadowDomElements.js → web-component/shadow-dom.js} +10 -12
- package/dist/web-component/shadow-dom.js.map +1 -0
- package/jest.config.cjs +21 -2
- package/jest.setup.js +0 -3
- package/package.json +4 -3
- package/src/Autocomplete.tsx +40 -330
- package/src/Box.tsx +4 -2
- package/src/Card.tsx +1 -0
- package/src/OdysseyDesignTokensContext.tsx +6 -3
- package/src/OdysseyProvider.tsx +29 -56
- package/src/OdysseyThemeProvider.test.tsx +209 -0
- package/src/OdysseyThemeProvider.tsx +43 -17
- package/src/OdysseyTranslationProvider.types.ts +1 -0
- package/src/Pagination/Pagination.test.tsx +305 -0
- package/src/Pagination/Pagination.tsx +86 -38
- package/src/Select.tsx +12 -3
- package/src/Surface.tsx +2 -1
- package/src/Tag.tsx +102 -41
- package/src/createUniqueAlphabeticalId.test.ts +1 -1
- package/src/createUniqueId.test.ts +1 -1
- package/src/i18n.ts +2 -0
- package/src/index.ts +6 -7
- package/src/labs/AppTile.tsx +169 -40
- package/src/labs/DataView/CardLayoutContent.tsx +12 -14
- package/src/labs/DataView/DataCard.tsx +137 -69
- package/src/labs/DataView/DataView.test.tsx +6 -4
- package/src/labs/DataView/TableLayoutContent.tsx +6 -2
- package/src/labs/DataView/componentTypes.ts +1 -1
- package/src/labs/DataView/index.tsx +1 -0
- package/src/labs/OdysseyPickers/ComposablePicker.test.tsx +29 -0
- package/src/labs/OdysseyPickers/ComposablePicker.tsx +188 -0
- package/src/labs/OdysseyPickers/Picker.tsx +381 -0
- package/src/labs/OdysseyPickers/PickerVirtualizationListBox.tsx +191 -0
- package/src/labs/OdysseyPickers/PickerWithOptionAdornment.tsx +429 -0
- package/src/labs/OdysseyPickers/index.ts +15 -0
- package/src/labs/PageTemplate.tsx +18 -10
- package/src/labs/SideNav/CollapseIcon.tsx +14 -28
- package/src/labs/SideNav/HandleIcon.tsx +35 -0
- package/src/labs/{NavAccordion.tsx → SideNav/NavAccordion.tsx} +48 -8
- package/src/labs/SideNav/OktaAura.tsx +35 -0
- package/src/labs/SideNav/OktaLogo.tsx +5 -10
- package/src/labs/SideNav/SideNav.test.tsx +323 -0
- package/src/labs/SideNav/SideNav.tsx +291 -204
- package/src/labs/SideNav/SideNavFooterContent.tsx +36 -28
- package/src/labs/SideNav/SideNavHeader.tsx +62 -45
- package/src/labs/SideNav/SideNavItemContent.tsx +142 -62
- package/src/labs/SideNav/SideNavItemContentContext.tsx +27 -0
- package/src/labs/SideNav/SideNavItemLinkContent.tsx +17 -14
- package/src/labs/SideNav/SideNavLogo.tsx +41 -0
- package/src/labs/SideNav/SideNavToggleButton.tsx +249 -0
- package/src/labs/SideNav/types.ts +72 -33
- package/src/labs/TopNav/TopNav.tsx +95 -0
- package/src/labs/TopNav/TopNavLinksList.tsx +68 -0
- package/src/labs/TopNav/TopNavListItem.tsx +209 -0
- package/src/labs/TopNav/UserProfile.tsx +79 -0
- package/src/labs/TopNav/index.ts +14 -0
- package/src/labs/UiShell/UiShell.test.tsx +284 -0
- package/src/labs/UiShell/UiShell.tsx +109 -0
- package/src/labs/UiShell/UiShellContent.tsx +170 -0
- package/src/labs/UiShell/bufferLatest.test.ts +79 -0
- package/src/labs/UiShell/bufferLatest.ts +64 -0
- package/src/labs/UiShell/createMessageBus.test.ts +115 -0
- package/src/labs/UiShell/createMessageBus.ts +53 -0
- package/src/labs/UiShell/createStore.test.ts +103 -0
- package/src/labs/UiShell/createStore.ts +37 -0
- package/src/labs/UiShell/index.ts +17 -0
- package/src/labs/UiShell/renderUiShell.test.tsx +197 -0
- package/src/labs/UiShell/renderUiShell.tsx +132 -0
- package/src/labs/UiShell/useHasUiShell.ts +25 -0
- package/src/labs/UiShell/useScrollState.ts +56 -0
- package/src/labs/index.ts +10 -3
- package/src/properties/odyssey-react-mui.properties +7 -0
- package/src/properties/translations/odyssey-react-mui_cs.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_da.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_de.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_el.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_es.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_fi.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_fr.properties +4 -3
- package/src/properties/translations/odyssey-react-mui_ht.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_hu.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_id.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_it.properties +3 -2
- package/src/properties/translations/odyssey-react-mui_ja.properties +8 -7
- package/src/properties/translations/odyssey-react-mui_ko.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_ms.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_nb.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_nl_NL.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_pl.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_pt_BR.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_ro.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_ru.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_sv.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_th.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_tr.properties +3 -2
- package/src/properties/translations/odyssey-react-mui_uk.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_vi.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_zh_CN.properties +2 -1
- package/src/properties/translations/odyssey-react-mui_zh_TW.properties +2 -1
- package/src/properties/ts/odyssey-react-mui.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_cs.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_da.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_de.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_el.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_es.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_fi.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_fr.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ht.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_hu.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_id.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_it.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ja.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ko.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ms.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_nb.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_nl_NL.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_pl.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_pt_BR.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ro.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_ru.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_sv.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_th.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_tr.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_uk.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_vi.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_zh_CN.ts +1 -1
- package/src/properties/ts/odyssey-react-mui_zh_TW.ts +1 -1
- package/src/test-selectors/querySelector.ts +1 -1
- package/src/theme/components.tsx +55 -31
- package/src/theme/createOdysseyMuiTheme.ts +4 -0
- package/src/theme/useContrastMode.test.tsx +503 -0
- package/src/useAutocomplete.tsx +183 -0
- package/src/useContrastMode.tsx +149 -0
- package/src/web-component/index.ts +14 -0
- package/src/web-component/renderReactInWebComponent.test.tsx +156 -0
- package/src/web-component/renderReactInWebComponent.ts +153 -0
- package/src/web-component/shadow-dom.test.ts +24 -0
- package/src/{createShadowDomElements.ts → web-component/shadow-dom.ts} +15 -14
- package/dist/ContrastModeProvider.js +0 -86
- package/dist/ContrastModeProvider.js.map +0 -1
- package/dist/createShadowDomElements.js.map +0 -1
- package/dist/labs/NavAccordion.js.map +0 -1
- package/dist/labs/TopNav.js +0 -281
- package/dist/labs/TopNav.js.map +0 -1
- package/dist/src/ContrastModeProvider.d.ts +0 -34
- package/dist/src/ContrastModeProvider.d.ts.map +0 -1
- package/dist/src/createShadowDomElements.d.ts.map +0 -1
- package/dist/src/labs/NavAccordion.d.ts.map +0 -1
- package/dist/src/labs/TopNav.d.ts +0 -78
- package/dist/src/labs/TopNav.d.ts.map +0 -1
- package/src/ContrastModeProvider.tsx +0 -131
- package/src/labs/TopNav.tsx +0 -396
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2023-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 {
|
|
14
|
+
createContext,
|
|
15
|
+
useContext,
|
|
16
|
+
useRef,
|
|
17
|
+
useLayoutEffect,
|
|
18
|
+
useState,
|
|
19
|
+
useCallback,
|
|
20
|
+
} from "react";
|
|
21
|
+
import * as Tokens from "@okta/odyssey-design-tokens";
|
|
22
|
+
|
|
23
|
+
export type ContrastMode = "lowContrast" | "highContrast";
|
|
24
|
+
export type ContrastModeContextType = {
|
|
25
|
+
contrastMode: ContrastMode;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const ContrastModeContext = createContext<ContrastModeContextType>({
|
|
29
|
+
contrastMode: "lowContrast",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const defaultContrast = "lowContrast";
|
|
33
|
+
|
|
34
|
+
export const useContrastModeContext = () => useContext(ContrastModeContext);
|
|
35
|
+
|
|
36
|
+
export const hexToRgb = (hexString: string) => {
|
|
37
|
+
const hexNumber = parseInt(hexString.slice(1), 16);
|
|
38
|
+
const red = (hexNumber >> 16) & 255;
|
|
39
|
+
const green = (hexNumber >> 8) & 255;
|
|
40
|
+
const blue = hexNumber & 255;
|
|
41
|
+
return `rgb(${red}, ${green}, ${blue})`;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const hueNeutral50Rgb = hexToRgb(Tokens.HueNeutral50);
|
|
45
|
+
|
|
46
|
+
export const isTransparentColor = (color: string) =>
|
|
47
|
+
color === "rgba(0, 0, 0, 0)" || color === "transparent";
|
|
48
|
+
|
|
49
|
+
export const normalizeRgbaToRgb = (rgba: string) =>
|
|
50
|
+
rgba.replace(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/, "rgb($1, $2, $3)");
|
|
51
|
+
|
|
52
|
+
export const getElementComputedBackgroundColor = (
|
|
53
|
+
element: HTMLElement,
|
|
54
|
+
): string => window.getComputedStyle(element).backgroundColor;
|
|
55
|
+
|
|
56
|
+
export const normalizeBackgroundColor = (bgColor: string): string => {
|
|
57
|
+
if (/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/.test(bgColor)) {
|
|
58
|
+
const normalizedColor = normalizeRgbaToRgb(bgColor);
|
|
59
|
+
return normalizedColor === hueNeutral50Rgb
|
|
60
|
+
? Tokens.HueNeutral50
|
|
61
|
+
: normalizedColor;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return bgColor === hueNeutral50Rgb ? Tokens.HueNeutral50 : bgColor;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const defaultParentBackgroundColor = "#ffffff";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Determines the effective background color of an element.
|
|
71
|
+
*
|
|
72
|
+
* @param element - The HTML element to check.
|
|
73
|
+
* @returns The effective background color. Returns defaultParentBackgroundColor if no non-transparent background is found.
|
|
74
|
+
*
|
|
75
|
+
* Note:
|
|
76
|
+
* - Low contrast mode is used for white background (defaultParentBackgroundColor or HueNeutralWhite).
|
|
77
|
+
* - High contrast mode is used for gray background (#f4f4f4 or HueNeutral50).
|
|
78
|
+
*/
|
|
79
|
+
export const getBackgroundColor = (element: HTMLElement | null): string => {
|
|
80
|
+
while (element) {
|
|
81
|
+
const bgColor = getElementComputedBackgroundColor(element);
|
|
82
|
+
if (!isTransparentColor(bgColor)) {
|
|
83
|
+
return normalizeBackgroundColor(bgColor);
|
|
84
|
+
}
|
|
85
|
+
element = element.parentElement;
|
|
86
|
+
}
|
|
87
|
+
return defaultParentBackgroundColor; // Default to white/low contrast if no background color is found
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
type UseContrastModeProps = {
|
|
91
|
+
contrastMode?: ContrastMode;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const useContrastMode = ({
|
|
95
|
+
contrastMode: explicitContrastMode,
|
|
96
|
+
}: UseContrastModeProps) => {
|
|
97
|
+
const contrastContainerRef = useRef<HTMLDivElement>(null);
|
|
98
|
+
const { contrastMode: existingContrastMode } = useContrastModeContext();
|
|
99
|
+
|
|
100
|
+
const [parentBackgroundColor, setParentBackgroundColor] = useState(
|
|
101
|
+
defaultParentBackgroundColor,
|
|
102
|
+
);
|
|
103
|
+
const [contrastMode, setContrastMode] = useState<ContrastMode>(
|
|
104
|
+
() => explicitContrastMode || existingContrastMode,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const updateBackgroundColor = useCallback(() => {
|
|
108
|
+
const newBgColor = getBackgroundColor(contrastContainerRef.current);
|
|
109
|
+
setParentBackgroundColor(newBgColor);
|
|
110
|
+
|
|
111
|
+
if (!explicitContrastMode) {
|
|
112
|
+
setContrastMode(
|
|
113
|
+
newBgColor === Tokens.HueNeutral50 ? "highContrast" : "lowContrast",
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}, [explicitContrastMode]);
|
|
117
|
+
|
|
118
|
+
useLayoutEffect(() => {
|
|
119
|
+
const observer = new MutationObserver(updateBackgroundColor);
|
|
120
|
+
observer.observe(document.querySelector("html") as HTMLHtmlElement, {
|
|
121
|
+
attributes: true,
|
|
122
|
+
attributeFilter: ["class", "style"],
|
|
123
|
+
});
|
|
124
|
+
observer.observe(document.head, {
|
|
125
|
+
childList: true,
|
|
126
|
+
subtree: true,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const onTransitionEnd = (event: TransitionEvent) => {
|
|
130
|
+
if (event.propertyName === "background-color") {
|
|
131
|
+
updateBackgroundColor();
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
document.addEventListener("transitionend", onTransitionEnd);
|
|
136
|
+
updateBackgroundColor();
|
|
137
|
+
|
|
138
|
+
return () => {
|
|
139
|
+
document.removeEventListener("transitionend", onTransitionEnd);
|
|
140
|
+
observer.disconnect();
|
|
141
|
+
};
|
|
142
|
+
}, [updateBackgroundColor]);
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
contrastContainerRef,
|
|
146
|
+
contrastMode,
|
|
147
|
+
parentBackgroundColor,
|
|
148
|
+
};
|
|
149
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
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 * from "./renderReactInWebComponent";
|
|
14
|
+
export * from "./shadow-dom";
|
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
import { waitFor } from "@testing-library/dom";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
createReactRootElements,
|
|
17
|
+
ReactInWebComponentElement,
|
|
18
|
+
reactWebComponentElementName,
|
|
19
|
+
renderReactInWebComponent,
|
|
20
|
+
} from "./renderReactInWebComponent";
|
|
21
|
+
|
|
22
|
+
describe("createReactRootElements", () => {
|
|
23
|
+
test("returns two elements at attach to a Shadow DOM", () => {
|
|
24
|
+
const { appRootElement, stylesRootElement } = createReactRootElements();
|
|
25
|
+
|
|
26
|
+
expect(appRootElement).toBeInstanceOf(HTMLDivElement);
|
|
27
|
+
expect(stylesRootElement).toBeInstanceOf(HTMLDivElement);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("App root element has the correct attributes", () => {
|
|
31
|
+
const { appRootElement } = createReactRootElements();
|
|
32
|
+
|
|
33
|
+
expect(appRootElement).toHaveAttribute("id", "app-root");
|
|
34
|
+
expect(appRootElement).toHaveAttribute("style", "height: inherit;");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("Emotion root element has the correct attributes", () => {
|
|
38
|
+
const nonce = "hello-world";
|
|
39
|
+
|
|
40
|
+
window.cspNonce = nonce;
|
|
41
|
+
|
|
42
|
+
const { stylesRootElement } = createReactRootElements();
|
|
43
|
+
|
|
44
|
+
expect(stylesRootElement).toHaveAttribute("id", "style-root");
|
|
45
|
+
expect(stylesRootElement).toHaveAttribute("nonce", nonce);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("renderReactInWebComponent", () => {
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
// Remove any appended elements
|
|
52
|
+
document.body.innerHTML = "";
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("returns web component element", async () => {
|
|
56
|
+
const rootElement = document.createElement("div");
|
|
57
|
+
const testElementText = "I'm a test component!";
|
|
58
|
+
|
|
59
|
+
// If this isn't appended to the DOM, the React app won't exist because of how Web Components run.
|
|
60
|
+
document.body.append(rootElement);
|
|
61
|
+
|
|
62
|
+
const reactInWebComponentElement = renderReactInWebComponent({
|
|
63
|
+
getReactComponent: () => <div>{testElementText}</div>,
|
|
64
|
+
webComponentRootElement: rootElement,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await waitFor(() => {
|
|
68
|
+
expect(reactInWebComponentElement).toBeInstanceOf(
|
|
69
|
+
ReactInWebComponentElement,
|
|
70
|
+
);
|
|
71
|
+
expect(reactInWebComponentElement.shadowRoot).toBeInstanceOf(ShadowRoot);
|
|
72
|
+
expect(reactInWebComponentElement).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("renders a React app into a web component", async () => {
|
|
77
|
+
const rootElement = document.createElement("div");
|
|
78
|
+
const testElementText = "I'm a test component!";
|
|
79
|
+
|
|
80
|
+
// If this isn't appended to the DOM, the React app won't exist because of how Web Components run.
|
|
81
|
+
document.body.append(rootElement);
|
|
82
|
+
|
|
83
|
+
const reactInWebComponentElement = renderReactInWebComponent({
|
|
84
|
+
getReactComponent: () => <div>{testElementText}</div>,
|
|
85
|
+
webComponentRootElement: rootElement,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await waitFor(() => {
|
|
89
|
+
expect(reactInWebComponentElement!.shadowRoot).toHaveTextContent(
|
|
90
|
+
testElementText,
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("renders 2 React apps without erroring", () => {
|
|
96
|
+
const rootElement = document.createElement("div");
|
|
97
|
+
|
|
98
|
+
// If this isn't appended to the DOM, the React app won't exist because of how Web Components run.
|
|
99
|
+
document.body.append(rootElement);
|
|
100
|
+
|
|
101
|
+
renderReactInWebComponent({
|
|
102
|
+
getReactComponent: () => <div />,
|
|
103
|
+
webComponentRootElement: rootElement,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
renderReactInWebComponent({
|
|
107
|
+
getReactComponent: () => <div />,
|
|
108
|
+
webComponentRootElement: rootElement,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(
|
|
112
|
+
document.querySelectorAll(reactWebComponentElementName),
|
|
113
|
+
).toHaveLength(2);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("renders a single element as children of the web component", () => {
|
|
117
|
+
const rootElement = document.createElement("div");
|
|
118
|
+
const webComponentChildren = document.createElement("div");
|
|
119
|
+
|
|
120
|
+
webComponentChildren.setAttribute("slot", "app");
|
|
121
|
+
|
|
122
|
+
// If this isn't appended to the DOM, the React app won't exist because of how Web Components run.
|
|
123
|
+
document.body.append(rootElement);
|
|
124
|
+
|
|
125
|
+
renderReactInWebComponent({
|
|
126
|
+
getReactComponent: () => <div />,
|
|
127
|
+
webComponentRootElement: rootElement,
|
|
128
|
+
webComponentChildren,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(document.querySelector("[slot=app]")).toBe(webComponentChildren);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("renders multiple elements as children of the web component", () => {
|
|
135
|
+
const rootElement = document.createElement("div");
|
|
136
|
+
const webComponentChild1 = document.createElement("div");
|
|
137
|
+
const webComponentChild2 = document.createElement("div");
|
|
138
|
+
|
|
139
|
+
const webComponentChildren = [webComponentChild1, webComponentChild2];
|
|
140
|
+
|
|
141
|
+
webComponentChild1.setAttribute("slot", "app");
|
|
142
|
+
webComponentChild2.setAttribute("slot", "footer");
|
|
143
|
+
|
|
144
|
+
// If this isn't appended to the DOM, the React app won't exist because of how Web Components run.
|
|
145
|
+
document.body.append(rootElement);
|
|
146
|
+
|
|
147
|
+
renderReactInWebComponent({
|
|
148
|
+
getReactComponent: () => <div />,
|
|
149
|
+
webComponentRootElement: rootElement,
|
|
150
|
+
webComponentChildren,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
expect(document.querySelector("[slot=app]")).toBe(webComponentChild1);
|
|
154
|
+
expect(document.querySelector("[slot=footer]")).toBe(webComponentChild2);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
import { type ReactNode } from "react";
|
|
14
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Creates elements for a Shadow DOM that Odyssey will render into.
|
|
18
|
+
* The Emotion root is for `<style>` tags and the app root is for an app to render into.
|
|
19
|
+
* These are bare elements that
|
|
20
|
+
*/
|
|
21
|
+
export const createReactRootElements = () => {
|
|
22
|
+
const appRootElement = document.createElement("div");
|
|
23
|
+
const stylesRootElement = document.createElement("div");
|
|
24
|
+
|
|
25
|
+
// This `div` may cause layout issues unless it inherits the parent's height.
|
|
26
|
+
appRootElement.style.setProperty("height", "inherit");
|
|
27
|
+
|
|
28
|
+
appRootElement.setAttribute("id", "app-root");
|
|
29
|
+
stylesRootElement.setAttribute("id", "style-root");
|
|
30
|
+
stylesRootElement.setAttribute("nonce", window.cspNonce);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
/**
|
|
34
|
+
* The element your React root component renders into.
|
|
35
|
+
* React has to render or portal somewhere, and this element can be used for that root element.
|
|
36
|
+
*
|
|
37
|
+
* In the case of a web component, there is no defined root element, so you have to define it yourself.
|
|
38
|
+
*/
|
|
39
|
+
appRootElement,
|
|
40
|
+
/**
|
|
41
|
+
* In React apps, your styles typically go in `document.head`, but you may want to render them somewhere else.
|
|
42
|
+
*
|
|
43
|
+
* Specifically when rendering in a web component, there is no `<head>`, so you have to create a spot for styles to render.
|
|
44
|
+
*/
|
|
45
|
+
stylesRootElement,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type ReactRootElements = ReturnType<typeof createReactRootElements>;
|
|
50
|
+
|
|
51
|
+
export const reactWebComponentElementName = "odyssey-react-web-component";
|
|
52
|
+
|
|
53
|
+
export type GetReactComponentInWebComponent = (
|
|
54
|
+
reactRootElements: ReactRootElements,
|
|
55
|
+
) => ReactNode;
|
|
56
|
+
|
|
57
|
+
export class ReactInWebComponentElement extends HTMLElement {
|
|
58
|
+
getReactComponent: GetReactComponentInWebComponent;
|
|
59
|
+
reactRoot: Root;
|
|
60
|
+
reactRootElements: ReactRootElements;
|
|
61
|
+
|
|
62
|
+
constructor(getReactComponent: GetReactComponentInWebComponent) {
|
|
63
|
+
super();
|
|
64
|
+
|
|
65
|
+
this.getReactComponent = getReactComponent;
|
|
66
|
+
this.reactRootElements = createReactRootElements();
|
|
67
|
+
|
|
68
|
+
const styleElement = document.createElement("style");
|
|
69
|
+
const shadowRoot = this.attachShadow({ mode: "open" });
|
|
70
|
+
|
|
71
|
+
styleElement.innerHTML = `
|
|
72
|
+
:host {
|
|
73
|
+
all: initial;
|
|
74
|
+
contain: content;
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
styleElement.setAttribute("nonce", window.cspNonce);
|
|
79
|
+
|
|
80
|
+
this.reactRootElements.stylesRootElement.appendChild(styleElement);
|
|
81
|
+
shadowRoot.appendChild(this.reactRootElements.stylesRootElement);
|
|
82
|
+
shadowRoot.appendChild(this.reactRootElements.appRootElement);
|
|
83
|
+
|
|
84
|
+
this.reactRoot = createRoot(this.reactRootElements.appRootElement);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
connectedCallback() {
|
|
88
|
+
this.reactRoot.render(this.getReactComponent(this.reactRootElements));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
disconnectedCallback() {
|
|
92
|
+
this.reactRoot.unmount();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!customElements.get(reactWebComponentElementName)) {
|
|
97
|
+
customElements.define(
|
|
98
|
+
reactWebComponentElementName,
|
|
99
|
+
ReactInWebComponentElement,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export type RenderReactInWebComponentProps = {
|
|
104
|
+
/**
|
|
105
|
+
* This is a callback function for rendering your React component or app in the Web Component.
|
|
106
|
+
* It gives you access to the Shadow DOM elements if you need them for Odyssey, Emotion, or MUI.
|
|
107
|
+
*
|
|
108
|
+
* You will need to add `<slot>` elements if you want to pass child elements or components or React apps.
|
|
109
|
+
* You can have multiple slots in your app if you add a `name` attribute to your `<slot>` elements.
|
|
110
|
+
*/
|
|
111
|
+
getReactComponent: GetReactComponentInWebComponent;
|
|
112
|
+
/**
|
|
113
|
+
* One or more HTML elements that are going to render as `children` of the web component.
|
|
114
|
+
* If your React component doesn't take children, this is unnecessary.
|
|
115
|
+
*
|
|
116
|
+
* Typically, a React app root element is passed, but it can include an array of other elements if there are multiple slots for children.
|
|
117
|
+
*
|
|
118
|
+
* You will need to have rendered `<slot>` elements in your React component or `children` won't show up.
|
|
119
|
+
*/
|
|
120
|
+
webComponentChildren?: HTMLElement | HTMLElement[];
|
|
121
|
+
/**
|
|
122
|
+
* You React app renders in the web component, but the web component needs to be rendered in the document.
|
|
123
|
+
*
|
|
124
|
+
* This is the element the web component is rendered into.
|
|
125
|
+
*/
|
|
126
|
+
webComponentRootElement: HTMLElement;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Lets you render React apps or components in a Web Component.
|
|
131
|
+
*
|
|
132
|
+
* This is useful when global styles are causing conflicts with your React components.
|
|
133
|
+
*/
|
|
134
|
+
export const renderReactInWebComponent = ({
|
|
135
|
+
getReactComponent,
|
|
136
|
+
webComponentChildren,
|
|
137
|
+
webComponentRootElement,
|
|
138
|
+
}: RenderReactInWebComponentProps) => {
|
|
139
|
+
const reactElement = new ReactInWebComponentElement(getReactComponent);
|
|
140
|
+
|
|
141
|
+
if (webComponentChildren) {
|
|
142
|
+
(Array.isArray(webComponentChildren)
|
|
143
|
+
? webComponentChildren
|
|
144
|
+
: [webComponentChildren]
|
|
145
|
+
).forEach((webComponentChild) => {
|
|
146
|
+
reactElement.appendChild(webComponentChild);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
webComponentRootElement.appendChild(reactElement);
|
|
151
|
+
|
|
152
|
+
return reactElement;
|
|
153
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
import { createShadowDomElements } from "./shadow-dom";
|
|
14
|
+
|
|
15
|
+
describe("createShadowDomElements", () => {
|
|
16
|
+
test("returns two elements attached to a Shadow DOM", () => {
|
|
17
|
+
const { emotionRootElement, shadowRootElement } = createShadowDomElements(
|
|
18
|
+
document.createElement("div"),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(emotionRootElement.parentNode).toBeInstanceOf(ShadowRoot);
|
|
22
|
+
expect(shadowRootElement.parentNode).toBeInstanceOf(ShadowRoot);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -10,28 +10,29 @@
|
|
|
10
10
|
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { createReactRootElements } from "./renderReactInWebComponent";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use `renderReactInWebComponent` instead. This function was necessary when using bare Shadow DOM, but with UI Shell rendering in a Web Component, you won't be able to render your Shadow DOM in its Shadow DOM without using a Web Component.
|
|
17
|
+
*/
|
|
13
18
|
export const createShadowDomElements = (containerElement: HTMLElement) => {
|
|
14
19
|
const shadowRoot = containerElement.attachShadow({ mode: "open" });
|
|
15
20
|
|
|
16
21
|
// Container for Emotion `<style>` elements.
|
|
17
|
-
const
|
|
18
|
-
emotionRootElement.setAttribute("id", "style-root");
|
|
19
|
-
emotionRootElement.setAttribute("nonce", window.cspNonce);
|
|
22
|
+
const { appRootElement, stylesRootElement } = createReactRootElements();
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
shadowRootElement.setAttribute("id", "shadow-root");
|
|
24
|
-
// This div could cause issues with layout of children.
|
|
25
|
-
// For flexibility, make it inherit its parent's height
|
|
26
|
-
shadowRootElement.style.setProperty("height", "inherit");
|
|
27
|
-
|
|
28
|
-
shadowRoot.appendChild(emotionRootElement);
|
|
29
|
-
shadowRoot.appendChild(shadowRootElement);
|
|
24
|
+
shadowRoot.appendChild(appRootElement);
|
|
25
|
+
shadowRoot.appendChild(stylesRootElement);
|
|
30
26
|
|
|
31
|
-
return {
|
|
27
|
+
return {
|
|
28
|
+
emotionRootElement: stylesRootElement,
|
|
29
|
+
shadowRootElement: appRootElement,
|
|
30
|
+
};
|
|
32
31
|
};
|
|
33
32
|
|
|
34
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Use `createShadowDomElements` instead which returns an object instead of an array. It's otherwise the same.
|
|
35
|
+
* @deprecated Ideally, use `renderReactInWebComponent` instead. This function was necessary when using bare Shadow DOM, but with UI Shell rendering in a Web Component, you won't be able to render your Shadow DOM in its Shadow DOM without using a Web Component. */
|
|
35
36
|
export const createShadowRootElement = (
|
|
36
37
|
containerElement: HTMLElement,
|
|
37
38
|
): [HTMLStyleElement, HTMLDivElement] => {
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2023-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 React, { createContext, useContext, useRef, useLayoutEffect, useState, useMemo } from "react";
|
|
14
|
-
import { createTheme, ThemeProvider, useTheme } from "@mui/material/styles";
|
|
15
|
-
import * as Tokens from "@okta/odyssey-design-tokens";
|
|
16
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
-
const ContrastModeContext = createContext({
|
|
18
|
-
contrastMode: "highContrast",
|
|
19
|
-
parentBackgroundColor: ""
|
|
20
|
-
});
|
|
21
|
-
export const useContrastContext = () => useContext(ContrastModeContext);
|
|
22
|
-
const hexToRgb = hex => {
|
|
23
|
-
const bigint = parseInt(hex.slice(1), 16);
|
|
24
|
-
const r = bigint >> 16 & 255;
|
|
25
|
-
const g = bigint >> 8 & 255;
|
|
26
|
-
const b = bigint & 255;
|
|
27
|
-
return `rgb(${r}, ${g}, ${b})`;
|
|
28
|
-
};
|
|
29
|
-
export const useParentBackgroundColor = ref => {
|
|
30
|
-
const [backgroundColor, setBackgroundColor] = useState("");
|
|
31
|
-
const hueNeutral50Rgb = useMemo(() => hexToRgb(Tokens.HueNeutral50), []);
|
|
32
|
-
useLayoutEffect(() => {
|
|
33
|
-
if (ref.current) {
|
|
34
|
-
let element = ref.current;
|
|
35
|
-
while (element) {
|
|
36
|
-
const bgColor = window.getComputedStyle(element).backgroundColor;
|
|
37
|
-
if (bgColor !== "rgba(0, 0, 0, 0)" && bgColor !== "transparent") {
|
|
38
|
-
if (bgColor === hueNeutral50Rgb) {
|
|
39
|
-
setBackgroundColor(Tokens.HueNeutral50);
|
|
40
|
-
} else {
|
|
41
|
-
setBackgroundColor(bgColor);
|
|
42
|
-
}
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
element = element.parentElement;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}, [ref, hueNeutral50Rgb]);
|
|
49
|
-
return backgroundColor;
|
|
50
|
-
};
|
|
51
|
-
export const ContrastModeProvider = ({
|
|
52
|
-
children,
|
|
53
|
-
contrastMode: explicitContrastMode
|
|
54
|
-
}) => {
|
|
55
|
-
const ref = useRef(null);
|
|
56
|
-
const parentBackgroundColor = useParentBackgroundColor(ref);
|
|
57
|
-
const [contrastMode, setContrastMode] = useState("highContrast");
|
|
58
|
-
useLayoutEffect(() => {
|
|
59
|
-
if (explicitContrastMode) {
|
|
60
|
-
setContrastMode(explicitContrastMode);
|
|
61
|
-
} else {
|
|
62
|
-
const isLowContrast = parentBackgroundColor === Tokens.HueNeutral50;
|
|
63
|
-
setContrastMode(isLowContrast ? "lowContrast" : "highContrast");
|
|
64
|
-
}
|
|
65
|
-
}, [parentBackgroundColor, explicitContrastMode]);
|
|
66
|
-
const contextValue = useMemo(() => ({
|
|
67
|
-
contrastMode,
|
|
68
|
-
parentBackgroundColor
|
|
69
|
-
}), [contrastMode, parentBackgroundColor]);
|
|
70
|
-
const existingTheme = useTheme();
|
|
71
|
-
const theme = useMemo(() => createTheme({
|
|
72
|
-
...existingTheme,
|
|
73
|
-
odysseyContrastMode: contrastMode
|
|
74
|
-
}), [existingTheme, contrastMode]);
|
|
75
|
-
return _jsx("div", {
|
|
76
|
-
ref: ref,
|
|
77
|
-
children: _jsx(ContrastModeContext.Provider, {
|
|
78
|
-
value: contextValue,
|
|
79
|
-
children: _jsx(ThemeProvider, {
|
|
80
|
-
theme: theme,
|
|
81
|
-
children: children
|
|
82
|
-
})
|
|
83
|
-
})
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
|
-
//# sourceMappingURL=ContrastModeProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ContrastModeProvider.js","names":["React","createContext","useContext","useRef","useLayoutEffect","useState","useMemo","createTheme","ThemeProvider","useTheme","Tokens","jsx","_jsx","ContrastModeContext","contrastMode","parentBackgroundColor","useContrastContext","hexToRgb","hex","bigint","parseInt","slice","r","g","b","useParentBackgroundColor","ref","backgroundColor","setBackgroundColor","hueNeutral50Rgb","HueNeutral50","current","element","bgColor","window","getComputedStyle","parentElement","ContrastModeProvider","children","explicitContrastMode","setContrastMode","isLowContrast","contextValue","existingTheme","theme","odysseyContrastMode","Provider","value"],"sources":["../src/ContrastModeProvider.tsx"],"sourcesContent":["/*!\n * Copyright (c) 2023-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 React, {\n createContext,\n useContext,\n useRef,\n useLayoutEffect,\n useState,\n useMemo,\n ReactNode,\n} from \"react\";\nimport { createTheme, ThemeProvider, useTheme } from \"@mui/material/styles\";\nimport * as Tokens from \"@okta/odyssey-design-tokens\";\n\ndeclare module \"@mui/material/styles\" {\n interface Theme {\n odysseyContrastMode: ContrastMode;\n }\n interface ThemeOptions {\n odysseyContrastMode?: ContrastMode;\n }\n}\n\nexport type ContrastMode = \"lowContrast\" | \"highContrast\";\n\nexport type ContrastModeContextType = {\n contrastMode: ContrastMode;\n parentBackgroundColor: string;\n};\n\nconst ContrastModeContext = createContext<ContrastModeContextType>({\n contrastMode: \"highContrast\",\n parentBackgroundColor: \"\",\n});\n\nexport const useContrastContext = () => useContext(ContrastModeContext);\n\nconst hexToRgb = (hex: string): string => {\n const bigint = parseInt(hex.slice(1), 16);\n const r = (bigint >> 16) & 255;\n const g = (bigint >> 8) & 255;\n const b = bigint & 255;\n return `rgb(${r}, ${g}, ${b})`;\n};\n\nexport const useParentBackgroundColor = (ref: React.RefObject<HTMLElement>) => {\n const [backgroundColor, setBackgroundColor] = useState(\"\");\n\n const hueNeutral50Rgb = useMemo(() => hexToRgb(Tokens.HueNeutral50), []);\n\n useLayoutEffect(() => {\n if (ref.current) {\n let element: HTMLElement | null = ref.current;\n while (element) {\n const bgColor = window.getComputedStyle(element).backgroundColor;\n\n if (bgColor !== \"rgba(0, 0, 0, 0)\" && bgColor !== \"transparent\") {\n if (bgColor === hueNeutral50Rgb) {\n setBackgroundColor(Tokens.HueNeutral50);\n } else {\n setBackgroundColor(bgColor);\n }\n break;\n }\n element = element.parentElement;\n }\n }\n }, [ref, hueNeutral50Rgb]);\n\n return backgroundColor;\n};\n\ntype ContrastModeProviderProps = {\n children: ReactNode;\n contrastMode?: ContrastMode;\n};\n\nexport const ContrastModeProvider = ({\n children,\n contrastMode: explicitContrastMode,\n}: ContrastModeProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const parentBackgroundColor = useParentBackgroundColor(ref);\n const [contrastMode, setContrastMode] =\n useState<ContrastMode>(\"highContrast\");\n\n useLayoutEffect(() => {\n if (explicitContrastMode) {\n setContrastMode(explicitContrastMode);\n } else {\n const isLowContrast = parentBackgroundColor === Tokens.HueNeutral50;\n setContrastMode(isLowContrast ? \"lowContrast\" : \"highContrast\");\n }\n }, [parentBackgroundColor, explicitContrastMode]);\n\n const contextValue = useMemo<ContrastModeContextType>(\n () => ({\n contrastMode,\n parentBackgroundColor,\n }),\n [contrastMode, parentBackgroundColor],\n );\n\n const existingTheme = useTheme();\n const theme = useMemo(\n () =>\n createTheme({\n ...existingTheme,\n odysseyContrastMode: contrastMode,\n }),\n [existingTheme, contrastMode],\n );\n\n return (\n <div ref={ref}>\n <ContrastModeContext.Provider value={contextValue}>\n <ThemeProvider theme={theme}>{children}</ThemeProvider>\n </ContrastModeContext.Provider>\n </div>\n );\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,KAAK,IACVC,aAAa,EACbC,UAAU,EACVC,MAAM,EACNC,eAAe,EACfC,QAAQ,EACRC,OAAO,QAEF,OAAO;AACd,SAASC,WAAW,EAAEC,aAAa,EAAEC,QAAQ,QAAQ,sBAAsB;AAC3E,OAAO,KAAKC,MAAM,MAAM,6BAA6B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAkBtD,MAAMC,mBAAmB,GAAGZ,aAAa,CAA0B;EACjEa,YAAY,EAAE,cAAc;EAC5BC,qBAAqB,EAAE;AACzB,CAAC,CAAC;AAEF,OAAO,MAAMC,kBAAkB,GAAGA,CAAA,KAAMd,UAAU,CAACW,mBAAmB,CAAC;AAEvE,MAAMI,QAAQ,GAAIC,GAAW,IAAa;EACxC,MAAMC,MAAM,GAAGC,QAAQ,CAACF,GAAG,CAACG,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;EACzC,MAAMC,CAAC,GAAIH,MAAM,IAAI,EAAE,GAAI,GAAG;EAC9B,MAAMI,CAAC,GAAIJ,MAAM,IAAI,CAAC,GAAI,GAAG;EAC7B,MAAMK,CAAC,GAAGL,MAAM,GAAG,GAAG;EACtB,OAAQ,OAAMG,CAAE,KAAIC,CAAE,KAAIC,CAAE,GAAE;AAChC,CAAC;AAED,OAAO,MAAMC,wBAAwB,GAAIC,GAAiC,IAAK;EAC7E,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGvB,QAAQ,CAAC,EAAE,CAAC;EAE1D,MAAMwB,eAAe,GAAGvB,OAAO,CAAC,MAAMW,QAAQ,CAACP,MAAM,CAACoB,YAAY,CAAC,EAAE,EAAE,CAAC;EAExE1B,eAAe,CAAC,MAAM;IACpB,IAAIsB,GAAG,CAACK,OAAO,EAAE;MACf,IAAIC,OAA2B,GAAGN,GAAG,CAACK,OAAO;MAC7C,OAAOC,OAAO,EAAE;QACd,MAAMC,OAAO,GAAGC,MAAM,CAACC,gBAAgB,CAACH,OAAO,CAAC,CAACL,eAAe;QAEhE,IAAIM,OAAO,KAAK,kBAAkB,IAAIA,OAAO,KAAK,aAAa,EAAE;UAC/D,IAAIA,OAAO,KAAKJ,eAAe,EAAE;YAC/BD,kBAAkB,CAAClB,MAAM,CAACoB,YAAY,CAAC;UACzC,CAAC,MAAM;YACLF,kBAAkB,CAACK,OAAO,CAAC;UAC7B;UACA;QACF;QACAD,OAAO,GAAGA,OAAO,CAACI,aAAa;MACjC;IACF;EACF,CAAC,EAAE,CAACV,GAAG,EAAEG,eAAe,CAAC,CAAC;EAE1B,OAAOF,eAAe;AACxB,CAAC;AAOD,OAAO,MAAMU,oBAAoB,GAAGA,CAAC;EACnCC,QAAQ;EACRxB,YAAY,EAAEyB;AACW,CAAC,KAAK;EAC/B,MAAMb,GAAG,GAAGvB,MAAM,CAAiB,IAAI,CAAC;EACxC,MAAMY,qBAAqB,GAAGU,wBAAwB,CAACC,GAAG,CAAC;EAC3D,MAAM,CAACZ,YAAY,EAAE0B,eAAe,CAAC,GACnCnC,QAAQ,CAAe,cAAc,CAAC;EAExCD,eAAe,CAAC,MAAM;IACpB,IAAImC,oBAAoB,EAAE;MACxBC,eAAe,CAACD,oBAAoB,CAAC;IACvC,CAAC,MAAM;MACL,MAAME,aAAa,GAAG1B,qBAAqB,KAAKL,MAAM,CAACoB,YAAY;MACnEU,eAAe,CAACC,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC;IACjE;EACF,CAAC,EAAE,CAAC1B,qBAAqB,EAAEwB,oBAAoB,CAAC,CAAC;EAEjD,MAAMG,YAAY,GAAGpC,OAAO,CAC1B,OAAO;IACLQ,YAAY;IACZC;EACF,CAAC,CAAC,EACF,CAACD,YAAY,EAAEC,qBAAqB,CACtC,CAAC;EAED,MAAM4B,aAAa,GAAGlC,QAAQ,CAAC,CAAC;EAChC,MAAMmC,KAAK,GAAGtC,OAAO,CACnB,MACEC,WAAW,CAAC;IACV,GAAGoC,aAAa;IAChBE,mBAAmB,EAAE/B;EACvB,CAAC,CAAC,EACJ,CAAC6B,aAAa,EAAE7B,YAAY,CAC9B,CAAC;EAED,OACEF,IAAA;IAAKc,GAAG,EAAEA,GAAI;IAAAY,QAAA,EACZ1B,IAAA,CAACC,mBAAmB,CAACiC,QAAQ;MAACC,KAAK,EAAEL,YAAa;MAAAJ,QAAA,EAChD1B,IAAA,CAACJ,aAAa;QAACoC,KAAK,EAAEA,KAAM;QAAAN,QAAA,EAAEA;MAAQ,CAAgB;IAAC,CAC3B;EAAC,CAC5B,CAAC;AAEV,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createShadowDomElements.js","names":["createShadowDomElements","containerElement","shadowRoot","attachShadow","mode","emotionRootElement","document","createElement","setAttribute","window","cspNonce","shadowRootElement","style","setProperty","appendChild","createShadowRootElement"],"sources":["../src/createShadowDomElements.ts"],"sourcesContent":["/*!\n * Copyright (c) 2023-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\nexport const createShadowDomElements = (containerElement: HTMLElement) => {\n const shadowRoot = containerElement.attachShadow({ mode: \"open\" });\n\n // Container for Emotion `<style>` elements.\n const emotionRootElement = document.createElement(\"div\");\n emotionRootElement.setAttribute(\"id\", \"style-root\");\n emotionRootElement.setAttribute(\"nonce\", window.cspNonce);\n\n // React app root component.\n const shadowRootElement = document.createElement(\"div\");\n shadowRootElement.setAttribute(\"id\", \"shadow-root\");\n // This div could cause issues with layout of children.\n // For flexibility, make it inherit its parent's height\n shadowRootElement.style.setProperty(\"height\", \"inherit\");\n\n shadowRoot.appendChild(emotionRootElement);\n shadowRoot.appendChild(shadowRootElement);\n\n return { emotionRootElement, shadowRootElement };\n};\n\n/** @deprecated Use `createShadowDomElements` instead. */\nexport const createShadowRootElement = (\n containerElement: HTMLElement,\n): [HTMLStyleElement, HTMLDivElement] => {\n const shadowRoot = containerElement.attachShadow({ mode: \"open\" });\n\n // the element that styles will be cached into\n const emotionRootElement = document.createElement(\"style\");\n emotionRootElement.setAttribute(\"id\", \"style-root\");\n emotionRootElement.setAttribute(\"nonce\", window.cspNonce);\n\n // the element that emotion renders html into\n const shadowRootElement = document.createElement(\"div\");\n shadowRootElement.setAttribute(\"id\", \"shadow-root\");\n\n shadowRoot.appendChild(emotionRootElement);\n shadowRoot.appendChild(shadowRootElement);\n\n return [emotionRootElement, shadowRootElement];\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,MAAMA,uBAAuB,GAAIC,gBAA6B,IAAK;EACxE,MAAMC,UAAU,GAAGD,gBAAgB,CAACE,YAAY,CAAC;IAAEC,IAAI,EAAE;EAAO,CAAC,CAAC;EAGlE,MAAMC,kBAAkB,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;EACxDF,kBAAkB,CAACG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC;EACnDH,kBAAkB,CAACG,YAAY,CAAC,OAAO,EAAEC,MAAM,CAACC,QAAQ,CAAC;EAGzD,MAAMC,iBAAiB,GAAGL,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;EACvDI,iBAAiB,CAACH,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC;EAGnDG,iBAAiB,CAACC,KAAK,CAACC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC;EAExDX,UAAU,CAACY,WAAW,CAACT,kBAAkB,CAAC;EAC1CH,UAAU,CAACY,WAAW,CAACH,iBAAiB,CAAC;EAEzC,OAAO;IAAEN,kBAAkB;IAAEM;EAAkB,CAAC;AAClD,CAAC;AAGD,OAAO,MAAMI,uBAAuB,GAClCd,gBAA6B,IACU;EACvC,MAAMC,UAAU,GAAGD,gBAAgB,CAACE,YAAY,CAAC;IAAEC,IAAI,EAAE;EAAO,CAAC,CAAC;EAGlE,MAAMC,kBAAkB,GAAGC,QAAQ,CAACC,aAAa,CAAC,OAAO,CAAC;EAC1DF,kBAAkB,CAACG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC;EACnDH,kBAAkB,CAACG,YAAY,CAAC,OAAO,EAAEC,MAAM,CAACC,QAAQ,CAAC;EAGzD,MAAMC,iBAAiB,GAAGL,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;EACvDI,iBAAiB,CAACH,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC;EAEnDN,UAAU,CAACY,WAAW,CAACT,kBAAkB,CAAC;EAC1CH,UAAU,CAACY,WAAW,CAACH,iBAAiB,CAAC;EAEzC,OAAO,CAACN,kBAAkB,EAAEM,iBAAiB,CAAC;AAChD,CAAC"}
|