Theming

Themes are used to custom the colours and default fonts of the Spreadsheet. You can also have customise colours of charts, embeds using a theme

Theme type

Themes have the following properties. You can inject a theme to SheetGrid component using the theme prop.

export type SpreadsheetTheme = {
  name: string;
  primaryFontFamily: string;
  themeColors: Record<ThemeColors, string>;
};

export type ThemeColors =
  | "text"
  | "background"
  | "accent1"
  | "accent2"
  | "accent3"
  | "accent4"
  | "accent5"
  | "accent6"
  | "hyperlink";

Dark/Light mode

Theme also automatically support light or dark mode if used with useSpreadsheetTheme hook.

import React, { useState } from "react"
import { 
  CanvasGrid, 
  SpreadsheetProvider,
  SpreadsheetTheme, 
  useSpreadsheetTheme,
  ColorMode
} from "@rowsncolumns/spreadsheet"

const MySpreadsheet = () => {
  const [colorMode, onChangeColorMode] = ueState<ColorMode>('dark');
  const {
    isDarkMode,
    // To support dark mode, customize colors of headers and cell text foreground and background color
    ...spreadsheetColors
  } = useSpreadsheetTheme({
    colorMode
  });
  
  return (
    <>
      <button onClick={() => onChangeColorMode('light')}>Switch color mode</button>
      <CanvasGrid
        {...spreadsheetColors}
        theme={spreadsheetTheme}
      />
    </>
  )
}

const App = () => {
  <SpreadsheetProvider>
    <MySpreadsheet />
  </SpreadsheetProvider>
}

Customising dark and light modes using CSS Variables

Spreadsheet 2 uses Tailwind for CSS styling of DOM components. The following are the CSS variables support by Spreadsheet 2.

.rnc-dark class is used for dark mode.

:root {
 --rnc-background: 0 0% 100%;
 --rnc-foreground: 222.2 47.4% 11.2%;

 --rnc-muted: 0 0% 90.9%;
 --rnc-muted-foreground: 215.4 16.3% 46.9%;

 --rnc-popover: 0 0% 100%;
 --rnc-popover-foreground: 222.2 47.4% 11.2%;

 --rnc-card: 0 0% 100%;
 --rnc-card-foreground: 222.2 47.4% 11.2%;

 --rnc-border: 0 0% 78.0%;
 --rnc-input: 0 0% 82%;

 --rnc-primary: 211 100%  43.2%;
 --rnc-primary-foreground: 210 40% 98%;

 --rnc-secondary: 210 40% 96.1%;
 --rnc-secondary-foreground: 222.2 47.4% 11.2%;

 --rnc-accent: 0 0% 90.9%;
 --rnc-accent-foreground: 222.2 47.4% 11.2%;

 --rnc-destructive: 0 100% 50%;
 --rnc-destructive-foreground: 210 40% 98%;

 --rnc-warning: 24 100% 46.5%;
 --rnc-warning-foreground: 210 40% 98%;

 --rnc-ring: 215 20.2% 65.1%;

 --rnc-radius: 0.5rem;

 /* Scrollbar */
 --rnc-scrollbar-border: 0 0% 85.8%;
 --rnc-scrollbar-background: 0 0% 97.3%;
 --rnc-scrollbar-thumb: 0 0% 78.0%;
 
}
 
.rnc-dark {
 --rnc-background: 224 71% 4%;
 --rnc-foreground: 213 31% 91%;

 --rnc-muted: 0 0% 17.9%;
 --rnc-muted-foreground: 215.4 16.3% 56.9%;

 --rnc-popover: 224 71% 4%;
 --rnc-popover-foreground: 215 20.2% 65.1%;

 --rnc-card: 224 71% 4%;
 --rnc-card-foreground: 213 31% 91%;

 --rnc-border: 0 0% 31.2%;
 --rnc-input: 216 34% 17%;

 --rnc-primary: 210 40% 98%;
 --rnc-primary-foreground: 222.2 47.4% 1.2%;

 --rnc-secondary: 222.2 47.4% 11.2%;
 --rnc-secondary-foreground: 210 40% 98%;

 --rnc-accent: 216 34% 17%;
 --rnc-accent-foreground: 210 40% 98%;

 --rnc-destructive: 0 100% 50%;
 --rnc-destructive-foreground: 210 40% 98%;

 --rnc-warning: 24 100% 58.5%;
 --rnc-warning-foreground: 210 40% 98%;

 --rnc-ring: 216 34% 17%;

 --rnc-radius: 0.5rem;

 /* Scrollbar */
 --rnc-scrollbar-border: 0 0% 24.3%;
 --rnc-scrollbar-background: 0 0% 11.0%;
 --rnc-scrollbar-thumb: 0 0% 31.2%;
}

Last updated