• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SAP / ui5-webcomponents-react / 10456022075

19 Aug 2024 03:11PM CUT coverage: 79.706% (+0.03%) from 79.674%
10456022075

Pull #6222

github

web-flow
Merge 224078f98 into 28b14d9b2
Pull Request #6222: feat: register current runtime version in window

2529 of 3775 branches covered (66.99%)

20 of 21 new or added lines in 3 files covered. (95.24%)

2 existing lines in 2 files now uncovered.

4615 of 5790 relevant lines covered (79.71%)

74594.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.56
/packages/main/src/components/ThemeProvider/index.tsx
1
'use client';
2

3
import { getTheme } from '@ui5/webcomponents-base/dist/config/Theme.js';
4
import { getScopedVarName } from '@ui5/webcomponents-base/dist/CustomElementsScope.js';
5
import { attachLanguageChange, detachLanguageChange } from '@ui5/webcomponents-base/dist/locale/languageChange.js';
6
import type { StyleDataCSP } from '@ui5/webcomponents-base/dist/ManagedStyles.js';
7
import { attachThemeLoaded, detachThemeLoaded } from '@ui5/webcomponents-base/dist/theming/ThemeLoaded.js';
8
import { I18nStore, StyleStore, useIsomorphicLayoutEffect, useStylesheet } from '@ui5/webcomponents-react-base';
9
import type { FC, ReactNode } from 'react';
10
import { useEffect, useId } from 'react';
11
import pkgJson from '../../../package.json';
12
import { parseSemVer } from '../../internal/utils.js';
13
import { styleData } from './ThemeProvider.css.js';
14

15
let _versionInfo = null;
362✔
16
let _versionInfoInjected = false;
362✔
17

18
function getVersionInfo() {
19
  if (!_versionInfo) {
5,591✔
20
    _versionInfo = parseSemVer(pkgJson.version);
346✔
21
  }
22
  return _versionInfo;
5,591✔
23
}
24

25
function ThemeProviderStyles() {
26
  const uniqueId = useId();
14,298✔
27
  useStylesheet(styleData, `${ThemeProvider.displayName}-${uniqueId}`);
14,298✔
28
  useStylesheet(ui5WcVariablesStyleData, `${ThemeProvider.displayName}-css-vars-${uniqueId}`);
14,298✔
29
  return null;
14,298✔
30
}
31

32
const InternalUI5WCVVarNames = {
362✔
33
  '--_ui5wcr_card_header_focus_offset': `var(${getScopedVarName('--_ui5_card_header_focus_offset')})`,
34
  '--_ui5wcr_card_header_focus_border': `var(${getScopedVarName('--_ui5_card_header_focus_border')})`,
35
  '--_ui5wcr_card_header_focus_radius': `var(${getScopedVarName('--_ui5_card_header_focus_radius')})`,
36
  '--_ui5wcr_card_header_focus_bottom_radius': `var(${getScopedVarName('--_ui5_card_header_focus_bottom_radius')})`,
37
  '--_ui5wcr_popup_header_font_family': `var(${getScopedVarName('--_ui5_popup_header_font_family')})`
38
};
39

40
const ui5WcVariablesStyleData: StyleDataCSP = {
362✔
41
  content: `:root {${Object.entries(InternalUI5WCVVarNames)
42
    .map(([key, value]) => {
43
      return `${key}: ${value};`;
1,810✔
44
    })
45
    .join(' ')}}`,
46
  packageName: '@ui5/webcomponents-react',
47
  fileName: 'ThemeProvider'
48
};
49

50
export interface ThemeProviderPropTypes {
51
  children: ReactNode;
52

53
  /**
54
   * You can set this flag to true in case you have imported our static CSS Bundle/s in your application.
55
   * This will prevent the ThemeProvider from injecting the CSS during runtime again.
56
   *
57
   * * __main:__ `import '@ui5/webcomponents-react/styles.css'`
58
   * * __charts:__ `import '@ui5/webcomponents-react-charts/styles.css'`
59
   */
60
  staticCssInjected?: boolean;
61
}
62

63
/**
64
 * In order to use `@ui5/webcomponents-react` you have to wrap your application's root component into the ThemeProvider.
65
 *
66
 * __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.
67
 */
68
const ThemeProvider: FC<ThemeProviderPropTypes> = (props: ThemeProviderPropTypes) => {
362✔
69
  const { children, staticCssInjected = false } = props;
5,682✔
70

71
  useIsomorphicLayoutEffect(() => {
5,591✔
72
    document.documentElement.setAttribute('data-sap-theme', getTheme());
5,591✔
73
    const handler = (newTheme: string) => {
5,591✔
74
      document.documentElement.setAttribute('data-sap-theme', newTheme);
4✔
75
    };
76
    // themeLoaded is fired on theme change
77
    attachThemeLoaded(handler);
5,591✔
78
    return () => {
5,591✔
79
      detachThemeLoaded(handler);
5,251✔
80
    };
81
  }, []);
82

83
  useIsomorphicLayoutEffect(() => {
5,591✔
84
    StyleStore.setStaticCssInjected(staticCssInjected);
5,591✔
85
  }, [staticCssInjected]);
86

87
  useIsomorphicLayoutEffect(() => {
5,591✔
88
    attachLanguageChange(I18nStore.handleLanguageChange);
5,591✔
89
    return () => {
5,591✔
90
      detachLanguageChange(I18nStore.handleLanguageChange);
5,251✔
91
    };
92
  }, []);
93

94
  useEffect(() => {
5,591✔
95
    if (_versionInfoInjected) {
5,591!
NEW
96
      return;
×
97
    }
98
    const versionInfo = getVersionInfo();
5,591✔
99
    globalThis['@ui5/webcomponents-react'] ??= {};
5,591✔
100
    globalThis['@ui5/webcomponents-react'].Runtimes ??= [];
5,591✔
101

102
    globalThis['@ui5/webcomponents-react'].Runtimes.push(versionInfo);
5,591✔
103
    _versionInfoInjected = true;
5,591✔
104
    return () => {
5,591✔
105
      globalThis['@ui5/webcomponents-react'].Runtimes = globalThis['@ui5/webcomponents-react'].Runtimes.filter(
5,251✔
106
        (info) => info !== versionInfo
5,251✔
107
      );
108
      _versionInfoInjected = false;
5,251✔
109
    };
110
  }, []);
111

112
  return (
5,591✔
113
    <>
114
      <ThemeProviderStyles />
115
      {children}
116
    </>
117
  );
118
};
119

120
ThemeProvider.displayName = 'ThemeProvider';
362✔
121

122
export { ThemeProvider };
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc