feat: add new form

pull/1877/head
tangjinzhou 2020-03-14 20:40:43 +08:00
parent 4c3feca9c5
commit c37fe37a56
10 changed files with 562 additions and 55 deletions

View File

@ -19,6 +19,7 @@
- 🔥🔥🔥 [Descriptions](https://antdv.com/components/descriptions/) Display multiple read-only fields in groups.
- 🔥🔥🔥 [PageHeader](https://antdv.com/components/page-header/) can be used to declare the topic of the page, display important information about the page that the user is concerned about, and carry the operation items related to the current page.
- 🔥🔥🔥 [Result](https://antdv.com/components/result) is used to feedback the processing results of a series of operation tasks.
- 🔥🔥🔥 [NewForm](https://antdv.com/components/n-form) Form components that use v-model for automatic validation are more concise than v-decorator forms.
- 🔥 Descriptions supports vertical layout.
- 🔥 Progress.Circle supports gradient colors.
- 🔥 Progress.Line supports gradient colors.

View File

@ -14,11 +14,12 @@
`2020-03-06`
- 新增了个组件:
- 新增了个组件:
- 🔥🔥🔥 [Mentions](https://antdv.com/components/mentions-cn/) 新增提及组件并废弃原有 Mention 组件。
- 🔥🔥🔥 [Descriptions](https://antdv.com/components/descriptions-cn/) 成组展示多个只读字段。
- 🔥🔥🔥 [PageHeader](https://antdv.com/components/page-header-cn/) 可用于声明页面主题、展示用户所关注的页面重要信息,以及承载与当前页相关的操作项。
- 🔥🔥🔥 [Result](https://antdv.com/components/result) 用于反馈一系列操作任务的处理结果。
- 🔥🔥🔥 [NewForm](https://antdv.com/components/n-form) 使用 v-model 进行自动校验的表单组件,相较于 v-decorator 形式的表单,更加简洁。
- 🔥 Descriptions 支持垂直布局。
- 🔥 Progress.Circle 支持渐变色。
- 🔥 Progress.Line 支持渐变色。

@ -1 +1 @@
Subproject commit 9a67d0070ac57b29c70624e8a630e39146b44725
Subproject commit 3ad62e059028e716305b9d88ca1bbf9e4d79118c

View File

@ -277,47 +277,45 @@ exports[`renders ./antdv-demo/docs/form/demo/horizontal-login.vue correctly 1`]
`;
exports[`renders ./antdv-demo/docs/form/demo/layout.vue correctly 1`] = `
<div>
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Form Layout" class="">Form Layout</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="horizontal"><span class="ant-radio-button-inner"></span></span><span>
Horizontal
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="vertical"><span class="ant-radio-button-inner"></span></span><span>
Vertical
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="inline"><span class="ant-radio-button-inner"></span></span><span>
Inline
</span></label></div></span>
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Form Layout" class="">Form Layout</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="horizontal"><span class="ant-radio-button-inner"></span></span><span>
Horizontal
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="vertical"><span class="ant-radio-button-inner"></span></span><span>
Vertical
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="inline"><span class="ant-radio-button-inner"></span></span><span>
Inline
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field A" class="">Field A</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field A" class="">Field A</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field B" class="">Field B</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field B" class="">Field B</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Submit</span></button></span>
<!---->
</div>
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Submit</span></button></span>
<!---->
</div>
</div>
</div>
</form>
</div>
`;
exports[`renders ./antdv-demo/docs/form/demo/normal-login.vue correctly 1`] = `

View File

@ -1,16 +1,11 @@
import PropTypes from '../_util/vue-types';
import classNames from 'classnames';
import { ColProps } from '../grid/Col';
import Vue from 'vue';
import isRegExp from 'lodash/isRegExp';
import warning from '../_util/warning';
import createDOMForm from '../vc-form/src/createDOMForm';
import createFormField from '../vc-form/src/createFormField';
import FormItem from './FormItem';
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants';
import { initDefaultProps, getListeners } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
import Base from '../base';
export const FormProps = {
layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']),
@ -144,7 +139,7 @@ const Form = {
if (message) {
valid = false;
}
invalidFields = objectAssign({}, invalidFields, field);
invalidFields = Object.assign({}, invalidFields, field);
if (typeof callback === 'function' && ++count === this.fields.length) {
callback(valid, invalidFields);
}

View File

@ -1,10 +1,19 @@
import AsyncValidator from 'async-validator';
import cloneDeep from 'lodash/cloneDeep';
import PropTypes from '../_util/vue-types';
import { ColProps } from '../grid/Col';
import { initDefaultProps, getComponentFromProp, getOptionProps } from '../_util/props-util';
import {
initDefaultProps,
getComponentFromProp,
getOptionProps,
getEvents,
filterEmpty,
isValidElement,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin';
import { ConfigConsumerProps } from '../config-provider';
import FormItem from '../form/FormItem';
import { cloneElement } from '../_util/vnode';
function noop() {}
@ -45,8 +54,9 @@ export const FormItemProps = {
hasFeedback: PropTypes.bool,
colon: PropTypes.bool,
labelAlign: PropTypes.oneOf(['left', 'right']),
name: PropTypes.string,
rules: PropTypes.array,
prop: PropTypes.string,
rules: PropTypes.oneOfType([Array, Object]),
autoLink: PropTypes.bool,
required: PropTypes.bool,
validateStatus: PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
};
@ -57,6 +67,7 @@ export default {
mixins: [BaseMixin],
props: initDefaultProps(FormItemProps, {
hasFeedback: false,
autoLink: true,
}),
provide() {
return {
@ -88,6 +99,20 @@ export default {
}
return getPropByPath(model, path, true).v;
},
isRequired() {
let rules = this.getRules();
let isRequired = false;
if (rules && rules.length) {
rules.every(rule => {
if (rule.required) {
isRequired = true;
return false;
}
return true;
});
}
return isRequired;
},
},
watch: {
validateStatus(val) {
@ -98,11 +123,7 @@ export default {
if (this.prop) {
const { addField } = this.FormContext;
addField && addField(this);
let initialValue = this.fieldValue;
if (Array.isArray(initialValue)) {
initialValue = [...initialValue];
}
this.initialValue = initialValue;
this.initialValue = cloneDeep(this.fieldValue);
}
},
beforeDestroy() {
@ -113,7 +134,7 @@ export default {
validate(trigger, callback = noop) {
this.validateDisabled = false;
const rules = this.getFilteredRule(trigger);
if ((!rules || rules.length === 0) && this.required === undefined) {
if (!rules || rules.length === 0) {
callback();
return true;
}
@ -138,12 +159,13 @@ export default {
});
},
getRules() {
let formRules = this.FormContext.rules || {};
let formRules = this.FormContext.rules;
const selfRules = this.rules;
const requiredRule = this.required !== undefined ? { required: !!this.required } : [];
const requiredRule =
this.required !== undefined ? { required: !!this.required, trigger: 'change' } : [];
const prop = getPropByPath(formRules, this.prop || '');
formRules = formRules ? prop.o[this.prop || ''] || prop.v : [];
return [...selfRules, ...formRules, ...requiredRule];
return [].concat(selfRules || formRules || []).concat(requiredRule);
},
getFilteredRule(trigger) {
const rules = this.getRules();
@ -196,7 +218,7 @@ export default {
},
},
render() {
const { $slots } = this;
const { $slots, $scopedSlots } = this;
const props = getOptionProps(this);
const label = getComponentFromProp(this, 'label');
const extra = getComponentFromProp(this, 'extra');
@ -208,8 +230,31 @@ export default {
extra,
validateStatus: this.validateState,
help: this.validateMessage || help,
required: this.isRequired || props.required,
},
};
return <FormItem {...formProps}>{$slots.default}</FormItem>;
const children = filterEmpty($scopedSlots.default ? $scopedSlots.default() : $slots.default);
let firstChildren = children[0];
if (this.prop && this.autoLink && isValidElement(firstChildren)) {
const originalEvents = getEvents(firstChildren);
firstChildren = cloneElement(firstChildren, {
on: {
blur: (...args) => {
originalEvents.blur && originalEvents.blur(...args);
this.onFieldBlur();
},
change: (...args) => {
originalEvents.change && originalEvents.change(...args);
this.onFieldChange();
},
},
});
}
return (
<FormItem {...formProps}>
{firstChildren}
{children.slice(1)}
</FormItem>
);
},
};

View File

@ -0,0 +1,282 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders ./antdv-demo/docs/n-form/demo/basic.md correctly 1`] = `
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity name" class="">Activity name</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity zone" class="">Activity zone</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div tabindex="0" class="ant-select ant-select-enabled"><div role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="test-uuid" class="ant-select-selection ant-select-selection--single"><div class="ant-select-selection__rendered"><div unselectable="on" class="ant-select-selection__placeholder" style="display: block; user-select: none;">please select your zone</div></div><span unselectable="on" class="ant-select-arrow" style="user-select: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></div>
</div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity time" class="">Activity time</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><span class="ant-calendar-picker" style="min-width: 195px; width: 100%;" type="date"><div class=""><input readonly="true" placeholder="Pick a date" class="ant-calendar-picker-input ant-input"><i aria-label="icon: calendar" class="ant-calendar-picker-icon anticon anticon-calendar"><svg viewBox="64 64 896 896" data-icon="calendar" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"></path></svg></i></div></span></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Instant delivery" class="">Instant delivery</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" role="switch" class="ant-switch"><span class="ant-switch-inner"></span></button></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity type" class="">Activity type</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-checkbox-group"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="1"><span class="ant-checkbox-inner"></span></span><span>
Online
</span></label> <label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="2"><span class="ant-checkbox-inner"></span></span><span>
Promotion
</span></label> <label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="3"><span class="ant-checkbox-inner"></span></span><span>
Offline
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Resources" class="">Resources</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="1"><span class="ant-radio-inner"></span></span><span>
Sponsor
</span></label><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="2"><span class="ant-radio-inner"></span></span><span>
Venue
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity form" class="">Activity form</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><textarea class="ant-input"></textarea></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Create</span></button><button type="button" class="ant-btn" style="margin-left: 10px;"><span>Cancel</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;
exports[`renders ./antdv-demo/docs/n-form/demo/custom-validation.md correctly 1`] = `
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Password" class="">Password</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input type="password" autocomplete="off" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Confirm" class="">Confirm</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input type="password" autocomplete="off" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Age" class="">Age</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Submit</span></button><button type="button" class="ant-btn" style="margin-left: 10px;"><span>Reset</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;
exports[`renders ./antdv-demo/docs/n-form/demo/dynamic-form-item.md correctly 1`] = `
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-xs-24 ant-col-xs-offset-0 ant-col-sm-20 ant-col-sm-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-dashed" style="width: 60%;"><i aria-label="icon: plus" class="anticon anticon-plus"><svg viewBox="64 64 896 896" data-icon="plus" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path><path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path></svg></i><span>Add field</span></button></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-xs-24 ant-col-xs-offset-0 ant-col-sm-20 ant-col-sm-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="submit" class="ant-btn ant-btn-primary"><span>Submit</span></button><button type="button" class="ant-btn" style="margin-left: 10px;"><span>Reset</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;
exports[`renders ./antdv-demo/docs/n-form/demo/horizontal-login.md correctly 1`] = `
<form class="ant-form ant-form-inline">
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><span class="ant-input-affix-wrapper"><span class="ant-input-prefix"><i slot="prefix" aria-label="icon: user" class="anticon anticon-user" style="color: rgba(0, 0, 0, 0.25);"><svg viewBox="64 64 896 896" data-icon="user" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"></path></svg></i></span><input placeholder="Username" type="text" class="ant-input"></span></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><span class="ant-input-affix-wrapper"><span class="ant-input-prefix"><i slot="prefix" aria-label="icon: lock" class="anticon anticon-lock" style="color: rgba(0, 0, 0, 0.25);"><svg viewBox="64 64 896 896" data-icon="lock" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><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 1 0-56 0z"></path></svg></i></span><input placeholder="Password" type="password" class="ant-input"></span></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button disabled="disabled" type="submit" class="ant-btn ant-btn-primary"><span>Log in</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;
exports[`renders ./antdv-demo/docs/n-form/demo/layout.md correctly 1`] = `
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Form Layout" class="">Form Layout</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="horizontal"><span class="ant-radio-button-inner"></span></span><span>
Horizontal
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="vertical"><span class="ant-radio-button-inner"></span></span><span>
Vertical
</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="inline"><span class="ant-radio-button-inner"></span></span><span>
Inline
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field A" class="">Field A</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Field B" class="">Field B</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="input placeholder" type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Submit</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;
exports[`renders ./antdv-demo/docs/n-form/demo/validation.md correctly 1`] = `
<form class="ant-form ant-form-horizontal">
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity name" class="ant-form-item-required">Activity name</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><input type="text" class="ant-input"></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity zone" class="ant-form-item-required">Activity zone</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div tabindex="0" class="ant-select ant-select-enabled"><div role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="test-uuid" class="ant-select-selection ant-select-selection--single"><div class="ant-select-selection__rendered"><div unselectable="on" class="ant-select-selection__placeholder" style="display: block; user-select: none;">please select your zone</div></div><span unselectable="on" class="ant-select-arrow" style="user-select: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></div>
</div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity time" class="ant-form-item-required">Activity time</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><span class="ant-calendar-picker" style="min-width: 195px; width: 100%;" type="date"><div class=""><input readonly="true" placeholder="Pick a date" class="ant-calendar-picker-input ant-input"><i aria-label="icon: calendar" class="ant-calendar-picker-icon anticon anticon-calendar"><svg viewBox="64 64 896 896" data-icon="calendar" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"></path></svg></i></div></span></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Instant delivery" class="">Instant delivery</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" role="switch" class="ant-switch"><span class="ant-switch-inner"></span></button></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity type" class="ant-form-item-required">Activity type</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-checkbox-group"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="1"><span class="ant-checkbox-inner"></span></span><span>
Online
</span></label> <label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="2"><span class="ant-checkbox-inner"></span></span><span>
Promotion
</span></label> <label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="3"><span class="ant-checkbox-inner"></span></span><span>
Offline
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Resources" class="ant-form-item-required">Resources</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="1"><span class="ant-radio-inner"></span></span><span>
Sponsor
</span></label><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="2"><span class="ant-radio-inner"></span></span><span>
Venue
</span></label></div></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-4 ant-form-item-label"><label title="Activity form" class="ant-form-item-required">Activity form</label></div>
<div class="ant-col ant-col-14 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><textarea class="ant-input"></textarea></span>
<!---->
</div>
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control-wrapper">
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="button" class="ant-btn ant-btn-primary"><span>Create</span></button><button type="button" class="ant-btn" style="margin-left: 10px;"><span>Reset</span></button></span>
<!---->
</div>
</div>
</div>
</form>
`;

View File

@ -27,6 +27,7 @@ Array [
"Divider",
"Dropdown",
"Form",
"NewForm",
"Icon",
"Input",
"InputNumber",

69
types/n-form/form-item.d.ts vendored Normal file
View File

@ -0,0 +1,69 @@
// Project: https://github.com/vueComponent/ant-design-vue
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from '../component';
import { Col } from '../grid/col';
export declare class NFormItem extends AntdComponent {
/**
* Used with label, whether to display : after label text.
* @default true
* @type boolean
*/
colon: boolean;
/**
* The extra prompt message. It is similar to help. Usage example: to display error message and prompt message at the same time.
* @type any (string | slot)
*/
extra: any;
/**
* Used with validateStatus, this option specifies the validation status icon. Recommended to be used only with Input.
* @default false
* @type boolean
*/
hasFeedback: boolean;
/**
* The prompt message. If not provided, the prompt message will be generated by the validation rule.
* @type any (string | slot)
*/
help: any;
/**
* Label test
* @type any (string | slot)
*/
label: any;
/**
* 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>
* @type Col
*/
labelCol: Col;
/**
* Whether provided or not, it will be generated by the validation rule.
* @default false
* @type boolean
*/
required: boolean;
/**
* The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating'
* @type string
*/
validateStatus: '' | 'success' | 'warning' | 'error' | 'validating';
/**
* The layout for input controls, same as labelCol
* @type Col
*/
wrapperCol: Col;
labelAlign: 'left' | 'right';
prop: string;
rules: object | array;
autoLink: boolean;
}

115
types/n-form/form.d.ts vendored Normal file
View File

@ -0,0 +1,115 @@
// Project: https://github.com/vueComponent/ant-design-vue
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from '../component';
import { Col } from '../grid/col';
import Vue from 'vue';
import { NFormItem } from './form-item';
declare interface ValidationRule {
trigger?: string;
/**
* validation error message
* @type string
*/
message?: string;
/**
* built-in validation type, available options: https://github.com/yiminghe/async-validator#type
* @default 'string'
* @type string
*/
type?: string;
/**
* indicates whether field is required
* @default false
* @type boolean
*/
required?: boolean;
/**
* treat required fields that only contain whitespace as errors
* @default false
* @type boolean
*/
whitespace?: boolean;
/**
* validate the exact length of a field
* @type number
*/
len?: number;
/**
* validate the min length of a field
* @type number
*/
min?: number;
/**
* validate the max length of a field
* @type number
*/
max?: number;
/**
* validate the value from a list of possible values
* @type string | string[]
*/
enum?: string | string[];
/**
* validate from a regular expression
* @type boolean
*/
pattern?: RegExp;
/**
* transform a value before validation
* @type Function
*/
transform?: (value: any) => any;
/**
* custom validate function (Note: callback must be called)
* @type Function
*/
validator?: (rule: any, value: any, callback: Function) => any;
}
export declare class NForm extends AntdComponent {
static Item: typeof NFormItem;
/**
* Hide required mark of all form items
* @default false
* @type boolean
*/
hideRequiredMark: boolean;
/**
* 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>
* @type Col
*/
labelCol: Col;
/**
* Define form layout
* @default 'horizontal'
* @type string
*/
layout: 'horizontal' | 'inline' | 'vertical';
/**
* The layout for input controls, same as labelCol
* @type Col
*/
wrapperCol: Col;
colon: boolean;
labelAlign: 'left' | 'right';
model: object;
rules: object;
validateOnRuleChange: boolean;
}