Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(expressive-modal): ensure waiting for transitionend event #5189

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license
*
* Copyright IBM Corp. 2020
* Copyright IBM Corp. 2020, 2021
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
Expand All @@ -20,6 +20,7 @@ import {
} from 'lit-element';
import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js';
import settings from 'carbon-components/es/globals/js/settings.js';
import on from 'carbon-components/es/globals/js/misc/on';
import { selectorTabbable } from 'carbon-web-components/es/globals/settings.js';
import HostListener from 'carbon-web-components/es/globals/decorators/host-listener.js';
import HostListenerMixin from 'carbon-web-components/es/globals/mixins/host-listener.js';
Expand Down Expand Up @@ -224,6 +225,29 @@ class DDSExpressiveModal extends StableSelectorMixin(HostListenerMixin(LitElemen
}
}

/**
* @param timeout The number of milliseconds as the longest time waiting for `transitionend` event.
* @returns A promise that is resolves when `transitionend` on the host element fires.
*/
private _waitForTransitionEnd(timeout: number = 1000) {
return new Promise(resolve => {
let done = false;
let hTransitionEnd;
const handleResolve = () => {
if (hTransitionEnd) {
hTransitionEnd.release();
hTransitionEnd = null;
}
if (!done) {
resolve(undefined);
done = true;
}
};
on(this, 'transitionend', handleResolve);
setTimeout(handleResolve, timeout);
});
}

/**
* @returns The header content.
*/
Expand Down Expand Up @@ -320,7 +344,7 @@ class DDSExpressiveModal extends StableSelectorMixin(HostListenerMixin(LitElemen
if (this.open) {
this._launcher = this.ownerDocument!.activeElement;
const primaryFocusNode = this.querySelector((this.constructor as typeof DDSExpressiveModal).selectorPrimaryFocus);
await (this.constructor as typeof DDSExpressiveModal)._delay();
await this._waitForTransitionEnd();
if (primaryFocusNode) {
// For cases where a `carbon-web-components` component (e.g. `<bx-btn>`) being `primaryFocusNode`,
// where its first update/render cycle that makes it focusable happens after `<bx-modal>`'s first update/render cycle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license
*
* Copyright IBM Corp. 2020
* Copyright IBM Corp. 2020, 2021
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
Expand Down Expand Up @@ -187,6 +187,16 @@ class DDSLocaleModal extends DDSExpressiveModal {
return `${ddsPrefix}-locale-search`;
}

/**
* A selector selecting the nodes that should be focused when modal gets open.
*/
static get selectorPrimaryFocus() {
return `
[data-modal-primary-focus],
${ddsPrefix}-region-item
kennylam marked this conversation as resolved.
Show resolved Hide resolved
`;
}

static get stableSelector() {
return `${ddsPrefix}--locale-modal`;
}
Expand Down