From a66ecdf0278508199528777d8627816f3d35bd99 Mon Sep 17 00:00:00 2001 From: Marko Date: Fri, 7 Jul 2023 19:28:44 -0400 Subject: [PATCH 1/2] 1433: POC for comments (+ fix build.watch()) --- scripts/build.js | 7 +++++-- src/components/popup/popup.ts | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index 315d70ea75..463bcd45b0 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -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) { diff --git a/src/components/popup/popup.ts b/src/components/popup/popup.ts index f2ac9fb0a3..0c0599bbd6 100644 --- a/src/components/popup/popup.ts +++ b/src/components/popup/popup.ts @@ -35,11 +35,16 @@ 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; +} + @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 | undefined; /** A reference to the internal popup container. Useful for animating and styling the popup with JavaScript. */ @@ -50,7 +55,9 @@ export default class SlPopup extends ShoelaceElement { * 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. */ - @property() anchor: Element | string; + @property() anchor: Element | string | undefined; + + @property({ attribute: 'virtual-anchor', type: Object }) virtualAnchor: VirtualElement | undefined; /** * Activates the positioning logic and shows the popup. When this attribute is removed, the positioning logic is torn @@ -206,7 +213,7 @@ export default class SlPopup extends ShoelaceElement { } // Update the anchor when anchor changes - if (changedProps.has('anchor')) { + if (changedProps.has('anchor') || changedProps.has('virtualAnchor')) { this.handleAnchorChange(); } @@ -220,7 +227,9 @@ export default class SlPopup extends ShoelaceElement { private async handleAnchorChange() { await this.stop(); - if (this.anchor && typeof this.anchor === 'string') { + if (this.virtualAnchor) { + this.anchorEl = this.virtualAnchor; + } else if (this.anchor && typeof this.anchor === 'string') { // Locate the anchor by id const root = this.getRootNode() as Document | ShadowRoot; this.anchorEl = root.getElementById(this.anchor); From 4733161088c0664b829a482b986050e42c9fddd4 Mon Sep 17 00:00:00 2001 From: Marko Date: Mon, 10 Jul 2023 22:41:47 -0400 Subject: [PATCH 2/2] 1433: consolidate virtualAnchor into anchor --- src/components/popup/popup.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/popup/popup.ts b/src/components/popup/popup.ts index 0c0599bbd6..3cdd50504f 100644 --- a/src/components/popup/popup.ts +++ b/src/components/popup/popup.ts @@ -40,6 +40,10 @@ 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; @@ -52,12 +56,10 @@ export default class SlPopup extends ShoelaceElement { @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 | undefined; - - @property({ attribute: 'virtual-anchor', type: Object }) virtualAnchor: VirtualElement | undefined; + @property() anchor: Element | string | VirtualElement; /** * Activates the positioning logic and shows the popup. When this attribute is removed, the positioning logic is torn @@ -213,7 +215,7 @@ export default class SlPopup extends ShoelaceElement { } // Update the anchor when anchor changes - if (changedProps.has('anchor') || changedProps.has('virtualAnchor')) { + if (changedProps.has('anchor')) { this.handleAnchorChange(); } @@ -227,13 +229,11 @@ export default class SlPopup extends ShoelaceElement { private async handleAnchorChange() { await this.stop(); - if (this.virtualAnchor) { - this.anchorEl = this.virtualAnchor; - } else if (this.anchor && typeof this.anchor === 'string') { + if (this.anchor && typeof this.anchor === 'string') { // 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 {