Skip to content

Commit

Permalink
feat: calculate body class names seperately (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
Raubzeug authored Dec 25, 2023
1 parent 533ded1 commit 3dcf03d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 24 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ or add specific CSS-classes to the root node:
</html>
```

it is possible to generate initial CSS-classes during SSR:

```js
import {getInitialRootClassName} from '@gravity-ui/uikit';

const theme = 'light';
const rootClassName = getInitialRootClassName({theme});
```

```js
// index.js
import {createRoot} from 'react-dom/client';
Expand Down
22 changes: 12 additions & 10 deletions src/components/theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import React from 'react';

import {block, blockNew} from '../utils/cn';

import {ThemeContext} from './ThemeContext';
import {ThemeSettingsContext} from './ThemeSettingsContext';
import {DEFAULT_DARK_THEME, DEFAULT_LIGHT_THEME, DEFAULT_THEME, ROOT_CLASS_NAME} from './constants';
import {DEFAULT_DARK_THEME, DEFAULT_LIGHT_THEME, DEFAULT_THEME} from './constants';
import {getDeprecatedRootClassName, getRootClassName} from './getBodyClassName';
import type {RealTheme, Theme} from './types';
import {updateBodyClassName} from './updateBodyClassName';
import {useSystemTheme} from './useSystemTheme';

const b = block(ROOT_CLASS_NAME);
const bNew = blockNew(ROOT_CLASS_NAME);

interface ThemeProviderExternalProps {}

interface ThemeProviderDefaultProps {
Expand Down Expand Up @@ -66,10 +62,16 @@ export function ThemeProvider({
<ThemeSettingsContext.Provider value={themeSettingsContext}>
{scoped ? (
<div
className={bNew({theme: themeValue, 'native-scrollbar': nativeScrollbar}, [
b({theme: themeValue, 'native-scrollbar': nativeScrollbar}),
rootClassName,
])}
className={getRootClassName(
{theme: themeValue, 'native-scrollbar': nativeScrollbar},
[
getDeprecatedRootClassName({
theme: themeValue,
'native-scrollbar': nativeScrollbar,
}),
rootClassName,
],
)}
>
{children}
</div>
Expand Down
2 changes: 0 additions & 2 deletions src/components/theme/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@ export const DEFAULT_DARK_THEME = 'dark';
export const LIGHT_THEMES = ['light', 'light-hc'];
export const DARK_THEMES = ['dark', 'dark-hc'];
export const THEMES = [...LIGHT_THEMES, ...DARK_THEMES];

export const ROOT_CLASS_NAME = 'root';
26 changes: 26 additions & 0 deletions src/components/theme/getBodyClassName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {block, blockNew} from '../utils/cn';

import type {RealTheme} from './types';
import type {BodyClassNameModifiers} from './updateBodyClassName';

const ROOT_CLASS_NAME = 'root';

const bNew = blockNew(ROOT_CLASS_NAME);
const b = block(ROOT_CLASS_NAME);

export function getDeprecatedRootClassName(
modifier?: Partial<BodyClassNameModifiers & {theme: RealTheme | boolean}>,
) {
return b(modifier);
}
export function getRootClassName(
modifier?: Partial<BodyClassNameModifiers & {theme: RealTheme | boolean}>,
addition?: string[],
) {
return bNew(modifier, addition);
}

export function getInitialRootClassName(props: {theme?: RealTheme} = {}) {
const {theme} = props;
return getRootClassName({theme});
}
1 change: 1 addition & 0 deletions src/components/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from './useThemeType';
export * from './withTheme';
export * from './withThemeValue';
export * from './getThemeType';
export {getInitialRootClassName} from './getBodyClassName';
export type {Theme, RealTheme, ThemeType} from './types';
22 changes: 10 additions & 12 deletions src/components/theme/updateBodyClassName.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import {block, blockNew, modsClassName} from '../utils/cn';
import {modsClassName} from '../utils/cn';

import {ROOT_CLASS_NAME} from './constants';
import {getDeprecatedRootClassName, getRootClassName} from './getBodyClassName';
import type {RealTheme} from './types';

const b = block(ROOT_CLASS_NAME);
const bNew = blockNew(ROOT_CLASS_NAME);
const rootClassName = b();
const rootNewClassName = bNew();
const rootClassName = getDeprecatedRootClassName();
const rootNewClassName = getRootClassName();

export type BodyClassNameModifiers = {
'native-scrollbar': boolean;
Expand Down Expand Up @@ -41,19 +39,19 @@ export function updateBodyClassName(
}

[...bodyEl.classList].forEach((cls) => {
if (cls.startsWith(modsClassName(b({theme: true})))) {
if (cls.startsWith(modsClassName(getDeprecatedRootClassName({theme: true})))) {
bodyEl.classList.remove(cls);
}

if (cls.startsWith(modsClassName(bNew({theme: true})))) {
if (cls.startsWith(modsClassName(getRootClassName({theme: true})))) {
bodyEl.classList.remove(cls);
}
});
bodyEl.classList.add(modsClassName(b({theme: newTheme})));
bodyEl.classList.add(modsClassName(bNew({theme: newTheme})));
bodyEl.classList.add(modsClassName(getDeprecatedRootClassName({theme: newTheme})));
bodyEl.classList.add(modsClassName(getRootClassName({theme: newTheme})));

for (const [key, value] of Object.entries({...defaultModifiers, ...modifiers})) {
bodyEl.classList.toggle(modsClassName(b({[key]: true})), value);
bodyEl.classList.toggle(modsClassName(bNew({[key]: true})), value);
bodyEl.classList.toggle(modsClassName(getDeprecatedRootClassName({[key]: true})), value);
bodyEl.classList.toggle(modsClassName(getRootClassName({[key]: true})), value);
}
}

0 comments on commit 3dcf03d

Please sign in to comment.