Skip to content

Commit 135e8e0

Browse files
fix(core): improve component style responsiveness
1 parent eb0b309 commit 135e8e0

File tree

4 files changed

+157
-40
lines changed

4 files changed

+157
-40
lines changed

.changeset/new-yaks-roll.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@yamada-ui/core': patch
3+
---
4+
5+
Adjusted minW calculation.
6+
Fixed types of componentVariants and componentSizes.
7+
Fixed did't support variant and size responsiveness and color mode.

packages/core/src/components/use-component-style.tsx

+146-35
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import {
55
filterUndefined,
66
omitObject,
77
Dict,
8+
isArray,
9+
isObject,
10+
keysFormObject,
811
} from '@yamada-ui/utils'
912
import { useRef } from 'react'
1013
import isEqual from 'react-fast-compare'
@@ -15,31 +18,143 @@ import {
1518
UIStyleProps,
1619
useTheme,
1720
useColorMode,
21+
ResponsiveObject,
22+
ColorModeArray,
23+
ComponentSizes,
24+
ComponentVariants,
25+
ComponentMultiVariants,
26+
ComponentMultiSizes,
27+
pseudos,
1828
} from '..'
1929

2030
type Styles<isMulti extends boolean = false> = isMulti extends false
2131
? CSSUIObject
2232
: Record<string, CSSUIObject>
2333

24-
const getStyles = <IsMulti extends boolean = false>(
25-
valOrFunc: UIStyle | Record<string, UIStyle>,
26-
props: UIStyleProps,
27-
isMulti?: boolean,
28-
): Styles<IsMulti> => {
29-
let styles = runIfFunc(valOrFunc, props)
34+
const getModifierStyles =
35+
<IsMulti extends boolean = false>(
36+
value: ResponsiveObject<string> | ColorModeArray<string> | string,
37+
singleOrMultiStyles:
38+
| ComponentVariants
39+
| ComponentSizes
40+
| ComponentMultiVariants
41+
| ComponentMultiSizes,
42+
props: UIStyleProps,
43+
) =>
44+
({ isMulti }: { isMulti: boolean }): Styles<IsMulti> => {
45+
let styles: Styles<IsMulti> = {}
46+
47+
if (isArray(value)) {
48+
const [lightValue, darkValue] = value
49+
50+
const lightStyles = getStyles<IsMulti>(
51+
singleOrMultiStyles[lightValue],
52+
props,
53+
)({ isMulti, query: pseudos._light })
54+
55+
const darkStyles = getStyles<IsMulti>(
56+
singleOrMultiStyles[darkValue],
57+
props,
58+
)({ isMulti, query: pseudos._dark })
59+
60+
styles = merge(lightStyles, darkStyles)
61+
} else if (isObject(value)) {
62+
if (keysFormObject(value).length === 1 && 'base' in value) {
63+
styles = getStyles<IsMulti>(
64+
singleOrMultiStyles[value.base],
65+
props,
66+
)({ isMulti })
67+
} else {
68+
const { queries = [] } = props.theme.__breakpoints ?? {}
69+
70+
const omitQueries = queries.filter(
71+
({ breakpoint }) =>
72+
breakpoint !== 'base' && keysFormObject(value).includes(breakpoint),
73+
)
74+
75+
const minQuery = omitQueries.sort(
76+
(a, b) => (a.minW ?? 0) - (b.minW ?? 0),
77+
)[0]
78+
const maxQuery = omitQueries.sort(
79+
(a, b) => (b.minW ?? 0) - (a.minW ?? 0),
80+
)[0]
81+
const nextMaxQuery = queries
82+
.filter(({ minW }) => (minW ?? 0) > (maxQuery?.minW ?? 0))
83+
.sort((a, b) => (a.minW ?? 0) - (b.minW ?? 0))[0]
84+
85+
styles = Object.entries(value).reduce(
86+
(styles, [breakpointKey, breakpointValue = '']) => {
87+
if (breakpointKey === 'base') {
88+
const query = nextMaxQuery.minWQuery
89+
90+
const baseStyles = getStyles<IsMulti>(
91+
singleOrMultiStyles[breakpointValue],
92+
props,
93+
)({ isMulti, query })
94+
95+
styles = merge(styles, baseStyles)
96+
} else {
97+
const isMin = breakpointKey === minQuery.breakpoint
98+
99+
const query = queries?.find(
100+
({ breakpoint }) => breakpoint === breakpointKey,
101+
)?.[isMin ? 'maxWQuery' : 'minMaxQuery']
102+
103+
const queryStyles = getStyles<IsMulti>(
104+
singleOrMultiStyles[breakpointValue],
105+
props,
106+
)({ isMulti, query })
107+
108+
styles = merge(styles, queryStyles)
109+
}
110+
111+
return styles
112+
},
113+
{} as Styles<IsMulti>,
114+
)
115+
}
116+
} else {
117+
styles = getStyles<IsMulti>(
118+
singleOrMultiStyles[value],
119+
props,
120+
)({ isMulti })
121+
}
30122

31-
if (isMulti) {
32-
for (const [key, valOrFunc] of Object.entries<UIStyle>(
33-
styles as Record<string, UIStyle>,
34-
)) {
35-
const value = runIfFunc(valOrFunc, props)
123+
return styles as Styles<IsMulti>
124+
}
36125

37-
styles = merge(styles, { [key]: value })
126+
const getStyles =
127+
<IsMulti extends boolean = false>(
128+
stylesOrFunc: UIStyle | Record<string, UIStyle>,
129+
props: UIStyleProps,
130+
) =>
131+
({
132+
isMulti,
133+
query,
134+
}: {
135+
isMulti: boolean
136+
query?: string
137+
}): Styles<IsMulti> => {
138+
let styles = runIfFunc(stylesOrFunc, props)
139+
140+
if (isMulti) {
141+
for (const [key, styleOrFunc] of Object.entries<UIStyle>(
142+
styles as Record<string, UIStyle>,
143+
)) {
144+
const style = runIfFunc(styleOrFunc, props)
145+
146+
if (query) {
147+
styles = merge(styles, { [key]: { [query]: style } })
148+
} else {
149+
styles = merge(styles, { [key]: style })
150+
}
151+
}
152+
} else if (query) {
153+
return { [query]: styles } as Styles<IsMulti>
38154
}
39-
}
40155

41-
return styles as Styles<IsMulti>
42-
}
156+
return styles as Styles<IsMulti>
157+
}
43158

44159
const setStyles = <Props extends Dict = Dict, IsMulti extends boolean = false>(
45160
name: string,
@@ -62,29 +177,25 @@ const setStyles = <Props extends Dict = Dict, IsMulti extends boolean = false>(
62177
if (componentStyle) {
63178
const args = omitObject(props, ['children'])
64179

65-
let styles = getStyles<IsMulti>(
66-
componentStyle.baseStyle ?? {},
180+
let styles = getStyles<IsMulti>(componentStyle.baseStyle ?? {}, {
181+
theme,
182+
colorMode,
183+
...args,
184+
})({ isMulti })
185+
186+
const variantStyles = getModifierStyles<IsMulti>(
187+
props.variant,
188+
componentStyle.variants ?? {},
67189
{ theme, colorMode, ...args },
68-
isMulti,
69-
)
70-
71-
const variant = getStyles<IsMulti>(
72-
componentStyle.variants?.[props.variant] ?? {},
73-
{
74-
theme,
75-
colorMode,
76-
...args,
77-
},
78-
isMulti,
79-
)
80-
const size = getStyles<IsMulti>(
81-
componentStyle.sizes?.[props.size] ?? {},
190+
)({ isMulti })
191+
const sizeStyles = getModifierStyles<IsMulti>(
192+
props.size,
193+
componentStyle.sizes ?? {},
82194
{ theme, colorMode, ...args },
83-
isMulti,
84-
)
195+
)({ isMulti })
85196

86-
styles = merge(styles, size)
87-
styles = merge(styles, variant)
197+
styles = merge(styles, sizeStyles)
198+
styles = merge(styles, variantStyles)
88199

89200
const isStylesEqual = isEqual(stylesRef.current, styles)
90201

packages/core/src/css/breakpoint.ts

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const createQueries = (breakpoints: Dict): BreakpointQueries => {
3232

3333
maxW = breakpoint !== 'base' ? maxW : undefined
3434

35+
if (minW) minW += 1
36+
3537
return {
3638
breakpoint,
3739
minW,

packages/core/src/theme.types.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,8 @@ export type UsageTheme = {
362362
}
363363

364364
export type ComponentBaseStyle = UIStyle | Record<string, UIStyle>
365-
export type ComponentVariants = Record<
366-
string,
367-
UIStyle | Record<string, UIStyle>
368-
>
369-
export type ComponentSizes = Record<string, UIStyle | Record<string, UIStyle>>
365+
export type ComponentVariants = Record<string, UIStyle>
366+
export type ComponentSizes = Record<string, UIStyle>
370367
export type ComponentDefaultProps<
371368
Y extends Dict = Dict,
372369
M extends keyof Theme['components'] | unknown = unknown,

0 commit comments

Comments
 (0)