Theme API

Theme API

You can change the look and feel of the dashboard by applying the theme properties to your Dashboard component.

The styling is processed at runtime, so you can optionally define customer branding based on a call to your API.

How to enable the API

It's as simple as using the theme prop on the Component and defining the styles for your components.

import Vizzly from '@vizzly/dashboard';
 
const MyAppDashboard = () =>
  <Vizzly.Dashboard
    theme={{
      ...
    }}
  />
 

Properties

Apart from the detail and rowLimit props, the theme properties aren't mandatory. If you don't specify a value, default values are used.

CSSProperties allows typing for styles using CSSType. You're able to use type assertion or module augmentation to add properties or an index signature of your own.

For examples and more information, visit: https://github.com/frenic/csstype (opens in a new tab)

Interface

export namespace VizzlyTheming {
  export type Base = {
    detail: "minimal" | "verbose";
    rowLimit: number;
    baseFont?: FontStyle;
    colors?: CSSProperties["color"][];
    buttons?: Buttons;
    panels?: Panel;
    forms?: Form;
    modals?: Modal;
    lists?: List;
    tabs?: Tabs;
    alerts?: Alerts;
    charts?: Charts;
    dropdowns?: Dropdown;
    popoverMenu?: PopoverMenu;
  };
 
  export interface Buttons {
    primary?: ButtonType;
    secondary?: ButtonType;
    area?: AreaButton;
    grid?: GridButtons;
  }
 
  export interface ButtonType extends ButtonState {
    padding?: CSSProperties["padding"];
    fontWeight?: CSSProperties["fontWeight"];
    boxShadow?: CSSProperties["boxShadow"];
    borderRadius?: CSSProperties["borderRadius"];
    fontSize?: CSSProperties["fontSize"];
    height?: CSSProperties["height"];
    "&:hover"?: ButtonState;
  }
 
  export type ButtonSize = {
    fontWeight?: CSSProperties["fontWeight"];
    padding?: CSSProperties["padding"];
    fontSize?: CSSProperties["fontSize"];
    height?: CSSProperties["height"];
  };
 
  export type ButtonState = {
    background?: CSSProperties["background"];
    color?: CSSProperties["color"];
    border?: CSSProperties["border"];
    borderRadius?: CSSProperties["borderRadius"];
  };
 
  export type AreaButton = {
    background?: CSSProperties["background"];
    border?: CSSProperties["border"];
    boxShadow?: CSSProperties["boxShadow"];
    borderRadius?: CSSProperties["borderRadius"];
    color?: CSSProperties["color"];
    "&:hover"?: {
      background?: CSSProperties["background"];
      border?: CSSProperties["border"];
      boxShadow?: CSSProperties["boxShadow"];
      color?: CSSProperties["color"];
    };
    medium?: AreaButtonTypes;
    large?: AreaButtonTypes;
  };
 
  export type AreaButtonTypes = {
    fontWeight?: CSSProperties["fontWeight"];
    fontSize?: CSSProperties["fontSize"];
  };
 
  export type GridButtons = {
    selected?: GridButton;
    unselected?: GridButton;
  };
 
  export type GridButton = {
    background?: CSSProperties["background"];
    border?: CSSProperties["border"];
    boxShadow?: CSSProperties["boxShadow"];
    borderRadius?: CSSProperties["borderRadius"];
    fontWeight?: CSSProperties["fontWeight"];
    fontSize?: CSSProperties["fontSize"];
    color?: CSSProperties["color"];
    "&:hover"?: {
      background?: CSSProperties["background"];
      border?: CSSProperties["border"];
      boxShadow?: CSSProperties["boxShadow"];
      color?: CSSProperties["color"];
    };
  };
 
  export type Panel = {
    border?: CSSProperties["border"];
    background?: CSSProperties["background"];
    boxShadow?: CSSProperties["boxShadow"];
    borderRadius?: CSSProperties["borderRadius"];
    padding?: CSSProperties["padding"];
  };
 
  export type Form = {
    label?: Label;
    input?: Input;
    select?: Select;
  };
 
  export interface Label extends FontStyle {}
 
  export interface Input extends InputStyle, InputState {
    sm?: InputStyle;
    "&:focus"?: InputState;
    "&:hover"?: InputState;
    "&:focus:hover"?: InputState;
  }
 
  export type InputStyle = {
    padding?: CSSProperties["padding"];
    fontSize?: CSSProperties["fontSize"];
    borderRadius?: CSSProperties["borderRadius"];
    fontWeight?: CSSProperties["fontWeight"];
    color?: CSSProperties["color"];
  };
 
  export interface Select extends Input {
    indicatorColor?: CSSProperties["color"];
  }
 
  export type InputState = {
    border?: CSSProperties["border"];
    boxShadow?: CSSProperties["boxShadow"];
    background?: CSSProperties["background"];
  };
 
  export type Modal = {
    overlay?: Overlay;
    base?: ModalBase;
    content?: ModalContent;
    header?: ModalHeader;
    footer?: ModalFooter;
  };
 
  export type ModalBase = {
    color?: CSSProperties["color"];
    background?: CSSProperties["background"];
    border?: CSSProperties["border"];
    boxShadow?: CSSProperties["boxShadow"];
    borderRadius?: CSSProperties["borderRadius"];
  };
 
  export type ModalContent = {
    padding?: CSSProperties["padding"];
  };
 
  export type ModalHeader = {
    padding?: CSSProperties["padding"];
    borderBottom?: CSSProperties["borderTop"];
    fontSize?: CSSProperties["fontSize"];
    fontWeight?: CSSProperties["fontWeight"];
  };
 
  export type ModalFooter = {
    borderTop?: CSSProperties["borderTop"];
    padding?: CSSProperties["padding"];
  };
 
  export type Overlay = {
    background?: CSSProperties["background"];
    opacity?: CSSProperties["opacity"];
  };
 
  export interface List extends Panel {
    color?: CSSProperties["color"];
    icon?: ListIcon;
  }
 
  export type ListIcon = {
    color?: CSSProperties["color"];
    background?: CSSProperties["background"];
    border?: CSSProperties["border"];
  };
 
  export interface ListAdd extends Omit<Panel, "subtitle"> {}
 
  export interface Dropdown {
    background?: CSSProperties["background"];
    color?: CSSProperties["color"];
    border?: CSSProperties["border"];
    boxShadow?: CSSProperties["boxShadow"];
    fontSize?: CSSProperties["fontSize"];
    separatorBorder?: CSSProperties["borderBottom"];
    selected?: Option;
    borderRadius?: CSSProperties["borderRadius"];
    padding?: CSSProperties["padding"];
    "&:hover"?: Option;
  }
 
  export type Option = {
    background?: CSSProperties["background"];
    fontWeight?: CSSProperties["fontWeight"];
    color?: CSSProperties["color"];
  };
 
  export type FontStyle = {
    color?: CSSProperties["color"];
    fontFamily?: CSSProperties["fontFamily"];
    fontSize?: CSSProperties["fontSize"];
    fontWeight?: CSSProperties["fontWeight"];
    margin?: CSSProperties["margin"];
  };
 
  export interface PopoverMenu extends Omit<Dropdown, "selected"> {
    noClose?: boolean;
  }
 
  export type Tabs = {
    selected?: TabButton;
    unselected?: TabButton;
  };
 
  export interface TabButton extends ButtonType {
    borderBottom?: CSSProperties["borderBottom"];
    borderTop?: CSSProperties["borderTop"];
    borderRight?: CSSProperties["borderRight"];
    borderLeft?: CSSProperties["borderLeft"];
  }
 
  export type Alerts = {
    padding?: CSSProperties["padding"];
    borderRadius?: CSSProperties["borderRadius"];
    title?: FontStyle;
    content?: FontStyle;
    info?: AlertType;
    warning?: AlertType;
    critical?: AlertType;
  };
 
  export type AlertType = {
    background?: CSSProperties["background"];
    border?: CSSProperties["border"];
    color?: CSSProperties["color"];
    iconColor?: CSSProperties["fill"];
    borderRadius?: CSSProperties["borderRadius"];
  };
 
  export type Charts = {
    labels?: ChartLabels;
    grid?: ChartGrid;
    axis?: ChartAxis;
  };
 
  export type ChartLabels = {
    color?: CSSProperties["color"];
    fontWeight?: CSSProperties["fontWeight"];
  };
 
  export type ChartGrid = {
    stroke: CSSProperties["stroke"];
  };
 
  export type ChartAxis = {
    stroke: CSSProperties["stroke"];
  };
}

Examples

Button properties

theme.buttons.primary

This property changes everthing you need to make the buttons appear like your own application.

import Vizzly from "@vizzly/dashboard";
 
const MyAppDashboard = () => (
  <Vizzly.Dashboard
    theme={{
      detail: "minimal",
      rowLimit: 5,
      buttons: {
        primary: {
          borderRadius: "15px",
          border: "1px solid rgb(17, 109, 255)",
          background: "rgb(17, 109, 255)",
          padding: "3px 17px 4.5px",
          boxShadow: "none",
          color: "#fff",
          fontSize: "14px",
          fontWeight: 530,
          height: 30,
          "&:hover": {
            border: "1px solid #0f62e6",
            background: "#0f62e6",
          },
        },
      },
    }}
  />
);

Input properties

theme.forms.label
theme.forms.input

This property changes everthing you need to make a type="text" or type=number input appear like your own application.

import Vizzly from "@vizzly/dashboard";
 
const MyAppDashboard = () => (
  <Vizzly.Dashboard
    theme={{
      detail: "minimal",
      rowLimit: 5,
      forms: {
        label: {
          fontSize: 14,
          fontWeight: 400,
          color: "#32536A",
          margin: "0 0 6px 0",
        },
        input: {
          border: "1px #a8caff solid",
          background: "rgb(255, 255, 255)",
          borderRadius: "0.375rem",
          padding: "5px 9px 5px 12px",
          color: "rgb(0, 6, 36)",
          fontSize: 16,
          fontWeight: 400,
          "&:focus": {
            border: "1px #3899EC solid",
            boxShadow: "0 0 0 3px #AADBFC",
          },
          "&:hover": {
            background: "#e7f0ff",
          },
        },
      },
    }}
  />
);

Chart properties

theme.charts.labels
theme.charts.grid
theme.charts.axis

The properties allow you to customise the base styles of the charts.

import Vizzly from "@vizzly/dashboard";
 
const MyAppDashboard = () => (
  <Vizzly.Dashboard
    theme={{
      detail: "minimal",
      rowLimit: 5,
      charts: {
        labels: {
          color: "#000",
          fontWeight: 300,
        },
        grid: {
          stroke: "rgba(25,144,206, 0.7)",
        },
        axis: {
          stroke: "rgba(25,144,206, 0.9)",
        },
      },
    }}
  />
);

Design Tokens with CSS Custom properties

The Theme API accepts Custom properties, also known as CSS variables. If you have defined your Design Tokens in a CSS file or in the head tag of your application, these can be used in the Vizzly Theme API.

To find out more about Custom properties visit https://developer.mozilla.org/en-US/docs/Web/CSS/--*/ (opens in a new tab)

Example

<Head>
  <title>Vizzly in-browser example</title>
  <style>
    :root {
      --dk-mode-color-1:         #010409;
      --dk-mode-color-2:         #30363d;
      --dk-mode-color-3:         #c9d1d9;
      --dk-mode-highlight-color: #3899EC;
 
      --font-size-standard:      14px;
      --font-size-small:         12px;
      --font-weight:             400;
 
      --border-radius:           6px;
      --border-color:            var(--dk-mode-color-2);
    }
  </style>
</Head>
 
const MyAppDashboard = () => (
  <Vizzly.Dashboard
    theme={{
      rowLimit: 6,
      detail: "minimal",
        forms: {
          select: {
            background: "var(--dk-mode-color-1)",
            borderRadius: "var(--border-radius)",
            border: "1px solid var(--border-color)",
            fontSize: "var(--font-size-standard)",
            padding: "6.25px 0.5rem",
            boxShadow: "inset 0 0 0 1px  transparent",
            color: "var(--dk-mode-color-3)",
            "&:hover": {
              border: "1px solid var(--dk-mode-highlight-color)",
              boxShadow: "inset 0 0 0 1px transparent",
            },
            "&:focus": {
              border: "1px solid var(--dk-mode-highlight-color)",
            },
            indicatorColor: "var(--dk-mode-highlight-color)",
          },
        },
        dropdowns: {
          fontSize: "var(--font-size-small)",
          background: "var(--dk-mode-color-2)",
          color: "var(--dk-mode-color-3)",
          boxShadow: "0 8px 24px var(--dk-mode-color-1)",
          borderRadius: "var(--border-radius)",
          border: "1px solid var(--border-color)",
          separatorBorder: "1px solid var(--border-color)",
          "&:hover": {
            background: "#6e76811a",
          },
          padding: "7px 18px",
        },
    }}
    ...
  />
);
Last updated on March 15, 2023