You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. Issues with refactoring Carousel and Testimonials to LitElement
2
+
No real blockers. The migration is straightforward because:
3
+
4
+
Light DOM is already solved. ThemePicker demonstrates the pattern: createRenderRoot() { return this }. Since all three components render their HTML via Astro templates (not Lit's render()), this is the correct approach and already in use.
5
+
LitElement is already bundled. ThemePicker pulls it in, so there's no added dependency cost.
6
+
Lifecycle maps cleanly. The manual connectedCallback → initialize() pattern in Carousel/Testimonials translates directly. The main changes are calling super.connectedCallback() / super.disconnectedCallback() and optionally using firstUpdated() instead of the manual DOMContentLoaded check.
7
+
Nanostore integration improves. Carousel and Testimonials currently call createAnimationController manually. With LitElement they could use StoreController for reactive bindings (like ThemePicker does with createThemeController), though it's not required since the animation lifecycle uses callbacks rather than direct store subscriptions.
8
+
The only thing to watch: the transition:persist directive must remain on the HTML custom element tag itself, not on an Astro component wrapper. That's already a project rule and isn't affected by LitElement vs HTMLElement.
9
+
10
+
2. Revised recommendation
11
+
12
+
With all three components sharing LitElement as a base, an abstract base class becomes the cleanest option.
13
+
14
+
Proposed structure:
15
+
16
+
```bash
17
+
src/components/scripts/embla/
18
+
EmblaCarouselBase.ts – abstract LitElement base class
|`abstract get autoplayOptions()`|[{ delay: 4000, ... }](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|[{ delay: 6000, ... }](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|`null` (no autoplay initially) |
49
+
|[abstract get animationId()](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|`'carousel'`|['testimonials-carousel'](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|`'skills-carousel'`|
50
+
|[abstract get scriptName()](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|['CarouselElement'](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|['TestimonialsCarouselElement'](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|`'SkillsCarouselElement'`|
51
+
|`abstract get logPrefix()`|`'carousel'`|['testimonials'](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|`'skills'`|
52
+
|`abstract get focusVisibleSelector()`|`'[data-carousel-slide] :focus-visible'`|`'[data-testimonials-slide] :focus-visible'`| component-specific |
| Viewport ID / `aria-controls` on buttons | Testimonials subclass only |
63
+
| Dot active styling ([is-active](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) vs `w-6`) | Override `applyDotActiveStyle()` / `applyDotInactiveStyle()`|
64
+
65
+
Two reasonable paths:
66
+
67
+
A: ThemePicker stays independent but extracts just the nav-button wiring into a small utility function in src/components/scripts/embla/navigation.ts (~30 lines). This avoids forcing ThemePicker into a base class that's 90% irrelevant to it.
68
+
B: ThemePicker extends EmblaCarouselBase with autoplay disabled and most features no-op'd. This feels forced and adds cognitive overhead for no real benefit.
69
+
I'd recommend A. The base class serves the autoplay-carousel family (Carousel, Testimonials, Skills, and any future autoplay carousel). ThemePicker shares one small utility.
70
+
71
+
Estimated result
72
+
EmblaCarouselBase.ts: ~350–400 lines (extracted from current duplication)
73
+
Each subclass (Carousel, Testimonials, Skills): ~50–150 lines of component-specific code
74
+
navigation.ts utility for ThemePicker: ~30 lines
75
+
Net reduction: ~400+ lines eliminated across Carousel and Testimonials
76
+
Skills starts with a thin subclass instead of copy-pasting a fourth time
Copy file name to clipboardExpand all lines: _TODO.md
+143-8Lines changed: 143 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,45 @@ Cons: Browser rendering can be inconsistent across different operating systems a
21
21
22
22
Axe accessibility (2) - axe-core integration
23
23
24
+
## Missing E2E Component Tests
25
+
26
+
- Code/CodeBlock
27
+
- Code/CodeTabs
28
+
- Consent/Checkbox
29
+
30
+
## Testimonials on mobile
31
+
32
+
We have E2E errors again testimonials slide on mobile chrome and safari. I think the problem is that we are pausing carousels when part of the carousel is outside of the viewport, and the testimonials are too large to display on mobile without being off viewport.
## Refactor of Common Code in Carousel related components
37
+
38
+
See if there's any code in common between Carousel, Testimonials, and Themepicker. We have another one to add that uses the carousel code - for Skills.
39
+
40
+
Issue identified with refactoring Testimonial and Carousel to Lit custom web components:
41
+
42
+
The only thing to watch: the `transition:persist` directive must remain on the HTML custom element tag itself, not on an Astro component wrapper. That's already a project rule and isn't affected by `LitElement` vs `HTMLElement`.
43
+
44
+
#### Selector files
45
+
46
+
Carousel/client/selectors.ts and Testimonials/client/selectors.ts follow an identical pattern — only the CSS selectors and data-attribute names differ. The query/get function pairs are structurally identical.
| Base class |[HTMLElement](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|[HTMLElement](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|[LitElement](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)|
62
+
24
63
## Youtube video for Backstage IDP hero on Home page
25
64
26
65
Discuss agentic AI integrations to add to Backstage
@@ -39,14 +78,6 @@ Vercel AI Gateway, maybe could use for a chatbot:
We have E2E errors again testimonials slide on mobile chrome and safari. I think the problem is that we are pausing carousels when part of the carousel is outside of the viewport, and the testimonials are too large to display on mobile without being off viewport.
45
-
46
-
See if there's any code in common between Carousel, Testimonials, and Themepicker. We have another one to add that uses the carousel code - for Skills.
We should start the mock containers with the dev server instead of with Playwright so that they're useable in a dev environment.
@@ -238,3 +269,107 @@ This article has different approaches to [print pagination](https://www.customjs
238
269
- cover.jpg for reliability-and-testing needs touch up in GIMP
239
270
- We need to check for short form and deep article articles where the deep-dive index.pdf has a non-featured tag lik "argo-cd" only in the pdf.mdx. In those cases, we should make sure the callout for the deep dive includes the name of that non-featured (technology) tag and add the name to the tags: frontmatter key in the index.mdx
240
271
- Need an article on OpenStack
272
+
273
+
## HTMLElement vs. extends HTMLElement
274
+
275
+
A bunch of our web components extend directly from HTMLElement instead of following the instructions to extend LitElement.
276
+
277
+
- Code/CodeBlock
278
+
- Code/CodeTabs
279
+
- Consent/Banner
280
+
- Consent/Checkbox
281
+
- Consent/Preferences
282
+
283
+
And the embla components: Carousel and Testimonials
284
+
285
+
The WebComponentModule type in this file is used throughout component scripts:
70:5 error Use `keyup with addButtonEventListeners or addWrapperEventListeners` from `elementListeners` for keyboard events (use keyup instead of keydown for better accessibility) instead of direct addEventListener. This ensures consistent accessibility support (isComposing check, repeat prevention, Enter/Escape key handling) custom-rules/enforce-centralized-events
FAIL src/components/Home/Hero/client/__tests__/index.spec.ts > HomeHeroElement (Lit) > types the ready prompt one character every 500ms and stops when complete
331
+
AssertionError: expected '' to be 'r' // Object.is equality
FAIL src/components/Home/Hero/client/__tests__/index.spec.ts > HomeHeroElement (Lit) > skips animation and shows final text when reduced motion is preferred
351
+
AssertionError: expected '' to be 'heck yes, let\'s talk...' // Object.is equality
at Object.transform (file:///home/kevin/Repos/WebstackBuilders/CorporateWebsite/astro.webstackbuilders.com/node_modules/@astrojs/mdx/dist/vite-plugin-mdx.js:60:18)
374
+
at process.processImmediate (node:internal/timers:473:9)
375
+
at async ModuleLoader.addModuleSource (file:///home/kevin/Repos/WebstackBuilders/CorporateWebsite/astro.webstackbuilders.com/node_modules/rollup/dist/es/shared/node-entry.js:21363:36)
0 commit comments