@twintag/twintag-form 1.6.2-beta.1 → 1.7.0

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.
Files changed (57) hide show
  1. package/.turbo/turbo-build.log +16 -16
  2. package/CHANGELOG.md +241 -221
  3. package/README.md +407 -407
  4. package/dev/index.css +32 -32
  5. package/dev/main.tsx +461 -460
  6. package/dist/common/button.d.ts +0 -1
  7. package/dist/common/form.d.ts +0 -1
  8. package/dist/common/icon.d.ts +0 -1
  9. package/dist/common/input.d.ts +0 -1
  10. package/dist/common/label.d.ts +0 -1
  11. package/dist/common/textarea.d.ts +0 -1
  12. package/dist/components/config.d.ts +0 -1
  13. package/dist/components/containers/accordion.d.ts +1 -2
  14. package/dist/components/containers/category.d.ts +0 -1
  15. package/dist/components/fields/checkbox.d.ts +0 -1
  16. package/dist/components/fields/file.d.ts +0 -1
  17. package/dist/components/fields/input.d.ts +0 -1
  18. package/dist/components/fields/radiogroup.d.ts +0 -1
  19. package/dist/components/fields/submit.d.ts +0 -1
  20. package/dist/components/fields/textarea.d.ts +0 -1
  21. package/dist/components/fields/toggle.d.ts +0 -1
  22. package/dist/components/fields/tri-toggle.d.ts +0 -1
  23. package/dist/components/form.d.ts +0 -1
  24. package/dist/components/input.d.ts +0 -1
  25. package/dist/components/label.d.ts +0 -1
  26. package/dist/components/provider.d.ts +1 -2
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.d.ts +0 -1
  29. package/dist/index.js +1437 -1601
  30. package/dist/types/index.d.ts +0 -1
  31. package/dist/utils/data.d.ts +0 -1
  32. package/dist/utils/style.d.ts +0 -1
  33. package/dist/webcomponent.cjs +1 -1
  34. package/dist/webcomponent.js +1118 -1104
  35. package/lib/common/icon.tsx +2 -1
  36. package/lib/components/config.tsx +1 -0
  37. package/lib/components/containers/accordion.tsx +3 -2
  38. package/lib/components/containers/category.tsx +1 -1
  39. package/lib/components/fields/checkbox.tsx +3 -6
  40. package/lib/components/fields/date-picker.tsx +151 -154
  41. package/lib/components/fields/file.tsx +81 -84
  42. package/lib/components/fields/input.tsx +67 -70
  43. package/lib/components/fields/radiogroup.tsx +3 -6
  44. package/lib/components/fields/submit.tsx +1 -0
  45. package/lib/components/fields/textarea.tsx +69 -72
  46. package/lib/components/fields/toggle.tsx +3 -6
  47. package/lib/components/fields/tri-toggle.tsx +3 -4
  48. package/lib/components/input.tsx +2 -1
  49. package/lib/components/label.tsx +1 -0
  50. package/lib/components/provider.tsx +163 -162
  51. package/lib/components/renderer.tsx +2 -1
  52. package/lib/index.tsx +46 -45
  53. package/lib/types/index.ts +102 -102
  54. package/lib/webcomponent.ts +1 -2
  55. package/package.json +9 -10
  56. package/prettier.config.mjs +1 -17
  57. package/vite.config.ts +2 -1
package/dev/main.tsx CHANGED
@@ -1,460 +1,461 @@
1
- import type { ComponentProps } from 'react';
2
- import type { Form } from '../lib';
3
-
4
- import '../dist/webcomponent';
5
- import './index.css';
6
-
7
- const config = [
8
- {
9
- type: 'label',
10
- props: {
11
- label: 'Custom label',
12
- },
13
- },
14
- {
15
- type: 'category',
16
- props: {
17
- label: 'Category 1st',
18
- },
19
- children: [
20
- {
21
- type: 'input',
22
- props: {
23
- subtype: 'toggle',
24
- label: 'Switch',
25
- bind: 'switch',
26
- options: {
27
- description: 'this field is required',
28
- },
29
- },
30
- },
31
- {
32
- type: 'input',
33
- props: {
34
- subtype: 'tri-toggle',
35
- label: 'Tri-toggle',
36
- bind: 'tri-toggle-bind',
37
- options: {
38
- description: 'this field is never required',
39
- },
40
- },
41
- },
42
- {
43
- type: 'input',
44
- props: {
45
- subtype: 'datepicker',
46
- label: 'Date picker',
47
- bind: 'datepicker',
48
- options: {
49
- description: 'this field is required',
50
- },
51
- },
52
- },
53
- {
54
- type: 'accordion',
55
- props: {
56
- defaultValue: 'required2',
57
- },
58
- children: [
59
- {
60
- type: 'accordion',
61
- props: {
62
- subtype: 'item',
63
- label: 'Required 1',
64
- value: 'required1',
65
- icon: 'archive-box-x-mark',
66
- },
67
- children: [
68
- {
69
- type: 'input',
70
- props: {
71
- subtype: 'toggle',
72
- label: 'Required',
73
- bind: 'required',
74
- options: {
75
- description: 'this field is required',
76
- },
77
- },
78
- },
79
- ],
80
- },
81
- {
82
- type: 'accordion',
83
- props: {
84
- subtype: 'item',
85
- label: 'Required 2',
86
- value: 'required2',
87
- icon: 'archive-box-x-mark',
88
- },
89
- children: [
90
- {
91
- type: 'input',
92
- props: {
93
- subtype: 'toggle',
94
- label: 'Required',
95
- bind: 'required',
96
- options: {
97
- description: 'this field is required',
98
- },
99
- },
100
- },
101
- ],
102
- },
103
- ],
104
- },
105
- ],
106
- },
107
- {
108
- type: 'category',
109
- props: {
110
- label: 'Category 2nd',
111
- },
112
- children: [
113
- {
114
- type: 'input',
115
- props: {
116
- subtype: 'simple',
117
- label: 'Email',
118
- bind: 'email',
119
- options: {
120
- error: 'This field is required',
121
- description: 'This field is required',
122
- },
123
- },
124
- },
125
- {
126
- type: 'input',
127
- props: {
128
- subtype: 'radiogroup',
129
- label: 'Radio Group',
130
- bind: 'radiogroup',
131
- options: {
132
- description: 'This field is required',
133
- error: 'This field is required',
134
- },
135
- },
136
- children: [
137
- {
138
- type: 'item',
139
- props: {
140
- label: 'Checkbox',
141
- bind: 'checkbox',
142
- options: {
143
- description: 'This field is required',
144
- error: 'This field is required',
145
- },
146
- },
147
- },
148
- {
149
- type: 'item',
150
- props: {
151
- label: 'Mote',
152
- bind: 'mote',
153
- options: {
154
- description: 'This field is required',
155
- error: 'This field is required',
156
- },
157
- },
158
- },
159
- ],
160
- },
161
- ],
162
- },
163
- {
164
- type: 'category',
165
- props: {
166
- label: 'Category 3rd',
167
- },
168
- children: [
169
- {
170
- type: 'input',
171
- props: {
172
- subtype: 'file',
173
- label: 'File',
174
- bind: 'file',
175
- options: {
176
- error: 'This field is required',
177
- description: 'This field is required',
178
- accept: 'image/*',
179
- },
180
- },
181
- },
182
- ],
183
- },
184
- {
185
- type: 'category',
186
- props: {
187
- label: 'Category 4th',
188
- },
189
- children: [
190
- {
191
- type: 'input',
192
- props: {
193
- subtype: 'textarea',
194
- label: 'Textarea',
195
- bind: 'textarea',
196
- options: {
197
- description: 'This field is required',
198
- error: 'This field is required',
199
- },
200
- },
201
- },
202
- {
203
- type: 'input',
204
- props: {
205
- subtype: 'checkbox',
206
- label: 'Checkbox',
207
- bind: 'checkbox',
208
- options: {
209
- description: 'This field is required',
210
- error: 'This field is required',
211
- },
212
- },
213
- },
214
- ],
215
- },
216
- {
217
- type: 'input',
218
- props: {
219
- subtype: 'submit',
220
- label: 'Submit',
221
- },
222
- },
223
- ] as React.ComponentProps<typeof Form>['config'];
224
-
225
- const config2 = [
226
- {
227
- type: 'category',
228
- props: {
229
- label: 'Category 1st',
230
- },
231
- children: [
232
- {
233
- type: 'input',
234
- props: {
235
- subtype: 'toggle',
236
- label: 'Switch',
237
- bind: 'switch',
238
- options: {
239
- description: 'this field is required',
240
- },
241
- },
242
- },
243
- {
244
- type: 'accordion',
245
- props: {
246
- defaultValue: 'required2',
247
- },
248
- children: [
249
- {
250
- type: 'accordion',
251
- props: {
252
- subtype: 'item',
253
- label: 'Required 2',
254
- value: 'required2',
255
- icon: 'archive-box-x-mark',
256
- },
257
- children: [
258
- {
259
- type: 'input',
260
- props: {
261
- subtype: 'toggle',
262
- label: 'Required',
263
- bind: 'required',
264
- options: {
265
- description: 'this field is required',
266
- },
267
- },
268
- },
269
- ],
270
- },
271
- ],
272
- },
273
- {
274
- type: 'input',
275
- props: {
276
- subtype: 'tri-toggle',
277
- label: 'Tri-toggle',
278
- bind: 'tri-toggle-bind',
279
- options: {
280
- description: 'this field is never required',
281
- },
282
- },
283
- },
284
- {
285
- type: 'input',
286
- props: {
287
- subtype: 'datepicker',
288
- label: 'Date picker',
289
- bind: 'datepicker',
290
- options: {
291
- description: 'this field is required',
292
- },
293
- },
294
- },
295
- ],
296
- },
297
- {
298
- type: 'category',
299
- props: {
300
- label: 'Category 2nd',
301
- },
302
- children: [
303
- {
304
- type: 'input',
305
- props: {
306
- subtype: 'simple',
307
- label: 'Email',
308
- bind: 'email',
309
- options: {
310
- error: 'This field is required',
311
- description: 'This field is required',
312
- },
313
- },
314
- },
315
- {
316
- type: 'input',
317
- props: {
318
- subtype: 'radiogroup',
319
- label: 'Radio Group',
320
- bind: 'radiogroup',
321
- options: {
322
- description: 'This field is required',
323
- error: 'This field is required',
324
- },
325
- },
326
- children: [
327
- {
328
- type: 'item',
329
- props: {
330
- label: 'Checkbox',
331
- bind: 'checkbox',
332
- options: {
333
- description: 'This field is required',
334
- error: 'This field is required',
335
- },
336
- },
337
- },
338
- {
339
- type: 'item',
340
- props: {
341
- label: 'Mote',
342
- bind: 'mote',
343
- options: {
344
- description: 'This field is required',
345
- error: 'This field is required',
346
- },
347
- },
348
- },
349
- ],
350
- },
351
- ],
352
- },
353
- {
354
- type: 'category',
355
- props: {
356
- label: 'Category 3rd',
357
- },
358
- children: [
359
- {
360
- type: 'input',
361
- props: {
362
- subtype: 'file',
363
- label: 'File',
364
- bind: 'file',
365
- options: {
366
- error: 'This field is required',
367
- description: 'This field is required',
368
- },
369
- },
370
- },
371
- ],
372
- },
373
- {
374
- type: 'category',
375
- props: {
376
- label: 'Category 4th',
377
- },
378
- children: [
379
- {
380
- type: 'input',
381
- props: {
382
- subtype: 'textarea',
383
- label: 'Textarea',
384
- bind: 'textarea',
385
- options: {
386
- description: 'This field is required',
387
- error: 'This field is required',
388
- },
389
- },
390
- },
391
- {
392
- type: 'input',
393
- props: {
394
- subtype: 'checkbox',
395
- label: 'Checkbox',
396
- bind: 'checkbox',
397
- options: {
398
- description: 'This field is required',
399
- error: 'This field is required',
400
- },
401
- },
402
- },
403
- ],
404
- },
405
- {
406
- type: 'input',
407
- props: {
408
- subtype: 'submit',
409
- label: 'Submit',
410
- },
411
- },
412
- ] as React.ComponentProps<typeof Form>['config'];
413
-
414
- const options = {
415
- defaultValues: {
416
- 'tri-toggle-bind': null,
417
- required: true,
418
- email: 'This should work',
419
- radiogroup: 'mote',
420
- checkbox: true,
421
- textarea: 'This is a textarea',
422
- },
423
- variant: 'outline',
424
- resetOnSubmit: true,
425
- } as ComponentProps<typeof Form>['options'];
426
-
427
- // the key properties for the defaultValues object are the same as the bind properties
428
- const form = document.querySelector('twintag-form');
429
-
430
- form?.setAttribute('config', JSON.stringify(config));
431
- form?.setAttribute('options', JSON.stringify(options));
432
-
433
- form?.addEventListener('twintag-form-values', (event) => {
434
- console.log('form values', (event as CustomEvent).detail);
435
- });
436
- form?.addEventListener('twintag-form-valid', (e) => {
437
- console.log('form valid', (e as CustomEvent).detail);
438
- });
439
- form?.addEventListener('twintag-form-invalid', (e) => {
440
- console.log('form invalid', (e as CustomEvent).detail);
441
- });
442
-
443
- const getValues = document.getElementById('get-values');
444
- getValues?.addEventListener('click', () => {
445
- form?.shadowRoot
446
- ?.querySelector('form')
447
- ?.dispatchEvent(new CustomEvent('twintag-form-get_values'));
448
- });
449
-
450
- const submit = document.getElementById('submit');
451
- submit?.addEventListener('click', () => {
452
- form?.shadowRoot
453
- ?.querySelector('form')
454
- ?.dispatchEvent(new CustomEvent('twintag-form-validate'));
455
- });
456
-
457
- const setConfig = document.getElementById('set-config');
458
- setConfig?.addEventListener('click', () => {
459
- form?.setAttribute('config', JSON.stringify(config2));
460
- });
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import type { Form } from '../lib';
4
+
5
+ import '../lib/webcomponent';
6
+ import './index.css';
7
+
8
+ const config = [
9
+ {
10
+ type: 'label',
11
+ props: {
12
+ label: 'Custom label',
13
+ },
14
+ },
15
+ {
16
+ type: 'category',
17
+ props: {
18
+ label: 'Category 1st',
19
+ },
20
+ children: [
21
+ {
22
+ type: 'input',
23
+ props: {
24
+ subtype: 'toggle',
25
+ label: 'Switch',
26
+ bind: 'switch',
27
+ options: {
28
+ description: 'this field is required',
29
+ },
30
+ },
31
+ },
32
+ {
33
+ type: 'input',
34
+ props: {
35
+ subtype: 'tri-toggle',
36
+ label: 'Tri-toggle',
37
+ bind: 'tri-toggle-bind',
38
+ options: {
39
+ description: 'this field is never required',
40
+ },
41
+ },
42
+ },
43
+ {
44
+ type: 'input',
45
+ props: {
46
+ subtype: 'datepicker',
47
+ label: 'Date picker',
48
+ bind: 'datepicker',
49
+ options: {
50
+ description: 'this field is required',
51
+ },
52
+ },
53
+ },
54
+ {
55
+ type: 'accordion',
56
+ props: {
57
+ defaultValue: 'required2',
58
+ },
59
+ children: [
60
+ {
61
+ type: 'accordion',
62
+ props: {
63
+ subtype: 'item',
64
+ label: 'Required 1',
65
+ value: 'required1',
66
+ icon: 'archive-box-x-mark',
67
+ },
68
+ children: [
69
+ {
70
+ type: 'input',
71
+ props: {
72
+ subtype: 'toggle',
73
+ label: 'Required',
74
+ bind: 'required',
75
+ options: {
76
+ description: 'this field is required',
77
+ },
78
+ },
79
+ },
80
+ ],
81
+ },
82
+ {
83
+ type: 'accordion',
84
+ props: {
85
+ subtype: 'item',
86
+ label: 'Required 2',
87
+ value: 'required2',
88
+ icon: 'archive-box-x-mark',
89
+ },
90
+ children: [
91
+ {
92
+ type: 'input',
93
+ props: {
94
+ subtype: 'toggle',
95
+ label: 'Required',
96
+ bind: 'required',
97
+ options: {
98
+ description: 'this field is required',
99
+ },
100
+ },
101
+ },
102
+ ],
103
+ },
104
+ ],
105
+ },
106
+ ],
107
+ },
108
+ {
109
+ type: 'category',
110
+ props: {
111
+ label: 'Category 2nd',
112
+ },
113
+ children: [
114
+ {
115
+ type: 'input',
116
+ props: {
117
+ subtype: 'simple',
118
+ label: 'Email',
119
+ bind: 'email',
120
+ options: {
121
+ error: 'This field is required',
122
+ description: 'This field is required',
123
+ },
124
+ },
125
+ },
126
+ {
127
+ type: 'input',
128
+ props: {
129
+ subtype: 'radiogroup',
130
+ label: 'Radio Group',
131
+ bind: 'radiogroup',
132
+ options: {
133
+ description: 'This field is required',
134
+ error: 'This field is required',
135
+ },
136
+ },
137
+ children: [
138
+ {
139
+ type: 'item',
140
+ props: {
141
+ label: 'Checkbox',
142
+ bind: 'checkbox',
143
+ options: {
144
+ description: 'This field is required',
145
+ error: 'This field is required',
146
+ },
147
+ },
148
+ },
149
+ {
150
+ type: 'item',
151
+ props: {
152
+ label: 'Mote',
153
+ bind: 'mote',
154
+ options: {
155
+ description: 'This field is required',
156
+ error: 'This field is required',
157
+ },
158
+ },
159
+ },
160
+ ],
161
+ },
162
+ ],
163
+ },
164
+ {
165
+ type: 'category',
166
+ props: {
167
+ label: 'Category 3rd',
168
+ },
169
+ children: [
170
+ {
171
+ type: 'input',
172
+ props: {
173
+ subtype: 'file',
174
+ label: 'File',
175
+ bind: 'file',
176
+ options: {
177
+ error: 'This field is required',
178
+ description: 'This field is required',
179
+ accept: 'image/*',
180
+ },
181
+ },
182
+ },
183
+ ],
184
+ },
185
+ {
186
+ type: 'category',
187
+ props: {
188
+ label: 'Category 4th',
189
+ },
190
+ children: [
191
+ {
192
+ type: 'input',
193
+ props: {
194
+ subtype: 'textarea',
195
+ label: 'Textarea',
196
+ bind: 'textarea',
197
+ options: {
198
+ description: 'This field is required',
199
+ error: 'This field is required',
200
+ },
201
+ },
202
+ },
203
+ {
204
+ type: 'input',
205
+ props: {
206
+ subtype: 'checkbox',
207
+ label: 'Checkbox',
208
+ bind: 'checkbox',
209
+ options: {
210
+ description: 'This field is required',
211
+ error: 'This field is required',
212
+ },
213
+ },
214
+ },
215
+ ],
216
+ },
217
+ {
218
+ type: 'input',
219
+ props: {
220
+ subtype: 'submit',
221
+ label: 'Submit',
222
+ },
223
+ },
224
+ ] as React.ComponentProps<typeof Form>['config'];
225
+
226
+ const config2 = [
227
+ {
228
+ type: 'category',
229
+ props: {
230
+ label: 'Category 1st',
231
+ },
232
+ children: [
233
+ {
234
+ type: 'input',
235
+ props: {
236
+ subtype: 'toggle',
237
+ label: 'Switch',
238
+ bind: 'switch',
239
+ options: {
240
+ description: 'this field is required',
241
+ },
242
+ },
243
+ },
244
+ {
245
+ type: 'accordion',
246
+ props: {
247
+ defaultValue: 'required2',
248
+ },
249
+ children: [
250
+ {
251
+ type: 'accordion',
252
+ props: {
253
+ subtype: 'item',
254
+ label: 'Required 2',
255
+ value: 'required2',
256
+ icon: 'archive-box-x-mark',
257
+ },
258
+ children: [
259
+ {
260
+ type: 'input',
261
+ props: {
262
+ subtype: 'toggle',
263
+ label: 'Required',
264
+ bind: 'required',
265
+ options: {
266
+ description: 'this field is required',
267
+ },
268
+ },
269
+ },
270
+ ],
271
+ },
272
+ ],
273
+ },
274
+ {
275
+ type: 'input',
276
+ props: {
277
+ subtype: 'tri-toggle',
278
+ label: 'Tri-toggle',
279
+ bind: 'tri-toggle-bind',
280
+ options: {
281
+ description: 'this field is never required',
282
+ },
283
+ },
284
+ },
285
+ {
286
+ type: 'input',
287
+ props: {
288
+ subtype: 'datepicker',
289
+ label: 'Date picker',
290
+ bind: 'datepicker',
291
+ options: {
292
+ description: 'this field is required',
293
+ },
294
+ },
295
+ },
296
+ ],
297
+ },
298
+ {
299
+ type: 'category',
300
+ props: {
301
+ label: 'Category 2nd',
302
+ },
303
+ children: [
304
+ {
305
+ type: 'input',
306
+ props: {
307
+ subtype: 'simple',
308
+ label: 'Email',
309
+ bind: 'email',
310
+ options: {
311
+ error: 'This field is required',
312
+ description: 'This field is required',
313
+ },
314
+ },
315
+ },
316
+ {
317
+ type: 'input',
318
+ props: {
319
+ subtype: 'radiogroup',
320
+ label: 'Radio Group',
321
+ bind: 'radiogroup',
322
+ options: {
323
+ description: 'This field is required',
324
+ error: 'This field is required',
325
+ },
326
+ },
327
+ children: [
328
+ {
329
+ type: 'item',
330
+ props: {
331
+ label: 'Checkbox',
332
+ bind: 'checkbox',
333
+ options: {
334
+ description: 'This field is required',
335
+ error: 'This field is required',
336
+ },
337
+ },
338
+ },
339
+ {
340
+ type: 'item',
341
+ props: {
342
+ label: 'Mote',
343
+ bind: 'mote',
344
+ options: {
345
+ description: 'This field is required',
346
+ error: 'This field is required',
347
+ },
348
+ },
349
+ },
350
+ ],
351
+ },
352
+ ],
353
+ },
354
+ {
355
+ type: 'category',
356
+ props: {
357
+ label: 'Category 3rd',
358
+ },
359
+ children: [
360
+ {
361
+ type: 'input',
362
+ props: {
363
+ subtype: 'file',
364
+ label: 'File',
365
+ bind: 'file',
366
+ options: {
367
+ error: 'This field is required',
368
+ description: 'This field is required',
369
+ },
370
+ },
371
+ },
372
+ ],
373
+ },
374
+ {
375
+ type: 'category',
376
+ props: {
377
+ label: 'Category 4th',
378
+ },
379
+ children: [
380
+ {
381
+ type: 'input',
382
+ props: {
383
+ subtype: 'textarea',
384
+ label: 'Textarea',
385
+ bind: 'textarea',
386
+ options: {
387
+ description: 'This field is required',
388
+ error: 'This field is required',
389
+ },
390
+ },
391
+ },
392
+ {
393
+ type: 'input',
394
+ props: {
395
+ subtype: 'checkbox',
396
+ label: 'Checkbox',
397
+ bind: 'checkbox',
398
+ options: {
399
+ description: 'This field is required',
400
+ error: 'This field is required',
401
+ },
402
+ },
403
+ },
404
+ ],
405
+ },
406
+ {
407
+ type: 'input',
408
+ props: {
409
+ subtype: 'submit',
410
+ label: 'Submit',
411
+ },
412
+ },
413
+ ] as React.ComponentProps<typeof Form>['config'];
414
+
415
+ const options = {
416
+ defaultValues: {
417
+ 'tri-toggle-bind': null,
418
+ required: true,
419
+ email: 'This should work',
420
+ radiogroup: 'mote',
421
+ checkbox: true,
422
+ textarea: 'This is a textarea',
423
+ },
424
+ variant: 'outline',
425
+ resetOnSubmit: true,
426
+ } as ComponentProps<typeof Form>['options'];
427
+
428
+ // the key properties for the defaultValues object are the same as the bind properties
429
+ const form = document.querySelector('twintag-form');
430
+
431
+ form?.setAttribute('config', JSON.stringify(config));
432
+ form?.setAttribute('options', JSON.stringify(options));
433
+
434
+ form?.addEventListener('twintag-form-values', (event) => {
435
+ console.log('form values', (event as CustomEvent).detail);
436
+ });
437
+ form?.addEventListener('twintag-form-valid', (e) => {
438
+ console.log('form valid', (e as CustomEvent).detail);
439
+ });
440
+ form?.addEventListener('twintag-form-invalid', (e) => {
441
+ console.log('form invalid', (e as CustomEvent).detail);
442
+ });
443
+
444
+ const getValues = document.getElementById('get-values');
445
+ getValues?.addEventListener('click', () => {
446
+ form?.shadowRoot
447
+ ?.querySelector('form')
448
+ ?.dispatchEvent(new CustomEvent('twintag-form-get_values'));
449
+ });
450
+
451
+ const submit = document.getElementById('submit');
452
+ submit?.addEventListener('click', () => {
453
+ form?.shadowRoot
454
+ ?.querySelector('form')
455
+ ?.dispatchEvent(new CustomEvent('twintag-form-validate'));
456
+ });
457
+
458
+ const setConfig = document.getElementById('set-config');
459
+ setConfig?.addEventListener('click', () => {
460
+ form?.setAttribute('config', JSON.stringify(config2));
461
+ });