Skip to content

Theming

Graphyn ships with a dark and a light colour scheme, four palette presets, and a GraphynBranding API for custom colours and logos.


Quick start

Pass GraphynBranding to GraphynEditorShell or GraphynApp:

GraphynEditorShell(
    branding = GraphynBranding(
        appName = "My Workflow Editor",
        palette = GraphynThemePresets.Violet,
    ),
    dependencies = ...,
    state = state,
)

Dark / light mode

GraphynTheme follows the system setting by default. Override with rememberGraphynAppearanceState:

val appearanceState = rememberGraphynAppearanceState()

// Force dark
appearanceState.themeMode = GraphynThemeMode.Dark

// Force light
appearanceState.themeMode = GraphynThemeMode.Light

// Follow system (default)
appearanceState.themeMode = GraphynThemeMode.System

Palette presets

Four built-in palettes:

Preset Accent colour
GraphynThemePresets.Default Coral #FF6D5A
GraphynThemePresets.Violet Violet #8B5CF6
GraphynThemePresets.Emerald Emerald #10B981
GraphynThemePresets.Coral Warm coral (legacy n8n-inspired)
GraphynBranding(palette = GraphynThemePresets.Emerald)

Custom palette

GraphynThemePreset is a data class — override individual colours:

val myPalette = GraphynThemePresets.Default.copy(
    darkAccent  = Color(0xFF3B82F6),  // blue accent in dark mode
    lightAccent = Color(0xFF2563EB),  // blue accent in light mode
)

GraphynBranding(palette = myPalette)

Design token reference

The full palette of semantic tokens used inside the editor is in GraphynDsColors. The dark and light variants are GraphynDsColors.Dark and GraphynDsColors.Light. These are derived from the active GraphynThemePreset at runtime — you do not normally need to override them directly.

Token Dark value Light value Used for
canvasBackground #1A1B26 #EEF0F5 Canvas surface fill
panelBackground #252630 #FFFFFF Side panels, toolbar
surfaceCard #2D2E3D #FFFFFF Node cards
textPrimary #E0E0E6 #1A1B26 Labels, node titles
textSecondary #9B9BA5 #6B7280 Port names, hints
accent #FF6D5A #F55A4A Selected state, run button
portInput #7AA2FF #4F7CFF Input port dots
portOutput #FF6D5A #F55A4A Output port dots
selectionRing #7AA2FF #4F7CFF Node selection border
danger #FF6B6B #DC2626 Error badge, delete actions

Access the active colours inside a composable:

val colors = GraphynDs.colors
Box(Modifier.background(colors.surfaceCard)) { ... }

Typography

The editor uses a single GraphynDsTypography instance with two weights. Override via branding if needed (future API — not yet exposed on GraphynBranding).


Embedding inside an existing theme

GraphynTheme is a self-contained CompositionLocal scope. Wrap only the editor portion — your app's own theme continues to apply outside:

MyAppTheme {
    // Your app UI here

    GraphynTheme(branding = myBranding, darkTheme = darkTheme) {
        GraphynEditorShell(...)
    }
}