Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | <template> <slot v-if="labelPosition === 'sticky'" name="label">{{ label }} </slot> <div ref="elRef" class="form-item" :class="labelClass" :style="state.item.itemStyle" :id="state.item.key" > <div v-if="labelPosition !== 'sticky'" class="label-wrapper" :style="{ width: __labelWith }" > <slot name="label">{{ label }} </slot> </div> <div class="content-wrapper"> <slot /> <div v-if="data?.$anyInvalid && data.$dirty" class="error-msg"> {{ data.validate.$message }} </div> </div> </div> </template> <script lang="ts" setup> import { computed, ref } from 'vue' import { LabelPoistion } from '../inject' import { useFormItemState } from './state' import { ValidateModel } from './type' defineOptions({ name: 'FormItem', }) const props = withDefaults( defineProps<{ data: ValidateModel label?: string labelWidth?: string | number labelPosition?: LabelPoistion classList?: string }>(), { labelPosition: 'left', classList: '', } ) const __labelWith = computed(() => { const { labelWidth } = props switch (typeof labelWidth) { case 'string': return labelWidth case 'number': return labelWidth + 'px' default: return '20px' } }) const elRef = ref<HTMLElement | null>(null) const LABEL_CLASS = { left: '', top: 'label-top', sticky: '', none: 'hide-label', } const state = useFormItemState() const labelClass = computed(() => { return [ LABEL_CLASS[state.item.labelPosition ?? props.labelPosition], props.classList, ].flatMap((e) => e.split(' ')) }) defineExpose({ el: elRef, }) </script> <style scoped lang="scss"> .label-wrapper { @apply flex-shrink-0 whitespace-nowrap relative z-1 mr-3; } .form-item { @apply flex text-sm relative; &.label-top { @apply block; } &.hide-label { & > .label-wrapper { display: none; } } } .error-msg { @apply text-red-400 text-xs; @apply absolute -bottom-1.3em left-0; } .content-wrapper { @apply flex-1 relative; } </style> |