hongluan-ui
Version:
Hongluan Component Library for Vue 3
444 lines (441 loc) • 16.7 kB
JavaScript
import { defineComponent, computed, inject, ref, shallowRef, nextTick, watch, onMounted, resolveComponent, openBlock, createElementBlock, mergeProps, renderSlot, createCommentVNode, createBlock, withModifiers, withCtx, createVNode, normalizeStyle, toDisplayString } from 'vue';
import { isNil } from 'lodash-unified';
import '../../../hooks/index.mjs';
import '../../../constants/index.mjs';
import '../../../utils/index.mjs';
import { useResizeObserver, isClient } from '@vueuse/core';
import '../../../tokens/index.mjs';
import { HlIcon } from '../../icon/index.mjs';
import '../../system-icon/index.mjs';
import { calcTextareaHeight } from './utils.mjs';
import { inputProps } from './input.mjs';
import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
import SystemClose from '../../system-icon/src/close.mjs';
import SystemShow from '../../system-icon/src/show.mjs';
import SystemHidden from '../../system-icon/src/hidden.mjs';
import { UPDATE_MODEL_EVENT } from '../../../constants/event.mjs';
import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
import { useAttrs } from '../../../hooks/use-attrs/index.mjs';
import { formContextKey, formItemContextKey, FormItemEvents } from '../../../tokens/form.mjs';
import { useFocusController } from '../../../hooks/use-focus-controller/index.mjs';
import { debugWarn } from '../../../utils/error.mjs';
import { useConsistentProp } from '../../../hooks/use-consistent-prop/index.mjs';
import { useCursor } from '../../../hooks/use-cursor/index.mjs';
import { useFormItemInputId } from '../../../hooks/use-form-item/index.mjs';
import { isObject } from '@vue/shared';
import { useComposition } from '../../../hooks/use-composition/index.mjs';
const _sfc_main = defineComponent({
name: "Input",
components: {
HlIcon,
SystemClose,
SystemShow,
SystemHidden
},
inheritAttrs: false,
props: inputProps,
emits: [
UPDATE_MODEL_EVENT,
"input",
"change",
"focus",
"blur",
"clear",
"mouseleave",
"mouseenter",
"keydown",
"compositionstart",
"compositionupdate",
"compositionend"
],
setup(props, { emit, slots, attrs: rawAttrs }) {
const { namespace } = useNamespace("input");
const containerAttrs = computed(() => {
const comboBoxAttrs = {};
if (props.containerRole === "combobox") {
comboBoxAttrs["aria-haspopup"] = rawAttrs["aria-haspopup"];
comboBoxAttrs["aria-owns"] = rawAttrs["aria-owns"];
comboBoxAttrs["aria-expanded"] = rawAttrs["aria-expanded"];
}
return comboBoxAttrs;
});
const attrs = useAttrs({
excludeKeys: computed(() => {
return Object.keys(containerAttrs.value);
})
});
const form = inject(formContextKey, {});
const formItem = inject(formItemContextKey, {});
const input = ref();
const textarea = ref();
const countStyle = ref();
const hovering = ref(false);
const passwordVisible = ref(false);
const _textareaCalcStyle = shallowRef(props.inputStyle);
const inputOrTextarea = computed(() => input.value || textarea.value);
const { wrapperRef, isFocused, handleFocus, handleBlur } = useFocusController(inputOrTextarea, {
afterBlur() {
var _a;
if (props.validateEvent) {
(_a = formItem == null ? void 0 : formItem.validate) == null ? void 0 : _a.call(formItem, "blur").catch((err) => debugWarn(err));
}
}
});
const { size: inputSize, disabled: inputDisabled, fill: inputFill } = useConsistentProp();
const needStatusIcon = computed(() => form.statusIcon);
const validateState = computed(() => formItem.validateState || "");
const textareaStyle = computed(() => [
props.inputStyle,
_textareaCalcStyle.value,
{ resize: props.resize }
]);
const nativeInputValue = computed(() => isNil(props.modelValue) ? "" : String(props.modelValue));
const showClear = computed(() => {
return props.clearable && !inputDisabled.value && !props.readonly && !!nativeInputValue.value && (isFocused.value || hovering.value);
});
const showPwdVisible = computed(() => {
return props.showPassword && !inputDisabled.value && !props.readonly && !!nativeInputValue.value && (!!nativeInputValue.value || isFocused.value);
});
const isWordLimitVisible = computed(() => {
return props.showWordLimit && !!props.maxlength && (props.nativeType === "text" || props.nativeType === "textarea") && !inputDisabled.value && !props.readonly && !props.showPassword;
});
const textLength = computed(() => nativeInputValue.value.length);
const inputExceed = computed(() => {
return isWordLimitVisible.value && textLength.value > Number(props.maxlength);
});
const [recordCursor, setCursor] = useCursor(input);
const { inputId } = useFormItemInputId(props, {
formItemContext: formItem
});
useResizeObserver(textarea, (entries) => {
onceInitSizeTextarea();
if (!isWordLimitVisible.value || props.resize !== "both")
return;
const entry = entries[0];
const { width } = entry.contentRect;
countStyle.value = {
right: `calc(100% - ${width + 15 + 6}px)`
};
});
const resizeTextarea = () => {
const { nativeType, autosize } = props;
if (!isClient || nativeType !== "textarea" || !textarea.value)
return;
if (autosize) {
const minRows = isObject(autosize) ? autosize.minRows : void 0;
const maxRows = isObject(autosize) ? autosize.maxRows : void 0;
const textareaStyle2 = calcTextareaHeight(textarea.value, minRows, maxRows);
_textareaCalcStyle.value = {
overflowY: "hidden",
...textareaStyle2
};
nextTick(() => {
textarea.value.offsetHeight;
_textareaCalcStyle.value = textareaStyle2;
});
} else {
_textareaCalcStyle.value = {
minHeight: calcTextareaHeight(textarea.value).minHeight
};
}
};
const createOnceInitResize = (resizeTextarea2) => {
let isInit = false;
return () => {
var _a;
if (isInit || !props.autosize)
return;
const isElHidden = ((_a = textarea.value) == null ? void 0 : _a.offsetParent) === null;
if (!isElHidden) {
resizeTextarea2();
isInit = true;
}
};
};
const onceInitSizeTextarea = createOnceInitResize(resizeTextarea);
const setNativeInputValue = () => {
const input2 = inputOrTextarea.value;
const formatterValue = props.formatter ? props.formatter(nativeInputValue.value) : nativeInputValue.value;
if (!input2 || input2.value === formatterValue)
return;
input2.value = formatterValue;
};
const handleInput = (event) => {
recordCursor();
let { value } = event.target;
if (props.formatter) {
value = props.parser ? props.parser(value) : value;
}
if (isComposing.value)
return;
if (value === nativeInputValue.value) {
setNativeInputValue();
return;
}
emit(UPDATE_MODEL_EVENT, value);
emit("input", value, event);
nextTick(setNativeInputValue);
setCursor();
};
const handleChange = (event) => {
emit("change", event.target.value);
};
const focus = () => {
nextTick(() => {
var _a;
(_a = inputOrTextarea.value) == null ? void 0 : _a.focus();
});
};
const blur = () => {
var _a;
(_a = inputOrTextarea.value) == null ? void 0 : _a.blur();
};
const select = () => {
var _a;
(_a = inputOrTextarea.value) == null ? void 0 : _a.select();
};
const {
isComposing,
handleCompositionStart,
handleCompositionUpdate,
handleCompositionEnd
} = useComposition({ emit, afterComposition: handleInput });
const clear = () => {
emit(UPDATE_MODEL_EVENT, "");
emit("change", "");
emit("clear");
emit("input", "");
};
const handlePasswordVisible = () => {
passwordVisible.value = !passwordVisible.value;
focus();
};
const getSuffixVisible = () => {
return slots.suffix || props.clearable || validateState.value && needStatusIcon.value;
};
const getPwdVisible = () => {
return props.showPassword || validateState.value && needStatusIcon.value;
};
watch(() => props.modelValue, () => {
var _a;
nextTick(() => resizeTextarea());
if (props.validateEvent) {
(_a = formItem.validate) == null ? void 0 : _a.call(formItem, FormItemEvents.change).catch((err) => debugWarn(err));
}
});
watch(nativeInputValue, () => {
setNativeInputValue();
});
watch(() => props.nativeType, () => {
nextTick(() => {
setNativeInputValue();
resizeTextarea();
});
});
onMounted(() => {
if (!props.formatter && props.parser) {
debugWarn("Input", "If you set the parser, you also need to set the formatter.");
}
setNativeInputValue();
nextTick(resizeTextarea);
});
const handleMouseLeave = (e) => {
hovering.value = false;
emit("mouseleave", e);
};
const handleMouseEnter = (e) => {
hovering.value = true;
emit("mouseenter", e);
};
const handleKeydown = (e) => {
emit("keydown", e);
};
return {
namespace,
isComposing,
input,
inputId,
textarea,
attrs,
containerAttrs,
inputSize,
validateState,
textareaStyle,
countStyle,
resizeTextarea,
inputDisabled,
inputFill,
showClear,
showPwdVisible,
isWordLimitVisible,
textLength,
hovering,
inputExceed,
passwordVisible,
inputOrTextarea,
wrapperRef,
handleInput,
handleChange,
handleFocus,
handleBlur,
handleCompositionStart,
handleCompositionUpdate,
handleCompositionEnd,
handlePasswordVisible,
clear,
select,
focus,
blur,
isFocused,
getSuffixVisible,
getPwdVisible,
handleMouseLeave,
handleMouseEnter,
handleKeydown
};
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_system_close = resolveComponent("system-close");
const _component_hl_icon = resolveComponent("hl-icon");
const _component_system_hidden = resolveComponent("system-hidden");
const _component_system_show = resolveComponent("system-show");
return openBlock(), createElementBlock("div", mergeProps(_ctx.containerAttrs, {
class: [
_ctx.namespace,
_ctx.inputSize ? _ctx.inputSize : "",
`as-${_ctx.nativeType}`,
_ctx.type ? _ctx.type : "",
_ctx.nativeType === "hidden" ? "display-none" : "",
{
"is-disabled": _ctx.inputDisabled,
"is-exceed": _ctx.inputExceed,
"is-focus": _ctx.isFocused,
"has-password-visible": _ctx.getPwdVisible(),
"has-suffix": _ctx.getSuffixVisible(),
"round": _ctx.round,
"fill": _ctx.inputFill,
"block": _ctx.block,
"thin": _ctx.thin
},
_ctx.$attrs.class
],
style: _ctx.$attrs.style,
role: _ctx.containerRole,
onMouseenter: _ctx.handleMouseEnter,
onMouseleave: _ctx.handleMouseLeave
}), [
_ctx.nativeType !== "textarea" ? (openBlock(), createElementBlock("div", {
key: 0,
ref: "wrapperRef",
class: "input-wrapper"
}, [
renderSlot(_ctx.$slots, "tags"),
_ctx.nativeType !== "textarea" ? (openBlock(), createElementBlock("input", mergeProps({
key: 0,
id: _ctx.inputId,
ref: "input"
}, _ctx.attrs, {
minlength: _ctx.minlength,
maxlength: _ctx.maxlength,
type: _ctx.showPassword ? _ctx.passwordVisible ? "text" : "password" : _ctx.nativeType,
disabled: _ctx.inputDisabled,
readonly: _ctx.readonly,
autocomplete: _ctx.autocomplete,
tabindex: _ctx.tabindex,
"aria-label": _ctx.label || _ctx.ariaLabel,
placeholder: _ctx.placeholder,
style: _ctx.inputStyle,
form: _ctx.form,
class: "input-inner",
autofocus: _ctx.autofocus,
onCompositionstart: _ctx.handleCompositionStart,
onCompositionupdate: _ctx.handleCompositionUpdate,
onCompositionend: _ctx.handleCompositionEnd,
onInput: _ctx.handleInput,
onFocus: _ctx.handleFocus,
onBlur: _ctx.handleBlur,
onChange: _ctx.handleChange,
onKeydown: _ctx.handleKeydown
}), null, 16, ["id", "minlength", "maxlength", "type", "disabled", "readonly", "autocomplete", "tabindex", "aria-label", "placeholder", "form", "autofocus", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onInput", "onFocus", "onBlur", "onChange", "onKeydown"])) : createCommentVNode("v-if", true),
_ctx.$slots.prefix ? (openBlock(), createElementBlock("span", {
key: 1,
class: "input-affixe prefix"
}, [
renderSlot(_ctx.$slots, "prefix")
])) : createCommentVNode("v-if", true),
_ctx.getSuffixVisible() ? (openBlock(), createElementBlock("span", {
key: 2,
class: "input-affixe suffix"
}, [
!_ctx.showClear ? renderSlot(_ctx.$slots, "suffix", { key: 0 }) : createCommentVNode("v-if", true),
_ctx.showClear ? (openBlock(), createBlock(_component_hl_icon, {
key: 1,
class: "input-close",
onMousedown: withModifiers(() => {
}, ["prevent"]),
onClick: _ctx.clear
}, {
default: withCtx(() => [
createVNode(_component_system_close)
]),
_: 1
}, 8, ["onMousedown", "onClick"])) : createCommentVNode("v-if", true)
])) : createCommentVNode("v-if", true),
_ctx.getPwdVisible() ? (openBlock(), createElementBlock("span", {
key: 3,
class: "input-affixe password-visible"
}, [
_ctx.showPwdVisible ? (openBlock(), createBlock(_component_hl_icon, {
key: 0,
onClick: _ctx.handlePasswordVisible
}, {
default: withCtx(() => [
_ctx.passwordVisible ? (openBlock(), createBlock(_component_system_hidden, { key: 0 })) : createCommentVNode("v-if", true),
!_ctx.passwordVisible ? (openBlock(), createBlock(_component_system_show, { key: 1 })) : createCommentVNode("v-if", true)
]),
_: 1
}, 8, ["onClick"])) : createCommentVNode("v-if", true)
])) : createCommentVNode("v-if", true),
_ctx.isWordLimitVisible ? (openBlock(), createElementBlock("span", {
key: 4,
style: normalizeStyle(_ctx.countStyle),
class: "input-count"
}, toDisplayString(_ctx.textLength) + " / " + toDisplayString(_ctx.maxlength), 5)) : createCommentVNode("v-if", true)
], 512)) : (openBlock(), createElementBlock("textarea", mergeProps({
key: 1,
id: _ctx.inputId,
ref: "textarea",
class: [`input-inner`, _ctx.type, _ctx.isFocused ? "is-focus" : ""]
}, _ctx.attrs, {
minlength: _ctx.minlength,
maxlength: _ctx.maxlength,
tabindex: _ctx.tabindex,
disabled: _ctx.inputDisabled,
readonly: _ctx.readonly,
autocomplete: _ctx.autocomplete,
style: _ctx.textareaStyle,
"aria-label": _ctx.label || _ctx.ariaLabel,
placeholder: _ctx.placeholder,
form: _ctx.form,
rows: _ctx.rows,
autofocus: _ctx.autofocus,
onCompositionstart: _ctx.handleCompositionStart,
onCompositionupdate: _ctx.handleCompositionUpdate,
onCompositionend: _ctx.handleCompositionEnd,
onInput: _ctx.handleInput,
onFocus: _ctx.handleFocus,
onBlur: _ctx.handleBlur,
onChange: _ctx.handleChange,
onKeydown: _ctx.handleKeydown
}), "\n ", 16, ["id", "minlength", "maxlength", "tabindex", "disabled", "readonly", "autocomplete", "aria-label", "placeholder", "form", "rows", "autofocus", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onInput", "onFocus", "onBlur", "onChange", "onKeydown"])),
_ctx.isWordLimitVisible && _ctx.nativeType === "textarea" ? (openBlock(), createElementBlock("span", {
key: 2,
style: normalizeStyle(_ctx.countStyle),
class: "input-count"
}, toDisplayString(_ctx.textLength) + " / " + toDisplayString(_ctx.maxlength), 5)) : createCommentVNode("v-if", true)
], 16, ["role", "onMouseenter", "onMouseleave"]);
}
var Input = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { Input as default };
//# sourceMappingURL=input2.mjs.map