vanilla-jui 1.5.12 → 1.5.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-jui",
3
- "version": "1.5.12",
3
+ "version": "1.5.13",
4
4
  "private": false,
5
5
  "description": "A lightweight, reactive, and fully customizable vanilla JS UI library.",
6
6
  "keywords": [
@@ -23,7 +23,10 @@ import {
23
23
  resolveProps,
24
24
  validateParam,
25
25
  } from '../utilities/types.ts';
26
- import { createValidator } from '../validation/validator.ts';
26
+ import {
27
+ createValidator,
28
+ type ValidatorClassNameConfig,
29
+ } from '../validation/validator.ts';
27
30
  import { createLoading } from '../primitives/loading.ts';
28
31
  import { t } from 'vanilla-signal-i18n';
29
32
  import locales from '../locales/index.ts';
@@ -137,6 +140,7 @@ export interface FormValidatorConfig {
137
140
  rules?: Record<string, Record<string, unknown>>;
138
141
  messages?: Record<string, Record<string, string>>;
139
142
  vanilla?: boolean;
143
+ className?: ValidatorClassNameConfig;
140
144
  onSubmit?: (() => void) | null;
141
145
  [key: string]: unknown;
142
146
  }
@@ -640,6 +644,7 @@ export function createForm(input: FormProps = {}): Form {
640
644
  if (!element) return;
641
645
  for (const control of Array.from(element.elements)) {
642
646
  control.classList.remove('is-valid', 'is-invalid');
647
+ control.removeAttribute('data-valid');
643
648
  }
644
649
  for (const help of all<HTMLElement>(
645
650
  '[data-field-help], [data-validator-help]',
@@ -31,7 +31,7 @@
31
31
  margin: var(--content-heading-space) 0
32
32
  calc(var(--content-heading-space) * 0.75);
33
33
  font-weight: 600;
34
- line-height: 1.3;
34
+ /* line-height: 1.3; */
35
35
  color: var(--content-heading-fg);
36
36
  letter-spacing: -0.02em;
37
37
  }
@@ -46,7 +46,7 @@
46
46
  .j-content h2 {
47
47
  font-size: 1.625em;
48
48
  font-weight: 650;
49
- padding-bottom: 0.5em;
49
+ padding-bottom: 0.25em;
50
50
  border-bottom: 1px solid var(--content-border-subtle);
51
51
  }
52
52
 
@@ -458,9 +458,15 @@
458
458
  .hljs-comment,
459
459
  .hljs-code,
460
460
  .hljs-formula {
461
- color: var(--ui-gray-shade);
461
+ color: var(--ui-fg-soft);
462
462
  }
463
463
 
464
+ /* .dark .hljs-comment,
465
+ .dark .hljs-code,
466
+ .dark .hljs-formula {
467
+ color: var(--ui-gray-shade);
468
+ } */
469
+
464
470
  /* prettylights-syntax-entity-tag */
465
471
  .hljs-name,
466
472
  .hljs-quote,
package/src/css/form.css CHANGED
@@ -70,7 +70,7 @@
70
70
  margin: 0;
71
71
  }
72
72
 
73
- .j-form .form-field .field-control .help-block.is-invalid {
73
+ .j-form .form-field .field-control .help-block[data-valid='false'] {
74
74
  color: var(--state-danger);
75
75
  }
76
76
 
@@ -188,12 +188,12 @@
188
188
  }
189
189
 
190
190
  /* input validate */
191
- /* .j-input.is-valid,
192
- .j-select.is-valid,
193
- .j-textarea.is-valid,
194
- .j-input.is-invalid,
195
- .j-select.is-invalid,
196
- .j-textarea.is-invalid {
191
+ /* .j-input[data-valid='true'],
192
+ .j-select[data-valid='true'],
193
+ .j-textarea[data-valid='true'],
194
+ .j-input[data-valid='false'],
195
+ .j-select[data-valid='false'],
196
+ .j-textarea[data-valid='false'] {
197
197
  padding-right: calc(1.4285714286em + 0.875rem);
198
198
  background-repeat: no-repeat;
199
199
  background-position: right calc(0.3571428572em + 0.21875rem) center;
@@ -201,16 +201,16 @@
201
201
  calc(0.7142857143em + 0.4375rem);
202
202
  } */
203
203
 
204
- /* .j-input.is-valid,
205
- .j-select.is-valid,
206
- .j-textarea.is-valid {
204
+ /* .j-input[data-valid='true'],
205
+ .j-select[data-valid='true'],
206
+ .j-textarea[data-valid='true'] {
207
207
  border-color: var(--form-valid-border-color, var(--state-success));
208
208
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232fb344' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='20 6 9 17 4 12'%3e%3c/polyline%3e%3c/svg%3e");
209
209
  } */
210
210
 
211
- .j-input.is-invalid,
212
- .j-select.is-invalid,
213
- .j-textarea.is-invalid {
211
+ .j-input[data-valid='false'],
212
+ .j-select[data-valid='false'],
213
+ .j-textarea[data-valid='false'] {
214
214
  border-color: var(--form-invalid-border-color, var(--state-danger));
215
215
  /* background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23d63939' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='18' y1='6' x2='6' y2='18'%3e%3c/line%3e%3cline x1='6' y1='6' x2='18' y2='18'%3e%3c/line%3e%3c/svg%3e"); */
216
216
  }
@@ -861,14 +861,14 @@
861
861
  box-shadow: var(--input-focus-shadow, none);
862
862
  }
863
863
 
864
- /* .j-input.is-valid:focus-within,
865
- .j-select.is-valid:focus-within {
864
+ /* .j-input[data-valid='true']:focus-within,
865
+ .j-select[data-valid='true']:focus-within {
866
866
  border-color: transparent;
867
867
  outline-color: var(--form-valid-border-color, var(--state-success));
868
868
  } */
869
869
 
870
- .j-input.is-invalid:focus-within,
871
- .j-select.is-invalid:focus-within {
870
+ .j-input[data-valid='false']:focus-within,
871
+ .j-select[data-valid='false']:focus-within {
872
872
  border-color: transparent;
873
873
  outline-color: var(--form-invalid-border-color, var(--state-danger));
874
874
  }
@@ -15,11 +15,11 @@
15
15
  --z-badge: 2;
16
16
  --z-toolbar: 2;
17
17
  --z-submenu: 5;
18
+ --z-overlay: 9500;
19
+ --z-offcanvas: 9600;
20
+ --z-popup: 9700;
21
+ --z-toast: 9800;
18
22
  --z-drop: 9900;
19
- --z-overlay: 9950;
20
- --z-offcanvas: 9960;
21
- --z-popup: 9970;
22
- --z-toast: 9980;
23
23
 
24
24
  /* --- Spacing --- */
25
25
  --space: 0.25rem;
@@ -317,7 +317,7 @@
317
317
  --ui-disabled-fg: #64748b;
318
318
  --ui-overlay: rgba(2, 6, 23, 0.7);
319
319
  --ui-overlay-muted: rgba(2, 6, 23, 0.45);
320
- --ui-popup-bg: rgba(17, 24, 39, 0.82);
320
+ --ui-popup-bg: rgba(17, 24, 39, 0.45);
321
321
  --ui-input-color: #f9fafb;
322
322
  --ui-input-border: rgba(148, 163, 184, 0.2);
323
323
  --ui-input-focus-border: #a78bfa;
@@ -1,7 +1,9 @@
1
1
  import { jsx } from 'vanilla-signal';
2
2
 
3
+ import { joinClasses } from '../utilities/class-name.ts';
3
4
  import { type DOMReference, all, resolveElement } from '../utilities/dom.ts';
4
5
  import { createEventManager } from '../utilities/events.ts';
6
+ import { isPlainObject } from '../utilities/object.ts';
5
7
  import {
6
8
  type ResolveSchema,
7
9
  resolveProps,
@@ -45,13 +47,21 @@ interface ValidatorProps extends Record<string, unknown> {
45
47
  rules?: Record<string, ValidatorRule>;
46
48
  messages?: ValidatorMessageMap;
47
49
  vanilla?: boolean;
50
+ className?: ValidatorClassNameConfig;
48
51
  onSubmit?: ((validator: ValidatorInstance) => void) | null;
49
52
  }
50
53
 
54
+ export interface ValidatorClassNames {
55
+ help: string;
56
+ }
57
+
58
+ export type ValidatorClassNameConfig = Partial<ValidatorClassNames>;
59
+
51
60
  interface ResolvedValidatorProps extends Record<string, unknown> {
52
61
  rules: Record<string, ValidatorRule>;
53
62
  messages: ValidatorMessageMap;
54
63
  vanilla: boolean;
64
+ className: ValidatorClassNames;
55
65
  onSubmit: ((validator: ValidatorInstance) => void) | null;
56
66
  }
57
67
 
@@ -75,19 +85,36 @@ export interface ValidatorInstance {
75
85
  destroy(): void;
76
86
  }
77
87
 
88
+ const DEFAULT_CLASS_NAMES: ValidatorClassNames = {
89
+ help: 'help-block',
90
+ };
91
+
78
92
  const VALIDATOR_PROPS_SCHEMA = {
79
93
  rules: { default: {}, type: 'object' },
80
94
  messages: { default: {}, type: 'object' },
81
95
  vanilla: { default: false, type: 'boolean' },
96
+ className: {
97
+ default: DEFAULT_CLASS_NAMES,
98
+ type: 'object',
99
+ normalize: (value: unknown) => resolveClassNames(value),
100
+ },
82
101
  onSubmit: { default: null, types: ['function', 'null'] },
83
102
  } satisfies ResolveSchema<ValidatorProps>;
84
103
 
104
+ function resolveClassNames(value: unknown): ValidatorClassNames {
105
+ return {
106
+ ...DEFAULT_CLASS_NAMES,
107
+ ...(isPlainObject(value) ? (value as ValidatorClassNameConfig) : {}),
108
+ } as ValidatorClassNames;
109
+ }
110
+
85
111
  function normalizeProps(input: ValidatorProps): ResolvedValidatorProps {
86
112
  const props = resolveProps(input, VALIDATOR_PROPS_SCHEMA, 'Validator.props');
87
113
  return {
88
114
  rules: props.rules as Record<string, ValidatorRule>,
89
115
  messages: props.messages as ValidatorMessageMap,
90
116
  vanilla: props.vanilla as boolean,
117
+ className: props.className as ValidatorClassNames,
91
118
  onSubmit: props.onSubmit as ResolvedValidatorProps['onSubmit'],
92
119
  };
93
120
  }
@@ -353,10 +380,7 @@ function showError(
353
380
  rule: string,
354
381
  customMessage = ''
355
382
  ): void {
356
- if (!(element instanceof HTMLInputElement) || element.type !== 'checkbox') {
357
- element.classList.remove('is-valid');
358
- element.classList.add('is-invalid');
359
- }
383
+ element.dataset.valid = 'false';
360
384
 
361
385
  const error = customMessage || props?.messages[name]?.[rule] || '';
362
386
  if (!error) return;
@@ -372,11 +396,13 @@ function showError(
372
396
  ) || null;
373
397
  if (!help) {
374
398
  help = jsx('div', {
375
- className: 'help-block is-invalid',
399
+ 'data-valid': 'false',
376
400
  'data-validator-help': name,
377
401
  }) as HTMLElement;
378
402
  formControl.appendChild(help);
379
403
  }
404
+ help.className = joinClasses(props?.className.help);
405
+ help.dataset.valid = 'false';
380
406
  help.textContent = error;
381
407
  }
382
408
 
@@ -388,9 +414,7 @@ function showSuccess(element: ValidatorElement): void {
388
414
  }
389
415
  }
390
416
 
391
- if (!(element instanceof HTMLInputElement) || element.type !== 'checkbox') {
392
- element.classList.remove('is-invalid');
393
- }
417
+ element.removeAttribute('data-valid');
394
418
  }
395
419
 
396
420
  export function createValidator(
@@ -543,7 +567,7 @@ export function createValidator(
543
567
  if (native) root.reset();
544
568
  for (const control of Array.from(root.elements)) {
545
569
  if (isValidatorElement(control)) {
546
- control.classList.remove('is-valid', 'is-invalid');
570
+ control.removeAttribute('data-valid');
547
571
  }
548
572
  }
549
573
  for (const help of all<HTMLElement>('[data-validator-help]', root)) {