Skip to content

Commit 31ca070

Browse files
authored
refactor: grid (#6220)
* refactor: grid * fix(grid): align & justify responsive * chore: update demo and snapshot
1 parent 1d01df4 commit 31ca070

27 files changed

+543
-380
lines changed

components/col/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { Col } from '../grid';
22
import { withInstall } from '../_util/type';
3-
export type { ColProps } from '../grid';
3+
export type { ColProps, ColSize } from '../grid';
44
export default withInstall(Col);

components/col/style/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Compatible for babel-plugin-import
2+
3+
/* istanbul ignore next */
4+
export default {};

components/col/style/index.tsx

-5
This file was deleted.

components/form/style/index.less

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@import '../../style/themes/index';
22
@import '../../style/mixins/index';
33
@import '../../input/style/mixin';
4-
@import '../../grid/style/mixin';
54
@import './components';
65
@import './inline';
76
@import './horizontal';
@@ -109,7 +108,9 @@
109108
}
110109

111110
// Required mark
112-
&.@{form-item-prefix-cls}-required:not(.@{form-item-prefix-cls}-required-mark-optional)::before {
111+
&.@{form-item-prefix-cls}-required:not(
112+
.@{form-item-prefix-cls}-required-mark-optional
113+
)::before {
113114
display: inline-block;
114115
margin-right: 4px;
115116
color: @label-required-color;

components/form/style/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ import '../../style/index.less';
22
import './index.less';
33

44
// style dependencies
5-
import '../../grid/style';
65
import '../../tooltip/style';

components/form/style/rtl.less

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@import '../../style/themes/index';
22
@import '../../style/mixins/index';
33
@import '../../input/style/mixin';
4-
@import '../../grid/style/mixin';
54

65
@form-prefix-cls: ~'@{ant-prefix}-form';
76
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';

components/grid/Col.tsx

+19-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { defineComponent, computed } from 'vue';
33
import classNames from '../_util/classNames';
44
import useConfigInject from '../config-provider/hooks/useConfigInject';
55
import { useInjectRow } from './context';
6+
import { useColStyle } from './style';
67

78
type ColSpanType = number | string;
89

@@ -68,18 +69,23 @@ export const colProps = () => ({
6869

6970
export type ColProps = Partial<ExtractPropTypes<ReturnType<typeof colProps>>>;
7071

72+
const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'] as const;
7173
export default defineComponent({
7274
compatConfig: { MODE: 3 },
7375
name: 'ACol',
76+
inheritAttrs: false,
7477
props: colProps(),
75-
setup(props, { slots }) {
78+
setup(props, { slots, attrs }) {
7679
const { gutter, supportFlexGap, wrap } = useInjectRow();
7780
const { prefixCls, direction } = useConfigInject('col', props);
81+
82+
const [wrapSSR, hashId] = useColStyle(prefixCls);
83+
7884
const classes = computed(() => {
7985
const { span, order, offset, push, pull } = props;
8086
const pre = prefixCls.value;
8187
let sizeClassObj = {};
82-
['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].forEach(size => {
88+
sizes.forEach(size => {
8389
let sizeProps: ColSize = {};
8490
const propSize = props[size];
8591
if (typeof propSize === 'number') {
@@ -108,6 +114,8 @@ export default defineComponent({
108114
[`${pre}-pull-${pull}`]: pull,
109115
},
110116
sizeClassObj,
117+
attrs.class,
118+
hashId.value,
111119
);
112120
});
113121

@@ -140,12 +148,16 @@ export default defineComponent({
140148
}
141149
return style;
142150
});
143-
return () => {
144-
return (
145-
<div class={classes.value} style={mergedStyle.value}>
151+
152+
return () =>
153+
wrapSSR(
154+
<div
155+
{...attrs}
156+
class={classes.value}
157+
style={{ ...mergedStyle.value, ...(attrs.style as CSSProperties) }}
158+
>
146159
{slots.default?.()}
147-
</div>
160+
</div>,
148161
);
149-
};
150162
},
151163
});

components/grid/Row.tsx

+79-18
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,41 @@
11
import type { ExtractPropTypes, CSSProperties, PropType } from 'vue';
22
import { defineComponent, ref, onMounted, onBeforeUnmount, computed } from 'vue';
33
import classNames from '../_util/classNames';
4-
import { tuple } from '../_util/type';
54
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve';
65
import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
76
import useConfigInject from '../config-provider/hooks/useConfigInject';
87
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
98
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+
};
1325

1426
type Gap = number | undefined;
1527
export type Gutter = number | undefined | Partial<Record<Breakpoint, number>>;
1628

29+
type ResponsiveAligns = ResponsiveLike<(typeof RowAligns)[number]>;
30+
type ResponsiveJustify = ResponsiveLike<(typeof RowJustify)[number]>;
31+
1732
export interface rowContextState {
1833
gutter?: [number, number];
1934
}
2035

2136
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>,
2439
prefixCls: String,
2540
gutter: {
2641
type: [Number, Array, Object] as PropType<Gutter | [Gutter, Gutter]>,
@@ -35,8 +50,10 @@ const ARow = defineComponent({
3550
compatConfig: { MODE: 3 },
3651
name: 'ARow',
3752
props: rowProps(),
38-
setup(props, { slots }) {
53+
inheritAttrs: false,
54+
setup(props, { slots, attrs }) {
3955
const { prefixCls, direction } = useConfigInject('row', props);
56+
const [wrapSSR, hashId] = useRowStyle(prefixCls);
4057

4158
let token: number;
4259

@@ -52,10 +69,46 @@ const ARow = defineComponent({
5269
xxxl: true,
5370
});
5471

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+
55107
const supportFlexGap = useFlexGapSupport();
56108

57109
onMounted(() => {
58110
token = responsiveObserve.value.subscribe(screen => {
111+
curScreens.value = screen;
59112
const currentGutter = props.gutter || 0;
60113
if (
61114
(!Array.isArray(currentGutter) && typeof currentGutter === 'object') ||
@@ -98,12 +151,17 @@ const ARow = defineComponent({
98151
});
99152

100153
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+
),
107165
);
108166

109167
const rowStyle = computed(() => {
@@ -128,13 +186,16 @@ const ARow = defineComponent({
128186
return style;
129187
});
130188

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+
>
134196
{slots.default?.()}
135-
</div>
197+
</div>,
136198
);
137-
};
138199
},
139200
});
140201

0 commit comments

Comments
 (0)