@aurodesignsystem/auro-library 5.13.1 → 5.13.3
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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/scripts/runtime/floatingUI.mjs +64 -4
- package/scripts/runtime/floatingUI.test.js +79 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Semantic Release Automated Changelog
|
|
2
2
|
|
|
3
|
+
## [5.13.3](https://github.com/AlaskaAirlines/auro-library/compare/v5.13.2...v5.13.3) (2026-08-07)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **floatingUI:** suppress Escape keydown for modal dialogs to prevent CloseWatcher force-close AB[#1613688](https://github.com/AlaskaAirlines/auro-library/issues/1613688) ([efd81c5](https://github.com/AlaskaAirlines/auro-library/commit/efd81c5fd96f4d02253e4ce76b4e7a2ddb8d25c7))
|
|
9
|
+
|
|
10
|
+
## [5.13.2](https://github.com/AlaskaAirlines/auro-library/compare/v5.13.1...v5.13.2) (2026-07-28)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* track visualViewport continuously during scroll lock ([631cf89](https://github.com/AlaskaAirlines/auro-library/commit/631cf89627fd4053b0ae8252736eb1db78919843))
|
|
16
|
+
|
|
3
17
|
## [5.13.1](https://github.com/AlaskaAirlines/auro-library/compare/v5.13.0...v5.13.1) (2026-07-10)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurodesignsystem/auro-library",
|
|
3
|
-
"version": "5.13.
|
|
3
|
+
"version": "5.13.3",
|
|
4
4
|
"description": "This repository holds shared scripts, utilities, and workflows utilized across repositories along the Auro Design System.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -339,15 +339,57 @@ export default class AuroFloatingUI {
|
|
|
339
339
|
document.body.style.top = `-${this._savedScrollY}px`;
|
|
340
340
|
document.body.style.width = "100%";
|
|
341
341
|
|
|
342
|
-
//
|
|
343
|
-
|
|
344
|
-
|
|
342
|
+
// Keep the bib aligned with the visual viewport as the VKB opens.
|
|
343
|
+
// A one-shot offsetTop check at lock time is stale by the time the user
|
|
344
|
+
// taps an input mid-drawer — iOS then pans visualViewport upward and the
|
|
345
|
+
// bib drifts off-screen. Listen continuously so the transform tracks the pan.
|
|
346
|
+
// RAF-throttled to avoid a style recalc on every scroll tick during the
|
|
347
|
+
// keyboard animation; the pending frame is canceled on unlock so it cannot
|
|
348
|
+
// reapply a translate after bibTransform has been restored.
|
|
349
|
+
if (window.visualViewport) {
|
|
350
|
+
this._viewportRafId = undefined;
|
|
351
|
+
this._viewportHandler = () => {
|
|
352
|
+
if (this._viewportRafId !== undefined) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
this._viewportRafId = requestAnimationFrame(() => {
|
|
356
|
+
this._viewportRafId = undefined;
|
|
357
|
+
if (element?.bib) {
|
|
358
|
+
element.bib.style.transform = `translateY(${window.visualViewport.offsetTop}px)`;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
window.visualViewport.addEventListener(
|
|
363
|
+
"resize",
|
|
364
|
+
this._viewportHandler,
|
|
365
|
+
);
|
|
366
|
+
window.visualViewport.addEventListener(
|
|
367
|
+
"scroll",
|
|
368
|
+
this._viewportHandler,
|
|
369
|
+
);
|
|
370
|
+
this._viewportHandler();
|
|
345
371
|
}
|
|
346
372
|
|
|
347
373
|
this.lockTouchScroll(true);
|
|
348
374
|
}
|
|
349
375
|
} else {
|
|
350
376
|
if (this._scrollLocked) {
|
|
377
|
+
if (this._viewportHandler && window.visualViewport) {
|
|
378
|
+
window.visualViewport.removeEventListener(
|
|
379
|
+
"resize",
|
|
380
|
+
this._viewportHandler,
|
|
381
|
+
);
|
|
382
|
+
window.visualViewport.removeEventListener(
|
|
383
|
+
"scroll",
|
|
384
|
+
this._viewportHandler,
|
|
385
|
+
);
|
|
386
|
+
this._viewportHandler = undefined;
|
|
387
|
+
}
|
|
388
|
+
if (this._viewportRafId !== undefined) {
|
|
389
|
+
cancelAnimationFrame(this._viewportRafId);
|
|
390
|
+
this._viewportRafId = undefined;
|
|
391
|
+
}
|
|
392
|
+
|
|
351
393
|
document.documentElement.style.scrollbarGutter =
|
|
352
394
|
this._savedScrollStyles?.rootScrollbarGutter ?? "";
|
|
353
395
|
document.documentElement.style.overflow =
|
|
@@ -439,7 +481,7 @@ export default class AuroFloatingUI {
|
|
|
439
481
|
bibContent.style.width = "";
|
|
440
482
|
bibContent.style.height = "";
|
|
441
483
|
bibContent.style.maxWidth = "";
|
|
442
|
-
bibContent.style.maxHeight =
|
|
484
|
+
bibContent.style.maxHeight = "";
|
|
443
485
|
this.configureTrial = 0;
|
|
444
486
|
} else if (this.configureTrial < MAX_CONFIGURATION_COUNT) {
|
|
445
487
|
this.configureTrial += 1;
|
|
@@ -736,6 +778,24 @@ export default class AuroFloatingUI {
|
|
|
736
778
|
if (!this.showing) {
|
|
737
779
|
if (!element.modal) {
|
|
738
780
|
this.setupHideHandlers();
|
|
781
|
+
} else {
|
|
782
|
+
if (this.keyDownHandler) {
|
|
783
|
+
document.removeEventListener("keydown", this.keyDownHandler);
|
|
784
|
+
}
|
|
785
|
+
this.keyDownHandler = (evt) => {
|
|
786
|
+
if (evt.key === "Escape" && element.isPopoverVisible) {
|
|
787
|
+
// Intercept at keydown so CloseWatcher never sees the keystroke.
|
|
788
|
+
// Canceling `cancel` alone is insufficient — a second Esc with no
|
|
789
|
+
// intervening user activation triggers the anti-trap and fires `close`
|
|
790
|
+
// directly, bypassing any `cancel` preventDefault (AB#1613688).
|
|
791
|
+
// stopImmediatePropagation is intentional: it prevents other document
|
|
792
|
+
// keydown handlers (e.g. consumer code, auro-dialog) from also acting
|
|
793
|
+
// on Escape while the modal owns the key.
|
|
794
|
+
evt.preventDefault();
|
|
795
|
+
evt.stopImmediatePropagation();
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
document.addEventListener("keydown", this.keyDownHandler);
|
|
739
799
|
}
|
|
740
800
|
this.showing = true;
|
|
741
801
|
element.isPopoverVisible = true;
|
|
@@ -295,6 +295,85 @@ describe("AuroFloatingUI", () => {
|
|
|
295
295
|
});
|
|
296
296
|
});
|
|
297
297
|
|
|
298
|
+
describe("AuroFloatingUI modal Escape suppression (AB#1613688)", () => {
|
|
299
|
+
let host;
|
|
300
|
+
let bib;
|
|
301
|
+
let floatingUI;
|
|
302
|
+
let hideBibSpy;
|
|
303
|
+
|
|
304
|
+
beforeEach(() => {
|
|
305
|
+
host = document.createElement("div");
|
|
306
|
+
bib = document.createElement("div");
|
|
307
|
+
host.bib = bib;
|
|
308
|
+
host.modal = true;
|
|
309
|
+
host.isPopoverVisible = false;
|
|
310
|
+
host.triggerChevron = document.createElement("span");
|
|
311
|
+
document.body.append(host, bib);
|
|
312
|
+
|
|
313
|
+
AuroFloatingUI.openingQueue = [];
|
|
314
|
+
document.expandedAuroFloater = null;
|
|
315
|
+
|
|
316
|
+
floatingUI = new AuroFloatingUI(host, "dialog");
|
|
317
|
+
hideBibSpy = sinon.spy(floatingUI, "hideBib");
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
afterEach(() => {
|
|
321
|
+
floatingUI.cleanupHideHandlers();
|
|
322
|
+
sinon.restore();
|
|
323
|
+
AuroFloatingUI.isMousePressed = false;
|
|
324
|
+
AuroFloatingUI.openingQueue = [];
|
|
325
|
+
document.expandedAuroFloater = null;
|
|
326
|
+
host?.remove();
|
|
327
|
+
bib?.remove();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("registers a keydown handler and skips setupHideHandlers when modal=true", () => {
|
|
331
|
+
const setupHideHandlersSpy = sinon.spy(floatingUI, "setupHideHandlers");
|
|
332
|
+
|
|
333
|
+
floatingUI.showBib();
|
|
334
|
+
|
|
335
|
+
expect(setupHideHandlersSpy.called).to.be.false;
|
|
336
|
+
expect(floatingUI.keyDownHandler).to.be.a("function");
|
|
337
|
+
expect(floatingUI.showing).to.be.true;
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it("does not call hideBib when Escape is pressed while modal dialog is open", () => {
|
|
341
|
+
floatingUI.showBib();
|
|
342
|
+
|
|
343
|
+
document.dispatchEvent(
|
|
344
|
+
new KeyboardEvent("keydown", {
|
|
345
|
+
key: "Escape",
|
|
346
|
+
bubbles: true,
|
|
347
|
+
cancelable: true,
|
|
348
|
+
}),
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect(hideBibSpy.called).to.be.false;
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it("calls preventDefault on Escape keydown while modal dialog is open", () => {
|
|
355
|
+
floatingUI.showBib();
|
|
356
|
+
|
|
357
|
+
const escEvent = new KeyboardEvent("keydown", {
|
|
358
|
+
key: "Escape",
|
|
359
|
+
bubbles: true,
|
|
360
|
+
cancelable: true,
|
|
361
|
+
});
|
|
362
|
+
const preventDefaultSpy = sinon.spy(escEvent, "preventDefault");
|
|
363
|
+
document.dispatchEvent(escEvent);
|
|
364
|
+
|
|
365
|
+
expect(preventDefaultSpy.calledOnce).to.be.true;
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it("removes the modal Escape keydown handler via cleanupHideHandlers", () => {
|
|
369
|
+
floatingUI.showBib();
|
|
370
|
+
expect(floatingUI.keyDownHandler).to.be.a("function");
|
|
371
|
+
|
|
372
|
+
floatingUI.cleanupHideHandlers();
|
|
373
|
+
expect(floatingUI.keyDownHandler).to.be.null;
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
298
377
|
describe("AuroFloatingUI.openingQueue and topOpeningFloatingUI", () => {
|
|
299
378
|
let floatingUI1;
|
|
300
379
|
let floatingUI2;
|