1
1
import type { ExtractPropTypes , CSSProperties , PropType } from 'vue' ;
2
2
import { defineComponent , ref , onMounted , onBeforeUnmount , computed } from 'vue' ;
3
3
import classNames from '../_util/classNames' ;
4
- import { tuple } from '../_util/type' ;
5
4
import type { Breakpoint , ScreenMap } from '../_util/responsiveObserve' ;
6
5
import useResponsiveObserve , { responsiveArray } from '../_util/responsiveObserve' ;
7
6
import useConfigInject from '../config-provider/hooks/useConfigInject' ;
8
7
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport' ;
9
8
import useProvideRow from './context' ;
10
-
11
- const RowAligns = tuple ( 'top' , 'middle' , 'bottom' , 'stretch' ) ;
12
- const RowJustify = tuple ( 'start' , 'end' , 'center' , 'space-around' , 'space-between' , 'space-evenly' ) ;
9
+ import { useRowStyle } from './style' ;
10
+
11
+ const RowAligns = [ 'top' , 'middle' , 'bottom' , 'stretch' ] as const ;
12
+ const RowJustify = [
13
+ 'start' ,
14
+ 'end' ,
15
+ 'center' ,
16
+ 'space-around' ,
17
+ 'space-between' ,
18
+ 'space-evenly' ,
19
+ ] as const ;
20
+
21
+ type Responsive = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs' ;
22
+ type ResponsiveLike < T > = {
23
+ [ key in Responsive ] ?: T ;
24
+ } ;
13
25
14
26
type Gap = number | undefined ;
15
27
export type Gutter = number | undefined | Partial < Record < Breakpoint , number > > ;
16
28
29
+ type ResponsiveAligns = ResponsiveLike < ( typeof RowAligns ) [ number ] > ;
30
+ type ResponsiveJustify = ResponsiveLike < ( typeof RowJustify ) [ number ] > ;
31
+
17
32
export interface rowContextState {
18
33
gutter ?: [ number , number ] ;
19
34
}
20
35
21
36
export const rowProps = ( ) => ( {
22
- align : String as PropType < ( typeof RowAligns ) [ number ] > ,
23
- justify : String as PropType < ( typeof RowJustify ) [ number ] > ,
37
+ align : [ String , Object ] as PropType < ( typeof RowAligns ) [ number ] | ResponsiveAligns > ,
38
+ justify : [ String , Object ] as PropType < ( typeof RowJustify ) [ number ] | ResponsiveJustify > ,
24
39
prefixCls : String ,
25
40
gutter : {
26
41
type : [ Number , Array , Object ] as PropType < Gutter | [ Gutter , Gutter ] > ,
@@ -35,8 +50,10 @@ const ARow = defineComponent({
35
50
compatConfig : { MODE : 3 } ,
36
51
name : 'ARow' ,
37
52
props : rowProps ( ) ,
38
- setup ( props , { slots } ) {
53
+ inheritAttrs : false ,
54
+ setup ( props , { slots, attrs } ) {
39
55
const { prefixCls, direction } = useConfigInject ( 'row' , props ) ;
56
+ const [ wrapSSR , hashId ] = useRowStyle ( prefixCls ) ;
40
57
41
58
let token : number ;
42
59
@@ -52,10 +69,46 @@ const ARow = defineComponent({
52
69
xxxl : true ,
53
70
} ) ;
54
71
72
+ const curScreens = ref < ScreenMap > ( {
73
+ xs : false ,
74
+ sm : false ,
75
+ md : false ,
76
+ lg : false ,
77
+ xl : false ,
78
+ xxl : false ,
79
+ xxxl : false ,
80
+ } ) ;
81
+
82
+ const mergePropsByScreen = ( oriProp : 'align' | 'justify' ) => {
83
+ return computed ( ( ) => {
84
+ if ( typeof props [ oriProp ] === 'string' ) {
85
+ return props [ oriProp ] ;
86
+ }
87
+ if ( typeof props [ oriProp ] !== 'object' ) {
88
+ return '' ;
89
+ }
90
+
91
+ for ( let i = 0 ; i < responsiveArray . length ; i ++ ) {
92
+ const breakpoint : Breakpoint = responsiveArray [ i ] ;
93
+ // if do not match, do nothing
94
+ if ( ! curScreens . value [ breakpoint ] ) continue ;
95
+ const curVal = props [ oriProp ] [ breakpoint ] ;
96
+ if ( curVal !== undefined ) {
97
+ return curVal ;
98
+ }
99
+ }
100
+ return '' ;
101
+ } ) ;
102
+ } ;
103
+
104
+ const mergeAlign = mergePropsByScreen ( 'align' ) ;
105
+ const mergeJustify = mergePropsByScreen ( 'justify' ) ;
106
+
55
107
const supportFlexGap = useFlexGapSupport ( ) ;
56
108
57
109
onMounted ( ( ) => {
58
110
token = responsiveObserve . value . subscribe ( screen => {
111
+ curScreens . value = screen ;
59
112
const currentGutter = props . gutter || 0 ;
60
113
if (
61
114
( ! Array . isArray ( currentGutter ) && typeof currentGutter === 'object' ) ||
@@ -98,12 +151,17 @@ const ARow = defineComponent({
98
151
} ) ;
99
152
100
153
const classes = computed ( ( ) =>
101
- classNames ( prefixCls . value , {
102
- [ `${ prefixCls . value } -no-wrap` ] : props . wrap === false ,
103
- [ `${ prefixCls . value } -${ props . justify } ` ] : props . justify ,
104
- [ `${ prefixCls . value } -${ props . align } ` ] : props . align ,
105
- [ `${ prefixCls . value } -rtl` ] : direction . value === 'rtl' ,
106
- } ) ,
154
+ classNames (
155
+ prefixCls . value ,
156
+ {
157
+ [ `${ prefixCls . value } -no-wrap` ] : props . wrap === false ,
158
+ [ `${ prefixCls . value } -${ mergeJustify . value } ` ] : mergeJustify . value ,
159
+ [ `${ prefixCls . value } -${ mergeAlign . value } ` ] : mergeAlign . value ,
160
+ [ `${ prefixCls . value } -rtl` ] : direction . value === 'rtl' ,
161
+ } ,
162
+ attrs . class ,
163
+ hashId . value ,
164
+ ) ,
107
165
) ;
108
166
109
167
const rowStyle = computed ( ( ) => {
@@ -128,13 +186,16 @@ const ARow = defineComponent({
128
186
return style ;
129
187
} ) ;
130
188
131
- return ( ) => {
132
- return (
133
- < div class = { classes . value } style = { rowStyle . value } >
189
+ return ( ) =>
190
+ wrapSSR (
191
+ < div
192
+ { ...attrs }
193
+ class = { classes . value }
194
+ style = { { ...rowStyle . value , ...( attrs . style as CSSProperties ) } }
195
+ >
134
196
{ slots . default ?.( ) }
135
- </ div >
197
+ </ div > ,
136
198
) ;
137
- } ;
138
199
} ,
139
200
} ) ;
140
201
0 commit comments