Skip to content

Commit

Permalink
refactor(core): updated theme and component types
Browse files Browse the repository at this point in the history
  • Loading branch information
hirotomoyamada committed Oct 15, 2023
1 parent 0e5e72e commit 02a33f1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-ladybugs-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@yamada-ui/core': patch
---

Updated theme and component types.
4 changes: 2 additions & 2 deletions packages/core/src/components/component.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {
CSSUIProps,
CSSUIObject,
StylesProps,
StyledTheme,
CSSObject,
Interpolation,
PropsTheme,
} from '..'
import { DOMElements } from '.'

Expand All @@ -23,7 +23,7 @@ export type UIFactory = {
}

export type StyledResolverProps = CSSUIObject & {
theme: StyledTheme
theme: PropsTheme
/**
* Used for internal css management.
*
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/components/use-component-style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const setStyles = <Props extends Dict = Dict, IsMulti extends boolean = false>(
props: Props,
isMulti: boolean = false,
): [styles: Styles<IsMulti>, props: Props] => {
const { theme } = useTheme()
const { theme, themeScheme } = useTheme()
const { colorMode } = useColorMode()

const componentStyle = get<ComponentStyle | undefined>(
Expand All @@ -180,18 +180,19 @@ const setStyles = <Props extends Dict = Dict, IsMulti extends boolean = false>(
let styles = getStyles<IsMulti>(componentStyle.baseStyle ?? {}, {
theme,
colorMode,
themeScheme,
...args,
})({ isMulti })

const variantStyles = getModifierStyles<IsMulti>(
props.variant,
componentStyle.variants ?? {},
{ theme, colorMode, ...args },
{ theme, colorMode, themeScheme, ...args },
)({ isMulti })
const sizeStyles = getModifierStyles<IsMulti>(
props.size,
componentStyle.sizes ?? {},
{ theme, colorMode, ...args },
{ theme, colorMode, themeScheme, ...args },
)({ isMulti })

styles = merge(styles, sizeStyles)
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/css/css.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Dict } from '@yamada-ui/utils'
import type * as CSS from 'csstype'
import { StylesProps, PseudosProps } from '../styles'
import { Theme, StyledTheme } from '../theme.types'
Expand Down Expand Up @@ -53,7 +52,7 @@ export type Token<
? ColorModeArray<Y> | Y
: Y

export type StyledProps<Y> = Y | ((theme: StyledTheme<Dict>) => Y)
export type StyledProps<Y> = Y | ((theme: StyledTheme) => Y)

export type StyleProperties = CSS.Properties &
Omit<StylesProps, keyof CSS.Properties>
Expand Down Expand Up @@ -91,9 +90,10 @@ export type CSSUIProps<Y = 'responsive', M = 'colorMode'> = StylesProps<Y, M> &
PseudosProps

export type UIStyleProps = {
theme: StyledTheme<Dict>
theme: StyledTheme
colorMode?: ColorMode
colorScheme?: Theme['colorSchemes']
themeScheme?: Theme['themeSchemes']
[key: string]: any
}

Expand Down Expand Up @@ -149,7 +149,7 @@ export type AnimationStyle = {
}

export type FunctionCSSInterpolation = {
(theme: StyledTheme<Dict>): CSSUIProps
(theme: StyledTheme): CSSUIProps
}

export type CSSObjectOrFunc = CSSUIProps | FunctionCSSInterpolation
82 changes: 55 additions & 27 deletions packages/core/src/providers/theme-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,38 @@ import {
ThemeProviderProps as EmotionThemeProviderProps,
Interpolation,
Theme,
CSSObject,
} from '@emotion/react'
import { Dict, runIfFunc, getMemoizedObject as get } from '@yamada-ui/utils'
import {
Dict,
runIfFunc,
getMemoizedObject as get,
isUndefined,
merge,
} from '@yamada-ui/utils'
import {
FC,
useMemo,
useContext,
Context,
useState,
useCallback,
useEffect,
} from 'react'
import { css, UIStyle } from '../css'
import { transformTheme } from '../theme'
import { StyledTheme, ThemeConfig, Theme as UITheme } from '../theme.types'
import {
ChangeThemeScheme,
PropsTheme,
StyledTheme,
ThemeConfig,
Theme as UITheme,
UsageTheme,
} from '../theme.types'
import { useColorMode } from './color-mode-provider'
import { themeSchemeManager, ThemeSchemeManager } from './theme-manager'

const { localStorage } = themeSchemeManager

export type ChangeThemeScheme = (themeScheme: UITheme['themeSchemes']) => void

type ThemeProviderOptions = {
/**
* The theme of the yamada ui.
Expand Down Expand Up @@ -98,9 +109,11 @@ export const ThemeProvider: FC<ThemeProviderProps> = ({
export const CSSVars: FC = () => {
return (
<Global
styles={({ __cssVars }: Dict) => ({
':host, :root, [data-mode]': __cssVars,
})}
styles={
(({ __cssVars }: PropsTheme) => {
return { ':host, :root, [data-mode]': __cssVars } as CSSObject
}) as Interpolation<Theme>
}
/>
)
}
Expand All @@ -111,10 +124,15 @@ export const ResetStyle: FC = () => {
return (
<Global
styles={
((theme: StyledTheme<Dict>) => {
((theme: PropsTheme) => {
const { themeScheme } = theme
let style = get<UIStyle>(theme, 'styles.resetStyle', {})

const computedStyle = runIfFunc(style, { theme, colorMode })
const computedStyle = runIfFunc(style, {
theme,
colorMode,
themeScheme,
})

if (!computedStyle) return undefined

Expand All @@ -131,10 +149,15 @@ export const GlobalStyle: FC = () => {
return (
<Global
styles={
((theme: StyledTheme<Dict>) => {
((theme: PropsTheme) => {
const { themeScheme } = theme
let style = get<UIStyle>(theme, 'styles.globalStyle', {})

const computedStyle = runIfFunc(style, { theme, colorMode })
const computedStyle = runIfFunc(style, {
theme,
colorMode,
themeScheme,
})

if (!computedStyle) return undefined

Expand All @@ -145,31 +168,36 @@ export const GlobalStyle: FC = () => {
)
}

type ThemeContext<T extends object = Dict> = Context<
{
themeScheme: UITheme['themeSchemes']
changeThemeScheme: ChangeThemeScheme
} & StyledTheme<T>
>

export const useTheme = <T extends object = Dict>() => {
const { themeScheme, changeThemeScheme, ...theme } = useContext(
ThemeContext as unknown as ThemeContext<T>,
)
const { themeScheme, changeThemeScheme, ...internalTheme } = useContext(
ThemeContext,
) as PropsTheme<UsageTheme>

if (!theme)
if (!internalTheme)
throw Error(
'useTheme: `theme` is undefined. Seems you forgot to wrap your app in `<UIProvider />`',
)

const theme = useMemo(() => {
if (isUndefined(themeScheme) || themeScheme === 'base') return internalTheme

const nestedTheme = internalTheme.themeSchemes?.[themeScheme]

if (!nestedTheme) return internalTheme

return merge(internalTheme, nestedTheme)
}, [themeScheme, internalTheme])

const value = useMemo(
() =>
({ themeScheme, changeThemeScheme, theme }) as {
themeScheme: UITheme['themeSchemes']
changeThemeScheme: ChangeThemeScheme
({ themeScheme, changeThemeScheme, theme, internalTheme }) as Pick<
PropsTheme,
'themeScheme' | 'changeThemeScheme'
> & {
theme: StyledTheme<T>
internalTheme: StyledTheme<T>
},
[changeThemeScheme, theme, themeScheme],
[themeScheme, changeThemeScheme, theme, internalTheme],
)

return value
Expand Down
13 changes: 12 additions & 1 deletion packages/core/src/theme.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,18 @@ export type CustomTheme = {}

export type Theme = CustomTheme extends UITheme ? CustomTheme : GeneratedTheme

export type StyledTheme<T> = T & {
export type ChangeThemeScheme = (themeScheme: Theme['themeSchemes']) => void

export type PropsTheme<T extends object = Dict> = T & {
themeScheme: Theme['themeSchemes']
changeThemeScheme: ChangeThemeScheme
__config: ThemeConfig
__cssVars: Dict
__cssMap: CSSMap
__breakpoints: AnalyzeBreakpointsReturn
}

export type StyledTheme<T extends object = Dict> = T & {
__config: ThemeConfig
__cssVars: Dict
__cssMap: CSSMap
Expand Down

0 comments on commit 02a33f1

Please sign in to comment.