@melodicdev/components 1.5.12 → 1.6.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/assets/melodic-components.js +1168 -451
- package/assets/melodic-components.js.map +1 -1
- package/assets/melodic-components.min.js +2480 -1814
- package/lib/components/data-display/badge/badge.styles.d.ts.map +1 -1
- package/lib/components/data-display/badge/badge.styles.js +11 -0
- package/lib/components/forms/autocomplete/autocomplete.component.d.ts.map +1 -1
- package/lib/components/forms/autocomplete/autocomplete.component.js +17 -0
- package/lib/components/forms/checkbox/checkbox.component.d.ts.map +1 -1
- package/lib/components/forms/checkbox/checkbox.component.js +8 -0
- package/lib/components/forms/date-picker/calendar.component.d.ts +48 -0
- package/lib/components/forms/date-picker/calendar.component.d.ts.map +1 -1
- package/lib/components/forms/date-picker/calendar.component.js +231 -3
- package/lib/components/forms/date-picker/calendar.styles.d.ts.map +1 -1
- package/lib/components/forms/date-picker/calendar.styles.js +104 -2
- package/lib/components/forms/date-picker/calendar.template.d.ts.map +1 -1
- package/lib/components/forms/date-picker/calendar.template.js +128 -39
- package/lib/components/forms/date-picker/date-picker.component.d.ts +4 -0
- package/lib/components/forms/date-picker/date-picker.component.d.ts.map +1 -1
- package/lib/components/forms/date-picker/date-picker.component.js +13 -1
- package/lib/components/forms/date-picker/date-picker.template.d.ts.map +1 -1
- package/lib/components/forms/date-picker/date-picker.template.js +2 -0
- package/lib/components/forms/date-time-picker/date-time-picker.component.d.ts.map +1 -1
- package/lib/components/forms/date-time-picker/date-time-picker.component.js +8 -0
- package/lib/components/forms/input/input.component.d.ts.map +1 -1
- package/lib/components/forms/input/input.component.js +8 -0
- package/lib/components/forms/radio/radio-group.component.d.ts.map +1 -1
- package/lib/components/forms/radio/radio-group.component.js +8 -0
- package/lib/components/forms/select/select.component.d.ts.map +1 -1
- package/lib/components/forms/select/select.component.js +17 -0
- package/lib/components/forms/slider/slider.component.d.ts.map +1 -1
- package/lib/components/forms/slider/slider.component.js +8 -0
- package/lib/components/forms/textarea/textarea.component.d.ts.map +1 -1
- package/lib/components/forms/textarea/textarea.component.js +8 -0
- package/lib/components/forms/time-picker/time-picker.component.d.ts.map +1 -1
- package/lib/components/forms/time-picker/time-picker.component.js +8 -0
- package/lib/components/forms/toggle/toggle.component.d.ts.map +1 -1
- package/lib/components/forms/toggle/toggle.component.js +8 -0
- package/lib/forms-adapters.d.ts +2 -0
- package/lib/forms-adapters.d.ts.map +1 -0
- package/lib/forms-adapters.js +105 -0
- package/package.json +1 -1
|
@@ -315,6 +315,292 @@ var cacheCssSheet = (text) => {
|
|
|
315
315
|
var hasCachedSheets = () => {
|
|
316
316
|
return cachedCssSheets.length > 0;
|
|
317
317
|
};
|
|
318
|
+
var activeEffect = null;
|
|
319
|
+
const setActiveEffect = (effect) => {
|
|
320
|
+
activeEffect = effect;
|
|
321
|
+
};
|
|
322
|
+
const getActiveEffect = () => activeEffect;
|
|
323
|
+
var SignalEffect = class {
|
|
324
|
+
constructor(execute) {
|
|
325
|
+
this.execute = execute;
|
|
326
|
+
this._dependencies = /* @__PURE__ */ new Set();
|
|
327
|
+
this._isRunning = false;
|
|
328
|
+
this._needsRerun = false;
|
|
329
|
+
this.run = () => {
|
|
330
|
+
if (this._isRunning) {
|
|
331
|
+
this._needsRerun = true;
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
this._isRunning = true;
|
|
335
|
+
do {
|
|
336
|
+
this._needsRerun = false;
|
|
337
|
+
this._dependencies.forEach((signal$1) => {
|
|
338
|
+
signal$1.unsubscribe(this.run);
|
|
339
|
+
});
|
|
340
|
+
this._dependencies.clear();
|
|
341
|
+
const prevEffect = getActiveEffect();
|
|
342
|
+
setActiveEffect(this);
|
|
343
|
+
this.execute();
|
|
344
|
+
setActiveEffect(prevEffect);
|
|
345
|
+
} while (this._needsRerun);
|
|
346
|
+
this._isRunning = false;
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
addDependency(signal$1) {
|
|
350
|
+
this._dependencies.add(signal$1);
|
|
351
|
+
}
|
|
352
|
+
destroy() {
|
|
353
|
+
this._dependencies.forEach((signal$1) => {
|
|
354
|
+
signal$1.unsubscribe(this.run);
|
|
355
|
+
});
|
|
356
|
+
this._dependencies.clear();
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
function signal(initialValue) {
|
|
360
|
+
let value = initialValue;
|
|
361
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
362
|
+
const notify = () => {
|
|
363
|
+
[...subscribers].forEach((subscriber) => subscriber(value));
|
|
364
|
+
};
|
|
365
|
+
const read = (() => {
|
|
366
|
+
const activeEffect$1 = getActiveEffect();
|
|
367
|
+
if (activeEffect$1) {
|
|
368
|
+
activeEffect$1.addDependency(read);
|
|
369
|
+
subscribers.add(activeEffect$1.run);
|
|
370
|
+
}
|
|
371
|
+
return value;
|
|
372
|
+
});
|
|
373
|
+
read.set = (newValue) => {
|
|
374
|
+
if (value !== newValue) {
|
|
375
|
+
value = newValue;
|
|
376
|
+
notify();
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
read.update = (updater) => {
|
|
380
|
+
read.set(updater(value));
|
|
381
|
+
};
|
|
382
|
+
read.subscribe = (subscriber) => {
|
|
383
|
+
subscribers.add(subscriber);
|
|
384
|
+
return () => subscribers.delete(subscriber);
|
|
385
|
+
};
|
|
386
|
+
read.unsubscribe = (subscriber) => {
|
|
387
|
+
subscribers.delete(subscriber);
|
|
388
|
+
};
|
|
389
|
+
read.destroy = () => {
|
|
390
|
+
subscribers.clear();
|
|
391
|
+
};
|
|
392
|
+
Object.defineProperty(read, SIGNAL_MARKER, {
|
|
393
|
+
value: true,
|
|
394
|
+
enumerable: false,
|
|
395
|
+
configurable: false
|
|
396
|
+
});
|
|
397
|
+
return read;
|
|
398
|
+
}
|
|
399
|
+
function computed(computation) {
|
|
400
|
+
const computedSignal = signal(void 0);
|
|
401
|
+
const effect = new SignalEffect(() => {
|
|
402
|
+
computedSignal.set(computation());
|
|
403
|
+
});
|
|
404
|
+
effect.run();
|
|
405
|
+
const originalDestroy = computedSignal.destroy;
|
|
406
|
+
computedSignal.destroy = () => {
|
|
407
|
+
effect.destroy();
|
|
408
|
+
originalDestroy();
|
|
409
|
+
};
|
|
410
|
+
return computedSignal;
|
|
411
|
+
}
|
|
412
|
+
var globalMessages = {};
|
|
413
|
+
function registerDefaultMessages(messages) {
|
|
414
|
+
for (const code of Object.keys(messages)) globalMessages[code] = messages[code];
|
|
415
|
+
}
|
|
416
|
+
function setDefaultMessage(code, message) {
|
|
417
|
+
globalMessages[code] = message;
|
|
418
|
+
}
|
|
419
|
+
function getGlobalMessage(code) {
|
|
420
|
+
return globalMessages[code];
|
|
421
|
+
}
|
|
422
|
+
function resolveMessage(message, params) {
|
|
423
|
+
if (typeof message === "function") return message(params ?? {});
|
|
424
|
+
return message;
|
|
425
|
+
}
|
|
426
|
+
var AbstractControl = class {
|
|
427
|
+
constructor(initialValue, options = {}) {
|
|
428
|
+
this.parent = null;
|
|
429
|
+
this._validators = [];
|
|
430
|
+
this._asyncValidators = [];
|
|
431
|
+
this._touched = signal(false);
|
|
432
|
+
this._dirty = signal(false);
|
|
433
|
+
this._pending = signal(false);
|
|
434
|
+
this._ownDisabled = signal(false);
|
|
435
|
+
this._asyncValidationId = 0;
|
|
436
|
+
this.value = signal(initialValue);
|
|
437
|
+
this.errors = signal(null);
|
|
438
|
+
this._validators = options.validators ?? [];
|
|
439
|
+
this._asyncValidators = options.asyncValidators ?? [];
|
|
440
|
+
this._ownDisabled.set(options.disabled ?? false);
|
|
441
|
+
this.updateOn = options.updateOn ?? "change";
|
|
442
|
+
this.messages = options.messages ?? {};
|
|
443
|
+
}
|
|
444
|
+
initializeAggregates() {
|
|
445
|
+
this.dirty = computed(() => this.computeDirty());
|
|
446
|
+
this.touched = computed(() => this.computeTouched());
|
|
447
|
+
this.pending = computed(() => this.computePending());
|
|
448
|
+
this.disabled = computed(() => this.computeDisabled());
|
|
449
|
+
this.pristine = computed(() => !this.dirty());
|
|
450
|
+
this.untouched = computed(() => !this.touched());
|
|
451
|
+
this.enabled = computed(() => !this.disabled());
|
|
452
|
+
this.invalid = computed(() => this.errors() !== null || this.hasInvalidChild());
|
|
453
|
+
this.valid = computed(() => !this.invalid() && !this.pending());
|
|
454
|
+
this.state = computed(() => ({
|
|
455
|
+
dirty: this.dirty(),
|
|
456
|
+
touched: this.touched(),
|
|
457
|
+
pristine: !this.dirty(),
|
|
458
|
+
untouched: !this.touched(),
|
|
459
|
+
valid: !this.invalid() && !this.pending(),
|
|
460
|
+
invalid: this.invalid(),
|
|
461
|
+
pending: this.pending(),
|
|
462
|
+
disabled: this.disabled(),
|
|
463
|
+
enabled: !this.disabled()
|
|
464
|
+
}));
|
|
465
|
+
}
|
|
466
|
+
markAsTouched() {
|
|
467
|
+
this._touched.set(true);
|
|
468
|
+
if (this.updateOn === "blur") this.runValidation();
|
|
469
|
+
}
|
|
470
|
+
markAsUntouched() {
|
|
471
|
+
this._touched.set(false);
|
|
472
|
+
}
|
|
473
|
+
markAsDirty() {
|
|
474
|
+
this._dirty.set(true);
|
|
475
|
+
}
|
|
476
|
+
markAsPristine() {
|
|
477
|
+
this._dirty.set(false);
|
|
478
|
+
}
|
|
479
|
+
markAllAsTouched() {
|
|
480
|
+
this.markAsTouched();
|
|
481
|
+
}
|
|
482
|
+
markAllAsUntouched() {
|
|
483
|
+
this.markAsUntouched();
|
|
484
|
+
}
|
|
485
|
+
disable() {
|
|
486
|
+
this._ownDisabled.set(true);
|
|
487
|
+
}
|
|
488
|
+
enable() {
|
|
489
|
+
this._ownDisabled.set(false);
|
|
490
|
+
}
|
|
491
|
+
setValidators(validators) {
|
|
492
|
+
this._validators = validators;
|
|
493
|
+
this.runValidation();
|
|
494
|
+
}
|
|
495
|
+
addValidators(validators) {
|
|
496
|
+
this._validators = [...this._validators, ...validators];
|
|
497
|
+
this.runValidation();
|
|
498
|
+
}
|
|
499
|
+
removeValidators(validators) {
|
|
500
|
+
this._validators = this._validators.filter((v) => !validators.includes(v));
|
|
501
|
+
this.runValidation();
|
|
502
|
+
}
|
|
503
|
+
setAsyncValidators(validators) {
|
|
504
|
+
this._asyncValidators = validators;
|
|
505
|
+
this.runValidation();
|
|
506
|
+
}
|
|
507
|
+
async validate() {
|
|
508
|
+
await this.runValidation();
|
|
509
|
+
}
|
|
510
|
+
getError(code) {
|
|
511
|
+
return this.errors()?.[code] ?? null;
|
|
512
|
+
}
|
|
513
|
+
hasError(code) {
|
|
514
|
+
return this.errors()?.[code] !== void 0;
|
|
515
|
+
}
|
|
516
|
+
getErrorMessage(code) {
|
|
517
|
+
const error = this.getError(code);
|
|
518
|
+
if (!error) return "";
|
|
519
|
+
const params = error.params;
|
|
520
|
+
const localMessage = this.resolveFromChain(code);
|
|
521
|
+
if (localMessage !== void 0) return resolveMessage(localMessage, params);
|
|
522
|
+
const globalMessage = getGlobalMessage(code);
|
|
523
|
+
if (globalMessage !== void 0) return resolveMessage(globalMessage, params);
|
|
524
|
+
return code;
|
|
525
|
+
}
|
|
526
|
+
getFirstErrorMessage() {
|
|
527
|
+
const errors = this.errors();
|
|
528
|
+
if (!errors) return "";
|
|
529
|
+
const codes = Object.keys(errors);
|
|
530
|
+
if (codes.length === 0) return "";
|
|
531
|
+
return this.getErrorMessage(codes[0]);
|
|
532
|
+
}
|
|
533
|
+
resolveFromChain(code) {
|
|
534
|
+
let control = this;
|
|
535
|
+
while (control !== null) {
|
|
536
|
+
if (control.messages[code] !== void 0) return control.messages[code];
|
|
537
|
+
control = control.parent;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
async runValidation() {
|
|
541
|
+
const value = this.value();
|
|
542
|
+
let errors = null;
|
|
543
|
+
for (const validator of this._validators) {
|
|
544
|
+
const result = validator(value);
|
|
545
|
+
if (result !== null) errors = {
|
|
546
|
+
...errors ?? {},
|
|
547
|
+
...result
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
if (errors !== null) {
|
|
551
|
+
this.errors.set(errors);
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
if (this._asyncValidators.length > 0) {
|
|
555
|
+
const id = ++this._asyncValidationId;
|
|
556
|
+
this._pending.set(true);
|
|
557
|
+
try {
|
|
558
|
+
const results = await Promise.all(this._asyncValidators.map((v) => v(value)));
|
|
559
|
+
if (id !== this._asyncValidationId) return;
|
|
560
|
+
for (const result of results) if (result !== null) errors = {
|
|
561
|
+
...errors ?? {},
|
|
562
|
+
...result
|
|
563
|
+
};
|
|
564
|
+
} finally {
|
|
565
|
+
if (id === this._asyncValidationId) this._pending.set(false);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
this.errors.set(errors);
|
|
569
|
+
}
|
|
570
|
+
computeDirty() {
|
|
571
|
+
return this._dirty();
|
|
572
|
+
}
|
|
573
|
+
computeTouched() {
|
|
574
|
+
return this._touched();
|
|
575
|
+
}
|
|
576
|
+
computePending() {
|
|
577
|
+
return this._pending();
|
|
578
|
+
}
|
|
579
|
+
computeDisabled() {
|
|
580
|
+
return this._ownDisabled();
|
|
581
|
+
}
|
|
582
|
+
hasInvalidChild() {
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
destroySignals() {
|
|
586
|
+
this.value.destroy();
|
|
587
|
+
this.errors.destroy();
|
|
588
|
+
this._touched.destroy();
|
|
589
|
+
this._dirty.destroy();
|
|
590
|
+
this._pending.destroy();
|
|
591
|
+
this._ownDisabled.destroy();
|
|
592
|
+
this.dirty.destroy();
|
|
593
|
+
this.touched.destroy();
|
|
594
|
+
this.pristine.destroy();
|
|
595
|
+
this.untouched.destroy();
|
|
596
|
+
this.valid.destroy();
|
|
597
|
+
this.invalid.destroy();
|
|
598
|
+
this.pending.destroy();
|
|
599
|
+
this.disabled.destroy();
|
|
600
|
+
this.enabled.destroy();
|
|
601
|
+
this.state.destroy();
|
|
602
|
+
}
|
|
603
|
+
};
|
|
318
604
|
var ComponentBase = class extends HTMLElement {
|
|
319
605
|
constructor(meta, component) {
|
|
320
606
|
super();
|
|
@@ -400,6 +686,10 @@ var ComponentBase = class extends HTMLElement {
|
|
|
400
686
|
this.subscribeToSignal(value);
|
|
401
687
|
return false;
|
|
402
688
|
}
|
|
689
|
+
if (value instanceof AbstractControl) {
|
|
690
|
+
this.subscribeToSignal(value.state);
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
403
693
|
if (typeof value === "function") return false;
|
|
404
694
|
return prop !== "elementRef" && prop !== "constructor";
|
|
405
695
|
});
|
|
@@ -2439,100 +2729,6 @@ function routerLinkDirective(element, value, _) {
|
|
|
2439
2729
|
});
|
|
2440
2730
|
}
|
|
2441
2731
|
registerAttributeDirective("routerLink", routerLinkDirective);
|
|
2442
|
-
var activeEffect = null;
|
|
2443
|
-
const setActiveEffect = (effect) => {
|
|
2444
|
-
activeEffect = effect;
|
|
2445
|
-
};
|
|
2446
|
-
const getActiveEffect = () => activeEffect;
|
|
2447
|
-
var SignalEffect = class {
|
|
2448
|
-
constructor(execute) {
|
|
2449
|
-
this.execute = execute;
|
|
2450
|
-
this._dependencies = /* @__PURE__ */ new Set();
|
|
2451
|
-
this._isRunning = false;
|
|
2452
|
-
this._needsRerun = false;
|
|
2453
|
-
this.run = () => {
|
|
2454
|
-
if (this._isRunning) {
|
|
2455
|
-
this._needsRerun = true;
|
|
2456
|
-
return;
|
|
2457
|
-
}
|
|
2458
|
-
this._isRunning = true;
|
|
2459
|
-
do {
|
|
2460
|
-
this._needsRerun = false;
|
|
2461
|
-
this._dependencies.forEach((signal$1) => {
|
|
2462
|
-
signal$1.unsubscribe(this.run);
|
|
2463
|
-
});
|
|
2464
|
-
this._dependencies.clear();
|
|
2465
|
-
const prevEffect = getActiveEffect();
|
|
2466
|
-
setActiveEffect(this);
|
|
2467
|
-
this.execute();
|
|
2468
|
-
setActiveEffect(prevEffect);
|
|
2469
|
-
} while (this._needsRerun);
|
|
2470
|
-
this._isRunning = false;
|
|
2471
|
-
};
|
|
2472
|
-
}
|
|
2473
|
-
addDependency(signal$1) {
|
|
2474
|
-
this._dependencies.add(signal$1);
|
|
2475
|
-
}
|
|
2476
|
-
destroy() {
|
|
2477
|
-
this._dependencies.forEach((signal$1) => {
|
|
2478
|
-
signal$1.unsubscribe(this.run);
|
|
2479
|
-
});
|
|
2480
|
-
this._dependencies.clear();
|
|
2481
|
-
}
|
|
2482
|
-
};
|
|
2483
|
-
function signal(initialValue) {
|
|
2484
|
-
let value = initialValue;
|
|
2485
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
2486
|
-
const notify = () => {
|
|
2487
|
-
[...subscribers].forEach((subscriber) => subscriber(value));
|
|
2488
|
-
};
|
|
2489
|
-
const read = (() => {
|
|
2490
|
-
const activeEffect$1 = getActiveEffect();
|
|
2491
|
-
if (activeEffect$1) {
|
|
2492
|
-
activeEffect$1.addDependency(read);
|
|
2493
|
-
subscribers.add(activeEffect$1.run);
|
|
2494
|
-
}
|
|
2495
|
-
return value;
|
|
2496
|
-
});
|
|
2497
|
-
read.set = (newValue) => {
|
|
2498
|
-
if (value !== newValue) {
|
|
2499
|
-
value = newValue;
|
|
2500
|
-
notify();
|
|
2501
|
-
}
|
|
2502
|
-
};
|
|
2503
|
-
read.update = (updater) => {
|
|
2504
|
-
read.set(updater(value));
|
|
2505
|
-
};
|
|
2506
|
-
read.subscribe = (subscriber) => {
|
|
2507
|
-
subscribers.add(subscriber);
|
|
2508
|
-
return () => subscribers.delete(subscriber);
|
|
2509
|
-
};
|
|
2510
|
-
read.unsubscribe = (subscriber) => {
|
|
2511
|
-
subscribers.delete(subscriber);
|
|
2512
|
-
};
|
|
2513
|
-
read.destroy = () => {
|
|
2514
|
-
subscribers.clear();
|
|
2515
|
-
};
|
|
2516
|
-
Object.defineProperty(read, SIGNAL_MARKER, {
|
|
2517
|
-
value: true,
|
|
2518
|
-
enumerable: false,
|
|
2519
|
-
configurable: false
|
|
2520
|
-
});
|
|
2521
|
-
return read;
|
|
2522
|
-
}
|
|
2523
|
-
function computed(computation) {
|
|
2524
|
-
const computedSignal = signal(void 0);
|
|
2525
|
-
const effect = new SignalEffect(() => {
|
|
2526
|
-
computedSignal.set(computation());
|
|
2527
|
-
});
|
|
2528
|
-
effect.run();
|
|
2529
|
-
const originalDestroy = computedSignal.destroy;
|
|
2530
|
-
computedSignal.destroy = () => {
|
|
2531
|
-
effect.destroy();
|
|
2532
|
-
originalDestroy();
|
|
2533
|
-
};
|
|
2534
|
-
return computedSignal;
|
|
2535
|
-
}
|
|
2536
2732
|
const props = () => {
|
|
2537
2733
|
return () => ({});
|
|
2538
2734
|
};
|
|
@@ -3305,53 +3501,23 @@ var Directive = class {
|
|
|
3305
3501
|
this.__directive = true;
|
|
3306
3502
|
}
|
|
3307
3503
|
};
|
|
3308
|
-
|
|
3309
|
-
var FormControl = class {
|
|
3504
|
+
var FormControl = class extends AbstractControl {
|
|
3310
3505
|
constructor(initialValue, options = {}) {
|
|
3311
|
-
|
|
3312
|
-
this._validators = [];
|
|
3313
|
-
this._asyncValidators = [];
|
|
3314
|
-
this._touched = signal(false);
|
|
3315
|
-
this._dirty = signal(false);
|
|
3316
|
-
this._pending = signal(false);
|
|
3317
|
-
this._disabled = signal(false);
|
|
3318
|
-
this._asyncValidationId = 0;
|
|
3506
|
+
super(initialValue, options);
|
|
3319
3507
|
this.initialValue = initialValue;
|
|
3320
|
-
this.
|
|
3321
|
-
this.errors = signal(null);
|
|
3322
|
-
this._validators = options.validators ?? [];
|
|
3323
|
-
this._asyncValidators = options.asyncValidators ?? [];
|
|
3324
|
-
this._disabled.set(options.disabled ?? false);
|
|
3325
|
-
this.updateOn = options.updateOn ?? "input";
|
|
3326
|
-
this.dirty = computed(() => this._dirty());
|
|
3327
|
-
this.touched = computed(() => this._touched());
|
|
3328
|
-
this.pristine = computed(() => !this._dirty());
|
|
3329
|
-
this.pending = computed(() => this._pending());
|
|
3330
|
-
this.disabled = computed(() => this._disabled());
|
|
3331
|
-
this.valid = computed(() => this.errors() === null && !this._pending());
|
|
3332
|
-
this.invalid = computed(() => this.errors() !== null);
|
|
3333
|
-
this.state = computed(() => ({
|
|
3334
|
-
dirty: this._dirty(),
|
|
3335
|
-
touched: this._touched(),
|
|
3336
|
-
pristine: !this._dirty(),
|
|
3337
|
-
untouched: !this._touched(),
|
|
3338
|
-
valid: this.errors() === null && !this._pending(),
|
|
3339
|
-
invalid: this.errors() !== null,
|
|
3340
|
-
pending: this._pending(),
|
|
3341
|
-
disabled: this._disabled(),
|
|
3342
|
-
enabled: !this._disabled()
|
|
3343
|
-
}));
|
|
3508
|
+
this.initializeAggregates();
|
|
3344
3509
|
this.runValidation();
|
|
3345
3510
|
}
|
|
3346
3511
|
setValue(value) {
|
|
3347
|
-
if (this.
|
|
3512
|
+
if (this._ownDisabled()) return;
|
|
3348
3513
|
this.value.set(value);
|
|
3349
3514
|
this._dirty.set(true);
|
|
3350
|
-
if (this.updateOn === "
|
|
3515
|
+
if (this.updateOn === "change") this.runValidation();
|
|
3351
3516
|
}
|
|
3352
3517
|
patchValue(value) {
|
|
3353
|
-
|
|
3354
|
-
|
|
3518
|
+
const current = this.value();
|
|
3519
|
+
if (typeof current === "object" && current !== null && !Array.isArray(current)) this.setValue({
|
|
3520
|
+
...current,
|
|
3355
3521
|
...value
|
|
3356
3522
|
});
|
|
3357
3523
|
else this.setValue(value);
|
|
@@ -3363,244 +3529,246 @@ var FormControl = class {
|
|
|
3363
3529
|
this.errors.set(null);
|
|
3364
3530
|
this.runValidation();
|
|
3365
3531
|
}
|
|
3366
|
-
|
|
3532
|
+
destroy() {
|
|
3533
|
+
this.destroySignals();
|
|
3534
|
+
}
|
|
3535
|
+
};
|
|
3536
|
+
var FormGroup = class FormGroup extends AbstractControl {
|
|
3537
|
+
constructor(initialControls, options = {}) {
|
|
3538
|
+
super(FormGroup.computeValue(initialControls), options);
|
|
3539
|
+
this.controls = signal({ ...initialControls });
|
|
3540
|
+
for (const key of Object.keys(initialControls)) initialControls[key].parent = this;
|
|
3541
|
+
this.initializeAggregates();
|
|
3542
|
+
this._childValueEffect = new SignalEffect(() => {
|
|
3543
|
+
const controls = this.controls();
|
|
3544
|
+
for (const key of Object.keys(controls)) controls[key].value();
|
|
3545
|
+
this.value.set(FormGroup.computeValue(controls));
|
|
3546
|
+
this.runValidation();
|
|
3547
|
+
});
|
|
3548
|
+
this._childValueEffect.run();
|
|
3549
|
+
}
|
|
3550
|
+
get(name) {
|
|
3551
|
+
return this.controls()[name];
|
|
3552
|
+
}
|
|
3553
|
+
contains(name) {
|
|
3554
|
+
return name in this.controls();
|
|
3555
|
+
}
|
|
3556
|
+
addControl(name, control) {
|
|
3557
|
+
control.parent = this;
|
|
3558
|
+
this.controls.update((current) => ({
|
|
3559
|
+
...current,
|
|
3560
|
+
[name]: control
|
|
3561
|
+
}));
|
|
3562
|
+
}
|
|
3563
|
+
removeControl(name) {
|
|
3564
|
+
const control = this.controls()[name];
|
|
3565
|
+
if (!control) return;
|
|
3566
|
+
control.parent = null;
|
|
3567
|
+
control.destroy();
|
|
3568
|
+
this.controls.update((current) => {
|
|
3569
|
+
const next = { ...current };
|
|
3570
|
+
delete next[name];
|
|
3571
|
+
return next;
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3574
|
+
setValue(value) {
|
|
3575
|
+
if (this._ownDisabled()) return;
|
|
3576
|
+
const controls = this.controls();
|
|
3577
|
+
for (const key of Object.keys(value)) controls[key]?.setValue(value[key]);
|
|
3578
|
+
}
|
|
3579
|
+
patchValue(value) {
|
|
3580
|
+
if (this._ownDisabled()) return;
|
|
3581
|
+
const controls = this.controls();
|
|
3582
|
+
for (const key of Object.keys(value)) if (value[key] !== void 0) controls[key]?.setValue(value[key]);
|
|
3583
|
+
}
|
|
3584
|
+
reset(value) {
|
|
3585
|
+
const controls = this.controls();
|
|
3586
|
+
for (const key of Object.keys(controls)) {
|
|
3587
|
+
const resetValue = value?.[key];
|
|
3588
|
+
controls[key].reset(resetValue);
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
markAllAsTouched() {
|
|
3367
3592
|
this._touched.set(true);
|
|
3368
|
-
|
|
3593
|
+
const controls = this.controls();
|
|
3594
|
+
for (const key of Object.keys(controls)) controls[key].markAllAsTouched();
|
|
3369
3595
|
}
|
|
3370
|
-
|
|
3596
|
+
markAllAsUntouched() {
|
|
3371
3597
|
this._touched.set(false);
|
|
3598
|
+
const controls = this.controls();
|
|
3599
|
+
for (const key of Object.keys(controls)) controls[key].markAllAsUntouched();
|
|
3372
3600
|
}
|
|
3373
|
-
|
|
3601
|
+
markAllAsDirty() {
|
|
3374
3602
|
this._dirty.set(true);
|
|
3603
|
+
const controls = this.controls();
|
|
3604
|
+
for (const key of Object.keys(controls)) {
|
|
3605
|
+
const child = controls[key];
|
|
3606
|
+
if ("markAllAsDirty" in child && typeof child.markAllAsDirty === "function") child.markAllAsDirty();
|
|
3607
|
+
else child.markAsDirty();
|
|
3608
|
+
}
|
|
3375
3609
|
}
|
|
3376
|
-
|
|
3610
|
+
markAllAsPristine() {
|
|
3377
3611
|
this._dirty.set(false);
|
|
3612
|
+
const controls = this.controls();
|
|
3613
|
+
for (const key of Object.keys(controls)) {
|
|
3614
|
+
const child = controls[key];
|
|
3615
|
+
if ("markAllAsPristine" in child && typeof child.markAllAsPristine === "function") child.markAllAsPristine();
|
|
3616
|
+
else child.markAsPristine();
|
|
3617
|
+
}
|
|
3378
3618
|
}
|
|
3379
3619
|
disable() {
|
|
3380
|
-
this.
|
|
3620
|
+
this._ownDisabled.set(true);
|
|
3621
|
+
const controls = this.controls();
|
|
3622
|
+
for (const key of Object.keys(controls)) controls[key].disable();
|
|
3381
3623
|
}
|
|
3382
3624
|
enable() {
|
|
3383
|
-
this.
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
this._validators = validators;
|
|
3387
|
-
this.runValidation();
|
|
3388
|
-
}
|
|
3389
|
-
setAsyncValidators(validators) {
|
|
3390
|
-
this._asyncValidators = validators;
|
|
3391
|
-
this.runValidation();
|
|
3392
|
-
}
|
|
3393
|
-
addValidators(validators) {
|
|
3394
|
-
this._validators = [...this._validators, ...validators];
|
|
3395
|
-
this.runValidation();
|
|
3396
|
-
}
|
|
3397
|
-
removeValidators(validators) {
|
|
3398
|
-
this._validators = this._validators.filter((v) => !validators.includes(v));
|
|
3399
|
-
this.runValidation();
|
|
3625
|
+
this._ownDisabled.set(false);
|
|
3626
|
+
const controls = this.controls();
|
|
3627
|
+
for (const key of Object.keys(controls)) controls[key].enable();
|
|
3400
3628
|
}
|
|
3401
3629
|
async validate() {
|
|
3630
|
+
const controls = this.controls();
|
|
3631
|
+
await Promise.all(Object.keys(controls).map((key) => controls[key].validate()));
|
|
3402
3632
|
await this.runValidation();
|
|
3403
3633
|
}
|
|
3404
|
-
getError(code) {
|
|
3405
|
-
return this.errors()?.[code] ?? null;
|
|
3406
|
-
}
|
|
3407
|
-
hasError(code) {
|
|
3408
|
-
return this.errors()?.[code] !== void 0;
|
|
3409
|
-
}
|
|
3410
3634
|
destroy() {
|
|
3411
|
-
this.
|
|
3412
|
-
this.
|
|
3413
|
-
|
|
3414
|
-
this.
|
|
3415
|
-
this.
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
const
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
if (
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
...result
|
|
3441
|
-
};
|
|
3442
|
-
} finally {
|
|
3443
|
-
if (validationId === this._asyncValidationId) this._pending.set(false);
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
this.errors.set(errors);
|
|
3635
|
+
this._childValueEffect.destroy();
|
|
3636
|
+
const controls = this.controls();
|
|
3637
|
+
for (const key of Object.keys(controls)) controls[key].destroy();
|
|
3638
|
+
this.destroySignals();
|
|
3639
|
+
this.controls.destroy();
|
|
3640
|
+
}
|
|
3641
|
+
computeDirty() {
|
|
3642
|
+
if (this._dirty()) return true;
|
|
3643
|
+
const controls = this.controls();
|
|
3644
|
+
return Object.keys(controls).some((key) => controls[key].dirty());
|
|
3645
|
+
}
|
|
3646
|
+
computeTouched() {
|
|
3647
|
+
if (this._touched()) return true;
|
|
3648
|
+
const controls = this.controls();
|
|
3649
|
+
return Object.keys(controls).some((key) => controls[key].touched());
|
|
3650
|
+
}
|
|
3651
|
+
computePending() {
|
|
3652
|
+
if (this._pending()) return true;
|
|
3653
|
+
const controls = this.controls();
|
|
3654
|
+
return Object.keys(controls).some((key) => controls[key].pending());
|
|
3655
|
+
}
|
|
3656
|
+
hasInvalidChild() {
|
|
3657
|
+
const controls = this.controls();
|
|
3658
|
+
return Object.keys(controls).some((key) => controls[key].invalid());
|
|
3659
|
+
}
|
|
3660
|
+
static computeValue(controls) {
|
|
3661
|
+
const result = {};
|
|
3662
|
+
for (const key of Object.keys(controls)) result[key] = controls[key].value();
|
|
3663
|
+
return result;
|
|
3447
3664
|
}
|
|
3448
3665
|
};
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
this
|
|
3453
|
-
|
|
3454
|
-
this.
|
|
3455
|
-
this.
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
this._disabled.set(options.disabled ?? false);
|
|
3461
|
-
this.value = computed(() => this.computeValue());
|
|
3462
|
-
this.errors = signal(null);
|
|
3463
|
-
this.setupControlWatchers();
|
|
3464
|
-
this.valid = computed(() => {
|
|
3465
|
-
if (this.errors() !== null) return false;
|
|
3466
|
-
return Object.values(this.controls).every((control) => control.valid());
|
|
3467
|
-
});
|
|
3468
|
-
this.invalid = computed(() => !this.valid());
|
|
3469
|
-
this.pending = computed(() => {
|
|
3470
|
-
return Object.values(this.controls).some((control) => control.pending());
|
|
3471
|
-
});
|
|
3472
|
-
this.dirty = computed(() => {
|
|
3473
|
-
return Object.values(this.controls).some((control) => control.dirty());
|
|
3474
|
-
});
|
|
3475
|
-
this.touched = computed(() => {
|
|
3476
|
-
return Object.values(this.controls).some((control) => control.touched());
|
|
3666
|
+
var FormArray = class extends AbstractControl {
|
|
3667
|
+
constructor(initialControls, options = {}) {
|
|
3668
|
+
super(initialControls.map((c) => c.value()), options);
|
|
3669
|
+
this.controls = signal([...initialControls]);
|
|
3670
|
+
for (const control of initialControls) control.parent = this;
|
|
3671
|
+
this.initializeAggregates();
|
|
3672
|
+
this._childValueEffect = new SignalEffect(() => {
|
|
3673
|
+
const controls = this.controls();
|
|
3674
|
+
for (const control of controls) control.value();
|
|
3675
|
+
this.value.set(controls.map((c) => c.value()));
|
|
3676
|
+
this.runValidation();
|
|
3477
3677
|
});
|
|
3478
|
-
this.
|
|
3479
|
-
this.disabled = computed(() => this._disabled());
|
|
3480
|
-
this.runGroupValidation();
|
|
3678
|
+
this._childValueEffect.run();
|
|
3481
3679
|
}
|
|
3482
|
-
get(
|
|
3483
|
-
return this.controls
|
|
3680
|
+
get length() {
|
|
3681
|
+
return this.controls().length;
|
|
3484
3682
|
}
|
|
3485
|
-
|
|
3486
|
-
this.controls[
|
|
3487
|
-
this.setupControlWatcher(control);
|
|
3683
|
+
at(index) {
|
|
3684
|
+
return this.controls()[index];
|
|
3488
3685
|
}
|
|
3489
|
-
|
|
3490
|
-
|
|
3686
|
+
push(control) {
|
|
3687
|
+
control.parent = this;
|
|
3688
|
+
this.controls.update((current) => [...current, control]);
|
|
3491
3689
|
}
|
|
3492
|
-
|
|
3493
|
-
|
|
3690
|
+
insert(index, control) {
|
|
3691
|
+
control.parent = this;
|
|
3692
|
+
this.controls.update((current) => {
|
|
3693
|
+
const next = [...current];
|
|
3694
|
+
next.splice(index, 0, control);
|
|
3695
|
+
return next;
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3698
|
+
removeAt(index) {
|
|
3699
|
+
const control = this.controls()[index];
|
|
3700
|
+
if (!control) return;
|
|
3701
|
+
control.parent = null;
|
|
3702
|
+
control.destroy();
|
|
3703
|
+
this.controls.update((current) => current.filter((_, i) => i !== index));
|
|
3704
|
+
}
|
|
3705
|
+
clear() {
|
|
3706
|
+
const controls = this.controls();
|
|
3707
|
+
for (const control of controls) {
|
|
3708
|
+
control.parent = null;
|
|
3709
|
+
control.destroy();
|
|
3710
|
+
}
|
|
3711
|
+
this.controls.set([]);
|
|
3494
3712
|
}
|
|
3495
3713
|
setValue(value) {
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3714
|
+
if (this._ownDisabled()) return;
|
|
3715
|
+
const controls = this.controls();
|
|
3716
|
+
value.forEach((v, i) => {
|
|
3717
|
+
controls[i]?.setValue(v);
|
|
3499
3718
|
});
|
|
3500
3719
|
}
|
|
3501
3720
|
patchValue(value) {
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3721
|
+
if (this._ownDisabled()) return;
|
|
3722
|
+
const controls = this.controls();
|
|
3723
|
+
value.forEach((v, i) => {
|
|
3724
|
+
if (v !== void 0) controls[i]?.setValue(v);
|
|
3505
3725
|
});
|
|
3506
3726
|
}
|
|
3507
3727
|
reset(value) {
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
const resetValue = value?.[key];
|
|
3511
|
-
control.reset(resetValue);
|
|
3728
|
+
this.controls().forEach((control, i) => {
|
|
3729
|
+
control.reset(value?.[i]);
|
|
3512
3730
|
});
|
|
3513
3731
|
}
|
|
3514
3732
|
markAllAsTouched() {
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
});
|
|
3733
|
+
this._touched.set(true);
|
|
3734
|
+
for (const control of this.controls()) control.markAllAsTouched();
|
|
3518
3735
|
}
|
|
3519
3736
|
markAllAsUntouched() {
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
});
|
|
3523
|
-
}
|
|
3524
|
-
markAllAsDirty() {
|
|
3525
|
-
Object.values(this.controls).forEach((control) => {
|
|
3526
|
-
control.markAsDirty();
|
|
3527
|
-
});
|
|
3528
|
-
}
|
|
3529
|
-
markAllAsPristine() {
|
|
3530
|
-
Object.values(this.controls).forEach((control) => {
|
|
3531
|
-
control.markAsPristine();
|
|
3532
|
-
});
|
|
3737
|
+
this._touched.set(false);
|
|
3738
|
+
for (const control of this.controls()) control.markAllAsUntouched();
|
|
3533
3739
|
}
|
|
3534
3740
|
disable() {
|
|
3535
|
-
this.
|
|
3536
|
-
|
|
3537
|
-
control.disable();
|
|
3538
|
-
});
|
|
3741
|
+
this._ownDisabled.set(true);
|
|
3742
|
+
for (const control of this.controls()) control.disable();
|
|
3539
3743
|
}
|
|
3540
3744
|
enable() {
|
|
3541
|
-
this.
|
|
3542
|
-
|
|
3543
|
-
control.enable();
|
|
3544
|
-
});
|
|
3745
|
+
this._ownDisabled.set(false);
|
|
3746
|
+
for (const control of this.controls()) control.enable();
|
|
3545
3747
|
}
|
|
3546
3748
|
async validate() {
|
|
3547
|
-
await Promise.all(
|
|
3548
|
-
await this.
|
|
3549
|
-
}
|
|
3550
|
-
setValidators(validators) {
|
|
3551
|
-
this._validators = validators;
|
|
3552
|
-
this.runGroupValidation();
|
|
3553
|
-
}
|
|
3554
|
-
getError(code) {
|
|
3555
|
-
return this.errors()?.[code] ?? null;
|
|
3556
|
-
}
|
|
3557
|
-
hasError(code) {
|
|
3558
|
-
return this.errors()?.[code] !== void 0;
|
|
3749
|
+
await Promise.all(this.controls().map((c) => c.validate()));
|
|
3750
|
+
await this.runValidation();
|
|
3559
3751
|
}
|
|
3560
3752
|
destroy() {
|
|
3561
|
-
this.
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3753
|
+
this._childValueEffect.destroy();
|
|
3754
|
+
for (const control of this.controls()) control.destroy();
|
|
3755
|
+
this.destroySignals();
|
|
3756
|
+
this.controls.destroy();
|
|
3565
3757
|
}
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
result[key] = this.controls[key].value();
|
|
3570
|
-
});
|
|
3571
|
-
return result;
|
|
3758
|
+
computeDirty() {
|
|
3759
|
+
if (this._dirty()) return true;
|
|
3760
|
+
return this.controls().some((c) => c.dirty());
|
|
3572
3761
|
}
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
});
|
|
3762
|
+
computeTouched() {
|
|
3763
|
+
if (this._touched()) return true;
|
|
3764
|
+
return this.controls().some((c) => c.touched());
|
|
3577
3765
|
}
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
this.runGroupValidation();
|
|
3582
|
-
});
|
|
3583
|
-
effect.run();
|
|
3584
|
-
this._controlEffects.push(effect);
|
|
3766
|
+
computePending() {
|
|
3767
|
+
if (this._pending()) return true;
|
|
3768
|
+
return this.controls().some((c) => c.pending());
|
|
3585
3769
|
}
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
let errors = null;
|
|
3589
|
-
for (const validator of this._validators) {
|
|
3590
|
-
const result = validator(value);
|
|
3591
|
-
if (result !== null) errors = {
|
|
3592
|
-
...errors ?? {},
|
|
3593
|
-
...result
|
|
3594
|
-
};
|
|
3595
|
-
}
|
|
3596
|
-
if (this._asyncValidators.length > 0 && errors === null) {
|
|
3597
|
-
const asyncResults = await Promise.all(this._asyncValidators.map((v) => v(value)));
|
|
3598
|
-
for (const result of asyncResults) if (result !== null) errors = {
|
|
3599
|
-
...errors ?? {},
|
|
3600
|
-
...result
|
|
3601
|
-
};
|
|
3602
|
-
}
|
|
3603
|
-
this.errors.set(errors);
|
|
3770
|
+
hasInvalidChild() {
|
|
3771
|
+
return this.controls().some((c) => c.invalid());
|
|
3604
3772
|
}
|
|
3605
3773
|
};
|
|
3606
3774
|
function createFormControl(initialValue, options) {
|
|
@@ -3609,19 +3777,32 @@ function createFormControl(initialValue, options) {
|
|
|
3609
3777
|
function createFormGroup(controls, options) {
|
|
3610
3778
|
return new FormGroup(controls, options);
|
|
3611
3779
|
}
|
|
3780
|
+
function createFormArray(controls, options) {
|
|
3781
|
+
return new FormArray(controls, options);
|
|
3782
|
+
}
|
|
3783
|
+
registerDefaultMessages({
|
|
3784
|
+
required: "This field is required",
|
|
3785
|
+
minLength: (params) => `Minimum length is ${params.min} characters`,
|
|
3786
|
+
maxLength: (params) => `Maximum length is ${params.max} characters`,
|
|
3787
|
+
pattern: "Value does not match required pattern",
|
|
3788
|
+
email: "Please enter a valid email address",
|
|
3789
|
+
min: (params) => `Value must be at least ${params.min}`,
|
|
3790
|
+
max: (params) => `Value must be at most ${params.max}`,
|
|
3791
|
+
range: (params) => `Value must be between ${params.min} and ${params.max}`
|
|
3792
|
+
});
|
|
3793
|
+
var EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
3794
|
+
function isEmpty(value) {
|
|
3795
|
+
return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
3796
|
+
}
|
|
3612
3797
|
const Validators = {
|
|
3613
|
-
required
|
|
3614
|
-
return value
|
|
3615
|
-
code: "required",
|
|
3616
|
-
message: "This field is required"
|
|
3617
|
-
} } : null;
|
|
3798
|
+
required(value) {
|
|
3799
|
+
return isEmpty(value) ? { required: { code: "required" } } : null;
|
|
3618
3800
|
},
|
|
3619
|
-
minLength
|
|
3801
|
+
minLength(min) {
|
|
3620
3802
|
return (value) => {
|
|
3621
3803
|
if (!value || value.length === 0) return null;
|
|
3622
3804
|
return value.length < min ? { minLength: {
|
|
3623
3805
|
code: "minLength",
|
|
3624
|
-
message: `Minimum length is ${min} characters`,
|
|
3625
3806
|
params: {
|
|
3626
3807
|
min,
|
|
3627
3808
|
actual: value.length
|
|
@@ -3629,12 +3810,11 @@ const Validators = {
|
|
|
3629
3810
|
} } : null;
|
|
3630
3811
|
};
|
|
3631
3812
|
},
|
|
3632
|
-
maxLength
|
|
3813
|
+
maxLength(max) {
|
|
3633
3814
|
return (value) => {
|
|
3634
3815
|
if (!value) return null;
|
|
3635
3816
|
return value.length > max ? { maxLength: {
|
|
3636
3817
|
code: "maxLength",
|
|
3637
|
-
message: `Maximum length is ${max} characters`,
|
|
3638
3818
|
params: {
|
|
3639
3819
|
max,
|
|
3640
3820
|
actual: value.length
|
|
@@ -3642,29 +3822,24 @@ const Validators = {
|
|
|
3642
3822
|
} } : null;
|
|
3643
3823
|
};
|
|
3644
3824
|
},
|
|
3645
|
-
pattern
|
|
3825
|
+
pattern(regex) {
|
|
3646
3826
|
return (value) => {
|
|
3647
3827
|
if (!value) return null;
|
|
3648
3828
|
return !regex.test(value) ? { pattern: {
|
|
3649
3829
|
code: "pattern",
|
|
3650
|
-
message: "Value does not match required pattern",
|
|
3651
3830
|
params: { pattern: regex.toString() }
|
|
3652
3831
|
} } : null;
|
|
3653
3832
|
};
|
|
3654
3833
|
},
|
|
3655
|
-
email
|
|
3834
|
+
email(value) {
|
|
3656
3835
|
if (!value) return null;
|
|
3657
|
-
return
|
|
3658
|
-
code: "email",
|
|
3659
|
-
message: "Please enter a valid email address"
|
|
3660
|
-
} } : null;
|
|
3836
|
+
return !EMAIL_REGEX.test(value) ? { email: { code: "email" } } : null;
|
|
3661
3837
|
},
|
|
3662
|
-
min
|
|
3838
|
+
min(minValue) {
|
|
3663
3839
|
return (value) => {
|
|
3664
3840
|
if (value === null || value === void 0) return null;
|
|
3665
3841
|
return value < minValue ? { min: {
|
|
3666
3842
|
code: "min",
|
|
3667
|
-
message: `Value must be at least ${minValue}`,
|
|
3668
3843
|
params: {
|
|
3669
3844
|
min: minValue,
|
|
3670
3845
|
actual: value
|
|
@@ -3672,12 +3847,11 @@ const Validators = {
|
|
|
3672
3847
|
} } : null;
|
|
3673
3848
|
};
|
|
3674
3849
|
},
|
|
3675
|
-
max
|
|
3850
|
+
max(maxValue) {
|
|
3676
3851
|
return (value) => {
|
|
3677
3852
|
if (value === null || value === void 0) return null;
|
|
3678
3853
|
return value > maxValue ? { max: {
|
|
3679
3854
|
code: "max",
|
|
3680
|
-
message: `Value must be at most ${maxValue}`,
|
|
3681
3855
|
params: {
|
|
3682
3856
|
max: maxValue,
|
|
3683
3857
|
actual: value
|
|
@@ -3685,12 +3859,11 @@ const Validators = {
|
|
|
3685
3859
|
} } : null;
|
|
3686
3860
|
};
|
|
3687
3861
|
},
|
|
3688
|
-
range
|
|
3862
|
+
range(minValue, maxValue) {
|
|
3689
3863
|
return (value) => {
|
|
3690
3864
|
if (value === null || value === void 0) return null;
|
|
3691
3865
|
if (value < minValue || value > maxValue) return { range: {
|
|
3692
3866
|
code: "range",
|
|
3693
|
-
message: `Value must be between ${minValue} and ${maxValue}`,
|
|
3694
3867
|
params: {
|
|
3695
3868
|
min: minValue,
|
|
3696
3869
|
max: maxValue,
|
|
@@ -3700,7 +3873,7 @@ const Validators = {
|
|
|
3700
3873
|
return null;
|
|
3701
3874
|
};
|
|
3702
3875
|
},
|
|
3703
|
-
compose
|
|
3876
|
+
compose(...validators) {
|
|
3704
3877
|
return (value) => {
|
|
3705
3878
|
let errors = null;
|
|
3706
3879
|
for (const validator of validators) {
|
|
@@ -3713,7 +3886,7 @@ const Validators = {
|
|
|
3713
3886
|
return errors;
|
|
3714
3887
|
};
|
|
3715
3888
|
},
|
|
3716
|
-
composeAsync
|
|
3889
|
+
composeAsync(...validators) {
|
|
3717
3890
|
return async (value) => {
|
|
3718
3891
|
const results = await Promise.all(validators.map((v) => v(value)));
|
|
3719
3892
|
let errors = null;
|
|
@@ -3725,56 +3898,99 @@ const Validators = {
|
|
|
3725
3898
|
};
|
|
3726
3899
|
}
|
|
3727
3900
|
};
|
|
3728
|
-
function createValidator(code, validationFn,
|
|
3901
|
+
function createValidator(code, validationFn, defaultMessage) {
|
|
3902
|
+
if (defaultMessage !== void 0) setDefaultMessage(code, defaultMessage);
|
|
3729
3903
|
return (value) => {
|
|
3730
3904
|
if (validationFn(value)) return null;
|
|
3731
|
-
return { [code]: {
|
|
3732
|
-
code,
|
|
3733
|
-
message: typeof message === "function" ? message(value) : message
|
|
3734
|
-
} };
|
|
3905
|
+
return { [code]: { code } };
|
|
3735
3906
|
};
|
|
3736
3907
|
}
|
|
3737
|
-
function createAsyncValidator(code, validationFn,
|
|
3908
|
+
function createAsyncValidator(code, validationFn, defaultMessage) {
|
|
3909
|
+
if (defaultMessage !== void 0) setDefaultMessage(code, defaultMessage);
|
|
3738
3910
|
return async (value) => {
|
|
3739
3911
|
if (await validationFn(value)) return null;
|
|
3740
|
-
return { [code]: {
|
|
3741
|
-
code,
|
|
3742
|
-
message: typeof message === "function" ? message(value) : message
|
|
3743
|
-
} };
|
|
3912
|
+
return { [code]: { code } };
|
|
3744
3913
|
};
|
|
3745
3914
|
}
|
|
3746
|
-
|
|
3747
|
-
|
|
3915
|
+
var registry = [];
|
|
3916
|
+
function registerAdapter(predicate, adapter) {
|
|
3917
|
+
registry.unshift({
|
|
3918
|
+
predicate,
|
|
3919
|
+
adapter
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
3922
|
+
function getAdapter(element) {
|
|
3923
|
+
for (const entry of registry) if (entry.predicate(element)) return entry.adapter;
|
|
3748
3924
|
}
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
}
|
|
3758
|
-
|
|
3925
|
+
const textAdapter = {
|
|
3926
|
+
inputEvent: "input",
|
|
3927
|
+
blurEvent: "focusout",
|
|
3928
|
+
getValue(element) {
|
|
3929
|
+
return element.value ?? "";
|
|
3930
|
+
},
|
|
3931
|
+
setValue(element, value) {
|
|
3932
|
+
element.value = value !== null && value !== void 0 ? String(value) : "";
|
|
3933
|
+
},
|
|
3934
|
+
setDisabled(element, disabled) {
|
|
3935
|
+
if (disabled) element.setAttribute("disabled", "");
|
|
3936
|
+
else element.removeAttribute("disabled");
|
|
3937
|
+
}
|
|
3938
|
+
};
|
|
3939
|
+
const checkboxAdapter = {
|
|
3940
|
+
inputEvent: "change",
|
|
3941
|
+
blurEvent: "focusout",
|
|
3942
|
+
getValue(element) {
|
|
3943
|
+
return element.checked;
|
|
3944
|
+
},
|
|
3945
|
+
setValue(element, value) {
|
|
3946
|
+
element.checked = Boolean(value);
|
|
3947
|
+
},
|
|
3948
|
+
setDisabled(element, disabled) {
|
|
3949
|
+
if (disabled) element.setAttribute("disabled", "");
|
|
3950
|
+
else element.removeAttribute("disabled");
|
|
3951
|
+
}
|
|
3952
|
+
};
|
|
3953
|
+
const radioAdapter = {
|
|
3954
|
+
inputEvent: "change",
|
|
3955
|
+
blurEvent: "focusout",
|
|
3956
|
+
getValue(element) {
|
|
3957
|
+
const input = element;
|
|
3958
|
+
return input.checked ? input.value : "";
|
|
3959
|
+
},
|
|
3960
|
+
setValue(element, value) {
|
|
3961
|
+
const input = element;
|
|
3962
|
+
input.checked = input.value === value;
|
|
3963
|
+
},
|
|
3964
|
+
setDisabled(element, disabled) {
|
|
3965
|
+
if (disabled) element.setAttribute("disabled", "");
|
|
3966
|
+
else element.removeAttribute("disabled");
|
|
3967
|
+
}
|
|
3968
|
+
};
|
|
3969
|
+
function registerNativeAdapters() {
|
|
3970
|
+
registerAdapter((el) => el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT", textAdapter);
|
|
3971
|
+
registerAdapter((el) => el.tagName === "INPUT" && el.type === "radio", radioAdapter);
|
|
3972
|
+
registerAdapter((el) => el.tagName === "INPUT" && el.type === "checkbox", checkboxAdapter);
|
|
3759
3973
|
}
|
|
3974
|
+
registerNativeAdapters();
|
|
3760
3975
|
function formControlDirective(element, value, _) {
|
|
3761
|
-
if (!
|
|
3762
|
-
console.warn("formControl directive: value must be
|
|
3976
|
+
if (!(value instanceof AbstractControl)) {
|
|
3977
|
+
console.warn("formControl directive: value must be an AbstractControl");
|
|
3763
3978
|
return;
|
|
3764
3979
|
}
|
|
3765
3980
|
const control = value;
|
|
3766
|
-
const
|
|
3981
|
+
const adapter = getAdapter(element);
|
|
3982
|
+
if (!adapter) {
|
|
3983
|
+
console.warn(`formControl directive: no adapter registered for <${element.tagName.toLowerCase()}>`);
|
|
3984
|
+
return;
|
|
3985
|
+
}
|
|
3767
3986
|
const cleanupFns = [];
|
|
3768
|
-
const
|
|
3769
|
-
|
|
3770
|
-
else if (inputType === "radio") element.checked = element.value === val;
|
|
3771
|
-
else element.value = val !== null && val !== void 0 ? String(val) : "";
|
|
3987
|
+
const syncElementValue = (val) => {
|
|
3988
|
+
adapter.setValue(element, val);
|
|
3772
3989
|
};
|
|
3773
|
-
const
|
|
3774
|
-
|
|
3775
|
-
else element.removeAttribute("disabled");
|
|
3990
|
+
const syncDisabled = (disabled) => {
|
|
3991
|
+
adapter.setDisabled?.(element, disabled);
|
|
3776
3992
|
};
|
|
3777
|
-
const
|
|
3993
|
+
const syncClasses = () => {
|
|
3778
3994
|
element.classList.toggle("mf-valid", control.valid());
|
|
3779
3995
|
element.classList.toggle("mf-invalid", control.invalid());
|
|
3780
3996
|
element.classList.toggle("mf-dirty", control.dirty());
|
|
@@ -3783,40 +3999,38 @@ function formControlDirective(element, value, _) {
|
|
|
3783
3999
|
element.classList.toggle("mf-pending", control.pending());
|
|
3784
4000
|
element.classList.toggle("mf-disabled", control.disabled());
|
|
3785
4001
|
};
|
|
3786
|
-
const
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
4002
|
+
const syncError = () => {
|
|
4003
|
+
if (!control.touched() || !control.errors()) {
|
|
4004
|
+
element.removeAttribute("error");
|
|
4005
|
+
return;
|
|
4006
|
+
}
|
|
4007
|
+
const message = control.getFirstErrorMessage();
|
|
4008
|
+
if (message) element.setAttribute("error", message);
|
|
4009
|
+
else element.removeAttribute("error");
|
|
4010
|
+
};
|
|
4011
|
+
const handleInput = (event) => {
|
|
4012
|
+
const target = event.target;
|
|
4013
|
+
if (target === element || element.contains(target)) control.setValue(adapter.getValue(element));
|
|
3792
4014
|
};
|
|
3793
4015
|
const handleBlur = () => {
|
|
3794
4016
|
control.markAsTouched();
|
|
3795
4017
|
};
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
cleanupFns.push(
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
const unsubscribeState = control.state.subscribe(() => {
|
|
3807
|
-
updateValidationClasses();
|
|
3808
|
-
});
|
|
3809
|
-
cleanupFns.push(unsubscribeState);
|
|
3810
|
-
updateValidationClasses();
|
|
3811
|
-
const eventType = control.updateOn === "blur" ? "change" : "input";
|
|
3812
|
-
element.addEventListener(eventType, handleInput);
|
|
3813
|
-
element.addEventListener("blur", handleBlur);
|
|
4018
|
+
syncElementValue(control.value());
|
|
4019
|
+
syncDisabled(control.disabled());
|
|
4020
|
+
syncClasses();
|
|
4021
|
+
syncError();
|
|
4022
|
+
cleanupFns.push(control.value.subscribe((v) => syncElementValue(v)));
|
|
4023
|
+
cleanupFns.push(control.disabled.subscribe((d) => syncDisabled(d)));
|
|
4024
|
+
cleanupFns.push(control.state.subscribe(() => syncClasses()));
|
|
4025
|
+
cleanupFns.push(control.state.subscribe(() => syncError()));
|
|
4026
|
+
element.addEventListener(adapter.inputEvent, handleInput);
|
|
4027
|
+
element.addEventListener(adapter.blurEvent, handleBlur);
|
|
3814
4028
|
element.setAttribute("data-form-control", "");
|
|
3815
4029
|
return () => {
|
|
3816
|
-
element.removeEventListener(
|
|
3817
|
-
element.removeEventListener(
|
|
4030
|
+
element.removeEventListener(adapter.inputEvent, handleInput);
|
|
4031
|
+
element.removeEventListener(adapter.blurEvent, handleBlur);
|
|
3818
4032
|
element.removeAttribute("data-form-control");
|
|
3819
|
-
|
|
4033
|
+
for (const fn of cleanupFns) fn();
|
|
3820
4034
|
};
|
|
3821
4035
|
}
|
|
3822
4036
|
registerAttributeDirective("formControl", formControlDirective);
|
|
@@ -5984,6 +6198,17 @@ const inputStyles = () => css`
|
|
|
5984
6198
|
flex-shrink: 0;
|
|
5985
6199
|
}
|
|
5986
6200
|
`;
|
|
6201
|
+
registerAdapter((el) => el.tagName === "ML-INPUT", {
|
|
6202
|
+
inputEvent: "ml:input",
|
|
6203
|
+
blurEvent: "focusout",
|
|
6204
|
+
getValue: (el) => el.value ?? "",
|
|
6205
|
+
setValue: (el, value) => {
|
|
6206
|
+
el.value = value !== null && value !== void 0 ? String(value) : "";
|
|
6207
|
+
},
|
|
6208
|
+
setDisabled: (el, disabled) => {
|
|
6209
|
+
el.disabled = disabled;
|
|
6210
|
+
}
|
|
6211
|
+
});
|
|
5987
6212
|
var InputComponent = class InputComponent$1 {
|
|
5988
6213
|
constructor() {
|
|
5989
6214
|
this.type = "text";
|
|
@@ -6260,6 +6485,17 @@ const textareaStyles = () => css`
|
|
|
6260
6485
|
font-size: var(--ml-text-base);
|
|
6261
6486
|
}
|
|
6262
6487
|
`;
|
|
6488
|
+
registerAdapter((el) => el.tagName === "ML-TEXTAREA", {
|
|
6489
|
+
inputEvent: "ml:input",
|
|
6490
|
+
blurEvent: "focusout",
|
|
6491
|
+
getValue: (el) => el.value ?? "",
|
|
6492
|
+
setValue: (el, value) => {
|
|
6493
|
+
el.value = value !== null && value !== void 0 ? String(value) : "";
|
|
6494
|
+
},
|
|
6495
|
+
setDisabled: (el, disabled) => {
|
|
6496
|
+
el.disabled = disabled;
|
|
6497
|
+
}
|
|
6498
|
+
});
|
|
6263
6499
|
var TextareaComponent = class TextareaComponent$1 {
|
|
6264
6500
|
constructor() {
|
|
6265
6501
|
this.value = "";
|
|
@@ -6514,6 +6750,17 @@ const checkboxStyles = () => css`
|
|
|
6514
6750
|
--ml-checkbox-label-line-height: 1.5rem;
|
|
6515
6751
|
}
|
|
6516
6752
|
`;
|
|
6753
|
+
registerAdapter((el) => el.tagName === "ML-CHECKBOX", {
|
|
6754
|
+
inputEvent: "ml:change",
|
|
6755
|
+
blurEvent: "focusout",
|
|
6756
|
+
getValue: (el) => Boolean(el.checked),
|
|
6757
|
+
setValue: (el, value) => {
|
|
6758
|
+
el.checked = Boolean(value);
|
|
6759
|
+
},
|
|
6760
|
+
setDisabled: (el, disabled) => {
|
|
6761
|
+
el.disabled = disabled;
|
|
6762
|
+
}
|
|
6763
|
+
});
|
|
6517
6764
|
var CheckboxComponent = class CheckboxComponent$1 {
|
|
6518
6765
|
constructor() {
|
|
6519
6766
|
this.label = "";
|
|
@@ -6858,6 +7105,17 @@ const radioGroupStyles = () => css`
|
|
|
6858
7105
|
color: var(--ml-color-danger);
|
|
6859
7106
|
}
|
|
6860
7107
|
`;
|
|
7108
|
+
registerAdapter((el) => el.tagName === "ML-RADIO-GROUP", {
|
|
7109
|
+
inputEvent: "ml:change",
|
|
7110
|
+
blurEvent: "focusout",
|
|
7111
|
+
getValue: (el) => el.value ?? "",
|
|
7112
|
+
setValue: (el, value) => {
|
|
7113
|
+
el.value = value !== null && value !== void 0 ? String(value) : "";
|
|
7114
|
+
},
|
|
7115
|
+
setDisabled: (el, disabled) => {
|
|
7116
|
+
el.disabled = disabled;
|
|
7117
|
+
}
|
|
7118
|
+
});
|
|
6861
7119
|
var RadioGroupComponent = class RadioGroupComponent$1 {
|
|
6862
7120
|
constructor() {
|
|
6863
7121
|
this.label = "";
|
|
@@ -7549,6 +7807,17 @@ const toggleStyles = () => css`
|
|
|
7549
7807
|
line-height: var(--ml-leading-tight);
|
|
7550
7808
|
}
|
|
7551
7809
|
`;
|
|
7810
|
+
registerAdapter((el) => el.tagName === "ML-TOGGLE", {
|
|
7811
|
+
inputEvent: "ml:change",
|
|
7812
|
+
blurEvent: "focusout",
|
|
7813
|
+
getValue: (el) => Boolean(el.checked),
|
|
7814
|
+
setValue: (el, value) => {
|
|
7815
|
+
el.checked = Boolean(value);
|
|
7816
|
+
},
|
|
7817
|
+
setDisabled: (el, disabled) => {
|
|
7818
|
+
el.disabled = disabled;
|
|
7819
|
+
}
|
|
7820
|
+
});
|
|
7552
7821
|
var ToggleComponent = class ToggleComponent$1 {
|
|
7553
7822
|
constructor() {
|
|
7554
7823
|
this.label = "";
|
|
@@ -8115,6 +8384,22 @@ const selectStyles = () => css`
|
|
|
8115
8384
|
pointer-events: none;
|
|
8116
8385
|
}
|
|
8117
8386
|
`;
|
|
8387
|
+
registerAdapter((el) => el.tagName === "ML-SELECT", {
|
|
8388
|
+
inputEvent: "ml:change",
|
|
8389
|
+
blurEvent: "focusout",
|
|
8390
|
+
getValue: (el) => {
|
|
8391
|
+
const e = el;
|
|
8392
|
+
return e.multiple ? e.values ?? [] : e.value ?? "";
|
|
8393
|
+
},
|
|
8394
|
+
setValue: (el, value) => {
|
|
8395
|
+
const e = el;
|
|
8396
|
+
if (Array.isArray(value)) e.values = value;
|
|
8397
|
+
else e.value = value !== null && value !== void 0 ? String(value) : "";
|
|
8398
|
+
},
|
|
8399
|
+
setDisabled: (el, disabled) => {
|
|
8400
|
+
el.disabled = disabled;
|
|
8401
|
+
}
|
|
8402
|
+
});
|
|
8118
8403
|
var SelectComponent = class SelectComponent$1 {
|
|
8119
8404
|
constructor() {
|
|
8120
8405
|
this.label = "";
|
|
@@ -8687,6 +8972,17 @@ const sliderStyles = () => css`
|
|
|
8687
8972
|
color: var(--ml-slider-error-color);
|
|
8688
8973
|
}
|
|
8689
8974
|
`;
|
|
8975
|
+
registerAdapter((el) => el.tagName === "ML-SLIDER", {
|
|
8976
|
+
inputEvent: "ml:input",
|
|
8977
|
+
blurEvent: "focusout",
|
|
8978
|
+
getValue: (el) => Number(el.value) || 0,
|
|
8979
|
+
setValue: (el, value) => {
|
|
8980
|
+
el.value = Number(value) || 0;
|
|
8981
|
+
},
|
|
8982
|
+
setDisabled: (el, disabled) => {
|
|
8983
|
+
el.disabled = disabled;
|
|
8984
|
+
}
|
|
8985
|
+
});
|
|
8690
8986
|
var SliderComponent = class SliderComponent$1 {
|
|
8691
8987
|
constructor() {
|
|
8692
8988
|
this.label = "";
|
|
@@ -9062,57 +9358,146 @@ FormFieldComponent = __decorate([MelodicComponent({
|
|
|
9062
9358
|
"required"
|
|
9063
9359
|
]
|
|
9064
9360
|
})], FormFieldComponent);
|
|
9361
|
+
function dayGrid(c) {
|
|
9362
|
+
return html`
|
|
9363
|
+
<div class="ml-calendar__weekdays" role="row">
|
|
9364
|
+
${repeat(c.weekdays, (d) => d, (d) => html`
|
|
9365
|
+
<span class="ml-calendar__weekday" role="columnheader">${d}</span>
|
|
9366
|
+
`)}
|
|
9367
|
+
</div>
|
|
9368
|
+
|
|
9369
|
+
<div class="ml-calendar__grid" @keydown=${c.handleGridKeyDown}>
|
|
9370
|
+
${repeat(c.days, (day) => day.iso, (day) => html`
|
|
9371
|
+
<button
|
|
9372
|
+
type="button"
|
|
9373
|
+
class=${classMap({
|
|
9374
|
+
"ml-calendar__day": true,
|
|
9375
|
+
"ml-calendar__day--other-month": !day.isCurrentMonth,
|
|
9376
|
+
"ml-calendar__day--today": day.isToday,
|
|
9377
|
+
"ml-calendar__day--selected": day.isSelected,
|
|
9378
|
+
"ml-calendar__day--disabled": day.isDisabled
|
|
9379
|
+
})}
|
|
9380
|
+
?disabled=${day.isDisabled || !day.isCurrentMonth}
|
|
9381
|
+
tabindex=${day.isCurrentMonth ? "0" : "-1"}
|
|
9382
|
+
aria-selected=${day.isSelected ? "true" : "false"}
|
|
9383
|
+
aria-label=${day.iso}
|
|
9384
|
+
@click=${() => c.selectDay(day)}
|
|
9385
|
+
>
|
|
9386
|
+
<span class="ml-calendar__day-number">${day.date}</span>
|
|
9387
|
+
${day.isToday ? html`<span class="ml-calendar__today-dot"></span>` : ""}
|
|
9388
|
+
</button>
|
|
9389
|
+
`)}
|
|
9390
|
+
</div>
|
|
9391
|
+
`;
|
|
9392
|
+
}
|
|
9393
|
+
function monthGrid(c) {
|
|
9394
|
+
return html`
|
|
9395
|
+
<div class="ml-calendar__cell-grid" @keydown=${c.handleGridKeyDown}>
|
|
9396
|
+
${repeat(c.months, (m) => m.index, (m) => html`
|
|
9397
|
+
<button
|
|
9398
|
+
type="button"
|
|
9399
|
+
class=${classMap({
|
|
9400
|
+
"ml-calendar__cell": true,
|
|
9401
|
+
"ml-calendar__cell--selected": m.isSelected,
|
|
9402
|
+
"ml-calendar__cell--current": m.isCurrent,
|
|
9403
|
+
"ml-calendar__cell--disabled": m.isDisabled
|
|
9404
|
+
})}
|
|
9405
|
+
?disabled=${m.isDisabled}
|
|
9406
|
+
tabindex="0"
|
|
9407
|
+
aria-selected=${m.isSelected ? "true" : "false"}
|
|
9408
|
+
aria-label=${m.label}
|
|
9409
|
+
@click=${() => c.selectViewMonth(m)}
|
|
9410
|
+
>
|
|
9411
|
+
${m.label}
|
|
9412
|
+
</button>
|
|
9413
|
+
`)}
|
|
9414
|
+
</div>
|
|
9415
|
+
`;
|
|
9416
|
+
}
|
|
9417
|
+
function yearGrid(c) {
|
|
9418
|
+
return html`
|
|
9419
|
+
<div class="ml-calendar__cell-grid" @keydown=${c.handleGridKeyDown}>
|
|
9420
|
+
${repeat(c.years, (y) => y.year, (y) => html`
|
|
9421
|
+
<button
|
|
9422
|
+
type="button"
|
|
9423
|
+
class=${classMap({
|
|
9424
|
+
"ml-calendar__cell": true,
|
|
9425
|
+
"ml-calendar__cell--selected": y.isSelected,
|
|
9426
|
+
"ml-calendar__cell--current": y.isCurrent,
|
|
9427
|
+
"ml-calendar__cell--disabled": y.isDisabled
|
|
9428
|
+
})}
|
|
9429
|
+
?disabled=${y.isDisabled}
|
|
9430
|
+
tabindex=${y.isDisabled ? "-1" : "0"}
|
|
9431
|
+
aria-selected=${y.isSelected ? "true" : "false"}
|
|
9432
|
+
aria-label=${String(y.year)}
|
|
9433
|
+
@click=${() => c.selectViewYear(y)}
|
|
9434
|
+
>
|
|
9435
|
+
${y.year}
|
|
9436
|
+
</button>
|
|
9437
|
+
`)}
|
|
9438
|
+
</div>
|
|
9439
|
+
`;
|
|
9440
|
+
}
|
|
9065
9441
|
function calendarTemplate(c) {
|
|
9066
9442
|
return html`
|
|
9067
|
-
<div class
|
|
9443
|
+
<div class=${classMap({
|
|
9444
|
+
"ml-calendar": true,
|
|
9445
|
+
[`ml-calendar--view-${c.view}`]: true
|
|
9446
|
+
})} role="grid" aria-label=${c.headerLabel}>
|
|
9068
9447
|
<div class="ml-calendar__header">
|
|
9069
9448
|
<div class="ml-calendar__nav-group">
|
|
9070
|
-
<button type="button" class="ml-calendar__nav" aria-label="Previous
|
|
9449
|
+
<button type="button" class="ml-calendar__nav" aria-label="Previous" @click=${c.headerPrevFar}>
|
|
9071
9450
|
<ml-icon icon="caret-double-left" size="sm"></ml-icon>
|
|
9072
9451
|
</button>
|
|
9073
|
-
|
|
9074
|
-
<
|
|
9075
|
-
|
|
9452
|
+
${when(c.view === "day", () => html`
|
|
9453
|
+
<button type="button" class="ml-calendar__nav" aria-label="Previous month" @click=${c.prevMonth}>
|
|
9454
|
+
<ml-icon icon="caret-left" size="sm"></ml-icon>
|
|
9455
|
+
</button>
|
|
9456
|
+
`)}
|
|
9076
9457
|
</div>
|
|
9077
|
-
|
|
9458
|
+
|
|
9459
|
+
${when(c.view === "day", () => html`
|
|
9460
|
+
<div class="ml-calendar__title">
|
|
9461
|
+
<button
|
|
9462
|
+
type="button"
|
|
9463
|
+
class="ml-calendar__title-btn"
|
|
9464
|
+
aria-label="Select month"
|
|
9465
|
+
aria-expanded="false"
|
|
9466
|
+
@click=${c.openMonthView}
|
|
9467
|
+
>${c.monthLabel}</button>
|
|
9468
|
+
<button
|
|
9469
|
+
type="button"
|
|
9470
|
+
class="ml-calendar__title-btn"
|
|
9471
|
+
aria-label="Select year"
|
|
9472
|
+
aria-expanded="false"
|
|
9473
|
+
@click=${c.openYearView}
|
|
9474
|
+
>${c.viewYear}</button>
|
|
9475
|
+
</div>
|
|
9476
|
+
`, () => html`
|
|
9477
|
+
<button
|
|
9478
|
+
type="button"
|
|
9479
|
+
class="ml-calendar__title-btn ml-calendar__title-btn--wide"
|
|
9480
|
+
aria-label=${c.view === "month" ? "Back to day view" : "Select year"}
|
|
9481
|
+
aria-expanded="true"
|
|
9482
|
+
@click=${c.view === "month" ? c.openMonthView : c.openYearView}
|
|
9483
|
+
>${c.headerLabel}</button>
|
|
9484
|
+
`)}
|
|
9485
|
+
|
|
9078
9486
|
<div class="ml-calendar__nav-group">
|
|
9079
|
-
|
|
9080
|
-
<
|
|
9081
|
-
|
|
9082
|
-
|
|
9487
|
+
${when(c.view === "day", () => html`
|
|
9488
|
+
<button type="button" class="ml-calendar__nav" aria-label="Next month" @click=${c.nextMonth}>
|
|
9489
|
+
<ml-icon icon="caret-right" size="sm"></ml-icon>
|
|
9490
|
+
</button>
|
|
9491
|
+
`)}
|
|
9492
|
+
<button type="button" class="ml-calendar__nav" aria-label="Next" @click=${c.headerNextFar}>
|
|
9083
9493
|
<ml-icon icon="caret-double-right" size="sm"></ml-icon>
|
|
9084
9494
|
</button>
|
|
9085
9495
|
</div>
|
|
9086
9496
|
</div>
|
|
9087
9497
|
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
`)}
|
|
9092
|
-
</div>
|
|
9093
|
-
|
|
9094
|
-
<div class="ml-calendar__grid">
|
|
9095
|
-
${repeat(c.days, (day) => day.iso, (day) => html`
|
|
9096
|
-
<button
|
|
9097
|
-
type="button"
|
|
9098
|
-
class=${classMap({
|
|
9099
|
-
"ml-calendar__day": true,
|
|
9100
|
-
"ml-calendar__day--other-month": !day.isCurrentMonth,
|
|
9101
|
-
"ml-calendar__day--today": day.isToday,
|
|
9102
|
-
"ml-calendar__day--selected": day.isSelected,
|
|
9103
|
-
"ml-calendar__day--disabled": day.isDisabled
|
|
9104
|
-
})}
|
|
9105
|
-
?disabled=${day.isDisabled || !day.isCurrentMonth}
|
|
9106
|
-
tabindex=${day.isCurrentMonth ? "0" : "-1"}
|
|
9107
|
-
aria-selected=${day.isSelected ? "true" : "false"}
|
|
9108
|
-
aria-label=${day.iso}
|
|
9109
|
-
@click=${() => c.selectDay(day)}
|
|
9110
|
-
>
|
|
9111
|
-
<span class="ml-calendar__day-number">${day.date}</span>
|
|
9112
|
-
${day.isToday ? html`<span class="ml-calendar__today-dot"></span>` : ""}
|
|
9113
|
-
</button>
|
|
9114
|
-
`)}
|
|
9115
|
-
</div>
|
|
9498
|
+
${when(c.view === "day", () => dayGrid(c))}
|
|
9499
|
+
${when(c.view === "month", () => monthGrid(c))}
|
|
9500
|
+
${when(c.view === "year", () => yearGrid(c))}
|
|
9116
9501
|
|
|
9117
9502
|
<div class="ml-calendar__footer">
|
|
9118
9503
|
<button type="button" class="ml-calendar__today-btn" @click=${c.goToToday}>Today</button>
|
|
@@ -9128,10 +9513,28 @@ const calendarStyles = () => css`
|
|
|
9128
9513
|
--ml-calendar-width: 280px;
|
|
9129
9514
|
--ml-calendar-font-family: var(--ml-font-sans);
|
|
9130
9515
|
|
|
9131
|
-
/* --- Month
|
|
9516
|
+
/* --- Month/year title --- */
|
|
9132
9517
|
--ml-calendar-month-font-size: var(--ml-text-sm);
|
|
9133
9518
|
--ml-calendar-month-font-weight: var(--ml-font-semibold);
|
|
9134
9519
|
--ml-calendar-month-color: var(--ml-color-text);
|
|
9520
|
+
--ml-calendar-title-btn-padding-x: var(--ml-space-1-5);
|
|
9521
|
+
--ml-calendar-title-btn-padding-y: var(--ml-space-1);
|
|
9522
|
+
--ml-calendar-title-btn-border-radius: var(--ml-radius-md);
|
|
9523
|
+
--ml-calendar-title-btn-hover-bg: var(--ml-color-surface-raised);
|
|
9524
|
+
--ml-calendar-title-btn-hover-color: var(--ml-color-text);
|
|
9525
|
+
|
|
9526
|
+
/* --- Month/year cells --- */
|
|
9527
|
+
--ml-calendar-cell-font-size: var(--ml-text-sm);
|
|
9528
|
+
--ml-calendar-cell-font-weight: var(--ml-font-regular);
|
|
9529
|
+
--ml-calendar-cell-color: var(--ml-color-text);
|
|
9530
|
+
--ml-calendar-cell-border-radius: var(--ml-radius-md);
|
|
9531
|
+
--ml-calendar-cell-hover-bg: var(--ml-color-surface-raised);
|
|
9532
|
+
--ml-calendar-cell-selected-bg: var(--ml-color-primary);
|
|
9533
|
+
--ml-calendar-cell-selected-color: var(--ml-color-text-inverse);
|
|
9534
|
+
--ml-calendar-cell-selected-font-weight: var(--ml-font-semibold);
|
|
9535
|
+
--ml-calendar-cell-selected-hover-bg: var(--ml-color-primary-hover);
|
|
9536
|
+
--ml-calendar-cell-current-font-weight: var(--ml-font-semibold);
|
|
9537
|
+
--ml-calendar-cell-height: 3rem;
|
|
9135
9538
|
|
|
9136
9539
|
/* --- Nav buttons --- */
|
|
9137
9540
|
--ml-calendar-nav-size: 2rem;
|
|
@@ -9205,10 +9608,94 @@ const calendarStyles = () => css`
|
|
|
9205
9608
|
gap: 0;
|
|
9206
9609
|
}
|
|
9207
9610
|
|
|
9208
|
-
.ml-
|
|
9611
|
+
.ml-calendar__title {
|
|
9612
|
+
display: flex;
|
|
9613
|
+
align-items: center;
|
|
9614
|
+
gap: var(--ml-space-1);
|
|
9615
|
+
}
|
|
9616
|
+
|
|
9617
|
+
.ml-calendar__title-btn {
|
|
9618
|
+
border: none;
|
|
9619
|
+
background: none;
|
|
9620
|
+
padding: var(--ml-calendar-title-btn-padding-y) var(--ml-calendar-title-btn-padding-x);
|
|
9621
|
+
border-radius: var(--ml-calendar-title-btn-border-radius);
|
|
9622
|
+
font-family: inherit;
|
|
9209
9623
|
font-size: var(--ml-calendar-month-font-size);
|
|
9210
9624
|
font-weight: var(--ml-calendar-month-font-weight);
|
|
9211
9625
|
color: var(--ml-calendar-month-color);
|
|
9626
|
+
cursor: pointer;
|
|
9627
|
+
transition: background-color var(--ml-calendar-transition-duration) var(--ml-calendar-transition-easing), color var(--ml-calendar-transition-duration) var(--ml-calendar-transition-easing);
|
|
9628
|
+
}
|
|
9629
|
+
|
|
9630
|
+
.ml-calendar__title-btn:hover {
|
|
9631
|
+
background-color: var(--ml-calendar-title-btn-hover-bg);
|
|
9632
|
+
color: var(--ml-calendar-title-btn-hover-color);
|
|
9633
|
+
}
|
|
9634
|
+
|
|
9635
|
+
.ml-calendar__title-btn:focus-visible {
|
|
9636
|
+
outline: none;
|
|
9637
|
+
box-shadow: var(--ml-calendar-focus-shadow);
|
|
9638
|
+
}
|
|
9639
|
+
|
|
9640
|
+
.ml-calendar__title-btn--wide {
|
|
9641
|
+
min-width: 0;
|
|
9642
|
+
}
|
|
9643
|
+
|
|
9644
|
+
/* Month / year cell grid */
|
|
9645
|
+
.ml-calendar__cell-grid {
|
|
9646
|
+
display: grid;
|
|
9647
|
+
grid-template-columns: repeat(3, 1fr);
|
|
9648
|
+
gap: var(--ml-space-1);
|
|
9649
|
+
padding: var(--ml-space-1) 0;
|
|
9650
|
+
}
|
|
9651
|
+
|
|
9652
|
+
.ml-calendar__cell {
|
|
9653
|
+
display: flex;
|
|
9654
|
+
align-items: center;
|
|
9655
|
+
justify-content: center;
|
|
9656
|
+
height: var(--ml-calendar-cell-height);
|
|
9657
|
+
border: none;
|
|
9658
|
+
border-radius: var(--ml-calendar-cell-border-radius);
|
|
9659
|
+
background: none;
|
|
9660
|
+
font-family: inherit;
|
|
9661
|
+
font-size: var(--ml-calendar-cell-font-size);
|
|
9662
|
+
font-weight: var(--ml-calendar-cell-font-weight);
|
|
9663
|
+
color: var(--ml-calendar-cell-color);
|
|
9664
|
+
cursor: pointer;
|
|
9665
|
+
padding: 0;
|
|
9666
|
+
transition:
|
|
9667
|
+
background-color var(--ml-calendar-transition-duration) var(--ml-calendar-transition-easing),
|
|
9668
|
+
color var(--ml-calendar-transition-duration) var(--ml-calendar-transition-easing);
|
|
9669
|
+
}
|
|
9670
|
+
|
|
9671
|
+
.ml-calendar__cell:hover:not(:disabled):not(.ml-calendar__cell--selected) {
|
|
9672
|
+
background-color: var(--ml-calendar-cell-hover-bg);
|
|
9673
|
+
}
|
|
9674
|
+
|
|
9675
|
+
.ml-calendar__cell:focus-visible {
|
|
9676
|
+
outline: none;
|
|
9677
|
+
box-shadow: var(--ml-calendar-focus-shadow);
|
|
9678
|
+
z-index: 1;
|
|
9679
|
+
}
|
|
9680
|
+
|
|
9681
|
+
.ml-calendar__cell--current {
|
|
9682
|
+
font-weight: var(--ml-calendar-cell-current-font-weight);
|
|
9683
|
+
}
|
|
9684
|
+
|
|
9685
|
+
.ml-calendar__cell--selected {
|
|
9686
|
+
background-color: var(--ml-calendar-cell-selected-bg);
|
|
9687
|
+
color: var(--ml-calendar-cell-selected-color);
|
|
9688
|
+
font-weight: var(--ml-calendar-cell-selected-font-weight);
|
|
9689
|
+
}
|
|
9690
|
+
|
|
9691
|
+
.ml-calendar__cell--selected:hover:not(:disabled) {
|
|
9692
|
+
background-color: var(--ml-calendar-cell-selected-hover-bg);
|
|
9693
|
+
}
|
|
9694
|
+
|
|
9695
|
+
.ml-calendar__cell--disabled,
|
|
9696
|
+
.ml-calendar__cell:disabled {
|
|
9697
|
+
opacity: var(--ml-calendar-disabled-opacity);
|
|
9698
|
+
cursor: not-allowed;
|
|
9212
9699
|
}
|
|
9213
9700
|
|
|
9214
9701
|
.ml-calendar__nav {
|
|
@@ -9380,6 +9867,20 @@ var MONTH_NAMES$1 = [
|
|
|
9380
9867
|
"November",
|
|
9381
9868
|
"December"
|
|
9382
9869
|
];
|
|
9870
|
+
var MONTH_NAMES_SHORT = [
|
|
9871
|
+
"Jan",
|
|
9872
|
+
"Feb",
|
|
9873
|
+
"Mar",
|
|
9874
|
+
"Apr",
|
|
9875
|
+
"May",
|
|
9876
|
+
"Jun",
|
|
9877
|
+
"Jul",
|
|
9878
|
+
"Aug",
|
|
9879
|
+
"Sep",
|
|
9880
|
+
"Oct",
|
|
9881
|
+
"Nov",
|
|
9882
|
+
"Dec"
|
|
9883
|
+
];
|
|
9383
9884
|
var WEEKDAYS = [
|
|
9384
9885
|
"Su",
|
|
9385
9886
|
"Mo",
|
|
@@ -9389,6 +9890,9 @@ var WEEKDAYS = [
|
|
|
9389
9890
|
"Fr",
|
|
9390
9891
|
"Sa"
|
|
9391
9892
|
];
|
|
9893
|
+
var YEARS_PER_PAGE = 12;
|
|
9894
|
+
var DEFAULT_MIN_YEAR_OFFSET = 120;
|
|
9895
|
+
var DEFAULT_MAX_YEAR_OFFSET = 10;
|
|
9392
9896
|
function toIso(year, month, day) {
|
|
9393
9897
|
return `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
9394
9898
|
}
|
|
@@ -9396,13 +9900,25 @@ function todayIso() {
|
|
|
9396
9900
|
const d = /* @__PURE__ */ new Date();
|
|
9397
9901
|
return toIso(d.getFullYear(), d.getMonth(), d.getDate());
|
|
9398
9902
|
}
|
|
9903
|
+
function parseYear(val) {
|
|
9904
|
+
if (typeof val === "number" && Number.isFinite(val)) return val;
|
|
9905
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
9906
|
+
const n = Number.parseInt(val, 10);
|
|
9907
|
+
if (Number.isFinite(n)) return n;
|
|
9908
|
+
}
|
|
9909
|
+
return null;
|
|
9910
|
+
}
|
|
9399
9911
|
var CalendarComponent = class CalendarComponent$1 {
|
|
9400
9912
|
constructor() {
|
|
9401
9913
|
this.value = "";
|
|
9402
9914
|
this.min = "";
|
|
9403
9915
|
this.max = "";
|
|
9916
|
+
this.minYear = "";
|
|
9917
|
+
this.maxYear = "";
|
|
9404
9918
|
this.viewMonth = (/* @__PURE__ */ new Date()).getMonth();
|
|
9405
9919
|
this.viewYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
9920
|
+
this.view = "day";
|
|
9921
|
+
this.yearPageStart = 0;
|
|
9406
9922
|
this.prevYear = () => {
|
|
9407
9923
|
this.viewYear--;
|
|
9408
9924
|
};
|
|
@@ -9421,6 +9937,55 @@ var CalendarComponent = class CalendarComponent$1 {
|
|
|
9421
9937
|
this.viewYear++;
|
|
9422
9938
|
} else this.viewMonth++;
|
|
9423
9939
|
};
|
|
9940
|
+
this.headerPrev = () => {
|
|
9941
|
+
if (this.view === "year") this.prevYearPage();
|
|
9942
|
+
else if (this.view === "month") this.prevYear();
|
|
9943
|
+
else this.prevMonth();
|
|
9944
|
+
};
|
|
9945
|
+
this.headerNext = () => {
|
|
9946
|
+
if (this.view === "year") this.nextYearPage();
|
|
9947
|
+
else if (this.view === "month") this.nextYear();
|
|
9948
|
+
else this.nextMonth();
|
|
9949
|
+
};
|
|
9950
|
+
this.headerPrevFar = () => {
|
|
9951
|
+
if (this.view === "year") this.prevYearPage();
|
|
9952
|
+
else this.prevYear();
|
|
9953
|
+
};
|
|
9954
|
+
this.headerNextFar = () => {
|
|
9955
|
+
if (this.view === "year") this.nextYearPage();
|
|
9956
|
+
else this.nextYear();
|
|
9957
|
+
};
|
|
9958
|
+
this.prevYearPage = () => {
|
|
9959
|
+
const next = this.yearPageStart - YEARS_PER_PAGE;
|
|
9960
|
+
const minPage = this.computeYearPageStart(this.resolvedMinYear);
|
|
9961
|
+
this.yearPageStart = Math.max(next, minPage);
|
|
9962
|
+
};
|
|
9963
|
+
this.nextYearPage = () => {
|
|
9964
|
+
const next = this.yearPageStart + YEARS_PER_PAGE;
|
|
9965
|
+
const maxPage = this.computeYearPageStart(this.resolvedMaxYear);
|
|
9966
|
+
this.yearPageStart = Math.min(next, maxPage);
|
|
9967
|
+
};
|
|
9968
|
+
this.openMonthView = () => {
|
|
9969
|
+
this.view = this.view === "month" ? "day" : "month";
|
|
9970
|
+
};
|
|
9971
|
+
this.openYearView = () => {
|
|
9972
|
+
if (this.view === "year") {
|
|
9973
|
+
this.view = "day";
|
|
9974
|
+
return;
|
|
9975
|
+
}
|
|
9976
|
+
this.yearPageStart = this.computeYearPageStart(this.viewYear);
|
|
9977
|
+
this.view = "year";
|
|
9978
|
+
};
|
|
9979
|
+
this.selectViewMonth = (month) => {
|
|
9980
|
+
if (month.isDisabled) return;
|
|
9981
|
+
this.viewMonth = month.index;
|
|
9982
|
+
this.view = "day";
|
|
9983
|
+
};
|
|
9984
|
+
this.selectViewYear = (year) => {
|
|
9985
|
+
if (year.isDisabled) return;
|
|
9986
|
+
this.viewYear = year.year;
|
|
9987
|
+
this.view = "month";
|
|
9988
|
+
};
|
|
9424
9989
|
this.selectDay = (day) => {
|
|
9425
9990
|
if (day.isDisabled) return;
|
|
9426
9991
|
this.value = day.iso;
|
|
@@ -9436,6 +10001,7 @@ var CalendarComponent = class CalendarComponent$1 {
|
|
|
9436
10001
|
const now = /* @__PURE__ */ new Date();
|
|
9437
10002
|
this.viewMonth = now.getMonth();
|
|
9438
10003
|
this.viewYear = now.getFullYear();
|
|
10004
|
+
this.view = "day";
|
|
9439
10005
|
const iso = todayIso();
|
|
9440
10006
|
if (!this.isDisabled(iso)) {
|
|
9441
10007
|
this.value = iso;
|
|
@@ -9446,12 +10012,56 @@ var CalendarComponent = class CalendarComponent$1 {
|
|
|
9446
10012
|
}));
|
|
9447
10013
|
}
|
|
9448
10014
|
};
|
|
10015
|
+
this.handleGridKeyDown = (event) => {
|
|
10016
|
+
const key = event.key;
|
|
10017
|
+
if (key !== "ArrowLeft" && key !== "ArrowRight" && key !== "ArrowUp" && key !== "ArrowDown" && key !== "Home" && key !== "End") return;
|
|
10018
|
+
const target = event.target;
|
|
10019
|
+
if (!target || target.tagName !== "BUTTON") return;
|
|
10020
|
+
const grid = target.closest(".ml-calendar__grid, .ml-calendar__cell-grid");
|
|
10021
|
+
if (!grid) return;
|
|
10022
|
+
const cells = Array.from(grid.querySelectorAll("button:not([disabled])")).filter((el) => el.tabIndex !== -1);
|
|
10023
|
+
if (cells.length === 0) return;
|
|
10024
|
+
const idx = cells.indexOf(target);
|
|
10025
|
+
if (idx === -1) return;
|
|
10026
|
+
const cols = this.view === "day" ? 7 : 3;
|
|
10027
|
+
let nextIdx = idx;
|
|
10028
|
+
switch (key) {
|
|
10029
|
+
case "ArrowLeft":
|
|
10030
|
+
nextIdx = idx - 1;
|
|
10031
|
+
break;
|
|
10032
|
+
case "ArrowRight":
|
|
10033
|
+
nextIdx = idx + 1;
|
|
10034
|
+
break;
|
|
10035
|
+
case "ArrowUp":
|
|
10036
|
+
nextIdx = idx - cols;
|
|
10037
|
+
break;
|
|
10038
|
+
case "ArrowDown":
|
|
10039
|
+
nextIdx = idx + cols;
|
|
10040
|
+
break;
|
|
10041
|
+
case "Home":
|
|
10042
|
+
nextIdx = 0;
|
|
10043
|
+
break;
|
|
10044
|
+
case "End":
|
|
10045
|
+
nextIdx = cells.length - 1;
|
|
10046
|
+
break;
|
|
10047
|
+
}
|
|
10048
|
+
if (nextIdx < 0 || nextIdx >= cells.length) {
|
|
10049
|
+
event.preventDefault();
|
|
10050
|
+
return;
|
|
10051
|
+
}
|
|
10052
|
+
event.preventDefault();
|
|
10053
|
+
cells[nextIdx].focus();
|
|
10054
|
+
};
|
|
9449
10055
|
}
|
|
9450
10056
|
onInit() {
|
|
9451
10057
|
this.navigateToValue();
|
|
10058
|
+
this.yearPageStart = this.computeYearPageStart(this.viewYear);
|
|
9452
10059
|
}
|
|
9453
10060
|
onAttributeChange(name, _, newVal) {
|
|
9454
|
-
if (name === "value" && newVal)
|
|
10061
|
+
if (name === "value" && newVal) {
|
|
10062
|
+
this.navigateToValue();
|
|
10063
|
+
this.yearPageStart = this.computeYearPageStart(this.viewYear);
|
|
10064
|
+
}
|
|
9455
10065
|
}
|
|
9456
10066
|
navigateToValue() {
|
|
9457
10067
|
if (!this.value) return;
|
|
@@ -9462,11 +10072,28 @@ var CalendarComponent = class CalendarComponent$1 {
|
|
|
9462
10072
|
}
|
|
9463
10073
|
}
|
|
9464
10074
|
get monthLabel() {
|
|
9465
|
-
return
|
|
10075
|
+
return MONTH_NAMES$1[this.viewMonth];
|
|
10076
|
+
}
|
|
10077
|
+
get yearLabel() {
|
|
10078
|
+
return String(this.viewYear);
|
|
10079
|
+
}
|
|
10080
|
+
get yearRangeLabel() {
|
|
10081
|
+
return `${this.yearPageStart} – ${this.yearPageStart + YEARS_PER_PAGE - 1}`;
|
|
10082
|
+
}
|
|
10083
|
+
get headerLabel() {
|
|
10084
|
+
if (this.view === "year") return this.yearRangeLabel;
|
|
10085
|
+
if (this.view === "month") return this.yearLabel;
|
|
10086
|
+
return `${this.monthLabel} ${this.viewYear}`;
|
|
9466
10087
|
}
|
|
9467
10088
|
get weekdays() {
|
|
9468
10089
|
return WEEKDAYS;
|
|
9469
10090
|
}
|
|
10091
|
+
get resolvedMinYear() {
|
|
10092
|
+
return parseYear(this.minYear) ?? (/* @__PURE__ */ new Date()).getFullYear() - DEFAULT_MIN_YEAR_OFFSET;
|
|
10093
|
+
}
|
|
10094
|
+
get resolvedMaxYear() {
|
|
10095
|
+
return parseYear(this.maxYear) ?? (/* @__PURE__ */ new Date()).getFullYear() + DEFAULT_MAX_YEAR_OFFSET;
|
|
10096
|
+
}
|
|
9470
10097
|
get days() {
|
|
9471
10098
|
const year = this.viewYear;
|
|
9472
10099
|
const month = this.viewMonth;
|
|
@@ -9525,6 +10152,66 @@ var CalendarComponent = class CalendarComponent$1 {
|
|
|
9525
10152
|
}
|
|
9526
10153
|
return result;
|
|
9527
10154
|
}
|
|
10155
|
+
get months() {
|
|
10156
|
+
const selectedMonth = this.selectedMonthForYear(this.viewYear);
|
|
10157
|
+
const now = /* @__PURE__ */ new Date();
|
|
10158
|
+
return MONTH_NAMES_SHORT.map((label, index) => ({
|
|
10159
|
+
index,
|
|
10160
|
+
label,
|
|
10161
|
+
isSelected: selectedMonth === index,
|
|
10162
|
+
isCurrent: now.getFullYear() === this.viewYear && now.getMonth() === index,
|
|
10163
|
+
isDisabled: this.isMonthDisabled(this.viewYear, index)
|
|
10164
|
+
}));
|
|
10165
|
+
}
|
|
10166
|
+
get years() {
|
|
10167
|
+
const result = [];
|
|
10168
|
+
const selectedYear = this.selectedYear();
|
|
10169
|
+
const now = (/* @__PURE__ */ new Date()).getFullYear();
|
|
10170
|
+
const minY = this.resolvedMinYear;
|
|
10171
|
+
const maxY = this.resolvedMaxYear;
|
|
10172
|
+
for (let i = 0; i < YEARS_PER_PAGE; i++) {
|
|
10173
|
+
const year = this.yearPageStart + i;
|
|
10174
|
+
const inRange = year >= minY && year <= maxY;
|
|
10175
|
+
result.push({
|
|
10176
|
+
year,
|
|
10177
|
+
isSelected: selectedYear === year,
|
|
10178
|
+
isCurrent: year === now,
|
|
10179
|
+
isDisabled: !inRange,
|
|
10180
|
+
isPlaceholder: !inRange && (year < minY || year > maxY)
|
|
10181
|
+
});
|
|
10182
|
+
}
|
|
10183
|
+
return result;
|
|
10184
|
+
}
|
|
10185
|
+
get canPageYearsBack() {
|
|
10186
|
+
return this.yearPageStart > this.resolvedMinYear;
|
|
10187
|
+
}
|
|
10188
|
+
get canPageYearsForward() {
|
|
10189
|
+
return this.yearPageStart + YEARS_PER_PAGE - 1 < this.resolvedMaxYear;
|
|
10190
|
+
}
|
|
10191
|
+
computeYearPageStart(year) {
|
|
10192
|
+
const minY = this.resolvedMinYear;
|
|
10193
|
+
return minY + Math.floor((year - minY) / YEARS_PER_PAGE) * YEARS_PER_PAGE;
|
|
10194
|
+
}
|
|
10195
|
+
selectedMonthForYear(year) {
|
|
10196
|
+
if (!this.value) return null;
|
|
10197
|
+
const parts = this.value.split("-");
|
|
10198
|
+
if (parts.length !== 3) return null;
|
|
10199
|
+
if (Number.parseInt(parts[0], 10) !== year) return null;
|
|
10200
|
+
return Number.parseInt(parts[1], 10) - 1;
|
|
10201
|
+
}
|
|
10202
|
+
selectedYear() {
|
|
10203
|
+
if (!this.value) return null;
|
|
10204
|
+
const parts = this.value.split("-");
|
|
10205
|
+
if (parts.length !== 3) return null;
|
|
10206
|
+
return Number.parseInt(parts[0], 10);
|
|
10207
|
+
}
|
|
10208
|
+
isMonthDisabled(year, month) {
|
|
10209
|
+
const monthEnd = toIso(year, month, new Date(year, month + 1, 0).getDate());
|
|
10210
|
+
const monthStart = toIso(year, month, 1);
|
|
10211
|
+
if (this.min && monthEnd < this.min) return true;
|
|
10212
|
+
if (this.max && monthStart > this.max) return true;
|
|
10213
|
+
return false;
|
|
10214
|
+
}
|
|
9528
10215
|
isDisabled(iso) {
|
|
9529
10216
|
if (this.min && iso < this.min) return true;
|
|
9530
10217
|
if (this.max && iso > this.max) return true;
|
|
@@ -9538,7 +10225,9 @@ CalendarComponent = __decorate([MelodicComponent({
|
|
|
9538
10225
|
attributes: [
|
|
9539
10226
|
"value",
|
|
9540
10227
|
"min",
|
|
9541
|
-
"max"
|
|
10228
|
+
"max",
|
|
10229
|
+
"min-year",
|
|
10230
|
+
"max-year"
|
|
9542
10231
|
]
|
|
9543
10232
|
})], CalendarComponent);
|
|
9544
10233
|
function datePickerTemplate(c) {
|
|
@@ -9590,6 +10279,8 @@ function datePickerTemplate(c) {
|
|
|
9590
10279
|
value=${c.value}
|
|
9591
10280
|
min=${c.min}
|
|
9592
10281
|
max=${c.max}
|
|
10282
|
+
min-year=${c.minYear}
|
|
10283
|
+
max-year=${c.maxYear}
|
|
9593
10284
|
@ml:select=${c.handleDateSelect}
|
|
9594
10285
|
></ml-calendar>
|
|
9595
10286
|
</div>
|
|
@@ -9834,6 +10525,17 @@ const datePickerStyles = () => css`
|
|
|
9834
10525
|
color: var(--ml-date-picker-error-color);
|
|
9835
10526
|
}
|
|
9836
10527
|
`;
|
|
10528
|
+
registerAdapter((el) => el.tagName === "ML-DATE-PICKER", {
|
|
10529
|
+
inputEvent: "ml:select",
|
|
10530
|
+
blurEvent: "focusout",
|
|
10531
|
+
getValue: (el) => el.value ?? "",
|
|
10532
|
+
setValue: (el, value) => {
|
|
10533
|
+
el.value = value !== null && value !== void 0 ? String(value) : "";
|
|
10534
|
+
},
|
|
10535
|
+
setDisabled: (el, disabled) => {
|
|
10536
|
+
el.disabled = disabled;
|
|
10537
|
+
}
|
|
10538
|
+
});
|
|
9837
10539
|
var DatePickerComponent = class DatePickerComponent$1 {
|
|
9838
10540
|
constructor() {
|
|
9839
10541
|
this.value = "";
|
|
@@ -9846,6 +10548,8 @@ var DatePickerComponent = class DatePickerComponent$1 {
|
|
|
9846
10548
|
this.required = false;
|
|
9847
10549
|
this.min = "";
|
|
9848
10550
|
this.max = "";
|
|
10551
|
+
this.minYear = "";
|
|
10552
|
+
this.maxYear = "";
|
|
9849
10553
|
this.isOpen = false;
|
|
9850
10554
|
this._cleanupAutoUpdate = null;
|
|
9851
10555
|
this.toggleCalendar = () => {
|
|
@@ -9961,7 +10665,9 @@ DatePickerComponent = __decorate([MelodicComponent({
|
|
|
9961
10665
|
"disabled",
|
|
9962
10666
|
"required",
|
|
9963
10667
|
"min",
|
|
9964
|
-
"max"
|
|
10668
|
+
"max",
|
|
10669
|
+
"min-year",
|
|
10670
|
+
"max-year"
|
|
9965
10671
|
]
|
|
9966
10672
|
})], DatePickerComponent);
|
|
9967
10673
|
function alertTemplate(c) {
|
|
@@ -11624,6 +12330,7 @@ const badgeStyles = () => css`
|
|
|
11624
12330
|
|
|
11625
12331
|
/* ── Badge: dot ── */
|
|
11626
12332
|
--ml-badge-dot-size: 0.375rem;
|
|
12333
|
+
--ml-badge-dot-size-xs: 0.3125rem;
|
|
11627
12334
|
--ml-badge-dot-size-lg: 0.5rem;
|
|
11628
12335
|
|
|
11629
12336
|
/* ── Badge: secondary variant ── */
|
|
@@ -11661,6 +12368,16 @@ const badgeStyles = () => css`
|
|
|
11661
12368
|
height: var(--ml-badge-dot-size-lg);
|
|
11662
12369
|
}
|
|
11663
12370
|
|
|
12371
|
+
.ml-badge--xs .ml-badge__dot {
|
|
12372
|
+
width: var(--ml-badge-dot-size-xs);
|
|
12373
|
+
height: var(--ml-badge-dot-size-xs);
|
|
12374
|
+
}
|
|
12375
|
+
|
|
12376
|
+
.ml-badge--xs {
|
|
12377
|
+
padding: 1px var(--ml-space-1-5);
|
|
12378
|
+
font-size: 0.6875rem;
|
|
12379
|
+
}
|
|
12380
|
+
|
|
11664
12381
|
.ml-badge--sm {
|
|
11665
12382
|
padding: 2px var(--ml-space-2);
|
|
11666
12383
|
font-size: var(--ml-text-xs);
|
|
@@ -24826,6 +25543,6 @@ DashboardPageComponent = __decorate([MelodicComponent({
|
|
|
24826
25543
|
"layout"
|
|
24827
25544
|
]
|
|
24828
25545
|
})], DashboardPageComponent);
|
|
24829
|
-
export { APP_CONFIG, AbortError, ActivityFeedComponent, ActivityFeedItemComponent, AlertComponent, AppShellComponent, AvatarComponent, BadgeComponent, BadgeGroupComponent, Binding, BreadcrumbComponent, BreadcrumbItemComponent, ButtonComponent, ButtonGroupComponent, ButtonGroupItemComponent, CalendarComponent, CalendarViewComponent, CardComponent, CheckboxComponent, ComponentBase, ComponentStateBaseService, ContainerComponent, DashboardPageComponent, DatePickerComponent, DialogComponent, DialogRef, DialogService, Directive, DividerComponent, DrawerComponent, DropdownComponent, DropdownGroupComponent, DropdownItemComponent, DropdownSeparatorComponent, EffectsBase,
|
|
25546
|
+
export { APP_CONFIG, AbortError, AbstractControl, ActivityFeedComponent, ActivityFeedItemComponent, AlertComponent, AppShellComponent, AvatarComponent, BadgeComponent, BadgeGroupComponent, Binding, BreadcrumbComponent, BreadcrumbItemComponent, ButtonComponent, ButtonGroupComponent, ButtonGroupItemComponent, CalendarComponent, CalendarViewComponent, CardComponent, CheckboxComponent, ComponentBase, ComponentStateBaseService, ContainerComponent, DashboardPageComponent, DatePickerComponent, DialogComponent, DialogRef, DialogService, Directive, DividerComponent, DrawerComponent, DropdownComponent, DropdownGroupComponent, DropdownItemComponent, DropdownSeparatorComponent, EffectsBase, FormArray, FormControl, FormFieldComponent, FormGroup, HeroSectionComponent, HttpBaseError, HttpClient, HttpError, IconComponent, Inject, Injectable, InjectionEngine, Injector, InputComponent, ListComponent, ListItemComponent, LoginPageComponent, MelodicComponent, NetworkError, PageHeaderComponent, PaginationComponent, PopoverComponent, ProgressComponent, ROUTE_CONTEXT_EVENT, RX_ACTION_PROVIDERS, RX_EFFECTS_PROVIDERS, RX_INIT_STATE, RX_STATE_DEBUG, RadioCardComponent, RadioCardGroupComponent, RadioComponent, RadioGroupComponent, RouteContextEvent, RouteContextService, RouteMatcher, RouterLinkComponent, RouterOutletComponent, RouterService, SIGNAL_MARKER, SelectComponent, Service, SidebarComponent, SidebarGroupComponent, SidebarItemComponent, SignalEffect, SignalStoreService, SignupPageComponent, SliderComponent, SpinnerComponent, StackComponent, StepComponent, StepPanelComponent, StepsComponent, TabComponent, TabPanelComponent, TableComponent, TabsComponent, TagComponent, TemplateResult, TextareaComponent, ToastComponent, ToastContainerComponent, ToastService, ToggleComponent, TooltipComponent, Validators, VirtualScroller, activityFeedItemStyles, activityFeedItemTemplate, activityFeedStyles, activityFeedTemplate, allTokens, announce, appShellStyles, appShellTemplate, applyGlobalStyles, applyTheme, arrow, autoUpdate, baseThemeCss, bootstrap, borderTokens, breadcrumbItemStyles, breadcrumbItemTemplate, breadcrumbStyles, breadcrumbTemplate, breakpointTokens, breakpoints, buildPathFromRoute, calendarViewStyles, calendarViewTemplate, checkboxAdapter, classMap, clickOutside, colorTokens, componentBaseStyles, computePosition, computed, containerStyles, containerTemplate, createAction, createAsyncValidator, createBrandTheme, createDeactivateGuard, createFocusTrap, createFormArray, createFormControl, createFormGroup, createGuard, createLiveRegion, createReducer, createResolver, createState, createTheme, createToken, createValidator, css, darkTheme, darkThemeCss, dashboardPageStyles, dashboardPageTemplate, defineConfig, directive, drawerStyles, drawerTemplate, dropdownGroupStyles, dropdownGroupTemplate, dropdownItemStyles, dropdownItemTemplate, dropdownSeparatorStyles, dropdownSeparatorTemplate, dropdownStyles, dropdownTemplate, environment, findRouteByName, flip, focusFirst, focusLast, focusTrap, focusVisible, formControlDirective, formFieldStyles, formFieldTemplate, getActiveEffect, getAdapter, getAttributeDirective, getEnvironment, getFirstFocusable, getFocusableElements, getGlobalMessage, getLastFocusable, getRegisteredDirectives, getResolvedTheme, getTheme, getTokenKey, hasAttributeDirective, heroSectionStyles, heroSectionTemplate, html, injectTheme, isDirective, isFocusVisible, isSignal, lightTheme, lightThemeCss, listItemStyles, listItemTemplate, listStyles, listTemplate, loginPageStyles, loginPageTemplate, matchRouteTree, newID, offset, onAction, onThemeChange, pageHeaderStyles, pageHeaderTemplate, paginationStyles, paginationTemplate, portalDirective, primitiveColors, progressStyles, progressTemplate, props, provideConfig, provideHttp, provideRX, radioAdapter, registerAdapter, registerAttributeDirective, registerDefaultMessages, render, repeat, repeatRaw, resetStyles, resolveMessage, routerLinkDirective, selectStyles, selectTemplate, setActiveEffect, setDefaultMessage, shadowTokens, shift, sidebarGroupStyles, sidebarGroupTemplate, sidebarItemStyles, sidebarItemTemplate, sidebarStyles, sidebarTemplate, signal, signupPageStyles, signupPageTemplate, sliderStyles, sliderTemplate, spacingTokens, stepPanelStyles, stepPanelTemplate, stepStyles, stepTemplate, stepsStyles, stepsTemplate, styleMap, tabPanelStyles, tabPanelTemplate, tabStyles, tabTemplate, tableStyles, tableTemplate, tabsStyles, tabsTemplate, textAdapter, toastContainerStyles, toastContainerTemplate, toastStyles, toastTemplate, toggleTheme, tokensToCss, tooltipDirective, transitionTokens, typographyTokens, unregisterAttributeDirective, unsafeHTML, visuallyHiddenStyles, when };
|
|
24830
25547
|
|
|
24831
25548
|
//# sourceMappingURL=melodic-components.js.map
|