@aurodesignsystem-dev/auro-formkit 0.0.0-pr1424.2 → 0.0.0-pr1424.4

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 (62) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +133 -183
  3. package/components/checkbox/demo/api.min.js +3 -3
  4. package/components/checkbox/demo/index.min.js +3 -3
  5. package/components/checkbox/dist/index.js +3 -3
  6. package/components/checkbox/dist/registered.js +3 -3
  7. package/components/combobox/demo/api.html +1 -0
  8. package/components/combobox/demo/api.js +3 -1
  9. package/components/combobox/demo/api.md +75 -0
  10. package/components/combobox/demo/api.min.js +314 -172
  11. package/components/combobox/demo/index.min.js +301 -171
  12. package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +1 -1
  13. package/components/combobox/dist/index.js +291 -171
  14. package/components/combobox/dist/registered.js +291 -171
  15. package/components/counter/demo/api.html +3 -0
  16. package/components/counter/demo/api.js +4 -0
  17. package/components/counter/demo/api.md +130 -0
  18. package/components/counter/demo/api.min.js +320 -167
  19. package/components/counter/demo/index.min.js +300 -167
  20. package/components/counter/dist/counterGroupKeyboardStrategy.d.ts +3 -0
  21. package/components/counter/dist/index.js +300 -167
  22. package/components/counter/dist/registered.js +300 -167
  23. package/components/datepicker/demo/api.html +1 -0
  24. package/components/datepicker/demo/api.js +2 -0
  25. package/components/datepicker/demo/api.md +57 -0
  26. package/components/datepicker/demo/api.min.js +376 -171
  27. package/components/datepicker/demo/index.min.js +364 -171
  28. package/components/datepicker/dist/datepickerKeyboardStrategy.d.ts +3 -1
  29. package/components/datepicker/dist/index.js +364 -171
  30. package/components/datepicker/dist/registered.js +364 -171
  31. package/components/dropdown/demo/api.html +1 -0
  32. package/components/dropdown/demo/api.js +2 -0
  33. package/components/dropdown/demo/api.md +95 -0
  34. package/components/dropdown/demo/api.min.js +296 -165
  35. package/components/dropdown/demo/index.min.js +276 -165
  36. package/components/dropdown/dist/index.js +276 -165
  37. package/components/dropdown/dist/registered.js +276 -165
  38. package/components/form/demo/api.min.js +1254 -684
  39. package/components/form/demo/index.min.js +1254 -684
  40. package/components/input/demo/api.min.js +1 -1
  41. package/components/input/demo/index.min.js +1 -1
  42. package/components/input/dist/index.js +1 -1
  43. package/components/input/dist/registered.js +1 -1
  44. package/components/menu/demo/api.md +1 -0
  45. package/components/menu/demo/api.min.js +10 -0
  46. package/components/menu/demo/index.min.js +10 -0
  47. package/components/menu/dist/auro-menuoption.d.ts +9 -0
  48. package/components/menu/dist/index.js +10 -0
  49. package/components/menu/dist/registered.js +10 -0
  50. package/components/radio/demo/api.min.js +2 -2
  51. package/components/radio/demo/index.min.js +2 -2
  52. package/components/radio/dist/index.js +2 -2
  53. package/components/radio/dist/registered.js +2 -2
  54. package/components/select/demo/api.html +1 -0
  55. package/components/select/demo/api.js +2 -0
  56. package/components/select/demo/api.md +76 -0
  57. package/components/select/demo/api.min.js +306 -169
  58. package/components/select/demo/index.min.js +293 -169
  59. package/components/select/dist/index.js +283 -169
  60. package/components/select/dist/registered.js +283 -169
  61. package/custom-elements.json +48 -3
  62. package/package.json +5 -3
@@ -52,6 +52,17 @@ function inDialogExample() {
52
52
  });
53
53
  }
54
54
 
55
+ function inDrawerExample() {
56
+ document.querySelector("#combobox-drawer-opener").addEventListener("click", () => {
57
+ const drawer = document.querySelector("#combobox-drawer");
58
+ if (drawer.hasAttribute('open')) {
59
+ drawer.removeAttribute('open');
60
+ } else {
61
+ drawer.setAttribute('open', true);
62
+ }
63
+ });
64
+ }
65
+
55
66
  function persistentExample() {
56
67
  const persistentExample = document.querySelector('#persistent');
57
68
 
@@ -1421,10 +1432,19 @@ const comboboxKeyboardStrategy = {
1421
1432
  }
1422
1433
  },
1423
1434
 
1424
- Escape(component, _evt, ctx) {
1425
- if (ctx.isExpanded && ctx.isModal) {
1435
+ Escape(component, evt, ctx) {
1436
+ if (!ctx.isExpanded) {
1437
+ return;
1438
+ }
1439
+
1440
+ // Prevent the Escape key from bubbling up and closing any parent dialogs / drawers / popups
1441
+ evt.stopPropagation();
1442
+
1443
+ if (ctx.isModal) {
1426
1444
  component.setTriggerInputFocus();
1427
1445
  }
1446
+
1447
+ component.hideBib();
1428
1448
  },
1429
1449
 
1430
1450
  Home(component, evt, ctx) {
@@ -3312,11 +3332,19 @@ class AuroFloatingUI {
3312
3332
  * This ensures that the bib content has the same dimensions as the sizer element.
3313
3333
  */
3314
3334
  mirrorSize() {
3335
+ const element = this.element;
3336
+ if (!element) {
3337
+ return;
3338
+ }
3339
+
3315
3340
  // mirror the boxsize from bibSizer
3316
- if (this.element.bibSizer && this.element.matchWidth) {
3317
- const sizerStyle = window.getComputedStyle(this.element.bibSizer);
3318
- const bibContent =
3319
- this.element.bib.shadowRoot.querySelector(".container");
3341
+ if (element.bibSizer && element.matchWidth && element.bib?.shadowRoot) {
3342
+ const sizerStyle = window.getComputedStyle(element.bibSizer);
3343
+ const bibContent = element.bib.shadowRoot.querySelector(".container");
3344
+ if (!bibContent) {
3345
+ return;
3346
+ }
3347
+
3320
3348
  if (sizerStyle.width !== "0px") {
3321
3349
  bibContent.style.width = sizerStyle.width;
3322
3350
  }
@@ -3338,9 +3366,14 @@ class AuroFloatingUI {
3338
3366
  * @returns {String} The positioning strategy, one of 'fullscreen', 'floating', 'cover'.
3339
3367
  */
3340
3368
  getPositioningStrategy() {
3369
+ const element = this.element;
3370
+ if (!element) {
3371
+ return "floating";
3372
+ }
3373
+
3341
3374
  const breakpoint =
3342
- this.element.bib.mobileFullscreenBreakpoint ||
3343
- this.element.floaterConfig?.fullscreenBreakpoint;
3375
+ element.bib?.mobileFullscreenBreakpoint ||
3376
+ element.floaterConfig?.fullscreenBreakpoint;
3344
3377
  switch (this.behavior) {
3345
3378
  case "tooltip":
3346
3379
  return "floating";
@@ -3351,9 +3384,9 @@ class AuroFloatingUI {
3351
3384
  `(max-width: ${breakpoint})`,
3352
3385
  ).matches;
3353
3386
 
3354
- this.element.expanded = smallerThanBreakpoint;
3387
+ element.expanded = smallerThanBreakpoint;
3355
3388
  }
3356
- if (this.element.nested) {
3389
+ if (element.nested) {
3357
3390
  return "cover";
3358
3391
  }
3359
3392
  return "fullscreen";
@@ -3383,42 +3416,65 @@ class AuroFloatingUI {
3383
3416
  * and applies the calculated position to the bib's style.
3384
3417
  */
3385
3418
  position() {
3419
+ const element = this.element;
3420
+ if (!element) {
3421
+ return;
3422
+ }
3423
+
3386
3424
  const strategy = this.getPositioningStrategy();
3387
3425
  this.configureBibStrategy(strategy);
3388
3426
 
3389
3427
  if (strategy === "floating") {
3428
+ if (!element.trigger || !element.bib) {
3429
+ return;
3430
+ }
3431
+
3390
3432
  this.mirrorSize();
3391
3433
  // Define the middlware for the floater configuration
3392
3434
  const middleware = [
3393
- offset(this.element.floaterConfig?.offset || 0),
3394
- ...(this.element.floaterConfig?.shift ? [shift()] : []), // Add shift middleware if shift is enabled.
3395
- ...(this.element.floaterConfig?.flip ? [flip()] : []), // Add flip middleware if flip is enabled.
3396
- ...(this.element.floaterConfig?.autoPlacement ? [autoPlacement()] : []), // Add autoPlacement middleware if autoPlacement is enabled.
3435
+ offset(element.floaterConfig?.offset || 0),
3436
+ ...(element.floaterConfig?.shift ? [shift()] : []), // Add shift middleware if shift is enabled.
3437
+ ...(element.floaterConfig?.flip ? [flip()] : []), // Add flip middleware if flip is enabled.
3438
+ ...(element.floaterConfig?.autoPlacement ? [autoPlacement()] : []), // Add autoPlacement middleware if autoPlacement is enabled.
3397
3439
  ];
3398
3440
 
3399
3441
  // Compute the position of the bib
3400
- computePosition(this.element.trigger, this.element.bib, {
3401
- strategy: this.element.floaterConfig?.strategy || "fixed",
3402
- placement: this.element.floaterConfig?.placement,
3442
+ computePosition(element.trigger, element.bib, {
3443
+ strategy: element.floaterConfig?.strategy || "fixed",
3444
+ placement: element.floaterConfig?.placement,
3403
3445
  middleware: middleware || [],
3404
3446
  }).then(({ x, y }) => {
3405
3447
  // eslint-disable-line id-length
3406
- Object.assign(this.element.bib.style, {
3448
+ const currentElement = this.element;
3449
+ if (!currentElement?.bib) {
3450
+ return;
3451
+ }
3452
+
3453
+ Object.assign(currentElement.bib.style, {
3407
3454
  left: `${x}px`,
3408
3455
  top: `${y}px`,
3409
3456
  });
3410
3457
  });
3411
3458
  } else if (strategy === "cover") {
3459
+ if (!element.parentNode || !element.bib) {
3460
+ return;
3461
+ }
3462
+
3412
3463
  // Compute the position of the bib
3413
- computePosition(this.element.parentNode, this.element.bib, {
3464
+ computePosition(element.parentNode, element.bib, {
3414
3465
  placement: "bottom-start",
3415
3466
  }).then(({ x, y }) => {
3416
3467
  // eslint-disable-line id-length
3417
- Object.assign(this.element.bib.style, {
3468
+ const currentElement = this.element;
3469
+ if (!currentElement?.bib || !currentElement.parentNode) {
3470
+ return;
3471
+ }
3472
+
3473
+ Object.assign(currentElement.bib.style, {
3418
3474
  left: `${x}px`,
3419
- top: `${y - this.element.parentNode.offsetHeight}px`,
3420
- width: `${this.element.parentNode.offsetWidth}px`,
3421
- height: `${this.element.parentNode.offsetHeight}px`,
3475
+ top: `${y - currentElement.parentNode.offsetHeight}px`,
3476
+ width: `${currentElement.parentNode.offsetWidth}px`,
3477
+ height: `${currentElement.parentNode.offsetHeight}px`,
3422
3478
  });
3423
3479
  });
3424
3480
  }
@@ -3430,11 +3486,17 @@ class AuroFloatingUI {
3430
3486
  * @param {Boolean} lock - If true, locks the body's scrolling functionlity; otherwise, unlock.
3431
3487
  */
3432
3488
  lockScroll(lock = true) {
3489
+ const element = this.element;
3490
+
3433
3491
  if (lock) {
3492
+ if (!element?.bib) {
3493
+ return;
3494
+ }
3495
+
3434
3496
  document.body.style.overflow = "hidden"; // hide body's scrollbar
3435
3497
 
3436
3498
  // Move `bib` by the amount the viewport is shifted to stay aligned in fullscreen.
3437
- this.element.bib.style.transform = `translateY(${window?.visualViewport?.offsetTop}px)`;
3499
+ element.bib.style.transform = `translateY(${window?.visualViewport?.offsetTop}px)`;
3438
3500
  } else {
3439
3501
  document.body.style.overflow = "";
3440
3502
  }
@@ -3450,20 +3512,24 @@ class AuroFloatingUI {
3450
3512
  * @param {string} strategy - The positioning strategy ('fullscreen' or 'floating').
3451
3513
  */
3452
3514
  configureBibStrategy(value) {
3515
+ const element = this.element;
3516
+ if (!element?.bib) {
3517
+ return;
3518
+ }
3519
+
3453
3520
  if (value === "fullscreen") {
3454
- this.element.isBibFullscreen = true;
3521
+ element.isBibFullscreen = true;
3455
3522
  // reset the prev position
3456
- this.element.bib.setAttribute("isfullscreen", "");
3457
- this.element.bib.style.position = "fixed";
3458
- this.element.bib.style.top = "0px";
3459
- this.element.bib.style.left = "0px";
3460
- this.element.bib.style.width = "";
3461
- this.element.bib.style.height = "";
3462
- this.element.style.contain = "";
3523
+ element.bib.setAttribute("isfullscreen", "");
3524
+ element.bib.style.position = "fixed";
3525
+ element.bib.style.top = "0px";
3526
+ element.bib.style.left = "0px";
3527
+ element.bib.style.width = "";
3528
+ element.bib.style.height = "";
3529
+ element.style.contain = "";
3463
3530
 
3464
3531
  // reset the size that was mirroring `size` css-part
3465
- const bibContent =
3466
- this.element.bib.shadowRoot.querySelector(".container");
3532
+ const bibContent = element.bib.shadowRoot?.querySelector(".container");
3467
3533
  if (bibContent) {
3468
3534
  bibContent.style.width = "";
3469
3535
  bibContent.style.height = "";
@@ -3478,14 +3544,14 @@ class AuroFloatingUI {
3478
3544
  }, 0);
3479
3545
  }
3480
3546
 
3481
- if (this.element.isPopoverVisible) {
3547
+ if (element.isPopoverVisible) {
3482
3548
  this.lockScroll(true);
3483
3549
  }
3484
3550
  } else {
3485
- this.element.bib.style.position = "";
3486
- this.element.bib.removeAttribute("isfullscreen");
3487
- this.element.isBibFullscreen = false;
3488
- this.element.style.contain = "layout";
3551
+ element.bib.style.position = "";
3552
+ element.bib.removeAttribute("isfullscreen");
3553
+ element.isBibFullscreen = false;
3554
+ element.style.contain = "layout";
3489
3555
  }
3490
3556
 
3491
3557
  const isChanged = this.strategy && this.strategy !== value;
@@ -3503,16 +3569,21 @@ class AuroFloatingUI {
3503
3569
  },
3504
3570
  );
3505
3571
 
3506
- this.element.dispatchEvent(event);
3572
+ element.dispatchEvent(event);
3507
3573
  }
3508
3574
  }
3509
3575
 
3510
3576
  updateState() {
3511
- const isVisible = this.element.isPopoverVisible;
3577
+ const element = this.element;
3578
+ if (!element) {
3579
+ return;
3580
+ }
3581
+
3582
+ const isVisible = element.isPopoverVisible;
3512
3583
  if (!isVisible) {
3513
3584
  this.cleanupHideHandlers();
3514
3585
  try {
3515
- this.element.cleanup?.();
3586
+ element.cleanup?.();
3516
3587
  } catch (error) {
3517
3588
  // Do nothing
3518
3589
  }
@@ -3528,28 +3599,30 @@ class AuroFloatingUI {
3528
3599
  * If not, and if the bib isn't in fullscreen mode with focus lost, it hides the bib.
3529
3600
  */
3530
3601
  handleFocusLoss() {
3602
+ const element = this.element;
3603
+ if (!element?.bib) {
3604
+ return;
3605
+ }
3606
+
3531
3607
  // if mouse is being pressed, skip and let click event to handle the action
3532
3608
  if (AuroFloatingUI.isMousePressed) {
3533
3609
  return;
3534
3610
  }
3535
3611
 
3536
3612
  if (
3537
- this.element.noHideOnThisFocusLoss ||
3538
- this.element.hasAttribute("noHideOnThisFocusLoss")
3613
+ element.noHideOnThisFocusLoss ||
3614
+ element.hasAttribute("noHideOnThisFocusLoss")
3539
3615
  ) {
3540
3616
  return;
3541
3617
  }
3542
3618
 
3543
3619
  // if focus is still inside of trigger or bib, do not close
3544
- if (
3545
- this.element.matches(":focus") ||
3546
- this.element.matches(":focus-within")
3547
- ) {
3620
+ if (element.matches(":focus") || element.matches(":focus-within")) {
3548
3621
  return;
3549
3622
  }
3550
3623
 
3551
3624
  // if fullscreen bib is in fullscreen mode, do not close
3552
- if (this.element.bib.hasAttribute("isfullscreen")) {
3625
+ if (element.bib.hasAttribute("isfullscreen")) {
3553
3626
  return;
3554
3627
  }
3555
3628
 
@@ -3557,23 +3630,33 @@ class AuroFloatingUI {
3557
3630
  }
3558
3631
 
3559
3632
  setupHideHandlers() {
3633
+ const element = this.element;
3634
+ if (!element) {
3635
+ return;
3636
+ }
3637
+
3560
3638
  // Define handlers & store references
3561
3639
  this.focusHandler = () => this.handleFocusLoss();
3562
3640
 
3563
3641
  this.clickHandler = (evt) => {
3642
+ const element = this.element;
3643
+ if (!element?.bib) {
3644
+ return;
3645
+ }
3646
+
3564
3647
  // When the bib is fullscreen (modal dialog), don't close on outside
3565
3648
  // clicks. VoiceOver's synthetic click events inside a top-layer modal
3566
3649
  // <dialog> may not include the bib in composedPath(), causing false
3567
3650
  // positives. This mirrors the fullscreen guard in handleFocusLoss().
3568
- if (this.element.bib && this.element.bib.hasAttribute("isfullscreen")) {
3651
+ if (element.bib.hasAttribute("isfullscreen")) {
3569
3652
  return;
3570
3653
  }
3571
3654
 
3572
3655
  if (
3573
- (!evt.composedPath().includes(this.element.trigger) &&
3574
- !evt.composedPath().includes(this.element.bib)) ||
3575
- (this.element.bib.backdrop &&
3576
- evt.composedPath().includes(this.element.bib.backdrop))
3656
+ (!evt.composedPath().includes(element.trigger) &&
3657
+ !evt.composedPath().includes(element.bib)) ||
3658
+ (element.bib.backdrop &&
3659
+ evt.composedPath().includes(element.bib.backdrop))
3577
3660
  ) {
3578
3661
  const existedVisibleFloatingUI =
3579
3662
  document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
@@ -3594,7 +3677,12 @@ class AuroFloatingUI {
3594
3677
 
3595
3678
  // ESC key handler
3596
3679
  this.keyDownHandler = (evt) => {
3597
- if (evt.key === "Escape" && this.element.isPopoverVisible) {
3680
+ const element = this.element;
3681
+ if (!element) {
3682
+ return;
3683
+ }
3684
+
3685
+ if (evt.key === "Escape" && element.isPopoverVisible) {
3598
3686
  const existedVisibleFloatingUI =
3599
3687
  document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
3600
3688
  if (
@@ -3651,6 +3739,10 @@ class AuroFloatingUI {
3651
3739
  }
3652
3740
 
3653
3741
  updateCurrentExpandedDropdown() {
3742
+ if (!this.element) {
3743
+ return;
3744
+ }
3745
+
3654
3746
  // Close any other dropdown that is already open
3655
3747
  const existedVisibleFloatingUI =
3656
3748
  document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
@@ -3667,25 +3759,34 @@ class AuroFloatingUI {
3667
3759
  }
3668
3760
 
3669
3761
  showBib() {
3670
- if (!this.element.disabled && !this.showing) {
3762
+ const element = this.element;
3763
+ if (!element) {
3764
+ return;
3765
+ }
3766
+
3767
+ if (!element.bib || (!element.trigger && !element.parentNode)) {
3768
+ return;
3769
+ }
3770
+
3771
+ if (!element.disabled && !this.showing) {
3671
3772
  this.updateCurrentExpandedDropdown();
3672
- this.element.triggerChevron?.setAttribute("data-expanded", true);
3773
+ element.triggerChevron?.setAttribute("data-expanded", true);
3673
3774
 
3674
3775
  // prevent double showing: isPopovervisible gets first and showBib gets called later
3675
3776
  if (!this.showing) {
3676
- if (!this.element.modal) {
3777
+ if (!element.modal) {
3677
3778
  this.setupHideHandlers();
3678
3779
  }
3679
3780
  this.showing = true;
3680
- this.element.isPopoverVisible = true;
3781
+ element.isPopoverVisible = true;
3681
3782
  this.position();
3682
3783
  this.dispatchEventDropdownToggle();
3683
3784
  }
3684
3785
 
3685
3786
  // Setup auto update to handle resize and scroll
3686
- this.element.cleanup = autoUpdate(
3687
- this.element.trigger || this.element.parentNode,
3688
- this.element.bib,
3787
+ element.cleanup = autoUpdate(
3788
+ element.trigger || element.parentNode,
3789
+ element.bib,
3689
3790
  () => {
3690
3791
  this.position();
3691
3792
  },
@@ -3698,22 +3799,27 @@ class AuroFloatingUI {
3698
3799
  * @param {String} eventType - The event type that triggered the hiding action.
3699
3800
  */
3700
3801
  hideBib(eventType = "unknown") {
3701
- if (this.element.disabled) {
3802
+ const element = this.element;
3803
+ if (!element) {
3804
+ return;
3805
+ }
3806
+
3807
+ if (element.disabled) {
3702
3808
  return;
3703
3809
  }
3704
3810
 
3705
3811
  // noToggle dropdowns should not close when the trigger is clicked (the
3706
3812
  // "toggle" behavior), but they CAN still close via other interactions like
3707
3813
  // Escape key or focus loss.
3708
- if (this.element.noToggle && eventType === "click") {
3814
+ if (element.noToggle && eventType === "click") {
3709
3815
  return;
3710
3816
  }
3711
3817
 
3712
3818
  this.lockScroll(false);
3713
- this.element.triggerChevron?.removeAttribute("data-expanded");
3819
+ element.triggerChevron?.removeAttribute("data-expanded");
3714
3820
 
3715
- if (this.element.isPopoverVisible) {
3716
- this.element.isPopoverVisible = false;
3821
+ if (element.isPopoverVisible) {
3822
+ element.isPopoverVisible = false;
3717
3823
  }
3718
3824
  if (this.showing) {
3719
3825
  this.cleanupHideHandlers();
@@ -3733,6 +3839,11 @@ class AuroFloatingUI {
3733
3839
  * @param {String} eventType - The event type that triggered the toggle action.
3734
3840
  */
3735
3841
  dispatchEventDropdownToggle(eventType) {
3842
+ const element = this.element;
3843
+ if (!element) {
3844
+ return;
3845
+ }
3846
+
3736
3847
  const event = new CustomEvent(
3737
3848
  this.eventPrefix ? `${this.eventPrefix}-toggled` : "toggled",
3738
3849
  {
@@ -3744,11 +3855,16 @@ class AuroFloatingUI {
3744
3855
  },
3745
3856
  );
3746
3857
 
3747
- this.element.dispatchEvent(event);
3858
+ element.dispatchEvent(event);
3748
3859
  }
3749
3860
 
3750
3861
  handleClick() {
3751
- if (this.element.isPopoverVisible) {
3862
+ const element = this.element;
3863
+ if (!element) {
3864
+ return;
3865
+ }
3866
+
3867
+ if (element.isPopoverVisible) {
3752
3868
  this.hideBib("click");
3753
3869
  } else {
3754
3870
  this.showBib();
@@ -3759,63 +3875,66 @@ class AuroFloatingUI {
3759
3875
  {
3760
3876
  composed: true,
3761
3877
  detail: {
3762
- expanded: this.element.isPopoverVisible,
3878
+ expanded: element.isPopoverVisible,
3763
3879
  },
3764
3880
  },
3765
3881
  );
3766
3882
 
3767
- this.element.dispatchEvent(event);
3883
+ element.dispatchEvent(event);
3768
3884
  }
3769
3885
 
3770
3886
  handleEvent(event) {
3771
- if (!this.element.disableEventShow) {
3772
- switch (event.type) {
3773
- case "keydown": {
3774
- // Support both Enter and Space keys for accessibility
3775
- // Space is included as it's expected behavior for interactive elements
3776
-
3777
- const origin = event.composedPath()[0];
3778
- if (
3779
- event.key === "Enter" ||
3780
- (event.key === " " && (!origin || origin.tagName !== "INPUT"))
3781
- ) {
3782
- event.preventDefault();
3783
- this.handleClick();
3784
- }
3785
- break;
3786
- }
3787
- case "mouseenter":
3788
- if (this.element.hoverToggle) {
3789
- this.showBib();
3790
- }
3791
- break;
3792
- case "mouseleave":
3793
- if (this.element.hoverToggle) {
3794
- this.hideBib("mouseleave");
3795
- }
3796
- break;
3797
- case "focus":
3798
- if (this.element.focusShow) {
3799
- /*
3800
- This needs to better handle clicking that gives focus -
3801
- currently it shows and then immediately hides the bib
3802
- */
3803
- this.showBib();
3804
- }
3805
- break;
3806
- case "blur":
3807
- // send this task 100ms later queue to
3808
- // wait a frame in case focus moves within the floating element/bib
3809
- setTimeout(() => this.handleFocusLoss(), 0);
3810
- break;
3811
- case "click":
3812
- if (document.activeElement === document.body) {
3813
- event.currentTarget.focus();
3814
- }
3887
+ const element = this.element;
3888
+ if (!element || element.disableEventShow) {
3889
+ return;
3890
+ }
3891
+
3892
+ switch (event.type) {
3893
+ case "keydown": {
3894
+ // Support both Enter and Space keys for accessibility
3895
+ // Space is included as it's expected behavior for interactive elements
3896
+
3897
+ const origin = event.composedPath()[0];
3898
+ if (
3899
+ event.key === "Enter" ||
3900
+ (event.key === " " && (!origin || origin.tagName !== "INPUT"))
3901
+ ) {
3902
+ event.preventDefault();
3815
3903
  this.handleClick();
3816
- break;
3817
- // Do nothing
3904
+ }
3905
+ break;
3818
3906
  }
3907
+ case "mouseenter":
3908
+ if (element.hoverToggle) {
3909
+ this.showBib();
3910
+ }
3911
+ break;
3912
+ case "mouseleave":
3913
+ if (element.hoverToggle) {
3914
+ this.hideBib("mouseleave");
3915
+ }
3916
+ break;
3917
+ case "focus":
3918
+ if (element.focusShow) {
3919
+ /*
3920
+ This needs to better handle clicking that gives focus -
3921
+ currently it shows and then immediately hides the bib
3922
+ */
3923
+ this.showBib();
3924
+ }
3925
+ break;
3926
+ case "blur":
3927
+ // send this task 100ms later queue to
3928
+ // wait a frame in case focus moves within the floating element/bib
3929
+ setTimeout(() => this.handleFocusLoss(), 0);
3930
+ break;
3931
+ case "click":
3932
+ if (document.activeElement === document.body) {
3933
+ event.currentTarget.focus();
3934
+ }
3935
+ this.handleClick();
3936
+ break;
3937
+ // Do nothing
3819
3938
  }
3820
3939
  }
3821
3940
 
@@ -3826,6 +3945,11 @@ class AuroFloatingUI {
3826
3945
  * This prevents the component itself from being focusable when the trigger element already handles focus.
3827
3946
  */
3828
3947
  handleTriggerTabIndex() {
3948
+ const element = this.element;
3949
+ if (!element) {
3950
+ return;
3951
+ }
3952
+
3829
3953
  const focusableElementSelectors = [
3830
3954
  "a",
3831
3955
  "button",
@@ -3838,7 +3962,7 @@ class AuroFloatingUI {
3838
3962
  "auro-hyperlink",
3839
3963
  ];
3840
3964
 
3841
- const triggerNode = this.element.querySelectorAll('[slot="trigger"]')[0];
3965
+ const triggerNode = element.querySelectorAll('[slot="trigger"]')[0];
3842
3966
  if (!triggerNode) {
3843
3967
  return;
3844
3968
  }
@@ -3847,13 +3971,13 @@ class AuroFloatingUI {
3847
3971
  focusableElementSelectors.forEach((selector) => {
3848
3972
  // Check if the trigger node element is focusable
3849
3973
  if (triggerNodeTagName === selector) {
3850
- this.element.tabIndex = -1;
3974
+ element.tabIndex = -1;
3851
3975
  return;
3852
3976
  }
3853
3977
 
3854
3978
  // Check if any child is focusable
3855
3979
  if (triggerNode.querySelector(selector)) {
3856
- this.element.tabIndex = -1;
3980
+ element.tabIndex = -1;
3857
3981
  }
3858
3982
  });
3859
3983
  }
@@ -3863,13 +3987,18 @@ class AuroFloatingUI {
3863
3987
  * @param {*} eventPrefix
3864
3988
  */
3865
3989
  regenerateBibId() {
3866
- this.id = this.element.getAttribute("id");
3990
+ const element = this.element;
3991
+ if (!element) {
3992
+ return;
3993
+ }
3994
+
3995
+ this.id = element.getAttribute("id");
3867
3996
  if (!this.id) {
3868
3997
  this.id = window.crypto.randomUUID();
3869
- this.element.setAttribute("id", this.id);
3998
+ element.setAttribute("id", this.id);
3870
3999
  }
3871
4000
 
3872
- this.element.bib.setAttribute("id", `${this.id}-floater-bib`);
4001
+ element.bib?.setAttribute("id", `${this.id}-floater-bib`);
3873
4002
  }
3874
4003
 
3875
4004
  configure(elem, eventPrefix, enableKeyboardHandling = true) {
@@ -3881,67 +4010,69 @@ class AuroFloatingUI {
3881
4010
  this.element = elem;
3882
4011
  }
3883
4012
 
3884
- if (this.behavior !== this.element.behavior) {
3885
- this.behavior = this.element.behavior;
4013
+ const element = this.element;
4014
+ if (!element) {
4015
+ return;
4016
+ }
4017
+
4018
+ if (this.behavior !== element.behavior) {
4019
+ this.behavior = element.behavior;
3886
4020
  }
3887
4021
 
3888
- if (this.element.trigger) {
4022
+ if (element.trigger) {
3889
4023
  this.disconnect();
3890
4024
  }
3891
- this.element.trigger =
3892
- this.element.triggerElement ||
3893
- this.element.shadowRoot.querySelector("#trigger") ||
3894
- this.element.trigger;
3895
- this.element.bib =
3896
- this.element.shadowRoot.querySelector("#bib") || this.element.bib;
3897
- this.element.bibSizer = this.element.shadowRoot.querySelector("#bibSizer");
3898
- this.element.triggerChevron =
3899
- this.element.shadowRoot.querySelector("#showStateIcon");
4025
+ element.trigger =
4026
+ element.triggerElement ||
4027
+ element.shadowRoot?.querySelector("#trigger") ||
4028
+ element.trigger;
4029
+ element.bib = element.shadowRoot?.querySelector("#bib") || element.bib;
4030
+ element.bibSizer = element.shadowRoot?.querySelector("#bibSizer");
4031
+ element.triggerChevron =
4032
+ element.shadowRoot?.querySelector("#showStateIcon");
3900
4033
 
3901
- if (this.element.floaterConfig) {
3902
- this.element.hoverToggle = this.element.floaterConfig.hoverToggle;
4034
+ if (element.floaterConfig) {
4035
+ element.hoverToggle = element.floaterConfig.hoverToggle;
3903
4036
  }
3904
4037
 
3905
4038
  this.regenerateBibId();
3906
4039
  this.handleTriggerTabIndex();
3907
4040
 
3908
4041
  this.handleEvent = this.handleEvent.bind(this);
3909
- if (this.element.trigger) {
4042
+ if (element.trigger) {
3910
4043
  if (this.enableKeyboardHandling) {
3911
- this.element.trigger.addEventListener("keydown", this.handleEvent);
4044
+ element.trigger.addEventListener("keydown", this.handleEvent);
3912
4045
  }
3913
- this.element.trigger.addEventListener("click", this.handleEvent);
3914
- this.element.trigger.addEventListener("mouseenter", this.handleEvent);
3915
- this.element.trigger.addEventListener("mouseleave", this.handleEvent);
3916
- this.element.trigger.addEventListener("focus", this.handleEvent);
3917
- this.element.trigger.addEventListener("blur", this.handleEvent);
4046
+ element.trigger.addEventListener("click", this.handleEvent);
4047
+ element.trigger.addEventListener("mouseenter", this.handleEvent);
4048
+ element.trigger.addEventListener("mouseleave", this.handleEvent);
4049
+ element.trigger.addEventListener("focus", this.handleEvent);
4050
+ element.trigger.addEventListener("blur", this.handleEvent);
3918
4051
  }
3919
4052
  }
3920
4053
 
3921
4054
  disconnect() {
3922
4055
  this.cleanupHideHandlers();
3923
- if (this.element) {
3924
- this.element.cleanup?.();
3925
4056
 
3926
- if (this.element.bib) {
3927
- this.element.shadowRoot.append(this.element.bib);
3928
- }
4057
+ const element = this.element;
4058
+ if (!element) {
4059
+ return;
4060
+ }
3929
4061
 
3930
- // Remove event & keyboard listeners
3931
- if (this.element?.trigger) {
3932
- this.element.trigger.removeEventListener("keydown", this.handleEvent);
3933
- this.element.trigger.removeEventListener("click", this.handleEvent);
3934
- this.element.trigger.removeEventListener(
3935
- "mouseenter",
3936
- this.handleEvent,
3937
- );
3938
- this.element.trigger.removeEventListener(
3939
- "mouseleave",
3940
- this.handleEvent,
3941
- );
3942
- this.element.trigger.removeEventListener("focus", this.handleEvent);
3943
- this.element.trigger.removeEventListener("blur", this.handleEvent);
3944
- }
4062
+ element.cleanup?.();
4063
+
4064
+ if (element.bib && element.shadowRoot) {
4065
+ element.shadowRoot.append(element.bib);
4066
+ }
4067
+
4068
+ // Remove event & keyboard listeners
4069
+ if (element.trigger) {
4070
+ element.trigger.removeEventListener("keydown", this.handleEvent);
4071
+ element.trigger.removeEventListener("click", this.handleEvent);
4072
+ element.trigger.removeEventListener("mouseenter", this.handleEvent);
4073
+ element.trigger.removeEventListener("mouseleave", this.handleEvent);
4074
+ element.trigger.removeEventListener("focus", this.handleEvent);
4075
+ element.trigger.removeEventListener("blur", this.handleEvent);
3945
4076
  }
3946
4077
  }
3947
4078
  }
@@ -5069,7 +5200,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5069
5200
  }
5070
5201
  };
5071
5202
 
5072
- var formkitVersion$2 = '202604072212';
5203
+ var formkitVersion$2 = '202604091759';
5073
5204
 
5074
5205
  let AuroElement$2 = class AuroElement extends i$4 {
5075
5206
  static get properties() {
@@ -5175,7 +5306,7 @@ let AuroElement$2 = class AuroElement extends i$4 {
5175
5306
  }
5176
5307
  };
5177
5308
 
5178
- // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
5309
+ // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
5179
5310
  // See LICENSE in the project root for license information.
5180
5311
 
5181
5312
 
@@ -12825,7 +12956,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12825
12956
  }
12826
12957
  };
12827
12958
 
12828
- var formkitVersion$1 = '202604072212';
12959
+ var formkitVersion$1 = '202604091759';
12829
12960
 
12830
12961
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12831
12962
  // See LICENSE in the project root for license information.
@@ -13890,7 +14021,7 @@ class AuroBibtemplate extends i$4 {
13890
14021
  }
13891
14022
  }
13892
14023
 
13893
- var formkitVersion = '202604072212';
14024
+ var formkitVersion = '202604091759';
13894
14025
 
13895
14026
  var styleCss$3 = i$7`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
13896
14027
 
@@ -14230,7 +14361,7 @@ class AuroHelpText extends i$4 {
14230
14361
  }
14231
14362
  }
14232
14363
 
14233
- // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
14364
+ // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
14234
14365
  // See LICENSE in the project root for license information.
14235
14366
 
14236
14367
 
@@ -14753,7 +14884,7 @@ class AuroCombobox extends AuroElement {
14753
14884
  * @returns {void}
14754
14885
  */
14755
14886
  activateFirstEnabledAvailableOption() {
14756
- const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled);
14887
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled && !opt.hasAttribute('nomatch'));
14757
14888
  this.updateActiveOption(firstEnabledOptionIndex);
14758
14889
  }
14759
14890
 
@@ -14767,7 +14898,7 @@ class AuroCombobox extends AuroElement {
14767
14898
 
14768
14899
  // Work backwards through the available options array to find the last enabled option
14769
14900
  for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14770
- if (!this.availableOptions[index].disabled) {
14901
+ if (!this.availableOptions[index].disabled && !this.availableOptions[index].hasAttribute('nomatch')) {
14771
14902
  lastEnabledOptionIndex = index;
14772
14903
  break;
14773
14904
  }
@@ -16032,6 +16163,7 @@ class AuroMenuOption extends AuroElement {
16032
16163
  this.selected = false;
16033
16164
  this.noCheckmark = false;
16034
16165
  this.disabled = false;
16166
+ this.noMatch = false;
16035
16167
 
16036
16168
  /**
16037
16169
  * @private
@@ -16107,6 +16239,15 @@ class AuroMenuOption extends AuroElement {
16107
16239
  reflect: true
16108
16240
  },
16109
16241
 
16242
+ /**
16243
+ * When true, marks this option as the "no matching results" placeholder shown by combobox when the user's input does not match any available options. Enables distinct styling and prevents the option from being treated as a selectable match.
16244
+ */
16245
+ noMatch: {
16246
+ type: Boolean,
16247
+ reflect: true,
16248
+ attribute: 'nomatch'
16249
+ },
16250
+
16110
16251
  /**
16111
16252
  * Specifies that an option is selected.
16112
16253
  */
@@ -17890,7 +18031,8 @@ function initExamples(initCount) {
17890
18031
  resetStateExample();
17891
18032
  setupExternalSelectionExample();
17892
18033
  valueExample();
17893
- inDialogExample();
18034
+ inDialogExample();
18035
+ inDrawerExample();
17894
18036
  persistentExample();
17895
18037
  swapValueExample();
17896
18038
  } catch (err) {