Skip to content

feat: add custom theme support via component_config#583

Open
paddymul wants to merge 11 commits intomainfrom
feat/custom-theme-support
Open

feat: add custom theme support via component_config#583
paddymul wants to merge 11 commits intomainfrom
feat/custom-theme-support

Conversation

@paddymul
Copy link
Copy Markdown
Collaborator

Summary

  • Add ThemeConfig type (7 optional color/scheme properties) nested inside ComponentConfig — rides the existing pipeline with no new traitlets or sync wiring
  • resolveColorScheme() is the single source of truth for light/dark resolution — respects colorScheme override or falls back to OS detection
  • className is now additive to the auto-detected AG Grid theme class (no longer replaces it)
  • CSS custom properties (--bk-accent-color, --bk-accent-hover-color, --bk-bg-color) scoped per-instance via inline style on the wrapper div
  • Server /load endpoint accepts optional component_config and merges it into df_display_args

Usage

import buckaroo
w = buckaroo.BuckarooWidget(df, component_config={
    'theme': {
        'colorScheme': 'dark',
        'accentColor': '#ff6600',
        'accentHoverColor': '#cc5200',
        'backgroundColor': '#1a1a2e',
    }
})

Test plan

  • uv run pytest tests/unit/test_theme_config.py -v — 4 Python config flow tests pass
  • uv run pytest tests/unit/ -v — 574 existing tests pass, 0 regressions
  • uv run pytest tests/unit/server/ -v — 13 server tests pass
  • TS compiles clean (tsc --noEmit — only pre-existing FloatingTooltip errors)
  • npx playwright test theme-custom — Storybook visual assertions
  • npx playwright test theme-custom-server — Server integration assertions
  • Manual: load themed stories in Storybook, verify colors

Closes #582

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 25, 2026

📦 TestPyPI package published

pip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.13.5.dev24014991341

or with uv:

uv pip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.13.5.dev24014991341

MCP server for Claude Code

claude mcp add buckaroo-table -- uvx --from "buckaroo[mcp]==0.13.5.dev24014991341" --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo-table

📖 Docs preview

🎨 Storybook preview

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0f02302e3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +283 to +285
dvc["component_config"] = {
**dvc.get("component_config", {}),
**component_config,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Persist component_config in buckaroo dataflow state

LoadHandler.post only overlays component_config onto session.df_display_args here, but buckaroo interactions later rebuild df_display_args from session.dataflow in DataStreamHandler._handle_buckaroo_state_change (websocket_handler.py), which never receives this config. In server mode="buckaroo", theme/custom component settings from /load are therefore lost after the first state-changing action (for example changing cleaning/post-processing), so the new feature does not persist through normal usage.

Useful? React with 👍 / 👎.

...hs.applicableStyle,
...(themeConfig?.accentColor ? { '--bk-accent-color': themeConfig.accentColor } as any : {}),
...(themeConfig?.accentHoverColor ? { '--bk-accent-hover-color': themeConfig.accentHoverColor } as any : {}),
...(themeConfig?.backgroundColor ? { '--bk-bg-color': themeConfig.backgroundColor } as any : {}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor forced colorScheme when backgroundColor is omitted

This style injection only sets --bk-bg-color when themeConfig.backgroundColor is provided, so a config like { colorScheme: 'dark' } leaves no background variable and .theme-hanger falls back to the OS media-query defaults in CSS. As a result, forced light/dark mode can still show the opposite wrapper/empty-grid background unless callers also set backgroundColor, which breaks the expected behavior of colorScheme override by itself.

Useful? React with 👍 / 👎.

@paddymul
Copy link
Copy Markdown
Collaborator Author

@codex implement any code fixes you see necessary on this PR

@chatgpt-codex-connector
Copy link
Copy Markdown

Summary

Testing

  • ⚠️ pytest tests/unit/server/test_server.py -q (failed in environment: missing pandas in non-uv interpreter).
  • ⚠️ uv run pytest tests/unit/server/test_server.py -q (failed in environment: missing built frontend artifact buckaroo/static/widget.js).
  • uv run python -m compileall buckaroo/server/handlers.py buckaroo/server/websocket_handler.py buckaroo/server/session.py
  • npm --prefix packages/buckaroo-js-core run -s build:tsc
  • ⚠️ Playwright screenshot attempt via browser tool to http://127.0.0.1:6006 failed with ERR_EMPTY_RESPONSE (Storybook server not running), so no screenshot artifact was produced.

Committed on the current branch (22ccd8a) and created a follow-up PR via make_pr.

View task →

Add ThemeConfig (colorScheme, accentColor, accentHoverColor, backgroundColor,
foregroundColor, oddRowBackgroundColor, borderColor) nested in ComponentConfig.
Flows through existing pipeline — Python widget, server /load endpoint, and
JS rendering all support theme overrides with no new traitlets or sync wiring.

Resolves #582

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@paddymul paddymul force-pushed the feat/custom-theme-support branch from 9cb2bd9 to 8f15640 Compare April 5, 2026 20:45
- Add docs/source/articles/theme-customization.rst with 13 live static
  embed demos (colors, auto light/dark, spacing, VC pricing)
- Add scripts/generate_theme_static_html.py to generate demo HTML
- Add light/dark sub-dicts to ThemeConfig for per-scheme color overrides
- Add resolveThemeColors() to merge scheme-specific overrides
- Add layout properties: spacing, cellHorizontalPaddingScale,
  rowVerticalPaddingScale, headerBorderColor
- Fix Codex P1: persist component_config in session state across
  dataflow rebuilds (session.py + websocket_handler.py)
- Fix Codex P2: always set --bk-bg-color with scheme-based fallback
- Wire RTD build to generate theme static HTML

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DFViewer embed type shows summary stats as pinned rows which dominated
the small demo datasets. Buckaroo embed type defaults to df_display=main.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add headerBackgroundColor to ThemeConfig — colors all header rows
  including MultiIndex group headers
- Add MultiIndex demo with styled header separators showing how
  borderColor, headerBorderColor, and headerBackgroundColor interact

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each theme property gets a distinct loud color so readers can see
exactly which key targets which piece of the grid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- BuckarooStaticWidget now passes themeConfig to StatusBar so the
  status bar picks up the same theme as the main grid
- MultiIndex demo uses CSS color names instead of hex for readability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@paddymul paddymul deployed to testpypi April 6, 2026 01:25 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add custom theme support

1 participant