native-document 1.0.70 → 1.0.72

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 (117) hide show
  1. package/components.js +2 -0
  2. package/dist/native-document.components.min.js +5636 -0
  3. package/dist/native-document.dev.js +380 -321
  4. package/dist/native-document.dev.js.map +1 -1
  5. package/dist/native-document.devtools.min.js +1 -1
  6. package/dist/native-document.min.js +1 -1
  7. package/elements.js +3 -3
  8. package/index.js +17 -17
  9. package/package.json +1 -1
  10. package/rollup.config.js +17 -1
  11. package/src/components/fom-control/FormControl.js +247 -0
  12. package/src/components/fom-control/default/DefaultLayout.js +8 -0
  13. package/src/components/fom-control/default/collection/DefaultCollectionLayout.js +12 -0
  14. package/src/components/fom-control/default/collection/DefaultCollectionTemplate.js +6 -0
  15. package/src/components/fom-control/field/DefaultRender.js +91 -0
  16. package/src/components/fom-control/field/Field.js +396 -0
  17. package/src/components/fom-control/field/FieldCollection.js +260 -0
  18. package/src/components/fom-control/field/FieldFactory.js +107 -0
  19. package/src/components/fom-control/field/types/AutocompleteField.js +46 -0
  20. package/src/components/fom-control/field/types/CheckboxField.js +17 -0
  21. package/src/components/fom-control/field/types/CheckboxGroupField.js +78 -0
  22. package/src/components/fom-control/field/types/ColorField.js +39 -0
  23. package/src/components/fom-control/field/types/DateField.js +62 -0
  24. package/src/components/fom-control/field/types/EmailField.js +44 -0
  25. package/src/components/fom-control/field/types/FileField.js +66 -0
  26. package/src/components/fom-control/field/types/HiddenField.js +8 -0
  27. package/src/components/fom-control/field/types/ImageField.js +49 -0
  28. package/src/components/fom-control/field/types/NumberField.js +74 -0
  29. package/src/components/fom-control/field/types/PasswordField.js +72 -0
  30. package/src/components/fom-control/field/types/RadioField.js +44 -0
  31. package/src/components/fom-control/field/types/RangeField.js +17 -0
  32. package/src/components/fom-control/field/types/SearchField.js +17 -0
  33. package/src/components/fom-control/field/types/SelectField.js +41 -0
  34. package/src/components/fom-control/field/types/StringField.js +49 -0
  35. package/src/components/fom-control/field/types/TelField.js +38 -0
  36. package/src/components/fom-control/field/types/TextAreaField.js +56 -0
  37. package/src/components/fom-control/field/types/TimeField.js +45 -0
  38. package/src/components/fom-control/field/types/UrlField.js +53 -0
  39. package/src/components/fom-control/index.js +8 -0
  40. package/src/components/fom-control/merge +0 -0
  41. package/src/components/fom-control/utils.js +17 -0
  42. package/src/components/fom-control/validation/Validation.js +556 -0
  43. package/src/components/table/Column.js +106 -0
  44. package/src/components/table/ColumnGroup.js +54 -0
  45. package/src/components/table/DataTable.js +195 -0
  46. package/src/components/table/SimpleTable.js +184 -0
  47. package/src/components/table/index.js +9 -0
  48. package/src/{data → core/data}/ObservableArray.js +1 -0
  49. package/src/{data → core/data}/ObservableItem.js +49 -3
  50. package/src/{data → core/data}/observable-helpers/computed.js +2 -1
  51. package/src/{elements → core/elements}/anchor.js +32 -32
  52. package/src/{elements → core/elements}/control/for-each-array.js +4 -2
  53. package/src/core/utils/EventEmitter.js +46 -0
  54. package/src/{utils → core/utils}/helpers.js +12 -0
  55. package/src/{utils → core/utils}/validator.js +7 -0
  56. package/src/{wrappers → core/wrappers}/ElementCreator.js +10 -33
  57. package/src/{wrappers → core/wrappers}/NDElement.js +0 -127
  58. package/src/core/wrappers/NdPrototype.js +147 -0
  59. package/src/core/wrappers/TemplateBinding.js +7 -0
  60. package/src/{wrappers → core/wrappers}/TemplateCloner.js +5 -6
  61. package/src/core/wrappers/prototype-extensions.js +56 -0
  62. package/src/devtools/hrm/ComponentRegistry.js +1 -1
  63. package/src/router/Route.js +1 -1
  64. package/src/router/RouteGroupHelper.js +1 -1
  65. package/src/router/Router.js +4 -4
  66. package/src/router/RouterComponent.js +13 -2
  67. package/src/router/link.js +2 -2
  68. package/src/router/modes/HistoryRouter.js +2 -2
  69. package/types/forms.d.ts +2 -1
  70. package/types/validator.ts +2 -1
  71. package/utils.js +3 -3
  72. package/src/wrappers/NdPrototype.js +0 -71
  73. /package/src/{data → core/data}/MemoryManager.js +0 -0
  74. /package/src/{data → core/data}/Observable.js +0 -0
  75. /package/src/{data → core/data}/ObservableChecker.js +0 -0
  76. /package/src/{data → core/data}/ObservableWhen.js +0 -0
  77. /package/src/{data → core/data}/Store.js +0 -0
  78. /package/src/{data → core/data}/observable-helpers/array.js +0 -0
  79. /package/src/{data → core/data}/observable-helpers/batch.js +0 -0
  80. /package/src/{data → core/data}/observable-helpers/object.js +0 -0
  81. /package/src/{elements → core/elements}/content-formatter.js +0 -0
  82. /package/src/{elements → core/elements}/control/for-each.js +0 -0
  83. /package/src/{elements → core/elements}/control/show-if.js +0 -0
  84. /package/src/{elements → core/elements}/control/show-when.js +0 -0
  85. /package/src/{elements → core/elements}/control/switch.js +0 -0
  86. /package/src/{elements → core/elements}/description-list.js +0 -0
  87. /package/src/{elements → core/elements}/form.js +0 -0
  88. /package/src/{elements → core/elements}/html5-semantics.js +0 -0
  89. /package/src/{elements → core/elements}/img.js +0 -0
  90. /package/src/{elements → core/elements}/index.js +0 -0
  91. /package/src/{elements → core/elements}/interactive.js +0 -0
  92. /package/src/{elements → core/elements}/list.js +0 -0
  93. /package/src/{elements → core/elements}/medias.js +0 -0
  94. /package/src/{elements → core/elements}/meta-data.js +0 -0
  95. /package/src/{elements → core/elements}/table.js +0 -0
  96. /package/src/{errors → core/errors}/ArgTypesError.js +0 -0
  97. /package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  98. /package/src/{errors → core/errors}/RouterError.js +0 -0
  99. /package/src/{utils → core/utils}/args-types.js +0 -0
  100. /package/src/{utils → core/utils}/debug-manager.js +0 -0
  101. /package/src/{utils → core/utils}/events.js +0 -0
  102. /package/src/{utils → core/utils}/filters/date.js +0 -0
  103. /package/src/{utils → core/utils}/filters/index.js +0 -0
  104. /package/src/{utils → core/utils}/filters/standard.js +0 -0
  105. /package/src/{utils → core/utils}/filters/strings.js +0 -0
  106. /package/src/{utils → core/utils}/filters/utils.js +0 -0
  107. /package/src/{utils → core/utils}/memoize.js +0 -0
  108. /package/src/{utils → core/utils}/plugins-manager.js +0 -0
  109. /package/src/{utils → core/utils}/property-accumulator.js +0 -0
  110. /package/src/{utils → core/utils}/prototypes.js +0 -0
  111. /package/src/{utils → core/utils}/service.js +0 -0
  112. /package/src/{wrappers → core/wrappers}/AttributesWrapper.js +0 -0
  113. /package/src/{wrappers → core/wrappers}/DocumentObserver.js +0 -0
  114. /package/src/{wrappers → core/wrappers}/HtmlElementWrapper.js +0 -0
  115. /package/src/{wrappers → core/wrappers}/SingletonView.js +0 -0
  116. /package/src/{wrappers → core/wrappers}/constants.js +0 -0
  117. /package/src/{utils/fetch → fetch}/NativeFetch.js +0 -0
@@ -0,0 +1,247 @@
1
+ import {debounce} from "../../core/utils/helpers";
2
+ import EventEmitter from "../../core/utils/EventEmitter";
3
+ import {Validator, Observable as $ } from "../../../index";
4
+ import NativeDocumentError from "../../core/errors/NativeDocumentError";
5
+ import DefaultLayout from "./default/DefaultLayout";
6
+
7
+ /**
8
+ * @param { {data: Observable } } configs
9
+ * @constructor
10
+ */
11
+ export default function FormControl(configs) {
12
+ EventEmitter.call(this);
13
+
14
+ this.$element = null;
15
+ this.$configs = configs;
16
+ this.$fields = new Map();
17
+ this.$submitting = $(false);
18
+ this.$errors = $(null);
19
+ this.$isDirty = $(false);
20
+ this.$isValid = $(false);
21
+ }
22
+
23
+ FormControl.create = function (configs) {
24
+ return new FormControl(configs);
25
+ };
26
+
27
+ FormControl.prototype = Object.create(EventEmitter.prototype);
28
+ FormControl.prototype.constructor = FormControl;
29
+
30
+ Object.defineProperty(FormControl.prototype, 'isDirty', {
31
+ get() { return this.$isDirty; }
32
+ });
33
+
34
+ Object.defineProperty(FormControl.prototype, 'isValid', {
35
+ get() { return this.$isValid; }
36
+ });
37
+
38
+ Object.defineProperty(FormControl.prototype, 'submitting', {
39
+ get() { return this.$submitting; }
40
+ });
41
+
42
+ FormControl.prototype.layout = function(layoutCallback) {
43
+ if (typeof layoutCallback !== 'function') {
44
+ throw new Error('Layout must be a function');
45
+ }
46
+
47
+ this.$layout = layoutCallback;
48
+ return this;
49
+ };
50
+
51
+ FormControl.prototype.field = function(field) {
52
+ const name = field.$description.name;
53
+ this.$fields.set(name, field);
54
+
55
+ const dataSource = this.$configs?.data?.[name];
56
+ if(dataSource) {
57
+ if(typeof field.checked === 'function') {
58
+ field.checked(dataSource)
59
+ }
60
+ else field.value(dataSource);
61
+ }
62
+
63
+ const value = field.$description.value || field.$description.checked;
64
+
65
+ if(Validator.isObservable(value)) {
66
+ value.subscribe(() => {
67
+ this.$isDirty.set(true);
68
+ this.emit('change', name, value, field);
69
+ });
70
+ }
71
+ return this;
72
+ };
73
+
74
+ FormControl.prototype.get = function(fieldName) {
75
+ const field = this.$fields.get(fieldName);
76
+ if (!field) {
77
+ throw new Error(`Field "${fieldName}" not found in form`);
78
+ }
79
+ return field;
80
+ };
81
+
82
+
83
+ FormControl.prototype.reset = function() {
84
+ this.$isDirty.set(false);
85
+ this.$isValid.set(true);
86
+
87
+ this.$configs?.data?.reset();
88
+
89
+ this.emit('reset');
90
+ return this;
91
+ };
92
+
93
+ FormControl.prototype.submit = function() {
94
+ this.$element?.submit();
95
+ return this;
96
+ };
97
+
98
+ FormControl.prototype.$handleSubmit = async function(event) {
99
+ this.emit('beforeSubmit', event, this);
100
+
101
+ const values = this.values();
102
+ const isValid = await this.validate(values);
103
+ if (!isValid) {
104
+ event.preventDefault();
105
+ this.emit('validationError', this.$errors.val(), this);
106
+ return;
107
+ }
108
+
109
+ this.$submitting.set(true);
110
+
111
+ try {
112
+ const result = await this.emit('submit', event, values);
113
+
114
+ this.emit('success', result, values, this);
115
+
116
+ return result;
117
+
118
+ } catch (error) {
119
+ this.emit('error', error, this);
120
+ if(!this.hasListeners('error')) {
121
+ throw error;
122
+ }
123
+ } finally {
124
+ this.$submitting.set(false);
125
+ this.emit('afterSubmit', this);
126
+ }
127
+ };
128
+
129
+ FormControl.prototype.disable = function() {
130
+ for (const [_, field] of this.$fields) {
131
+ field.disabled?.(true);
132
+ }
133
+ this.emit('disable');
134
+ return this;
135
+ };
136
+
137
+ FormControl.prototype.enable = function() {
138
+ for (const [_, field] of this.$fields) {
139
+ field.disabled?.(false);
140
+ }
141
+ this.emit('enable');
142
+ return this;
143
+ };
144
+
145
+ FormControl.prototype.values = function() {
146
+ const values = {};
147
+ for(const [_, field] of this.$fields) {
148
+ values[field.$description.name] = field.getValue();
149
+ }
150
+ return values;
151
+ };
152
+
153
+ FormControl.prototype.validate = async function(allValues) {
154
+ const errors = {};
155
+ const values = allValues || this.values();
156
+
157
+ for (const [name, field] of this.$fields) {
158
+ const fieldErrors = await field.validate(values);
159
+
160
+ if (fieldErrors && fieldErrors.length > 0) {
161
+ errors[name] = fieldErrors;
162
+ }
163
+ }
164
+
165
+ const hasError = Object.keys(errors).length > 0;
166
+
167
+ this.$errors.set(hasError ? errors : null);
168
+
169
+ this.$isValid.set(!hasError);
170
+
171
+ this.emit('validate', !hasError, errors);
172
+
173
+ return Object.keys(errors).length === 0;
174
+ };
175
+
176
+ FormControl.prototype.onSubmit = function(callback) {
177
+ this.on('submit', callback);
178
+ return this;
179
+ };
180
+
181
+ FormControl.prototype.onPreventSubmit = function(callback) {
182
+ this.on('submit', function(event) {
183
+ event.preventDefault();
184
+ return callback.apply(this, arguments);
185
+ });
186
+ return this;
187
+ };
188
+
189
+ FormControl.prototype.onDebouncedSubmit = function(callback, delay = 300) {
190
+ return this.onSubmit(debounce(callback.bind(this), delay));
191
+ };
192
+
193
+ FormControl.prototype.onSuccess = function (callback) {
194
+ this.on('success', callback);
195
+ return this;
196
+ };
197
+
198
+ FormControl.prototype.onError = function (callback) {
199
+ this.on('error', callback);
200
+ return this;
201
+ };
202
+
203
+ FormControl.prototype.onChange = function(callback) {
204
+ this.on('change', callback);
205
+ return this;
206
+ };
207
+
208
+ FormControl.prototype.onReset = function(callback) {
209
+ this.on('reset', callback);
210
+ return this;
211
+ };
212
+ FormControl.prototype.onBeforeSubmit = function(callback) {
213
+ this.on('beforeSubmit', callback);
214
+ return this;
215
+ };
216
+ FormControl.prototype.onAfterSubmit = function(callback) {
217
+ this.on('afterSubmit', callback);
218
+ return this;
219
+ };
220
+ FormControl.prototype.onValidationError = function(callback) {
221
+ this.on('validationError', callback);
222
+ return this;
223
+ };
224
+
225
+
226
+ FormControl.prototype.toNdElement = function() {
227
+ const fieldsObject = {};
228
+ for (const [name, field] of this.$fields) {
229
+ fieldsObject[name] = field;
230
+ }
231
+
232
+ const layoutFn = this.$layout || DefaultLayout;
233
+
234
+ const form = layoutFn({
235
+ fields: fieldsObject,
236
+ form: this
237
+ });
238
+ if(!((form instanceof HTMLFormElement) || form?.$element instanceof HTMLFormElement)) {
239
+ throw new NativeDocumentError('Layout must return an HtmlFormElement');
240
+ }
241
+ const self = this;
242
+ form.nd.onSubmit(async function(event) {
243
+ return await self.$handleSubmit(event);
244
+ });
245
+ this.$element = form;
246
+ return this.$element;
247
+ };
@@ -0,0 +1,8 @@
1
+ import {Button, Form} from "../../../../elements";
2
+
3
+ export default function DefaultLayout({ fields, form }) {
4
+ return Form([
5
+ Object.values(fields),
6
+ Button({ type: 'submit', disabled: form.submitting }, 'Submit')
7
+ ]);
8
+ }
@@ -0,0 +1,12 @@
1
+ import {Button} from "../../../../../elements";
2
+
3
+ export default function DefaultCollectionLayout({collection, data, Template}) {
4
+
5
+ return Div({ class: 'field-collection-layout'}, [
6
+ Div({ class: 'field-collection-layout-header'}, [
7
+ Button({ class: 'field-collection-layout-add-btn', type: 'button' }, ['Add +'])
8
+ .nd.onClick(() => collection.add())
9
+ ]),
10
+ ForEachArray(data, Template)
11
+ ]);
12
+ }
@@ -0,0 +1,6 @@
1
+
2
+
3
+ export default function DefaultCollectionTemplate(item, index, {collection, fields}) {
4
+
5
+ return Object.values(fields);
6
+ }
@@ -0,0 +1,91 @@
1
+ import {Input, Label, Select, ShowIf, Switch} from "../../../core/elements/index";
2
+ import { $ } from "../../../../index";
3
+
4
+
5
+ const ErrorDisplayer = (errors) => {
6
+
7
+ const shouldDisplayError = $.computed(() => {
8
+ const val = errors.val();
9
+ return (val && val.length > 0);
10
+ }, [errors]);
11
+
12
+ return ShowIf(shouldDisplayError, () => {
13
+ const val = errors.val();
14
+ if(typeof val === 'string') return Div({ class: 'form-control-error' }, val);
15
+ return Div({ class: 'form-control-error' },
16
+ val.map(error => Div({ class: 'form-control-error-item' }, error))
17
+ );
18
+ });
19
+ }
20
+
21
+ export default function DefaultRender(field) {
22
+ const description = field?.toJSON();
23
+ const suffix = description.suffix || 'field';
24
+ const fieldId = description.id || description.name;
25
+
26
+ const inputProps = {
27
+ id: fieldId,
28
+ name: description.name,
29
+ type: description.type,
30
+ value: description.value,
31
+ placeholder: description.placeholder,
32
+ disabled: description.disabled,
33
+ readonly: description.readonly,
34
+ checked: description.checked
35
+ };
36
+
37
+ if(description.showErrors) {
38
+ description.errors = description.errors || $(null);
39
+ field.errors(description.errors);
40
+ }
41
+
42
+ const hasErrors = description.showErrors ? $.computed(() => {
43
+ const errs = description.errors?.val();
44
+ return errs && errs.length > 0;
45
+ }, [description.errors]) : null;
46
+ const hasFocus = $(false);
47
+
48
+ const wrapperClasses = {
49
+ [suffix+'-wrapper']: true,
50
+ [suffix+'-error']: hasErrors,
51
+ [suffix+'-focused']: hasFocus,
52
+ [suffix+'-disabled']: description.disabled,
53
+ [`${suffix}-${description.type}`]: true
54
+ };
55
+
56
+ const children = [];
57
+
58
+ switch (description.type) {
59
+ case 'radio':
60
+ case 'checkbox':
61
+ field.$input = Input({ ...inputProps });
62
+ children.push(
63
+ field.$input,
64
+ Label({for: fieldId}, description.label),
65
+ );
66
+ break;
67
+ case 'select':
68
+ field.$input = Select({ ...inputProps });
69
+ children.push(
70
+ Label({for: fieldId}, description.label),
71
+ field.$input,
72
+ );
73
+ break;
74
+ default:
75
+ field.$input = Input({ ...inputProps });
76
+ children.push(
77
+ Label({for: fieldId}, description.label),
78
+ field.$input,
79
+ );
80
+ }
81
+
82
+ for(const eventName in description.events) {
83
+ field.$input.addEventListener(eventName, description.events[eventName]);
84
+ }
85
+
86
+ return Div({ class: wrapperClasses }, [
87
+ children,
88
+ description.help ? Div({ class: suffix+'-hint' }, description.help) : null,
89
+ description.showErrors ? ErrorDisplayer(description.errors, field) : null,
90
+ ]);
91
+ };