in packages/element/src/form-item/index.ts [142:498]
setup(props, { slots, refs }) {
const active = ref(false)
const deepLayoutRef = useFormLayout()
const prefixCls = `${stylePrefix}-form-item`
const { elRef: containerRef, elRefBinder } = useCompatRef(refs)
const overflow = useOverflow(containerRef)
provide(FormLayoutShallowContext, ref(null))
return () => {
const gridStyles: Record<string, any> = {}
const deepLayout = deepLayoutRef.value
const {
label,
colon = deepLayout.colon ?? true,
layout = deepLayout.layout ?? 'horizontal',
tooltip,
labelStyle = {},
labelWrap = deepLayout.labelWrap ?? false,
labelWidth = deepLayout.labelWidth,
wrapperWidth = deepLayout.wrapperWidth,
labelCol = deepLayout.labelCol,
wrapperCol = deepLayout.wrapperCol,
wrapperAlign = deepLayout.wrapperAlign ?? 'left',
wrapperWrap = deepLayout.wrapperWrap,
wrapperStyle = {},
fullness = deepLayout.fullness,
addonBefore,
addonAfter,
size = deepLayout.size,
extra,
feedbackText,
feedbackLayout = deepLayout.feedbackLayout ?? 'loose',
tooltipLayout = deepLayout.tooltipLayout ?? 'icon',
feedbackStatus,
feedbackIcon,
asterisk,
bordered = deepLayout.bordered,
inset = deepLayout.inset,
} = props
const labelAlign =
deepLayout.layout === 'vertical'
? props.labelAlign ?? deepLayout.labelAlign ?? 'left'
: props.labelAlign ?? deepLayout.labelAlign ?? 'right'
// 固定宽度
let enableCol = false
if (labelWidth || wrapperWidth) {
if (labelWidth) {
labelStyle.width = `${labelWidth}px`
labelStyle.maxWidth = `${labelWidth}px`
}
if (wrapperWidth) {
wrapperStyle.width = `${wrapperWidth}px`
wrapperStyle.maxWidth = `${wrapperWidth}px`
}
// 栅格模式
} else if (labelCol || wrapperCol) {
enableCol = true
}
const formatChildren =
feedbackLayout === 'popover'
? h(
'el-popover',
{
props: {
disabled: !feedbackText,
placement: 'top',
},
},
{
reference: () =>
h('div', {}, { default: () => slots.default?.() }),
default: () => [
h(
'div',
{
class: {
[`${prefixCls}-${feedbackStatus}-help`]:
!!feedbackStatus,
[`${prefixCls}-help`]: true,
},
},
{
default: () => [
feedbackStatus &&
['error', 'success', 'warning'].includes(feedbackStatus)
? ICON_MAP[
feedbackStatus as 'error' | 'success' | 'warning'
]()
: '',
resolveComponent(feedbackText),
],
}
),
],
}
)
: slots.default?.()
const renderLabelText = () => {
const labelChildren = h(
'div',
{
class: `${prefixCls}-label-content`,
ref: elRefBinder,
},
{
default: () => [
asterisk &&
h(
'span',
{ class: `${prefixCls}-asterisk` },
{ default: () => ['*'] }
),
h('label', {}, { default: () => [resolveComponent(label)] }),
],
}
)
const isTextTooltip = tooltip && tooltipLayout === 'text'
if (isTextTooltip || overflow.value) {
return h(
Tooltip,
{
props: {
placement: 'top',
},
},
{
default: () => [labelChildren],
content: () =>
h(
'div',
{},
{
default: () => [
overflow.value && resolveComponent(label),
isTextTooltip && resolveComponent(tooltip),
],
}
),
}
)
} else {
return labelChildren
}
}
const renderTooltipIcon = () => {
if (tooltip && tooltipLayout === 'icon') {
return h(
'span',
{
class: `${prefixCls}-label-tooltip`,
},
{
default: () => [
h(
Tooltip,
{
props: {
placement: 'top',
},
},
{
default: () => [h('i', { class: 'el-icon-info' }, {})],
content: () =>
h(
'div',
{
class: `${prefixCls}-label-tooltip-content`,
},
{
default: () => [resolveComponent(tooltip)],
}
),
}
),
],
}
)
}
}
const renderLabel =
label &&
h(
'div',
{
class: {
[`${prefixCls}-label`]: true,
[`${prefixCls}-label-tooltip`]:
(tooltip && tooltipLayout === 'text') || overflow.value,
[`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol,
},
style: labelStyle,
},
{
default: () => [
// label content
renderLabelText(),
// label tooltip
renderTooltipIcon(),
// label colon
label &&
h(
'span',
{
class: `${prefixCls}-colon`,
},
{ default: () => [colon ? ':' : ''] }
),
],
}
)
const renderFeedback =
!!feedbackText &&
feedbackLayout !== 'popover' &&
feedbackLayout !== 'none' &&
h(
'div',
{
class: {
[`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,
[`${prefixCls}-help`]: true,
[`${prefixCls}-help-enter`]: true,
[`${prefixCls}-help-enter-active`]: true,
},
},
{ default: () => [resolveComponent(feedbackText)] }
)
const renderExtra =
extra &&
h(
'div',
{ class: `${prefixCls}-extra` },
{ default: () => [resolveComponent(extra)] }
)
const renderContent = h(
'div',
{
class: {
[`${prefixCls}-control`]: true,
[`${prefixCls}-item-col-${wrapperCol}`]: enableCol && !!wrapperCol,
},
},
{
default: () => [
h(
'div',
{ class: `${prefixCls}-control-content` },
{
default: () => [
addonBefore &&
h(
'div',
{ class: `${prefixCls}-addon-before` },
{
default: () => [resolveComponent(addonBefore)],
}
),
h(
'div',
{
class: {
[`${prefixCls}-control-content-component`]: true,
[`${prefixCls}-control-content-component-has-feedback-icon`]:
!!feedbackIcon,
},
style: wrapperStyle,
},
{
default: () => [
formatChildren,
feedbackIcon &&
h(
'div',
{ class: `${prefixCls}-feedback-icon` },
{
default: () => [
typeof feedbackIcon === 'string'
? h('i', { class: feedbackIcon }, {})
: resolveComponent(feedbackIcon),
],
}
),
],
}
),
addonAfter &&
h(
'div',
{ class: `${prefixCls}-addon-after` },
{
default: () => [resolveComponent(addonAfter)],
}
),
],
}
),
renderFeedback,
renderExtra,
],
}
)
return h(
'div',
{
style: {
...gridStyles,
},
attrs: {
'data-grid-span': props.gridSpan,
},
class: {
[`${prefixCls}`]: true,
[`${prefixCls}-layout-${layout}`]: true,
[`${prefixCls}-${feedbackStatus}`]: !!feedbackStatus,
[`${prefixCls}-feedback-has-text`]: !!feedbackText,
[`${prefixCls}-size-${size}`]: !!size,
[`${prefixCls}-feedback-layout-${feedbackLayout}`]:
!!feedbackLayout,
[`${prefixCls}-fullness`]: !!fullness || !!inset || !!feedbackIcon,
[`${prefixCls}-inset`]: !!inset,
[`${prefixCls}-active`]: active.value,
[`${prefixCls}-inset-active`]: !!inset && active.value,
[`${prefixCls}-label-align-${labelAlign}`]: true,
[`${prefixCls}-control-align-${wrapperAlign}`]: true,
[`${prefixCls}-label-wrap`]: !!labelWrap,
[`${prefixCls}-control-wrap`]: !!wrapperWrap,
[`${prefixCls}-bordered-none`]:
bordered === false || !!inset || !!feedbackIcon,
[`${props.className}`]: !!props.className,
},
on: {
focus: () => {
if (feedbackIcon || inset) {
active.value = true
}
},
blur: () => {
if (feedbackIcon || inset) {
active.value = false
}
},
},
},
{
default: () => [renderLabel, renderContent],
}
)
}
},