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

1433: Add support for sl-popup "virtualAnchor" #1434

Closed
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 5 additions & 2 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,16 @@ if (serve) {
});

// Rebuild and reload when source files change
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
bs.watch('src/**/!(*.test).*').on('change', async filename => {
console.log('updated file: ', filename);

try {
const isTheme = /^src\/themes/.test(filename);
const isStylesheet = /(\.css|\.styles\.ts)$/.test(filename);

// Rebuild the source
await Promise.all([buildResults.map(result => result.rebuild())]);
const rebuildResults = buildResults.map(result => result.rebuild());
await Promise.all(rebuildResults);

// Rebuild stylesheets when a theme file changes
if (isTheme) {
Expand Down
19 changes: 14 additions & 5 deletions src/components/popup/popup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,31 @@ import type { CSSResultGroup } from 'lit';
* popup can be before overflowing. Useful for positioning child elements that need to overflow. This property is only
* available when using `auto-size`.
*/

export interface VirtualElement {
getBoundingClientRect: () => DOMRect;
}

function isVirtualElement(e: unknown): e is VirtualElement {
return e !== null && typeof e === 'object' && 'getBoundingClientRect' in e;
}

@customElement('sl-popup')
export default class SlPopup extends ShoelaceElement {
static styles: CSSResultGroup = styles;

private anchorEl: Element | null;
private anchorEl: Element | VirtualElement | null;
private cleanup: ReturnType<typeof autoUpdate> | undefined;

/** A reference to the internal popup container. Useful for animating and styling the popup with JavaScript. */
@query('.popup') popup: HTMLElement;
@query('.popup__arrow') private arrowEl: HTMLElement;

/**
* The element the popup will be anchored to. If the anchor lives outside of the popup, you can provide its `id` or a
* reference to it here. If the anchor lives inside the popup, use the `anchor` slot instead.
* The element the popup will be anchored to. If the anchor lives outside of the popup, you can provide the anchor element `id`, or an
* dom element reference, or a VirtualElement. If the anchor lives inside the popup, use the `anchor` slot instead.
*/
@property() anchor: Element | string;
@property() anchor: Element | string | VirtualElement;

/**
* Activates the positioning logic and shows the popup. When this attribute is removed, the positioning logic is torn
Expand Down Expand Up @@ -224,7 +233,7 @@ export default class SlPopup extends ShoelaceElement {
// Locate the anchor by id
const root = this.getRootNode() as Document | ShadowRoot;
this.anchorEl = root.getElementById(this.anchor);
} else if (this.anchor instanceof Element) {
} else if (this.anchor instanceof Element || isVirtualElement(this.anchor)) {
// Use the anchor's reference
this.anchorEl = this.anchor;
} else {
Expand Down