@aurodesignsystem/auro-formkit 3.1.0-beta.1 → 3.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/components/checkbox/README.md +1 -1
  3. package/components/checkbox/demo/api.min.js +468 -25
  4. package/components/checkbox/demo/index.min.js +468 -25
  5. package/components/checkbox/demo/readme.md +1 -1
  6. package/components/checkbox/dist/index.js +468 -25
  7. package/components/checkbox/dist/registered.js +468 -25
  8. package/components/combobox/README.md +1 -1
  9. package/components/combobox/demo/api.min.js +1125 -74
  10. package/components/combobox/demo/index.min.js +1125 -74
  11. package/components/combobox/demo/readme.md +1 -1
  12. package/components/combobox/dist/auro-combobox.d.ts +30 -0
  13. package/components/combobox/dist/index.js +1125 -74
  14. package/components/combobox/dist/registered.js +1125 -74
  15. package/components/counter/README.md +1 -1
  16. package/components/counter/demo/api.min.js +570 -45
  17. package/components/counter/demo/index.min.js +570 -45
  18. package/components/counter/demo/readme.md +1 -1
  19. package/components/counter/dist/index.js +570 -45
  20. package/components/counter/dist/registered.js +570 -45
  21. package/components/datepicker/README.md +1 -1
  22. package/components/datepicker/demo/api.min.js +1073 -70
  23. package/components/datepicker/demo/index.min.js +1073 -70
  24. package/components/datepicker/demo/readme.md +1 -1
  25. package/components/datepicker/dist/index.js +1073 -70
  26. package/components/datepicker/dist/registered.js +1073 -70
  27. package/components/dropdown/README.md +1 -1
  28. package/components/dropdown/demo/api.md +8 -5
  29. package/components/dropdown/demo/api.min.js +104 -22
  30. package/components/dropdown/demo/index.min.js +104 -22
  31. package/components/dropdown/demo/readme.md +1 -1
  32. package/components/dropdown/dist/auro-dropdown.d.ts +29 -0
  33. package/components/dropdown/dist/index.js +104 -22
  34. package/components/dropdown/dist/registered.js +104 -22
  35. package/components/form/README.md +1 -1
  36. package/components/form/demo/readme.md +1 -1
  37. package/components/input/README.md +1 -1
  38. package/components/input/demo/api.md +4 -1
  39. package/components/input/demo/api.min.js +503 -25
  40. package/components/input/demo/index.min.js +503 -25
  41. package/components/input/demo/readme.md +1 -1
  42. package/components/input/dist/base-input.d.ts +24 -0
  43. package/components/input/dist/index.js +503 -25
  44. package/components/input/dist/registered.js +503 -25
  45. package/components/menu/README.md +1 -1
  46. package/components/menu/demo/readme.md +1 -1
  47. package/components/radio/README.md +1 -1
  48. package/components/radio/demo/api.min.js +468 -25
  49. package/components/radio/demo/index.min.js +468 -25
  50. package/components/radio/demo/readme.md +1 -1
  51. package/components/radio/dist/index.js +468 -25
  52. package/components/radio/dist/registered.js +468 -25
  53. package/components/select/README.md +1 -1
  54. package/components/select/demo/api.min.js +570 -45
  55. package/components/select/demo/index.min.js +570 -45
  56. package/components/select/demo/readme.md +1 -1
  57. package/components/select/dist/index.js +570 -45
  58. package/components/select/dist/registered.js +570 -45
  59. package/package.json +2 -2
@@ -380,11 +380,420 @@ var styleCss$1 = i$5`:host{display:block;padding-bottom:var(--ds-size-150, 0.75r
380
380
 
381
381
  var colorCss$1 = i$5`:host legend{color:var(--ds-auro-radio-group-label-color)}:host([disabled]){--ds-auro-radio-group-label-color: var(--ds-basic-color-texticon-disabled, #d0d0d0)}:host([onDark]){--ds-auro-radio-group-label-color: var(--ds-basic-color-texticon-inverse, #ffffff)}:host([onDark][disabled]){--ds-auro-radio-group-label-color: var(--ds-basic-color-texticon-inverse-disabled, #7e8894)}`;
382
382
 
383
+ class DateFormatter {
384
+
385
+ constructor() {
386
+
387
+ /**
388
+ * @description Parses a date string into its components.
389
+ * @param {string} dateStr - Date string to parse.
390
+ * @param {string} format - Date format to parse.
391
+ * @returns {Object<key["month" | "day" | "year"]: number>|undefined}
392
+ */
393
+ this.parseDate = (dateStr, format = 'mm/dd/yyyy') => {
394
+
395
+ // Guard Clause: Date string is defined
396
+ if (!dateStr) {
397
+ return undefined;
398
+ }
399
+
400
+ // Assume the separator is a "/" a defined in our code base
401
+ const separator = '/';
402
+
403
+ // Get the parts of the date and format
404
+ const valueParts = dateStr.split(separator);
405
+ const formatParts = format.split(separator);
406
+
407
+ // Check if the value and format have the correct number of parts
408
+ if (valueParts.length !== formatParts.length) {
409
+ throw new Error('AuroDatepickerUtilities | parseDate: Date string and format length do not match');
410
+ }
411
+
412
+ // Holds the result to be returned
413
+ const result = formatParts.reduce((acc, part, index) => {
414
+ const value = valueParts[index];
415
+
416
+ if ((/m/iu).test(part)) {
417
+ acc.month = value;
418
+ } else if ((/d/iu).test(part)) {
419
+ acc.day = value;
420
+ } else if ((/y/iu).test(part)) {
421
+ acc.year = value;
422
+ }
423
+
424
+ return acc;
425
+ }, {});
426
+
427
+ // If we found all the parts, return the result
428
+ if (result.month && result.year) {
429
+ return result;
430
+ }
431
+
432
+ // Throw an error to let the dev know we were unable to parse the date string
433
+ throw new Error('AuroDatepickerUtilities | parseDate: Unable to parse date string');
434
+ };
435
+
436
+ /**
437
+ * Convert a date object to string format.
438
+ * @param {Object} date - Date to convert to string.
439
+ * @returns {Object} Returns the date as a string.
440
+ */
441
+ this.getDateAsString = (date) => date.toLocaleDateString(undefined, {
442
+ year: "numeric",
443
+ month: "2-digit",
444
+ day: "2-digit",
445
+ });
446
+
447
+ /**
448
+ * Converts a date string to a North American date format.
449
+ * @param {String} dateStr - Date to validate.
450
+ * @param {String} format - Date format to validate against.
451
+ * @returns {Boolean}
452
+ */
453
+ this.toNorthAmericanFormat = (dateStr, format) => {
454
+
455
+ if (format === 'mm/dd/yyyy') {
456
+ return dateStr;
457
+ }
458
+
459
+ const parsedDate = this.parseDate(dateStr, format);
460
+
461
+ if (!parsedDate) {
462
+ throw new Error('AuroDatepickerUtilities | toNorthAmericanFormat: Unable to parse date string');
463
+ }
464
+
465
+ const { month, day, year } = parsedDate;
466
+
467
+ const dateParts = [];
468
+ if (month) {
469
+ dateParts.push(month);
470
+ }
471
+
472
+ if (day) {
473
+ dateParts.push(day);
474
+ }
475
+
476
+ if (year) {
477
+ dateParts.push(year);
478
+ }
479
+
480
+ return dateParts.join('/');
481
+ };
482
+ }
483
+ }
484
+ const dateFormatter = new DateFormatter();
485
+
486
+ // filepath: dateConstraints.mjs
487
+ const DATE_UTIL_CONSTRAINTS = {
488
+ maxDay: 31,
489
+ maxMonth: 12,
490
+ maxYear: 2400,
491
+ minDay: 1,
492
+ minMonth: 1,
493
+ minYear: 1900,
494
+ };
495
+
496
+ class AuroDateUtilitiesBase {
497
+
498
+ /**
499
+ * @description The maximum day value allowed by the various utilities in this class.
500
+ * @readonly
501
+ * @type {Number}
502
+ */
503
+ get maxDay() {
504
+ return DATE_UTIL_CONSTRAINTS.maxDay;
505
+ }
506
+
507
+ /**
508
+ * @description The maximum month value allowed by the various utilities in this class.
509
+ * @readonly
510
+ * @type {Number}
511
+ */
512
+ get maxMonth() {
513
+ return DATE_UTIL_CONSTRAINTS.maxMonth;
514
+ }
515
+
516
+ /**
517
+ * @description The maximum year value allowed by the various utilities in this class.
518
+ * @readonly
519
+ * @type {Number}
520
+ */
521
+ get maxYear() {
522
+ return DATE_UTIL_CONSTRAINTS.maxYear;
523
+ }
524
+
525
+ /**
526
+ * @description The minimum day value allowed by the various utilities in this class.
527
+ * @readonly
528
+ * @type {Number}
529
+ */
530
+ get minDay() {
531
+ return DATE_UTIL_CONSTRAINTS.minDay;
532
+ }
533
+
534
+ /**
535
+ * @description The minimum month value allowed by the various utilities in this class.
536
+ * @readonly
537
+ * @type {Number}
538
+ */
539
+ get minMonth() {
540
+ return DATE_UTIL_CONSTRAINTS.minMonth;
541
+ }
542
+
543
+ /**
544
+ * @description The minimum year value allowed by the various utilities in this class.
545
+ * @readonly
546
+ * @type {Number}
547
+ */
548
+ get minYear() {
549
+ return DATE_UTIL_CONSTRAINTS.minYear;
550
+ }
551
+ }
552
+
553
+ /* eslint-disable no-magic-numbers */
554
+
555
+ class AuroDateUtilities extends AuroDateUtilitiesBase {
556
+
557
+ /**
558
+ * Returns the current century.
559
+ * @returns {String} The current century.
560
+ */
561
+ getCentury () {
562
+ return String(new Date().getFullYear()).slice(0, 2);
563
+ }
564
+
565
+ /**
566
+ * Returns a four digit year.
567
+ * @param {String} year - The year to convert to four digits.
568
+ * @returns {String} The four digit year.
569
+ */
570
+ getFourDigitYear (year) {
571
+
572
+ const strYear = String(year).trim();
573
+ return strYear.length <= 2 ? this.getCentury() + strYear : strYear;
574
+ }
575
+
576
+ constructor() {
577
+
578
+ super();
579
+
580
+ /**
581
+ * Compares two dates to see if they match.
582
+ * @param {Object} date1 - First date to compare.
583
+ * @param {Object} date2 - Second date to compare.
584
+ * @returns {Boolean} Returns true if the dates match.
585
+ */
586
+ this.datesMatch = (date1, date2) => new Date(date1).getTime() === new Date(date2).getTime();
587
+
588
+ /**
589
+ * Returns true if value passed in is a valid date.
590
+ * @param {String} date - Date to validate.
591
+ * @param {String} format - Date format to validate against.
592
+ * @returns {Boolean}
593
+ */
594
+ this.validDateStr = (date, format) => {
595
+
596
+ // The length we expect the date string to be
597
+ const dateStrLength = format.length;
598
+
599
+ // Guard Clause: Date and format are defined
600
+ if (typeof date === "undefined" || typeof format === "undefined") {
601
+ throw new Error('AuroDatepickerUtilities | validateDateStr: Date and format are required');
602
+ }
603
+
604
+ // Guard Clause: Date should be of type string
605
+ if (typeof date !== "string") {
606
+ throw new Error('AuroDatepickerUtilities | validateDateStr: Date must be a string');
607
+ }
608
+
609
+ // Guard Clause: Format should be of type string
610
+ if (typeof format !== "string") {
611
+ throw new Error('AuroDatepickerUtilities | validateDateStr: Format must be a string');
612
+ }
613
+
614
+ // Guard Clause: Length is what we expect it to be
615
+ if (date.length !== dateStrLength) {
616
+ return false;
617
+ }
618
+ // Get a formatted date string and parse it
619
+ const dateParts = dateFormatter.parseDate(date, format);
620
+
621
+ // Guard Clause: Date parse succeeded
622
+ if (!dateParts) {
623
+ return false;
624
+ }
625
+
626
+ // Create the expected date string based on the date parts
627
+ const expectedDateStr = `${dateParts.month}/${dateParts.day || "01"}/${this.getFourDigitYear(dateParts.year)}`;
628
+
629
+ // Generate a date object that we will extract a string date from to compare to the passed in date string
630
+ const dateObj = new Date(this.getFourDigitYear(dateParts.year), dateParts.month - 1, dateParts.day || 1);
631
+
632
+ // Get the date string of the date object we created from the string date
633
+ const actualDateStr = dateFormatter.getDateAsString(dateObj);
634
+
635
+ // Guard Clause: Generated date matches date string input
636
+ if (expectedDateStr !== actualDateStr) {
637
+ return false;
638
+ }
639
+
640
+ // If we passed all other checks, we can assume the date is valid
641
+ return true;
642
+ };
643
+
644
+ /**
645
+ * Determines if a string date value matches the format provided.
646
+ * @param {string} value = The date string value.
647
+ * @param { string} format = The date format to match against.
648
+ * @returns {boolean}
649
+ */
650
+ this.dateAndFormatMatch = (value, format) => {
651
+
652
+ // Ensure we have both values we need to do the comparison
653
+ if (!value || !format) {
654
+ throw new Error('AuroFormValidation | dateFormatMatch: value and format are required');
655
+ }
656
+
657
+ // If the lengths are different, they cannot match
658
+ if (value.length !== format.length) {
659
+ return false;
660
+ }
661
+
662
+ // Get the parts of the date
663
+ const dateParts = dateFormatter.parseDate(value, format);
664
+
665
+ // Validator for day
666
+ const dayValueIsValid = (day) => {
667
+
668
+ // Guard clause: if there is no day in the dateParts, we can ignore this check.
669
+ if (!dateParts.day) {
670
+ return true;
671
+ }
672
+
673
+ // Guard clause: ensure day exists.
674
+ if (!day) {
675
+ return false;
676
+ }
677
+
678
+ // Convert day to number
679
+ const numDay = Number.parseInt(day, 10);
680
+
681
+ // Guard clause: ensure day is a valid integer
682
+ if (Number.isNaN(numDay)) {
683
+ throw new Error('AuroDatepickerUtilities | dayValueIsValid: Unable to parse day value integer');
684
+ }
685
+
686
+ // Guard clause: ensure day is within the valid range
687
+ if (numDay < this.minDay || numDay > this.maxDay) {
688
+ return false;
689
+ }
690
+
691
+ // Default return
692
+ return true;
693
+ };
694
+
695
+ // Validator for month
696
+ const monthValueIsValid = (month) => {
697
+
698
+ // Guard clause: ensure month exists.
699
+ if (!month) {
700
+ return false;
701
+ }
702
+
703
+ // Convert month to number
704
+ const numMonth = Number.parseInt(month, 10);
705
+
706
+ // Guard clause: ensure month is a valid integer
707
+ if (Number.isNaN(numMonth)) {
708
+ throw new Error('AuroDatepickerUtilities | monthValueIsValid: Unable to parse month value integer');
709
+ }
710
+
711
+ // Guard clause: ensure month is within the valid range
712
+ if (numMonth < this.minMonth || numMonth > this.maxMonth) {
713
+ return false;
714
+ }
715
+
716
+ // Default return
717
+ return true;
718
+ };
719
+
720
+ // Validator for year
721
+ const yearIsValid = (_year) => {
722
+
723
+ // Guard clause: ensure year exists.
724
+ if (!_year) {
725
+ return false;
726
+ }
727
+
728
+ // Get the full year
729
+ const year = this.getFourDigitYear(_year);
730
+
731
+ // Convert year to number
732
+ const numYear = Number.parseInt(year, 10);
733
+
734
+ // Guard clause: ensure year is a valid integer
735
+ if (Number.isNaN(numYear)) {
736
+ throw new Error('AuroDatepickerUtilities | yearValueIsValid: Unable to parse year value integer');
737
+ }
738
+
739
+ // Guard clause: ensure year is within the valid range
740
+ if (numYear < this.minYear || numYear > this.maxYear) {
741
+ return false;
742
+ }
743
+
744
+ // Default return
745
+ return true;
746
+ };
747
+
748
+ // Self-contained checks for month, day, and year
749
+ const checks = [
750
+ monthValueIsValid(dateParts.month),
751
+ dayValueIsValid(dateParts.day),
752
+ yearIsValid(dateParts.year)
753
+ ];
754
+
755
+ // If any of the checks failed, the date format does not match and the result is invalid
756
+ const isValid = checks.every((check) => check === true);
757
+
758
+ // If the check is invalid, return false
759
+ if (!isValid) {
760
+ return false;
761
+ }
762
+
763
+ // Default case
764
+ return true;
765
+ };
766
+ }
767
+ }
768
+
769
+ // Export a class instance
770
+ const dateUtilities = new AuroDateUtilities();
771
+
772
+ // Export the class instance methods individually
773
+ const {
774
+ datesMatch,
775
+ validDateStr,
776
+ dateAndFormatMatch,
777
+ minDay,
778
+ minMonth,
779
+ minYear,
780
+ maxDay,
781
+ maxMonth,
782
+ maxYear
783
+ } = dateUtilities;
784
+
785
+ const {
786
+ toNorthAmericanFormat,
787
+ parseDate,
788
+ getDateAsString
789
+ } = dateFormatter;
790
+
383
791
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
384
792
  // See LICENSE in the project root for license information.
385
793
 
386
794
 
387
795
  class AuroFormValidation {
796
+
388
797
  constructor() {
389
798
  this.runtimeUtils = new AuroLibraryRuntimeUtils$1();
390
799
  }
@@ -476,17 +885,17 @@ class AuroFormValidation {
476
885
  ]
477
886
  }
478
887
  };
479
-
888
+
480
889
  let elementType;
481
890
  if (this.runtimeUtils.elementMatch(elem, 'auro-input')) {
482
891
  elementType = 'input';
483
892
  } else if (this.runtimeUtils.elementMatch(elem, 'auro-counter') || this.runtimeUtils.elementMatch(elem, 'auro-counter-group')) {
484
893
  elementType = 'counter';
485
894
  }
486
-
895
+
487
896
  if (elementType) {
488
897
  const rules = validationRules[elementType];
489
-
898
+
490
899
  if (rules) {
491
900
  Object.values(rules).flat().forEach(rule => {
492
901
  if (rule.check(elem)) {
@@ -512,48 +921,82 @@ class AuroFormValidation {
512
921
  if (!elem.value.match(emailRegex)) {
513
922
  elem.validity = 'patternMismatch';
514
923
  elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
924
+ return;
515
925
  }
516
926
  } else if (elem.type === 'credit-card') {
517
927
  if (elem.value.length > 0 && elem.value.length < elem.validationCCLength) {
518
928
  elem.validity = 'tooShort';
519
929
  elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
930
+ return;
520
931
  }
521
932
  } else if (elem.type === 'number') {
522
933
  if (elem.max !== undefined && Number(elem.max) < Number(elem.value)) {
523
934
  elem.validity = 'rangeOverflow';
524
935
  elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
936
+ return;
525
937
  }
526
938
 
527
939
  if (elem.min !== undefined && elem.value?.length > 0 && Number(elem.min) > Number(elem.value)) {
528
940
  elem.validity = 'rangeUnderflow';
529
941
  elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
942
+ return;
530
943
  }
531
- } else if (elem.type === 'date') {
532
- if (elem.value?.length > 0 && elem.value?.length < elem.lengthForType) {
944
+ } else if (elem.type === 'date' && elem.value?.length > 0) {
945
+
946
+ // Guard Clause: if the value is too short
947
+ if (elem.value.length < elem.lengthForType) {
948
+
533
949
  elem.validity = 'tooShort';
534
950
  elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
535
- } else if (elem.value?.length === elem.lengthForType && elem.util.toNorthAmericanFormat(elem.value, elem.format)) {
536
- const formattedValue = elem.util.toNorthAmericanFormat(elem.value, elem.format);
537
- const valueDate = new Date(formattedValue.dateForComparison);
538
-
539
- // validate max
540
- if (elem.max?.length === elem.lengthForType) {
541
- const maxDate = new Date(elem.util.toNorthAmericanFormat(elem.max, elem.format).dateForComparison);
542
-
543
- if (valueDate > maxDate) {
544
- elem.validity = 'rangeOverflow';
545
- elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
546
- }
951
+ return;
952
+ }
953
+
954
+ // Guard Clause: If the value is too long for the type
955
+ if (elem.value?.length > elem.lengthForType) {
956
+
957
+ elem.validity = 'tooLong';
958
+ elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || '';
959
+ return;
960
+ }
961
+
962
+ // Validate that the date passed was the correct format
963
+ if (!dateAndFormatMatch(elem.value, elem.format)) {
964
+ elem.validity = 'patternMismatch';
965
+ elem.errorMessage = elem.setCustomValidityForType || elem.setCustomValidity || 'Invalid Date Format Entered';
966
+ return;
967
+ }
968
+
969
+ // Validate that the date passed was a valid date
970
+ if (!validDateStr(elem.value, elem.format)) {
971
+ elem.validity = 'invalidDate';
972
+ elem.errorMessage = elem.setCustomValidityInvalidDate || elem.setCustomValidity || 'Invalid Date Entered';
973
+ return;
974
+ }
975
+
976
+ // Perform the rest of the validation
977
+ const formattedValue = toNorthAmericanFormat(elem.value, elem.format);
978
+ const valueDate = new Date(formattedValue);
979
+
980
+ // // Validate max date
981
+ if (elem.max?.length === elem.lengthForType) {
982
+
983
+ const maxDate = new Date(toNorthAmericanFormat(elem.max, elem.format));
984
+
985
+ if (valueDate > maxDate) {
986
+ elem.validity = 'rangeOverflow';
987
+ elem.errorMessage = elem.setCustomValidityRangeOverflow || elem.setCustomValidity || '';
988
+ return;
547
989
  }
990
+ }
548
991
 
549
- // validate min
550
- if (elem.min?.length === elem.lengthForType) {
551
- const minDate = new Date(elem.util.toNorthAmericanFormat(elem.min, elem.format).dateForComparison);
992
+ // Validate min date
993
+ if (elem.min?.length === elem.lengthForType) {
994
+ const minDate = new Date(toNorthAmericanFormat(elem.min, elem.format));
552
995
 
553
- if (valueDate < minDate) {
554
- elem.validity = 'rangeUnderflow';
555
- elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
556
- }
996
+ if (valueDate < minDate) {
997
+ elem.validity = 'rangeUnderflow';
998
+ elem.errorMessage = elem.setCustomValidityRangeUnderflow || elem.setCustomValidity || '';
999
+ return;
557
1000
  }
558
1001
  }
559
1002
  }
@@ -672,7 +1115,7 @@ class AuroFormValidation {
672
1115
  if (input.validationMessage.length > 0) {
673
1116
  elem.errorMessage = input.validationMessage;
674
1117
  }
675
- } else if (this.inputElements?.length > 0 && elem.errorMessage === '') {
1118
+ } else if (this.inputElements?.length > 0 && elem.errorMessage === '') {
676
1119
  const firstInput = this.inputElements[0];
677
1120
 
678
1121
  if (firstInput.validationMessage.length > 0) {
@@ -100,7 +100,7 @@ The use of any Auro custom element has a dependency on the [Auro Design Tokens](
100
100
  In cases where the project is not able to process JS assets, there are pre-processed assets available for use. Legacy browsers such as IE11 are no longer supported.
101
101
 
102
102
  ```html
103
- <script type="module" src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-formkit@3.0.1/auro-radio/+esm"></script>
103
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-formkit@3.1.0/auro-radio/+esm"></script>
104
104
  ```
105
105
  <!-- AURO-GENERATED-CONTENT:END -->
106
106