@longhongguo/form-create-ant-design-vue 3.2.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,303 @@
1
+ import getConfig from './config';
2
+ import mergeProps from '@form-create/utils/lib/mergeprops';
3
+ import is, {hasProperty} from '@form-create/utils/lib/type';
4
+ import extend from '@form-create/utils/lib/extend';
5
+
6
+ function isTooltip(info) {
7
+ return info.type === 'tooltip';
8
+ }
9
+
10
+ function tidy(props, name) {
11
+ if (!hasProperty(props, name)) return;
12
+ if (is.String(props[name])) {
13
+ props[name] = {[name]: props[name], show: true};
14
+ }
15
+ }
16
+
17
+ function isFalse(val) {
18
+ return val === false;
19
+ }
20
+
21
+ function tidyBool(opt, name) {
22
+ if (hasProperty(opt, name) && !is.Object(opt[name])) {
23
+ opt[name] = {show: !!opt[name]};
24
+ }
25
+ }
26
+
27
+ function tidyRule(rule) {
28
+ const _rule = {...rule};
29
+ delete _rule.children;
30
+ return _rule;
31
+ }
32
+
33
+ export default {
34
+ validate() {
35
+ const form = this.form();
36
+ if (form) {
37
+ return form.validate();
38
+ } else {
39
+ return new Promise(v => v());
40
+ }
41
+ },
42
+ validateField(field) {
43
+ const form = this.form();
44
+ if (form) {
45
+ return form.validateFields(field);
46
+ } else {
47
+ return new Promise(v => v());
48
+ }
49
+ },
50
+ clearValidateState(ctx) {
51
+ const fItem = this.vm.refs[ctx.wrapRef];
52
+ if (fItem) {
53
+ fItem.clearValidate();
54
+ }
55
+ },
56
+ tidyOptions(options) {
57
+ ['submitBtn', 'resetBtn', 'row', 'info', 'wrap', 'col', 'title'].forEach(name => {
58
+ tidyBool(options, name);
59
+ })
60
+ return options;
61
+ },
62
+ tidyRule({prop}) {
63
+ tidy(prop, 'title');
64
+ tidy(prop, 'info');
65
+ return prop;
66
+ },
67
+ mergeProp(ctx) {
68
+ const def = {
69
+ info: {
70
+ type: 'popover',
71
+ placement: 'topLeft',
72
+ icon: 'QuestionCircleOutlined'
73
+ },
74
+ title: {},
75
+ col: {span: 24},
76
+ wrap: {},
77
+ };
78
+ ['info', 'wrap', 'col', 'title'].forEach(name => {
79
+ ctx.prop[name] = mergeProps([this.options[name] || {}, ctx.prop[name] || {}], def[name]);
80
+ });
81
+ },
82
+ getDefaultOptions() {
83
+ return getConfig();
84
+ },
85
+ adapterValidate(validate, validator) {
86
+ validate.validator = (rule, value) => {
87
+ return new Promise((resolve, reject) => {
88
+ const callback = (err) => {
89
+ if (err) {
90
+ reject(err);
91
+ } else {
92
+ resolve();
93
+ }
94
+ }
95
+ return validator(value, callback);
96
+ })
97
+ }
98
+ return validate;
99
+ },
100
+ update() {
101
+ const form = this.options.form;
102
+ this.rule = {
103
+ props: {...form},
104
+ on: {
105
+ submit: (e) => {
106
+ e.preventDefault();
107
+ }
108
+ },
109
+ style: form.style,
110
+ type: 'form',
111
+ };
112
+ },
113
+ beforeRender() {
114
+ const {key, ref, $handle} = this;
115
+ const form = this.options.form;
116
+ extend(this.rule, {key, ref, class: [form.className, form.class, 'form-create', this.$handle.preview ? 'is-preview' : '']});
117
+ extend(this.rule.props, {
118
+ model: $handle.formData,
119
+ });
120
+ },
121
+ render(children) {
122
+ if (children.slotLen() && !this.$handle.preview) {
123
+ children.setSlot(undefined, () => this.makeFormBtn());
124
+ }
125
+ return this.$r(this.rule, isFalse(this.options.row.show) ? children.getSlots() : [this.makeRow(children)]);
126
+ },
127
+ makeWrap(ctx, children) {
128
+ const rule = ctx.prop;
129
+ const uni = `${this.key}${ctx.key}`;
130
+ const col = rule.col;
131
+ const isTitle = this.isTitle(rule) && rule.wrap.title !== false;
132
+ const {layout, col: _col} = this.rule.props;
133
+ const cls = rule.wrap.class;
134
+ delete rule.wrap.class;
135
+ delete rule.wrap.title;
136
+ const item = isFalse(rule.wrap.show) ? children : this.$r(mergeProps([rule.wrap, {
137
+ props: {
138
+ ...tidyRule(rule.wrap || {}),
139
+ name: ctx.id,
140
+ rules: ctx.injectValidate(),
141
+ ...(layout !== 'horizontal' ? {labelCol: {}, wrapperCol: {}} : {})
142
+ },
143
+ class: this.$render.mergeClass(cls || rule.className, 'fc-form-item'),
144
+ key: `${uni}fi`,
145
+ ref: ctx.wrapRef,
146
+ type: 'formItem',
147
+ }]), {default: () => children, ...(isTitle ? {label: () => this.makeInfo(rule, uni, ctx)} : {})});
148
+ return (layout === 'inline' || isFalse(_col) || isFalse(col.show)) ? item : this.makeCol(rule, uni, [item]);
149
+ },
150
+ isTitle(rule) {
151
+ if (this.options.form.title === false) return false;
152
+ const title = rule.title;
153
+ return !((!title.title && !title.native) || isFalse(title.show));
154
+ },
155
+ makeInfo(rule, uni, ctx) {
156
+ const titleProp = {...rule.title};
157
+ const infoProp = {...rule.info};
158
+ if (this.options.form.title === false) return false;
159
+ if ((!titleProp.title && !titleProp.native) || isFalse(titleProp.show)) return;
160
+ const isTip = isTooltip(infoProp);
161
+ const titleSlot = this.getSlot('title');
162
+ const children = [titleSlot ? titleSlot({title: ctx.refRule?.__$title?.value, rule: ctx.rule, options: this.options}) : ctx.refRule?.__$title?.value];
163
+
164
+ if (!isFalse(infoProp.show) && (infoProp.info || infoProp.native) && !isFalse(infoProp.icon)) {
165
+ const prop = {
166
+ type: infoProp.type || 'popover',
167
+ props: tidyRule(infoProp),
168
+ key: `${uni}pop`,
169
+ };
170
+
171
+ delete prop.props.icon;
172
+ delete prop.props.show;
173
+ delete prop.props.info;
174
+ delete prop.props.align;
175
+ delete prop.props.native;
176
+
177
+ const field = isTip ? 'title' : 'content';
178
+ if (infoProp.info && !hasProperty(prop.props, field)) {
179
+ prop.props[field] = ctx.refRule?.__$info?.value;
180
+ }
181
+ children[infoProp.align !== 'left' ? 'unshift' : 'push'](this.$r(mergeProps([infoProp, prop]), {
182
+ [titleProp.slot || 'default']: () => this.$r({
183
+ type: infoProp.icon === true ? 'QuestionCircleOutlined' : (infoProp.icon || ''),
184
+ props: {type: infoProp.icon === true ? 'QuestionCircleOutlined' : infoProp.icon},
185
+ key: `${uni}i`
186
+ })
187
+ }))
188
+ }
189
+
190
+ const _prop = mergeProps([titleProp, {
191
+ props: tidyRule(titleProp),
192
+ key: `${uni}tit`,
193
+ class: 'fc-form-title',
194
+ type: titleProp.type || 'span',
195
+ }]);
196
+
197
+ delete _prop.props.show;
198
+ delete _prop.props.title;
199
+ delete _prop.props.native;
200
+
201
+ return this.$r(_prop, children);
202
+ },
203
+ makeCol(rule, uni, children) {
204
+ const col = rule.col;
205
+ return this.$r({
206
+ class: this.$render.mergeClass(col.class, 'fc-form-col'),
207
+ type: 'col',
208
+ props: col || {span: 24},
209
+ key: `${uni}col`
210
+ }, children);
211
+ },
212
+ makeRow(children) {
213
+ const row = this.options.row || {};
214
+ return this.$r({
215
+ type: 'row',
216
+ props: row,
217
+ class: this.$render.mergeClass(row.class, 'fc-form-row'),
218
+ key: `${this.key}row`
219
+ }, children)
220
+ },
221
+ makeFormBtn() {
222
+ let vn = [];
223
+ if (!isFalse(this.options.submitBtn.show)) {
224
+ vn.push(this.makeSubmitBtn())
225
+ }
226
+ if (!isFalse(this.options.resetBtn.show)) {
227
+ vn.push(this.makeResetBtn())
228
+ }
229
+ if (!vn.length) {
230
+ return;
231
+ }
232
+ let {labelCol, wrapperCol, layout} = this.rule.props;
233
+ if (layout !== 'horizontal') {
234
+ labelCol = wrapperCol = {};
235
+ }
236
+ const item = this.$r({
237
+ type: 'formItem',
238
+ class: 'fc-form-item fc-form-footer',
239
+ key: `${this.key}fb`,
240
+ props: {
241
+ labelCol,
242
+ wrapperCol,
243
+ label: ' ', colon: false
244
+ }
245
+ }, vn);
246
+
247
+ return layout === 'inline'
248
+ ? item
249
+ : this.$r({
250
+ type: 'col',
251
+ class: 'fc-form-col',
252
+ props: {span: 24},
253
+ key: `${this.key}fc`
254
+ }, [item]);
255
+ },
256
+
257
+ makeResetBtn() {
258
+ const resetBtn = {...this.options.resetBtn};
259
+ const innerText = resetBtn.innerText || this.$handle.api.t('reset') || '重置';
260
+ delete resetBtn.innerText;
261
+ delete resetBtn.click;
262
+ delete resetBtn.col;
263
+ delete resetBtn.show;
264
+ return this.$r({
265
+ type: 'button',
266
+ props: resetBtn,
267
+ class: 'fc-reset-btn',
268
+ style: {width: resetBtn.width, marginLeft: '10px'},
269
+ on: {
270
+ click: () => {
271
+ const fApi = this.$handle.api;
272
+ this.options.resetBtn.click
273
+ ? this.options.resetBtn.click(fApi)
274
+ : fApi.resetFields();
275
+ }
276
+ },
277
+ key: `${this.key}b2`,
278
+ }, [innerText]);
279
+ },
280
+ makeSubmitBtn() {
281
+ const submitBtn = {...this.options.submitBtn};
282
+ const innerText = submitBtn.innerText || this.$handle.api.t('submit') || '提交';
283
+ delete submitBtn.innerText;
284
+ delete submitBtn.click;
285
+ delete submitBtn.col;
286
+ delete submitBtn.show;
287
+ return this.$r({
288
+ type: 'button',
289
+ props: submitBtn,
290
+ class: 'fc-submit-btn',
291
+ style: {width: submitBtn.width},
292
+ on: {
293
+ click: () => {
294
+ const fApi = this.$handle.api;
295
+ this.options.submitBtn.click
296
+ ? this.options.submitBtn.click(fApi)
297
+ : fApi.submit().catch(()=>{});
298
+ }
299
+ },
300
+ key: `${this.key}b1`,
301
+ }, [innerText]);
302
+ }
303
+ }
@@ -0,0 +1,11 @@
1
+ export default {
2
+ autoComplete: 'value',
3
+ cascader: 'value',
4
+ inputNumber: 'value',
5
+ inputPassword: 'value',
6
+ textarea: 'value',
7
+ rate: 'value',
8
+ slider: 'value',
9
+ treeSelect: 'value',
10
+ switch: 'checked',
11
+ }
@@ -0,0 +1,55 @@
1
+ import is from '@form-create/utils/lib/type';
2
+
3
+ const required = {
4
+ name: 'required',
5
+ load(inject, rule, api) {
6
+ const val = parseVal(inject.getValue());
7
+ if (val.required === false) {
8
+ inject.clearProp();
9
+ api.clearValidateState([rule.field]);
10
+ } else {
11
+ const validate = {
12
+ required: true,
13
+ validator(_, v) {
14
+ return new Promise((resolve, reject) => {
15
+ is.empty(v) ? reject(validate.message) : resolve();
16
+ })
17
+ },
18
+ ...val,
19
+ };
20
+ const title = rule.__fc__.refRule?.__$title?.value;
21
+ if (!validate.message) {
22
+ validate.message = api.t('required', {title}) || (title + (api.getLocale() === 'en' ? ' is required' : '不能为空'));
23
+ } else {
24
+ const match = validate.message.match(/^\{\{\s*\$t\.(.+)\s*\}\}$/);
25
+ if (match) {
26
+ validate.message = api.t(match[1], {title});
27
+ }
28
+ }
29
+ inject.getProp().validate = [validate];
30
+ }
31
+ api.sync(rule);
32
+ },
33
+ watch(...args) {
34
+ required.load(...args);
35
+ }
36
+ }
37
+
38
+ function parseVal(val) {
39
+ if (is.Boolean(val)) {
40
+ return {required: val}
41
+ } else if (is.String(val)) {
42
+ return {message: val};
43
+ } else if (is.Undef(val)) {
44
+ return {required: false};
45
+ } else if (is.Function(val)) {
46
+ return {validator: val};
47
+ } else if (!is.Object(val)) {
48
+ return {};
49
+ } else {
50
+ return val;
51
+ }
52
+ }
53
+
54
+
55
+ export default required
package/src/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import antdvFormCreate from './core/index';
2
+
3
+ const FormCreate = antdvFormCreate();
4
+
5
+ if (typeof window !== 'undefined') {
6
+ window.formCreate = FormCreate;
7
+ }
8
+
9
+ const maker = FormCreate.maker;
10
+
11
+ export {maker}
12
+
13
+ export default FormCreate;
@@ -0,0 +1,35 @@
1
+ import { hasProperty } from '@form-create/utils/lib/type'
2
+
3
+ export default {
4
+ name: 'cascader',
5
+ mergeProp(ctx) {
6
+ const props = ctx.prop.props
7
+ if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []
8
+
9
+ // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态
10
+ const fetchData = ctx.effectData('fetch')
11
+ const isLoading = fetchData && fetchData.loading === true
12
+
13
+ // 如果正在加载,设置 disabled 和 loading
14
+ if (isLoading) {
15
+ props.disabled = true
16
+ props.loading = true
17
+ }
18
+ },
19
+ render(children, ctx) {
20
+ // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)
21
+ const fetchData = ctx.effectData('fetch')
22
+ const isLoading = fetchData && fetchData.loading === true
23
+
24
+ // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽
25
+ if (isLoading && children.loading) {
26
+ // 将 loading 插槽合并到 children 中,作为 notFoundContent
27
+ const newChildren = { ...children }
28
+ newChildren.notFoundContent = children.loading
29
+ return ctx.$render.defaultRender(ctx, newChildren)
30
+ }
31
+
32
+ // 调用默认渲染
33
+ return ctx.$render.defaultRender(ctx, children)
34
+ }
35
+ }
@@ -0,0 +1,12 @@
1
+ import {hasProperty} from '@form-create/utils/lib/type';
2
+
3
+ export default {
4
+ name: 'checkbox',
5
+ modelField: 'value',
6
+ mergeProp(ctx) {
7
+ const props = ctx.prop.props;
8
+ if (!hasProperty(props, 'options'))
9
+ props.options = ctx.prop.options || [];
10
+ }
11
+
12
+ }
@@ -0,0 +1,44 @@
1
+ import { creatorFactory } from '@longhongguo/form-create-core/src/index'
2
+
3
+ const FORMAT_TYPE = {
4
+ date: 'YYYY-MM-DD',
5
+ month: 'YYYY-MM',
6
+ week: 'YYYY-wo',
7
+ quarter: 'YYYY-qQ',
8
+ year: 'YYYY'
9
+ }
10
+
11
+ const name = 'datePicker'
12
+
13
+ export default {
14
+ name,
15
+ maker: (function () {
16
+ return ['date', 'month', 'week'].reduce(
17
+ (initial, type) => {
18
+ initial[type] = creatorFactory(name, { type })
19
+ return initial
20
+ },
21
+ {
22
+ dateRange: creatorFactory(name, { type: 'range' }),
23
+ datetimeRange: creatorFactory(name, (m) =>
24
+ m.props({ type: 'range', showTime: true })
25
+ )
26
+ }
27
+ )
28
+ })(),
29
+ modelField: 'value',
30
+ mergeProp(ctx) {
31
+ const props = ctx.prop.props
32
+ const type = props.type || props.picker
33
+ if (!props.valueFormat) {
34
+ props.valueFormat =
35
+ (FORMAT_TYPE[type] || FORMAT_TYPE['date']) +
36
+ (props.showTime && (!type || type === 'date') ? ' HH:mm:ss' : '')
37
+ }
38
+ },
39
+ render(children, ctx) {
40
+ return ctx.$render.vNode[
41
+ (ctx.prop.props.range === true ? 'range' : 'date') + 'Picker'
42
+ ](ctx.prop, children)
43
+ }
44
+ }
@@ -0,0 +1,13 @@
1
+ import { creatorFactory } from '@longhongguo/form-create-core/src/index'
2
+
3
+ const name = 'hidden'
4
+
5
+ export default {
6
+ name,
7
+ maker: {
8
+ [name]: (field, value) => creatorFactory(name)('', field, value)
9
+ },
10
+ render() {
11
+ return []
12
+ }
13
+ }
@@ -0,0 +1,27 @@
1
+ import checkbox from './checkbox'
2
+ import radio from './radio'
3
+ import select from './select'
4
+ import cascader from './cascader'
5
+ import datePicker from './datePicker'
6
+ import hidden from './hidden'
7
+ import input from './input'
8
+ import timePicker from './timePicker'
9
+ import tree from './tree'
10
+ import row from './row'
11
+ import rangePicker from './rangePicker'
12
+ import timeRangePicker from './timeRangePicker'
13
+
14
+ export default [
15
+ checkbox,
16
+ datePicker,
17
+ rangePicker,
18
+ hidden,
19
+ input,
20
+ timePicker,
21
+ timeRangePicker,
22
+ tree,
23
+ radio,
24
+ select,
25
+ cascader,
26
+ row
27
+ ]
@@ -0,0 +1,30 @@
1
+ import { creatorFactory } from '@longhongguo/form-create-core/src/index'
2
+
3
+ const name = 'input'
4
+ export default {
5
+ name,
6
+ maker: (function () {
7
+ return ['password', 'url', 'email', 'text', 'textarea', 'search'].reduce(
8
+ (maker, type) => {
9
+ maker[type] = creatorFactory(name, { type })
10
+ return maker
11
+ },
12
+ {
13
+ idate: creatorFactory(name, { type: 'date' })
14
+ }
15
+ )
16
+ })(),
17
+ modelField: 'value',
18
+ render(children, ctx) {
19
+ let type = ctx.prop.props.type
20
+ if (['textarea', 'search', 'password'].indexOf(type) === -1) type = 'input'
21
+
22
+ type =
23
+ {
24
+ textarea: 'aTextarea',
25
+ search: 'aInputSearch',
26
+ password: 'aInputPassword'
27
+ }[type] || 'aInput'
28
+ return ctx.$render.vNode.make(type, ctx.prop, children)
29
+ }
30
+ }
@@ -0,0 +1,5 @@
1
+ import checkbox from './checkbox';
2
+
3
+ export default {
4
+ ...checkbox, name: 'radio'
5
+ };
@@ -0,0 +1,12 @@
1
+ import datePicker from './datePicker';
2
+
3
+ const name = 'rangePicker';
4
+
5
+ export default {
6
+ ...datePicker,
7
+ name,
8
+ maker: {},
9
+ render(children, ctx) {
10
+ return ctx.$render.vNode['rangePicker'](ctx.prop, children);
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ export default {
2
+ name: 'FcRow',
3
+ render(_, ctx) {
4
+ return ctx.vNode.col({props: {span: 24}}, {
5
+ default: () => [
6
+ ctx.vNode.row(ctx.prop, _)
7
+ ]
8
+ })
9
+ }
10
+ }
@@ -0,0 +1,37 @@
1
+ import checkbox from './checkbox'
2
+ import { hasProperty } from '@form-create/utils/lib/type'
3
+
4
+ export default {
5
+ ...checkbox,
6
+ name: 'select',
7
+ mergeProp(ctx) {
8
+ const props = ctx.prop.props
9
+ if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []
10
+
11
+ // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态
12
+ const fetchData = ctx.effectData('fetch')
13
+ const isLoading = fetchData && fetchData.loading === true
14
+
15
+ // 如果正在加载,设置 disabled 和 loading
16
+ if (isLoading) {
17
+ props.disabled = true
18
+ props.loading = true
19
+ }
20
+ },
21
+ render(children, ctx) {
22
+ // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)
23
+ const fetchData = ctx.effectData('fetch')
24
+ const isLoading = fetchData && fetchData.loading === true
25
+
26
+ // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽
27
+ if (isLoading && children.loading) {
28
+ // 将 loading 插槽合并到 children 中,作为 notFoundContent
29
+ const newChildren = { ...children }
30
+ newChildren.notFoundContent = children.loading
31
+ return ctx.$render.defaultRender(ctx, newChildren)
32
+ }
33
+
34
+ // 调用默认渲染
35
+ return ctx.$render.defaultRender(ctx, children)
36
+ }
37
+ }
@@ -0,0 +1,15 @@
1
+ export default {
2
+ name: 'timePicker',
3
+ modelField: 'value',
4
+ mergeProp(ctx) {
5
+ const props = ctx.prop.props;
6
+ if (!props.valueFormat) {
7
+ props.valueFormat = 'HH:mm:ss';
8
+ }
9
+ },
10
+ render(children, ctx) {
11
+ return ctx.$render.vNode['time' +( ctx.prop.props.range === true ? 'Range' : '') + 'Picker'](ctx.prop, children);
12
+ }
13
+
14
+ }
15
+
@@ -0,0 +1,11 @@
1
+ import timePicker from './timePicker';
2
+
3
+ const name = 'timeRangePicker';
4
+
5
+ export default {
6
+ ...timePicker,
7
+ name,
8
+ render(children, ctx) {
9
+ return ctx.$render.vNode['timeRangePicker'](ctx.prop, children);
10
+ }
11
+ }
@@ -0,0 +1,16 @@
1
+ export default {
2
+ name: 'tree',
3
+ modelField: 'checkedKeys',
4
+ mergeProp(ctx) {
5
+ const props = ctx.prop.props;
6
+ if (!props.fieldNames)
7
+ props.fieldNames = {
8
+ key: 'id'
9
+ };
10
+ else if (!props.fieldNames.key) props.fieldNames.key = 'id';
11
+ props.checkedKeys = ctx.rule.value;
12
+ props.checkable = true;
13
+ },
14
+
15
+ }
16
+
@@ -0,0 +1,23 @@
1
+ .form-create .form-create .ant-form-item {
2
+ margin-bottom: 22px;
3
+ }
4
+
5
+ .form-create .form-create .ant-form-item.ant-form-item-with-help {
6
+ margin-bottom: 3px;
7
+ }
8
+
9
+ .form-create .form-create .ant-form-item .ant-form-item.ant-form-item-with-help {
10
+ margin-bottom: -22px;
11
+ }
12
+
13
+ .form-create{
14
+ width: 100%;
15
+ }
16
+
17
+ .form-create.is-preview .fc-clock, .form-create .fc-none, .form-create.is-preview .ant-form-item .ant-form-item-label >label.ant-form-item-required::before {
18
+ display: none !important;
19
+ }
20
+
21
+ .fc-form-footer {
22
+ margin-top: 12px;
23
+ }