@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
81 lines (80 loc) • 3.67 kB
JavaScript
'use client';
import { getTheme } from '@ui5/webcomponents-base/dist/config/Theme.js';
import { getScopedVarName } from '@ui5/webcomponents-base/dist/CustomElementsScope.js';
import { attachLanguageChange, detachLanguageChange } from '@ui5/webcomponents-base/dist/locale/languageChange.js';
import { attachThemeLoaded, detachThemeLoaded } from '@ui5/webcomponents-base/dist/theming/ThemeLoaded.js';
import { I18nStore, StyleStore, useIsomorphicLayoutEffect, useStylesheet } from '@ui5/webcomponents-react-base';
import { useEffect, useId } from 'react';
import VersionInfo from '../../generated/VersionInfo.js';
import { styleData } from './ThemeProvider.css.js';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
let _versionInfoInjected = false;
function ThemeProviderStyles() {
const uniqueId = useId();
useStylesheet(styleData, `${ThemeProvider.displayName}-${uniqueId}`);
useStylesheet(ui5WcVariablesStyleData, `${ThemeProvider.displayName}-css-vars-${uniqueId}`);
return null;
}
const InternalUI5WCVVarNames = {
'--_ui5wcr_card_header_focus_offset': `var(${getScopedVarName('--_ui5_card_header_focus_offset')})`,
'--_ui5wcr_card_header_focus_border': `var(${getScopedVarName('--_ui5_card_header_focus_border')})`,
'--_ui5wcr_card_header_focus_radius': `var(${getScopedVarName('--_ui5_card_header_focus_radius')})`,
'--_ui5wcr_card_header_focus_bottom_radius': `var(${getScopedVarName('--_ui5_card_header_focus_bottom_radius')})`,
'--_ui5wcr_popup_header_font_family': `var(${getScopedVarName('--_ui5_popup_header_font_family')})`
};
const ui5WcVariablesStyleData = {
content: `:root {${Object.entries(InternalUI5WCVVarNames).map(([key, value]) => {
return `${key}: ${value};`;
}).join(' ')}}`,
packageName: '@ui5/webcomponents-react',
fileName: 'ThemeProvider'
};
/**
* In order to use `@ui5/webcomponents-react` you have to wrap your application's root component into the ThemeProvider.
*
* __Note:__ Per default, the `ThemeProvider` injects the CSS for the components during runtime. If you have imported our static CSS bundle/s in your application, you can set the prop `staticCssInjected` to `true` to prevent this.
*/
const ThemeProvider = props => {
const {
children,
staticCssInjected = false
} = props;
useIsomorphicLayoutEffect(() => {
document.documentElement.setAttribute('data-sap-theme', getTheme());
const handler = newTheme => {
document.documentElement.setAttribute('data-sap-theme', newTheme);
};
// themeLoaded is fired on theme change
attachThemeLoaded(handler);
return () => {
detachThemeLoaded(handler);
};
}, []);
useIsomorphicLayoutEffect(() => {
StyleStore.setStaticCssInjected(staticCssInjected);
}, [staticCssInjected]);
useIsomorphicLayoutEffect(() => {
attachLanguageChange(I18nStore.handleLanguageChange);
return () => {
detachLanguageChange(I18nStore.handleLanguageChange);
};
}, []);
useEffect(() => {
if (_versionInfoInjected) {
return;
}
globalThis['@ui5/webcomponents-react'] ??= {};
globalThis['@ui5/webcomponents-react'].Runtimes ??= [];
globalThis['@ui5/webcomponents-react'].Runtimes.push(VersionInfo);
_versionInfoInjected = true;
return () => {
globalThis['@ui5/webcomponents-react'].Runtimes = globalThis['@ui5/webcomponents-react'].Runtimes.filter(info => info !== VersionInfo);
_versionInfoInjected = false;
};
}, []);
return /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(ThemeProviderStyles, {}), children]
});
};
ThemeProvider.displayName = 'ThemeProvider';
export { ThemeProvider };