Static CMS comes with two default themes (light
and dark
), and you can add your own custom themes as well.
Static CMS exposes a window.CMS
global object that you can use to register custom themes via registerTheme
. The same object is also the default export if you import Static CMS as an npm module.
Register Theme
Register a custom theme.
theme:
themes:
- name: Custom Dark
text:
primary: '#fff'
secondary: 'rgba(255, 255, 255, 0.7)'
disabled: 'rgba(255, 255, 255, 0.5)'
background:
main: '#1e293b'
light: '#2c3b55'
dark: '#0f172a'
divider: '#2c3b55'
scrollbar:
main: '#1e293b'
light: '#2c3b55'
button:
disabled: '#334155'
primary:
main: '#339ef4'
light: '#6bb9f7'
dark: '#0c82e0'
contrastColor: '#ffffff'
error:
main: '#f44336'
light: '#e57373'
dark: '#d32f2f'
contrastColor: '#ffffff'
warning:
main: '#ffa726'
light: '#ffb74d'
dark: '#f57c00'
contrastColor: '#ffffff'
info:
main: '#29b6f6'
light: '#4fc3f7'
dark: '#0288d1'
contrastColor: '#ffffff'
success:
main: '#66bb6a'
light: '#81c784'
dark: '#388e3c'
contrastColor: '#ffffff'
codemirror:
theme: dark
const theme = {
name: 'Custom Dark',
text: {
primary: '#fff',
secondary: 'rgba(255, 255, 255, 0.7)',
disabled: 'rgba(255, 255, 255, 0.5)',
},
background: {
main: '#1e293b',
light: '#2c3b55',
dark: '#0f172a',
divider: '#2c3b55',
},
scrollbar: {
main: '#1e293b',
light: '#2c3b55',
},
button: {
disabled: '#334155',
},
primary: {
main: '#339ef4',
light: '#6bb9f7',
dark: '#0c82e0',
contrastColor: '#ffffff',
},
error: {
main: '#f44336',
light: '#e57373',
dark: '#d32f2f',
contrastColor: '#ffffff',
},
warning: {
main: '#ffa726',
light: '#ffb74d',
dark: '#f57c00',
contrastColor: '#ffffff',
},
info: {
main: '#29b6f6',
light: '#4fc3f7',
dark: '#0288d1',
contrastColor: '#ffffff',
},
success: {
main: '#66bb6a',
light: '#81c784',
dark: '#388e3c',
contrastColor: '#ffffff',
},
codemirror: {
theme: 'dark',
},
};
// Using global window object
CMS.registerTheme(theme);
// Using npm module import
import CMS from '@staticcms/core';
CMS.registerTheme(theme);
Extend Built-in Themes
Extend either the light
or dark
themes.
theme:
themes:
- name: Red Orange
extends: dark
primary:
main: '#ff4500'
// Using global window object
CMS.registerTheme({
name: 'Red Orange',
extends: 'dark',
primary: {
main: '#ff4500',
},
});
// Using npm module import
import CMS from '@staticcms/core';
CMS.registerTheme({
name: 'Red Orange',
extends: 'dark',
primary: {
main: '#ff4500',
},
});
Set Default Theme
By default light
is the main theme (or dark
if the user’s system is set to dark mode). default_theme
allows you to change that.
theme:
default_theme: false
themes:
# Can also be registered via javascript
- name: Red Orange
extends: dark
primary:
main: '#ff4500'
Hide Built-in themes
By default both a light
and dark
them are available. However, if you provide at least one custom theme, include_built_in_themes
allows you to disable the built-in themes.
If default_theme
is not provided, then the first custom theme is used (when include_built_in_themes
is false
).
theme:
include_built_in_themes: false
themes:
# Can also be registered via javascript
- name: Red Orange
extends: dark
primary:
main: '#ff4500'
useTheme Hook
The useTheme
hook can be utilized in customize widgets and previews to utilize values from the theme.
Example Preview Card
const PostPreviewCard = ({ entry, widgetFor }) => {
const theme = useTheme();
return h(
'div',
{ style: { width: '100%' } },
widgetFor('image'),
h(
'div',
{ style: { padding: '16px', width: '100%' } },
h(
'div',
{
style: {
display: 'flex',
width: '100%',
justifyContent: 'space-between',
alignItems: 'start',
},
},
h(
'div',
{
style: {
display: 'flex',
flexDirection: 'column',
alignItems: 'baseline',
gap: '8px',
},
},
h('strong', { style: { fontSize: '24px' } }, entry.data.title),
h('span', { style: { fontSize: '16px' } }, entry.data.date),
),
h(
'div',
{
style: {
backgroundColor: entry.data.draft === true
? theme.info.main
: theme.success.main,
color: 'white',
border: 'none',
padding: '4px 8px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
},
},
entry.data.draft === true ? 'Draft' : 'Published',
),
),
),
);
};
CMS.registerPreviewCard('posts', PostPreviewCard, () => 240);
import CMS from '@staticcms/core';
const PostPreviewCard = ({ entry, widgetFor }) => {
const theme = useTheme();
return (
<div style={{ width: '100%' }}>
{widgetFor('image')}
<div style={{ padding: '16px', width: '100%' }}>
<div
style={{
display: 'flex',
width: '100%',
justifyContent: 'space-between',
alignItems: 'start',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'baseline',
gap: '8px',
}}
>
<strong style={{ fontSize: '24px' }}>{entry.data.title}</strong>
<span style={{ fontSize: '16px' }}>{entry.data.date}</span>
</div>
<div
style={{
backgroundColor: entry.data.draft === true
? theme.info.main
: theme.success.main,
color: 'white',
border: 'none',
padding: '4px 8px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
}}
>
{entry.data.draft === true ? 'Draft' : 'Published'}
</div>
</div>
</div>
</div>
);
};
CMS.registerPreviewCard('posts', PostPreviewCard, () => 240);
import CMS, { useTheme } from '@staticcms/core';
import type { TemplatePreviewCardProps } from '@staticcms/core';
/**
* The type for 'entry.data'
*/
interface Post {
image: string;
title: string;
date: string;
body: string;
draft: boolean;
}
const PostPreviewCard = ({ entry, widgetFor }: TemplatePreviewCardProps<Post>) => {
const theme = useTheme();
return (
<div style={{ width: '100%' }}>
{widgetFor('image')}
<div style={{ padding: '16px', width: '100%' }}>
<div
style={{
display: 'flex',
width: '100%',
justifyContent: 'space-between',
alignItems: 'start',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'baseline',
gap: '8px',
}}
>
<strong style={{ fontSize: '24px' }}>{entry.data?.title}</strong>
<span style={{ fontSize: '16px' }}>{entry.data?.date}</span>
</div>
<div
style={{
backgroundColor: entry.data?.draft === true
? theme.info.main
: theme.success.main,
color: 'white',
border: 'none',
padding: '4px 8px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
}}
>
{entry.data?.draft === true ? 'Draft' : 'Published'}
</div>
</div>
</div>
</div>
);
};
CMS.registerPreviewCard('posts', PostPreviewCard, () => 240);
Theme
The react component that renders the control. It receives the following props:
Param 17437_74937a-34> |
Type 17437_5d1c7c-a0> |
Description 17437_d68e64-6a> |
---|---|---|
name 17437_3171c3-76> |
string 17437_c27fdf-3b> |
The name of the theme 17437_f9eea0-d5> |
extends 17437_a0fce8-3f> |
string 17437_5259eb-f8> |
Optional if all other theme options are provided. |
common 17437_002438-4c> |
object 17437_5e3e17-23> |
Optional if |
text 17437_b8cf42-fa> |
object 17437_2d9a2a-55> |
Optional if |
background 17437_564608-62> |
object 17437_31cd44-e3> |
Optional if |
scrollbar 17437_774723-b4> |
object 17437_3266bf-44> |
Optional if |
primary 17437_bed508-f9> |
object 17437_f5a2a0-4f> |
Optional if |
error 17437_f89739-ef> |
object 17437_518173-e3> |
Optional if |
warning 17437_c74050-79> |
object 17437_55bd76-04> |
Optional if |
info 17437_b45b19-da> |
object 17437_822366-71> |
Optional if |
success 17437_cb0bb3-a3> |
object 17437_8d4e98-6e> |
Optional if |
codemirror 17437_fc7743-63> |
object 17437_1318d0-8a> |
Optional if |
Common Colors
common
allows you to change the common colors.
Param 17437_533b4a-cc> |
Type 17437_e29cc2-85> |
Description 17437_40f6b8-25> |
---|---|---|
gray 17437_59d608-76> |
string 17437_148bcd-e6> |
Optional if |
Text Colors
text
allows you to change the text colors.
Param 17437_61b931-27> |
Type 17437_7b122d-c9> |
Description 17437_569347-68> |
---|---|---|
primary 17437_2e6761-09> |
string 17437_c08bc8-72> |
Optional if |
secondary 17437_923224-d6> |
string 17437_2029ef-35> |
Optional if |
disabled 17437_5c8040-55> |
string 17437_628540-12> |
Optional if |
Background Colors
background
allows you to change the background colors.
Param 17437_f9e7b3-f1> |
Type 17437_42a6c7-7c> |
Description 17437_2cd84c-a3> |
---|---|---|
main 17437_6da85c-28> |
string 17437_b93dea-c9> |
Optional if |
light 17437_c2a74f-bd> |
string 17437_d2368f-1d> |
Optional if |
dark 17437_97ee1d-f2> |
string 17437_476e40-b0> |
Optional if |
divider 17437_1b1ea5-c6> |
string 17437_cfc95e-55> |
Optional if |
Scrollbar Colors
scrollbar
allows you to change the scrollbar colors.
Param 17437_9270aa-88> |
Type 17437_a2c9f6-63> |
Description 17437_3fd8b3-08> |
---|---|---|
main 17437_ef4d17-9e> |
string 17437_371ec0-fa> |
Optional if |
light 17437_02a40a-bd> |
string 17437_435b82-10> |
Optional if |
Theme Color
primary
, error
, warning
, info
and success
are theme colors and share the same options.
Param 17437_11d5a9-0e> |
Type 17437_34bc8a-fc> |
Description 17437_b5d104-79> |
---|---|---|
main 17437_f7bb72-7c> |
string 17437_e3b349-74> |
Optional if |
light 17437_0b6db7-77> |
string 17437_859549-ca> |
Optional if |
dark 17437_3b1fc5-90> |
string 17437_8c4297-9b> |
Optional if |
contrastColor 17437_ba306f-09> |
string 17437_a70b88-e4> |
Optional if |
Codemirror
codemirror
allows you to change the theme settings for Codemirror instances (used by the code and markdown widgets).
Param | Type | Description |
---|---|---|
main | string | Optional if extends is provided. |
light | string | Optional if extends is provided.Will be calculated from main if not provided. |