Skip to content

feat: Implement Color Palette Extensibility & Dynamic Theme Registry (#3334) - #3510

Open
knoxiboy wants to merge 1 commit into
Karanjot786:mainfrom
knoxiboy:3334-feat-color-palette-extensibility-dynamic-theme-registry
Open

feat: Implement Color Palette Extensibility & Dynamic Theme Registry (#3334)#3510
knoxiboy wants to merge 1 commit into
Karanjot786:mainfrom
knoxiboy:3334-feat-color-palette-extensibility-dynamic-theme-registry

Conversation

@knoxiboy

@knoxiboy knoxiboy commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

Implements runtime theme registration and dynamic color palette extensibility (ThemeRegistryManager) allowing developers to extend terminal UI color themes dynamically.

Related Issue

Closes #3334

Which package(s)?

@termuijs/core

Type of Change

  • 🐛 Bug fix (type:bug)
  • ✨ Feature (type:feature)
  • 📝 Docs (type:docs)
  • 🧪 Tests (type:testing)
  • ♻️ Refactor (type:refactor)
  • 🎨 Design / UX (type:design)
  • ♿ Accessibility (type:accessibility)
  • ⚡ Performance (type:performance)
  • 🔧 DevOps / CI (type:devops)
  • 🔒 Security (type:security)

Checklist

  • ⭐ You starred the repo. The needs-star check blocks your merge otherwise.
  • Tests pass locally: bun vitest run
  • Build passes: bun run build
  • Typecheck passes: bun run typecheck
  • You read CONTRIBUTING.md.
  • Your PR title follows type: short description.
  • Widget state mutators call markDirty() (if your change affects rendering).
  • No new any types without an inline comment explaining why.
  • No unrelated refactors bundled into this PR.

GSSoC 2026 Participation

  • You are a GSSoC 2026 contributor.
  • Your GSSoC profile: https://gssoc.girlscript.org/profile/knoxiboy

Screenshots / Recordings (UI changes)

Supports dynamic theme swapping at runtime with zero restart overhead.

Notes for the Reviewer

Zero external dependencies; integrates with existing ANSI theme tokens.

Summary by CodeRabbit

  • New Features
    • Added theme management with a default theme and support for registering and switching between custom themes.
    • Added configurable color palettes, including optional border and accent colors.
    • Added the ability to extend active theme palettes and view available themes.

@knoxiboy
knoxiboy requested a review from Karanjot786 as a code owner August 4, 2026 18:27
Copilot AI lite review requested due to automatic review settings August 4, 2026 18:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added type:feature +10 pts. New feature. area:core @termuijs/core type:testing +10 pts. Tests. labels Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a theme registry subsystem with palette and theme contracts. ThemeRegistryManager initializes a default theme, supports custom theme registration and activation, extends palettes, retrieves the active theme, and lists registered themes. Unit tests cover the main operations.

Changes

Theme registry

Layer / File(s) Summary
Theme registry contracts and operations
packages/core/src/theme/themeRegistry.ts
Adds ColorPalette, ThemeDefinition, and ThemeRegistryManager. The manager supports default initialization, guarded registration, active-theme switching, fallback retrieval, partial palette merging, and theme-name listing.
Theme registry behavior validation
packages/core/test/themeRegistry.test.ts
Tests default theme values, custom theme registration and activation, and palette color overrides.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related issues

  • #3507 — The PR adds the theme and color-palette registry described by the issue.

Suggested reviewers: karanjot786, copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds a registry and palette extension, but it omits the required presets, color-mode support, JSON schema, and fallback-resolution tests [#3334]. Add Dracula, Nord, Monokai, and Cyberpunk presets, support ANSI/256/TrueColor schemas, and add color-resolution and non-TrueColor fallback tests.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the new color palette extensibility and dynamic theme registry feature.
Description check ✅ Passed The description includes the required sections, linked issue, package, feature type, checklist, and reviewer notes.
Out of Scope Changes check ✅ Passed The changed files implement the requested theme registry feature and related unit tests without unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/theme/themeRegistry.ts`:
- Around line 22-34: Update the ThemeRegistry constructor to register the
required built-in Dracula, Nord, Monokai, and Cyberpunk presets alongside
default, using each preset’s defined name and palette. Add behavior tests
confirming each preset is available through listThemes() and can be selected
with setActiveTheme().
- Around line 36-59: The ThemeRegistry methods must validate runtime theme data
against the JSON theme schema before storage or mutation. Update registerTheme
to reject themes lacking required palette keys or containing non-string/invalid
color values, and update extendPalette to validate every customPalette entry
before merging so existing valid data is preserved on failure; return a
caller-handleable success/failure result from both operations and keep
this.themes.set and palette updates limited to valid input.
- Around line 1-13: Replace the undifferentiated string fields in ColorPalette
with a discriminated color value type carrying RGB, indexed, or ANSI metadata,
and add a capability-aware resolver in the theme registry. Resolve colors
appropriately for TrueColor, 256-color, and 16-color ANSI terminals, with
non-TrueColor fallbacks preserving usable output. Add tests covering RGB,
indexed, ANSI, and each fallback path.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ff54ddd8-374b-4f05-9cef-9d8b7ad1f19f

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7584e and 54b1cb4.

📒 Files selected for processing (2)
  • packages/core/src/theme/themeRegistry.ts
  • packages/core/test/themeRegistry.test.ts

Comment on lines +1 to +13
export interface ColorPalette {
primary: string;
secondary: string;
background: string;
text: string;
border?: string;
accent?: string;
}

export interface ThemeDefinition {
name: string;
palette: ColorPalette;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Add color-mode metadata and fallback resolution.

ColorPalette stores every color as an undifferentiated string. The manager cannot resolve RGB values to 256-color or ANSI 16-color values when terminal support is limited.

Use a discriminated color value type and add a capability-aware resolver. Test RGB, indexed, and ANSI fallback behavior.

Based on PR objectives, the registry must support 16-color ANSI, 256-color, TrueColor, and non-TrueColor fallback behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/theme/themeRegistry.ts` around lines 1 - 13, Replace the
undifferentiated string fields in ColorPalette with a discriminated color value
type carrying RGB, indexed, or ANSI metadata, and add a capability-aware
resolver in the theme registry. Resolve colors appropriately for TrueColor,
256-color, and 16-color ANSI terminals, with non-TrueColor fallbacks preserving
usable output. Add tests covering RGB, indexed, ANSI, and each fallback path.

Comment on lines +22 to +34
constructor() {
this.registerTheme({
name: 'default',
palette: {
primary: '#3b82f6',
secondary: '#64748b',
background: '#0f172a',
text: '#f8fafc',
border: '#334155',
accent: '#eab308',
},
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Register the required built-in presets.

The constructor registers only default. It does not register the required Dracula, Nord, Monokai, and Cyberpunk presets. listThemes() and setActiveTheme() cannot use those themes until a caller adds them manually.

Register the four presets during initialization and add behavior tests for each preset.

Based on PR objectives, these four presets are required defaults.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/theme/themeRegistry.ts` around lines 22 - 34, Update the
ThemeRegistry constructor to register the required built-in Dracula, Nord,
Monokai, and Cyberpunk presets alongside default, using each preset’s defined
name and palette. Add behavior tests confirming each preset is available through
listThemes() and can be selected with setActiveTheme().

Comment on lines +36 to +59
registerTheme(theme: ThemeDefinition): void {
if (!theme || !theme.name) return;
this.themes.set(theme.name, theme);
}

setActiveTheme(name: string): boolean {
if (this.themes.has(name)) {
this.activeThemeName = name;
return true;
}
return false;
}

getActiveTheme(): ThemeDefinition {
return this.themes.get(this.activeThemeName) || Array.from(this.themes.values())[0];
}

extendPalette(themeName: string, customPalette: Partial<ColorPalette>): void {
const existing = this.themes.get(themeName);
if (existing) {
existing.palette = {
...existing.palette,
...customPalette,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate runtime theme data before storage or merge.

registerTheme() checks only theme.name. A parsed external JSON theme can omit required palette fields or provide non-string values. extendPalette() can also overwrite a required color with an invalid value. The registry then returns data that violates ThemeDefinition.

Validate required palette keys and color value formats before this.themes.set() and before merging customPalette. Reject invalid input with a result that callers can handle.

Based on PR objectives, registerTheme() must support external JSON themes through a JSON theme schema.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/theme/themeRegistry.ts` around lines 36 - 59, The
ThemeRegistry methods must validate runtime theme data against the JSON theme
schema before storage or mutation. Update registerTheme to reject themes lacking
required palette keys or containing non-string/invalid color values, and update
extendPalette to validate every customPalette entry before merging so existing
valid data is preserved on failure; return a caller-handleable success/failure
result from both operations and keep this.themes.set and palette updates limited
to valid input.

@saurabhhhcodes saurabhhhcodes mentioned this pull request Aug 4, 2026
4 tasks
@Karanjot786

Copy link
Copy Markdown
Owner

Duplicates existing — ThemeRegistryManager parallels the tss theme system (BUILTIN_THEMES/ThemeTokens/engine/AutoThemeProvider) with no ThemeTokens compatibility and no wiring into ThemeSwitcher or the engine; unexported/unreferenced dead island. Build on the tss theme system.

@Karanjot786 Karanjot786 added the quality:needs-work Needs changes before merge. label Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core @termuijs/core quality:needs-work Needs changes before merge. type:feature +10 pts. New feature. type:testing +10 pts. Tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Implement Color Palette Extensibility & Dynamic Theme Registry

3 participants