@fesjs/fes-design
Version:
fes-design for PC
237 lines (233 loc) • 8.27 kB
JavaScript
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 };