raystack / raystack/apsara

[Theme] Enhance customization capabilities

Open
#578 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

global triage
Dominant language
TypeScript
Stars
70
Forks
13
Avg merge
2d 5h
Merged PRs (30d)
8

Description

Summary

Enhance the ThemeProvider to support comprehensive theming customization, making Apsara more adaptable to different design requirements and use cases.

Current Capabilities

The ThemeProvider already handles:

  • Theme mode (light / dark / system)
  • Style variants (modern / traditional)
  • Accent colors (indigo / orange / mint)
  • Gray scales (gray / mauve / slate / sage)
  • Persistence via localStorage
  • System preference detection
  • FOUC prevention with inline script

Proposed Enhancements

1. Scaling/Density
scaling: 'compact' | 'default' | 'comfortable' | 'spacious'

Adjusts spacing tokens globally for different UI densities. Useful for data-dense applications vs content-focused interfaces.

2. Border Radius Control
radius: 'none' | 'small' | 'medium' | 'large' | 'full'

Global control over component roundness beyond style variants. Allows sharp corners for enterprise apps or pill-shaped components for playful designs.

3. Typography Scale
fontFamily: { body: string; heading: string; mono: string }
fontSize: 'small' | 'default' | 'large'  // Base scale multiplier

Allow consumers to customize font families and adjust the base font size scale.

4. Custom Token Overrides
tokens: {
  colors?: Partial<ColorTokens>
  spacing?: Partial<SpacingTokens>
  radius?: Partial<RadiusTokens>
  shadows?: Partial<ShadowTokens>
}

Allow consumers to override any design token for brand-specific customization.

5. Component-Level Defaults
components: {
  Button?: { variant?: 'solid' | 'outline'; size?: 'sm' | 'md' }
  Input?: { variant?: 'default' | 'soft' }
  // etc.
}

Set default props for components at the theme level, reducing repetition across the app.

6. Animation Control
reducedMotion: boolean | 'system'
transitionDuration: 'none' | 'fast' | 'default' | 'slow'

Respect user accessibility preferences and allow global animation speed control.

7. Nested Appearance Mode
appearance: 'light' | 'dark' | 'inherit'  // Per-subtree theming

Allows nested theme contexts with different modes (e.g., dark sidebar in light app).

8. Panel Background Mode
panelBackground: 'solid' | 'translucent'  // For glassmorphism effects

Support for modern translucent/blur backgrounds on panels, cards, and overlays.

9. Cursor Token System

Add cursor CSS variables for global control over cursor styles on interactive components:

cursors?: {
  button?: string
  checkbox?: string
  disabled?: string
  link?: string
  slider?: string
  switch?: string
}

Exposed as CSS variables (--rs-cursor-button, --rs-cursor-checkbox, --rs-cursor-disabled, etc.) so teams can globally customize cursor behavior (e.g., pointer on buttons vs default).

10. Auto-Paired Gray + Accent Colors

Automatically pair accent colors with complementary gray scales when no explicit grayColor is set:

  • indigo / iris / violetslate
  • mint / teal / cyansage
  • orange / ambermauve
  • crimson / pinkmauve

This provides better visual harmony out of the box while still allowing manual override.

Suggested Interface

interface ThemeProviderProps {
  // Existing
  theme?: 'light' | 'dark' | 'system'
  style?: 'modern' | 'traditional'
  accentColor?: 'indigo' | 'orange' | 'mint' | string
  grayColor?: 'gray' | 'mauve' | 'slate' | 'sage'
  
  // New capabilities
  scaling?: 'compact' | 'default' | 'comfortable' | 'spacious'
  radius?: 'none' | 'small' | 'medium' | 'large' | 'full'
  reducedMotion?: boolean | 'system'
  transitionDuration?: 'none' | 'fast' | 'default' | 'slow'
  panelBackground?: 'solid' | 'translucent'
  cursors?: Partial<CursorTokens>
  
  // Advanced customization
  tokens?: DeepPartial<DesignTokens>
  components?: ComponentDefaults
  
  // Configuration
  storageKey?: string
  disableTransitionOnChange?: boolean
}

Implementation Notes

  • All new props should have sensible defaults to maintain backward compatibility
  • CSS variables should be the primary mechanism for runtime theming
  • Consider generating CSS at build time for static themes to improve performance

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Begin with the existing ThemeProvider and its current theme, variant, color, persistence, and CSS-variable behavior. Break the proposal into separately scoped capabilities and identify the design-token and component-default entry points before implementation. Done requires agreed defaults, backward compatibility, runtime CSS-variable support, and coverage for the requested customization options.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
design, frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.