forked from vueComponent/ant-design-vue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCol.tsx
140 lines (125 loc) · 4.23 KB
/
Col.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import type { CSSProperties, ExtractPropTypes } from 'vue';
import { defineComponent, computed } from 'vue';
import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import useConfigInject from '../_util/hooks/useConfigInject';
import { useInjectRow } from './context';
type ColSpanType = number | string;
type FlexType = number | 'none' | 'auto' | string;
export interface ColSize {
span?: ColSpanType;
order?: ColSpanType;
offset?: ColSpanType;
push?: ColSpanType;
pull?: ColSpanType;
}
function parseFlex(flex: FlexType): string {
if (typeof flex === 'number') {
return `${flex} ${flex} auto`;
}
if (/^\d+(\.\d+)?(px|em|rem|%)$/.test(flex)) {
return `0 0 ${flex}`;
}
return flex;
}
const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
export const colSize = PropTypes.shape<ColSize>({
span: stringOrNumber,
order: stringOrNumber,
offset: stringOrNumber,
push: stringOrNumber,
pull: stringOrNumber,
}).loose;
const objectOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number, colSize]);
const colProps = {
span: stringOrNumber,
order: stringOrNumber,
offset: stringOrNumber,
push: stringOrNumber,
pull: stringOrNumber,
xs: objectOrNumber,
sm: objectOrNumber,
md: objectOrNumber,
lg: objectOrNumber,
xl: objectOrNumber,
xxl: objectOrNumber,
xxxl: objectOrNumber,
prefixCls: PropTypes.string,
flex: stringOrNumber,
};
export type ColProps = Partial<ExtractPropTypes<typeof colProps>>;
export default defineComponent({
name: 'ACol',
props: colProps,
setup(props, { slots }) {
const { gutter, supportFlexGap, wrap } = useInjectRow();
const { prefixCls, direction } = useConfigInject('col', props);
const classes = computed(() => {
const { span, order, offset, push, pull } = props;
const pre = prefixCls.value;
let sizeClassObj = {};
['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].forEach(size => {
let sizeProps: ColSize = {};
const propSize = props[size];
if (typeof propSize === 'number') {
sizeProps.span = propSize;
} else if (typeof propSize === 'object') {
sizeProps = propSize || {};
}
sizeClassObj = {
...sizeClassObj,
[`${pre}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
[`${pre}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0,
[`${pre}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset || sizeProps.offset === 0,
[`${pre}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0,
[`${pre}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0,
[`${pre}-rtl`]: direction.value === 'rtl',
};
});
return classNames(
pre,
{
[`${pre}-${span}`]: span !== undefined,
[`${pre}-order-${order}`]: order,
[`${pre}-offset-${offset}`]: offset,
[`${pre}-push-${push}`]: push,
[`${pre}-pull-${pull}`]: pull,
},
sizeClassObj,
);
});
const mergedStyle = computed(() => {
const { flex } = props;
const gutterVal = gutter.value;
const style: CSSProperties = {};
// Horizontal gutter use padding
if (gutterVal && gutterVal[0] > 0) {
const horizontalGutter = `${gutterVal[0] / 2}px`;
style.paddingLeft = horizontalGutter;
style.paddingRight = horizontalGutter;
}
// Vertical gutter use padding when gap not support
if (gutterVal && gutterVal[1] > 0 && !supportFlexGap.value) {
const verticalGutter = `${gutterVal[1] / 2}px`;
style.paddingTop = verticalGutter;
style.paddingBottom = verticalGutter;
}
if (flex) {
style.flex = parseFlex(flex);
// Hack for Firefox to avoid size issue
// https://github.com/ant-design/ant-design/pull/20023#issuecomment-564389553
if (flex === 'auto' && wrap.value === false && !style.minWidth) {
style.minWidth = 0;
}
}
return style;
});
return () => {
return (
<div class={classes.value} style={mergedStyle.value}>
{slots.default?.()}
</div>
);
};
},
});