Skip to content

Commit

Permalink
fix(overlay): ensure that passing "open" to the directive manages a s…
Browse files Browse the repository at this point in the history
…ingle strategy
  • Loading branch information
Westbrook committed May 21, 2024
1 parent 39706da commit 900c2b2
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 8 deletions.
7 changes: 6 additions & 1 deletion packages/overlay/src/InteractionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@ export class InteractionController implements ReactiveController {

private handleOverlayReady?: (overlay: AbstractOverlay) => void;

// Holds optimistic open state when an Overlay is not yet present
private isLazilyOpen = false;

public get open(): boolean {
return this.overlay?.open ?? false;
return this.overlay?.open ?? this.isLazilyOpen;
}

/**
* Set `open` against the associated Overlay lazily.
*/
public set open(open: boolean) {
if (open === this.open) return;
this.isLazilyOpen = open;
if (this.overlay) {
// If there already is an Overlay, apply the value of `open` directly.
this.overlay.open = open;
Expand Down
4 changes: 2 additions & 2 deletions packages/overlay/src/overlay-trigger-directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from './slottable-request-event.js';
import { SlottableRequestDirective } from './slottable-request-directive.js';
import { AbstractOverlay } from './AbstractOverlay.js';
import { InteractionTypes } from './InteractionController.js';

export type InsertionOptions = {
el: HTMLElement | (() => HTMLElement);
Expand Down Expand Up @@ -81,8 +82,7 @@ export class OverlayTriggerDirective extends SlottableRequestDirective {
const triggerInteraction = (options?.triggerInteraction ||
this.defaultOptions.triggerInteraction) as TriggerInteraction;
const newStrategy =
(this.strategy?.type as unknown as TriggerInteraction) !==
triggerInteraction;
InteractionTypes[this.strategy?.type] !== triggerInteraction;
if (this.target !== part.element) {
this.target = part.element as HTMLElement;
newTarget = true;
Expand Down
97 changes: 92 additions & 5 deletions packages/overlay/stories/overlay-directive.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { html, TemplateResult } from '@spectrum-web-components/base';
import {
html,
LitElement,
TemplateResult,
} from '@spectrum-web-components/base';
import {
OverlayContentTypes,
OverlayOpenCloseDetail,
Placement,
TriggerInteractions,
} from '@spectrum-web-components/overlay';
Expand Down Expand Up @@ -46,6 +51,7 @@ import '../../../projects/story-decorator/src/types.js';
import './overlay-story-components.js';
import { tooltip } from '@spectrum-web-components/tooltip/src/tooltip-directive.js';
import { ifDefined } from '@spectrum-web-components/base/src/directives.js';
import { state } from '@spectrum-web-components/base/src/decorators.js';

const storyStyles = html`
<style>
Expand Down Expand Up @@ -180,10 +186,9 @@ const template = ({
</div>
<sp-button
${tooltip(
() =>
html`
Click to open another popover.
`
() => html`
Click to open another popover.
`
)}
${trigger(
() => html`
Expand Down Expand Up @@ -266,3 +271,85 @@ insertionOptions.args = {
insertionOptions.swc_vrt = {
skip: true,
};

class ManagedOverlayTrigger extends LitElement {
@state()
private isRenderOverlay = false;

@state()
private isOpenState = false;

protected override render(): TemplateResult {
return html`
<sp-button
@click=${() => {
this.isRenderOverlay = !this.isRenderOverlay;
}}
>
Toggle Overlay Render Button
</sp-button>
<sp-button
@click=${() => {
this.isRenderOverlay = true;
this.isOpenState = true;
}}
>
Create Overlay Render Button And Open Overlay
</sp-button>
${this.isRenderOverlay ? this.renderOverlayButton() : html``}
`;
}

private renderOverlayButton(): TemplateResult {
return html`
<sp-button
?selected=${this.isOpenState}
${trigger(
() => html`
<sp-popover
@sp-opened=${(
event: CustomEvent<OverlayOpenCloseDetail>
) => {
if (event.target !== event.currentTarget) {
return;
}
console.log('sp-opened');
this.isOpenState = true;
}}
@sp-closed=${(
event: CustomEvent<OverlayOpenCloseDetail>
) => {
if (event.target !== event.currentTarget) {
return;
}
console.log('sp-closed');
this.isOpenState = false;
}}
>
<h1>My Test Popover</h1>
</sp-popover>
`,
{
triggerInteraction: 'click',
overlayOptions: { placement: 'bottom-end' },
open: this.isOpenState,
}
)}
>
Toggle Popover
</sp-button>
`;
}
}

customElements.define('managed-overlay-trigger', ManagedOverlayTrigger);

export const managedOverlayTrigger = (): TemplateResult => html`
<managed-overlay-trigger></managed-overlay-trigger>
`;

managedOverlayTrigger.swc_vrt = {
skip: true,
};

0 comments on commit 900c2b2

Please sign in to comment.