refactor(Space): less to cssinjs & add compact mode (#6229)

* refactor(Space): less to cssinjs & add compact mode

* chore(space): update md

* chore(space): add demo

* chore(space): add some demo

* feat(button): add compact mode

* fix: reactivity lose

* docs: fix props version

---------

Co-authored-by: tangjinzhou <415800467@qq.com>
pull/6246/head^2
bqy_fe 2023-02-12 09:26:39 +08:00 committed by GitHub
parent e2d4f8c2e3
commit f0649999fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 827 additions and 84 deletions

View File

@ -19,6 +19,7 @@ import useStyle from './style';
import type { ButtonType } from './buttonTypes';
import type { VNode, Ref } from 'vue';
import { GroupSizeContext } from './button-group';
import { useCompactItemContext } from '../space/Compact';
type Loading = boolean | number;
@ -49,6 +50,7 @@ export default defineComponent({
const hasTwoCNChar = ref(false);
const autoInsertSpace = computed(() => autoInsertSpaceInButton.value !== false);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
// =============== Update Loading ===============
const loadingOrDelay = computed(() =>
@ -79,22 +81,25 @@ export default defineComponent({
const pre = prefixCls.value;
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
const sizeFullname = groupSize?.value || size.value;
const sizeFullname = compactSize.value || groupSize?.value || size.value;
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
return {
[hashId.value]: true,
[`${pre}`]: true,
[`${pre}-${shape}`]: shape !== 'default' && shape,
[`${pre}-${type}`]: type,
[`${pre}-${sizeCls}`]: sizeCls,
[`${pre}-loading`]: innerLoading.value,
[`${pre}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
[`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value,
[`${pre}-block`]: block,
[`${pre}-dangerous`]: !!danger,
[`${pre}-rtl`]: direction.value === 'rtl',
};
return [
compactItemClassnames.value,
{
[hashId.value]: true,
[`${pre}`]: true,
[`${pre}-${shape}`]: shape !== 'default' && shape,
[`${pre}-${type}`]: type,
[`${pre}-${sizeCls}`]: sizeCls,
[`${pre}-loading`]: innerLoading.value,
[`${pre}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
[`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value,
[`${pre}-block`]: block,
[`${pre}-dangerous`]: !!danger,
[`${pre}-rtl`]: direction.value === 'rtl',
},
];
});
const fixTwoCNChar = () => {
@ -209,7 +214,11 @@ export default defineComponent({
);
if (!isUnBorderedButtonType(type)) {
buttonNode = <Wave ref="wave" disabled={!!innerLoading.value}>{buttonNode}</Wave>;
buttonNode = (
<Wave ref="wave" disabled={!!innerLoading.value}>
{buttonNode}
</Wave>
);
}
return wrapSSR(buttonNode);

View File

@ -0,0 +1,135 @@
import classNames from '../_util/classNames';
import type { DirectionType, SizeType } from '../config-provider';
import createContext from '../_util/createContext';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
import { computed, defineComponent } from 'vue';
import type { PropType, ExtractPropTypes, Ref } from 'vue';
import PropTypes from '../_util/vue-types';
import { booleanType, tuple } from '../_util/type';
import { isEmpty } from 'lodash-es';
export const spaceCompactItemProps = () => ({
compactSize: String as PropType<SizeType>,
compactDirection: PropTypes.oneOf(tuple('horizontal', 'vertical')).def('horizontal'),
isFirstItem: booleanType(),
isLastItem: booleanType(),
});
export type SpaceCompactItemContextType = Partial<
ExtractPropTypes<ReturnType<typeof spaceCompactItemProps>>
>;
export const SpaceCompactItemContext = createContext<SpaceCompactItemContextType | null>(null);
export const useCompactItemContext = (prefixCls: Ref<string>, direction: Ref<DirectionType>) => {
const compactItemContext = SpaceCompactItemContext.useInject();
const compactItemClassnames = computed(() => {
if (!compactItemContext || isEmpty(compactItemContext)) return '';
const { compactDirection, isFirstItem, isLastItem } = compactItemContext;
const separator = compactDirection === 'vertical' ? '-vertical-' : '-';
return classNames({
[`${prefixCls.value}-compact${separator}item`]: true,
[`${prefixCls.value}-compact${separator}first-item`]: isFirstItem,
[`${prefixCls.value}-compact${separator}last-item`]: isLastItem,
[`${prefixCls.value}-compact${separator}item-rtl`]: direction.value === 'rtl',
});
});
return {
compactSize: computed(() => compactItemContext?.compactSize),
compactDirection: computed(() => compactItemContext?.compactDirection),
compactItemClassnames,
};
};
export const NoCompactStyle = defineComponent({
name: 'NoCompactStyle',
setup(_, { slots }) {
SpaceCompactItemContext.useProvide(null);
return () => {
return slots.default?.();
};
},
});
export const spaceCompactProps = () => ({
prefixCls: String,
size: {
type: [String, Number, Array] as PropType<SizeType>,
},
direction: PropTypes.oneOf(tuple('horizontal', 'vertical')).def('horizontal'),
align: PropTypes.oneOf(tuple('start', 'end', 'center', 'baseline')),
block: { type: Boolean, default: undefined },
});
export type SpaceCompactProps = Partial<ExtractPropTypes<ReturnType<typeof spaceCompactProps>>>;
const CompactItem = defineComponent({
name: 'CompactItem',
props: spaceCompactItemProps(),
setup(props, { slots }) {
SpaceCompactItemContext.useProvide(props);
return () => slots.default?.();
},
});
const Compact = defineComponent({
name: 'ASpaceCompact',
inheritAttrs: false,
props: spaceCompactProps(),
setup(props, { attrs, slots }) {
const { prefixCls, direction: directionConfig } = useConfigInject('space-compact', props);
const compactItemContext = SpaceCompactItemContext.useInject();
const [wrapSSR, hashId] = useStyle(prefixCls);
const clx = computed(() => {
return classNames(prefixCls.value, hashId.value, {
[`${prefixCls.value}-rtl`]: directionConfig.value === 'rtl',
[`${prefixCls.value}-block`]: props.block,
[`${prefixCls.value}-vertical`]: props.direction === 'vertical',
});
});
return () => {
// =========================== Render ===========================
if (slots.default?.()?.length === 0) {
return null;
}
const childNodes = slots.default?.() || [];
return wrapSSR(
<div class={clx.value} {...attrs}>
{childNodes.map((child, i) => {
const key = (child && child.key) || `${prefixCls.value}-item-${i}`;
const noCompactItemContext = !compactItemContext || isEmpty(compactItemContext);
return (
<CompactItem
key={key}
compactSize={props.size}
compactDirection={props.direction}
isFirstItem={i === 0 && (noCompactItemContext || compactItemContext?.isFirstItem)}
isLastItem={
i === childNodes.length - 1 &&
(noCompactItemContext || compactItemContext?.isLastItem)
}
>
{child}
</CompactItem>
);
})}
</div>,
);
};
},
});
export default Compact;

View File

@ -0,0 +1,43 @@
<docs>
---
order: 8
title:
zh-CN: 垂直方向紧凑布局
en-US: Vertical Compact Mode
---
## zh-CN
垂直方向的紧凑布局目前仅支持 Button 组合
## en-US
Vertical Mode for Space.Compact, support Button only.
</docs>
<template>
<a-space>
<a-space-compact direction="vertical">
<a-button>Button 1</a-button>
<a-button>Button 2</a-button>
<a-button>Button 3</a-button>
</a-space-compact>
<a-space-compact direction="vertical">
<a-button type="dashed">Button 1</a-button>
<a-button type="dashed">Button 2</a-button>
<a-button type="dashed">Button 3</a-button>
</a-space-compact>
<a-space-compact direction="vertical">
<a-button type="primary">Button 1</a-button>
<a-button type="primary">Button 2</a-button>
<a-button type="primary">Button 3</a-button>
</a-space-compact>
</a-space>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({});
</script>

View File

@ -0,0 +1,151 @@
<docs>
---
order: 7
title:
zh-CN: Button 紧凑布局
en-US: Button Compact Mode
---
## zh-CN
Button 组件紧凑排列的示例
## en-US
Button component compact example.
</docs>
<template>
<div>
<a-space-compact block>
<a-tooltip title="Like">
<a-button>
<LikeOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Comment">
<a-button>
<CommentOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Star">
<a-button>
<StarOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Heart">
<a-button>
<HeartOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Share">
<a-button>
<ShareAltOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Download">
<a-button>
<DownloadOutlined />
</a-button>
</a-tooltip>
<a-dropdown placement="bottomRight" :trigger="['click']">
<a-button>
<EllipsisOutlined />
</a-button>
<template #overlay>
<a-menu>
<a-menu-item>
<a href="javascript:;">1st menu item</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">2nd menu item</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">3rd menu item</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space-compact>
<br />
<a-space-compact block>
<a-button type="primary">Button 1</a-button>
<a-button type="primary">Button 2</a-button>
<a-button type="primary">Button 3</a-button>
<a-button type="primary">Button 4</a-button>
<a-tooltip title="Tooltip">
<a-button type="primary" disabled>
<DownloadOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Tooltip">
<a-button type="primary" disabled>
<DownloadOutlined />
</a-button>
</a-tooltip>
</a-space-compact>
<br />
<a-space-compact block>
<a-button>Button 1</a-button>
<a-button>Button 2</a-button>
<a-button>Button 3</a-button>
<a-tooltip title="Tooltip">
<a-button disabled>
<DownloadOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="Tooltip">
<a-button>
<DownloadOutlined />
</a-button>
</a-tooltip>
<a-button type="primary">Button 4</a-button>
<a-dropdown placement="bottomRight" :trigger="['click']">
<a-button type="primary">
<EllipsisOutlined />
</a-button>
<template #overlay>
<a-menu>
<a-menu-item>
<a href="javascript:;">1st menu item</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">2nd menu item</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">3rd menu item</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space-compact>
</div>
</template>
<script lang="ts">
import {
DownloadOutlined,
EllipsisOutlined,
HeartOutlined,
LikeOutlined,
CommentOutlined,
StarOutlined,
ShareAltOutlined,
} from '@ant-design/icons-vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
DownloadOutlined,
EllipsisOutlined,
HeartOutlined,
LikeOutlined,
CommentOutlined,
StarOutlined,
ShareAltOutlined,
},
});
</script>

View File

@ -0,0 +1,227 @@
<docs>
---
order: 6
title:
zh-CN: 紧凑布局组合
en-US: Compact Mode for form component
---
## zh-CN
使用 Space.Compact 让表单组件之间紧凑连接且合并边框
## en-US
Compact Mode for form component.
</docs>
<template>
<div className="site-space-compact-wrapper">
<a-space-compact block>
<a-input :style="{ width: '20%' }" default-value="0571" />
<a-input :style="{ width: '30%' }" default-value="26888888" />
</a-space-compact>
<br />
<a-space-compact block size="small">
<a-input :style="{ width: 'calc(100% - 200px)' }" default-value="https://ant.design" />
<a-button type="primary">Submit</a-button>
</a-space-compact>
<br />
<a-space-compact block>
<a-input :style="{ width: 'calc(100% - 200px)' }" default-value="https://ant.design" />
<a-button type="primary">Submit</a-button>
</a-space-compact>
<br />
<a-space-compact block>
<a-input
:style="{ width: 'calc(100% - 200px)' }"
default-value="git@github.com:ant-design/ant-design.git"
/>
<a-tooltip title="copy git url">
<a-button>
<CopyOutlined />
</a-button>
</a-tooltip>
</a-space-compact>
<br />
<a-space-compact block>
<a-select default-value="Zhejiang" allow-clear>
<a-select-option value="Zhejiang">Zhejiang</a-select-option>
<a-select-option value="Jiangsu">Jiangsu</a-select-option>
</a-select>
<a-input :style="{ width: '50%' }" default-value="Xihu District, Hangzhou" />
</a-space-compact>
<br />
<a-space-compact block>
<a-select allow-clear mode="multiple" default-value="Zhejianggggg" :style="{ width: '50%' }">
<a-select-option value="Zhejianggggg">Zhejianggggg</a-select-option>
<a-select-option value="Jiangsu">Jiangsu</a-select-option>
</a-select>
<a-input :style="{ width: '50%' }" default-value="Xihu District, Hangzhou" />
</a-space-compact>
<br />
<a-space-compact block>
<a-input-search :style="{ width: '30%' }" default-value="0571" />
<a-input-search allow-clear :style="{ width: '50%' }" default-value="26888888" />
<a-input-search :style="{ width: '20%' }" default-value="+1" />
</a-space-compact>
<br />
<a-space-compact block>
<a-select default-value="Option1">
<a-select-option value="Option1">Option1</a-select-option>
<a-select-option value="Option2">Option2</a-select-option>
</a-select>
<a-input :style="{ width: '50%' }" default-value="input content" />
<a-input-number :default-value="12" />
</a-space-compact>
<br />
<a-space-compact block>
<a-input :style="{ width: '50%' }" default-value="input content" />
<a-date-picker :style="{ width: '50%' }" />
</a-space-compact>
<br />
<a-space-compact block>
<a-range-picker :style="{ width: '70%' }" />
<a-input :style="{ width: '30%' }" default-value="input content" />
<a-button type="primary">查询</a-button>
</a-space-compact>
<br />
<a-space-compact block>
<a-input :style="{ width: '30%' }" default-value="input content" />
<a-range-picker :style="{ width: '70%' }" />
</a-space-compact>
<br />
<a-space-compact block>
<a-select default-value="Option1-1">
<a-select-option value="Option1-1">Option1-1</a-select-option>
<a-select-option value="Option1-2">Option1-2</a-select-option>
</a-select>
<a-select default-value="Option2-2">
<a-select-option value="Option2-1">Option2-1</a-select-option>
<a-select-option value="Option2-2">Option2-2</a-select-option>
</a-select>
</a-space-compact>
<br />
<a-space-compact block>
<a-select default-value="1">
<a-select-option value="1">Between</a-select-option>
<a-select-option value="2">Except</a-select-option>
</a-select>
<a-input :style="{ width: 100, textAlig: 'center' }" placeholder="Minimum" />
<a-input
class="site-input-split"
:style="{
width: 30,
borderLef: 0,
borderRight: 0,
pointerEvents: 'none',
}"
placeholder="~"
disabled
/>
<a-input
class="site-input-right"
:style="{
width: 100,
textAlig: 'center',
}"
placeholder="Maximum"
/>
</a-space-compact>
<br />
<a-space-compact block>
<a-select default-value="Sign Up" :style="{ width: '30%' }">
<a-select-option value="Sign Up">Sign Up</a-select-option>
<a-select-option value="Sign In">Sign In</a-select-option>
</a-select>
<a-auto-complete
:style="{ width: '70%' }"
placeholder="Email"
:options="[{ value: 'text 1' }, { value: 'text 2' }]"
/>
</a-space-compact>
<br />
<a-space-compact block>
<a-time-picker :style="{ width: '70%' }" />
<a-cascader
:style="{ width: '70%' }"
:options="[
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
]"
placeholder="Select Address"
/>
</a-space-compact>
<br />
<a-space-compact block>
<a-time-range-picker />
<a-tree-select
show-search
:style="{ width: '60%' }"
value="leaf1"
:dropdown-style="{ maxHeight: 400, overflow: 'auto' }"
placeholder="Please select"
allow-clear
tree-default-expand-all
>
<a-tree-select-node value="parent 1" title="parent 1">
<a-tree-select-node value="parent 1-0" title="parent 1-0">
<a-tree-select-node value="leaf1" title="leaf1" />
<a-tree-select-node value="leaf2" title="leaf2" />
</a-tree-select-node>
<a-tree-select-node value="parent 1-1" title="parent 1-1">
<a-tree-select-node value="leaf3">
<template #title>
<b :style="{ color: '#08c' }">leaf3</b>
</template>
</a-tree-select-node>
</a-tree-select-node>
</a-tree-select-node>
</a-tree-select>
<a-button type="primary">Submit</a-button>
</a-space-compact>
<br />
</div>
</template>
<script lang="ts">
import { CopyOutlined } from '@ant-design/icons-vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
CopyOutlined,
},
});
</script>

View File

@ -4,6 +4,11 @@
<Customize />
<Vertical />
<Align />
<Wrap />
<Split />
<Compact />
<CompactButtons />
<CompactButtonVertical />
</demo-sort>
</template>
<script lang="ts">
@ -11,6 +16,11 @@ import Base from './base.vue';
import Customize from './customize.vue';
import Vertical from './vertical.vue';
import Align from './align.vue';
import Wrap from './wrap.vue';
import Split from './split.vue';
import Compact from './compact.vue';
import CompactButtons from './compact-buttons.vue';
import CompactButtonVertical from './compact-button-vertical.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
import { defineComponent } from 'vue';
@ -23,6 +33,11 @@ export default defineComponent({
Customize,
Vertical,
Align,
Wrap,
Split,
Compact,
CompactButtons,
CompactButtonVertical,
},
setup() {
return {};

View File

@ -0,0 +1,33 @@
<docs>
---
order: 0
title:
zh-CN: 分隔符
en-US: Split
---
## zh-CN
相邻组件分隔符
## en-US
Crowded components split.
</docs>
<template>
<a-space>
<template #split>
<a-divider type="vertical" />
</template>
<a-typography-link>Link</a-typography-link>
<a-typography-link>Link</a-typography-link>
<a-typography-link>Link</a-typography-link>
</a-space>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({});
</script>

View File

@ -0,0 +1,30 @@
<docs>
---
order: 0
title:
zh-CN: 自动换行
en-US: Basic Usage
---
## zh-CN
自动换行
## en-US
Wrap
</docs>
<template>
<a-space :size="[8, 16]" wrap>
<template v-for="index in 20" :key="index">
<a-button>Button</a-button>
</template>
</a-space>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({});
</script>

View File

@ -10,12 +10,36 @@ Set components spacing.
## When To Use
Avoid components clinging together and set a unified space.
- Avoid components clinging together and set a unified space.
- Use Space.Compact when child form components are compactly connected and the border is collapsed (After version `ant-design-vue@4.0.0` Supported).
## API
### Space
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| align | Align items | `start` \| `end` \|`center` \|`baseline` | - | 1.6.5 |
| direction | The space direction | `vertical` \| `horizontal` | `horizontal` | 1.6.5 |
| size | The space size | `small` \| `middle` \| `large` \| `number` | `small` | 1.6.5 |
| split | Set split | VueNode \| v-slot | - | 2.2.0 |
| wrap | Auto wrap line, when `horizontal` effective | boolean | false | 2.2.0 |
### Space.Compact
Use Space.Compact when child form components are compactly connected and the border is collapsed. The supported components are
- Button
- AutoComplete
- Cascader
- DatePicker
- Input/Input.Search
- Select
- TimePicker
- TreeSelect
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| block | Option to fit width to its parent\'s width | boolean | false | 4.0.0 |
| direction | Set direction of layout | `vertical` \| `horizontal` | `horizontal` | 4.0.0 |
| size | Set child component size | `large` \| `middle` \| `small` | `middle` | 4.0.0 |

View File

@ -1,12 +1,15 @@
import type { PropType, ExtractPropTypes, CSSProperties } from 'vue';
import type { PropType, ExtractPropTypes, CSSProperties, Plugin, App } from 'vue';
import { defineComponent, computed, ref, watch } from 'vue';
import PropTypes from '../_util/vue-types';
import { filterEmpty } from '../_util/props-util';
import type { SizeType } from '../config-provider';
import { tuple, withInstall } from '../_util/type';
import { booleanType, tuple } from '../_util/type';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
import classNames from '../_util/classNames';
import Compact from './Compact';
import useStyle from './style';
export type SpaceSize = SizeType | number;
const spaceSize = {
@ -21,7 +24,7 @@ export const spaceProps = () => ({
},
direction: PropTypes.oneOf(tuple('horizontal', 'vertical')).def('horizontal'),
align: PropTypes.oneOf(tuple('start', 'end', 'center', 'baseline')),
wrap: { type: Boolean, default: undefined },
wrap: booleanType(),
});
export type SpaceProps = Partial<ExtractPropTypes<ReturnType<typeof spaceProps>>>;
@ -33,10 +36,12 @@ function getNumberSize(size: SpaceSize) {
const Space = defineComponent({
compatConfig: { MODE: 3 },
name: 'ASpace',
inheritAttrs: false,
props: spaceProps(),
slots: ['split'],
setup(props, { slots }) {
setup(props, { slots, attrs }) {
const { prefixCls, space, direction: directionConfig } = useConfigInject('space', props);
const [wrapSSR, hashId] = useStyle(prefixCls);
const supportFlexGap = useFlexGapSupport();
const size = computed(() => props.size ?? space?.value?.size ?? 'small');
const horizontalSize = ref<number>();
@ -58,7 +63,7 @@ const Space = defineComponent({
props.align === undefined && props.direction === 'horizontal' ? 'center' : props.align,
);
const cn = computed(() => {
return classNames(prefixCls.value, `${prefixCls.value}-${props.direction}`, {
return classNames(prefixCls.value, hashId.value, `${prefixCls.value}-${props.direction}`, {
[`${prefixCls.value}-rtl`]: directionConfig.value === 'rtl',
[`${prefixCls.value}-align-${mergedAlign.value}`]: mergedAlign.value,
});
@ -92,7 +97,7 @@ const Space = defineComponent({
const horizontalSizeVal = horizontalSize.value;
const latestIndex = len - 1;
return (
<div class={cn.value} style={style.value}>
<div {...attrs} class={cn.value} style={style.value}>
{items.map((child, index) => {
let itemStyle: CSSProperties = {};
if (!supportFlexGap.value) {
@ -110,7 +115,7 @@ const Space = defineComponent({
}
}
return (
return wrapSSR(
<>
<div class={itemClassName} style={itemStyle}>
{child}
@ -120,7 +125,7 @@ const Space = defineComponent({
{split}
</span>
)}
</>
</>,
);
})}
</div>
@ -129,4 +134,17 @@ const Space = defineComponent({
},
});
export default withInstall(Space);
Space.Compact = Compact;
Space.install = function (app: App) {
app.component(Space.name, Space);
app.component(Compact.name, Compact);
return app;
};
export { Compact };
export default Space as typeof Space &
Plugin & {
readonly Compact: typeof Compact;
};

View File

@ -15,11 +15,37 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/wc6%263gJ0Y8/Space.svg
- 适合行内元素的水平间距。
- 可以设置各种水平对齐方式。
- 需要表单组件之间紧凑连接且合并边框时,使用 Space.Compact`ant-design-vue@4.0.0` 版本开始提供该组件)。
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------- | -------- | ------------------------------------------ | ------------ | ----- |
| align | 对齐方式 | `start` \| `end` \|`center` \|`baseline` | - | 1.6.5 |
| direction | 间距方向 | `vertical` \| `horizontal` | `horizontal` | 1.6.5 |
| size | 间距大小 | `small` \| `middle` \| `large` \| `number` | `small` | 1.6.5 |
### Space
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| align | 对齐方式 | `start` \| `end` \|`center` \|`baseline` | - | 1.6.5 |
| direction | 间距方向 | `vertical` \| `horizontal` | `horizontal` | 1.6.5 |
| size | 间距大小 | `small` \| `middle` \| `large` \| `number` | `small` | 1.6.5 |
| split | 设置拆分 | VueNode \| v-slot | - | 2.2.0 |
| wrap | 是否自动换行,仅在 `horizontal` 时有效 | boolean | false | 2.2.0 |
### Space.Compact
> 自 ant-design-vue@4.0.0 版本开始提供该组件。
需要表单组件之间紧凑连接且合并边框时,使用 Space.Compact。支持的组件有
- Button
- AutoComplete
- Cascader
- DatePicker
- Input/Input.Search
- Select
- TimePicker
- TreeSelect
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------- | ---------------------------- | ------------------------------ | ------------ | ----- |
| block | 将宽度调整为父元素宽度的选项 | boolean | false | 4.0.0 |
| direction | 指定排列方向 | `vertical` \| `horizontal` | `horizontal` | 4.0.0 |
| size | 子组件大小 | `large` \| `middle` \| `small` | `middle` | 4.0.0 |

View File

@ -0,0 +1,29 @@
import type { FullToken, GenerateStyle } from '../../theme/internal';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
}
interface SpaceToken extends FullToken<'Space'> {
// Custom token here
}
const genSpaceCompactStyle: GenerateStyle<SpaceToken> = token => {
const { componentCls } = token;
return {
[componentCls]: {
display: 'inline-flex',
'&-block': {
display: 'flex',
width: '100%',
},
'&-vertical': {
flexDirection: 'column',
},
},
};
};
// ============================== Export ==============================
export default genSpaceCompactStyle;

View File

@ -1,39 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@space-prefix-cls: ~'@{ant-prefix}-space';
@space-item-prefix-cls: ~'@{ant-prefix}-space-item';
.@{space-prefix-cls} {
display: inline-flex;
&-vertical {
flex-direction: column;
}
&-align {
&-center {
align-items: center;
}
&-start {
align-items: flex-start;
}
&-end {
align-items: flex-end;
}
&-baseline {
align-items: baseline;
}
}
}
.@{space-item-prefix-cls} {
&:empty {
display: none;
}
}
@import './rtl';

View File

@ -1,2 +1,54 @@
import '../../style/index.less';
import './index.less';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook } from '../../theme/internal';
import genSpaceCompactStyle from './compact';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
}
interface SpaceToken extends FullToken<'Space'> {
// Custom token here
}
const genSpaceStyle: GenerateStyle<SpaceToken> = token => {
const { componentCls } = token;
return {
[componentCls]: {
display: 'inline-flex',
'&-rtl': {
direction: 'rtl',
},
'&-vertical': {
flexDirection: 'column',
},
'&-align': {
flexDirection: 'column',
'&-center': {
alignItems: 'center',
},
'&-start': {
alignItems: 'flex-start',
},
'&-end': {
alignItems: 'flex-end',
},
'&-baseline': {
alignItems: 'baseline',
},
},
[`${componentCls}-space-item`]: {
'&:empty': {
display: 'none',
},
},
},
};
};
// ============================== Export ==============================
export default genComponentStyleHook('Space', token => [
genSpaceStyle(token),
genSpaceCompactStyle(token),
]);

View File

@ -1,10 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@space-prefix-cls: ~'@{ant-prefix}-space';
.@{space-prefix-cls} {
&-rtl {
direction: rtl;
}
}

View File

@ -58,7 +58,7 @@ import './result/style';
// import './descriptions/style';
// import './page-header/style';
import './form/style';
import './space/style';
// import './space/style';
import './image/style';
import './typography/style';
// import './color-picker/style';

View File

@ -34,7 +34,7 @@ import type { ComponentToken as ProgressComponentToken } from '../../progress/st
// import type { ComponentToken as SelectComponentToken } from '../../select/style';
import type { ComponentToken as SkeletonComponentToken } from '../../skeleton/style';
// import type { ComponentToken as SliderComponentToken } from '../../slider/style';
// import type { ComponentToken as SpaceComponentToken } from '../../space/style';
import type { ComponentToken as SpaceComponentToken } from '../../space/style';
import type { ComponentToken as SpinComponentToken } from '../../spin/style';
// import type { ComponentToken as StepsComponentToken } from '../../steps/style';
// import type { ComponentToken as TableComponentToken } from '../../table/style';
@ -111,7 +111,7 @@ export interface ComponentTokenMap {
Tooltip?: TooltipComponentToken;
// Table?: TableComponentToken;
// Space?: SpaceComponentToken;
Progress?: ProgressComponentToken;
// Progress?: ProgressComponentToken;
// Tour?: TourComponentToken;
// QRCode?: QRCodeComponentToken;
// App?: AppComponentToken;