-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Description
Bug description
Context
While implementing custom themes for Superset I’m facing challenges that make customization more difficult than it should be, especially regarding how tokens are used across components.
Current Problems
Problem 1: Token Hierarchy Inconsistency
Current Situation:
- Superset uses Ant Design GLOBAL tokens for theming
- Global tokens (
colorPrimary,colorText, etc.) are properly exposed via SupersetTheme - Component tokens (
components.Button.colorPrimary,components.Menu.itemColor, etc.) are not consistently accessible
When Superset styles reference tokens, they often use global tokens where component tokens would be more appropriate.
Example - Modal theming conflict:
// Theme provides:
{
"token": {
"colorBgContainer": "#ffffff", // Global token ✓
},
"components": {
"Modal": {
"contentBg": "#f6f7f8", // Component token - NOT in SupersetTheme ❌
"contentPadding": "20px" // Component token - NOT in SupersetTheme ❌
}
}
}
// Superset overrides modal styles with:
const StyledModal = styled(Modal)`
${({ theme }) => css`
.ant-modal-content {
background-color: ${theme.colorBgContainer}; // Uses global, not component token
padding: 0; // Hardcoded, ignores theme.components.Modal.contentPadding
}
`}
`;Question: Should SupersetTheme interface include Ant Design's component tokens?
Problem 2: Custom Components Without Theming Support
Example - Toast component:
// Current implementation:
function Toast({ toast, onCloseToast }: ToastPresenterProps) {
...
return (
<ToastContainer
className={cx('alert', 'toast', visible && 'toast--visible', className)}
data-test="toast-container"
role="alert"
>
<div className="toast__content">
{icon}
<Interweave content={toast.text} noHtml={!toast.allowHtml} />
</div>
<Icons.CloseOutlined
iconSize="m"
className="toast__close pointer"
role="button"
tabIndex={0}
onClick={handleClosePress}
aria-label="Close"
data-test="close-button"
/>
</ToastContainer>
);
}
// Problem - can't theme via components tokens (Toast is custom, not Antd)Other examples:
- Chart type selector (custom, not Antd.List)
PublishedLabelcomponent- "View mode" control on dashboard
Question: Should we:
- Add custom tokens for Superset-specific components?
- Convert custom components to use Ant Design's theming system?
- Create a separate theming layer for Superset components?
Problem 3: Style Override Conflicts
The override chain becomes unpredictable:
- Ant Design default styles
- Ant Design theme tokens (may or may not be exposed)
- Superset global overrides (hardcoded CSS)
- User's custom theme (only affects exposed tokens)
- User's custom CSS (breaks with updates)
Result: Theming feels like "whack-a-mole" - fix one thing, break another.
Proposal for Discussion
We need a systematic approach to theming. Possible directions:
Option A: Extend SupersetTheme type
- Add tokens for Antd components
- Add tokens for custom Superset components
Option B: Component Standardization
- Convert Superset-specific components to use Ant Design equivalent where possible
- For truly custom components, implement consistent theming pattern
- Avoid overriding Ant Design component styles unless absolutely necessary
- When styling is needed, use token-based approaches rather than hardcoded CSS
Option C: Documentation + Tooling
- Document which components are themeable and how
- Create theme debugging tool (shows which tokens affect which elements)
- Provide migration path for users with custom themes
Conclusion
Current state: Theming requires deep knowledge of:
- Which tokens are exposed
- Which components override which styles
- Where hardcoded values bypass theme
- Workarounds for unthemeable components
Desired state: Predictable, hierarchical theming where:
- All visual aspects controlled via tokens
- Component tokens > Global tokens hierarchy
- Custom components follow same pattern
- Overrides are intentional, not accidental
It would be really helpful to hear from the Superset authors and maintainers about these theming patterns. You built the system and know it best. Your thoughts could help us understand what changes would work and what might cause problems.
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.9
Node version
16
Browser
Chrome
Additional context
No response
Checklist
- I have searched Superset docs and Slack and didn't find a solution to my problem.
- I have searched the GitHub issue tracker and didn't find a similar bug report.
- I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.