@bpmn-io/form-js-viewer 0.5.1 → 0.7.1

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.
@@ -2,45 +2,42 @@
2
2
  * Theming
3
3
  */
4
4
  .fjs-container {
5
- --color-blue-base-65: #4d90ff;
6
- --color-blue-base-65-opacity-10: rgba(77, 144, 255, 0.1);
7
- --color-blue-darken-48: #005df7;
8
- --color-blue-darken-55: #1a70ff;
9
- --color-blue-darken-62: #3c85ff;
10
- --color-blue-lighten-75: #80b0ff;
11
- --color-blue-lighten-82: #a2c5ff;
12
- --color-blue-lighten-93: #dbe9ff;
13
-
14
- --color-silver-base-97: #f8f8f8;
15
- --color-silver-lighten-99: #fcfcfc;
16
- --color-silver-darken-80: #cdcdcd;
17
- --color-silver-darken-87: #dedede;
18
- --color-silver-darken-94: #efefef;
19
-
20
- --color-grey-base-40: #666666;
21
- --color-grey-lighten-56: #909090;
22
- --color-grey-darken-23: #3b3b3b;
23
- --color-grey-darken-30: #4c4c4c;
24
- --color-grey-darken-33: #535353;
25
-
26
- --color-red-base-62: #ff3d3d;
27
- --color-red-darken-38: #C20000;
28
- --color-red-lighten-85: #ffb3b3;
29
-
30
- --color-black: #000000;
31
- --color-white: #ffffff;
5
+ --color-grey-225-10-15: hsl(225, 10%, 15%);
6
+ --color-grey-225-10-35: hsl(225, 10%, 35%);
7
+ --color-grey-225-10-55: hsl(225, 10%, 55%);
8
+ --color-grey-225-10-75: hsl(225, 10%, 75%);
9
+ --color-grey-225-10-80: hsl(225, 10%, 80%);
10
+ --color-grey-225-10-85: hsl(225, 10%, 85%);
11
+ --color-grey-225-10-90: hsl(225, 10%, 90%);
12
+ --color-grey-225-10-95: hsl(225, 10%, 95%);
13
+ --color-grey-225-10-97: hsl(225, 10%, 97%);
14
+
15
+ --color-blue-205-100-45: hsl(205, 100%, 45%);
16
+ --color-blue-205-100-50: hsl(205, 100%, 50%);
17
+ --color-blue-205-100-80: hsl(205, 100%, 80%);
18
+ --color-blue-205-100-95: hsl(205, 100%, 95%);
19
+
20
+ --color-green-150-86-44: hsl(150, 86%, 44%);
21
+
22
+ --color-red-360-100-40: hsl(360, 100%, 40%);
23
+ --color-red-360-100-45: hsl(360, 100%, 45%);
24
+ --color-red-360-100-92: hsl(360, 100%, 92%);
25
+ --color-red-360-100-97: hsl(360, 100%, 97%);
26
+
27
+ --color-white: hsl(0, 0%, 100%);
28
+ --color-black: hsl(0, 0%, 0%);
32
29
 
33
30
  --color-background: var(--color-white);
34
- --color-background-disabled: var(--color-silver-darken-94);
35
- --color-text: var(--color-grey-darken-23);
36
- --color-text-light: var(--color-grey-lighten-56);
37
- --color-text-lighter: var(--color-grey-base-40);
31
+ --color-background-disabled: var(--color-grey-225-10-95);
32
+ --color-text: var(--color-grey-225-10-15);
33
+ --color-text-light: var(--color-grey-225-10-35);
34
+ --color-text-lighter: var(--color-grey-225-10-55);
38
35
  --color-text-inverted: var(--color-white);
39
- --color-borders: var(--color-grey-lighten-56);
40
- --color-borders-disabled: var(--color-silver-darken-80);
41
- --color-warning: var(--color-red-base-62);
42
- --color-accent: var(--color-blue-darken-62);
43
- --color-accent-dark: var(--color-blue-darken-48);
36
+ --color-borders: var(--color-grey-225-10-55);
37
+ --color-borders-disabled: var(--color-grey-225-10-75);
38
+ --color-warning: var(--color-red-360-100-45);
39
+ --color-accent: var(--color-blue-205-100-45);
40
+ --color-accent-dark: var(--color-blue-205-100-45);
44
41
 
45
42
  --font-family: 'IBM Plex Sans', sans-serif;
46
43
 
@@ -108,7 +105,7 @@
108
105
  font-style: italic;
109
106
  letter-spacing: .25px;
110
107
 
111
- color: var(--color-text-light);
108
+ color: var(--color-text-lighter);
112
109
  }
113
110
 
114
111
  .fjs-container .fjs-form-field-label {
@@ -217,6 +214,7 @@
217
214
  }
218
215
 
219
216
  .fjs-container .fjs-form-field.fjs-has-errors .fjs-input,
217
+ .fjs-container .fjs-form-field.fjs-has-errors .fjs-select,
220
218
  .fjs-container .fjs-form-field.fjs-has-errors .fjs-textarea {
221
219
  border-color: var(--color-warning);
222
220
  }
@@ -236,5 +234,5 @@
236
234
  }
237
235
 
238
236
  .fjs-container .fjs-form-field-text a {
239
- color: var(--color-blue-darken-48);
237
+ color: var(--color-blue-205-100-45);
240
238
  }
package/dist/index.cjs CHANGED
@@ -18,109 +18,6 @@ var Ids__default = /*#__PURE__*/_interopDefaultLegacy(Ids);
18
18
  var snarkdown__default = /*#__PURE__*/_interopDefaultLegacy(snarkdown);
19
19
  var Markup__default = /*#__PURE__*/_interopDefaultLegacy(Markup);
20
20
 
21
- function createInjector(bootstrapModules) {
22
- const modules = [],
23
- components = [];
24
-
25
- function hasModule(module) {
26
- return modules.includes(module);
27
- }
28
-
29
- function addModule(module) {
30
- modules.push(module);
31
- }
32
-
33
- function visit(module) {
34
- if (hasModule(module)) {
35
- return;
36
- }
37
-
38
- (module.__depends__ || []).forEach(visit);
39
-
40
- if (hasModule(module)) {
41
- return;
42
- }
43
-
44
- addModule(module);
45
- (module.__init__ || []).forEach(function (component) {
46
- components.push(component);
47
- });
48
- }
49
-
50
- bootstrapModules.forEach(visit);
51
- const injector = new didi.Injector(modules);
52
- components.forEach(function (component) {
53
- try {
54
- injector[typeof component === 'string' ? 'get' : 'invoke'](component);
55
- } catch (err) {
56
- console.error('Failed to instantiate component');
57
- console.error(err.stack);
58
- throw err;
59
- }
60
- });
61
- return injector;
62
- }
63
-
64
- /**
65
- * @param {string?} prefix
66
- *
67
- * @returns Element
68
- */
69
- function createFormContainer(prefix = 'fjs') {
70
- const container = document.createElement('div');
71
- container.classList.add(`${prefix}-container`);
72
- return container;
73
- }
74
-
75
- function findErrors(errors, path) {
76
- return errors[pathStringify(path)];
77
- }
78
- function isRequired(field) {
79
- return field.required;
80
- }
81
- function pathParse(path) {
82
- if (!path) {
83
- return [];
84
- }
85
-
86
- return path.split('.').map(key => {
87
- return isNaN(parseInt(key)) ? key : parseInt(key);
88
- });
89
- }
90
- function pathsEqual(a, b) {
91
- return a && b && a.length === b.length && a.every((value, index) => value === b[index]);
92
- }
93
- function pathStringify(path) {
94
- if (!path) {
95
- return '';
96
- }
97
-
98
- return path.join('.');
99
- }
100
- const indices = {};
101
- function generateIndexForType(type) {
102
- if (type in indices) {
103
- indices[type]++;
104
- } else {
105
- indices[type] = 1;
106
- }
107
-
108
- return indices[type];
109
- }
110
- function generateIdForType(type) {
111
- return `${type}${generateIndexForType(type)}`;
112
- }
113
- /**
114
- * @template T
115
- * @param {T} data
116
- * @param {(this: any, key: string, value: any) => any} [replacer]
117
- * @return {T}
118
- */
119
-
120
- function clone(data, replacer) {
121
- return JSON.parse(JSON.stringify(data, replacer));
122
- }
123
-
124
21
  var FN_REF = '__fn';
125
22
  var DEFAULT_PRIORITY = 1000;
126
23
  var slice = Array.prototype.slice;
@@ -610,7 +507,7 @@ class Validator {
610
507
  errors = [...errors, `Field must match pattern ${validate.pattern}.`];
611
508
  }
612
509
 
613
- if (validate.required && (typeof value === 'undefined' || value === '')) {
510
+ if (validate.required && (minDash.isNil(value) || value === '')) {
614
511
  errors = [...errors, 'Field is required.'];
615
512
  }
616
513
 
@@ -634,6 +531,7 @@ class Validator {
634
531
  }
635
532
 
636
533
  }
534
+ Validator.$inject = [];
637
535
 
638
536
  class FormFieldRegistry {
639
537
  constructor(eventBus) {
@@ -699,6 +597,109 @@ class FormFieldRegistry {
699
597
  }
700
598
  FormFieldRegistry.$inject = ['eventBus'];
701
599
 
600
+ function createInjector(bootstrapModules) {
601
+ const modules = [],
602
+ components = [];
603
+
604
+ function hasModule(module) {
605
+ return modules.includes(module);
606
+ }
607
+
608
+ function addModule(module) {
609
+ modules.push(module);
610
+ }
611
+
612
+ function visit(module) {
613
+ if (hasModule(module)) {
614
+ return;
615
+ }
616
+
617
+ (module.__depends__ || []).forEach(visit);
618
+
619
+ if (hasModule(module)) {
620
+ return;
621
+ }
622
+
623
+ addModule(module);
624
+ (module.__init__ || []).forEach(function (component) {
625
+ components.push(component);
626
+ });
627
+ }
628
+
629
+ bootstrapModules.forEach(visit);
630
+ const injector = new didi.Injector(modules);
631
+ components.forEach(function (component) {
632
+ try {
633
+ injector[typeof component === 'string' ? 'get' : 'invoke'](component);
634
+ } catch (err) {
635
+ console.error('Failed to instantiate component');
636
+ console.error(err.stack);
637
+ throw err;
638
+ }
639
+ });
640
+ return injector;
641
+ }
642
+
643
+ /**
644
+ * @param {string?} prefix
645
+ *
646
+ * @returns Element
647
+ */
648
+ function createFormContainer(prefix = 'fjs') {
649
+ const container = document.createElement('div');
650
+ container.classList.add(`${prefix}-container`);
651
+ return container;
652
+ }
653
+
654
+ function findErrors(errors, path) {
655
+ return errors[pathStringify(path)];
656
+ }
657
+ function isRequired(field) {
658
+ return field.required;
659
+ }
660
+ function pathParse(path) {
661
+ if (!path) {
662
+ return [];
663
+ }
664
+
665
+ return path.split('.').map(key => {
666
+ return isNaN(parseInt(key)) ? key : parseInt(key);
667
+ });
668
+ }
669
+ function pathsEqual(a, b) {
670
+ return a && b && a.length === b.length && a.every((value, index) => value === b[index]);
671
+ }
672
+ function pathStringify(path) {
673
+ if (!path) {
674
+ return '';
675
+ }
676
+
677
+ return path.join('.');
678
+ }
679
+ const indices = {};
680
+ function generateIndexForType(type) {
681
+ if (type in indices) {
682
+ indices[type]++;
683
+ } else {
684
+ indices[type] = 1;
685
+ }
686
+
687
+ return indices[type];
688
+ }
689
+ function generateIdForType(type) {
690
+ return `${type}${generateIndexForType(type)}`;
691
+ }
692
+ /**
693
+ * @template T
694
+ * @param {T} data
695
+ * @param {(this: any, key: string, value: any) => any} [replacer]
696
+ * @return {T}
697
+ */
698
+
699
+ function clone(data, replacer) {
700
+ return JSON.parse(JSON.stringify(data, replacer));
701
+ }
702
+
702
703
  class Importer {
703
704
  /**
704
705
  * @constructor
@@ -726,8 +727,8 @@ class Importer {
726
727
  const warnings = [];
727
728
 
728
729
  try {
729
- const importedData = clone(data);
730
- const importedSchema = this.importFormField(clone(schema), importedData);
730
+ const importedSchema = this.importFormField(clone(schema)),
731
+ importedData = this.importData(clone(data));
731
732
  return {
732
733
  warnings,
733
734
  schema: importedSchema,
@@ -740,14 +741,13 @@ class Importer {
740
741
  }
741
742
  /**
742
743
  * @param {any} formField
743
- * @param {Object} [data]
744
744
  * @param {string} [parentId]
745
745
  *
746
- * @return {any} field
746
+ * @return {any} importedField
747
747
  */
748
748
 
749
749
 
750
- importFormField(formField, data = {}, parentId) {
750
+ importFormField(formField, parentId) {
751
751
  const {
752
752
  components,
753
753
  key,
@@ -770,10 +770,13 @@ class Importer {
770
770
  throw new Error(`form field with key <${key}> already exists`);
771
771
  }
772
772
 
773
- this._formFieldRegistry._keys.claim(key, formField); // set form field path
773
+ this._formFieldRegistry._keys.claim(key, formField); // TODO: buttons should not have key
774
774
 
775
775
 
776
- formField._path = [key];
776
+ if (type !== 'button') {
777
+ // set form field path
778
+ formField._path = [key];
779
+ }
777
780
  }
778
781
 
779
782
  if (id) {
@@ -791,17 +794,44 @@ class Importer {
791
794
  this._formFieldRegistry.add(formField);
792
795
 
793
796
  if (components) {
794
- this.importFormFields(components, data, id);
797
+ this.importFormFields(components, id);
795
798
  }
796
799
 
797
800
  return formField;
798
801
  }
799
802
 
800
- importFormFields(components, data = {}, parentId) {
803
+ importFormFields(components, parentId) {
801
804
  components.forEach(component => {
802
- this.importFormField(component, data, parentId);
805
+ this.importFormField(component, parentId);
803
806
  });
804
807
  }
808
+ /**
809
+ * @param {Object} data
810
+ *
811
+ * @return {Object} importedData
812
+ */
813
+
814
+
815
+ importData(data) {
816
+ return this._formFieldRegistry.getAll().reduce((importedData, formField) => {
817
+ const {
818
+ defaultValue,
819
+ _path,
820
+ type
821
+ } = formField;
822
+
823
+ if (!_path) {
824
+ return importedData;
825
+ } // (1) try to get value from data
826
+ // (2) try to get default value from form field
827
+ // (3) get empty value from form field
828
+
829
+
830
+ return { ...importedData,
831
+ [_path[0]]: minDash.get(data, _path, minDash.isUndefined(defaultValue) ? this._formFields.get(type).emptyValue : defaultValue)
832
+ };
833
+ }, {});
834
+ }
805
835
 
806
836
  }
807
837
  Importer.$inject = ['formFieldRegistry', 'formFields'];
@@ -1125,6 +1155,7 @@ Checkbox.create = function (options = {}) {
1125
1155
  Checkbox.type = type$5;
1126
1156
  Checkbox.label = 'Checkbox';
1127
1157
  Checkbox.keyed = true;
1158
+ Checkbox.emptyValue = false;
1128
1159
 
1129
1160
  function useService (type, strict) {
1130
1161
  const {
@@ -1365,7 +1396,7 @@ function Number(props) {
1365
1396
  const parsedValue = parseInt(target.value, 10);
1366
1397
  props.onChange({
1367
1398
  field,
1368
- value: isNaN(parsedValue) ? undefined : parsedValue
1399
+ value: isNaN(parsedValue) ? null : parsedValue
1369
1400
  });
1370
1401
  };
1371
1402
 
@@ -1401,6 +1432,7 @@ Number.create = function (options = {}) {
1401
1432
  Number.type = type$4;
1402
1433
  Number.keyed = true;
1403
1434
  Number.label = 'Number';
1435
+ Number.emptyValue = null;
1404
1436
 
1405
1437
  const type$3 = 'radio';
1406
1438
  function Radio(props) {
@@ -1449,7 +1481,7 @@ function Radio(props) {
1449
1481
  type: "radio",
1450
1482
  onClick: () => onChange(v.value)
1451
1483
  })
1452
- }, v.value);
1484
+ }, `${id}-${index}`);
1453
1485
  }), jsxRuntime.jsx(Description, {
1454
1486
  description: description
1455
1487
  }), jsxRuntime.jsx(Errors, {
@@ -1471,6 +1503,7 @@ Radio.create = function (options = {}) {
1471
1503
  Radio.type = type$3;
1472
1504
  Radio.label = 'Radio';
1473
1505
  Radio.keyed = true;
1506
+ Radio.emptyValue = null;
1474
1507
 
1475
1508
  const type$2 = 'select';
1476
1509
  function Select(props) {
@@ -1496,7 +1529,7 @@ function Select(props) {
1496
1529
  }) => {
1497
1530
  props.onChange({
1498
1531
  field,
1499
- value: target.value === '' ? undefined : target.value
1532
+ value: target.value === '' ? null : target.value
1500
1533
  });
1501
1534
  };
1502
1535
 
@@ -1517,11 +1550,11 @@ function Select(props) {
1517
1550
  value: value || '',
1518
1551
  children: [jsxRuntime.jsx("option", {
1519
1552
  value: ""
1520
- }), values.map(v => {
1553
+ }), values.map((v, index) => {
1521
1554
  return jsxRuntime.jsx("option", {
1522
1555
  value: v.value,
1523
1556
  children: v.label
1524
- }, v.value);
1557
+ }, `${id}-${index}`);
1525
1558
  })]
1526
1559
  }), jsxRuntime.jsx(Description, {
1527
1560
  description: description
@@ -1544,6 +1577,7 @@ Select.create = function (options = {}) {
1544
1577
  Select.type = type$2;
1545
1578
  Select.label = 'Select';
1546
1579
  Select.keyed = true;
1580
+ Select.emptyValue = null;
1547
1581
 
1548
1582
  const type$1 = 'text';
1549
1583
  function Text(props) {
@@ -1631,6 +1665,7 @@ Textfield.create = function (options = {}) {
1631
1665
  Textfield.type = type;
1632
1666
  Textfield.label = 'Text Field';
1633
1667
  Textfield.keyed = true;
1668
+ Textfield.emptyValue = '';
1634
1669
 
1635
1670
  const formFields = [Button, Checkbox, Default, Number, Radio, Select, Text, Textfield];
1636
1671
 
@@ -1741,6 +1776,10 @@ var core = {
1741
1776
  * properties: FormProperties,
1742
1777
  * schema: Schema
1743
1778
  * } } State
1779
+ *
1780
+ * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
1781
+ * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
1782
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
1744
1783
  */
1745
1784
 
1746
1785
  const ids = new Ids__default['default']([32, 36, 1]);
@@ -1754,10 +1793,16 @@ class Form {
1754
1793
  * @param {FormOptions} options
1755
1794
  */
1756
1795
  constructor(options = {}) {
1796
+ /**
1797
+ * @public
1798
+ * @type {OnEventType}
1799
+ */
1800
+ this.on = this._onEvent;
1757
1801
  /**
1758
1802
  * @public
1759
1803
  * @type {String}
1760
1804
  */
1805
+
1761
1806
  this._id = ids.next();
1762
1807
  /**
1763
1808
  * @private
@@ -1872,21 +1917,22 @@ class Form {
1872
1917
  throw new Error('form is read-only');
1873
1918
  }
1874
1919
 
1875
- const formFieldRegistry = this.get('formFieldRegistry'); // do not submit disabled form fields
1876
-
1920
+ const formFieldRegistry = this.get('formFieldRegistry');
1877
1921
  const data = formFieldRegistry.getAll().reduce((data, field) => {
1878
1922
  const {
1879
1923
  disabled,
1880
1924
  _path
1881
- } = field;
1925
+ } = field; // do not submit disabled form fields
1882
1926
 
1883
- if (disabled) {
1884
- // strip disabled field value
1885
- minDash.set(data, _path, undefined);
1927
+ if (disabled || !_path) {
1928
+ return data;
1886
1929
  }
1887
1930
 
1888
- return data;
1889
- }, clone(this._getState().data));
1931
+ const value = minDash.get(this._getState().data, _path);
1932
+ return { ...data,
1933
+ [_path[0]]: value
1934
+ };
1935
+ }, {});
1890
1936
  const errors = this.validate();
1891
1937
 
1892
1938
  this._emit('submit', {
@@ -2003,16 +2049,6 @@ class Form {
2003
2049
  properties
2004
2050
  });
2005
2051
  }
2006
- /**
2007
- * @param {FormEvent} type
2008
- * @param {number} priority
2009
- * @param {Function} handler
2010
- */
2011
-
2012
-
2013
- on(type, priority, handler) {
2014
- this.get('eventBus').on(type, priority, handler);
2015
- }
2016
2052
  /**
2017
2053
  * @param {FormEvent} type
2018
2054
  * @param {Function} handler
@@ -2107,10 +2143,18 @@ class Form {
2107
2143
 
2108
2144
  this._emit('changed', this._getState());
2109
2145
  }
2146
+ /**
2147
+ * @internal
2148
+ */
2149
+
2150
+
2151
+ _onEvent(type, priority, handler) {
2152
+ this.get('eventBus').on(type, priority, handler);
2153
+ }
2110
2154
 
2111
2155
  }
2112
2156
 
2113
- const schemaVersion = 2;
2157
+ const schemaVersion = 4;
2114
2158
  /**
2115
2159
  * @typedef { import('./types').CreateFormOptions } CreateFormOptions
2116
2160
  */