From 25ce2522a530887cb1c55142e3f1101791edffa4 Mon Sep 17 00:00:00 2001 From: Todd Olson Date: Sun, 29 Mar 2026 10:16:24 -0400 Subject: [PATCH 1/2] NOVUS-391 Defer custom element registration to consumer Move all customElements.define() calls out of individual component files into an exported registerGuideComponents() function. This prevents NotSupportedError when the plugin script is loaded twice (e.g. staging), since the consumer controls when registration happens. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/elements/pendo-button.js | 2 -- src/elements/pendo-close-button.js | 2 -- src/elements/pendo-divider.js | 2 -- src/elements/pendo-guide.js | 2 -- src/elements/pendo-image.js | 2 -- src/elements/pendo-input.js | 1 - src/elements/pendo-link.js | 1 - src/elements/pendo-list.js | 2 -- src/elements/pendo-text.js | 2 -- src/elements/pendo-title.js | 2 -- src/elements/pendo-video.js | 2 -- src/index.js | 5 +++- src/polls/pendo-emoji-scale.js | 1 - src/polls/pendo-nps.js | 1 - src/polls/pendo-number-scale.js | 1 - src/polls/pendo-open-text.js | 1 - src/polls/pendo-star-rating.js | 1 - src/register.js | 48 ++++++++++++++++++++++++++++++ test/pendo-button.test.js | 3 ++ 19 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 src/register.js diff --git a/src/elements/pendo-button.js b/src/elements/pendo-button.js index bb419c3..7fd4e9f 100644 --- a/src/elements/pendo-button.js +++ b/src/elements/pendo-button.js @@ -138,6 +138,4 @@ class PendoButton extends PendoBaseElement { } } -customElements.define('pendo-button', PendoButton); - export { PendoButton }; diff --git a/src/elements/pendo-close-button.js b/src/elements/pendo-close-button.js index 3241dee..0d7135e 100644 --- a/src/elements/pendo-close-button.js +++ b/src/elements/pendo-close-button.js @@ -37,6 +37,4 @@ class PendoCloseButton extends PendoBaseElement { } } -customElements.define('pendo-close-button', PendoCloseButton); - export { PendoCloseButton }; diff --git a/src/elements/pendo-divider.js b/src/elements/pendo-divider.js index 1ce9ecc..89777c5 100644 --- a/src/elements/pendo-divider.js +++ b/src/elements/pendo-divider.js @@ -13,6 +13,4 @@ class PendoDivider extends PendoBaseElement { } } -customElements.define('pendo-divider', PendoDivider); - export { PendoDivider }; diff --git a/src/elements/pendo-guide.js b/src/elements/pendo-guide.js index d126d30..400bd7c 100644 --- a/src/elements/pendo-guide.js +++ b/src/elements/pendo-guide.js @@ -118,6 +118,4 @@ class PendoGuide extends PendoBaseElement { } } -customElements.define('pendo-guide', PendoGuide); - export { PendoGuide }; diff --git a/src/elements/pendo-image.js b/src/elements/pendo-image.js index 4ced0c9..077b425 100644 --- a/src/elements/pendo-image.js +++ b/src/elements/pendo-image.js @@ -41,6 +41,4 @@ class PendoImage extends PendoBaseElement { } } -customElements.define('pendo-image', PendoImage); - export { PendoImage }; diff --git a/src/elements/pendo-input.js b/src/elements/pendo-input.js index 0c0a1bb..f3c02d2 100644 --- a/src/elements/pendo-input.js +++ b/src/elements/pendo-input.js @@ -232,4 +232,3 @@ export class PendoInput extends PendoBaseElement { } } -customElements.define('pendo-input', PendoInput); diff --git a/src/elements/pendo-link.js b/src/elements/pendo-link.js index edd792c..e1acc5c 100644 --- a/src/elements/pendo-link.js +++ b/src/elements/pendo-link.js @@ -40,4 +40,3 @@ export class PendoLink extends PendoBaseElement { } } -customElements.define('pendo-link', PendoLink); diff --git a/src/elements/pendo-list.js b/src/elements/pendo-list.js index 04c086a..b10518d 100644 --- a/src/elements/pendo-list.js +++ b/src/elements/pendo-list.js @@ -69,5 +69,3 @@ export class PendoListItem extends PendoBaseElement { // Content is processed by parent PendoList } -customElements.define('pendo-list', PendoList); -customElements.define('pendo-list-item', PendoListItem); diff --git a/src/elements/pendo-text.js b/src/elements/pendo-text.js index 22da89f..e88fee5 100644 --- a/src/elements/pendo-text.js +++ b/src/elements/pendo-text.js @@ -12,6 +12,4 @@ class PendoText extends PendoBaseElement { } } -customElements.define('pendo-text', PendoText); - export { PendoText }; diff --git a/src/elements/pendo-title.js b/src/elements/pendo-title.js index 73ce3b3..63f7609 100644 --- a/src/elements/pendo-title.js +++ b/src/elements/pendo-title.js @@ -21,6 +21,4 @@ class PendoTitle extends PendoBaseElement { } } -customElements.define('pendo-title', PendoTitle); - export { PendoTitle }; diff --git a/src/elements/pendo-video.js b/src/elements/pendo-video.js index 8782e06..273dede 100644 --- a/src/elements/pendo-video.js +++ b/src/elements/pendo-video.js @@ -101,6 +101,4 @@ class PendoVideo extends PendoBaseElement { } } -customElements.define('pendo-video', PendoVideo); - export { PendoVideo }; diff --git a/src/index.js b/src/index.js index 5948453..e412476 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ * @pendo/guide-components * * Custom elements for rendering Pendo HTML guides. - * Import this module to register all pendo-* custom elements. + * Call registerGuideComponents() to register all pendo-* custom elements. */ // Base class (exported for extension) @@ -35,5 +35,8 @@ export { PendoEmojiScale } from './polls/pendo-emoji-scale.js'; // Configuration API export { configurePendoComponents } from './configure.js'; +// Registration (deferred — consumers call this when ready) +export { registerGuideComponents } from './register.js'; + // Import styles (will be extracted by build) import './styles/defaults.css'; diff --git a/src/polls/pendo-emoji-scale.js b/src/polls/pendo-emoji-scale.js index f920885..e60ecf3 100644 --- a/src/polls/pendo-emoji-scale.js +++ b/src/polls/pendo-emoji-scale.js @@ -122,4 +122,3 @@ export class PendoEmojiScale extends PendoBaseElement { } } -customElements.define('pendo-emoji-scale', PendoEmojiScale); diff --git a/src/polls/pendo-nps.js b/src/polls/pendo-nps.js index 4bacbd1..3b192cf 100644 --- a/src/polls/pendo-nps.js +++ b/src/polls/pendo-nps.js @@ -120,4 +120,3 @@ export class PendoNps extends PendoBaseElement { } } -customElements.define('pendo-nps', PendoNps); diff --git a/src/polls/pendo-number-scale.js b/src/polls/pendo-number-scale.js index 0264464..8ec48aa 100644 --- a/src/polls/pendo-number-scale.js +++ b/src/polls/pendo-number-scale.js @@ -125,4 +125,3 @@ export class PendoNumberScale extends PendoBaseElement { } } -customElements.define('pendo-number-scale', PendoNumberScale); diff --git a/src/polls/pendo-open-text.js b/src/polls/pendo-open-text.js index 84b16b7..8dae0b6 100644 --- a/src/polls/pendo-open-text.js +++ b/src/polls/pendo-open-text.js @@ -137,4 +137,3 @@ export class PendoOpenText extends PendoBaseElement { } } -customElements.define('pendo-open-text', PendoOpenText); diff --git a/src/polls/pendo-star-rating.js b/src/polls/pendo-star-rating.js index 86f747e..9a9b726 100644 --- a/src/polls/pendo-star-rating.js +++ b/src/polls/pendo-star-rating.js @@ -119,4 +119,3 @@ export class PendoStarRating extends PendoBaseElement { } } -customElements.define('pendo-star-rating', PendoStarRating); diff --git a/src/register.js b/src/register.js new file mode 100644 index 0000000..f459748 --- /dev/null +++ b/src/register.js @@ -0,0 +1,48 @@ +import { PendoGuide } from './elements/pendo-guide.js'; +import { PendoTitle } from './elements/pendo-title.js'; +import { PendoText } from './elements/pendo-text.js'; +import { PendoButton } from './elements/pendo-button.js'; +import { PendoCloseButton } from './elements/pendo-close-button.js'; +import { PendoImage } from './elements/pendo-image.js'; +import { PendoDivider } from './elements/pendo-divider.js'; +import { PendoVideo } from './elements/pendo-video.js'; +import { PendoLink } from './elements/pendo-link.js'; +import { PendoList, PendoListItem } from './elements/pendo-list.js'; +import { PendoInput } from './elements/pendo-input.js'; +import { PendoStarRating } from './polls/pendo-star-rating.js'; +import { PendoNps } from './polls/pendo-nps.js'; +import { PendoNumberScale } from './polls/pendo-number-scale.js'; +import { PendoOpenText } from './polls/pendo-open-text.js'; +import { PendoEmojiScale } from './polls/pendo-emoji-scale.js'; + +const components = [ + ['pendo-guide', PendoGuide], + ['pendo-title', PendoTitle], + ['pendo-text', PendoText], + ['pendo-button', PendoButton], + ['pendo-close-button', PendoCloseButton], + ['pendo-image', PendoImage], + ['pendo-divider', PendoDivider], + ['pendo-video', PendoVideo], + ['pendo-link', PendoLink], + ['pendo-list', PendoList], + ['pendo-list-item', PendoListItem], + ['pendo-input', PendoInput], + ['pendo-star-rating', PendoStarRating], + ['pendo-nps', PendoNps], + ['pendo-number-scale', PendoNumberScale], + ['pendo-open-text', PendoOpenText], + ['pendo-emoji-scale', PendoEmojiScale] +]; + +/** + * Register all pendo-* custom elements. + * Safe to call multiple times — skips already-registered elements. + */ +export function registerGuideComponents() { + components.forEach(function([name, ctor]) { + if (!customElements.get(name)) { + customElements.define(name, ctor); + } + }); +} diff --git a/test/pendo-button.test.js b/test/pendo-button.test.js index 3be1435..cc050ad 100644 --- a/test/pendo-button.test.js +++ b/test/pendo-button.test.js @@ -3,6 +3,9 @@ */ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { PendoButton } from '../src/elements/pendo-button.js'; +import { registerGuideComponents } from '../src/register.js'; + +registerGuideComponents(); describe('PendoButton', () => { describe('parseAction', () => { From 6a4f598d2d245dc1fc6783cd004b1fa370dfc4f7 Mon Sep 17 00:00:00 2001 From: Todd Olson Date: Mon, 13 Apr 2026 19:18:22 -0400 Subject: [PATCH 2/2] Add pendo-pick-list and pendo-yes-no poll components New poll types with registration, exports, styles, and demo harness updates. Co-Authored-By: Claude Opus 4.6 (1M context) --- demo/index.html | 4 + demo/mock-guides.js | 91 ++++++++++++++++++++ demo/mock-pendo.js | 59 +++++++------ package.json | 4 +- src/index.js | 2 + src/polls/pendo-pick-list.js | 159 +++++++++++++++++++++++++++++++++++ src/polls/pendo-yes-no.js | 116 +++++++++++++++++++++++++ src/register.js | 6 +- src/styles/defaults.css | 71 ++++++++++++++++ 9 files changed, 482 insertions(+), 30 deletions(-) create mode 100644 src/polls/pendo-pick-list.js create mode 100644 src/polls/pendo-yes-no.js diff --git a/demo/index.html b/demo/index.html index c67b624..e97aa2a 100644 --- a/demo/index.html +++ b/demo/index.html @@ -472,6 +472,7 @@

Pendo Demo Controls

+ @@ -483,6 +484,9 @@

Pendo Demo Controls