From 603ea700357f328db378ac264ec6aa52ccfff13e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:38:52 +0000 Subject: [PATCH 1/6] Initial plan From 117121e35aac26f16492345d723f35ef149600a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:41:11 +0000 Subject: [PATCH 2/6] Initial exploration of tabbed-interface repository Co-authored-by: aarongustafson <75736+aarongustafson@users.noreply.github.com> --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 9e1928a..dc7b048 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "vitest": "^4.0.10" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" } }, "node_modules/@babel/code-frame": { From 43eb85a9fd4d66bcae58a8d7a612ae0777a85bbe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:45:47 +0000 Subject: [PATCH 3/6] Implement CSS custom properties and improve style inheritance - Add color: inherit to :host to allow text color to flow from outside - Implement all documented CSS custom properties for tablist, tab, and tabpanel - Add color: inherit to tabpanel to pass text color to content - This allows better style inheritance through the shadow DOM boundary Co-authored-by: aarongustafson <75736+aarongustafson@users.noreply.github.com> --- tabbed-interface.js | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/tabbed-interface.js b/tabbed-interface.js index d1f6668..0ea875c 100644 --- a/tabbed-interface.js +++ b/tabbed-interface.js @@ -258,16 +258,18 @@ export class TabbedInterfaceElement extends HTMLElement { + + +
+

Style Inheritance Demo

+

+ This page demonstrates how the tabbed interface now supports + style inheritance through the shadow DOM boundary using CSS + custom properties and inherited properties. +

+
+ +
+ +
+

Example 1: Inherited Properties

+

+ Properties like color and + font-family naturally inherit through shadow + DOM boundaries. The component now properly passes these + through to tab panel content. +

+ +
+ +

Welcome

+

+ This text inherits the white color from the parent + .hero div. +

+

+ The gradient background is on the parent, and the + text color flows through the shadow DOM boundary. +

+ +

Features

+
    +
  • Color inheritance works seamlessly
  • +
  • Font family is inherited from parent
  • +
  • + Text maintains the same styling as the + surrounding context +
  • +
  • No special configuration needed!
  • +
+ +

How It Works

+

+ The component uses color: inherit on + both :host and + [role="tabpanel"]. +

+

+ This allows inherited CSS properties to flow through + the shadow DOM boundary naturally. +

+
+
+ +
+ Key Insight: The white text you see in the + tabs above is inherited from the parent .hero div, not set + directly on the component. This is exactly what the bug + report requested! +
+
+ + +
+

Example 2: CSS Custom Properties

+

+ The component now implements all documented CSS custom + properties, allowing you to customize the appearance without + piercing the shadow DOM. +

+ +
+ +

Dark Theme

+

+ This tabbed interface uses CSS custom properties to + achieve a dark theme with red accents. +

+

+ The text color (dark gray) is inherited from the + parent element. +

+ +

Customization

+

All styling is done with CSS custom properties:

+
    +
  • + --tabbed-interface-tab-background +
  • +
  • + --tabbed-interface-tab-active-background +
  • +
  • + --tabbed-interface-tabpanel-padding +
  • +
  • And many more!
  • +
+ +

Benefits

+

+ Using CSS custom properties allows for complete + customization while respecting the component + boundary. +

+
+
+
+ + +
+

Example 3: Typography Inheritance

+

+ Font family and size are inherited, allowing the component + to adapt to different typographic contexts. +

+ +
+ +

Typography

+

+ This example uses Georgia serif font, inherited from + the parent container. The font family flows through + to all text within the tabbed interface. +

+

+ Line height and font size are also inherited, + ensuring consistent typography throughout. +

+ +

Readability

+

+ Proper typography inheritance ensures that your + content maintains its intended readability and + aesthetic, regardless of where it's placed. +

+

+ The component adapts to your design system rather + than imposing its own styles. +

+ +

Design Systems

+

+ This makes the component perfect for use in design + systems where consistent typography is essential. +

+
+
+
+ + +
+

Example 4: VS Code Dark Theme

+

+ A practical example showing how the component can adapt to a + code editor aesthetic. +

+ +
+ +

JavaScript

+

const message = 'Hello World';

+

console.log(message);

+

// This code uses VS Code dark theme colors

+ +

CSS

+

.container {

+

  display: flex;

+

  color: inherit;

+

}

+ +

HTML

+

<div class="container">

+

  <p>Content here</p>

+

</div>

+
+
+
+ + +
+

Before vs After

+ +
+
+

❌ Before (Browser Defaults)

+

+ Issue: Content lost its styling + when wrapped in a tabpanel +

+
    +
  • Text reverted to black (#000)
  • +
  • Font family reset to browser default
  • +
  • Custom backgrounds lost
  • +
  • Design system styles not applied
  • +
+
+ +
+

✅ After (With Inheritance)

+

Fixed: Styles properly inherited

+
    +
  • Text color inherited from parent
  • +
  • Font family preserved
  • +
  • Typography maintained
  • +
  • CSS custom properties work
  • +
+
+
+
+ + +
+

Technical Implementation

+ +
+ What Changed: +
    +
  • + Added color: inherit to + :host element +
  • +
  • + Added color: inherit to + [role="tabpanel"] +
  • +
  • + Implemented all documented CSS custom properties +
  • +
  • + Properties can now be customized with + var(--tabbed-interface-*) +
  • +
+
+ +

Available CSS Custom Properties

+ +
+
+ + + + + + From 5e9b84c4deb47b20148f738039cf676420a28789 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:49:41 +0000 Subject: [PATCH 6/6] Format test file with prettier Co-authored-by: aarongustafson <75736+aarongustafson@users.noreply.github.com> --- test/style-inheritance.test.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/style-inheritance.test.js b/test/style-inheritance.test.js index f71d0f3..eafb681 100644 --- a/test/style-inheritance.test.js +++ b/test/style-inheritance.test.js @@ -36,7 +36,8 @@ describe('TabbedInterfaceElement - Style Inheritance', () => { expect(hostStyle.color).toBe('rgb(255, 0, 0)'); // Check tabpanel has color: inherit in its CSS - const tabpanel = element.shadowRoot.querySelector('[role="tabpanel"]'); + const tabpanel = + element.shadowRoot.querySelector('[role="tabpanel"]'); expect(tabpanel).toBeTruthy(); // The tabpanel should have color: inherit which allows it to inherit from :host @@ -62,8 +63,12 @@ describe('TabbedInterfaceElement - Style Inheritance', () => { }); it('should apply --tabbed-interface-tabpanel-padding', () => { - element.style.setProperty('--tabbed-interface-tabpanel-padding', '2em'); - const tabpanel = element.shadowRoot.querySelector('[role="tabpanel"]'); + element.style.setProperty( + '--tabbed-interface-tabpanel-padding', + '2em', + ); + const tabpanel = + element.shadowRoot.querySelector('[role="tabpanel"]'); const style = window.getComputedStyle(tabpanel); // The padding should be set (exact value depends on font size) @@ -75,7 +80,8 @@ describe('TabbedInterfaceElement - Style Inheritance', () => { '--tabbed-interface-tabpanel-background', 'rgb(173, 216, 230)', ); - const tabpanel = element.shadowRoot.querySelector('[role="tabpanel"]'); + const tabpanel = + element.shadowRoot.querySelector('[role="tabpanel"]'); const style = window.getComputedStyle(tabpanel); expect(style.backgroundColor).toBe('rgb(173, 216, 230)'); @@ -129,7 +135,8 @@ describe('TabbedInterfaceElement - Style Inheritance', () => { await new Promise((resolve) => requestAnimationFrame(resolve)); await new Promise((resolve) => setTimeout(resolve, 10)); - const tabpanel = element.shadowRoot.querySelector('[role="tabpanel"]'); + const tabpanel = + element.shadowRoot.querySelector('[role="tabpanel"]'); const paragraph = tabpanel.querySelector('p'); const pStyle = window.getComputedStyle(paragraph);