feat: form add labelWrap

feat-css-var
tangjinzhou 2022-02-28 10:26:09 +08:00
parent 0ec4ebcf23
commit cb95d1202a
26 changed files with 310 additions and 236 deletions

View File

@ -1,16 +1,16 @@
import { addClass, removeClass } from '../../vc-util/Dom/class';
import { nextTick } from 'vue';
import type { CSSMotionProps } from '../../_util/transition';
import { addClass, removeClass } from '../vc-util/Dom/class';
import type { CSSMotionProps } from './transition';
const listAnimation = (name): CSSMotionProps => {
const collapseMotion = (name = 'ant-motion-collapse'): CSSMotionProps => {
return {
name,
appear: true,
css: true,
onBeforeEnter: (node: HTMLDivElement) => {
addClass(node, name);
node.style.height = '0px';
node.style.opacity = '0';
addClass(node, name);
},
onEnter: (node: HTMLDivElement) => {
nextTick(() => {
@ -41,4 +41,4 @@ const listAnimation = (name): CSSMotionProps => {
},
};
};
export default listAnimation;
export default collapseMotion;

View File

@ -19,6 +19,7 @@ export default (
pageHeader: ComputedRef<{ ghost: boolean }>;
form?: ComputedRef<{
requiredMark?: RequiredMark;
colon?: boolean;
}>;
autoInsertSpaceInButton: ComputedRef<boolean>;
renderEmpty?: ComputedRef<(componentName?: string) => VueNode>;

View File

@ -129,13 +129,17 @@ export interface CSSMotionProps extends Partial<BaseTransitionProps<Element>> {
css?: boolean;
}
const collapseMotion = (style: Ref<CSSProperties>, className: Ref<string>): CSSMotionProps => {
const collapseMotion = (
name = 'ant-motion-collapse',
style: Ref<CSSProperties>,
className: Ref<string>,
): CSSMotionProps => {
return {
name: 'ant-motion-collapse',
name,
appear: true,
css: true,
onBeforeEnter: node => {
className.value = 'ant-motion-collapse';
className.value = name;
style.value = getCollapsedHeight(node);
},
onEnter: node => {
@ -148,7 +152,7 @@ const collapseMotion = (style: Ref<CSSProperties>, className: Ref<string>): CSSM
style.value = {};
},
onBeforeLeave: node => {
className.value = 'ant-motion-collapse';
className.value = name;
style.value = getCurrentHeight(node);
},
onLeave: node => {

View File

@ -1,9 +1,9 @@
import { useInjectFormItemPrefix } from './context';
import type { VueNode } from '../_util/type';
import { defineComponent, onBeforeUnmount, ref, watch } from 'vue';
import classNames from '../_util/classNames';
import Transition, { getTransitionProps } from '../_util/transition';
import { computed, defineComponent, ref, watch } from 'vue';
import { getTransitionGroupProps, TransitionGroup } from '../_util/transition';
import useConfigInject from '../_util/hooks/useConfigInject';
import collapseMotion from '../_util/collapseMotion';
export interface ErrorListProps {
errors?: VueNode[];
@ -15,72 +15,40 @@ export interface ErrorListProps {
export default defineComponent({
name: 'ErrorList',
props: ['errors', 'help', 'onDomErrorVisibleChange'],
props: ['errors', 'help', 'onDomErrorVisibleChange', 'helpStatus', 'warnings'],
setup(props) {
const { prefixCls: rootPrefixCls } = useConfigInject('', props);
const { prefixCls, status } = useInjectFormItemPrefix();
const visible = ref(!!(props.errors && props.errors.length));
const baseClassName = computed(() => `${prefixCls.value}-item-explain`);
const visible = computed(() => !!(props.errors && props.errors.length));
const innerStatus = ref(status.value);
const timeout = ref();
const cacheErrors = ref([...props.errors]);
watch([() => [...props.errors], () => props.help], newValues => {
clearTimeout(timeout.value);
if (props.help) {
visible.value = !!(props.errors && props.errors.length);
if (visible.value) {
cacheErrors.value = newValues[0];
}
} else {
timeout.value = setTimeout(() => {
visible.value = !!(props.errors && props.errors.length);
if (visible.value) {
cacheErrors.value = newValues[0];
}
});
}
});
onBeforeUnmount(() => {
clearTimeout(timeout.value);
});
// Memo status in same visible
watch([visible, status], () => {
if (visible.value) {
innerStatus.value = status.value;
}
});
watch(
visible,
() => {
if (visible.value) {
props.onDomErrorVisibleChange?.(true);
}
},
{ immediate: true, flush: 'post' },
);
return () => {
const baseClassName = `${prefixCls.value}-item-explain`;
const transitionProps = getTransitionProps(`${rootPrefixCls.value}-show-help`, {
onAfterLeave: () => {
props.onDomErrorVisibleChange?.(false);
},
});
const colMItem = collapseMotion(`${rootPrefixCls.value}-show-help-item`);
const transitionGroupProps = getTransitionGroupProps(
`${rootPrefixCls.value}-show-help-item`,
colMItem,
);
(transitionGroupProps as any).class = baseClassName.value;
return (
<Transition {...transitionProps}>
{visible.value ? (
<TransitionGroup {...transitionGroupProps} tag="div">
{props.errors?.map((error: any, index: number) => (
<div
class={classNames(baseClassName, {
[`${baseClassName}-${innerStatus.value}`]: innerStatus.value,
})}
key="help"
key={index}
role="alert"
class={innerStatus.value ? `${baseClassName.value}-${innerStatus.value}` : ''}
>
{cacheErrors.value?.map((error: any, index: number) => (
<div key={index} role="alert">
{error}
</div>
))}
{error}
</div>
) : null}
</Transition>
))}
</TransitionGroup>
);
};
},

View File

@ -66,6 +66,7 @@ export const formProps = {
wrapperCol: { type: Object as PropType<ColProps & HTMLAttributes> },
colon: PropTypes.looseBool,
labelAlign: PropTypes.oneOf(tuple('left', 'right')),
labelWrap: PropTypes.looseBool,
prefixCls: PropTypes.string,
requiredMark: { type: [String, Boolean] as PropType<RequiredMark | ''>, default: undefined },
/** @deprecated Will warning in future branch. Pls use `requiredMark` instead. */
@ -145,6 +146,7 @@ const Form = defineComponent({
}
return true;
});
const mergedColon = computed(() => props.colon ?? contextForm.value?.colon);
const validateMessages = computed(() => {
return {
...defaultValidateMessages,
@ -367,9 +369,10 @@ const Form = defineComponent({
name: computed(() => props.name),
labelAlign: computed(() => props.labelAlign),
labelCol: computed(() => props.labelCol),
labelWrap: computed(() => props.labelWrap),
wrapperCol: computed(() => props.wrapperCol),
vertical: computed(() => props.layout === 'vertical'),
colon: computed(() => props.colon),
colon: mergedColon,
requiredMark: mergedRequiredMark,
validateTrigger: computed(() => props.validateTrigger),
rules: computed(() => props.rules),

View File

@ -134,7 +134,6 @@ export default defineComponent({
const fieldName = computed(() => props.name || props.prop);
const errors = ref([]);
const validateDisabled = ref(false);
const domErrorVisible = ref(false);
const inputRef = ref();
const namePath = computed(() => {
const val = fieldName.value;
@ -388,7 +387,9 @@ export default defineComponent({
{...attrs}
class={[
itemClassName.value,
domErrorVisible.value || !!help ? `${prefixCls.value}-item-with-help` : '',
(help !== undefined && help !== null) || errors.value.length
? `${prefixCls.value}-item-with-help`
: '',
attrs.class,
]}
key="row"
@ -411,7 +412,6 @@ export default defineComponent({
errors={help !== undefined && help !== null ? toArray(help) : errors.value}
prefixCls={prefixCls.value}
status={validateState.value}
onDomErrorVisibleChange={(v: boolean) => (domErrorVisible.value = v)}
validateStatus={validateState.value}
ref={inputRef}
help={help}

View File

@ -11,14 +11,13 @@ import classNames from '../_util/classNames';
import type { ValidateStatus } from './FormItem';
import type { VueNode } from '../_util/type';
import type { HTMLAttributes } from 'vue';
import { computed, defineComponent, onUnmounted } from 'vue';
import { computed, defineComponent } from 'vue';
export interface FormItemInputMiscProps {
prefixCls: string;
errors: VueNode[];
hasFeedback?: boolean;
validateStatus?: ValidateStatus;
onDomErrorVisibleChange: (visible: boolean) => void;
}
export interface FormItemInputProps {
@ -62,17 +61,12 @@ const FormItemInput = defineComponent({
status: computed(() => props.status),
});
onUnmounted(() => {
props.onDomErrorVisibleChange(false);
});
return () => {
const {
prefixCls,
wrapperCol,
help = slots.help?.(),
errors = slots.errors?.(),
onDomErrorVisibleChange,
hasFeedback,
validateStatus,
extra = slots.extra?.(),
@ -105,7 +99,7 @@ const FormItemInput = defineComponent({
<ErrorList
errors={errors}
help={help}
onDomErrorVisibleChange={onDomErrorVisibleChange}
class={`${baseClassName}-explain-connected`}
/>
{extra ? <div class={`${baseClassName}-extra`}>{extra}</div> : null}
</>

View File

@ -33,6 +33,7 @@ const FormItemLabel: FunctionalComponent<FormItemLabelProps> = (props, { slots,
vertical,
labelAlign: contextLabelAlign,
labelCol: contextLabelCol,
labelWrap,
colon: contextColon,
} = useInjectForm();
const mergedLabelCol: FormItemLabelProps['labelCol'] = labelCol || contextLabelCol?.value || {};
@ -44,6 +45,9 @@ const FormItemLabel: FunctionalComponent<FormItemLabelProps> = (props, { slots,
labelClsBasic,
mergedLabelAlign === 'left' && `${labelClsBasic}-left`,
mergedLabelCol.class,
{
[`${labelClsBasic}-wrap`]: !!labelWrap.value,
},
);
let labelChildren = label;

View File

@ -14,7 +14,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-1" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -29,7 +29,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-2" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -44,7 +44,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-3" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -59,7 +59,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-4" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -74,7 +74,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-5" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -89,7 +89,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-6" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -104,7 +104,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-7" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -119,7 +119,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-8" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -134,7 +134,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-9" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -149,7 +149,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-10" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -178,7 +178,7 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="basic_username" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -191,7 +191,7 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><!----><input id="basic_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -202,7 +202,7 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"><span class="ant-checkbox ant-checkbox-checked"><input id="basic_remember" type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Remember me</span></label></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -215,7 +215,7 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -233,7 +233,7 @@ exports[`renders ./components/form/demo/custom-validation.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input autocomplete="off" type="password" id="custom-validation_pass" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -246,7 +246,7 @@ exports[`renders ./components/form/demo/custom-validation.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input autocomplete="off" type="password" id="custom-validation_checkPass" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -264,7 +264,7 @@ exports[`renders ./components/form/demo/custom-validation.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -279,7 +279,7 @@ exports[`renders ./components/form/demo/custom-validation.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -302,7 +302,7 @@ exports[`renders ./components/form/demo/customized-form-controls.vue correctly 1
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -315,7 +315,7 @@ exports[`renders ./components/form/demo/customized-form-controls.vue correctly 1
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -333,7 +333,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -348,7 +348,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -366,7 +366,7 @@ exports[`renders ./components/form/demo/dynamic-form-items.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -379,7 +379,7 @@ exports[`renders ./components/form/demo/dynamic-form-items.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -406,7 +406,7 @@ exports[`renders ./components/form/demo/dynamic-form-items-complex.vue correctly
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -419,7 +419,7 @@ exports[`renders ./components/form/demo/dynamic-form-items-complex.vue correctly
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -432,7 +432,7 @@ exports[`renders ./components/form/demo/dynamic-form-items-complex.vue correctly
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -450,7 +450,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="dynamic_rule_username" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -463,7 +463,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="dynamic_rule_nickname" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -474,7 +474,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input id="dynamic_rule_checkNick" type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Nickname is required</span></label></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -487,7 +487,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -505,7 +505,7 @@ exports[`renders ./components/form/demo/form-context.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="form_context_group" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -520,7 +520,7 @@ exports[`renders ./components/form/demo/form-context.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -535,7 +535,7 @@ exports[`renders ./components/form/demo/form-context.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -562,7 +562,7 @@ exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -575,7 +575,7 @@ exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -588,7 +588,7 @@ exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -608,7 +608,7 @@ exports[`renders ./components/form/demo/inline-login.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -621,7 +621,7 @@ exports[`renders ./components/form/demo/inline-login.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><span class="ant-input-prefix"><span role="img" aria-label="lock" class="anticon anticon-lock site-form-item-icon"><svg focusable="false" class="" data-icon="lock" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 10-56 0z"></path></svg></span></span><input id="horizontal_login_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -634,7 +634,7 @@ exports[`renders ./components/form/demo/inline-login.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -652,7 +652,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -667,7 +667,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -682,7 +682,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -697,7 +697,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -710,7 +710,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="textarea" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -725,7 +725,7 @@ exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -745,7 +745,7 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -758,7 +758,7 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="input placeholder" type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -771,7 +771,7 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input placeholder="input placeholder" type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -784,7 +784,7 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -802,7 +802,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_name" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -815,7 +815,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_email" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -833,7 +833,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -846,7 +846,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_website" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -859,7 +859,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><textarea id="nest-messages_user_introduction" class="ant-input"></textarea></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -872,7 +872,7 @@ exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -892,7 +892,7 @@ exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -905,7 +905,7 @@ exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><span class="ant-input-prefix"><span role="img" aria-label="lock" class="anticon anticon-lock site-form-item-icon"><svg focusable="false" class="" data-icon="lock" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 10-56 0z"></path></svg></span></span><input id="normal_login_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -919,7 +919,7 @@ exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
</button> Or <a href="">register now!</a></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -944,7 +944,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -964,7 +964,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -984,7 +984,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1006,7 +1006,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1028,7 +1028,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1048,7 +1048,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1061,7 +1061,7 @@ exports[`renders ./components/form/demo/time-related-controls.vue correctly 1`]
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1079,7 +1079,7 @@ exports[`renders ./components/form/demo/useForm-basic.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1101,7 +1101,7 @@ exports[`renders ./components/form/demo/useForm-basic.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1116,7 +1116,7 @@ exports[`renders ./components/form/demo/useForm-basic.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1131,7 +1131,7 @@ exports[`renders ./components/form/demo/useForm-basic.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1149,7 +1149,7 @@ exports[`renders ./components/form/demo/useForm-merge.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1171,7 +1171,7 @@ exports[`renders ./components/form/demo/useForm-merge.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1186,7 +1186,7 @@ exports[`renders ./components/form/demo/useForm-merge.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1201,7 +1201,7 @@ exports[`renders ./components/form/demo/useForm-merge.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1219,7 +1219,7 @@ exports[`renders ./components/form/demo/useForm-nested.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1232,7 +1232,7 @@ exports[`renders ./components/form/demo/useForm-nested.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1247,7 +1247,7 @@ exports[`renders ./components/form/demo/useForm-nested.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1265,7 +1265,7 @@ exports[`renders ./components/form/demo/useForm-trigger.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1287,7 +1287,7 @@ exports[`renders ./components/form/demo/useForm-trigger.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1302,7 +1302,7 @@ exports[`renders ./components/form/demo/useForm-trigger.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1320,7 +1320,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><span class="ant-form-text">China</span></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1342,7 +1342,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1370,7 +1370,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1388,7 +1388,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1403,7 +1403,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1425,7 +1425,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1440,7 +1440,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1455,7 +1455,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1479,7 +1479,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1525,7 +1525,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1542,7 +1542,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<div class="ant-form-item-extra">longgggggggggggggggggggggggggggggggggg</div>
</div>
</div>
@ -1562,7 +1562,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1575,7 +1575,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1593,7 +1593,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><input type="text" id="form_item_name" class="ant-input"></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1615,7 +1615,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1635,7 +1635,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1650,7 +1650,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1665,7 +1665,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1680,7 +1680,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1693,7 +1693,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
<div class="ant-form-item-control-input-content"><textarea id="form_item_desc" class="ant-input"></textarea></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
@ -1708,7 +1708,7 @@ exports[`renders ./components/form/demo/validation.vue correctly 1`] = `
</button></div>
<!---->
</div>
<!---->
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>

View File

@ -12,6 +12,7 @@ export interface FormContextProps {
name?: ComputedRef<string>;
colon?: ComputedRef<boolean>;
labelAlign?: ComputedRef<FormLabelAlign>;
labelWrap?: ComputedRef<boolean>;
labelCol?: ComputedRef<ColProps>;
wrapperCol?: ComputedRef<ColProps>;
requiredMark?: ComputedRef<RequiredMark>;

View File

@ -36,6 +36,7 @@ A form consists of one or more form fields whose type includes input, textarea,
| hideRequiredMark | Hide required mark of all form items | Boolean | false | |
| layout | Define form layout | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
| labelAlign | text align of label of all items | 'left' \| 'right' | 'right' | |
| labelWrap | whether label can be wrap | boolean | false | 3.0 |
| labelCol | The layout of label. You can set `span` `offset` to something like `{span: 3, offset: 12}` or `sm: {span: 3, offset: 12}` same as with `<Col>` | [object](/components/grid/#Col) | | |
| wrapperCol | The layout for input controls, same as `labelCol` | [object](/components/grid/#Col) | | |
| colon | change default props colon value of Form.Item (only effective when prop layout is horizontal) | boolean | true | |

View File

@ -36,9 +36,10 @@ cover: https://gw.alipayobjects.com/zos/alicdn/ORmcdeaoO/Form.svg
| rules | 表单验证规则 | object | | |
| hideRequiredMark | 隐藏所有表单项的必选标记 | Boolean | false | |
| labelAlign | label 标签的文本对齐方式 | 'left' \| 'right' | 'right' | |
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
| labelWrap | label 标签的文本换行方式 | boolean | false | 3.0 |
| labelCol | label 标签布局,同 `<Col>` 组件,设置 `span` `offset` 值,如 `{span: 3, offset: 12}``sm: {span: 3, offset: 12}` | [object](/components/grid-cn/#Col) | | |
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](/components/grid-cn/#Col) | | |
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
| colon | 配置 Form.Item 的 colon 的默认值 (只有在属性 layout 为 horizontal 时有效) | boolean | true | |
| validateOnRuleChange | 是否在 rules 属性改变后立即触发一次验证 | boolean | true | |
| scrollToFirstError | 提交失败自动滚动到第一个错误字段 | boolean \| [options](https://github.com/stipsan/scroll-into-view-if-needed/#options) | false | 2.0.0 |

View File

@ -1,14 +1,12 @@
@import './index';
@import (reference) '../../style/themes/index';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
// ================================================================
// = Children Component =
// ================================================================
.@{form-item-prefix-cls} {
.@{ant-prefix}-mentions,
textarea.@{ant-prefix}-input {
height: auto;
}
// input[type=file]
.@{ant-prefix}-upload {
background: transparent;
@ -51,6 +49,7 @@
+ .@{form-prefix-cls}-text {
margin-left: 8px;
}
&-handler-wrap {
z-index: 2; // https://github.com/ant-design/ant-design/issues/6289
}

View File

@ -1,4 +1,7 @@
@import './index';
@import (reference) '../../style/themes/index';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
.@{form-prefix-cls}-horizontal {
.@{form-item-prefix-cls}-label {
@ -7,4 +10,9 @@
.@{form-item-prefix-cls}-control {
flex: 1 1 0;
}
// https://github.com/ant-design/ant-design/issues/32980
.@{form-item-prefix-cls}-control:not(.@{ant-prefix}-col) {
// https://github.com/ant-design/ant-design/issues/32777
min-width: 0;
}
}

View File

@ -39,6 +39,7 @@
&-small {
.formSize(@input-height-sm);
}
&-large {
.formSize(@input-height-lg);
}
@ -61,9 +62,12 @@
margin-bottom: @form-item-margin-bottom;
vertical-align: top;
// We delay one frame (0.017s) here to let CSSMotion goes
transition: margin-bottom @animation-duration-slow 0.017s linear;
&-with-help {
margin-bottom: 0;
// margin-bottom: 0;
transition: none;
}
&-hidden,
@ -87,11 +91,17 @@
text-align: left;
}
&-wrap {
overflow: unset;
line-height: (@line-height-base - 0.25em);
white-space: unset;
}
> label {
position: relative;
// display: inline;
display: inline-flex;
align-items: center;
max-width: 100%;
height: @form-item-label-height;
color: @label-color;
font-size: @form-item-label-font-size;
@ -179,10 +189,12 @@
}
}
// ==============================================================
// = Explain =
// ==============================================================
&-explain,
&-extra {
clear: both;
min-height: @form-item-margin-bottom;
color: @text-color-secondary;
font-size: @font-size-base;
line-height: @line-height-base;
@ -190,43 +202,66 @@
.explainAndExtraDistance((@form-item-margin-bottom - @form-font-height) / 2);
}
&-explain-connected {
height: 0;
min-height: @form-item-margin-bottom;
opacity: 0;
margin-top: -@form-item-margin-bottom;
transform: translateY(@form-item-margin-bottom);
}
&-extra {
min-height: @form-item-margin-bottom;
}
.@{ant-prefix}-input-textarea-show-count {
&::after {
margin-bottom: -22px;
}
}
}
.show-help-motion(@className, @keyframeName, @duration: @animation-duration-slow) {
@name: ~'@{ant-prefix}-@{className}';
.make-motion(@name, @keyframeName, @duration);
.@{name}-enter,
.@{name}-appear {
opacity: 0;
animation-timing-function: @ease-in-out;
}
.@{name}-leave {
animation-timing-function: @ease-in-out;
}
}
.show-help-motion(show-help, antShowHelp, 0.3s);
@keyframes antShowHelpIn {
0% {
transform: translateY(-5px);
opacity: 0;
}
100% {
transform: translateY(0);
&-with-help &-explain {
height: auto;
min-height: @form-item-margin-bottom;
opacity: 1;
}
}
@keyframes antShowHelpOut {
to {
// >>>>>>>>>> Motion <<<<<<<<<<
// Explain holder
.@{ant-prefix}-show-help {
transition: height @animation-duration-slow linear, min-height @animation-duration-slow linear,
margin-bottom @animation-duration-slow @ease-in-out,
opacity @animation-duration-slow @ease-in-out;
&-leave {
min-height: @form-item-margin-bottom;
&-active {
min-height: 0;
}
}
}
// Explain
.@{ant-prefix}-show-help-item {
overflow: hidden;
transition: height @animation-duration-slow @ease-in-out,
opacity @animation-duration-slow @ease-in-out, transform @animation-duration-slow @ease-in-out !important;
&-appear,
&-enter {
transform: translateY(-5px);
opacity: 0;
&-active {
transform: translateY(0);
opacity: 1;
}
}
&-leave-active {
transform: translateY(-5px);
}
}
@ -235,27 +270,36 @@
@keyframes diffZoomIn1 {
0% {
transform: scale(0);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes diffZoomIn2 {
0% {
transform: scale(0);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes diffZoomIn3 {
0% {
transform: scale(0);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}

View File

@ -1,4 +1,7 @@
@import './index';
@import (reference) '../../style/themes/index';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
.@{form-prefix-cls}-inline {
display: flex;

View File

@ -12,7 +12,8 @@
}
// 输入框的不同校验状态
:not(.@{ant-prefix}-input-disabled):not(.@{ant-prefix}-input-borderless).@{ant-prefix}-input,
:not(.@{ant-prefix}-input-affix-wrapper-disabled):not(.@{ant-prefix}-input-affix-wrapper-borderless).@{ant-prefix}-input-affix-wrapper {
:not(.@{ant-prefix}-input-affix-wrapper-disabled):not(.@{ant-prefix}-input-affix-wrapper-borderless).@{ant-prefix}-input-affix-wrapper,
:not(.@{ant-prefix}-input-number-affix-wrapper-disabled):not(.@{ant-prefix}-input-number-affix-wrapper-borderless).@{ant-prefix}-input-number-affix-wrapper {
&,
&:hover {
background-color: @background-color;
@ -29,7 +30,8 @@
.active(@border-color, @hoverBorderColor, @outlineColor);
}
.@{ant-prefix}-input-prefix {
.@{ant-prefix}-input-prefix,
.@{ant-prefix}-input-number-prefix {
color: @text-color;
}

View File

@ -80,6 +80,14 @@
}
}
.@{ant-prefix}-input-number-affix-wrapper {
.@{ant-prefix}-input-number {
.@{form-prefix-cls}-rtl & {
padding: 0;
}
}
}
.@{ant-prefix}-input-search:not(.@{ant-prefix}-input-search-enter-button) {
.@{ant-prefix}-input-suffix {
.@{form-prefix-cls}-rtl & {

View File

@ -1,19 +1,24 @@
@import './index.less';
@import (reference) '../../style/themes/index';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
.@{form-item-prefix-cls} {
// ================================================================
// = Status =
// ================================================================
/* Some non-status related component style is in `components.less` */
// ========================= Explain =========================
/* To support leave along ErrorList. We add additional className to handle explain style */
&-explain {
&&-error {
&-error {
color: @error-color;
}
&&-warning {
&-warning {
color: @warning-color;
}
}
@ -67,6 +72,17 @@
padding-right: 42px;
}
// ======================= Cascader ========================
.@{ant-prefix}-cascader-picker {
&-arrow {
margin-right: 19px;
}
&-clear {
right: 32px;
}
}
// ======================== Picker =========================
// Fix issue: https://github.com/ant-design/ant-design/issues/4783
.@{ant-prefix}-picker {
@ -132,7 +148,7 @@
}
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
.active(@warning-color);
.active(@warning-color, @warning-color-hover, @warning-color-outline);
}
}
@ -141,10 +157,12 @@
.@{ant-prefix}-picker {
background-color: @form-warning-input-bg;
border-color: @warning-color;
&-focused,
&:focus {
.active(@warning-color);
.active(@warning-color, @warning-color-hover, @warning-color-outline);
}
&:not([disabled]):hover {
background-color: @form-warning-input-bg;
border-color: @warning-color;
@ -152,7 +170,7 @@
}
.@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input {
.active(@warning-color);
.active(@warning-color, @warning-color-hover, @warning-color-outline);
}
}
@ -173,7 +191,7 @@
}
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
.active(@error-color);
.active(@error-color, @error-color-hover, @error-color-outline);
}
}
@ -201,10 +219,12 @@
.@{ant-prefix}-picker {
background-color: @form-error-input-bg;
border-color: @error-color;
&-focused,
&:focus {
.active(@error-color);
.active(@error-color, @error-color-hover, @error-color-outline);
}
&:not([disabled]):hover {
background-color: @form-error-input-bg;
border-color: @error-color;
@ -221,11 +241,11 @@
}
&.@{ant-prefix}-mention-active:not([disabled]) .@{ant-prefix}-mention-editor,
.@{ant-prefix}-mention-editor:not([disabled]):focus {
.active(@error-color);
.active(@error-color, @error-color-hover, @error-color-outline);
}
}
// cascader
// Cascader
.@{ant-prefix}-cascader-picker {
&:hover
.@{ant-prefix}-cascader-picker-label:hover
@ -235,11 +255,11 @@
&:focus .@{ant-prefix}-cascader-input {
background-color: @form-error-input-bg;
.active(@error-color);
.active(@error-color, @error-color-hover, @error-color-outline);
}
}
// transfer
// Transfer
.@{ant-prefix}-transfer {
&-list {
border-color: @error-color;
@ -258,7 +278,7 @@
}
}
// RadioGroup
// Radio.Group
.@{ant-prefix}-radio-button-wrapper {
border-color: @error-color !important;
@ -268,6 +288,16 @@
}
}
}
// Mentions
.@{ant-prefix}-mentions {
border-color: @error-color !important;
&-focused,
&:focus {
.active(@error-color, @error-color-hover, @error-color-outline);
}
}
}
// ====================== Validating =======================

View File

@ -1,4 +1,7 @@
@import './index';
@import (reference) '../../style/themes/index';
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
// ================== Label ==================
.make-vertical-layout-label() {
@ -46,7 +49,7 @@
}
.@{form-prefix-cls}-vertical .@{form-item-prefix-cls}-label,
// when labelCol is 24, it is a vertical form
/* when labelCol is 24, it is a vertical form */
.@{ant-prefix}-col-24.@{form-item-prefix-cls}-label,
.@{ant-prefix}-col-xl-24.@{form-item-prefix-cls}-label {
.make-vertical-layout-label();

View File

@ -36,7 +36,7 @@ export default defineComponent({
const mergedMotion = computed(() => {
const m =
motion.value || defaultMotions.value?.[fixedMode.value] || defaultMotions.value?.other;
const res = typeof m === 'function' ? m(style, className) : m;
const res = typeof m === 'function' ? m(undefined, style, className) : m;
return { ...res, appear: props.keyPath.length <= 1 };
});
return () => {

View File

@ -75,7 +75,7 @@ export default defineComponent({
const className = ref('');
const mergedMotion = computed(() => {
const m = motion.value || defaultMotions.value?.[mode.value] || defaultMotions.value?.other;
const res = typeof m === 'function' ? m(style, className) : m;
const res = typeof m === 'function' ? m(undefined, style, className) : m;
return res ? getTransitionProps(res.name, { css: true }) : undefined;
});
return () => {

View File

@ -61,7 +61,7 @@ export interface MenuContextProps {
defaultMotions?: ComputedRef<Partial<{
[key in MenuMode | 'other']:
| CSSMotionProps
| ((style: Ref<CSSProperties>, className: Ref<string>) => CSSMotionProps);
| ((name: string, style: Ref<CSSProperties>, className: Ref<string>) => CSSMotionProps);
}> | null>;
// // Popup

View File

@ -14,7 +14,7 @@ import { initDefaultProps, isValidElement } from '../../_util/props-util';
import type { VueNode } from '../../_util/type';
import useConfigInject from '../../_util/hooks/useConfigInject';
import { getTransitionGroupProps, TransitionGroup } from '../../_util/transition';
import listAnimation from './listAnimation';
import collapseMotion from '../../_util/collapseMotion';
const HackSlot = (_, { slots }) => {
return slots.default?.()[0];
@ -143,7 +143,7 @@ export default defineComponent({
[`${prefixCls.value}-list-rtl`]: direction.value === 'rtl',
}));
const transitionGroupProps = computed(() => ({
...listAnimation(
...collapseMotion(
`${prefixCls.value}-${props.listType === 'picture-card' ? 'animate-inline' : 'animate'}`,
),
...getTransitionGroupProps(

View File

@ -42,7 +42,7 @@ export default defineComponent({
if (props.motion) {
return props.motion;
} else {
return collapseMotion(transitionStyle, transitionClass);
return collapseMotion(undefined, transitionStyle, transitionClass);
}
});
const onMotionEnd = (type?: 'appear' | 'leave') => {