UNPKG

@fesjs/fes-design

Version:
237 lines (233 loc) 8.27 kB
import { defineComponent, computed, ref, createVNode, nextTick } from 'vue'; import _defineProperty from '@babel/runtime/helpers/esm/defineProperty'; import { isUndefined, isArray } from 'lodash-es'; import getPrefixCls from '../_util/getPrefixCls'; import LoadingOutlined from '../icon/LoadingOutlined'; import RightOutlined from '../icon/RightOutlined'; import CheckOutlined from '../icon/CheckOutlined'; import Checkbox from '../checkbox'; import Radio from '../radio'; import Ellipsis from '../ellipsis'; import Tooltip from '../tooltip'; import { useLocale } from '../config-provider/useLocale'; import useCascaderNode from './useCascaderNode'; import { COMPONENT_NAME, EXPAND_TRIGGER, CHECK_STRATEGY } from './const'; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } const prefixCls = getPrefixCls('cascader-node'); const cascaderNodeProps = { value: { type: [String, Number], required: true }, label: { type: String, required: true }, disabled: { type: Boolean }, selectable: { type: Boolean }, checkable: { type: Boolean }, isLeaf: { type: Boolean, default: false }, level: { type: Number, default: 0 } }; var cascaderNode = defineComponent({ name: COMPONENT_NAME.CASCADER_NODE, props: cascaderNodeProps, setup(props, _ref) { let { slots } = _ref; const { root, isExpanded, isInitLoading, isSelected, isChecked, isIndeterminate, isLoaded, isCheckLoaded, isActive } = useCascaderNode(props); const disabled = computed(() => props.disabled); const selectable = computed(() => isUndefined(props.selectable) ? root.props.selectable : props.selectable); const checkable = computed(() => isUndefined(props.checkable) ? root.props.checkable : props.checkable); const classList = computed(() => [prefixCls, disabled.value && 'is-disabled', isExpanded.value && 'is-expanded', isSelected.value && 'is-selected', (isChecked.value || isIndeterminate.value) && 'is-checked', isActive.value && 'is-active'].filter(Boolean)); const { t } = useLocale(); const loadingRequiredMessage = computed(() => t('cascader.loadingRequiredMessage', { label: props.label })); const isLoading = ref(false); const handleClickSwitcher = async event => { if (isInitLoading.value || isLoading.value) { return; } const node = root.nodeList[props.value]; if (!isLoaded.value) { isLoading.value = true; try { const children = await root.props.loadData(_objectSpread({}, node.origin)); if (isArray(children)) { node.origin.children = children; // 当前操作节点信息重新生成后再继续展开操作 await nextTick(); root.expandNode(props.value, event); } } catch (e) { console.error(e); } isLoading.value = false; } else { root.expandNode(props.value, event); } }; const handleHoverSwitcher = event => { if (root.props.expandTrigger !== EXPAND_TRIGGER.HOVER) { return; } handleClickSwitcher(event); }; const handleClickContent = event => { // 若为非叶子节点,则直接展开操作 if (!props.isLeaf) { return handleClickSwitcher(event); } if (disabled.value) { return; } // 再 select 行为 if (selectable.value) { return root.selectNode(props.value, event); } // 再 check 行为 if (checkable.value && isCheckLoaded.value) { return root.checkNode(props.value, event); } }; const handleHoverContent = event => { if (root.props.expandTrigger !== EXPAND_TRIGGER.HOVER) { return; } // 若为非叶子节点,则直接展开操作 if (!props.isLeaf) { return handleClickSwitcher(event); } }; const handleClickCheckbox = event => { if (disabled.value) { return; } if (checkable.value && isCheckLoaded.value) { return root.checkNode(props.value, event); } }; const handleClickRadio = event => { if (disabled.value) { return; } // 仅 select 行为 if (selectable.value) { return root.selectNode(props.value, event); } }; const handleStopClickPrefix = event => { event.stopPropagation(); }; const renderSwitcher = () => { const currentClassList = [`${prefixCls}-switcher`, disabled.value && 'is-disabled'].filter(Boolean); if (props.isLeaf) { return createVNode("span", { "class": currentClassList }, [!checkable.value && isSelected.value ? createVNode(CheckOutlined, { "class": 'is-checked' }, null) : null]); } return createVNode("span", { "class": currentClassList, "onClick": handleClickSwitcher, "onMouseenter": handleHoverSwitcher }, [isInitLoading.value || isLoading.value ? createVNode(LoadingOutlined, null, null) : createVNode(RightOutlined, null, null)]); }; const renderCheckbox = () => { if (checkable.value) { return createVNode("span", { "class": `${prefixCls}-checkbox` }, [isCheckLoaded.value ? createVNode(Checkbox, { "indeterminate": isIndeterminate.value, "modelValue": isChecked.value, "onChange": handleClickCheckbox, "disabled": props.disabled }, null) : createVNode(Tooltip, { "placement": "top-start", "content": loadingRequiredMessage.value }, { default: () => [createVNode(Checkbox, { "indeterminate": isIndeterminate.value, "modelValue": isChecked.value, "disabled": true }, null)] })]); } return null; }; const renderRadio = () => { if (!checkable.value && selectable.value && root.props.checkStrictly === CHECK_STRATEGY.ALL) { return createVNode("span", { "class": `${prefixCls}-radio` }, [createVNode(Radio, { "modelValue": isSelected.value, "onChange": handleClickRadio, "disabled": props.disabled }, null)]); } return null; }; const renderPrefix = () => { var _slots$prefix; if (!slots.prefix) { return null; } return createVNode("span", { "class": `${prefixCls}-content-prefix`, "onClick": handleStopClickPrefix }, [(_slots$prefix = slots.prefix) === null || _slots$prefix === void 0 ? void 0 : _slots$prefix.call(slots)]); }; const renderSuffix = () => { var _slots$suffix; if (!slots.suffix) { return null; } return createVNode("span", { "class": `${prefixCls}-content-suffix`, "onClick": handleStopClickPrefix }, [(_slots$suffix = slots.suffix) === null || _slots$suffix === void 0 ? void 0 : _slots$suffix.call(slots)]); }; return () => createVNode("div", { "class": classList.value, "data-value": props.value, "role": "cascader-node" }, [renderCheckbox(), renderRadio(), createVNode("span", { "class": `${prefixCls}-content`, "onClick": handleClickContent, "onMouseenter": handleHoverContent }, [renderPrefix(), createVNode("span", { "class": `${prefixCls}-content-label` }, [createVNode(Ellipsis, { "content": props.label }, null)]), renderSuffix()]), renderSwitcher()]); } }); export { cascaderNode as default };