Skip to content

Commit

Permalink
fix: do not set theme provider in portal inside global provider
Browse files Browse the repository at this point in the history
  • Loading branch information
ValeraS committed Apr 15, 2024
1 parent ce1a79d commit 94e7969
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 29 deletions.
12 changes: 9 additions & 3 deletions src/components/Portal/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ReactDOM from 'react-dom';

import {usePortalContainer} from '../../hooks';
import {ThemeProvider} from '../theme';
import {useThemeContext} from '../theme/useThemeContext';
import {block} from '../utils/cn';

import './Portal.scss';
Expand All @@ -18,6 +19,7 @@ export interface PortalProps {

export function Portal({container, children, disablePortal}: PortalProps) {
const defaultContainer = usePortalContainer();
const {scoped} = useThemeContext();

const containerNode = container ?? defaultContainer;

Expand All @@ -27,9 +29,13 @@ export function Portal({container, children, disablePortal}: PortalProps) {

return containerNode
? ReactDOM.createPortal(
<ThemeProvider rootClassName={b('theme-wrapper')} scoped>
{children}
</ThemeProvider>,
scoped ? (
<ThemeProvider rootClassName={b('theme-wrapper')} scoped>
{children}
</ThemeProvider>
) : (
children
),
containerNode,
)
: null;
Expand Down
3 changes: 2 additions & 1 deletion src/components/theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ export function ThemeProvider({
theme,
themeValue,
direction,
scoped,
}) satisfies ThemeContextProps,
[theme, themeValue, direction],
[theme, themeValue, direction, scoped],
);

const themeSettingsContext = React.useMemo(
Expand Down
77 changes: 52 additions & 25 deletions src/components/theme/__stories__/Theme.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {Meta, StoryObj} from '@storybook/react';

import {Button} from '../../Button';
import {Dialog} from '../../Dialog';
import {Select} from '../../Select';
import {Text} from '../../Text';
import {Tooltip} from '../../Tooltip';
import {ThemeProvider} from '../ThemeProvider';
Expand All @@ -13,24 +14,9 @@ const meta: Meta<typeof ThemeProvider> = {
title: 'Components/Utils/ThemeProvider',
component: ThemeProvider,
tags: ['nodocs'],
argTypes: {
theme: {
options: ['none', 'light', 'dark', 'light-hc', 'dark-hc', 'system'],
control: {
type: 'select',
},
mapping: {
none: undefined,
},
},
direction: {
options: ['none', 'ltr', 'rtl'],
control: {
type: 'radio',
},
mapping: {
none: undefined,
},
parameters: {
controls: {
disable: true,
},
},
};
Expand All @@ -52,21 +38,62 @@ function ScopedComponent() {
</Tooltip>
<Dialog open={open} onClose={() => setOpen(false)}>
<Dialog.Header caption="Dialog.Header" />
<Dialog.Body>Dialog.Body</Dialog.Body>
<Dialog.Body>
Dialog.Body
<Select>
<Select.Option value="one">One</Select.Option>
<Select.Option value="two">Two</Select.Option>
<Select.Option value="three">Three</Select.Option>
</Select>
</Dialog.Body>
</Dialog>
</div>
);
}

export const Scoped: Story = {
render: function ThemeScoped(props) {
const style: React.CSSProperties = {
border: '1px red dotted',
padding: 10,
height: '100%',
boxSizing: 'border-box',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
gap: 10,
};
return (
<div>
<ScopedComponent />

<ThemeProvider {...props}>
<div style={{border: '1px red dotted', padding: 10, marginBlockStart: 10}}>
<Text>Inside scoped theme provider</Text>
<div
style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: '300px 300px',
gap: 10,
}}
>
<ThemeProvider {...props} theme="light" direction="rtl">
<div style={style}>
<Text>Inside scoped theme provider (light)</Text>
<ScopedComponent />
</div>
</ThemeProvider>
<ThemeProvider {...props} theme="dark">
<div style={style}>
<Text>Inside scoped theme provider (dark)</Text>
<ScopedComponent />
</div>
</ThemeProvider>
<ThemeProvider {...props} theme="light-hc">
<div style={style}>
<Text>Inside scoped theme provider (light-hc)</Text>
<ScopedComponent />
</div>
</ThemeProvider>
<ThemeProvider {...props} theme="dark-hc" direction="rtl">
<div style={style}>
<Text>Inside scoped theme provider (dark-hc)</Text>
<ScopedComponent />
</div>
</ThemeProvider>
Expand Down
1 change: 1 addition & 0 deletions src/components/theme/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export interface ThemeContextProps {
theme: Theme;
themeValue: RealTheme;
direction: Direction;
scoped: boolean;
}

0 comments on commit 94e7969

Please sign in to comment.