refactor: tree select (#6296)
parent
124aae72a4
commit
799eeed346
|
@ -47,7 +47,7 @@ import './cascader/style';
|
|||
// import './layout/style';
|
||||
// import './anchor/style';
|
||||
// import './list/style';
|
||||
import './tree-select/style';
|
||||
// import './tree-select/style';
|
||||
import './drawer/style';
|
||||
// import './skeleton/style';
|
||||
// import './comment/style';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
category: Components
|
||||
type: Data Entry
|
||||
title: TreeSelect
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/Ax4DA0njr/TreeSelect.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*DfTMRYSDngEAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
Tree selection control.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App, ExtractPropTypes, PropType } from 'vue';
|
||||
import type { App, ExtractPropTypes } from 'vue';
|
||||
import { computed, ref, watchEffect, defineComponent } from 'vue';
|
||||
import VcTreeSelect, {
|
||||
TreeNode,
|
||||
|
@ -28,6 +28,11 @@ import type { SelectCommonPlacement } from '../_util/transition';
|
|||
import { getTransitionDirection } from '../_util/transition';
|
||||
import type { InputStatus } from '../_util/statusUtils';
|
||||
import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
|
||||
import { booleanType, stringType, objectType, someType, functionType } from '../_util/type';
|
||||
|
||||
// CSSINJS
|
||||
import useSelectStyle from '../select/style';
|
||||
import useStyle from './style';
|
||||
|
||||
const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
|
||||
if (transitionName !== undefined) {
|
||||
|
@ -62,15 +67,15 @@ export function treeSelectProps<
|
|||
'customSlots',
|
||||
]),
|
||||
suffixIcon: PropTypes.any,
|
||||
size: { type: String as PropType<SizeType> },
|
||||
bordered: { type: Boolean, default: undefined },
|
||||
treeLine: { type: [Boolean, Object] as PropType<TreeProps['showLine']>, default: undefined },
|
||||
replaceFields: { type: Object as PropType<FieldNames> },
|
||||
placement: String as PropType<SelectCommonPlacement>,
|
||||
status: String as PropType<InputStatus>,
|
||||
'onUpdate:value': { type: Function as PropType<(value: any) => void> },
|
||||
'onUpdate:treeExpandedKeys': { type: Function as PropType<(keys: Key[]) => void> },
|
||||
'onUpdate:searchValue': { type: Function as PropType<(value: string) => void> },
|
||||
size: stringType<SizeType>(),
|
||||
bordered: booleanType(),
|
||||
treeLine: someType<TreeProps['showLine']>([Boolean, Object]),
|
||||
replaceFields: objectType<FieldNames>(),
|
||||
placement: stringType<SelectCommonPlacement>(),
|
||||
status: stringType<InputStatus>(),
|
||||
'onUpdate:value': functionType<(value: any) => void>(),
|
||||
'onUpdate:treeExpandedKeys': functionType<(keys: Key[]) => void>(),
|
||||
'onUpdate:searchValue': functionType<(value: string) => void>(),
|
||||
};
|
||||
}
|
||||
export type TreeSelectProps = Partial<ExtractPropTypes<ReturnType<typeof treeSelectProps>>>;
|
||||
|
@ -149,10 +154,19 @@ const TreeSelect = defineComponent({
|
|||
const treePrefixCls = computed(() => getPrefixCls('select-tree', props.prefixCls));
|
||||
const treeSelectPrefixCls = computed(() => getPrefixCls('tree-select', props.prefixCls));
|
||||
|
||||
// style
|
||||
const [wrapSelectSSR, hashId] = useSelectStyle(prefixCls);
|
||||
const [wrapTreeSelectSSR] = useStyle(treeSelectPrefixCls, treePrefixCls);
|
||||
|
||||
const mergedDropdownClassName = computed(() =>
|
||||
classNames(props.dropdownClassName, `${treeSelectPrefixCls.value}-dropdown`, {
|
||||
[`${treeSelectPrefixCls.value}-dropdown-rtl`]: direction.value === 'rtl',
|
||||
}),
|
||||
classNames(
|
||||
props.dropdownClassName,
|
||||
`${treeSelectPrefixCls.value}-dropdown`,
|
||||
{
|
||||
[`${treeSelectPrefixCls.value}-dropdown-rtl`]: direction.value === 'rtl',
|
||||
},
|
||||
hashId.value,
|
||||
),
|
||||
);
|
||||
|
||||
const isMultiple = computed(() => !!(props.treeCheckable || props.multiple));
|
||||
|
@ -249,62 +263,65 @@ const TreeSelect = defineComponent({
|
|||
},
|
||||
getStatusClassNames(prefixCls.value, mergedStatus.value, hasFeedback),
|
||||
attrs.class,
|
||||
hashId.value,
|
||||
);
|
||||
const otherProps: any = {};
|
||||
if (props.treeData === undefined && slots.default) {
|
||||
otherProps.children = flattenChildren(slots.default());
|
||||
}
|
||||
return (
|
||||
<VcTreeSelect
|
||||
{...attrs}
|
||||
{...selectProps}
|
||||
virtual={virtual.value}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth.value}
|
||||
id={id}
|
||||
fieldNames={fieldNames}
|
||||
ref={treeSelectRef}
|
||||
prefixCls={prefixCls.value}
|
||||
class={mergedClassName}
|
||||
listHeight={listHeight}
|
||||
listItemHeight={listItemHeight}
|
||||
treeLine={!!treeLine}
|
||||
inputIcon={suffixIcon}
|
||||
multiple={multiple}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
switcherIcon={(nodeProps: SwitcherIconProps) =>
|
||||
renderSwitcherIcon(
|
||||
treePrefixCls.value,
|
||||
switcherIcon,
|
||||
nodeProps,
|
||||
slots.leafIcon,
|
||||
treeLine,
|
||||
)
|
||||
}
|
||||
showTreeIcon={treeIcon as any}
|
||||
notFoundContent={mergedNotFound}
|
||||
getPopupContainer={getPopupContainer.value}
|
||||
treeMotion={null}
|
||||
dropdownClassName={mergedDropdownClassName.value}
|
||||
choiceTransitionName={choiceTransitionName.value}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
onSearch={handleSearch}
|
||||
onTreeExpand={handleTreeExpand}
|
||||
v-slots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
{...otherProps}
|
||||
transitionName={transitionName.value}
|
||||
customSlots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
|
||||
placement={placement.value}
|
||||
showArrow={hasFeedback || showArrow}
|
||||
/>
|
||||
return wrapSelectSSR(
|
||||
wrapTreeSelectSSR(
|
||||
<VcTreeSelect
|
||||
{...attrs}
|
||||
{...selectProps}
|
||||
virtual={virtual.value}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth.value}
|
||||
id={id}
|
||||
fieldNames={fieldNames}
|
||||
ref={treeSelectRef}
|
||||
prefixCls={prefixCls.value}
|
||||
class={mergedClassName}
|
||||
listHeight={listHeight}
|
||||
listItemHeight={listItemHeight}
|
||||
treeLine={!!treeLine}
|
||||
inputIcon={suffixIcon}
|
||||
multiple={multiple}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
switcherIcon={(nodeProps: SwitcherIconProps) =>
|
||||
renderSwitcherIcon(
|
||||
treePrefixCls.value,
|
||||
switcherIcon,
|
||||
nodeProps,
|
||||
slots.leafIcon,
|
||||
treeLine,
|
||||
)
|
||||
}
|
||||
showTreeIcon={treeIcon as any}
|
||||
notFoundContent={mergedNotFound}
|
||||
getPopupContainer={getPopupContainer.value}
|
||||
treeMotion={null}
|
||||
dropdownClassName={mergedDropdownClassName.value}
|
||||
choiceTransitionName={choiceTransitionName.value}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
onSearch={handleSearch}
|
||||
onTreeExpand={handleTreeExpand}
|
||||
v-slots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
{...otherProps}
|
||||
transitionName={transitionName.value}
|
||||
customSlots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
|
||||
placement={placement.value}
|
||||
showArrow={hasFeedback || showArrow}
|
||||
/>,
|
||||
),
|
||||
);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ category: Components
|
|||
type: 数据录入
|
||||
title: TreeSelect
|
||||
subtitle: 树选择
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/Ax4DA0njr/TreeSelect.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*DfTMRYSDngEAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
树型选择控件。
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../tree/style/mixin';
|
||||
@import '../../checkbox/style/mixin';
|
||||
|
||||
@tree-select-prefix-cls: ~'@{ant-prefix}-tree-select';
|
||||
@select-tree-prefix-cls: ~'@{ant-prefix}-select-tree';
|
||||
|
||||
.antCheckboxFn(@checkbox-prefix-cls: ~'@{select-tree-prefix-cls}-checkbox');
|
||||
|
||||
.@{tree-select-prefix-cls} {
|
||||
// ======================= Dropdown =======================
|
||||
&-dropdown {
|
||||
padding: @padding-xs (@padding-xs / 2);
|
||||
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
// ======================== Tree ========================
|
||||
.@{select-tree-prefix-cls} {
|
||||
border-radius: 0;
|
||||
|
||||
&-list-holder-inner {
|
||||
align-items: stretch;
|
||||
|
||||
.@{select-tree-prefix-cls}-treenode {
|
||||
.@{select-tree-prefix-cls}-node-content-wrapper {
|
||||
flex: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-tree-prefix-cls} {
|
||||
.antTreeFn(@select-tree-prefix-cls);
|
||||
|
||||
// change switcher icon rotation in rtl direction
|
||||
& &-switcher {
|
||||
&_close {
|
||||
.@{select-tree-prefix-cls}-switcher-icon {
|
||||
svg {
|
||||
.@{tree-select-prefix-cls}-dropdown-rtl & {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-loading-icon {
|
||||
.@{tree-select-prefix-cls}-dropdown-rtl & {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,74 @@
|
|||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
import type { Ref } from 'vue';
|
||||
import { getStyle as getCheckboxStyle } from '../../checkbox/style';
|
||||
import type { AliasToken, FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { genTreeStyle } from '../../tree/style';
|
||||
|
||||
// style dependencies
|
||||
// deps-lint-skip: tree, form
|
||||
import '../../select/style';
|
||||
import '../../empty/style';
|
||||
interface TreeSelectToken extends FullToken<'TreeSelect'> {
|
||||
treePrefixCls: string;
|
||||
}
|
||||
|
||||
// =============================== Base ===============================
|
||||
const genBaseStyle: GenerateStyle<TreeSelectToken> = token => {
|
||||
const { componentCls, treePrefixCls, colorBgElevated } = token;
|
||||
const treeCls = `.${treePrefixCls}`;
|
||||
|
||||
return [
|
||||
// ======================================================
|
||||
// == Dropdown ==
|
||||
// ======================================================
|
||||
{
|
||||
[`${componentCls}-dropdown`]: [
|
||||
{
|
||||
padding: `${token.paddingXS}px ${token.paddingXS / 2}px`,
|
||||
},
|
||||
|
||||
// ====================== Tree ======================
|
||||
genTreeStyle(
|
||||
treePrefixCls,
|
||||
mergeToken<AliasToken>(token, { colorBgContainer: colorBgElevated }),
|
||||
),
|
||||
{
|
||||
[treeCls]: {
|
||||
borderRadius: 0,
|
||||
'&-list-holder-inner': {
|
||||
alignItems: 'stretch',
|
||||
|
||||
[`${treeCls}-treenode`]: {
|
||||
[`${treeCls}-node-content-wrapper`]: {
|
||||
flex: 'auto',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ==================== Checkbox ====================
|
||||
getCheckboxStyle(`${treePrefixCls}-checkbox`, token),
|
||||
|
||||
// ====================== RTL =======================
|
||||
{
|
||||
'&-rtl': {
|
||||
direction: 'rtl',
|
||||
|
||||
[`${treeCls}-switcher${treeCls}-switcher_close`]: {
|
||||
[`${treeCls}-switcher-icon svg`]: {
|
||||
transform: 'rotate(90deg)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default function useTreeSelectStyle(prefixCls: Ref<string>, treePrefixCls: Ref<string>) {
|
||||
return genComponentStyleHook('TreeSelect', token => {
|
||||
const treeSelectToken = mergeToken<TreeSelectToken>(token, {
|
||||
treePrefixCls: treePrefixCls.value,
|
||||
});
|
||||
return [genBaseStyle(treeSelectToken)];
|
||||
})(prefixCls);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue