feat: tree-select add context size

pull/6299/head
tangjinzhou 2023-02-20 11:04:25 +08:00
parent 799eeed346
commit 087dfa2f1b
9 changed files with 44 additions and 26 deletions

View File

@ -1,9 +1,10 @@
import { computed, inject } from 'vue'; import { computed, h, inject } from 'vue';
import { defaultConfigProvider, configProviderKey } from '../context'; import { defaultConfigProvider, configProviderKey } from '../context';
import { DefaultRenderEmpty } from '../renderEmpty';
export default (name: string, props: Record<any, any>) => { export default (name: string, props: Record<any, any>) => {
const configProvider = inject(configProviderKey, { const configProvider = inject(configProviderKey, {
...defaultConfigProvider, ...defaultConfigProvider,
renderEmpty: () => null, renderEmpty: (name?: string) => h(DefaultRenderEmpty, { componentName: name }),
}); });
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls)); const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
const direction = computed(() => props.direction ?? configProvider.direction?.value); const direction = computed(() => props.direction ?? configProvider.direction?.value);

View File

@ -32,7 +32,7 @@ Select component to select value from options.
| defaultActiveFirstOption | Whether active first option by default | boolean | true | | | defaultActiveFirstOption | Whether active first option by default | boolean | true | |
| defaultOpen | Initial open state of dropdown | boolean | - | | | defaultOpen | Initial open state of dropdown | boolean | - | |
| disabled | Whether disabled select | boolean | false | | | disabled | Whether disabled select | boolean | false | |
| dropdownClassName | className of dropdown menu | string | - | | | popupClassName | className of dropdown menu | string | - | 4.0 |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | | | dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | |
| dropdownMenuStyle | additional style applied to dropdown menu | object | - | | | dropdownMenuStyle | additional style applied to dropdown menu | object | - | |
| dropdownRender | Customize dropdown content | ({menuNode: VNode, props}) => VNode \| v-slot | - | | | dropdownRender | Customize dropdown content | ({menuNode: VNode, props}) => VNode \| v-slot | - | |

View File

@ -142,10 +142,11 @@ const Select = defineComponent({
} = useConfigInject('select', props); } = useConfigInject('select', props);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const mergedSize = computed(() => compactSize.value || contextSize.value); const mergedSize = computed(() => compactSize.value || contextSize.value);
// style
const [wrapSSR, hashId] = useStyle(prefixCls);
const contextDisabled = useInjectDisabled(); const contextDisabled = useInjectDisabled();
const mergedDisabled = computed(() => disabled.value ?? contextDisabled.value); const mergedDisabled = computed(() => disabled.value ?? contextDisabled.value);
// style
const [wrapSSR, hashId] = useStyle(prefixCls);
const rootPrefixCls = computed(() => getPrefixCls()); const rootPrefixCls = computed(() => getPrefixCls());
// ===================== Placement ===================== // ===================== Placement =====================
const placement = computed(() => { const placement = computed(() => {

View File

@ -33,7 +33,7 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*zo76T7KQx2UAAAAAAA
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | | | defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | | | defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| disabled | 是否禁用 | boolean | false | | | disabled | 是否禁用 | boolean | false | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | | | popupClassName | 下拉菜单的 className 属性 | string | - | 4.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | | | dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | | | dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | |
| dropdownRender | 自定义下拉框内容 | ({menuNode: VNode, props}) => VNode \| v-slot | - | | | dropdownRender | 自定义下拉框内容 | ({menuNode: VNode, props}) => VNode \| v-slot | - | |

View File

@ -97,7 +97,7 @@ const Space = defineComponent({
const horizontalSizeVal = horizontalSize.value; const horizontalSizeVal = horizontalSize.value;
const latestIndex = len - 1; const latestIndex = len - 1;
return ( return (
<div {...attrs} class={cn.value} style={style.value}> <div {...attrs} class={cn.value} style={[style.value, attrs.style as any]}>
{items.map((child, index) => { {items.map((child, index) => {
let itemStyle: CSSProperties = {}; let itemStyle: CSSProperties = {};
if (!supportFlexGap.value) { if (!supportFlexGap.value) {

View File

@ -20,7 +20,7 @@ Tree selection control.
| allowClear | Whether allow clear | boolean | false | | | | allowClear | Whether allow clear | boolean | false | | |
| defaultValue | To set the initial selected treeNode(s). | string\|string\[] | - | | | | defaultValue | To set the initial selected treeNode(s). | string\|string\[] | - | | |
| disabled | Disabled or not | boolean | false | | | | disabled | Disabled or not | boolean | false | | |
| dropdownClassName | className of dropdown menu | string | - | | | | popupClassName | className of dropdown menu | string | - | | 4.0 |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | | | | dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | | |
| dropdownStyle | To set the style of the dropdown menu | object | - | | | | dropdownStyle | To set the style of the dropdown menu | object | - | | |
| fieldNames | Replace the label,value, key and children fields in treeNode with the corresponding fields in treeData | object | {children:'children', label:'title', key:'key', value: 'value' } | | 3.0.0 | | fieldNames | Replace the label,value, key and children fields in treeNode with the corresponding fields in treeData | object | {children:'children', label:'title', key:'key', value: 'value' } | | 3.0.0 |

View File

@ -1,5 +1,5 @@
import type { App, ExtractPropTypes } from 'vue'; import type { App, ExtractPropTypes } from 'vue';
import { computed, ref, watchEffect, defineComponent } from 'vue'; import { computed, ref, defineComponent } from 'vue';
import VcTreeSelect, { import VcTreeSelect, {
TreeNode, TreeNode,
SHOW_ALL, SHOW_ALL,
@ -33,6 +33,8 @@ import { booleanType, stringType, objectType, someType, functionType } from '../
// CSSINJS // CSSINJS
import useSelectStyle from '../select/style'; import useSelectStyle from '../select/style';
import useStyle from './style'; import useStyle from './style';
import { useCompactItemContext } from '../space/Compact';
import { useInjectDisabled } from '../config-provider/DisabledContext';
const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => { const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
if (transitionName !== undefined) { if (transitionName !== undefined) {
@ -73,6 +75,9 @@ export function treeSelectProps<
replaceFields: objectType<FieldNames>(), replaceFields: objectType<FieldNames>(),
placement: stringType<SelectCommonPlacement>(), placement: stringType<SelectCommonPlacement>(),
status: stringType<InputStatus>(), status: stringType<InputStatus>(),
popupClassName: String,
/** @deprecated Please use `popupClassName` instead */
dropdownClassName: String,
'onUpdate:value': functionType<(value: any) => void>(), 'onUpdate:value': functionType<(value: any) => void>(),
'onUpdate:treeExpandedKeys': functionType<(keys: Key[]) => void>(), 'onUpdate:treeExpandedKeys': functionType<(keys: Key[]) => void>(),
'onUpdate:searchValue': functionType<(value: string) => void>(), 'onUpdate:searchValue': functionType<(value: string) => void>(),
@ -105,18 +110,21 @@ const TreeSelect = defineComponent({
!(props.treeData === undefined && slots.default), !(props.treeData === undefined && slots.default),
'`children` of TreeSelect is deprecated. Please use `treeData` instead.', '`children` of TreeSelect is deprecated. Please use `treeData` instead.',
); );
watchEffect(() => { devWarning(
devWarning( props.multiple !== false || !props.treeCheckable,
props.multiple !== false || !props.treeCheckable, 'TreeSelect',
'TreeSelect', '`multiple` will always be `true` when `treeCheckable` is true',
'`multiple` will always be `true` when `treeCheckable` is true', );
); devWarning(
devWarning( props.replaceFields === undefined,
props.replaceFields === undefined, 'TreeSelect',
'TreeSelect', '`replaceFields` is deprecated, please use fieldNames instead',
'`replaceFields` is deprecated, please use fieldNames instead', );
); devWarning(
}); !props.dropdownClassName,
'TreeSelect',
'`dropdownClassName` is deprecated. Please use `popupClassName` instead.',
);
const formItemContext = useInjectFormItemContext(); const formItemContext = useInjectFormItemContext();
const formItemInputContext = FormItemInputContext.useInject(); const formItemInputContext = FormItemInputContext.useInject();
@ -127,10 +135,15 @@ const TreeSelect = defineComponent({
direction, direction,
virtual, virtual,
dropdownMatchSelectWidth, dropdownMatchSelectWidth,
size, size: contextSize,
getPopupContainer, getPopupContainer,
getPrefixCls, getPrefixCls,
disabled,
} = useConfigInject('select', props); } = useConfigInject('select', props);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const mergedSize = computed(() => compactSize.value || contextSize.value);
const contextDisabled = useInjectDisabled();
const mergedDisabled = computed(() => disabled.value ?? contextDisabled.value);
const rootPrefixCls = computed(() => getPrefixCls()); const rootPrefixCls = computed(() => getPrefixCls());
// ===================== Placement ===================== // ===================== Placement =====================
const placement = computed(() => { const placement = computed(() => {
@ -160,7 +173,7 @@ const TreeSelect = defineComponent({
const mergedDropdownClassName = computed(() => const mergedDropdownClassName = computed(() =>
classNames( classNames(
props.dropdownClassName, props.popupClassName || props.dropdownClassName,
`${treeSelectPrefixCls.value}-dropdown`, `${treeSelectPrefixCls.value}-dropdown`,
{ {
[`${treeSelectPrefixCls.value}-dropdown-rtl`]: direction.value === 'rtl', [`${treeSelectPrefixCls.value}-dropdown-rtl`]: direction.value === 'rtl',
@ -255,13 +268,14 @@ const TreeSelect = defineComponent({
const mergedClassName = classNames( const mergedClassName = classNames(
!customizePrefixCls && treeSelectPrefixCls.value, !customizePrefixCls && treeSelectPrefixCls.value,
{ {
[`${prefixCls.value}-lg`]: size.value === 'large', [`${prefixCls.value}-lg`]: mergedSize.value === 'large',
[`${prefixCls.value}-sm`]: size.value === 'small', [`${prefixCls.value}-sm`]: mergedSize.value === 'small',
[`${prefixCls.value}-rtl`]: direction.value === 'rtl', [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
[`${prefixCls.value}-borderless`]: !bordered, [`${prefixCls.value}-borderless`]: !bordered,
[`${prefixCls.value}-in-form-item`]: isFormItemInput, [`${prefixCls.value}-in-form-item`]: isFormItemInput,
}, },
getStatusClassNames(prefixCls.value, mergedStatus.value, hasFeedback), getStatusClassNames(prefixCls.value, mergedStatus.value, hasFeedback),
compactItemClassnames.value,
attrs.class, attrs.class,
hashId.value, hashId.value,
); );
@ -274,6 +288,7 @@ const TreeSelect = defineComponent({
<VcTreeSelect <VcTreeSelect
{...attrs} {...attrs}
{...selectProps} {...selectProps}
disabled={mergedDisabled.value}
virtual={virtual.value} virtual={virtual.value}
dropdownMatchSelectWidth={dropdownMatchSelectWidth.value} dropdownMatchSelectWidth={dropdownMatchSelectWidth.value}
id={id} id={id}

View File

@ -21,7 +21,7 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*DfTMRYSDngEAAAAAAA
| allowClear | 显示清除按钮 | boolean | false | | | | allowClear | 显示清除按钮 | boolean | false | | |
| defaultValue | 指定默认选中的条目 | string/string\[] | - | | | | defaultValue | 指定默认选中的条目 | string/string\[] | - | | |
| disabled | 是否禁用 | boolean | false | | | | disabled | 是否禁用 | boolean | false | | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | | | | popupClassName | 下拉菜单的 className 属性 | string | - | | 4.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | | | | dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | | |
| dropdownStyle | 下拉菜单的样式 | object | - | | | | dropdownStyle | 下拉菜单的样式 | object | - | | |
| fieldNames | 替换 treeNode 中 label,value,key,children 字段为 treeData 中对应的字段 | object | {children:'children', label:'title', value: 'value' } | | 3.0.0 | | fieldNames | 替换 treeNode 中 label,value,key,children 字段为 treeData 中对应的字段 | object | {children:'children', label:'title', value: 'value' } | | 3.0.0 |

View File

@ -679,6 +679,7 @@ export default defineComponent({
const restProps = omit(props, [ const restProps = omit(props, [
'id', 'id',
'prefixCls', 'prefixCls',
'customSlots',
// Value // Value
'value', 'value',