refactor: divider

pull/4076/head
tanjinzhou 2021-05-11 16:23:49 +08:00
parent 11ffa8dfda
commit 170a169f35
5 changed files with 154 additions and 142 deletions

View File

@ -1,4 +1,4 @@
import { reactive, provide, VNodeTypes, PropType, defineComponent, watch } from 'vue'; import { reactive, provide, PropType, defineComponent, watch, ExtractPropTypes } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty'; import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider'; import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
@ -14,30 +14,6 @@ export interface CSPConfig {
export { RenderEmptyHandler }; export { RenderEmptyHandler };
export interface ConfigConsumerProps {
getTargetContainer?: () => HTMLElement;
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
rootPrefixCls?: string;
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;
renderEmpty: RenderEmptyHandler;
transformCellText?: (tableProps: TransformCellTextProps) => any;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
input?: {
autoComplete?: string;
};
locale?: Locale;
pageHeader?: {
ghost: boolean;
};
direction?: 'ltr' | 'rtl';
space?: {
size?: SizeType | number;
};
virtual?: boolean;
dropdownMatchSelectWidth?: boolean;
}
export const configConsumerProps = [ export const configConsumerProps = [
'getTargetContainer', 'getTargetContainer',
'getPopupContainer', 'getPopupContainer',
@ -50,72 +26,51 @@ export const configConsumerProps = [
'pageHeader', 'pageHeader',
]; ];
export interface ConfigProviderProps { export const configProviderProps = {
getTargetContainer?: () => HTMLElement; getTargetContainer: {
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement; type: Function as PropType<() => HTMLElement>,
prefixCls?: string; },
children?: VNodeTypes; getPopupContainer: {
renderEmpty?: RenderEmptyHandler; type: Function as PropType<(triggerNode: HTMLElement) => HTMLElement>,
transformCellText?: (tableProps: TransformCellTextProps) => any; },
csp?: CSPConfig; prefixCls: String,
autoInsertSpaceInButton?: boolean; getPrefixCls: {
input?: { type: Function as PropType<(suffixCls?: string, customizePrefixCls?: string) => string>,
autoComplete?: string; },
}; renderEmpty: {
locale?: Locale; type: Function as PropType<RenderEmptyHandler>,
pageHeader?: { },
ghost: boolean; transformCellText: {
}; type: Function as PropType<(tableProps: TransformCellTextProps) => any>,
componentSize?: SizeType; },
direction?: 'ltr' | 'rtl'; csp: {
space?: { type: Object as PropType<CSPConfig>,
size?: SizeType | number; },
}; autoInsertSpaceInButton: PropTypes.looseBool,
virtual?: boolean; locale: {
dropdownMatchSelectWidth?: boolean; type: Object as PropType<Locale>,
} },
pageHeader: {
type: Object as PropType<{ ghost: boolean }>,
},
componentSize: {
type: Object as PropType<SizeType>,
},
direction: {
type: String as PropType<'ltr' | 'rtl'>,
},
space: {
type: [String, Number] as PropType<SizeType | number>,
},
virtual: PropTypes.looseBool,
dropdownMatchSelectWidth: PropTypes.looseBool,
};
export type ConfigProviderProps = ExtractPropTypes<typeof configProviderProps>;
const ConfigProvider = defineComponent({ const ConfigProvider = defineComponent({
name: 'AConfigProvider', name: 'AConfigProvider',
props: { props: configProviderProps,
getTargetContainer: {
type: Function as PropType<() => HTMLElement>,
},
getPopupContainer: {
type: Function as PropType<(triggerNode: HTMLElement) => HTMLElement>,
},
prefixCls: String,
getPrefixCls: {
type: Function as PropType<(suffixCls?: string, customizePrefixCls?: string) => string>,
},
renderEmpty: {
type: Function as PropType<RenderEmptyHandler>,
},
transformCellText: {
type: Function as PropType<(tableProps: TransformCellTextProps) => any>,
},
csp: {
type: Object as PropType<CSPConfig>,
},
autoInsertSpaceInButton: PropTypes.looseBool,
locale: {
type: Object as PropType<Locale>,
},
pageHeader: {
type: Object as PropType<{ ghost: boolean }>,
},
componentSize: {
type: Object as PropType<SizeType>,
},
direction: {
type: String as PropType<'ltr' | 'rtl'>,
},
space: {
type: [String, Number] as PropType<SizeType | number>,
},
virtual: PropTypes.looseBool,
dropdownMatchSelectWidth: PropTypes.looseBool,
},
setup(props, { slots }) { setup(props, { slots }) {
const getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => { const getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
const { prefixCls = 'ant' } = props; const { prefixCls = 'ant' } = props;
@ -166,12 +121,13 @@ const ConfigProvider = defineComponent({
}, },
}); });
export const defaultConfigProvider: ConfigConsumerProps = { export const defaultConfigProvider: ConfigProviderProps = {
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => { getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls; if (customizePrefixCls) return customizePrefixCls;
return `ant-${suffixCls}`; return `ant-${suffixCls}`;
}, },
renderEmpty: defaultRenderEmpty, renderEmpty: defaultRenderEmpty,
direction: 'ltr',
}; };
export default withInstall(ConfigProvider); export default withInstall(ConfigProvider);

View File

@ -1,46 +1,67 @@
import { flattenChildren } from '../_util/props-util'; import { flattenChildren } from '../_util/props-util';
import { computed, defineComponent, inject, PropType } from 'vue'; import { computed, defineComponent, ExtractPropTypes, inject, PropType } from 'vue';
import { defaultConfigProvider } from '../config-provider'; import { defaultConfigProvider } from '../config-provider';
import { withInstall } from '../_util/type'; import { withInstall } from '../_util/type';
export const dividerProps = {
prefixCls: String,
type: {
type: String as PropType<'horizontal' | 'vertical' | ''>,
default: 'horizontal',
},
dashed: {
type: Boolean,
default: false,
},
orientation: {
type: String as PropType<'left' | 'right' | 'center'>,
default: 'center',
},
plain: {
type: Boolean,
default: false,
},
};
export type DividerProps = ExtractPropTypes<typeof dividerProps>;
const Divider = defineComponent({ const Divider = defineComponent({
name: 'ADivider', name: 'ADivider',
props: { props: dividerProps,
prefixCls: String,
type: {
type: String as PropType<'horizontal' | 'vertical' | ''>,
default: 'horizontal',
},
dashed: {
type: Boolean,
default: false,
},
orientation: {
type: String as PropType<'left' | 'right' | 'center'>,
default: 'center',
},
},
setup(props, { slots }) { setup(props, { slots }) {
const { getPrefixCls } = inject('configProvider', defaultConfigProvider); const configProvider = inject('configProvider', defaultConfigProvider);
const prefixCls = computed(() => getPrefixCls('divider', props.prefixCls)); const prefixClsRef = computed(() => configProvider.getPrefixCls('divider', props.prefixCls));
const classString = computed(() => { const classString = computed(() => {
const { type, dashed, orientation } = props; const { type, dashed, plain } = props;
const orientationPrefix = orientation.length > 0 ? '-' + orientation : orientation; const prefixCls = prefixClsRef.value;
const prefixClsRef = prefixCls.value;
return { return {
[prefixClsRef]: true, [prefixCls]: true,
[`${prefixClsRef}-${type}`]: true, [`${prefixCls}-${type}`]: true,
[`${prefixClsRef}-with-text${orientationPrefix}`]: slots.default, [`${prefixCls}-dashed`]: !!dashed,
[`${prefixClsRef}-dashed`]: !!dashed, [`${prefixCls}-plain`]: !!plain,
[`${prefixCls}-rtl`]: configProvider.direction === 'rtl',
}; };
}); });
const orientationPrefix = computed(() =>
props.orientation.length > 0 ? '-' + props.orientation : props.orientation,
);
return () => { return () => {
const children = flattenChildren(slots.default?.()); const children = flattenChildren(slots.default?.());
return ( return (
<div class={classString.value} role="separator"> <div
{children.length ? <span class={`${prefixCls.value}-inner-text`}>{children}</span> : null} class={[
classString.value,
children.length
? `${prefixClsRef.value}-with-text ${prefixClsRef.value}-with-text${orientationPrefix.value}`
: '',
]}
role="separator"
>
{children.length ? (
<span class={`${prefixClsRef.value}-inner-text`}>{children}</span>
) : null}
</div> </div>
); );
}; };

View File

@ -6,59 +6,52 @@
.@{divider-prefix-cls} { .@{divider-prefix-cls} {
.reset-component(); .reset-component();
background: @border-color-split; border-top: @border-width-base solid @divider-color;
&, /* for compatiable */
&-vertical { &-vertical {
position: relative; position: relative;
top: -0.06em; top: -0.06em;
display: inline-block; display: inline-block;
width: 1px;
height: 0.9em; height: 0.9em;
margin: 0 8px; margin: 0 8px;
vertical-align: middle; vertical-align: middle;
border-top: 0;
border-left: @border-width-base solid @divider-color;
} }
&-horizontal { &-horizontal {
display: block; display: flex;
clear: both; clear: both;
width: 100%; width: 100%;
min-width: 100%; // Fix https://github.com/ant-design/ant-design/issues/10914 min-width: 100%; // Fix https://github.com/ant-design/ant-design/issues/10914
height: 1px;
margin: 24px 0; margin: 24px 0;
} }
&-horizontal&-with-text-center, &-horizontal&-with-text {
&-horizontal&-with-text-left, display: flex;
&-horizontal&-with-text-right {
display: table;
margin: 16px 0; margin: 16px 0;
color: @heading-color; color: @heading-color;
font-weight: 500; font-weight: 500;
font-size: @font-size-lg; font-size: @font-size-lg;
white-space: nowrap; white-space: nowrap;
text-align: center; text-align: center;
background: transparent; border-top: 0;
border-top-color: @divider-color;
&::before, &::before,
&::after { &::after {
position: relative; position: relative;
top: 50%; top: 50%;
display: table-cell;
width: 50%; width: 50%;
border-top: 1px solid @border-color-split; border-top: @border-width-base solid transparent;
// Chrome not accept `inherit` in `border-top`
border-top-color: inherit;
border-bottom: 0;
transform: translateY(50%); transform: translateY(50%);
content: ''; content: '';
} }
} }
&-horizontal&-with-text-left,
&-horizontal&-with-text-right {
.@{divider-prefix-cls}-inner-text {
display: inline-block;
padding: 0 10px;
}
}
&-horizontal&-with-text-left { &-horizontal&-with-text-left {
&::before { &::before {
top: 50%; top: 50%;
@ -90,12 +83,10 @@
background: none; background: none;
border-color: @divider-color; border-color: @divider-color;
border-style: dashed; border-style: dashed;
border-width: 1px 0 0; border-width: @border-width-base 0 0;
} }
&-horizontal&-with-text-center&-dashed, &-horizontal&-with-text&-dashed {
&-horizontal&-with-text-left&-dashed,
&-horizontal&-with-text-right&-dashed {
border-top: 0; border-top: 0;
&::before, &::before,
&::after { &::after {
@ -104,6 +95,14 @@
} }
&-vertical&-dashed { &-vertical&-dashed {
border-width: 0 0 0 1px; border-width: 0 0 0 @border-width-base;
}
&-plain&-with-text {
color: @text-color;
font-weight: normal;
font-size: @font-size-base;
} }
} }
@import './rtl';

View File

@ -0,0 +1,36 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@divider-prefix-cls: ~'@{ant-prefix}-divider';
.@{divider-prefix-cls} {
&-rtl {
direction: rtl;
}
&-horizontal&-with-text-left {
&::before {
.@{divider-prefix-cls}-rtl& {
width: 100% - @divider-orientation-margin;
}
}
&::after {
.@{divider-prefix-cls}-rtl& {
width: @divider-orientation-margin;
}
}
}
&-horizontal&-with-text-right {
&::before {
.@{divider-prefix-cls}-rtl& {
width: @divider-orientation-margin;
}
}
&::after {
.@{divider-prefix-cls}-rtl& {
width: 100% - @divider-orientation-margin;
}
}
}
}

2
v2-doc

@ -1 +1 @@
Subproject commit 4da56dac85f43ad7a288951cbf09d860ecf93bb4 Subproject commit 4f1ece5073f736e79c6eb22527a9a83e8c6182b3