Skip to main content

Theming

Customize the appearance of DialStack components using CSS variables, theme presets, and layout variants.

Quick Start

const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: {
theme: 'light',
variables: {
colorPrimary: '#6772E5',
fontFamily: 'Inter, system-ui, sans-serif',
borderRadius: '8px',
},
},
});

Theme Variants

Choose a base theme:

ThemeDescription
'light'Light background with dark text
'dark'Dark background with light text
'auto'Follows system preference (prefers-color-scheme)
// Follow system preference
initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: {
theme: 'auto',
},
});

Layout Variants

Adjust component density with layoutVariant:

VariantDescription
'compact'Minimal padding, dense layout
'default'Standard spacing
'comfortable'Extra padding, breathing room
<CallLogs layoutVariant="compact" />
<Voicemails layoutVariant="comfortable" />

CSS Variables

Customize components using CSS variables in the variables option:

Colors

variables: {
// Primary brand color
colorPrimary: '#6772E5',
colorPrimaryHover: '#5469D4',

// Base colors
colorBackground: '#ffffff',
colorText: '#1a1a1a',
colorTextSecondary: '#6b7280',

// Semantic colors
colorDanger: '#e5484d',
colorSuccess: '#30a46c',
colorWarning: '#f5a623',

// Surface colors
colorSurfaceSubtle: '#f9fafb',
colorBorder: '#e5e7eb',
colorBorderSubtle: '#f3f4f6',
}

Typography

variables: {
fontFamily: 'Inter, system-ui, sans-serif',
fontSizeBase: '14px',
fontSizeSmall: '12px',
fontSizeLarge: '16px',
fontSizeXLarge: '18px',
fontWeightNormal: '400',
fontWeightMedium: '500',
fontWeightBold: '600',
lineHeight: '1.5',
}

Spacing

variables: {
spacingUnit: '8px',
spacingXs: '4px',
spacingSm: '8px',
spacingMd: '16px',
spacingLg: '24px',
spacingXl: '32px',
}

Border & Effects

variables: {
borderRadius: '6px',
borderRadiusSmall: '4px',
borderRadiusLarge: '12px',
transitionDuration: '150ms',
focusRingColor: 'rgba(59, 130, 246, 0.5)',
focusRingWidth: '2px',
}

Component-Specific

variables: {
// Icons
iconSize: '20px',
iconSizeSmall: '16px',

// Audio player
playerButtonSize: '40px',
playerProgressHeight: '4px',
playerProgressHandleSize: '12px',

// Indicators
unreadIndicatorSize: '8px',
spinnerSize: '24px',

// Time display
timeDisplayWidth: '48px',
}

Complete Variables Reference

VariableDefault (Light)Description
Colors
colorPrimary#2563ebPrimary brand color
colorPrimaryHover#1d4ed8Primary color on hover
colorBackground#ffffffBackground color
colorText#111827Primary text color
colorTextSecondary#6b7280Secondary text color
colorDanger#dc2626Error/danger color
colorSuccess#16a34aSuccess color
colorWarning#d97706Warning color
colorSurfaceSubtle#f9fafbSubtle surface color
colorBorder#e5e7ebBorder color
colorBorderSubtle#f3f4f6Subtle border color
Typography
fontFamilysystem-ui, sans-serifFont family
fontSizeBase14pxBase font size
fontSizeSmall12pxSmall text
fontSizeLarge16pxLarge text
fontSizeXLarge18pxExtra large text
fontWeightNormal400Normal weight
fontWeightMedium500Medium weight
fontWeightBold600Bold weight
lineHeight1.5Line height
Spacing
spacingUnit8pxBase spacing unit
spacingXs4pxExtra small
spacingSm8pxSmall
spacingMd16pxMedium
spacingLg24pxLarge
spacingXl32pxExtra large
Border
borderRadius6pxDefault radius
borderRadiusSmall4pxSmall radius
borderRadiusLarge12pxLarge radius
Effects
transitionDuration150msAnimation duration
focusRingColorrgba(59, 130, 246, 0.5)Focus outline color
focusRingWidth2pxFocus outline width

CSS Class Overrides

Apply custom CSS classes using the classes prop:

CallLogs Classes

<CallLogs
classes={{
base: 'rounded-lg shadow-md',
loading: 'animate-pulse',
error: 'border-red-500 bg-red-50',
empty: 'text-gray-400 italic',
table: 'min-w-full divide-y',
header: 'bg-gray-50 font-semibold',
row: 'hover:bg-gray-100 cursor-pointer',
rowInbound: 'border-l-4 border-green-500',
rowOutbound: 'border-l-4 border-blue-500',
pagination: 'flex justify-between mt-4',
}}
/>

Voicemails Classes

<Voicemails
userId="user_123"
classes={{
base: 'bg-white rounded-lg',
loading: 'opacity-50',
error: 'text-red-600',
empty: 'text-center py-8',
list: 'divide-y divide-gray-200',
item: 'p-4 transition-colors',
itemExpanded: 'bg-blue-50',
itemUnread: 'border-l-4 border-blue-500 bg-blue-50/50',
player: 'bg-gray-100 rounded p-2',
actions: 'flex gap-2 mt-2',
}}
/>

Updating Theme at Runtime

Use the update() method to change appearance after initialization:

const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: { theme: 'light' },
});

// Later: switch to dark mode
dialstack.update({
appearance: {
theme: 'dark',
variables: {
colorPrimary: '#8B5CF6',
},
},
});

Custom Icons

Replace default icons with custom SVG:

<CallLogs
icons={{
inbound: '<svg>...</svg>',
outbound: '<svg>...</svg>',
play: '<svg>...</svg>',
pause: '<svg>...</svg>',
phone: '<svg>...</svg>',
trash: '<svg>...</svg>',
chevronLeft: '<svg>...</svg>',
chevronRight: '<svg>...</svg>',
chevronDown: '<svg>...</svg>',
spinner: '<svg>...</svg>',
}}
/>

Framework Integration

Tailwind CSS

<CallLogs
classes={{
base: 'bg-white rounded-xl shadow-lg overflow-hidden',
table: 'min-w-full divide-y divide-gray-200',
header: 'px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider',
row: 'px-6 py-4 whitespace-nowrap hover:bg-gray-50 transition-colors',
pagination: 'px-6 py-3 flex items-center justify-between bg-gray-50',
}}
/>

Bootstrap

<CallLogs
classes={{
base: 'card',
table: 'table table-hover mb-0',
header: 'bg-light',
row: 'cursor-pointer',
pagination: 'd-flex justify-content-between p-3',
}}
/>

Complete Example

import { initialize, DialstackComponentsProvider, CallLogs, Voicemails } from '@dialstack/sdk';

const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: {
theme: 'auto',
variables: {
// Brand colors
colorPrimary: '#6366F1',
colorPrimaryHover: '#4F46E5',

// Typography
fontFamily: '"Inter", -apple-system, sans-serif',
fontSizeBase: '14px',

// Spacing
spacingUnit: '8px',
borderRadius: '8px',

// Focus states
focusRingColor: 'rgba(99, 102, 241, 0.5)',
focusRingWidth: '3px',
},
},
});

function App() {
return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={secret}>
<div className="max-w-4xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Voice Dashboard</h1>

<section className="mb-8">
<h2 className="text-xl mb-4">Recent Calls</h2>
<CallLogs
layoutVariant="comfortable"
classes={{
base: 'bg-white rounded-xl shadow-lg',
row: 'cursor-pointer hover:bg-indigo-50',
}}
/>
</section>

<section>
<h2 className="text-xl mb-4">Voicemails</h2>
<Voicemails
userId="user_123"
layoutVariant="comfortable"
classes={{
base: 'bg-white rounded-xl shadow-lg',
itemUnread: 'border-l-4 border-indigo-500',
}}
/>
</section>
</div>
</DialstackComponentsProvider>
);
}

Next Steps

  • i18n - Internationalization
  • CallLogs - CallLogs component reference
  • Voicemails - Voicemails component reference