Skip to content

Commit

Permalink
fix(root id): fix root id
Browse files Browse the repository at this point in the history
  • Loading branch information
morewings committed May 27, 2024
1 parent 83a33ea commit 0947f47
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 58 deletions.
4 changes: 2 additions & 2 deletions src/lib/LocalTheme/LocalRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type {HTMLAttributes, ReactNode} from 'react';
import {createElement, forwardRef, useEffect, useMemo} from 'react';
import type {ThemeType} from 'css-vars-hook';

import {createStyleObject} from '../utils';
import type {DataAttributes, LibraryProps} from '../NativeProps';
import {createStyleObject} from '@/lib/utils';
import type {DataAttributes, LibraryProps} from '@/lib/NativeProps';

/**
* @public
Expand Down
5 changes: 3 additions & 2 deletions src/lib/LocalTheme/useLocalTheme.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {useCallback, useRef, useMemo} from 'react';
import type {ThemeType} from 'css-vars-hook';

import {setCSSVariable} from '../utils';
import {setCSSVariable} from '@/lib/utils';
import type {UnitType} from '@/lib/UnitType';

import type {LocalRootProps} from './LocalRoot';
import {LocalRoot} from './LocalRoot';
import type {UnitType} from '../UnitType';

/**
* @public
Expand Down
3 changes: 2 additions & 1 deletion src/lib/NativeProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export type DataAttributeKey = `data-${string}`;
export type DataAttributes = Record<DataAttributeKey, string>;

export type LibraryProps<TElement = HTMLDivElement> = AriaAttributes & {
id?: string;
/** Provide an id for Provider component */
id?: HTMLAttributes<TElement>['id'];
/**
* Set native ARIA role attribute
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
Expand Down
2 changes: 1 addition & 1 deletion src/lib/RootTheme/HookInterfaceType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {ThemeType} from 'css-vars-hook';

import type {UnitType} from '../UnitType';
import type {UnitType} from '@/lib/UnitType';

/**
* @public
Expand Down
11 changes: 6 additions & 5 deletions src/lib/RootTheme/RootThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type {FC, ReactNode} from 'react';
import {useMemo, useEffect} from 'react';
import {useMemo, useEffect, useId} from 'react';
import type {ThemeType} from 'css-vars-hook';

import {ROOT_ID} from '../config';
import type {DataAttributes, LibraryProps} from '../NativeProps';
import {RootContext} from './RootContext';
import {useRootTheme} from './useRootTheme';
Expand All @@ -24,11 +23,13 @@ export const RootThemeProvider: FC<RootThemeProviderProps> = ({
children,
theme,
className,
id = ROOT_ID,
id,
...nativeProps
}) => {
const backupId = useId();
const rootId = id ? id : backupId;
const {setTheme, style, getTheme, getVariable, setVariable, removeVariable} =
useRootTheme(theme);
useRootTheme(theme, rootId);

const {Provider} = RootContext;

Expand All @@ -43,7 +44,7 @@ export const RootThemeProvider: FC<RootThemeProviderProps> = ({

return (
<Provider value={actions}>
<div {...nativeProps} id={id} className={className} style={style}>
<div {...nativeProps} id={rootId} className={className} style={style}>
{children}
</div>
</Provider>
Expand Down
57 changes: 34 additions & 23 deletions src/lib/RootTheme/useRootTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,63 @@ import {useCallback, useMemo, useRef} from 'react';
import type {CSSProperties} from 'react';
import type {ThemeType} from 'css-vars-hook';

import type {UnitType} from '@/lib/UnitType';

import {
createStyleObject,
getRootVariable,
removeRootVariable,
setRootVariable,
} from '../utils';
import type {HookInterface} from './HookInterfaceType';
import type {UnitType} from '../UnitType';

/**
* @private
* Logic for root theme handling such as updates and CSS style creation
*/
export const useRootTheme = (
theme: ThemeType
theme: ThemeType,
id: string
): HookInterface & {style: CSSProperties} => {
const themeRef = useRef(theme);

const setTheme = useCallback((nextTheme: ThemeType) => {
Object.keys(nextTheme).forEach(key => {
setRootVariable(key, nextTheme[key]);
});
const setTheme = useCallback(
(nextTheme: ThemeType) => {
Object.keys(nextTheme).forEach(key => {
setRootVariable(id)(key, nextTheme[key]);
});

themeRef.current = nextTheme;
}, []);
themeRef.current = nextTheme;
},
[id]
);

const getTheme = useCallback(() => themeRef.current, []);

const getVariable = useCallback(
(variableName: string) => getRootVariable(variableName),
[]
(variableName: string) => getRootVariable(id)(variableName),
[id]
);
const setVariable = useCallback(
(variableName: string, value: UnitType) => {
setRootVariable(id)(variableName, value);
themeRef.current = {
...themeRef.current,
[variableName]: value,
};
},
[id]
);
const setVariable = useCallback((variableName: string, value: UnitType) => {
setRootVariable(variableName, value);
themeRef.current = {
...themeRef.current,
[variableName]: value,
};
}, []);

const removeVariable = useCallback((variableName: string) => {
removeRootVariable(variableName);
const nextTheme = {...themeRef.current};
delete nextTheme[variableName];
themeRef.current = nextTheme;
}, []);
const removeVariable = useCallback(
(variableName: string) => {
removeRootVariable(id)(variableName);
const nextTheme = {...themeRef.current};
delete nextTheme[variableName];
themeRef.current = nextTheme;
},
[id]
);

const style = useMemo(() => createStyleObject(themeRef.current), []);

Expand Down
5 changes: 0 additions & 5 deletions src/lib/config.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ export {useRootTheme, RootThemeProvider} from './RootTheme';
export type {RootThemeProviderProps} from './RootTheme';
export {useLocalTheme} from './LocalTheme';
export type {LocalRootProps} from './LocalTheme';
export {ROOT_ID} from './config';
export type {UnitType} from './UnitType';
export type {LibraryProps, DataAttributes, DataAttributeKey} from './NativeProps';
32 changes: 14 additions & 18 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type {MutableRefObject, CSSProperties} from 'react';
import type {ThemeType} from 'css-vars-hook';

import {ROOT_ID} from './config';
import type {UnitType} from './UnitType';
import type {UnitType} from '@/lib/UnitType';

const normalizeUnit = (unit: UnitType) => {
if (typeof unit === 'string') {
Expand Down Expand Up @@ -53,35 +52,32 @@ export const createStyleObject = (theme: ThemeType): CSSProperties => {
return result;
};

/** @function
* @name getRootElement
* @description Get theme root element in an SSR-safe way
*/
export const getRootElement = (): HTMLElement => document.getElementById(ROOT_ID)!;

/** @function
* @name setRootVariable
* @description Set CSS variable on theme root element
*/
export const setRootVariable = (variableName: string, value: UnitType) => {
const root = getRootElement();
root?.style?.setProperty?.(`--${variableName}`, normalizeUnit(value));
};
export const setRootVariable =
(id: string) => (variableName: string, value: UnitType) => {
const root = document.getElementById(id)!;
root?.style?.setProperty?.(`--${variableName}`, normalizeUnit(value));
};

/** @function
* @name getRootVariable
* @description Get CSS variable on theme root element
*/
export const getRootVariable = (variableName: string): string => {
const root = getRootElement();
return root?.style?.getPropertyValue?.(`--${variableName}`);
};
export const getRootVariable =
(id: string) =>
(variableName: string): string => {
const root = document.getElementById(id)!;
return root?.style?.getPropertyValue?.(`--${variableName}`);
};

/** @function
* @name removeRootVariable
* @description Remove CSS variable from theme root element
*/
export const removeRootVariable = (variableName: string) => {
const root = getRootElement();
export const removeRootVariable = (id: string) => (variableName: string) => {
const root = document.getElementById(id)!;
root?.style?.removeProperty?.(`--${variableName}`);
};

0 comments on commit 0947f47

Please sign in to comment.