hongluan-ui
Version:
Hongluan Component Library for Vue 3
681 lines (678 loc) • 26.2 kB
JavaScript
import { defineComponent, toRefs, provide, reactive, onMounted, nextTick, computed, resolveComponent, resolveDirective, withDirectives, openBlock, createElementBlock, normalizeClass, withModifiers, createVNode, withCtx, createElementVNode, withKeys, createSlots, renderSlot, Fragment, renderList, createBlock, createTextVNode, toDisplayString, createCommentVNode, vModelText, vShow } from 'vue';
import { HlInput } from '../../input/index.mjs';
import { placements } from '@popperjs/core';
import { useResizeObserver } from '@vueuse/core';
import { HlTag } from '../../tag/index.mjs';
import { HlTooltip } from '../../tooltip/index.mjs';
import { HlScrollbar } from '../../scrollbar/index.mjs';
import { HlIcon } from '../../icon/index.mjs';
import '../../system-icon/index.mjs';
import '../../popper/index.mjs';
import '../../../directives/index.mjs';
import '../../../utils/index.mjs';
import '../../../hooks/index.mjs';
import '../../../constants/index.mjs';
import { useSelectStates, useSelect } from './useSelect.mjs';
import { selectKey } from './token.mjs';
import HlOption from './option.mjs';
import HlOptions from './options.mjs';
import HlSelectMenu from './select-dropdown.mjs';
import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
import SystemSelectArrow from '../../system-icon/src/select-arrow.mjs';
import SystemClose from '../../system-icon/src/close.mjs';
import ClickOutside from '../../../directives/click-outside/index.mjs';
import { isValidComponentSize } from '../../../utils/vue/validator.mjs';
import { useTooltipContentProps } from '../../tooltip/src/content2.mjs';
import { useAriaProps } from '../../../hooks/use-aria/index.mjs';
import { useEmptyValuesProps } from '../../../hooks/use-empty-values/index.mjs';
import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs';
import { useLocale } from '../../../hooks/use-locale/index.mjs';
import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
import { useId } from '../../../hooks/use-id/index.mjs';
import { useDeprecateAppendToBody } from '../../popper/src/deprecation.mjs';
const _sfc_main = defineComponent({
name: "Select",
componentName: "Select",
components: {
HlInput,
HlSelectMenu,
HlOption,
HlOptions,
HlTag,
HlScrollbar,
HlTooltip,
HlIcon,
SystemSelectArrow,
SystemClose
},
directives: { ClickOutside },
props: {
name: String,
id: String,
modelValue: {
type: [Array, String, Number, Boolean, Object],
default: void 0
},
autocomplete: {
type: String,
default: "off"
},
automaticDropdown: Boolean,
size: {
type: String,
validator: isValidComponentSize
},
effect: {
type: String,
default: ""
},
disabled: Boolean,
clearable: Boolean,
filterable: Boolean,
allowCreate: Boolean,
block: Boolean,
loading: Boolean,
popperClass: {
type: String,
default: ""
},
popperOptions: {
type: Object,
default: () => ({})
},
remote: Boolean,
loadingText: String,
noMatchText: String,
noDataText: String,
remoteMethod: Function,
filterMethod: Function,
multiple: Boolean,
multipleLimit: {
type: Number,
default: 0
},
placeholder: {
type: String
},
defaultFirstOption: Boolean,
reserveKeyword: {
type: Boolean,
default: true
},
valueKey: {
type: String,
default: "value"
},
collapseTags: Boolean,
collapseTagsTooltip: Boolean,
maxCollapseTags: {
type: Number,
default: 1
},
popperAppendToBody: {
type: Boolean,
default: void 0
},
teleported: useTooltipContentProps.teleported,
persistent: {
type: Boolean,
default: true
},
fill: Boolean,
thin: Boolean,
round: Boolean,
tagType: {
type: String,
default: ""
},
popperOffset: {
type: Number,
default: 4
},
validateEvent: {
type: Boolean,
default: true
},
remoteShowSuffix: Boolean,
suffixTransition: {
type: Boolean,
default: true
},
placement: {
type: String,
values: placements,
default: "bottom-start"
},
...useAriaProps(["ariaLabel"]),
...useEmptyValuesProps
},
emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT, "remove-tag", "clear", "visible-change", "focus", "blur"],
setup(props, ctx) {
const { t } = useLocale();
const { namespace } = useNamespace();
const states = useSelectStates(props);
const contentId = useId();
const {
optionList,
optionsArray,
hoverOption,
selectSize,
readonly,
handleResize,
debouncedOnInputChange,
debouncedQueryChange,
deletePrevTag,
deleteTag,
deleteSelected,
handleOptionSelect,
scrollToOption,
setSelected,
managePlaceholder,
showClose,
selectDisabled,
selectFill,
iconClass,
showIcon,
showNewOption,
emptyText,
toggleLastOptionHitState,
resetInputState,
handleComposition,
onOptionCreate,
onOptionDestroy,
handleMenuEnter,
handleFocus,
blur,
focus,
handleBlur,
handleClearClick,
handleClose,
handleKeydownEscape,
toggleMenu,
selectOption,
getValueKey,
navigateOptions,
handleDeleteTooltipTag,
dropMenuVisible,
queryChange,
groupQueryChange,
reference,
input,
tooltipRef,
tagTooltipRef,
tags,
selectWrapper,
scrollbar,
handleMouseEnter,
handleMouseLeave,
showTagList,
collapseTagList
} = useSelect(props, states, ctx);
const {
selected,
filteredOptionsCount,
visible,
selectedLabel,
hoverIndex,
query,
inputHovering,
currentPlaceholder,
menuVisibleOnFocus,
isOnComposition,
options,
cachedOptions,
optionsCount
} = toRefs(states);
provide(selectKey, reactive({
props,
options,
optionsArray,
cachedOptions,
optionsCount,
filteredOptionsCount,
hoverIndex,
handleOptionSelect,
onOptionCreate,
onOptionDestroy,
selectWrapper,
selected,
setSelected,
queryChange,
groupQueryChange
}));
onMounted(() => {
var _a;
states.cachedPlaceHolder = currentPlaceholder.value = props.placeholder || (() => t("hl.select.placeholder"));
if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) {
currentPlaceholder.value = "";
}
useResizeObserver(selectWrapper, handleResize);
if ((_a = reference.value) == null ? void 0 : _a.$el) {
}
if (props.remote && props.multiple) {
}
nextTick(() => {
var _a2;
if ((_a2 = reference.value) == null ? void 0 : _a2.$el) {
}
if (ctx.slots.prefix) {
}
});
setSelected();
});
if (props.multiple && !Array.isArray(props.modelValue)) {
ctx.emit(UPDATE_MODEL_EVENT, []);
}
if (!props.multiple && Array.isArray(props.modelValue)) {
ctx.emit(UPDATE_MODEL_EVENT, "");
}
const popperPaneRef = computed(() => {
var _a, _b;
return (_b = (_a = tooltipRef.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef;
});
const { compatTeleported } = useDeprecateAppendToBody("Select", "popperAppendToBody");
const onOptionsRendered = (v) => {
optionList.value = v;
};
return {
namespace,
onOptionsRendered,
compatTeleported,
selectSize,
readonly,
handleResize,
debouncedOnInputChange,
debouncedQueryChange,
deletePrevTag,
deleteTag,
handleDeleteTooltipTag,
deleteSelected,
handleOptionSelect,
scrollToOption,
selected,
filteredOptionsCount,
visible,
selectedLabel,
hoverIndex,
query,
inputHovering,
currentPlaceholder,
menuVisibleOnFocus,
isOnComposition,
options,
managePlaceholder,
showClose,
selectDisabled,
selectFill,
iconClass,
showIcon,
showNewOption,
emptyText,
toggleLastOptionHitState,
resetInputState,
handleComposition,
handleMenuEnter,
handleFocus,
handleKeydownEscape,
blur,
handleBlur,
handleClearClick,
handleClose,
toggleMenu,
selectOption,
getValueKey,
navigateOptions,
dropMenuVisible,
focus,
reference,
input,
tooltipRef,
popperPaneRef,
tags,
selectWrapper,
scrollbar,
handleMouseEnter,
handleMouseLeave,
showTagList,
collapseTagList,
tagTooltipRef,
contentId,
hoverOption
};
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_hl_tag = resolveComponent("hl-tag");
const _component_hl_tooltip = resolveComponent("hl-tooltip");
const _component_system_select_arrow = resolveComponent("system-select-arrow");
const _component_hl_icon = resolveComponent("hl-icon");
const _component_system_close = resolveComponent("system-close");
const _component_hl_input = resolveComponent("hl-input");
const _component_hl_option = resolveComponent("hl-option");
const _component_hl_options = resolveComponent("hl-options");
const _component_hl_scrollbar = resolveComponent("hl-scrollbar");
const _component_hl_select_menu = resolveComponent("hl-select-menu");
const _directive_click_outside = resolveDirective("click-outside");
return withDirectives((openBlock(), createElementBlock("div", {
ref: "selectWrapper",
class: normalizeClass([
_ctx.namespace + "-input-select",
_ctx.selectSize,
_ctx.block ? "block" : ""
]),
onMouseenter: _ctx.handleMouseEnter,
onMouseleave: _ctx.handleMouseLeave,
onClick: withModifiers(_ctx.toggleMenu, ["stop"])
}, [
createVNode(_component_hl_tooltip, {
ref: "tooltipRef",
visible: _ctx.dropMenuVisible,
placement: _ctx.placement,
teleported: _ctx.compatTeleported,
offset: _ctx.popperOffset,
"popper-class": `${_ctx.namespace}-select-popper ${_ctx.popperClass}`,
"popper-options": _ctx.popperOptions,
"fallback-placements": ["bottom-start", "top-start", "right", "left"],
effect: _ctx.effect,
trigger: "click",
transition: "dropdown",
persistent: _ctx.persistent,
"show-arrow": false,
"stop-popper-mouse-event": false,
"gpu-acceleration": false,
onShow: _ctx.handleMenuEnter
}, {
default: withCtx(() => {
var _a;
return [
createElementVNode("div", {
class: "select-trigger",
onMouseenter: ($event) => _ctx.inputHovering = true,
onMouseleave: ($event) => _ctx.inputHovering = false
}, [
createVNode(_component_hl_input, {
id: _ctx.id,
ref: "reference",
modelValue: _ctx.selectedLabel,
"onUpdate:modelValue": ($event) => _ctx.selectedLabel = $event,
"native-type": "text",
placeholder: typeof _ctx.currentPlaceholder === "function" ? _ctx.currentPlaceholder() : _ctx.currentPlaceholder,
name: _ctx.name,
autocomplete: _ctx.autocomplete,
size: _ctx.selectSize,
fill: _ctx.selectFill,
thin: _ctx.thin,
round: _ctx.round,
disabled: _ctx.selectDisabled,
readonly: _ctx.readonly,
"validate-event": false,
label: _ctx.ariaLabel,
"aria-autocomplete": "none",
"aria-haspopup": "listbox",
class: normalizeClass({
"is-focus": _ctx.visible,
"is-tags": _ctx.selected.length,
"is-remote": !_ctx.showIcon
}),
tabindex: _ctx.multiple && _ctx.filterable ? "-1" : null,
role: "combobox",
"aria-activedescendant": ((_a = _ctx.hoverOption) == null ? void 0 : _a.id) || "",
"aria-controls": _ctx.contentId,
"aria-expanded": _ctx.dropMenuVisible,
onFocus: _ctx.handleFocus,
onBlur: _ctx.handleBlur,
onInput: _ctx.debouncedOnInputChange,
onPaste: _ctx.debouncedOnInputChange,
onCompositionstart: _ctx.handleComposition,
onCompositionupdate: _ctx.handleComposition,
onCompositionend: _ctx.handleComposition,
onKeydown: [
withKeys(withModifiers(($event) => _ctx.navigateOptions("next"), ["stop", "prevent"]), ["down"]),
withKeys(withModifiers(($event) => _ctx.navigateOptions("prev"), ["stop", "prevent"]), ["up"]),
withKeys(withModifiers(_ctx.selectOption, ["stop", "prevent"]), ["enter"]),
withKeys(_ctx.handleKeydownEscape, ["esc"]),
withKeys(($event) => _ctx.visible = false, ["tab"])
]
}, createSlots({
suffix: withCtx(() => [
renderSlot(_ctx.$slots, "suffix", {
className: `${_ctx.iconClass} ${!_ctx.showClose && _ctx.showIcon ? "visible" : ""}`
}, () => [
createVNode(_component_hl_icon, {
class: normalizeClass([_ctx.iconClass, !_ctx.showClose && _ctx.showIcon ? "visible" : ""])
}, {
default: withCtx(() => [
createVNode(_component_system_select_arrow)
]),
_: 1
}, 8, ["class"])
]),
renderSlot(_ctx.$slots, "clear", {}, () => [
createVNode(_component_hl_icon, {
class: normalizeClass(["select-close", _ctx.showClose && "visible"]),
onClick: _ctx.handleClearClick
}, {
default: withCtx(() => [
createVNode(_component_system_close)
]),
_: 1
}, 8, ["class", "onClick"])
])
]),
_: 2
}, [
_ctx.multiple ? {
name: "tags",
fn: withCtx(() => [
withDirectives(createElementVNode("div", {
ref: "tags",
tabindex: "-1",
class: normalizeClass(["input-tags", _ctx.selectDisabled ? "is-disabled" : ""]),
onClick: _ctx.focus
}, [
_ctx.collapseTags && _ctx.selected.length ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.showTagList, (item) => {
return openBlock(), createBlock(_component_hl_tag, {
key: _ctx.getValueKey(item),
closable: !_ctx.selectDisabled && !item.isDisabled,
active: item.hitState,
"disable-transitions": "",
size: _ctx.selectSize,
type: _ctx.tagType,
onClose: ($event) => _ctx.deleteTag($event, item)
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(item.currentLabel), 1)
]),
_: 2
}, 1032, ["closable", "active", "size", "type", "onClose"]);
}), 128)),
_ctx.selected.length > _ctx.maxCollapseTags ? (openBlock(), createBlock(_component_hl_tag, {
key: 0,
closable: false,
"disable-transitions": "",
size: _ctx.selectSize,
type: _ctx.tagType
}, {
default: withCtx(() => [
_ctx.collapseTagsTooltip ? (openBlock(), createBlock(_component_hl_tooltip, {
key: 0,
ref: "tagTooltipRef",
disabled: _ctx.dropMenuVisible,
"fallback-placements": ["bottom", "top", "right", "left"],
effect: _ctx.effect,
placement: "bottom",
teleported: false,
"popper-class": `collapse-tags-popper`
}, {
default: withCtx(() => [
createTextVNode(" + " + toDisplayString(_ctx.selected.length - _ctx.maxCollapseTags), 1)
]),
content: withCtx(() => [
createElementVNode("div", { class: "collapse-tags" }, [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.collapseTagList, (item) => {
return openBlock(), createElementBlock("div", {
key: _ctx.getValueKey(item),
class: "collapse-tag"
}, [
(openBlock(), createBlock(_component_hl_tag, {
key: _ctx.getValueKey(item),
class: "in-tooltip",
closable: !_ctx.selectDisabled && !item.isDisabled,
size: _ctx.selectSize,
hit: item.hitState,
type: _ctx.tagType,
"disable-transitions": "",
onClose: ($event) => _ctx.handleDeleteTooltipTag($event, item)
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(item.currentLabel), 1)
]),
_: 2
}, 1032, ["closable", "size", "hit", "type", "onClose"]))
]);
}), 128))
])
]),
_: 1
}, 8, ["disabled", "effect"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
createTextVNode(" + " + toDisplayString(_ctx.selected.length - _ctx.maxCollapseTags), 1)
], 2112))
]),
_: 1
}, 8, ["size", "type"])) : createCommentVNode("v-if", true)
], 64)) : createCommentVNode("v-if", true),
!_ctx.collapseTags ? renderSlot(_ctx.$slots, "tag", {
key: 1,
items: _ctx.selected
}, () => [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.selected, (item) => {
return openBlock(), createBlock(_component_hl_tag, {
key: _ctx.getValueKey(item),
closable: !_ctx.selectDisabled && !item.isDisabled,
active: item.hitState,
"disable-transitions": "",
size: _ctx.selectSize,
type: _ctx.tagType,
onClose: ($event) => _ctx.deleteTag($event, item)
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(item.currentLabel), 1)
]),
_: 2
}, 1032, ["closable", "active", "size", "type", "onClose"]);
}), 128))
]) : createCommentVNode("v-if", true),
_ctx.filterable ? withDirectives((openBlock(), createElementBlock("input", {
key: 2,
ref: "input",
"onUpdate:modelValue": ($event) => _ctx.query = $event,
type: "text",
class: normalizeClass([
"select-input",
_ctx.selectSize ? `is-${_ctx.selectSize}` : "",
_ctx.selectDisabled ? "is-disabled" : ""
]),
"aria-label": _ctx.ariaLabel,
disabled: _ctx.selectDisabled,
autocomplete: _ctx.autocomplete,
onFocus: _ctx.handleFocus,
onBlur: _ctx.handleBlur,
onKeyup: _ctx.managePlaceholder,
onKeydown: [
_ctx.resetInputState,
withKeys(withModifiers(($event) => _ctx.navigateOptions("next"), ["prevent"]), ["down"]),
withKeys(withModifiers(($event) => _ctx.navigateOptions("prev"), ["prevent"]), ["up"]),
withKeys(_ctx.handleKeydownEscape, ["esc"]),
withKeys(withModifiers(_ctx.selectOption, ["stop", "prevent"]), ["enter"]),
withKeys(_ctx.deletePrevTag, ["delete"]),
withKeys(($event) => _ctx.visible = false, ["tab"])
],
onCompositionstart: _ctx.handleComposition,
onCompositionupdate: _ctx.handleComposition,
onCompositionend: _ctx.handleComposition,
onInput: _ctx.debouncedQueryChange
}, null, 42, ["onUpdate:modelValue", "aria-label", "disabled", "autocomplete", "onFocus", "onBlur", "onKeyup", "onKeydown", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onInput"])), [
[vModelText, _ctx.query]
]) : createCommentVNode("v-if", true)
], 10, ["onClick"]), [
[vShow, _ctx.selected.length]
])
])
} : void 0,
_ctx.$slots.prefix ? {
name: "prefix",
fn: withCtx(() => [
createElementVNode("div", null, [
renderSlot(_ctx.$slots, "prefix")
])
])
} : void 0
]), 1032, ["id", "modelValue", "onUpdate:modelValue", "placeholder", "name", "autocomplete", "size", "fill", "thin", "round", "disabled", "readonly", "label", "class", "tabindex", "aria-activedescendant", "aria-controls", "aria-expanded", "onFocus", "onBlur", "onInput", "onPaste", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onKeydown"])
], 40, ["onMouseenter", "onMouseleave"])
];
}),
content: withCtx(() => [
createVNode(_component_hl_select_menu, null, createSlots({
default: withCtx(() => [
withDirectives(createVNode(_component_hl_scrollbar, {
id: _ctx.contentId,
ref: "scrollbar",
tag: "ul",
"wrap-class": "select-dropdown-wrap",
"view-class": "select-dropdown-list",
class: normalizeClass({ "is-empty": !_ctx.allowCreate && Boolean(_ctx.query) && _ctx.filteredOptionsCount === 0 }),
role: "listbox",
"aria-label": _ctx.ariaLabel,
"aria-orientation": "vertical",
onAtEnd: ($event) => _ctx.$emit("at-end")
}, {
default: withCtx(() => [
_ctx.showNewOption ? (openBlock(), createBlock(_component_hl_option, {
key: 0,
value: _ctx.query,
created: true
}, null, 8, ["value"])) : createCommentVNode("v-if", true),
createVNode(_component_hl_options, { onUpdateOptions: _ctx.onOptionsRendered }, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["onUpdateOptions"])
]),
_: 3
}, 8, ["id", "class", "aria-label", "onAtEnd"]), [
[vShow, _ctx.options.size > 0 && !_ctx.loading]
]),
_ctx.emptyText && (!_ctx.allowCreate || _ctx.loading || _ctx.allowCreate && _ctx.options.size === 0) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
_ctx.$slots.empty ? renderSlot(_ctx.$slots, "empty", { key: 0 }) : (openBlock(), createElementBlock("p", {
key: 1,
class: "select-dropdown-empty"
}, toDisplayString(_ctx.emptyText), 1))
], 2112)) : createCommentVNode("v-if", true)
]),
_: 2
}, [
_ctx.$slots.header ? {
name: "header",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "header")
])
} : void 0,
_ctx.$slots.footer ? {
name: "footer",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "footer")
])
} : void 0
]), 1024)
]),
_: 3
}, 8, ["visible", "placement", "teleported", "offset", "popper-class", "popper-options", "effect", "persistent", "onShow"])
], 42, ["onMouseenter", "onMouseleave", "onClick"])), [
[_directive_click_outside, _ctx.handleClose, _ctx.popperPaneRef]
]);
}
var Select = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { Select as default };
//# sourceMappingURL=select.mjs.map