@steveesamson/microform 0.0.10 → 1.0.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.
package/README.md CHANGED
@@ -25,18 +25,23 @@ Once you've added `microform` to your project, use it as shown below, in your vi
25
25
  ### In the view Script
26
26
 
27
27
  ```ts
28
- <script lang='ts'>
28
+ <script>
29
29
  import uForm from "@steveesamson/microform";
30
30
  // default form data, probably passed as props
31
- export let defaultData:any = {};
31
+ let defaultData:any = $props();
32
32
 
33
33
  // Instatiate microform
34
- const { form, values, errors, submit, valid } = uForm({
34
+ const { form, values, errors, submit, sanity } = uForm({
35
35
  // Set default form data
36
36
  data:{...defaultData},
37
37
  // Set a global event for validation, can be overriden on a each field.
38
38
  // Possible values: blur, change, input, keyup
39
- validateEvent:'blur'
39
+ options:{
40
+ // Default event that triggers validation
41
+ validateEvent:'blur',
42
+ // Configure validators here
43
+ validators:{}
44
+ }
40
45
  });
41
46
 
42
47
  // Submit handler
@@ -51,11 +56,11 @@ const onSubmit = (data:unknown) => {
51
56
 
52
57
  On the instantiation of `microform`, we have access to:
53
58
 
54
- - `values`, a `FormValues`, which is a `svelte store` for form data.
55
- - `errors`, a `FormErrors`, which is a `svelte store` for form errors.
59
+ - `values`, a `FormValues`, which represents form data.
60
+ - `errors`, a `FormErrors`, which represents form errors.
56
61
  - `form`, which is a `svelte action` that actually does the `microform` magic.
57
62
  - `submit`, which is another `svelte action` to handle form submission.
58
- - `valid`, a `FormSanity`, which is a `svelte store` that tells if a form is clean/without errors.
63
+ - `sanity`, a `FormSanity`, which tells us if a form is clean/without errors by it's `ok` property.
59
64
  - `reset`, a function to reset form
60
65
  - `onsubmit`, a function to handle form submission.
61
66
 
@@ -63,91 +68,162 @@ On the instantiation of `microform`, we have access to:
63
68
 
64
69
  ```html
65
70
  <form use:submit={onSubmit}>
66
- <label for='username'>
67
- Username:
68
- <input
69
- type='text'
70
- name='username'
71
- id='username'
72
- use:form
73
- data-validations='required'>
74
- {#if $errors.username}
75
- <small>{$errors.username}</small>
76
- {/if}
77
- </label>
78
- <label for='email_account'>
79
- Email Account:
80
- <input
81
- type='text'
82
- name='email_account'
83
- id='email_account'
84
- use:form={{
85
- validations:'required|email'
86
- }}/>
87
- {#if $errors.email_account}
88
- <small>{$errors.email_account}</small>
89
- {/if}
90
- </label>
91
- <label for='gender'>
92
- Gender:
93
- <select
94
- name='gender'
95
- id='gender'
96
- use:form={{
97
- validations:'required',
98
- validateEvent:'change'
99
- }}>
100
- <options value=''>Gender please</option>
101
- <options value='F'>Female</option>
102
- <options value='M'>Male</option>
103
- </select>
104
- {#if $errors.gender}
105
- <small>{$errors.gender}</small>
106
- {/if}
107
- </label>
108
- <label for='password'>
109
- Password:
110
- <input
111
- type='text'
112
- name='password'
113
- id='password'
114
- use:form
115
- data-validations='required'>
116
- {#if $errors.password}
117
- <small>{$errors.password}</small>
118
- {/if}
119
- </label>
120
- <label for='confirm_password'>
121
- Confirm password:
122
- <input
123
- type='text'
124
- name='confirm_password'
125
- id='confirm_password'
126
- use:form
127
- data-validations='required|match:password'>
128
- {#if $errors.confirm_password}
129
- <small>{$errors.confirm_password}</small>
130
- {/if}
131
- </label>
132
- <label for="story">
133
- Story:
134
- <div
135
- contenteditable="true"
136
- use:form={{
137
- validateEvent: 'input',
138
- validations: 'required',
139
- name: 'story',
140
- html: true
141
- }}
142
- />
143
- {#if $errors.story}
144
- <small>{$errors.story}</small>
145
- {/if}
146
- </label>
71
+ <label for="fullname">
72
+ Name:
73
+ <input
74
+ type="text"
75
+ name="fullname"
76
+ id="fullname"
77
+ use:form={{ validations: ['required'] }}
78
+ />
79
+ {#if errors.fullname}
80
+ <small>{errors.fullname}</small>
81
+ {/if}
82
+ </label>
83
+ <label for="dob">
84
+ DOB:
85
+ <input
86
+ type="date"
87
+ name="dob"
88
+ id="dob"
89
+ use:form={{ validations: ['required'] }}
90
+ />
91
+ {#if errors.dob}
92
+ <small>{errors.dob}</small>
93
+ {/if}
94
+ </label>
95
+ <label for="supper_time">
96
+ Supper time:
97
+ <input
98
+ type="time"
99
+ name="supper_time"
100
+ id="supper_time"
101
+ use:form={{ validations: ['required'] }}
102
+ />
103
+ {#if errors.supper_time}
104
+ <small>{errors.supper_time}</small>
105
+ {/if}
106
+ </label>
107
+ <label for="password">
108
+ Password:
109
+ <input
110
+ type="password"
111
+ name="password"
112
+ id="password"
113
+ use:form={{ validations: ['required'] }}
114
+ />
115
+ {#if errors.password}
116
+ <small>{errors.password}</small>
117
+ {/if}
118
+ </label>
119
+ <label for="gender">
120
+ Gender:
121
+ <select
122
+ name="gender"
123
+ id="gender"
124
+ use:form={{ validateEvent: 'change', validations: ['required'] }}
125
+ >
126
+ <option value="">Select gender</option>
127
+ <option value="M">Male</option>
128
+ <option value="F">Female</option>
129
+ </select>
130
+ {#if errors.gender}
131
+ <small>{errors.gender}</small>
132
+ {/if}
133
+ </label>
134
+ <label for="email">
135
+ Email:
136
+ <input
137
+ type="text"
138
+ name="email"
139
+ id="email"
140
+ use:form={{ validations: ['required', 'email'] }}
141
+ />
142
+ {#if errors.email}
143
+ <small>{errors.email}</small>
144
+ {/if}
145
+ </label>
146
+ <label for="resume">
147
+ Resume:
148
+ <input
149
+ type="file"
150
+ name="resume"
151
+ id="resume"
152
+ use:form={{
153
+ validateEvent:'change',
154
+ validations: ['required', 'file-size-mb:3']
155
+ }}
156
+ />
157
+ {#if errors.resume}
158
+ <small>{errors.resume}</small>
159
+ {/if}
160
+ </label>
161
+ <label for="comment">
162
+ Comment:
163
+ <textarea
164
+ name="comment"
165
+ id="comment"
166
+ use:form={{ validations: ['required'] }}
167
+ ></textarea>
168
+ {#if errors.comment}
169
+ <small>{errors.comment}</small>
170
+ {/if}
171
+ </label>
172
+ <label for="beverage">
173
+ Beverage:
174
+ {#each items as item (item.value)}
175
+ <span>
176
+ <input
177
+ type="radio"
178
+ name="beverage"
179
+ value={item.value}
180
+ use:form={{ validateEvent: 'input', validations: ['required'] }}
181
+ bind:group={values.beverage}
182
+ />
183
+ {item.label}
184
+ </span>
185
+ {/each}
186
+ {#if errors.beverage}
187
+ <small>{errors.beverage}</small>
188
+ {/if}
189
+ </label>
190
+ <label for="favfoods">
191
+ Fav Foods:
192
+ {#each foods as item (item.value)}
193
+ <span>
194
+ <input
195
+ type="checkbox"
196
+ name="favfoods"
197
+ value={item.value}
198
+ use:form={{ validateEvent: 'change', validations: ['required'] }}
199
+ bind:group={values['favfoods']}
200
+ />
201
+ {item.label}
202
+ </span>
203
+ {/each}
204
+ {#if errors.favfoods}
205
+ <small>{errors.favfoods}</small>
206
+ {/if}
207
+ </label>
208
+ <label for="story">
209
+ Story:
210
+ <div
211
+ contenteditable="true"
212
+ use:form={{
213
+ validateEvent: 'input',
214
+ validations: ['required'],
215
+ name: 'story',
216
+ html: true
217
+ }}
218
+ ></div>
219
+ {#if errors.story}
220
+ <small>{errors.story}</small>
221
+ {/if}
222
+ </label>
147
223
 
148
224
  <button
149
225
  type='submit'
150
- disabled={!$valid}>
226
+ disabled={!sanity.ok}>
151
227
  Submit form
152
228
  </button>
153
229
  </form>
@@ -159,9 +235,16 @@ While the above example uses the `submit` action of `microform`, form could also
159
235
  <form>
160
236
  <label for="password">
161
237
  Password:
162
- <input type="text" name="password" id="password" use:form data-validations="required" />
163
- {#if $errors.password}
164
- <small>{$errors.password}</small>
238
+ <input
239
+ type="text"
240
+ name="password"
241
+ id="password"
242
+ use:form={{
243
+ validations: ['required']
244
+ }}
245
+ />
246
+ {#if errors.password}
247
+ <small>{errors.password}</small>
165
248
  {/if}
166
249
  </label>
167
250
  <label for="confirm_password">
@@ -170,15 +253,16 @@ While the above example uses the `submit` action of `microform`, form could also
170
253
  type="text"
171
254
  name="confirm_password"
172
255
  id="confirm_password"
173
- use:form
174
- data-validations="required|match:password"
256
+ use:form={{
257
+ validations: ['required','match:password'],
258
+ }}
175
259
  />
176
- {#if $errors.confirm_password}
177
- <small>{$errors.confirm_password}</small>
260
+ {#if errors.confirm_password}
261
+ <small>{errors.confirm_password}</small>
178
262
  {/if}
179
263
  </label>
180
264
 
181
- <button type="button" disabled="{!$valid}" on:click="{onsubmit(onSubmit)}">Submit form</button>
265
+ <button type="button" disabled="{!sanity.ok}" onclick="{onsubmit(onSubmit)}">Submit form</button>
182
266
  </form>
183
267
  ```
184
268
 
@@ -186,12 +270,12 @@ While the above example uses the `submit` action of `microform`, form could also
186
270
 
187
271
  `microform` performs its magic by relying the `form` action. The `form` action can optionally accept the following:
188
272
 
189
- ```javascript
273
+ ```ts
190
274
  <input
191
275
  use:form={{
192
276
  // an optional list of validations
193
277
  // default is '' - no validations
194
- validations: 'email|length:20',
278
+ validations: ['email', 'len:20'],
195
279
  // an optional string of
196
280
  // any of blur, change, input, keyup.
197
281
  // default is blur
@@ -214,46 +298,36 @@ You need not bind the `values` to your fields except when there is a definite ne
214
298
 
215
299
  ```html
216
300
  <input
217
- type="text"
218
- name="email_account"
219
- id="email_account"
220
- value="{$values.email_account}"
221
- data-validations="required|email"
222
- use:form
301
+ ...
302
+ value="{values.email_account}"
223
303
  />
224
304
  ```
225
305
 
226
306
  ### 1. Validations
227
307
 
228
- Uses both inline `data-validations` on field and `validations` props on `form` action. For instance, the following are perfectly identical:
308
+ `validations` is an array of validations to check field values against for correctnes. Uses `validations` props on `form` action. For instance, the following:
229
309
 
230
310
  ```html
231
- <input
232
- type='text'
233
- name='email_account'
234
- id='email_account'
235
- data-validations='required|email'
236
- use:form/>
237
-
238
311
  <input
239
312
  type='text'
240
313
  name='email_account'
241
314
  id='email_account'
242
315
  use:form={{
243
- validations:'required|email'
244
- }}/>
316
+ validations:[ 'required', 'email' ]
317
+ }}
318
+ />
245
319
  ```
246
320
 
247
321
  ### 2. Validation Event
248
322
 
249
- Validation event can be changed/specified on a per-field basis. For instance, in our example, the global `validateEvent` was set to `blur` but we changed it on the select field to `change` like so:
323
+ Validation event is to configure the event that should trigger validations. It can be changed/specified on a per-field basis. For instance, in our example, the global `validateEvent` was set to `blur` but we changed it on the select field to `change` like so:
250
324
 
251
325
  ```html
252
326
  <select
253
327
  name='gender'
254
328
  id='gender'
255
329
  use:form={{
256
- validations:'required',
330
+ validations:['required'],
257
331
  validateEvent:'change'
258
332
  }}>
259
333
  <options value=''>Gender please</option>
@@ -274,13 +348,13 @@ Validation event can be changed/specified on a per-field basis. For instance, in
274
348
  contenteditable="true"
275
349
  use:form={{
276
350
  validateEvent: 'input',
277
- validations: 'required',
351
+ validations: ['required'],
278
352
  name: 'story',
279
353
  html: true
280
354
  }}
281
- />
282
- {#if $errors.story}
283
- <small>{$errors.story}</small>
355
+ ></div>
356
+ {#if errors.story}
357
+ <small>{errors.story}</small>
284
358
  {/if}
285
359
  </label>
286
360
  </form>
@@ -290,35 +364,128 @@ Validation event can be changed/specified on a per-field basis. For instance, in
290
364
 
291
365
  `microform` provides a set of usable validations out-of-box. The following is a list of provided validations:
292
366
 
293
- - `required`: Usage, `validations='required'`
294
- - `email`: Usage, `validations='email'`
295
- - `url`: Usage, `validations='url'`
296
- - `ip`: Usage, `validations='ip'`
297
- - `length`: Usage, `validations='length:40'`
298
- - `number`: Usage, `validations='number'`
299
- - `integer`: Usage, `validations='integer'`
300
- - `alpha`: Usage, `validations='alpha'` - only alphabets
301
- - `alphanum`: Usage, `validations='alphanum'` - alphanumeric
302
- - `match`: Usage, `validations='match:<name-of-field-to-match>'`. For instance, this is examplified in our example with `password` and `confirm_password` fields
303
- - `min-length`: Usage, `validations='min-length:6'`
304
- - `max-length`: Usage, `validations='max-length:15'`
305
- - `max`: Usage, `validations='max:25'`
306
- - `max-file-size-mb`: Usage, `validations='max-file-size-mb:30'` - for file upload
367
+ - `required`: Usage, `validations:['required']`
368
+ - `email`: Usage, `validations:['email']`
369
+ - `url`: Usage, `validations:['url']`
370
+ - `ip`: Usage, `validations:['ip']`
371
+ - `len:<number>`: Usage, `validations:['len:40']`
372
+ - `number`: Usage, `validations:['number']`
373
+ - `integer`: Usage, `validations:['integer']`
374
+ - `alpha`: Usage, `validations:['alpha']` - only alphabets
375
+ - `alphanum`: Usage, `validations:['alphanum']` - alphanumeric
376
+ - `match:<input-id>`: Usage, `validations:['match:<id-of-field-to-match>']`. For instance, this is examplified in our example with `password` and `confirm_password` fields
377
+ - `minlen:<number>`: Usage, `validations:['minlen:6']`
378
+ - `maxlen:<number>`: Usage, `validations:['maxlen:15']`
379
+ - `max:<number>`: Usage, `validations:['max:25']`
380
+ - `file-size-mb:<number>`: Usage, `validations:['file-size-mb:30']` - for file upload
307
381
 
308
382
  Every validation listed above also comes with a very good default error message.
309
383
 
310
- Finally, the validations can be combined to form a complex graph of validations based on use cases by separating each validation rule with a `pipe`, `|`. For instance, a required field that also should be an email field could be validated thus:
384
+ Finally, the validations can be combined to form a complex graph of validations based on use cases by combining them in a single array of validations. For instance, a required field that also should be an email field could be configured thus:
311
385
 
312
386
  ```html
313
387
  <input
314
388
  type="text"
315
389
  name="email_account"
316
390
  id="email_account"
317
- data-validations="required|email"
318
- use:form
391
+ use:form={{
392
+ validations:['required','email']
393
+ }}
319
394
  />
320
395
  ```
321
396
 
322
- # TODO
397
+ # Overriding validators
398
+ Validators could be overriden to provide custom validation and/or messages besides the default ones. For instance, let us overide the `len` validation rule. Every non-empty string/message returned from a validator's call becomes the error to be displayed to the user; and it shows up in the `errors` keyed by the field name.
399
+
400
+ ### Approach 1
401
+ ```ts
402
+ <script>
403
+ import uForm, { type FieldProps } from "@steveesamson/microform";
404
+ // default form data, probably passed as props
405
+ export let defaultData:any = {};
406
+
407
+ // Instatiate microform
408
+ const { form, values, errors, submit, sanity } = uForm({
409
+ // Set default form data
410
+ data:{...defaultData},
411
+ // Set a global event for validation, can be overriden on a each field.
412
+ // Possible values: blur, change, input, keyup
413
+ options:{
414
+ // Default event that triggers validation
415
+ validateEvent:'blur',
416
+ // Configure validators here
417
+ validators:{
418
+ len:({name, label, parts}:FieldProps) =>{
419
+ if (!parts || parts.length < 2) {
420
+ return `${label}: length validation requires length.`;
421
+ }
422
+ const extra = parts[1].trim();
423
+ return !!value && value.length !== parseInt(parts[1], 10) ? `${label} must exactly be ${extra} characters long.` : "";
424
+ }
425
+ }
426
+ }
427
+ });
428
+ </script>
429
+ ```
430
+ Instead of using the literal validation keys like `len`, `required` etc., while overriding validators, the exported key namee could be used. The key names are:
431
+ - IS_REQUIRED = `required`
432
+ - IS_EMAIL = `email`
433
+ - IS_URL = `url`
434
+ - IS_IP = `ip`
435
+ - IS_INTEGER = `integer`
436
+ - IS_NUMBER = `number`
437
+ - IS_ALPHA = `alpha`
438
+ - IS_ALPHANUM = `alphanum`
439
+ - IS_MIN_LEN = `minlen`
440
+ - IS_MAX_LEN = `maxlen`
441
+ - IS_LEN = `len`
442
+ - IS_MIN = `min`
443
+ - IS_MAX = `max`
444
+ - IT_MATCHES = `match`
445
+ - IS_FILE_SIZE_MB = `file-size-mb`
446
+
447
+ Therefore, the following is equivalent to the configuration in `Approach 1`:
448
+
449
+ ### Approach 2
450
+ ```ts
451
+ <script>
452
+ import uForm, { type FieldProps, IS_LEN } from "@steveesamson/microform";
453
+ // default form data, probably passed as props
454
+ export let defaultData:any = {};
455
+
456
+ // Instatiate microform
457
+ const { form, values, errors, submit, sanity } = uForm({
458
+ // Set default form data
459
+ data:{...defaultData},
460
+ // Set a global event for validation, can be overriden on a each field.
461
+ // Possible values: blur, change, input, keyup
462
+ options:{
463
+ // Default event that triggers validation
464
+ validateEvent:'blur',
465
+ // Configure validators here
466
+ validators:{
467
+ [IS_LEN]:({name, label, parts}:FieldProps) =>{
468
+ if (!parts || parts.length < 2) {
469
+ return `${label}: length validation requires length.`;
470
+ }
471
+ const extra = parts[1].trim();
472
+ return !!value && value.length !== parseInt(parts[1], 10) ? `${label} must exactly be ${extra} characters long.` : "";
473
+ }
474
+ }
475
+ }
476
+ });
477
+ </script>
478
+ ```
323
479
 
324
- I shall be working on how to allow users register their `validators` and `error messages` for the purpose of customisation.
480
+ The validation will be used on the view as below:
481
+
482
+ ```html
483
+ <input
484
+ type="text"
485
+ name="comment"
486
+ id="comment"
487
+ use:form={{
488
+ validations:['required','len:30']
489
+ }}
490
+ />
491
+ ```
@@ -1,4 +1,5 @@
1
1
  /// <reference types="svelte" />
2
2
  import { type Writable } from "svelte/store";
3
- import type { FormErrors, FormOptions, FormValues, Params, FormAction } from "./types.js";
4
- export declare const formAction: (values: FormValues, errors: FormErrors, unfits: Writable<Params>, isdirty: Writable<boolean>, options: FormOptions, validationMap: Params) => FormAction;
3
+ import type { FormOptions, FormAction } from "./types.js";
4
+ import type { Params } from "./internal.js";
5
+ export declare const formAction: (values: Writable<Params>, errors: Writable<Params>, unfits: Writable<Params>, isdirty: Writable<boolean>, options: FormOptions, validationMap: Params) => FormAction;
@@ -7,22 +7,34 @@ const isField = (node) => {
7
7
  node instanceof HTMLTextAreaElement;
8
8
  };
9
9
  const isExcluded = (node) => {
10
- return node instanceof HTMLInputElement && ['radio', 'checkbox', 'file'].includes(node.type.toLowerCase());
10
+ return node instanceof HTMLInputElement && ['radio', 'checkbox'].includes(node.type.toLowerCase());
11
11
  };
12
- const checkFormFitness = (values, unfits, validationMap) => {
13
- const validate = useValidator(unfits, values);
12
+ const isCheckbox = (node) => {
13
+ return node instanceof HTMLInputElement && ['checkbox'].includes(node.type.toLowerCase());
14
+ };
15
+ const isRadio = (node) => {
16
+ return node instanceof HTMLInputElement && ['radio'].includes(node.type.toLowerCase());
17
+ };
18
+ const checkFormFitness = (values, validationMap, validate) => {
14
19
  const _values = get(values);
15
20
  for (const [name, { validations }] of Object.entries(validationMap)) {
16
21
  validate({ name, value: _values[name], validations, });
17
22
  }
18
23
  };
19
24
  export const formAction = (values, errors, unfits, isdirty, options, validationMap) => {
20
- const validate = useValidator(errors, values);
25
+ const { validators: customValidators } = options;
26
+ const { validate, validators } = useValidator(errors, values);
27
+ // override
28
+ if (customValidators) {
29
+ for (const [key, val] of Object.entries(customValidators)) {
30
+ validators[key] = val;
31
+ }
32
+ }
21
33
  return (node, eventProps) => {
22
34
  const nodeName = isField(node) ? node.name : '';
23
- const { name: dsname = nodeName, validations: dsvalidations = '' } = node.dataset || {};
24
- const { name = dsname, validations = dsvalidations, validateEvent = options.validateEvent, html = false } = eventProps || {};
25
- validationMap[name] = { validations, html, nodeRef: isField(node) ? false : node };
35
+ const { name: dsname = nodeName } = node.dataset || {};
36
+ const { name = dsname, validations = [], validateEvent = options.validateEvent = 'blur', html = false } = eventProps || {};
37
+ validationMap[name] = { validations, html, nodeRef: node };
26
38
  const storedValue = get(values)[name] || '';
27
39
  let defValue = storedValue;
28
40
  if (isField(node) && !isExcluded(node)) {
@@ -55,7 +67,28 @@ export const formAction = (values, errors, unfits, isdirty, options, validationM
55
67
  return { ...data, [name]: htm, [`${name}-text`]: text };
56
68
  });
57
69
  }
58
- checkFormFitness(values, unfits, validationMap);
70
+ else if (isCheckbox(node)) {
71
+ const { checked, value: val } = node;
72
+ const { [name]: fieldValue } = get(values);
73
+ let current = fieldValue;
74
+ if (checked) {
75
+ current.push(val);
76
+ }
77
+ else {
78
+ current = current.filter((next) => next !== val);
79
+ }
80
+ values.update((data) => {
81
+ return { ...data, [name]: [...new Set(current)] };
82
+ });
83
+ }
84
+ else if (isRadio(node)) {
85
+ const { value: fvalue } = node;
86
+ values.update((data) => {
87
+ return { ...data, [name]: fvalue };
88
+ });
89
+ }
90
+ const { validate: validateUnfit } = useValidator(unfits, values, validators);
91
+ checkFormFitness(values, validationMap, validateUnfit);
59
92
  isdirty.set(true);
60
93
  };
61
94
  node.addEventListener(validateEvent, updateNode);
@@ -1,2 +1,23 @@
1
- import type { FormErrors, FormValues, ValidateArgs } from "./types.js";
2
- export declare const useValidator: (errors: FormErrors, values: FormValues) => ({ name, value, validations, node }: ValidateArgs) => Promise<void>;
1
+ /// <reference types="svelte" />
2
+ import { type Writable } from "svelte/store";
3
+ import type { ValidateArgs, ValidatorType, ValidatorMap } from "./types.js";
4
+ import type { Params } from "./internal.js";
5
+ export declare const IS_REQUIRED = "required";
6
+ export declare const IS_EMAIL = "email";
7
+ export declare const IS_URL = "url";
8
+ export declare const IS_IP = "ip";
9
+ export declare const IS_INTEGER = "integer";
10
+ export declare const IS_NUMBER = "number";
11
+ export declare const IS_ALPHA = "alpha";
12
+ export declare const IS_ALPHANUM = "alphanum";
13
+ export declare const IS_MIN_LEN = "minlen";
14
+ export declare const IS_MAX_LEN = "maxlen";
15
+ export declare const IS_LEN = "len";
16
+ export declare const IS_MIN = "min";
17
+ export declare const IS_MAX = "max";
18
+ export declare const IT_MATCHES = "match";
19
+ export declare const IS_FILE_SIZE_MB = "file-size-mb";
20
+ export declare const useValidator: (errors: Writable<Params>, values: Writable<Params>, validators?: ValidatorMap<ValidatorType>) => {
21
+ validate: ({ name, value, validations, node }: ValidateArgs) => Promise<void>;
22
+ validators: ValidatorMap<ValidatorType>;
23
+ };