mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-14 09:20:51 +08:00
ef35578a32
Co-authored-by: bastarder <jie.qian@blockheaders.com>
103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
import {
|
|
defineComponent,
|
|
h,
|
|
inject,
|
|
ref,
|
|
watch,
|
|
onMounted,
|
|
onUpdated,
|
|
onBeforeUnmount,
|
|
nextTick,
|
|
Fragment,
|
|
} from 'vue'
|
|
|
|
import {
|
|
elFormKey, elFormItemKey,
|
|
} from './token'
|
|
import {
|
|
addResizeListener,
|
|
removeResizeListener,
|
|
ResizableElement,
|
|
} from '@element-plus/utils/resize-event'
|
|
|
|
export default defineComponent({
|
|
name: 'ElLabelWrap',
|
|
props: {
|
|
isAutoWidth: Boolean,
|
|
updateAll: Boolean,
|
|
},
|
|
setup(props, { slots }) {
|
|
const el = ref<Nullable<HTMLElement>>(null)
|
|
const elForm = inject(elFormKey)
|
|
const elFormItem = inject(elFormItemKey)
|
|
|
|
const computedWidth = ref(0)
|
|
watch(computedWidth, (val, oldVal) => {
|
|
if (props.updateAll) {
|
|
elForm.registerLabelWidth(val, oldVal)
|
|
elFormItem.updateComputedLabelWidth(val)
|
|
}
|
|
})
|
|
|
|
const getLabelWidth = () => {
|
|
if (el.value?.firstElementChild) {
|
|
const width = window.getComputedStyle(el.value.firstElementChild)
|
|
.width
|
|
return Math.ceil(parseFloat(width))
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
const updateLabelWidth = (action = 'update') => {
|
|
nextTick(() => {
|
|
if (slots.default && props.isAutoWidth) {
|
|
if (action === 'update') {
|
|
computedWidth.value = getLabelWidth()
|
|
} else if (action === 'remove') {
|
|
elForm.deregisterLabelWidth(computedWidth.value)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
const updateLabelWidthFn = () => updateLabelWidth('update')
|
|
|
|
onMounted(() => {
|
|
addResizeListener(el.value.firstElementChild as ResizableElement, updateLabelWidthFn)
|
|
updateLabelWidthFn()
|
|
})
|
|
|
|
onUpdated(updateLabelWidthFn)
|
|
|
|
onBeforeUnmount(() => {
|
|
updateLabelWidth('remove')
|
|
removeResizeListener(el.value.firstElementChild as ResizableElement, updateLabelWidthFn)
|
|
})
|
|
|
|
function render() {
|
|
if (!slots) return null
|
|
if (props.isAutoWidth) {
|
|
const autoLabelWidth = elForm.autoLabelWidth
|
|
const style = {} as CSSStyleDeclaration
|
|
if (autoLabelWidth && autoLabelWidth !== 'auto') {
|
|
const marginLeft = parseInt(autoLabelWidth, 10) - computedWidth.value
|
|
if (marginLeft) {
|
|
style.marginLeft = marginLeft + 'px'
|
|
}
|
|
}
|
|
return h(
|
|
'div',
|
|
{
|
|
ref: el,
|
|
class: ['el-form-item__label-wrap'],
|
|
style,
|
|
},
|
|
slots.default?.(),
|
|
)
|
|
} else {
|
|
return h(Fragment, { ref: el }, slots.default?.())
|
|
}
|
|
}
|
|
return render
|
|
},
|
|
})
|