native-document 1.0.69 → 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 (131) hide show
  1. package/.npmrc.example +0 -0
  2. package/components.js +2 -0
  3. package/dist/native-document.components.min.js +5636 -0
  4. package/dist/native-document.dev.js +384 -323
  5. package/dist/native-document.dev.js.map +1 -1
  6. package/dist/native-document.devtools.min.js +1 -1
  7. package/dist/native-document.min.js +1 -1
  8. package/elements.js +3 -3
  9. package/hrm.js +0 -0
  10. package/index.js +17 -17
  11. package/package.json +1 -1
  12. package/rollup.config.js +17 -1
  13. package/src/components/fom-control/FormControl.js +247 -0
  14. package/src/components/fom-control/default/DefaultLayout.js +8 -0
  15. package/src/components/fom-control/default/collection/DefaultCollectionLayout.js +12 -0
  16. package/src/components/fom-control/default/collection/DefaultCollectionTemplate.js +6 -0
  17. package/src/components/fom-control/field/DefaultRender.js +91 -0
  18. package/src/components/fom-control/field/Field.js +396 -0
  19. package/src/components/fom-control/field/FieldCollection.js +260 -0
  20. package/src/components/fom-control/field/FieldFactory.js +107 -0
  21. package/src/components/fom-control/field/types/AutocompleteField.js +46 -0
  22. package/src/components/fom-control/field/types/CheckboxField.js +17 -0
  23. package/src/components/fom-control/field/types/CheckboxGroupField.js +78 -0
  24. package/src/components/fom-control/field/types/ColorField.js +39 -0
  25. package/src/components/fom-control/field/types/DateField.js +62 -0
  26. package/src/components/fom-control/field/types/EmailField.js +44 -0
  27. package/src/components/fom-control/field/types/FileField.js +66 -0
  28. package/src/components/fom-control/field/types/HiddenField.js +8 -0
  29. package/src/components/fom-control/field/types/ImageField.js +49 -0
  30. package/src/components/fom-control/field/types/NumberField.js +74 -0
  31. package/src/components/fom-control/field/types/PasswordField.js +72 -0
  32. package/src/components/fom-control/field/types/RadioField.js +44 -0
  33. package/src/components/fom-control/field/types/RangeField.js +17 -0
  34. package/src/components/fom-control/field/types/SearchField.js +17 -0
  35. package/src/components/fom-control/field/types/SelectField.js +41 -0
  36. package/src/components/fom-control/field/types/StringField.js +49 -0
  37. package/src/components/fom-control/field/types/TelField.js +38 -0
  38. package/src/components/fom-control/field/types/TextAreaField.js +56 -0
  39. package/src/components/fom-control/field/types/TimeField.js +45 -0
  40. package/src/components/fom-control/field/types/UrlField.js +53 -0
  41. package/src/components/fom-control/index.js +8 -0
  42. package/src/components/fom-control/merge +0 -0
  43. package/src/components/fom-control/utils.js +17 -0
  44. package/src/components/fom-control/validation/Validation.js +556 -0
  45. package/src/components/table/Column.js +106 -0
  46. package/src/components/table/ColumnGroup.js +54 -0
  47. package/src/components/table/DataTable.js +195 -0
  48. package/src/components/table/SimpleTable.js +184 -0
  49. package/src/components/table/index.js +9 -0
  50. package/src/{data → core/data}/ObservableArray.js +2 -0
  51. package/src/{data → core/data}/ObservableItem.js +49 -3
  52. package/src/{data → core/data}/ObservableWhen.js +0 -0
  53. package/src/{data → core/data}/observable-helpers/computed.js +2 -1
  54. package/src/{elements → core/elements}/anchor.js +32 -32
  55. package/src/{elements → core/elements}/control/for-each-array.js +4 -2
  56. package/src/{elements → core/elements}/control/show-when.js +0 -0
  57. package/src/core/utils/EventEmitter.js +46 -0
  58. package/src/{utils → core/utils}/filters/date.js +2 -0
  59. package/src/{utils → core/utils}/filters/index.js +0 -0
  60. package/src/{utils → core/utils}/filters/standard.js +1 -1
  61. package/src/{utils → core/utils}/filters/strings.js +0 -0
  62. package/src/{utils → core/utils}/filters/utils.js +0 -0
  63. package/src/{utils → core/utils}/helpers.js +12 -0
  64. package/src/{utils → core/utils}/memoize.js +0 -0
  65. package/src/{utils → core/utils}/service.js +0 -0
  66. package/src/{utils → core/utils}/validator.js +7 -0
  67. package/src/{wrappers → core/wrappers}/ElementCreator.js +10 -33
  68. package/src/{wrappers → core/wrappers}/NDElement.js +0 -127
  69. package/src/core/wrappers/NdPrototype.js +147 -0
  70. package/src/core/wrappers/TemplateBinding.js +7 -0
  71. package/src/{wrappers → core/wrappers}/TemplateCloner.js +5 -6
  72. package/src/core/wrappers/prototype-extensions.js +56 -0
  73. package/src/devtools/hrm/ComponentRegistry.js +1 -1
  74. package/src/devtools/hrm/hrm.hook.template.js +0 -0
  75. package/src/devtools/hrm/hrm.orbservable.hook.template.js +0 -0
  76. package/src/devtools/hrm/nd-vite-hot-reload.js +0 -0
  77. package/src/devtools/hrm/transformComponent.js +0 -0
  78. package/src/router/Route.js +1 -1
  79. package/src/router/RouteGroupHelper.js +1 -1
  80. package/src/router/Router.js +4 -4
  81. package/src/router/RouterComponent.js +13 -2
  82. package/src/router/link.js +2 -2
  83. package/src/router/modes/HistoryRouter.js +2 -2
  84. package/types/filters/dates.d.ts +43 -0
  85. package/types/filters/standard.d.ts +71 -0
  86. package/types/filters/strings.d.ts +21 -0
  87. package/types/filters/types.d.ts +20 -0
  88. package/types/forms.d.ts +2 -1
  89. package/types/memoize.d.ts +0 -0
  90. package/types/native-fetch.d.ts +0 -0
  91. package/types/observable.d.ts +6 -0
  92. package/types/service.d.ts +0 -0
  93. package/types/validator.ts +2 -1
  94. package/utils.js +3 -3
  95. package/src/wrappers/NdPrototype.js +0 -71
  96. /package/src/{data → core/data}/MemoryManager.js +0 -0
  97. /package/src/{data → core/data}/Observable.js +0 -0
  98. /package/src/{data → core/data}/ObservableChecker.js +0 -0
  99. /package/src/{data → core/data}/Store.js +0 -0
  100. /package/src/{data → core/data}/observable-helpers/array.js +0 -0
  101. /package/src/{data → core/data}/observable-helpers/batch.js +0 -0
  102. /package/src/{data → core/data}/observable-helpers/object.js +0 -0
  103. /package/src/{elements → core/elements}/content-formatter.js +0 -0
  104. /package/src/{elements → core/elements}/control/for-each.js +0 -0
  105. /package/src/{elements → core/elements}/control/show-if.js +0 -0
  106. /package/src/{elements → core/elements}/control/switch.js +0 -0
  107. /package/src/{elements → core/elements}/description-list.js +0 -0
  108. /package/src/{elements → core/elements}/form.js +0 -0
  109. /package/src/{elements → core/elements}/html5-semantics.js +0 -0
  110. /package/src/{elements → core/elements}/img.js +0 -0
  111. /package/src/{elements → core/elements}/index.js +0 -0
  112. /package/src/{elements → core/elements}/interactive.js +0 -0
  113. /package/src/{elements → core/elements}/list.js +0 -0
  114. /package/src/{elements → core/elements}/medias.js +0 -0
  115. /package/src/{elements → core/elements}/meta-data.js +0 -0
  116. /package/src/{elements → core/elements}/table.js +0 -0
  117. /package/src/{errors → core/errors}/ArgTypesError.js +0 -0
  118. /package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  119. /package/src/{errors → core/errors}/RouterError.js +0 -0
  120. /package/src/{utils → core/utils}/args-types.js +0 -0
  121. /package/src/{utils → core/utils}/debug-manager.js +0 -0
  122. /package/src/{utils → core/utils}/events.js +0 -0
  123. /package/src/{utils → core/utils}/plugins-manager.js +0 -0
  124. /package/src/{utils → core/utils}/property-accumulator.js +0 -0
  125. /package/src/{utils → core/utils}/prototypes.js +0 -0
  126. /package/src/{wrappers → core/wrappers}/AttributesWrapper.js +0 -0
  127. /package/src/{wrappers → core/wrappers}/DocumentObserver.js +0 -0
  128. /package/src/{wrappers → core/wrappers}/HtmlElementWrapper.js +0 -0
  129. /package/src/{wrappers → core/wrappers}/SingletonView.js +0 -0
  130. /package/src/{wrappers → core/wrappers}/constants.js +0 -0
  131. /package/src/{utils/fetch → fetch}/NativeFetch.js +0 -0
@@ -0,0 +1,107 @@
1
+ import StringField from "./types/StringField";
2
+ import EmailField from "./types/EmailField";
3
+ import PasswordField from "./types/PasswordField";
4
+ import NumberField from "./types/NumberField";
5
+ import TextAreaField from "./types/TextAreaField";
6
+ import CheckboxField from "./types/CheckboxField";
7
+ import RadioField from "./types/RadioField";
8
+ import SelectField from "./types/SelectField";
9
+ import HiddenField from "./types/HiddenField";
10
+ import FileField from "./types/FileField";
11
+ import DateField from "./types/DateField";
12
+ import TimeField from "./types/TimeField";
13
+ import TelField from "./types/TelField";
14
+ import UrlField from "./types/UrlField";
15
+ import ColorField from "./types/ColorField";
16
+ import RangeField from "./types/RangeField";
17
+ import ImageField from "./types/ImageField";
18
+ import CheckboxGroupField from "./types/CheckboxGroupField";
19
+ import AutocompleteField from "./types/AutocompleteField";
20
+
21
+ import Field from "./Field";
22
+ import FieldCollection from "./FieldCollection";
23
+
24
+
25
+ Field.string = function(name, defaultConfig) {
26
+ return new StringField(name, 'text', defaultConfig);
27
+ };
28
+
29
+ Field.text = function(name, defaultConfig) {
30
+ return new StringField(name, 'text', defaultConfig);
31
+ };
32
+
33
+ Field.email = function(name, defaultConfig) {
34
+ return new EmailField(name, defaultConfig);
35
+ };
36
+
37
+ Field.password = function(name, defaultConfig) {
38
+ return new PasswordField(name, defaultConfig);
39
+ };
40
+
41
+ Field.number = function(name, defaultConfig) {
42
+ return new NumberField(name, 'number', defaultConfig);
43
+ };
44
+
45
+ Field.textarea = function(name, defaultConfig) {
46
+ return new TextAreaField(name, defaultConfig);
47
+ };
48
+
49
+ Field.checkbox = function(name, defaultConfig) {
50
+ return new CheckboxField(name, defaultConfig);
51
+ };
52
+
53
+ Field.radio = function(name, options, defaultConfig) {
54
+ return new RadioField(name, options, defaultConfig);
55
+ };
56
+
57
+ Field.select = function(name, options, defaultConfig) {
58
+ return new SelectField(name, options, defaultConfig);
59
+ };
60
+
61
+ Field.hidden = function(name, defaultConfig) {
62
+ return new HiddenField(name, defaultConfig);
63
+ };
64
+
65
+ Field.file = function(name, defaultConfig) {
66
+ return new FileField(name, 'file', defaultConfig);
67
+ };
68
+
69
+ Field.date = function(name, defaultConfig) {
70
+ return new DateField(name, defaultConfig);
71
+ };
72
+
73
+ Field.time = function(name, defaultConfig) {
74
+ return new TimeField(name, defaultConfig);
75
+ };
76
+
77
+ Field.tel = function(name, defaultConfig) {
78
+ return new TelField(name, defaultConfig);
79
+ };
80
+
81
+ Field.url = function(name, defaultConfig) {
82
+ return new UrlField(name, defaultConfig);
83
+ };
84
+
85
+ Field.color = function(name, defaultConfig) {
86
+ return new ColorField(name, defaultConfig);
87
+ };
88
+
89
+ Field.range = function(name, defaultConfig) {
90
+ return new RangeField(name, defaultConfig);
91
+ };
92
+
93
+ Field.image = function(name, defaultConfig) {
94
+ return new ImageField(name, defaultConfig);
95
+ };
96
+
97
+ Field.checkboxGroup = function(name, options, defaultConfig) {
98
+ return new CheckboxGroupField(name, options, defaultConfig);
99
+ };
100
+
101
+ Field.autocomplete = function(name, defaultConfig) {
102
+ return new AutocompleteField(name, defaultConfig);
103
+ };
104
+
105
+ Field.collection = function(name, defaultConfig) {
106
+ return new FieldCollection(name, defaultConfig);
107
+ };
@@ -0,0 +1,46 @@
1
+ import StringField from "./StringField";
2
+
3
+ export default function AutocompleteField(name, defaultConfig) {
4
+ StringField.call(this, name, 'autocomplete', defaultConfig);
5
+
6
+ Object.assign(this.$description, {
7
+ source: null,
8
+ minChars: 2,
9
+ debounce: 300,
10
+ maxResults: 10
11
+ });
12
+ }
13
+
14
+ AutocompleteField.prototype = Object.create(StringField.prototype);
15
+ AutocompleteField.prototype.constructor = AutocompleteField;
16
+
17
+ AutocompleteField.prototype.source = function(dataSource) {
18
+ this.$description.source = dataSource;
19
+ return this;
20
+ };
21
+
22
+ AutocompleteField.prototype.minChars = function(min) {
23
+ this.$description.minChars = min;
24
+ return this;
25
+ };
26
+
27
+ AutocompleteField.prototype.debounce = function(ms) {
28
+ this.$description.debounce = ms;
29
+ return this;
30
+ };
31
+
32
+ AutocompleteField.prototype.maxResults = function(max) {
33
+ this.$description.maxResults = max;
34
+ return this;
35
+ };
36
+
37
+ AutocompleteField.prototype.oneOf = function(allowedValues, message) {
38
+ this.$description.rules.push({
39
+ validate: (value) => {
40
+ if (!value) return true;
41
+ return allowedValues.includes(value);
42
+ },
43
+ message: message || `Must be one of: ${allowedValues.join(', ')}`
44
+ });
45
+ return this;
46
+ };
@@ -0,0 +1,17 @@
1
+ import Field from "../Field";
2
+
3
+ export default function CheckboxField(name, defaultConfig) {
4
+ Field.call(this, name, 'checkbox', defaultConfig);
5
+
6
+ Object.assign(this.$description, {
7
+ checked: false,
8
+ });
9
+ }
10
+
11
+ CheckboxField.prototype = Object.create(Field.prototype);
12
+ CheckboxField.prototype.constructor = CheckboxField;
13
+
14
+ CheckboxField.prototype.checked = function(value) {
15
+ this.$description.checked = value;
16
+ return this;
17
+ };
@@ -0,0 +1,78 @@
1
+ import Field from "../Field";
2
+
3
+ export default function CheckboxGroupField(name, options, defaultConfig) {
4
+ Field.call(this, name, 'checkbox-group', defaultConfig);
5
+
6
+ Object.assign(this.$description, {
7
+ options: options || [],
8
+ layout: 'vertical',
9
+ defaultValue: []
10
+ });
11
+ }
12
+
13
+ CheckboxGroupField.prototype = Object.create(Field.prototype);
14
+ CheckboxGroupField.prototype.constructor = CheckboxGroupField;
15
+
16
+ CheckboxGroupField.prototype.options = function(opts) {
17
+ this.$description.options = opts;
18
+ return this;
19
+ };
20
+
21
+ CheckboxGroupField.prototype.layout = function(value) {
22
+ const allowedLayouts = ['vertical', 'horizontal', 'grid'];
23
+
24
+ if (!allowedLayouts.includes(value)) {
25
+ throw new Error(`Invalid layout "${value}". Must be one of: ${allowedLayouts.join(', ')}`);
26
+ }
27
+
28
+ this.$description.layout = value;
29
+ return this;
30
+ };
31
+
32
+ CheckboxGroupField.prototype.horizontal = function() {
33
+ this.$description.layout = 'horizontal';
34
+ return this;
35
+ };
36
+
37
+ CheckboxGroupField.prototype.vertical = function() {
38
+ this.$description.layout = 'vertical';
39
+ return this;
40
+ };
41
+
42
+ CheckboxGroupField.prototype.grid = function() {
43
+ this.$description.layout = 'grid';
44
+ return this;
45
+ };
46
+
47
+ CheckboxGroupField.prototype.minChecked = function(min, message) {
48
+ this.$description.rules.push({
49
+ validate: (values) => {
50
+ if (!Array.isArray(values)) return false;
51
+ return values.length >= min;
52
+ },
53
+ message: message || `At least ${min} option${min > 1 ? 's' : ''} must be selected`
54
+ });
55
+ return this;
56
+ };
57
+
58
+ CheckboxGroupField.prototype.maxChecked = function(max, message) {
59
+ this.$description.rules.push({
60
+ validate: (values) => {
61
+ if (!Array.isArray(values)) return false;
62
+ return values.length <= max;
63
+ },
64
+ message: message || `Maximum ${max} option${max > 1 ? 's' : ''} allowed`
65
+ });
66
+ return this;
67
+ };
68
+
69
+ CheckboxGroupField.prototype.exactChecked = function(count, message) {
70
+ this.$description.rules.push({
71
+ validate: (values) => {
72
+ if (!Array.isArray(values)) return false;
73
+ return values.length === count;
74
+ },
75
+ message: message || `Exactly ${count} option${count > 1 ? 's' : ''} must be selected`
76
+ });
77
+ return this;
78
+ };
@@ -0,0 +1,39 @@
1
+ // ColorField.js
2
+ import Field from "../Field";
3
+ import {Validation} from "../../validation/Validation";
4
+
5
+ export default function ColorField(name, defaultConfig) {
6
+ Field.call(this, name, 'color', defaultConfig);
7
+
8
+ Object.assign(this.$description, {
9
+ format: 'hex',
10
+ presets: null
11
+ });
12
+ }
13
+
14
+ ColorField.prototype = Object.create(Field.prototype);
15
+ ColorField.prototype.constructor = ColorField;
16
+
17
+ ColorField.prototype.format = function(formatType) {
18
+ const allowedFormats = ['hex', 'rgb', 'hsl'];
19
+
20
+ if (!allowedFormats.includes(formatType)) {
21
+ throw new Error(`Invalid format "${formatType}". Must be one of: ${allowedFormats.join(', ')}`);
22
+ }
23
+
24
+ this.$description.format = formatType;
25
+ return this;
26
+ };
27
+
28
+ ColorField.prototype.presets = function(colors) {
29
+ this.$description.presets = colors;
30
+ return this;
31
+ };
32
+
33
+ ColorField.prototype.hex = function(message) {
34
+ return this.addRule(Validation.hexColor, [], message);
35
+ };
36
+
37
+ ColorField.prototype.rgb = function(message) {
38
+ return this.addRule(Validation.rgbColor, [], message);
39
+ };
@@ -0,0 +1,62 @@
1
+ import Field from "../Field";
2
+ import {Validation} from "../../validation/Validation";
3
+
4
+ export default function DateField(name, defaultConfig) {
5
+ Field.call(this, name, 'date', defaultConfig);
6
+
7
+ Object.assign(this.$description, {
8
+ format: 'YYYY-MM-DD',
9
+ minDate: null,
10
+ maxDate: null,
11
+ disabledDates: [],
12
+ picker: true
13
+ });
14
+ }
15
+
16
+ DateField.prototype = Object.create(Field.prototype);
17
+ DateField.prototype.constructor = DateField;
18
+
19
+ DateField.prototype.format = function(formatString) {
20
+ this.$description.format = formatString;
21
+ return this;
22
+ };
23
+
24
+ DateField.prototype.minDate = function(date) {
25
+ this.$description.minDate = date;
26
+ return this;
27
+ };
28
+
29
+ DateField.prototype.maxDate = function(date) {
30
+ this.$description.maxDate = date;
31
+ return this;
32
+ };
33
+
34
+ DateField.prototype.disabledDates = function(dates) {
35
+ this.$description.disabledDates = dates;
36
+ return this;
37
+ };
38
+
39
+ DateField.prototype.picker = function(enabled = true) {
40
+ this.$description.picker = enabled;
41
+ return this;
42
+ };
43
+
44
+ DateField.prototype.min = function(date, message) {
45
+ return this.addRule(Validation.afterDate, [date], message);
46
+ };
47
+
48
+ DateField.prototype.max = function(date, message) {
49
+ return this.addRule(Validation.beforeDate, [date], message);
50
+ };
51
+
52
+ DateField.prototype.between = function(startDate, endDate, message) {
53
+ return this.addRule(Validation.betweenDates, [startDate, endDate], message);
54
+ };
55
+
56
+ DateField.prototype.after = function(date, message) {
57
+ return this.addRule(Validation.afterDate, [date], message);
58
+ };
59
+
60
+ DateField.prototype.before = function(date, message) {
61
+ return this.addRule(Validation.beforeDate, [date], message);
62
+ };
@@ -0,0 +1,44 @@
1
+ import Field from "../Field";
2
+ import {Validation} from "../../validation/Validation";
3
+
4
+ export default function EmailField(name, defaultConfig) {
5
+ Field.call(this, name, 'email', defaultConfig);
6
+
7
+ // Auto-apply email validation
8
+ this.addRule(Validation.email, []);
9
+ }
10
+
11
+ EmailField.prototype = Object.create(Field.prototype);
12
+ EmailField.prototype.constructor = EmailField;
13
+
14
+ EmailField.prototype.email = function(message) {
15
+ const existingRule = this.rules.find(r => r.fn === Validation.email);
16
+ if (existingRule && message) {
17
+ existingRule.message = message;
18
+ }
19
+ return this;
20
+ };
21
+
22
+ EmailField.prototype.allowedDomain = function(allowedDomains, message) {
23
+ this.$description.rules.push({
24
+ validate: (value) => {
25
+ if (!value) return true;
26
+ const domain = value.split('@')[1];
27
+ return allowedDomains.includes(domain);
28
+ },
29
+ message: message || `Allowed domains: ${allowedDomains.join(', ')}`
30
+ });
31
+ return this;
32
+ };
33
+
34
+ EmailField.prototype.notAllowedDomain = function(blockedDomains, message) {
35
+ this.$description.rules.push({
36
+ validate: (value) => {
37
+ if (!value) return true;
38
+ const domain = value.split('@')[1];
39
+ return !blockedDomains.includes(domain);
40
+ },
41
+ message: message || `Domain not allowed`
42
+ });
43
+ return this;
44
+ };
@@ -0,0 +1,66 @@
1
+ import Field from "../Field";
2
+ import {Validation} from "../../validation/Validation";
3
+
4
+ export default function FileField(name, type = 'file', defaultConfig = {}) {
5
+ Field.call(this, name, type, defaultConfig);
6
+
7
+ Object.assign(this.$description, {
8
+ accept: null,
9
+ multiple: false,
10
+ preview: false,
11
+ dragDrop: false,
12
+ compress: false
13
+ });
14
+ }
15
+
16
+ FileField.prototype = Object.create(Field.prototype);
17
+ FileField.prototype.constructor = FileField;
18
+
19
+ FileField.prototype.accept = function(mimeTypes) {
20
+ this.$description.accept = Array.isArray(mimeTypes) ? mimeTypes.join(',') : mimeTypes;
21
+ return this;
22
+ };
23
+
24
+ FileField.prototype.multiple = function(enabled = true) {
25
+ this.$description.multiple = enabled;
26
+ return this;
27
+ };
28
+
29
+ FileField.prototype.preview = function(enabled = true) {
30
+ this.$description.preview = enabled;
31
+ return this;
32
+ };
33
+
34
+ FileField.prototype.dragDrop = function(enabled = true) {
35
+ this.$description.dragDrop = enabled;
36
+ return this;
37
+ };
38
+
39
+ FileField.prototype.compress = function(enabled = true) {
40
+ this.$description.compress = enabled;
41
+ return this;
42
+ };
43
+
44
+ FileField.prototype.maxSize = function(bytes, message) {
45
+ return this.addRule(Validation.maxFileSize, [bytes], message);
46
+ };
47
+
48
+ FileField.prototype.minSize = function(bytes, message) {
49
+ return this.addRule(Validation.minFileSize, [bytes], message);
50
+ };
51
+
52
+ FileField.prototype.mimeTypes = function(types, message) {
53
+ return this.addRule(Validation.mimeTypes, [types], message);
54
+ };
55
+
56
+ FileField.prototype.extensions = function(extensions, message) {
57
+ return this.addRule(Validation.extensions, [extensions], message);
58
+ };
59
+
60
+ FileField.prototype.maxFiles = function(max, message) {
61
+ return this.addRule(Validation.maxFiles, [max], message);
62
+ };
63
+
64
+ FileField.prototype.minFiles = function(min, message) {
65
+ return this.addRule(Validation.minFiles, [min], message);
66
+ };
@@ -0,0 +1,8 @@
1
+ import Field from "../Field";
2
+
3
+ export default function HiddenField(name, defaultConfig) {
4
+ Field.call(this, name, 'hidden', defaultConfig);
5
+ }
6
+
7
+ HiddenField.prototype = Object.create(Field.prototype);
8
+ HiddenField.prototype.constructor = HiddenField;
@@ -0,0 +1,49 @@
1
+ import FileField from "./FileField";
2
+ import {Validation} from "../../validation/Validation";
3
+
4
+ export default function ImageField(name, defaultConfig) {
5
+ FileField.call(this, name, 'image', defaultConfig);
6
+
7
+ Object.assign(this.$description, {
8
+ maxWidth: null,
9
+ maxHeight: null,
10
+ crop: false
11
+ });
12
+
13
+ // Auto-apply image mime types
14
+ this.accept(['image/jpeg', 'image/png', 'image/gif', 'image/webp']);
15
+ }
16
+
17
+ ImageField.prototype = Object.create(FileField.prototype);
18
+ ImageField.prototype.constructor = ImageField;
19
+
20
+ ImageField.prototype.maxWidth = function(width) {
21
+ this.$description.maxWidth = width;
22
+ return this;
23
+ };
24
+
25
+ ImageField.prototype.maxHeight = function(height) {
26
+ this.$description.maxHeight = height;
27
+ return this;
28
+ };
29
+
30
+ ImageField.prototype.crop = function(enabled = true) {
31
+ this.$description.crop = enabled;
32
+ return this;
33
+ };
34
+
35
+ ImageField.prototype.dimensions = function(width, height, message) {
36
+ return this.addRule(Validation.dimensions, [width, height], message);
37
+ };
38
+
39
+ ImageField.prototype.maxDimensions = function(width, height, message) {
40
+ return this.addRule(Validation.maxDimensions, [width, height], message);
41
+ };
42
+
43
+ ImageField.prototype.minDimensions = function(width, height, message) {
44
+ return this.addRule(Validation.minDimensions, [width, height], message);
45
+ };
46
+
47
+ ImageField.prototype.aspectRatio = function(ratio, message) {
48
+ return this.addRule(Validation.aspectRatio, [ratio], message);
49
+ };
@@ -0,0 +1,74 @@
1
+ import {Validation} from "../../validation/Validation";
2
+ import Field from "../Field";
3
+
4
+ export default function NumberField(name, type = 'number', defaultConfig = {}) {
5
+ Field.call(this, name, type, defaultConfig);
6
+
7
+ Object.assign(this.$description, {
8
+ ...this.$description,
9
+ step: null,
10
+ decimals: null,
11
+ prefix: null,
12
+ suffix: null,
13
+ });
14
+ }
15
+
16
+ NumberField.prototype = Object.create(Field.prototype);
17
+ NumberField.prototype.constructor = NumberField;
18
+
19
+ NumberField.prototype.min = function(min, message) {
20
+ return this.addRule(Validation.min, [min], message);
21
+ };
22
+
23
+ NumberField.prototype.max = function(max, message) {
24
+ return this.addRule(Validation.max, [max], message);
25
+ };
26
+
27
+ NumberField.prototype.between = function(min, max, message) {
28
+ return this.addRule(Validation.between, [min, max], message);
29
+ };
30
+
31
+ NumberField.prototype.integer = function(message) {
32
+ return this.addRule(Validation.integer, [], message);
33
+ };
34
+
35
+ NumberField.prototype.positive = function(message) {
36
+ return this.addRule(Validation.positive, [], message);
37
+ };
38
+
39
+ NumberField.prototype.unsigned = NumberField.prototype.positive;
40
+
41
+ NumberField.prototype.negative = function(message) {
42
+ return this.addRule(Validation.negative, [], message);
43
+ };
44
+
45
+ NumberField.prototype.multipleOf = function(n, message) {
46
+ this.$description.rules.push({
47
+ validate: (value) => {
48
+ if (!value && value !== 0) return true;
49
+ return Number(value) % n === 0;
50
+ },
51
+ message: message || `Must be a multiple of ${n}`
52
+ });
53
+ return this;
54
+ };
55
+
56
+ NumberField.prototype.step = function(value) {
57
+ this.$description.step = value;
58
+ return this;
59
+ };
60
+
61
+ NumberField.prototype.decimals = function(value) {
62
+ this.$description.decimals = value;
63
+ return this;
64
+ };
65
+
66
+ NumberField.prototype.prefix = function(text) {
67
+ this.$description.prefix = text;
68
+ return this;
69
+ };
70
+
71
+ NumberField.prototype.suffix = function(text) {
72
+ this.$description.suffix = text;
73
+ return this;
74
+ };
@@ -0,0 +1,72 @@
1
+ import {Validation} from "../../validation/Validation";
2
+ import StringField from "./StringField";
3
+
4
+ export default function PasswordField(name, defaultConfig) {
5
+ StringField.call(this, name, 'password', defaultConfig);
6
+ Object.assign(this.$description, {
7
+ visibilityToggle: false,
8
+ showStrengthMeter: false
9
+ });
10
+ }
11
+
12
+ PasswordField.prototype = Object.create(StringField.prototype);
13
+ PasswordField.prototype.constructor = PasswordField;
14
+
15
+ PasswordField.prototype.strong = function(message) {
16
+ const strongPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
17
+ return this.addRule(
18
+ Validation.pattern,
19
+ [strongPattern],
20
+ message || 'Password must contain uppercase, lowercase, and number'
21
+ );
22
+ };
23
+
24
+ PasswordField.prototype.containsNumber = function(message) {
25
+ return this.addRule(
26
+ Validation.pattern,
27
+ [/\d/],
28
+ message || 'Must contain at least one number'
29
+ );
30
+ };
31
+
32
+ PasswordField.prototype.containsUppercase = function(message) {
33
+ return this.addRule(
34
+ Validation.pattern,
35
+ [/[A-Z]/],
36
+ message || 'Must contain at least one uppercase letter'
37
+ );
38
+ };
39
+
40
+ PasswordField.prototype.containsLowercase = function(message) {
41
+ return this.addRule(
42
+ Validation.pattern,
43
+ [/[a-z]/],
44
+ message || 'Must contain at least one lowercase letter'
45
+ );
46
+ };
47
+
48
+ PasswordField.prototype.containsSpecialChar = function(message) {
49
+ return this.addRule(
50
+ Validation.pattern,
51
+ [/[!@#$%^&*(),.?":{}|<>]/],
52
+ message || 'Must contain at least one special character'
53
+ );
54
+ };
55
+
56
+ PasswordField.prototype.visibilityToggle = function(enabled = true) {
57
+ this.$description.visibilityToggle = enabled;
58
+ return this;
59
+ };
60
+
61
+ PasswordField.prototype.showStrengthMeter = function(enabled = true) {
62
+ this.$description.showStrengthMeter = enabled;
63
+ return this;
64
+ };
65
+
66
+ PasswordField.prototype.same = function(fieldName, message) {
67
+ return this.addRule(Validation.same, [fieldName], message || 'Passwords must match');
68
+ };
69
+
70
+ PasswordField.prototype.different = function(fieldName, message) {
71
+ return this.addRule(Validation.different, [fieldName], message);
72
+ };