Skip to content

Commit

Permalink
Fix theme without localstorage usage
Browse files Browse the repository at this point in the history
  • Loading branch information
ivy-lli committed May 8, 2024
1 parent 1fb7d56 commit ecd2f1a
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ test('toggle by label', async () => {
test('toggled with keyboard', async () => {
render(<Radio />);
const radios = screen.getAllByRole('radio');
await userEvent.tab();
await act(async () => await userEvent.tab());
expect(radios.at(0)).toHaveFocus();
expect(radios.at(0)).toBeChecked();

Expand All @@ -54,7 +54,6 @@ test('toggled with keyboard', async () => {

test('readonly mode', () => {
render(<Radio />, { wrapperProps: { readonly: true } });
screen.debug();
expect(screen.getByRole('radiogroup')).toHaveAttribute('data-disabled');
expect(screen.getAllByRole('radio').at(0)).toBeDisabled();
});
Expand Down
13 changes: 13 additions & 0 deletions packages/components/src/context/useReadonly.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { renderHook } from 'test-utils';
import { expect, test } from 'vitest';
import { useReadonly } from './useReadonly';

test('off', async () => {
const { result } = renderHook(useReadonly);
expect(result.current).toBeFalsy();
});

test('on', async () => {
const { result } = renderHook(useReadonly, { wrapperProps: { readonly: true } });
expect(result.current).toBeTruthy();
});
56 changes: 56 additions & 0 deletions packages/components/src/context/useTheme.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { afterEach, expect, test } from 'vitest';
import { ThemeProvider, useTheme } from './useTheme';
import { act, renderHook } from '@testing-library/react';

afterEach(() => {
window.document.documentElement.classList.remove('light', 'dark');
localStorage.clear();
});

test('dark theme', async () => {
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} defaultTheme='dark' /> });
expect(result.current.theme).toEqual('dark');
expect(window.document.documentElement.className).includes('dark');
});

test('light theme', async () => {
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} defaultTheme='light' /> });
expect(result.current.theme).toEqual('light');
expect(window.document.documentElement.className).includes('light');
});

test('system theme', async () => {
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} defaultTheme='system' /> });
expect(result.current.theme).toEqual('system');
expect(window.document.documentElement.className).includes('light');
});

test('body element', async () => {
const root = window.document.body;
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} root={root} /> });
expect(result.current.theme).toEqual('system');
expect(window.document.documentElement.className).to.be.empty;
expect(root.className).includes('light');
});

test('no storage', async () => {
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} /> });
expect(localStorage.length).to.equal(0);
act(() => result.current.setTheme('dark'));
expect(localStorage.length).to.equal(0);
});

test('storage', async () => {
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} storageKey='test' /> });
expect(localStorage.length).to.equal(0);
act(() => result.current.setTheme('dark'));
expect(localStorage.length).to.equal(1);
expect(localStorage.getItem('test')).to.equal('dark');
});

test('existing storage', async () => {
localStorage.setItem('test', 'dark');
const { result } = renderHook(useTheme, { wrapper: props => <ThemeProvider {...props} storageKey='test' /> });
expect(result.current.theme).toEqual('dark');
expect(window.document.documentElement.className).includes('dark');
});
8 changes: 5 additions & 3 deletions packages/components/src/context/useTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export const ThemeProvider = ({
children,
defaultTheme = 'system',
storageKey = 'ivy-ui-theme',
storageKey,
root = window.document.documentElement,
...props
}: ThemeProviderProps) => {
const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme);
const [theme, setTheme] = useState<Theme>(() => (storageKey && (localStorage.getItem(storageKey) as Theme)) || defaultTheme);

useEffect(() => {
root.classList.remove('light', 'dark');
Expand All @@ -44,7 +44,9 @@ export const ThemeProvider = ({
const value = {
theme,
setTheme: (theme: Theme) => {
localStorage.setItem(storageKey, theme);
if (storageKey) {
localStorage.setItem(storageKey, theme);
}
setTheme(theme);
}
};
Expand Down

0 comments on commit ecd2f1a

Please sign in to comment.