@form-create/component-elm-group 3.1.23 → 3.1.27

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.
package/src/component.jsx CHANGED
@@ -1,9 +1,8 @@
1
1
  import {hasProperty} from '@form-create/utils/lib/type';
2
- import {defineComponent, markRaw, nextTick} from 'vue';
3
- import IconCirclePlus from './IconCirclePlus.vue';
4
- import IconRemove from './IconRemove.vue';
2
+ import {defineComponent, markRaw, nextTick, watch} from 'vue';
5
3
  import deepExtend, {deepCopy} from '@form-create/utils/lib/deepextend';
6
4
  import extend from '@form-create/utils/lib/extend';
5
+ import './style.css';
7
6
 
8
7
  const NAME = 'fcGroup';
9
8
 
@@ -32,6 +31,10 @@ export default defineComponent({
32
31
  default: () => []
33
32
  },
34
33
  defaultValue: Object,
34
+ sortBtn: {
35
+ type: Boolean,
36
+ default: true
37
+ },
35
38
  disabled: {
36
39
  type: Boolean,
37
40
  default: false
@@ -40,10 +43,6 @@ export default defineComponent({
40
43
  type: Boolean,
41
44
  default: true
42
45
  },
43
- fontSize: {
44
- type: Number,
45
- default: 28
46
- },
47
46
  onBeforeRemove: {
48
47
  type: Function,
49
48
  default: () => {
@@ -55,12 +54,14 @@ export default defineComponent({
55
54
  }
56
55
  },
57
56
  formCreateInject: Object,
57
+ parse: Function,
58
58
  },
59
59
  data() {
60
60
  return {
61
61
  len: 0,
62
62
  cacheRule: {},
63
63
  cacheValue: {},
64
+ sort: [],
64
65
  form: markRaw(this.formCreateInject.form.$form())
65
66
  }
66
67
  },
@@ -106,7 +107,7 @@ export default defineComponent({
106
107
  modelValue: {
107
108
  handler(n) {
108
109
  n = n || [];
109
- let keys = Object.keys(this.cacheRule), total = keys.length, len = total - n.length;
110
+ let keys = Object.keys(this.sort), total = keys.length, len = total - n.length;
110
111
  if (len < 0) {
111
112
  for (let i = len; i < 0; i++) {
112
113
  this.addRule(n.length + i, true);
@@ -141,7 +142,7 @@ export default defineComponent({
141
142
  },
142
143
  formData(key, formData) {
143
144
  const cacheRule = this.cacheRule;
144
- const keys = Object.keys(cacheRule);
145
+ const keys = this.sort;
145
146
  if (keys.filter(k => cacheRule[k].$f).length !== keys.length) {
146
147
  return;
147
148
  }
@@ -174,6 +175,7 @@ export default defineComponent({
174
175
  const defVal = deepCopy(this.defaultValue);
175
176
  extend(options.formData, this.field ? {[this.field]: defVal} : defVal);
176
177
  }
178
+ this.parse && this.parse({rule, options, index: this.sort.length});
177
179
  this.cacheRule[++this.len] = {rule, options};
178
180
  if (emit) {
179
181
  nextTick(() => this.$emit('add', rule, Object.keys(this.cacheRule).length - 1));
@@ -181,7 +183,6 @@ export default defineComponent({
181
183
  },
182
184
  add$f(i, key, $f) {
183
185
  this.cacheRule[key].$f = $f;
184
- this.formData(key, $f.formData());
185
186
  nextTick(() => {
186
187
  if (this.syncDisabled) {
187
188
  $f.disabled(this.disabled);
@@ -197,34 +198,43 @@ export default defineComponent({
197
198
  nextTick(() => this.$emit('remove', index));
198
199
  }
199
200
  },
200
- add() {
201
+ add(i) {
201
202
  if (this.disabled || false === this.onBeforeAdd(this.modelValue)) {
202
203
  return;
203
204
  }
204
- this.modelValue.push(this.field ? null : {});
205
- this.$emit('update:modelValue', this.modelValue);
205
+ const value = [...this.modelValue];
206
+ value.push(this.defaultValue ? deepCopy(this.defaultValue) : (this.field ? null : {}));
207
+ this.input(value);
206
208
  },
207
209
  del(index, key) {
208
210
  if (this.disabled || false === this.onBeforeRemove(this.modelValue, index)) {
209
211
  return;
210
212
  }
211
213
  this.removeRule(key, true);
212
- this.modelValue.splice(index, 1);
213
- this.input(this.modelValue);
214
+ const value = [...this.modelValue];
215
+ value.splice(index, 1);
216
+ this.input(value);
214
217
  },
215
218
  addIcon(key) {
216
- return <ElIcon key={`a${key}`}
217
- style={`font-size:${this.fontSize}px;cursor:${this.disabled ? 'not-allowed;color:#c9cdd4' : 'pointer'};`}
218
- onClick={this.add}>
219
- <IconCirclePlus/>
220
- </ElIcon>
219
+ return <div class="_fc-group-btn _fc-group-plus-minus" onClick={this.add}></div>;
221
220
  },
222
221
  delIcon(index, key) {
223
- return <ElIcon key={`d${key}`} class="el-icon-remove-outline"
224
- style={`font-size:${this.fontSize}px;cursor:${this.disabled ? 'not-allowed;color:#c9cdd4' : 'pointer;color:#606266'};`}
225
- onClick={() => this.del(index, key)}>
226
- <IconRemove/>
227
- </ElIcon>
222
+ return <div class="_fc-group-btn _fc-group-plus-minus _fc-group-minus"
223
+ onClick={() => this.del(index, key)}></div>
224
+ },
225
+ sortUpIcon(index) {
226
+ return <div class="_fc-group-btn _fc-group-arrow _fc-group-up"
227
+ onClick={() => this.changeSort(index, -1)}></div>
228
+ },
229
+ sortDownIcon(index) {
230
+ return <div class="_fc-group-btn _fc-group-arrow _fc-group-down"
231
+ onClick={() => this.changeSort(index, 1)}></div>
232
+ },
233
+ changeSort(index, sort) {
234
+ const a = this.sort[index];
235
+ this.sort[index] = this.sort[index + sort];
236
+ this.sort[index + sort] = a;
237
+ this.formData(0);
228
238
  },
229
239
  makeIcon(total, index, key) {
230
240
  if (this.$slots.button) {
@@ -237,23 +247,34 @@ export default defineComponent({
237
247
  add: this.add
238
248
  });
239
249
  }
240
- if (index === 0) {
241
- return [(this.max !== 0 && total >= this.max) ? null : this.addIcon(key), (this.min === 0 || total > this.min) ? this.delIcon(index, key) : null];
250
+ const btn = [];
251
+ if ((!this.max || total < this.max) && total === index + 1) {
252
+ btn.push(this.addIcon(key));
242
253
  }
243
254
  if (total > this.min) {
244
- return this.delIcon(index, key);
255
+ btn.push(this.delIcon(index, key));
256
+ }
257
+ if (this.sortBtn && index) {
258
+ btn.push(this.sortUpIcon(index));
245
259
  }
260
+ if (this.sortBtn && index !== total - 1) {
261
+ btn.push(this.sortDownIcon(index));
262
+ }
263
+ return btn;
246
264
  },
247
265
  emitEvent(name, args, index, key) {
248
266
  this.$emit(name, ...args, this.cacheRule[key].$f, index);
249
267
  },
250
268
  expandRule(n) {
251
269
  for (let i = 0; i < n; i++) {
252
- this.modelValue.push(this.field ? null : {});
270
+ this.addRule(i);
253
271
  }
254
272
  }
255
273
  },
256
274
  created() {
275
+ watch(() => ({...this.cacheRule}), (n) => {
276
+ this.sort = Object.keys(n);
277
+ }, {immediate: true})
257
278
  const d = (this.expand || 0) - this.modelValue.length;
258
279
  for (let i = 0; i < this.modelValue.length; i++) {
259
280
  this.addRule(i);
@@ -263,32 +284,37 @@ export default defineComponent({
263
284
  }
264
285
  },
265
286
  render() {
266
- const keys = Object.keys(this.cacheRule);
287
+ const keys = this.sort;
267
288
  const button = this.button;
268
289
  const Type = this.form;
269
- return keys.length === 0 ?
290
+ const disabled = this.disabled;
291
+
292
+ const children = keys.length === 0 ?
270
293
  (this.$slots.default ? (this.$slots.default({
271
294
  vm: this,
272
295
  add: this.add
273
- })) : <ElIcon key={1}
274
- style={`font-size:${this.fontSize}px;vertical-align:middle;color:${this.disabled ? '#c9cdd4;cursor: not-allowed' : '#606266;cursor:pointer'};`}
275
- onClick={this.add}>
276
- <IconCirclePlus/>
277
- </ElIcon>) :
278
- <div style="width: 100%;" key={2}>{keys.map((key, index) => {
296
+ })) : <div key={'a_def'} class="_fc-group-plus-minus _fc-group-add"
297
+ onClick={this.add}/>) : keys.map((key, index) => {
279
298
  const {rule, options} = this.cacheRule[key];
280
- return <ElRow align="middle" key={key}
281
- style="border-bottom:1px dashed #DCDFE6;margin-bottom:10px;">
282
- <ElCol span={button ? 20 : 24}><Type
283
- key={key} inFor={true}
284
- onUpdate:modelValue={(formData) => this.formData(key, formData)}
285
- modelValue={this.field ? {[this.field]: this._value(this.modelValue[index])} : this.modelValue[index]}
286
- onEmit-event={(name, ...args) => this.emitEvent(name, args, index, key)}
287
- onUpdate:api={($f) => this.add$f(index, key, $f)}
288
- rule={rule}
289
- option={options} extendOption={true}/></ElCol>
290
- {button ? <ElCol span={2} pull={1} push={1}>{this.makeIcon(keys.length, index, key)}</ElCol> : null}
291
- </ElRow>
292
- })}</div>
299
+ const btn = button && !disabled ? this.makeIcon(keys.length, index, key) : [];
300
+ return <div class="_fc-group-container" key={key}>
301
+ <Type
302
+ key={key}
303
+ {...{
304
+ 'onUpdate:modelValue': (formData) => this.formData(key, formData),
305
+ 'onEmit-event': (name, ...args) => this.emitEvent(name, args, index, key),
306
+ 'onUpdate:api': ($f) => this.add$f(index, key, $f),
307
+ inFor: true,
308
+ modelValue: this.field ? {[this.field]: this._value(this.modelValue[index])} : this.modelValue[index],
309
+ rule,
310
+ option: options,
311
+ extendOption: true
312
+ }}
313
+ />
314
+ <div class="_fc-group-idx">{index + 1}</div>
315
+ {(btn.length) ? <div class="_fc-group-handle">{btn}</div> : null}
316
+ </div>
317
+ });
318
+ return <div key={'con'} class={'_fc-group ' + (disabled ? '_fc-group-disabled' : '')}>{children}</div>
293
319
  }
294
320
  });
package/src/style.css ADDED
@@ -0,0 +1,125 @@
1
+ ._fc-group{
2
+ display: flex;
3
+ min-height: 38px;
4
+ justify-content: center;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ }
8
+
9
+ ._fc-group-disabled ._fc-group-btn, ._fc-group-disabled ._fc-group-add{
10
+ cursor: not-allowed;
11
+ }
12
+
13
+ ._fc-group-handle {
14
+ display: flex;
15
+ flex-direction: row;
16
+ position: absolute;
17
+ bottom: -15px;
18
+ right: 30px;
19
+ border-radius: 15px;
20
+ border: 1px dashed #d9d9d9;
21
+ padding: 3px 8px;
22
+ background-color: #ffffff;
23
+ }
24
+
25
+ ._fc-group-btn{
26
+ cursor: pointer;
27
+ }
28
+
29
+ ._fc-group-idx {
30
+ position: absolute;
31
+ bottom: -15px;
32
+ left: 10px;
33
+ width: 30px;
34
+ height: 30px;
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ background: #eee;
39
+ border-radius: 15px;
40
+ font-weight: 700;
41
+ }
42
+
43
+ ._fc-group-handle ._fc-group-btn + ._fc-group-btn {
44
+ margin-left: 7px;
45
+ }
46
+
47
+ ._fc-group-container{
48
+ position: relative;
49
+ display: flex;
50
+ flex-direction: column;
51
+ border: 1px dashed #d9d9d9;
52
+ padding: 20px;
53
+ margin: 5px;
54
+ border-radius: 5px;
55
+ margin-bottom: 25px;
56
+ padding-bottom: 25px;
57
+ }
58
+
59
+ ._fc-group-arrow {
60
+ position: relative;
61
+ width: 20px;
62
+ height: 20px;
63
+ }
64
+
65
+ ._fc-group-arrow::before {
66
+ content: "";
67
+ position: absolute;
68
+ top: 8px;
69
+ left: 5px;
70
+ width: 9px;
71
+ height: 9px;
72
+ border-left: 2px solid #999;
73
+ border-top: 2px solid #999;
74
+ }
75
+ ._fc-group-arrow::before {
76
+ transform: rotate(45deg);
77
+ }
78
+
79
+ ._fc-group-arrow._fc-group-down {
80
+ transform: rotate(180deg);
81
+ }
82
+
83
+ ._fc-group-plus-minus {
84
+ width: 20px;
85
+ height: 20px;
86
+ position: relative;
87
+ cursor: pointer;
88
+ }
89
+
90
+ ._fc-group-plus-minus::before,
91
+ ._fc-group-plus-minus::after {
92
+ content: "";
93
+ position: absolute;
94
+ top: 50%;
95
+ left: 50%;
96
+ width: 60%;
97
+ height: 2px;
98
+ background-color: #409eff;
99
+ transform: translate(-50%, -50%);
100
+ }
101
+
102
+ ._fc-group-plus-minus::before {
103
+ transform: translate(-50%, -50%) rotate(90deg);
104
+ }
105
+
106
+ ._fc-group-plus-minus._fc-group-minus::before {
107
+ display: none;
108
+ }
109
+ ._fc-group-plus-minus._fc-group-minus::after {
110
+ background-color: #f56c6c;
111
+ }
112
+
113
+
114
+ ._fc-group-add{
115
+ cursor: pointer;
116
+ width: 25px;
117
+ height: 25px;
118
+ border: 1px solid rgb(64 158 255 / 50%);
119
+ border-radius: 15px;
120
+ }
121
+
122
+ ._fc-group-add._fc-group-plus-minus::before, ._fc-group-add._fc-group-plus-minus::after {
123
+ width: 50%;
124
+ }
125
+
@@ -1,14 +0,0 @@
1
- <template>
2
- <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
3
- <path fill="currentColor" d="M352 480h320a32 32 0 110 64H352a32 32 0 010-64z"></path>
4
- <path fill="currentColor" d="M480 672V352a32 32 0 1164 0v320a32 32 0 01-64 0z"></path>
5
- <path fill="currentColor"
6
- d="M512 896a384 384 0 100-768 384 384 0 000 768zm0 64a448 448 0 110-896 448 448 0 010 896z"></path>
7
- </svg>
8
- </template>
9
-
10
- <script>
11
- export default {
12
- name: 'IconCirclePlus'
13
- }
14
- </script>
@@ -1,13 +0,0 @@
1
- <template>
2
- <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
3
- <path fill="currentColor" d="M352 480h320a32 32 0 110 64H352a32 32 0 010-64z"></path>
4
- <path fill="currentColor"
5
- d="M512 896a384 384 0 100-768 384 384 0 000 768zm0 64a448 448 0 110-896 448 448 0 010 896z"></path>
6
- </svg>
7
- </template>
8
-
9
- <script>
10
- export default {
11
- name: 'IconRemove'
12
- }
13
- </script>