@seemusic/ui-components
Version:
A Vue 3 UI Library. Uses Composable.
1 lines • 5.15 kB
Source Map (JSON)
{"version":3,"file":"SopInput.vue.mjs","sources":["../../../src/components/SopInput/SopInput.vue"],"sourcesContent":["<template>\n <ElInput\n ref=\"inputRef\"\n class=\"sop-input\"\n :modelValue=\"modelValue\"\n @update:modelValue=\"(val) => $emit('update:modelValue', val)\"\n v-bind=\"$attrs\"\n >\n <template\n v-for=\"(slot, slotName) in $slots\"\n #[slotName]=\"slotProps\"\n >\n <slot\n :name=\"slotName\"\n v-bind=\"slotProps\"\n />\n </template>\n </ElInput>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, onMounted, watch } from 'vue';\nimport { ElInput, type InputInstance } from 'element-plus';\ntype ExposeInput = Pick<\n InputInstance,\n 'blur' | 'clear' | 'focus' |\n 'input' | 'resizeTextarea' | '_ref' |\n 'select' | 'textarea' | 'textareaStyle'\n>;\n\nexport default defineComponent({\n name: 'SopInput',\n components: { ElInput },\n props: {\n modelValue: { default: '' },\n scrollPlaceholder: {\n type: Boolean,\n default: false\n }\n },\n emits: ['update:modelValue'],\n setup(props, { attrs, expose }) {\n // const attrs = useAttrs();\n const placeholderText = ref(attrs.placeholder as string || '');\n const inputRef = ref<InputInstance | null>(null);\n\n const inputWrapper = ref<HTMLDivElement | null>();\n // const inputSuffix = ref<HTMLDivElement | null>();\n const inputPrefix = ref<HTMLDivElement | null>();\n const input = ref<HTMLInputElement | null>();\n const placeholder = ref<HTMLDivElement | null>();\n\n // 用户更改 placeholder 时,更新 placeholder\n watch(() => attrs.placeholder, (val) => {\n placeholderText.value = val as string;\n }, { immediate: true });\n\n watch(() => props.modelValue, () => {\n setPlaceholderVisibility(props.modelValue !== '');\n }, { immediate: true });\n\n onMounted(() => {\n if (inputRef.value === null) return;\n input.value = inputRef.value.$refs.input as HTMLInputElement;\n // 如果不需要滚动字幕, 将原生的显示出来\n if (!props.scrollPlaceholder) {\n input.value.classList.remove('el-input__inner--scroll');\n return;\n }\n input.value.classList.add('el-input__inner--scroll');\n\n inputWrapper.value =\n inputRef.value.$el.querySelector('.el-input__wrapper') as HTMLDivElement;\n // inputSuffix.value =\n // inputWrapper.value?.querySelector('.el-input__suffix') as HTMLDivElement;\n inputPrefix.value =\n inputWrapper.value?.querySelector('.el-input__prefix') as HTMLDivElement;\n\n createPlaceholderElement();\n setPlaceholderPosition();\n });\n\n function createPlaceholderElement() {\n const div = document.createElement('div');\n const span = document.createElement('span');\n div.classList.add('el-input__placeholder');\n div.appendChild(span);\n span.textContent = placeholderText.value;\n inputWrapper.value?.appendChild(div);\n }\n\n function setPlaceholderPosition() {\n // const suffixWidth = inputSuffix.value?.offsetWidth || 0;\n const prefixWidth = inputPrefix.value?.offsetWidth || 0;\n const inputWidth = input.value?.offsetWidth || 0;\n placeholder.value =\n inputWrapper.value?.querySelector('.el-input__placeholder') as HTMLDivElement;\n const placeholderWidth = placeholder.value?.offsetWidth || 0;\n\n if (prefixWidth) {\n placeholder.value.style.left = `${prefixWidth + 8}px`;\n }\n\n // 字幕滚动\n if (placeholderWidth > inputWidth) {\n placeholder.value.classList.add('is-scroll');\n placeholder.value.style.maxWidth = `${inputWidth}px`;\n } else {\n placeholder.value.classList.remove('is-scroll');\n }\n }\n\n function setPlaceholderVisibility(val: boolean) {\n if (placeholder.value) {\n val\n ? placeholder.value.style.opacity = '0'\n : placeholder.value.style.opacity = '1';\n }\n }\n\n const _expose: ExposeInput = new Proxy(\n {} as ExposeInput,\n {\n get(_, key, receiver) {\n if (inputRef.value === null) return;\n if (key === 'ref') {\n return Reflect.get(inputRef.value, '_ref', receiver);\n }\n return Reflect.get(inputRef.value, key, receiver);\n },\n has(_, key) {\n if (inputRef.value === null) return false;\n return Reflect.has(inputRef.value, key);\n }\n }\n );\n expose(_expose) as unknown as (exposed?: ExposeInput) => void;\n\n return {\n inputRef\n };\n }\n}) as unknown as typeof ElInput;\n</script>\n"],"names":["_resolveComponent","_openBlock","_createBlock","_mergeProps","_createSlots","_withCtx"],"mappings":";;;;6BACEA,iBAgBU,SAAA;AAdH,SAAAC,UAAY,GAAAC,YAAA,oBAAAC,WAAA;AAAA,IAChB,KAAA;AAAA,IACA,OAAA;AAAA,IACa,YAAA,KAAA;AAAA,IAGqB,uBAAA,OAArB,OAAE,OAAQ,CAAA,IAAA,CAAA,QAAA,KAAA,MAAA,qBAAA,GAAA;AAAA,EAAA,GAAA,KAAA,MAAA,GAAAC,YAAA,EAAA,GAAA,KAAA;AAAA,eACrB,KAAU,QAAA,CAAA,MAAA,aAAA;;QAEX,MAAA;AAAA,QAAA,IAAAC,QAAA,CAAA,cAAA;AAAA;;;;;;;"}