UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

357 lines (356 loc) • 11.8 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { computed, defineComponent, nextTick, ref, watch } from "vue"; import { call, isEmpty, preventDefault, raf, toNumber } from "@varlet/shared"; import { useClickOutside, useEventListener, useVModel } from "@varlet/use"; import VarFormDetails from "../form-details/index.mjs"; import { useForm } from "../form/provide.mjs"; import VarInput from "../input/index.mjs"; import VarMenuOption from "../menu-option/index.mjs"; import VarMenuSelect from "../menu-select/index.mjs"; import { createNamespace, useValidation } from "../utils/components.mjs"; import { props } from "./props.mjs"; const { name, n } = createNamespace("auto-complete"); import { renderSlot as _renderSlot, resolveComponent as _resolveComponent, mergeProps as _mergeProps, withCtx as _withCtx, createSlots as _createSlots, createVNode as _createVNode, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, createBlock as _createBlock, normalizeClass as _normalizeClass, createElementVNode as _createElementVNode } from "vue"; const _hoisted_1 = ["tabindex"]; function __render__(_ctx, _cache) { const _component_var_input = _resolveComponent("var-input"); const _component_var_menu_option = _resolveComponent("var-menu-option"); const _component_var_menu_select = _resolveComponent("var-menu-select"); const _component_var_form_details = _resolveComponent("var-form-details"); return _openBlock(), _createElementBlock("div", { ref: "root", class: _normalizeClass(_ctx.n()), tabindex: _ctx.disabled || _ctx.formDisabled ? void 0 : "0", onFocusin: _cache[2] || (_cache[2] = (...args) => _ctx.focus && _ctx.focus(...args)), onClick: _cache[3] || (_cache[3] = (...args) => _ctx.handleClick && _ctx.handleClick(...args)) }, [ _createVNode(_component_var_menu_select, { show: _ctx.isShowMenuSelect, "onUpdate:show": _cache[1] || (_cache[1] = ($event) => _ctx.isShowMenuSelect = $event), "same-width": "", "auto-complete-cover": "", scrollable: "", trigger: "manual", placement: "bottom", disabled: _ctx.disabled || _ctx.formDisabled || _ctx.readonly || _ctx.formReadonly, class: _normalizeClass(_ctx.n("menu-select")), "popover-class": _ctx.variant === "standard" ? _ctx.n("--standard-menu-margin") : void 0, "onUpdate:modelValue": _ctx.handleAutoComplete, onKeyEscape: _ctx.handleKeyEscape }, { options: _withCtx(() => [ _createElementVNode( "div", { class: _normalizeClass(_ctx.n("options")) }, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList(_ctx.viewOptions, (option) => { return _openBlock(), _createBlock(_component_var_menu_option, { key: option[_ctx.valueKey], label: option[_ctx.labelKey], value: option[_ctx.valueKey], option, disabled: option.disabled }, null, 8, ["label", "value", "option", "disabled"]); }), 128 /* KEYED_FRAGMENT */ )) ], 2 /* CLASS */ ) ]), default: _withCtx(() => [ _createVNode(_component_var_input, _mergeProps({ ref: "input" }, { maxlength: _ctx.maxlength, enterkeyhint: _ctx.enterkeyhint, placeholder: _ctx.placeholder, size: _ctx.size, variant: _ctx.variant, line: _ctx.line, hint: _ctx.hint, textColor: _ctx.textColor, focusColor: _ctx.focusColor, blurColor: _ctx.blurColor, readonly: _ctx.readonly, disabled: _ctx.disabled, clearable: _ctx.clearable }, { modelValue: _ctx.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.value = $event), autocomplete: "off", "is-force-focusing-effect": _ctx.isFocusing, "is-force-error-effect": !!_ctx.errorMessage, "is-show-form-details": false, onInput: _ctx.handleInput, onBlur: _ctx.handleBlur, onClear: _ctx.handleClear, onChange: _ctx.handleChange }), _createSlots({ _: 2 /* DYNAMIC */ }, [ _ctx.$slots["prepend-icon"] ? { name: "prepend-icon", fn: _withCtx(() => [ _renderSlot(_ctx.$slots, "prepend-icon") ]), key: "0" } : void 0, _ctx.$slots["append-icon"] ? { name: "append-icon", fn: _withCtx(() => [ _renderSlot(_ctx.$slots, "append-icon") ]), key: "1" } : void 0, _ctx.$slots["clear-icon"] ? { name: "clear-icon", fn: _withCtx(({ clear }) => [ _renderSlot(_ctx.$slots, "clear-icon", { clear }) ]), key: "2" } : void 0, _ctx.$slots["extra-message"] ? { name: "extra-message", fn: _withCtx(() => [ _renderSlot(_ctx.$slots, "extra-message") ]), key: "3" } : void 0 ]), 1040, ["modelValue", "is-force-focusing-effect", "is-force-error-effect", "onInput", "onBlur", "onClear", "onChange"]) ]), _: 3 /* FORWARDED */ }, 8, ["show", "disabled", "class", "popover-class", "onUpdate:modelValue", "onKeyEscape"]), _createVNode(_component_var_form_details, { "error-message": _ctx.errorMessage, "extra-message": _ctx.maxlengthText }, null, 8, ["error-message", "extra-message"]) ], 42, _hoisted_1); } const __sfc__ = defineComponent({ name, components: { VarInput, VarMenuSelect, VarMenuOption, VarFormDetails }, props, setup(props2) { const root = ref(); const input = ref(); const isFocusing = ref(false); const value = useVModel(props2, "modelValue"); const viewOptions = ref([]); const isShowMenuSelect = ref(false); const maxlengthText = computed(() => { const { maxlength } = props2; if (!maxlength) { return ""; } if (isEmpty(value.value)) { return `0 / ${maxlength}`; } return `${String(value.value).length}/${maxlength}`; }); const { errorMessage, validateWithTrigger: vt, validate: v, // expose resetValidation } = useValidation(); const { bindForm, form } = useForm(); let clearing = false; const autoCompleteProvider = { reset, resetValidation, validate }; useClickOutside( () => root.value, "click", () => { if (clearing) { clearing = false; return; } blur(); } ); watch(() => [props2.options, isFocusing.value], changeMenuState); call(bindForm, autoCompleteProvider); useEventListener(() => window, "keydown", handleKeydown); function reset() { call(props2["onUpdate:modelValue"], ""); resetValidation(); } function validate() { return v(props2.rules, props2.modelValue); } function focus() { if (isFocusing.value || props2.disabled || (form == null ? void 0 : form.disabled.value)) { return; } isFocusing.value = true; input.value.focus(); call(props2.onFocus); validateWithTrigger("onFocus"); } function blur() { if (!isFocusing.value) { return; } isFocusing.value = false; isShowMenuSelect.value = false; input.value.blur(); call(props2.onBlur); validateWithTrigger("onBlur"); } function handleBlur() { if (isShowMenuSelect.value) { return; } blur(); } function validateWithTrigger(trigger) { nextTick(() => { const { validateTrigger, rules, modelValue } = props2; vt(validateTrigger, trigger, rules, modelValue); }); } function handleKeydown(event) { return __async(this, null, function* () { var _a; if ((form == null ? void 0 : form.disabled.value) || (form == null ? void 0 : form.readonly.value) || props2.disabled || props2.readonly || !isFocusing.value || !isShowMenuSelect.value) { return; } const { key } = event; if (key === "Tab") { preventDefault(event); root.value.focus(); isShowMenuSelect.value = false; return; } if (!["ArrowUp", "ArrowDown", "Enter"].includes(key)) { input.value.focus(); return; } if (key === "Enter") { yield raf(); (_a = input.value) == null ? void 0 : _a.focus(); } }); } function changeMenuState() { if (isFocusing.value) { isShowMenuSelect.value = getShowMenuSelect(value.value); } if (isShowMenuSelect.value) { viewOptions.value = props2.options; } } function handleInput(newValue, event) { changeMenuState(); call(props2.onInput, newValue, event); validateWithTrigger("onInput"); } function handleClear() { clearing = true; changeMenuState(); call(props2.onClear, value.value); validateWithTrigger("onClear"); } function handleClick(event) { if (props2.disabled || (form == null ? void 0 : form.disabled.value)) { return; } call(props2.onClick, event); validateWithTrigger("onClick"); } function handleChange(newValue) { call(props2.onChange, newValue); validateWithTrigger("onChange"); } function handleAutoComplete(newValue) { return __async(this, null, function* () { var _a; if (props2.maxlength != null) { newValue = newValue.slice(0, toNumber(props2.maxlength)); } if (newValue !== value.value) { value.value = newValue; call(props2.onChange, newValue); validateWithTrigger("onChange"); } yield raf(); (_a = input.value) == null ? void 0 : _a.focus(); }); } function handleKeyEscape() { input.value.focus(); } function getShowMenuSelect(newValue) { if (props2.disabled || props2.readonly || (form == null ? void 0 : form.disabled.value) || (form == null ? void 0 : form.readonly.value)) { return false; } return props2.options.length > 0 && (props2.getShow != null ? props2.getShow(newValue) : newValue.length > 0); } return { root, input, value, isShowMenuSelect, viewOptions, isFocusing, formDisabled: form == null ? void 0 : form.disabled, formReadonly: form == null ? void 0 : form.readonly, errorMessage, maxlengthText, n, handleInput, handleClear, handleClick, handleChange, handleBlur, handleKeyEscape, handleAutoComplete, reset, validate, resetValidation, blur, focus }; } }); __sfc__.render = __render__; var stdin_default = __sfc__; export { stdin_default as default };