refactor: Simplify Button Group Style

pull/5820/head
tangjinzhou 2022-05-10 16:18:44 +08:00
parent 3aedf48eaf
commit 0244e7f5b4
4 changed files with 35 additions and 33 deletions

View File

@ -0,0 +1,17 @@
import { inject, provide } from 'vue';
function createContext<T>() {
const contextKey = Symbol('contextKey');
const useProvide = (props: T) => {
provide(contextKey, props);
};
const useInject = () => {
return inject(contextKey, undefined as T) || ({} as T);
};
return {
useProvide,
useInject,
};
}
export default createContext;

View File

@ -2,9 +2,10 @@ import { computed, defineComponent } from 'vue';
import { flattenChildren } from '../_util/props-util'; import { flattenChildren } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
import type { ExtractPropTypes, PropType } from 'vue'; import type { ExtractPropTypes, PropType, ComputedRef } from 'vue';
import type { SizeType } from '../config-provider'; import type { SizeType } from '../config-provider';
import UnreachableException from '../_util/unreachableException'; import devWarning from '../vc-util/devWarning';
import createContext from '../_util/createContext';
export const buttonGroupProps = () => ({ export const buttonGroupProps = () => ({
prefixCls: String, prefixCls: String,
@ -14,12 +15,17 @@ export const buttonGroupProps = () => ({
}); });
export type ButtonGroupProps = Partial<ExtractPropTypes<ReturnType<typeof buttonGroupProps>>>; export type ButtonGroupProps = Partial<ExtractPropTypes<ReturnType<typeof buttonGroupProps>>>;
export const GroupSizeContext = createContext<{
size: ComputedRef<SizeType>;
}>();
export default defineComponent({ export default defineComponent({
name: 'AButtonGroup', name: 'AButtonGroup',
props: buttonGroupProps(), props: buttonGroupProps(),
setup(props, { slots }) { setup(props, { slots }) {
const { prefixCls, direction } = useConfigInject('btn-group', props); const { prefixCls, direction } = useConfigInject('btn-group', props);
GroupSizeContext.useProvide({
size: computed(() => props.size),
});
const classes = computed(() => { const classes = computed(() => {
const { size } = props; const { size } = props;
// large => lg // large => lg
@ -37,7 +43,7 @@ export default defineComponent({
break; break;
default: default:
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn(new UnreachableException(size).error); devWarning(!size, 'Button.Group', 'Invalid prop `size`.');
} }
return { return {
[`${prefixCls.value}`]: true, [`${prefixCls.value}`]: true,

View File

@ -18,13 +18,14 @@ import LoadingIcon from './LoadingIcon';
import type { ButtonType } from './buttonTypes'; import type { ButtonType } from './buttonTypes';
import type { VNode, Ref } from 'vue'; import type { VNode, Ref } from 'vue';
import { GroupSizeContext } from './button-group';
type Loading = boolean | number; type Loading = boolean | number;
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
function isUnborderedButtonType(type: ButtonType | undefined) { function isUnBorderedButtonType(type: ButtonType | undefined) {
return type === 'text' || type === 'link'; return type === 'text' || type === 'link';
} }
export { buttonProps }; export { buttonProps };
@ -37,7 +38,7 @@ export default defineComponent({
// emits: ['click', 'mousedown'], // emits: ['click', 'mousedown'],
setup(props, { slots, attrs, emit }) { setup(props, { slots, attrs, emit }) {
const { prefixCls, autoInsertSpaceInButton, direction, size } = useConfigInject('btn', props); const { prefixCls, autoInsertSpaceInButton, direction, size } = useConfigInject('btn', props);
const { size: groupSize } = GroupSizeContext.useInject();
const buttonNodeRef = ref<HTMLElement>(null); const buttonNodeRef = ref<HTMLElement>(null);
const delayTimeoutRef = ref(undefined); const delayTimeoutRef = ref(undefined);
let isNeedInserted = false; let isNeedInserted = false;
@ -76,7 +77,7 @@ export default defineComponent({
const pre = prefixCls.value; const pre = prefixCls.value;
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined }; const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
const sizeFullname = size.value; const sizeFullname = groupSize?.value || size.value;
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : ''; const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
return { return {
@ -85,7 +86,7 @@ export default defineComponent({
[`${pre}-${shape}`]: shape !== 'default' && shape, [`${pre}-${shape}`]: shape !== 'default' && shape,
[`${pre}-${sizeCls}`]: sizeCls, [`${pre}-${sizeCls}`]: sizeCls,
[`${pre}-loading`]: innerLoading.value, [`${pre}-loading`]: innerLoading.value,
[`${pre}-background-ghost`]: ghost && !isUnborderedButtonType(type), [`${pre}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
[`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value, [`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value,
[`${pre}-block`]: block, [`${pre}-block`]: block,
[`${pre}-dangerous`]: !!danger, [`${pre}-dangerous`]: !!danger,
@ -132,7 +133,7 @@ export default defineComponent({
watchEffect(() => { watchEffect(() => {
devWarning( devWarning(
!(props.ghost && isUnborderedButtonType(props.type)), !(props.ghost && isUnBorderedButtonType(props.type)),
'Button', 'Button',
"`link` or `text` button can't be a `ghost` button.", "`link` or `text` button can't be a `ghost` button.",
); );
@ -149,7 +150,7 @@ export default defineComponent({
const { icon = slots.icon?.() } = props; const { icon = slots.icon?.() } = props;
const children = flattenChildren(slots.default?.()); const children = flattenChildren(slots.default?.());
isNeedInserted = children.length === 1 && !icon && !isUnborderedButtonType(props.type); isNeedInserted = children.length === 1 && !icon && !isUnBorderedButtonType(props.type);
const { type, htmlType, disabled, href, title, target, onMousedown } = props; const { type, htmlType, disabled, href, title, target, onMousedown } = props;
@ -202,7 +203,7 @@ export default defineComponent({
</button> </button>
); );
if (isUnborderedButtonType(type)) { if (isUnBorderedButtonType(type)) {
return buttonNode; return buttonNode;
} }

View File

@ -210,28 +210,6 @@
.@{btnClassName}-icon-only { .@{btnClassName}-icon-only {
font-size: @font-size-base; font-size: @font-size-base;
} }
// size
&-lg > .@{btnClassName},
&-lg > span > .@{btnClassName} {
.button-size(@btn-height-lg; @btn-padding-horizontal-lg; @btn-font-size-lg; 0);
}
&-lg .@{btnClassName}.@{btnClassName}-icon-only {
.square(@btn-height-lg);
padding-right: 0;
padding-left: 0;
}
&-sm > .@{btnClassName},
&-sm > span > .@{btnClassName} {
.button-size(@btn-height-sm; @btn-padding-horizontal-sm; @font-size-base; 0);
> .@{iconfont-css-prefix} {
font-size: @font-size-base;
}
}
&-sm .@{btnClassName}.@{btnClassName}-icon-only {
.square(@btn-height-sm);
padding-right: 0;
padding-left: 0;
}
} }
// Base styles of buttons // Base styles of buttons
// -------------------------------------------------- // --------------------------------------------------