refactor: grid (#6220)

* refactor: grid

* fix(grid): align & justify responsive

* chore: update demo and snapshot
This commit is contained in:
zkwolf 2023-01-31 22:20:43 +08:00 committed by GitHub
parent 1d01df4b85
commit 31ca070a18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 542 additions and 379 deletions

View File

@ -1,4 +1,4 @@
import { Col } from '../grid';
import { withInstall } from '../_util/type';
export type { ColProps } from '../grid';
export type { ColProps, ColSize } from '../grid';
export default withInstall(Col);

View File

@ -0,0 +1,4 @@
// Compatible for babel-plugin-import
/* istanbul ignore next */
export default {};

View File

@ -1,5 +0,0 @@
import '../../style/index.less';
// style dependencies
// deps-lint-skip: grid
import '../../grid/style';

View File

@ -1,7 +1,6 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import '../../input/style/mixin';
@import '../../grid/style/mixin';
@import './components';
@import './inline';
@import './horizontal';
@ -109,7 +108,9 @@
}
// Required mark
&.@{form-item-prefix-cls}-required:not(.@{form-item-prefix-cls}-required-mark-optional)::before {
&.@{form-item-prefix-cls}-required:not(
.@{form-item-prefix-cls}-required-mark-optional
)::before {
display: inline-block;
margin-right: 4px;
color: @label-required-color;

View File

@ -2,5 +2,4 @@ import '../../style/index.less';
import './index.less';
// style dependencies
import '../../grid/style';
import '../../tooltip/style';

View File

@ -1,7 +1,6 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import '../../input/style/mixin';
@import '../../grid/style/mixin';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';

View File

@ -3,6 +3,7 @@ import { defineComponent, computed } from 'vue';
import classNames from '../_util/classNames';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectRow } from './context';
import { useColStyle } from './style';
type ColSpanType = number | string;
@ -68,18 +69,23 @@ export const colProps = () => ({
export type ColProps = Partial<ExtractPropTypes<ReturnType<typeof colProps>>>;
const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'] as const;
export default defineComponent({
compatConfig: { MODE: 3 },
name: 'ACol',
inheritAttrs: false,
props: colProps(),
setup(props, { slots }) {
setup(props, { slots, attrs }) {
const { gutter, supportFlexGap, wrap } = useInjectRow();
const { prefixCls, direction } = useConfigInject('col', props);
const [wrapSSR, hashId] = useColStyle(prefixCls);
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 => {
sizes.forEach(size => {
let sizeProps: ColSize = {};
const propSize = props[size];
if (typeof propSize === 'number') {
@ -108,6 +114,8 @@ export default defineComponent({
[`${pre}-pull-${pull}`]: pull,
},
sizeClassObj,
attrs.class,
hashId.value,
);
});
@ -140,12 +148,16 @@ export default defineComponent({
}
return style;
});
return () => {
return (
<div class={classes.value} style={mergedStyle.value}>
return () =>
wrapSSR(
<div
{...attrs}
class={classes.value}
style={{ ...mergedStyle.value, ...(attrs.style as CSSProperties) }}
>
{slots.default?.()}
</div>
</div>,
);
};
},
});

View File

@ -1,26 +1,41 @@
import type { ExtractPropTypes, CSSProperties, PropType } from 'vue';
import { defineComponent, ref, onMounted, onBeforeUnmount, computed } from 'vue';
import classNames from '../_util/classNames';
import { tuple } from '../_util/type';
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve';
import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
import useProvideRow from './context';
import { useRowStyle } from './style';
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between', 'space-evenly');
const RowAligns = ['top', 'middle', 'bottom', 'stretch'] as const;
const RowJustify = [
'start',
'end',
'center',
'space-around',
'space-between',
'space-evenly',
] as const;
type Responsive = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
type ResponsiveLike<T> = {
[key in Responsive]?: T;
};
type Gap = number | undefined;
export type Gutter = number | undefined | Partial<Record<Breakpoint, number>>;
type ResponsiveAligns = ResponsiveLike<(typeof RowAligns)[number]>;
type ResponsiveJustify = ResponsiveLike<(typeof RowJustify)[number]>;
export interface rowContextState {
gutter?: [number, number];
}
export const rowProps = () => ({
align: String as PropType<(typeof RowAligns)[number]>,
justify: String as PropType<(typeof RowJustify)[number]>,
align: [String, Object] as PropType<(typeof RowAligns)[number] | ResponsiveAligns>,
justify: [String, Object] as PropType<(typeof RowJustify)[number] | ResponsiveJustify>,
prefixCls: String,
gutter: {
type: [Number, Array, Object] as PropType<Gutter | [Gutter, Gutter]>,
@ -35,8 +50,10 @@ const ARow = defineComponent({
compatConfig: { MODE: 3 },
name: 'ARow',
props: rowProps(),
setup(props, { slots }) {
inheritAttrs: false,
setup(props, { slots, attrs }) {
const { prefixCls, direction } = useConfigInject('row', props);
const [wrapSSR, hashId] = useRowStyle(prefixCls);
let token: number;
@ -52,10 +69,46 @@ const ARow = defineComponent({
xxxl: true,
});
const curScreens = ref<ScreenMap>({
xs: false,
sm: false,
md: false,
lg: false,
xl: false,
xxl: false,
xxxl: false,
});
const mergePropsByScreen = (oriProp: 'align' | 'justify') => {
return computed(() => {
if (typeof props[oriProp] === 'string') {
return props[oriProp];
}
if (typeof props[oriProp] !== 'object') {
return '';
}
for (let i = 0; i < responsiveArray.length; i++) {
const breakpoint: Breakpoint = responsiveArray[i];
// if do not match, do nothing
if (!curScreens.value[breakpoint]) continue;
const curVal = props[oriProp][breakpoint];
if (curVal !== undefined) {
return curVal;
}
}
return '';
});
};
const mergeAlign = mergePropsByScreen('align');
const mergeJustify = mergePropsByScreen('justify');
const supportFlexGap = useFlexGapSupport();
onMounted(() => {
token = responsiveObserve.value.subscribe(screen => {
curScreens.value = screen;
const currentGutter = props.gutter || 0;
if (
(!Array.isArray(currentGutter) && typeof currentGutter === 'object') ||
@ -98,12 +151,17 @@ const ARow = defineComponent({
});
const classes = computed(() =>
classNames(prefixCls.value, {
[`${prefixCls.value}-no-wrap`]: props.wrap === false,
[`${prefixCls.value}-${props.justify}`]: props.justify,
[`${prefixCls.value}-${props.align}`]: props.align,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
}),
classNames(
prefixCls.value,
{
[`${prefixCls.value}-no-wrap`]: props.wrap === false,
[`${prefixCls.value}-${mergeJustify.value}`]: mergeJustify.value,
[`${prefixCls.value}-${mergeAlign.value}`]: mergeAlign.value,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
},
attrs.class,
hashId.value,
),
);
const rowStyle = computed(() => {
@ -128,13 +186,16 @@ const ARow = defineComponent({
return style;
});
return () => {
return (
<div class={classes.value} style={rowStyle.value}>
return () =>
wrapSSR(
<div
{...attrs}
class={classes.value}
style={{ ...rowStyle.value, ...(attrs.style as CSSProperties) }}
>
{slots.default?.()}
</div>
</div>,
);
};
},
});

View File

@ -1,6 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders ./components/grid/demo/basic.vue correctly 1`] = `
<div class="ant-row">
<div class="ant-col ant-col-24">col</div>
</div>
<div class="ant-row">
<div class="ant-col ant-col-12">col-12</div>
<div class="ant-col ant-col-12">col-12</div>
@ -20,47 +23,54 @@ exports[`renders ./components/grid/demo/basic.vue correctly 1`] = `
exports[`renders ./components/grid/demo/flex.vue correctly 1`] = `
<div id="components-grid-demo-flex">
<p>sub-element align left</p>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element align left</span></div>
<div class="ant-row ant-row-start">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
<p>sub-element align center</p>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element align center</span></div>
<div class="ant-row ant-row-center">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
<p>sub-element align right</p>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element align right</span></div>
<div class="ant-row ant-row-end">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
<p>sub-element monospaced arrangement</p>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element monospaced arrangement</span></div>
<div class="ant-row ant-row-space-between">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
<p>sub-element align full</p>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element align full</span></div>
<div class="ant-row ant-row-space-around">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">sub-element align full</span></div>
<div class="ant-row ant-row-space-evenly">
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
<div class="ant-col ant-col-4">col-4</div>
</div>
</div>
`;
exports[`renders ./components/grid/demo/flex-align.vue correctly 1`] = `
<p>Align Top</p>
<div class="ant-row ant-row-center ant-row-top" type="flex">
<div class="ant-row ant-row-center ant-row-top">
<div class="ant-col ant-col-4">
<p class="height-100">col-4</p>
</div>
@ -75,7 +85,7 @@ exports[`renders ./components/grid/demo/flex-align.vue correctly 1`] = `
</div>
</div>
<p>Align Center</p>
<div class="ant-row ant-row-space-around ant-row-middle" type="flex">
<div class="ant-row ant-row-space-around ant-row-middle">
<div class="ant-col ant-col-4">
<p class="height-100">col-4</p>
</div>
@ -90,7 +100,7 @@ exports[`renders ./components/grid/demo/flex-align.vue correctly 1`] = `
</div>
</div>
<p>Align Bottom</p>
<div class="ant-row ant-row-space-between ant-row-bottom" type="flex">
<div class="ant-row ant-row-space-between ant-row-bottom">
<div class="ant-col ant-col-4">
<p class="height-100">col-4</p>
</div>
@ -108,14 +118,14 @@ exports[`renders ./components/grid/demo/flex-align.vue correctly 1`] = `
exports[`renders ./components/grid/demo/flex-order.vue correctly 1`] = `
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Normal</span></div>
<div class="ant-row" type="flex">
<div class="ant-row">
<div class="ant-col ant-col-6 ant-col-order-4">1 col-order-4</div>
<div class="ant-col ant-col-6 ant-col-order-3">2 col-order-3</div>
<div class="ant-col ant-col-6 ant-col-order-2">3 col-order-2</div>
<div class="ant-col ant-col-6 ant-col-order-1">4 col-order-1</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Responsive</span></div>
<div class="ant-row" type="flex">
<div class="ant-row">
<div class="ant-col ant-col-6 ant-col-xs-order-1 ant-col-sm-order-2 ant-col-md-order-3 ant-col-lg-order-4"> 1 col-order-responsive </div>
<div class="ant-col ant-col-6 ant-col-xs-order-2 ant-col-sm-order-1 ant-col-md-order-4 ant-col-lg-order-3"> 2 col-order-responsive </div>
<div class="ant-col ant-col-6 ant-col-xs-order-3 ant-col-sm-order-4 ant-col-md-order-2 ant-col-lg-order-2"> 3 col-order-responsive </div>
@ -125,37 +135,84 @@ exports[`renders ./components/grid/demo/flex-order.vue correctly 1`] = `
exports[`renders ./components/grid/demo/flex-stretch.vue correctly 1`] = `
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Percentage columns</span></div>
<div class="ant-row" type="flex">
<div class="ant-row">
<div class="ant-col" style="flex: 2 2 auto;">2 / 5</div>
<div class="ant-col" style="flex: 3 3 auto;">3 / 5</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Fill rest</span></div>
<div class="ant-row" type="flex">
<div class="ant-row">
<div class="ant-col" style="flex: 0 0 100px;">100px</div>
<div class="ant-col" style="flex-basis: auto;">auto</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Raw flex style</span></div>
<div class="ant-row" type="flex">
<div class="ant-row">
<div class="ant-col" style="flex: 1 1 200px;">1 1 200px</div>
<div class="ant-col" style="flex: 0 1 300px;">0 1 300px</div>
</div>
<div class="ant-row ant-row-no-wrap">
<div class="ant-col" style="flex: 0 0 auto;">
<div style="padding: 0px 16px;">none</div>
</div>
<div class="ant-col" style="flex-basis: auto; min-width: 0;">auto with no-wrap</div>
</div>
`;
exports[`renders ./components/grid/demo/gutter.vue correctly 1`] = `
<div class="gutter-example">
<div class="ant-row" style="margin-left: -8px; margin-right: -8px;">
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Horizontal</span></div>
<div class="ant-row" style="margin-left: -8px; margin-right: -8px;">
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 8px; padding-right: 8px;">
<div class="gutter-box">col-6</div>
</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Responsive</span></div>
<div class="ant-row" style="margin-left: -16px; margin-right: -16px;">
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 16px; padding-right: 16px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 16px; padding-right: 16px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 16px; padding-right: 16px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding-left: 16px; padding-right: 16px;">
<div class="gutter-box">col-6</div>
</div>
</div>
<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left" role="separator"><span class="ant-divider-inner-text">Vertical</span></div>
<div class="ant-row" style="margin: -12px -8px -12px -8px;">
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
<div class="ant-col ant-col-6 gutter-row" style="padding: 12px 8px 12px 8px;">
<div class="gutter-box">col-6</div>
</div>
</div>
`;
@ -233,6 +290,19 @@ exports[`renders ./components/grid/demo/playfround.vue correctly 1`] = `
<div class="ant-col ant-col-6" style="padding: 8px 8px 8px 8px;">
<div>Column</div>
</div>
</div> Another Row: <div class="ant-row" style="margin: -8px -8px -8px -8px;">
<div class="ant-col ant-col-6" style="padding: 8px 8px 8px 8px;">
<div>Column</div>
</div>
<div class="ant-col ant-col-6" style="padding: 8px 8px 8px 8px;">
<div>Column</div>
</div>
<div class="ant-col ant-col-6" style="padding: 8px 8px 8px 8px;">
<div>Column</div>
</div>
<div class="ant-col ant-col-6" style="padding: 8px 8px 8px 8px;">
<div>Column</div>
</div>
</div><pre>&lt;a-row :gutter="[16,16]"&gt;
&lt;a-col :span="6"/&gt;
&lt;a-col :span="6"/&gt;
@ -269,3 +339,5 @@ exports[`renders ./components/grid/demo/sort.vue correctly 1`] = `
<div class="ant-col ant-col-6 ant-col-pull-18">col-6 col-pull-18</div>
</div>
`;
exports[`renders ./components/grid/demo/use-breakpoint.vue correctly 1`] = `" Current break point:"`;

View File

@ -21,6 +21,9 @@ You can create a basic grid system by using a single set of `Row` and `Col` grid
</docs>
<template>
<a-row>
<a-col :span="24">col</a-col>
</a-row>
<a-row>
<a-col :span="12">col-12</a-col>
<a-col :span="12">col-12</a-col>

View File

@ -32,4 +32,10 @@ Col provides `flex` prop to support fill rest.
<a-col flex="1 1 200px">1 1 200px</a-col>
<a-col flex="0 1 300px">0 1 300px</a-col>
</a-row>
<a-row :wrap="false">
<a-col flex="none">
<div style="padding: 0 16px">none</div>
</a-col>
<a-col flex="auto">auto with no-wrap</a-col>
</a-row>
</template>

View File

@ -20,7 +20,7 @@ Child elements depending on the value of the `start`,`center`, `end`,`space-betw
<template>
<div id="components-grid-demo-flex">
<p>sub-element align left</p>
<a-divider orientation="left">sub-element align left</a-divider>
<a-row justify="start">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
@ -28,7 +28,7 @@ Child elements depending on the value of the `start`,`center`, `end`,`space-betw
<a-col :span="4">col-4</a-col>
</a-row>
<p>sub-element align center</p>
<a-divider orientation="left">sub-element align center</a-divider>
<a-row justify="center">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
@ -36,7 +36,7 @@ Child elements depending on the value of the `start`,`center`, `end`,`space-betw
<a-col :span="4">col-4</a-col>
</a-row>
<p>sub-element align right</p>
<a-divider orientation="left">sub-element align right</a-divider>
<a-row justify="end">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
@ -44,7 +44,7 @@ Child elements depending on the value of the `start`,`center`, `end`,`space-betw
<a-col :span="4">col-4</a-col>
</a-row>
<p>sub-element monospaced arrangement</p>
<a-divider orientation="left">sub-element monospaced arrangement</a-divider>
<a-row justify="space-between">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
@ -52,13 +52,21 @@ Child elements depending on the value of the `start`,`center`, `end`,`space-betw
<a-col :span="4">col-4</a-col>
</a-row>
<p>sub-element align full</p>
<a-divider orientation="left">sub-element align full</a-divider>
<a-row justify="space-around">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
</a-row>
<a-divider orientation="left">sub-element align full</a-divider>
<a-row justify="space-evenly">
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
<a-col :span="4">col-4</a-col>
</a-row>
</div>
</template>

View File

@ -29,31 +29,68 @@ You can use an array to set vertical spacing, `[horizontal, vertical]` `[16, { x
</docs>
<template>
<div class="gutter-example">
<a-row :gutter="16">
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
</a-row>
</div>
<a-divider orientation="left">Horizontal</a-divider>
<a-row :gutter="16">
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
</a-row>
<a-divider orientation="left">Responsive</a-divider>
<a-row :gutter="{ xs: 8, sm: 16, md: 24, lg: 32 }">
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
</a-row>
<a-divider orientation="left">Vertical</a-divider>
<a-row :gutter="[16, 24]">
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
<a-col class="gutter-row" :span="6">
<div class="gutter-box">col-6</div>
</a-col>
</a-row>
</template>
<style scoped>
.gutter-example :deep(.ant-row > div) {
background: transparent;
border: 0;
}
.gutter-box {
background: #00a0e9;
padding: 5px 0;
background: #0092ff;
padding: 8px 0;
}
</style>
```

View File

@ -1,16 +1,17 @@
<template>
<demo-sort :cols="1">
<basic />
<gutter />
<offset />
<sort />
<flex />
<flex-align />
<flex-order />
<flex-stretch />
<flex />
<gutter />
<offset />
<ResponsiveMore />
<responsive />
<sort />
<ResponsiveMore />
<playfround />
<UseBreakpoint />
</demo-sort>
</template>
<script lang="ts">
@ -26,6 +27,7 @@ import ResponsiveMore from './responsive-more.vue';
import Responsive from './responsive.vue';
import Sort from './sort.vue';
import Playfround from './playfround.vue';
import UseBreakpoint from './use-breakpoint.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
@ -44,6 +46,7 @@ export default defineComponent({
Responsive,
Sort,
Playfround,
UseBreakpoint,
},
});
</script>

View File

@ -66,6 +66,16 @@ A simple playground for column count and gutter.
<div>Column</div>
</a-col>
</a-row>
Another Row:
<a-row :gutter="[gutters[gutterKey], vgutters[vgutterKey]]">
<a-col
v-for="item in colCounts[colCountKey]"
:key="item.toString()"
:span="24 / colCounts[colCountKey]"
>
<div>Column</div>
</a-col>
</a-row>
<pre>{{ rowColHtml }}</pre>
<br />
<pre>{{ rowColHtml }}</pre>
@ -141,11 +151,4 @@ export default defineComponent({
#components-grid-demo-playground .ant-col {
padding: 0;
}
.code-box-demo #components-grid-demo-playground .ant-row > div {
margin-top: 0;
margin-bottom: 0;
}
[data-theme='dark'] #components-grid-demo-playground [class~='ant-col'] > div {
background: #028ac8;
}
</style>

View File

@ -0,0 +1,41 @@
<docs>
---
order: 10
title:
zh-CN: useBreakpoint Hook
en-US: useBreakpoint Hook
---
## zh-CN
使用 `useBreakpoint` 个性化布局
## en-US
Use `useBreakpoint` Hook provide personalized layout.
</docs>
<template>
Current break point:
<template v-for="(value, key) in screens">
<a-tag v-if="!!value" color="blue" :key="key">
{{ key }}
</a-tag>
</template>
</template>
<script>
import { defineComponent } from 'vue';
import { Grid } from 'ant-design-vue';
const useBreakpoint = Grid.useBreakpoint;
export default defineComponent({
setup() {
const screens = useBreakpoint();
return {
screens,
};
},
});
</script>

View File

@ -3,7 +3,7 @@ category: Components
type: Layout
cols: 1
title: Grid
cover: https://gw.alipayobjects.com/zos/alicdn/5rWLU27so/Grid.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*mfJeS6cqZrEAAAAAAAAAAAAADrJ8AQ/original
---
24 Grids System.
@ -37,29 +37,29 @@ Our grid systems support Flex layout to allow the elements within the parent to
### Row
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| align | the vertical alignment of the flex layout: `top` `middle` `bottom` | string | `top` |
| gutter | spacing between grids, could be a number or a object like `{ xs: 8, sm: 16, md: 24}`. or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` (supported after `1.5.0`) | number/object/array | 0 |
| justify | horizontal arrangement of the flex layout: `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` | string | `start` |
| wrap | Auto wrap line | boolean | false |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| align | Vertical alignment | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl']: 'top' | 'middle' | 'bottom' | 'stretch'}` | `top` | object: 4.0 |
| gutter | Spacing between grids, could be a number or a object like `{ xs: 8, sm: 16, md: 24}`. or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` (supported after `1.5.0`) | number/object/array | 0 | - |
| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl']: 'start' | 'end' | 'center' | 'space-around' | 'space-between' | 'space-evenly'}` | `start` | object: 4.0 |
| wrap | Auto wrap line | boolean | false | - |
### Col
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| flex | the layout fill of flex | string\|number | - |
| offset | the number of cells to offset Col from the left | number | 0 |
| order | raster order, used in `flex` layout mode | number | 0 |
| pull | the number of cells that raster is moved to the left | number | 0 |
| push | the number of cells that raster is moved to the right | number | 0 |
| span | raster number of cells to occupy, 0 corresponds to `display: none` | number | none |
| xxxl | `≥2000px`, could be a `span` value or an object containing above props | number\|object | - |
| xs | `<576px` and also default setting, could be a `span` value or an object containing above props | number\|object | - |
| sm | `≥576px`, could be a `span` value or an object containing above props | number\|object | - |
| md | `≥768px`, could be a `span` value or an object containing above props | number\|object | - |
| lg | `≥992px`, could be a `span` value or an object containing above props | number\|object | - |
| xl | `≥1200px`, could be a `span` value or an object containing above props | number\|object | - |
| xxl | `≥1600px`, could be a `span` value or an object containing above props | number\|object | - |
| xxxl | `≥2000px`, could be a `span` value or an object containing above props | number\|object | 3.0 |
The breakpoints of responsive grid follow [BootStrap 4 media queries rules](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints)(not including `occasionally part`).

View File

@ -4,7 +4,7 @@ subtitle: 栅格
type: 布局
cols: 1
title: Grid
cover: https://gw.alipayobjects.com/zos/alicdn/5rWLU27so/Grid.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*mfJeS6cqZrEAAAAAAAAAAAAADrJ8AQ/original
---
24 栅格系统。
@ -34,12 +34,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5rWLU27so/Grid.svg
### Row
| 成员 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| align | flex 布局下的垂直对齐方式:`top` `middle` `bottom` | string | `top` |
| gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 `{ xs: 8, sm: 16, md: 24}`。或者使用数组形式同时设置 `[水平间距, 垂直间距]``1.5.0 后支持`)。 | number/object/array | 0 |
| justify | flex 布局下的水平排列方式: `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` | string | `start` |
| wrap | 是否自动换行 | boolean | false |
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| align | 垂直对齐方式 | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl']: 'top' | 'middle' | 'bottom' | 'stretch'}` | `top` | object: 4.0 |
| gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 `{ xs: 8, sm: 16, md: 24}`。或者使用数组形式同时设置 `[水平间距, 垂直间距]``1.5.0 后支持`)。 | number \| object \| array | 0 | - |
| justify | 水平排列方式 | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl']: 'start' | 'end' | 'center' | 'space-around' | 'space-between' | 'space-evenly'}` | `start` | object: 4.0 |
| wrap | 是否自动换行 | boolean | false | - |
### Col
@ -51,12 +51,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5rWLU27so/Grid.svg
| pull | 栅格向左移动格数 | number | 0 | |
| push | 栅格向右移动格数 | number | 0 | |
| span | 栅格占位格数,为 0 时相当于 `display: none` | number | - | |
| xxxl | `≥2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | 3.0 |
| xs | `<576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| sm | `≥576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| md | `≥768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| lg | `≥992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| xl | `≥1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| xxl | `≥1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | |
| xxxl | `≥2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | 3.0 |
响应式栅格的断点扩展自 [BootStrap 4 的规则](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints)(不包含链接里 `occasionally` 的部分)。

View File

@ -1,127 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import './mixin';
// Grid system
.@{row-prefix-cls} {
display: flex;
flex-flow: row wrap;
&::before,
&::after {
display: flex;
}
// No wrap of flex
&-no-wrap {
flex-wrap: nowrap;
}
}
// x轴原点
.@{row-prefix-cls}-start {
justify-content: flex-start;
}
// x轴居中
.@{row-prefix-cls}-center {
justify-content: center;
}
// x轴反方向
.@{row-prefix-cls}-end {
justify-content: flex-end;
}
// x轴平分
.@{row-prefix-cls}-space-between {
justify-content: space-between;
}
// x轴有间隔地平分
.@{row-prefix-cls}-space-around {
justify-content: space-around;
}
// x轴有间隔地均分
.@{row-prefix-cls}-space-evenly {
justify-content: space-evenly;
}
// 顶部对齐
.@{row-prefix-cls}-top {
align-items: flex-start;
}
// 居中对齐
.@{row-prefix-cls}-middle {
align-items: center;
}
// 底部对齐
.@{row-prefix-cls}-bottom {
align-items: flex-end;
}
.@{col-prefix-cls} {
position: relative;
max-width: 100%;
// Prevent columns from collapsing when empty
min-height: 1px;
}
.make-grid();
// Extra small grid
//
// Columns, offsets, pushes, and pulls for extra small devices like
// smartphones.
.make-grid(-xs);
// Small grid
//
// Columns, offsets, pushes, and pulls for the small device range, from phones
// to tablets.
@media (min-width: @screen-sm-min) {
.make-grid(-sm);
}
// Medium grid
//
// Columns, offsets, pushes, and pulls for the desktop device range.
@media (min-width: @screen-md-min) {
.make-grid(-md);
}
// Large grid
//
// Columns, offsets, pushes, and pulls for the large desktop device range.
@media (min-width: @screen-lg-min) {
.make-grid(-lg);
}
// Extra Large grid
//
// Columns, offsets, pushes, and pulls for the full hd device range.
@media (min-width: @screen-xl-min) {
.make-grid(-xl);
}
// Extra Extra Large grid
//
// Columns, offsets, pushes, and pulls for the full hd device range.
@media (min-width: @screen-xxl-min) {
.make-grid(-xxl);
}
@media (min-width: @screen-xxxl-min) {
.make-grid(-xxxl);
}
@import './rtl';

View File

@ -0,0 +1,175 @@
import type { CSSObject } from '../../_util/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
interface GridRowToken extends FullToken<'Grid'> {}
interface GridColToken extends FullToken<'Grid'> {
gridColumns: number;
}
// ============================== Row-Shared ==============================
const genGridRowStyle: GenerateStyle<GridRowToken> = (token): CSSObject => {
const { componentCls } = token;
return {
// Grid system
[componentCls]: {
display: 'flex',
flexFlow: 'row wrap',
minWidth: 0,
'&::before, &::after': {
display: 'flex',
},
'&-no-wrap': {
flexWrap: 'nowrap',
},
// The origin of the X-axis
'&-start': {
justifyContent: 'flex-start',
},
// The center of the X-axis
'&-center': {
justifyContent: 'center',
},
// The opposite of the X-axis
'&-end': {
justifyContent: 'flex-end',
},
'&-space-between': {
justifyContent: 'space-between',
},
'&-space-around ': {
justifyContent: 'space-around',
},
// Align at the top
'&-top': {
alignItems: 'flex-start',
},
// Align at the center
'&-middle': {
alignItems: 'center',
},
'&-bottom': {
alignItems: 'flex-end',
},
},
};
};
// ============================== Col-Shared ==============================
const genGridColStyle: GenerateStyle<GridColToken> = (token): CSSObject => {
const { componentCls } = token;
return {
// Grid system
[componentCls]: {
position: 'relative',
maxWidth: '100%',
// Prevent columns from collapsing when empty
minHeight: 1,
},
};
};
const genLoopGridColumnsStyle = (token: GridColToken, sizeCls: string): CSSObject => {
const { componentCls, gridColumns } = token;
const gridColumnsStyle: CSSObject = {};
for (let i = gridColumns; i >= 0; i--) {
if (i === 0) {
gridColumnsStyle[`${componentCls}${sizeCls}-${i}`] = {
display: 'none',
};
gridColumnsStyle[`${componentCls}-push-${i}`] = {
insetInlineStart: 'auto',
};
gridColumnsStyle[`${componentCls}-pull-${i}`] = {
insetInlineEnd: 'auto',
};
gridColumnsStyle[`${componentCls}${sizeCls}-push-${i}`] = {
insetInlineStart: 'auto',
};
gridColumnsStyle[`${componentCls}${sizeCls}-pull-${i}`] = {
insetInlineEnd: 'auto',
};
gridColumnsStyle[`${componentCls}${sizeCls}-offset-${i}`] = {
marginInlineEnd: 0,
};
gridColumnsStyle[`${componentCls}${sizeCls}-order-${i}`] = {
order: 0,
};
} else {
gridColumnsStyle[`${componentCls}${sizeCls}-${i}`] = {
display: 'block',
flex: `0 0 ${(i / gridColumns) * 100}%`,
maxWidth: `${(i / gridColumns) * 100}%`,
};
gridColumnsStyle[`${componentCls}${sizeCls}-push-${i}`] = {
insetInlineStart: `${(i / gridColumns) * 100}%`,
};
gridColumnsStyle[`${componentCls}${sizeCls}-pull-${i}`] = {
insetInlineEnd: `${(i / gridColumns) * 100}%`,
};
gridColumnsStyle[`${componentCls}${sizeCls}-offset-${i}`] = {
marginInlineStart: `${(i / gridColumns) * 100}%`,
};
gridColumnsStyle[`${componentCls}${sizeCls}-order-${i}`] = {
order: i,
};
}
}
return gridColumnsStyle;
};
const genGridStyle = (token: GridColToken, sizeCls: string): CSSObject =>
genLoopGridColumnsStyle(token, sizeCls);
const genGridMediaStyle = (
token: GridColToken,
screenSize: number,
sizeCls: string,
): CSSObject => ({
[`@media (min-width: ${screenSize}px)`]: {
...genGridStyle(token, sizeCls),
},
});
// ============================== Export ==============================
export const useRowStyle = genComponentStyleHook('Grid', token => [genGridRowStyle(token)]);
export const useColStyle = genComponentStyleHook('Grid', token => {
const gridToken: GridColToken = mergeToken<GridColToken>(token, {
gridColumns: 24, // Row is divided into 24 parts in Grid
});
const gridMediaSizesMap = {
'-sm': gridToken.screenSMMin,
'-md': gridToken.screenMDMin,
'-lg': gridToken.screenLGMin,
'-xl': gridToken.screenXLMin,
'-xxl': gridToken.screenXXLMin,
};
return [
genGridColStyle(gridToken),
genGridStyle(gridToken, ''),
genGridStyle(gridToken, '-xs'),
Object.keys(gridMediaSizesMap)
.map((key: keyof typeof gridMediaSizesMap) =>
genGridMediaStyle(gridToken, gridMediaSizesMap[key], key),
)
.reduce((pre, cur) => ({ ...pre, ...cur }), {}),
];
});

View File

@ -1,2 +0,0 @@
import '../../style/index.less';
import './index.less';

View File

@ -1,56 +0,0 @@
@import '../../style/mixins/index';
@row-prefix-cls: ~'@{ant-prefix}-row';
@col-prefix-cls: ~'@{ant-prefix}-col';
// mixins for grid system
// ------------------------
.loop-grid-columns(@index, @class) when (@index > 0) {
.@{col-prefix-cls}@{class}-@{index} {
display: block;
flex: 0 0 percentage((@index / @grid-columns));
max-width: percentage((@index / @grid-columns));
}
.@{col-prefix-cls}@{class}-push-@{index} {
left: percentage((@index / @grid-columns));
}
.@{col-prefix-cls}@{class}-pull-@{index} {
right: percentage((@index / @grid-columns));
}
.@{col-prefix-cls}@{class}-offset-@{index} {
margin-left: percentage((@index / @grid-columns));
}
.@{col-prefix-cls}@{class}-order-@{index} {
order: @index;
}
.loop-grid-columns((@index - 1), @class);
}
.loop-grid-columns(@index, @class) when (@index = 0) {
.@{col-prefix-cls}@{class}-@{index} {
display: none;
}
.@{col-prefix-cls}-push-@{index} {
left: auto;
}
.@{col-prefix-cls}-pull-@{index} {
right: auto;
}
.@{col-prefix-cls}@{class}-push-@{index} {
left: auto;
}
.@{col-prefix-cls}@{class}-pull-@{index} {
right: auto;
}
.@{col-prefix-cls}@{class}-offset-@{index} {
margin-left: 0;
}
.@{col-prefix-cls}@{class}-order-@{index} {
order: 0;
}
}
.make-grid(@class: ~'') {
.loop-grid-columns(@grid-columns, @class);
}

View File

@ -1,69 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import './mixin';
.@{row-prefix-cls} {
&-rtl {
direction: rtl;
}
}
// mixin
.loop-grid-columns(@index, @class) when (@index > 0) {
.@{col-prefix-cls}@{class}-push-@{index} {
// reset property in RTL direction
&.@{col-prefix-cls}-rtl {
right: percentage((@index / @grid-columns));
left: auto;
}
}
.@{col-prefix-cls}@{class}-pull-@{index} {
// reset property in RTL direction
&.@{col-prefix-cls}-rtl {
right: auto;
left: percentage((@index / @grid-columns));
}
}
.@{col-prefix-cls}@{class}-offset-@{index} {
// reset property in RTL direction
&.@{col-prefix-cls}-rtl {
margin-right: percentage((@index / @grid-columns));
margin-left: 0;
}
}
}
.loop-grid-columns(@index, @class) when (@index = 0) {
.@{col-prefix-cls}-push-@{index} {
// reset property in RTL direction
&.@{col-prefix-cls}-rtl {
right: auto;
}
}
.@{col-prefix-cls}-pull-@{index} {
&.@{col-prefix-cls}-rtl {
left: auto;
}
}
.@{col-prefix-cls}@{class}-push-@{index} {
&.@{col-prefix-cls}-rtl {
right: auto;
}
}
.@{col-prefix-cls}@{class}-pull-@{index} {
&.@{col-prefix-cls}-rtl {
left: auto;
}
}
.@{col-prefix-cls}@{class}-offset-@{index} {
&.@{col-prefix-cls}-rtl {
margin-right: 0;
}
}
}

View File

@ -5,4 +5,3 @@ import './index.less';
import '../../empty/style';
import '../../spin/style';
import '../../pagination/style';
import '../../grid/style';

View File

@ -0,0 +1,4 @@
// Compatible for babel-plugin-import
/* istanbul ignore next */
export default {};

View File

@ -1,5 +0,0 @@
import '../../style/index.less';
// style dependencies
// deps-lint-skip: grid
import '../../grid/style';

View File

@ -2,7 +2,7 @@
// import './icon/style';
import './radio/style';
import './checkbox/style';
import './grid/style';
// import './grid/style';
import './tag/style';
import './rate/style';
import './pagination/style';