Theming
FlowX.AI UI Toolkit provides a comprehensive theming system that allows you to customize the appearance of all components to match your brand identity. You can override colors, typography, spacing, and component-specific styles without modifying the toolkit source code.
Theming approach
The toolkit uses CSS custom properties (variables) for theming, making it easy to customize without deep CSS knowledge. You can:
Override global theme variables
Customize individual components
Create multiple themes (light/dark mode)
Adapt to existing design systems
Theme structure
The theme is organized into logical sections:
Colors: Primary, secondary, status colors
Typography: Font families, sizes, weights
Spacing: Margins, padding, gaps
Borders: Radius, width, colors
Shadows: Elevation and depth
Components: Component-specific styling
Basic customization
Override theme variables in your global stylesheet.
Create or update src/styles.scss: // Import the base FlowX styles first
@import '@flowx/angular-ui-toolkit/styles/main' ;
// Override theme variables
:root {
// Brand colors
--flx-color-primary : #0066cc ;
--flx-color-primary-hover : #0052a3 ;
--flx-color-primary-active : #003d7a ;
--flx-color-secondary : #6c757d ;
// Typography
--flx-font-family : 'Inter' , -apple-system , BlinkMacSystemFont, 'Segoe UI' , sans-serif ;
--flx-font-size-base : 16 px ;
--flx-font-weight-normal : 400 ;
--flx-font-weight-medium : 500 ;
--flx-font-weight-bold : 700 ;
// Spacing
--flx-spacing-xs : 4 px ;
--flx-spacing-sm : 8 px ;
--flx-spacing-md : 16 px ;
--flx-spacing-lg : 24 px ;
--flx-spacing-xl : 32 px ;
// Border radius
--flx-border-radius-sm : 4 px ;
--flx-border-radius-md : 8 px ;
--flx-border-radius-lg : 12 px ;
}
Create or update src/index.css: /* Import the base FlowX styles first */
@import '@flowx/react-ui-toolkit/dist/styles.css' ;
/* Override theme variables */
:root {
/* Brand colors */
--flx-color-primary : #0066cc ;
--flx-color-primary-hover : #0052a3 ;
--flx-color-primary-active : #003d7a ;
--flx-color-secondary : #6c757d ;
/* Typography */
--flx-font-family : 'Inter' , -apple-system , BlinkMacSystemFont, 'Segoe UI' , sans-serif ;
--flx-font-size-base : 16 px ;
--flx-font-weight-normal : 400 ;
--flx-font-weight-medium : 500 ;
--flx-font-weight-bold : 700 ;
/* Spacing */
--flx-spacing-xs : 4 px ;
--flx-spacing-sm : 8 px ;
--flx-spacing-md : 16 px ;
--flx-spacing-lg : 24 px ;
--flx-spacing-xl : 32 px ;
/* Border radius */
--flx-border-radius-sm : 4 px ;
--flx-border-radius-md : 8 px ;
--flx-border-radius-lg : 12 px ;
}
Color system
The toolkit provides a comprehensive color palette with semantic naming.
Primary colors
:root {
/* Primary brand color */
--flx-color-primary : #0066cc ;
--flx-color-primary-light : #3385d6 ;
--flx-color-primary-dark : #004d99 ;
--flx-color-primary-hover : #0052a3 ;
--flx-color-primary-active : #003d7a ;
/* Text on primary background */
--flx-color-primary-contrast : #ffffff ;
}
Status colors
:root {
/* Success */
--flx-color-success : #28a745 ;
--flx-color-success-light : #d4edda ;
--flx-color-success-dark : #1e7e34 ;
/* Warning */
--flx-color-warning : #ffc107 ;
--flx-color-warning-light : #fff3cd ;
--flx-color-warning-dark : #d39e00 ;
/* Error */
--flx-color-error : #dc3545 ;
--flx-color-error-light : #f8d7da ;
--flx-color-error-dark : #bd2130 ;
/* Info */
--flx-color-info : #17a2b8 ;
--flx-color-info-light : #d1ecf1 ;
--flx-color-info-dark : #117a8b ;
}
Neutral colors
:root {
/* Backgrounds */
--flx-color-background : #ffffff ;
--flx-color-background-alt : #f8f9fa ;
--flx-color-background-disabled : #e9ecef ;
/* Borders */
--flx-color-border : #dee2e6 ;
--flx-color-border-light : #e9ecef ;
--flx-color-border-dark : #adb5bd ;
/* Text */
--flx-color-text : #212529 ;
--flx-color-text-secondary : #6c757d ;
--flx-color-text-disabled : #adb5bd ;
--flx-color-text-inverse : #ffffff ;
}
Typography
Customize fonts, sizes, and text styles.
Font families
:root {
--flx-font-family : 'Inter' , -apple-system , BlinkMacSystemFont, 'Segoe UI' , sans-serif ;
--flx-font-family-monospace : 'Fira Code' , 'Courier New' , monospace ;
}
Remember to include font files in your application if using custom fonts. Add @font-face declarations or link to a font service like Google Fonts.
Font sizes
:root {
--flx-font-size-xs : 12 px ;
--flx-font-size-sm : 14 px ;
--flx-font-size-base : 16 px ;
--flx-font-size-lg : 18 px ;
--flx-font-size-xl : 20 px ;
--flx-font-size-2xl : 24 px ;
--flx-font-size-3xl : 30 px ;
--flx-font-size-4xl : 36 px ;
}
Font weights
:root {
--flx-font-weight-light : 300 ;
--flx-font-weight-normal : 400 ;
--flx-font-weight-medium : 500 ;
--flx-font-weight-semibold : 600 ;
--flx-font-weight-bold : 700 ;
}
Line heights
:root {
--flx-line-height-tight : 1.25 ;
--flx-line-height-normal : 1.5 ;
--flx-line-height-relaxed : 1.75 ;
}
Component-specific theming
Customize individual components with targeted variables.
:root {
--flx-button-padding-y : 10 px ;
--flx-button-padding-x : 20 px ;
--flx-button-border-radius : 6 px ;
--flx-button-font-weight : 500 ;
--flx-button-transition : all 0.2 s ease-in-out ;
/* Button sizes */
--flx-button-padding-sm : 6 px 12 px ;
--flx-button-padding-md : 10 px 20 px ;
--flx-button-padding-lg : 14 px 28 px ;
}
:root {
--flx-input-padding-y : 10 px ;
--flx-input-padding-x : 12 px ;
--flx-input-border-width : 1 px ;
--flx-input-border-color : var ( --flx-color-border );
--flx-input-border-radius : 6 px ;
--flx-input-focus-border-color : var ( --flx-color-primary );
--flx-input-focus-shadow : 0 0 0 3 px rgba ( 0 , 102 , 204 , 0.1 );
}
Cards
:root {
--flx-card-padding : 24 px ;
--flx-card-border-radius : 12 px ;
--flx-card-border-color : var ( --flx-color-border );
--flx-card-shadow : 0 2 px 8 px rgba ( 0 , 0 , 0 , 0.1 );
--flx-card-background : var ( --flx-color-background );
}
Dark mode
Implement dark mode by overriding variables within a dark theme class.
/* Define dark theme colors */
[ data-theme = "dark" ] {
/* Backgrounds */
--flx-color-background : #1a1a1a ;
--flx-color-background-alt : #2d2d2d ;
--flx-color-background-disabled : #404040 ;
/* Borders */
--flx-color-border : #404040 ;
--flx-color-border-light : #333333 ;
--flx-color-border-dark : #555555 ;
/* Text */
--flx-color-text : #e9e9e9 ;
--flx-color-text-secondary : #a0a0a0 ;
--flx-color-text-disabled : #666666 ;
/* Adjust component shadows for dark mode */
--flx-card-shadow : 0 2 px 8 px rgba ( 0 , 0 , 0 , 0.3 );
--flx-input-focus-shadow : 0 0 0 3 px rgba ( 0 , 102 , 204 , 0.2 );
}
Toggle dark mode by adding/removing the data attribute:
import { Injectable } from '@angular/core' ;
@ Injectable ({ providedIn: 'root' })
export class ThemeService {
private isDark = false ;
toggleTheme () {
this . isDark = ! this . isDark ;
document . documentElement . setAttribute (
'data-theme' ,
this . isDark ? 'dark' : 'light'
);
}
setTheme ( theme : 'light' | 'dark' ) {
this . isDark = theme === 'dark' ;
document . documentElement . setAttribute ( 'data-theme' , theme );
}
}
import { useState , useEffect } from 'react' ;
export function useTheme () {
const [ isDark , setIsDark ] = useState ( false );
useEffect (() => {
document . documentElement . setAttribute (
'data-theme' ,
isDark ? 'dark' : 'light'
);
}, [ isDark ]);
const toggleTheme = () => setIsDark ( ! isDark );
const setTheme = ( theme : 'light' | 'dark' ) => setIsDark ( theme === 'dark' );
return { isDark , toggleTheme , setTheme };
}
Advanced customization
Component class overrides
For complex styling needs, target component CSS classes directly:
// Override button styles
.flx-button {
& .flx-button--primary {
background : linear-gradient ( 135 deg , #667eea 0 % , #764ba2 100 % );
border : none ;
& :hover {
transform : translateY ( -2 px );
box-shadow : 0 4 px 12 px rgba ( 102 , 126 , 234 , 0.4 );
}
}
}
// Override input styles
.flx-input {
& __field {
border : 2 px solid transparent ;
background : var ( --flx-color-background-alt );
& :focus {
border-color : var ( --flx-color-primary );
background : var ( --flx-color-background );
}
}
}
SCSS mixins
If using SCSS, leverage mixins for consistent theming:
// Define theme mixin
@mixin theme-colors ( $primary , $secondary ) {
--flx-color-primary : #{$primary} ;
--flx-color-primary-hover : #{ darken ($primary, 10 % )} ;
--flx-color-primary-active : #{ darken ($primary, 15 % )} ;
--flx-color-secondary : #{$secondary} ;
}
// Apply to different brands
.brand-corporate {
@include theme-colors ( #0066cc , #6c757d );
}
.brand-creative {
@include theme-colors ( #ff6b6b , #4ecdc4 );
}
Theme configuration via TypeScript
For programmatic theme control, use the theme configuration API:
import { FlowxModule } from '@flowx/angular-ui-toolkit' ;
const themeConfig = {
colors: {
primary: '#0066cc' ,
secondary: '#6c757d' ,
success: '#28a745' ,
warning: '#ffc107' ,
error: '#dc3545'
},
typography: {
fontFamily: 'Inter, sans-serif' ,
fontSize: '16px'
},
spacing: {
unit: 8 // Base spacing unit in pixels
}
};
@ NgModule ({
imports: [
FlowxModule . forRoot ({
// ... other config
theme: themeConfig
})
]
})
export class AppModule { }
import { FlowxProvider } from '@flowx/react-ui-toolkit' ;
const themeConfig = {
colors: {
primary: '#0066cc' ,
secondary: '#6c757d' ,
success: '#28a745' ,
warning: '#ffc107' ,
error: '#dc3545'
},
typography: {
fontFamily: 'Inter, sans-serif' ,
fontSize: '16px'
},
spacing: {
unit: 8 // Base spacing unit in pixels
}
};
function App () {
return (
< FlowxProvider
config = { { /* ... */ } }
theme = { themeConfig }
>
{ /* ... */ }
</ FlowxProvider >
);
}
Complete theme variables reference
For a complete list of all available theme variables, see the Storybook documentation for your toolkit version. Each version’s Storybook includes a “Theme” section with all customizable variables.
Testing your theme
Visual inspection
Review all components in your application to ensure consistent styling.
Use Storybook
Test your theme variables in Storybook by temporarily applying them to see immediate results.
Check contrast ratios
Ensure text colors meet WCAG accessibility standards (4.5:1 for normal text, 3:1 for large text).
Test dark mode
If implementing dark mode, verify all components work in both themes.
Always test theme changes across different browsers and devices. Some CSS custom properties may have limited support in older browsers.
Next steps
Best practices Learn production-ready patterns for building robust applications