5
5
filterUndefined ,
6
6
omitObject ,
7
7
Dict ,
8
+ isArray ,
9
+ isObject ,
10
+ keysFormObject ,
8
11
} from '@yamada-ui/utils'
9
12
import { useRef } from 'react'
10
13
import isEqual from 'react-fast-compare'
@@ -15,31 +18,143 @@ import {
15
18
UIStyleProps ,
16
19
useTheme ,
17
20
useColorMode ,
21
+ ResponsiveObject ,
22
+ ColorModeArray ,
23
+ ComponentSizes ,
24
+ ComponentVariants ,
25
+ ComponentMultiVariants ,
26
+ ComponentMultiSizes ,
27
+ pseudos ,
18
28
} from '..'
19
29
20
30
type Styles < isMulti extends boolean = false > = isMulti extends false
21
31
? CSSUIObject
22
32
: Record < string , CSSUIObject >
23
33
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
+ }
30
122
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
+ }
36
125
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 >
38
154
}
39
- }
40
155
41
- return styles as Styles < IsMulti >
42
- }
156
+ return styles as Styles < IsMulti >
157
+ }
43
158
44
159
const setStyles = < Props extends Dict = Dict , IsMulti extends boolean = false > (
45
160
name : string ,
@@ -62,29 +177,25 @@ const setStyles = <Props extends Dict = Dict, IsMulti extends boolean = false>(
62
177
if ( componentStyle ) {
63
178
const args = omitObject ( props , [ 'children' ] )
64
179
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 ?? { } ,
67
189
{ 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 ?? { } ,
82
194
{ theme, colorMode, ...args } ,
83
- isMulti ,
84
- )
195
+ ) ( { isMulti } )
85
196
86
- styles = merge ( styles , size )
87
- styles = merge ( styles , variant )
197
+ styles = merge ( styles , sizeStyles )
198
+ styles = merge ( styles , variantStyles )
88
199
89
200
const isStylesEqual = isEqual ( stylesRef . current , styles )
90
201
0 commit comments