Skip to content

Migration to V3 (WIP)

Ruo Ling edited this page Dec 4, 2024 · 39 revisions

Migrating from V2

1. Upgrade to the V3 Design System

npm i @lifesg/react-design-system@latest

2. Add the V3 css stylesheet

+ https://assets.life.gov.sg/react-design-system/v3/css/main.css

Depending on the theme that your product uses, load the corresponding font stylesheet

// if using default LifeSG theme, or Open Sans font
https://assets.life.gov.sg/react-design-system/v3/css/open-sans.css

// if using default BookingSG theme, or Jakarta Sans font
https://assets.life.gov.sg/react-design-system/v3/css/plus-jakarta-sans.css

3. Run codemod to migrate imports

V3 offers a set of codemods written with JSCodeShift to ease migration to the new design tokens.

To start the codemod helper, run the following command:

npx lifesg-react-design-system

Press <space> to select deprecate-v2-tokens and press <enter> to proceed. Follow the remaining prompts on the command line.

4. Use the new theme object

- import { V2_BaseTheme } from "@lifesg/react-design-system/v2_theme";
+ import { LifeSGTheme } from "@lifesg/react-design-system/theme";
import { ThemeProvider } from "styled-components";

- <ThemeProvider theme={V2_BaseTheme}>{children}</ThemeProvider>
+ <ThemeProvider theme={LifeSGTheme}>{children}</ThemeProvider>

5. Declare theme types (recommended)

If you access the theme object via the useTheme hook in a Typescript project, you can type it by adding a custom declaration file. Read more at the Styled Components api docs.

// styled.d.ts
import "styled-components";

import { ThemeSpec } from "@lifesg/react-design-system/theme/types";

declare module "styled-components" {
    export interface DefaultTheme extends ThemeSpec {}
}

Summary of changes

Changes

Migrate deprecated imports

The old design tokens have been deprecated and renamed to make way for the new tokens. They will be removed in a future version. However, you may continue to use them in V3 until your project is ready to switch over.

Affected components:

  • Color
  • DesignToken
  • Layout
  • MediaQuery
  • Text

To migrate, run the codemod helper and select deprecate-v2-tokens

npx lifesg-react-design-system

V2 usage

import { Color } from "@lifesg/react-design-system/color";

V3 usage

import { V2_Color } from "@lifesg/react-design-system/v2_color";

New design tokens

The design system offers the following types of tokens:

  • Colour
  • Typography
  • Breakpoint
  • Spacing
  • Motion
  • Border
  • Border radius

Read up more on the usage of the new design tokens in the documentation.

Color has been deprecated

V2 usage

import { Color } from "@lifesg/react-design-system/color";

export const ExampleComponent = styled.div`
  color: ${Color.Neutral[3]};
  box-shadow: 0px 0px 1px 1px ${Color.Neutral[5]};
`

V3 usage

Documentation

Where possible, switch to the semantic tokens. The primitive tokens can be used for cases where no suitable semantic tokens are available.

import { Colour } from "@lifesg/react-design-system/theme";

export const ExampleComponent = styled.div`
  color: ${Color["text"]};
  :hover {
    color: ${Colour["text-hover"]};
  }

  background-color: ${Color.Primitive["brand-80"]};
`

Tip

A basic codemod is available to migrate V2 tokens to V3 primitive tokens. To migrate, run the codemod helper and select deprecate-v2-tokens:

npx lifesg-react-design-system

TextStyleHelper has been deprecated

V2 usage

import { TextStyleHelper } from "@lifesg/react-design-system/text";

export const ExampleComponent = styled.div`
  ${TextStyleHelper.getTextStyle("Body", "semibold")}
`

V3 usage

Documentation

You can use the font tokens directly to specify text styling (font family, size, weight, line-height and letter-spacing) or specific overrides.

import { Font, FontSpec } from "@lifesg/react-design-system/theme";

export const ExampleComponent = styled.div`
  ${Font["body-baseline-semibold"]} // apply all font-related styles
  font-weight: ${FontSpec["weight-regular"]}; // only override 1 property e.g. when inheriting
`

Text has been deprecated

V2 usage

import { Text } from "@lifesg/react-design-system/text";

<Text.H1 weight="semibold">Hello world</Text.H1>
<Text.Body>Hello world</Text.Body>
<Text.Hyperlink.Default>Hello world</Text.Hyperlink.Default>

V3 usage

Documentation

Use the Typography component with the equivalent font size and weight.

import { Typography } from "@lifesg/react-design-system/theme";

<Typography.HeaderXXL weight="semibold">Hello world</Typography.HeaderXXL>
<Typography.BodyBL>Hello world</Typography.BodyBL>
<Typography.LinkBL>Hello world</Text.LinkBL>

As a general rule of thumb, V2 can be mapped to V3 as follows:

V2 V3 weight
Text.D1 Typography.HeaderXXL bold
Text.D2 Typography.HeaderXL bold
Text.D3 Typography.HeaderMD bold
Text.D4 Typography.HeaderSM bold
Text.DBody Typography.HeaderSM light
Text.H1 Typography.HeaderLG bold
Text.H2 Typography.HeaderMD bold
Text.H3 Typography.HeaderSM bold
Text.H4 Typography.HeaderXS bold
Text.H5 Typography.BodyMD bold
Text.H6 Typography.BodySM bold

For accessibility, you should override the rendered HTML element by specifying the as prop. The actual element to use depends on your page structure. For more information on building accessible headers, refer to this article.

For example, to render HeaderXXL as a div instead of h1, you can do this:

<Typography.HeaderXXL as="div">Hello world<Typography.HeaderXXL>

Tip

A basic codemod is available to migrate V2 Text to V3 Typography. To migrate, run the codemod helper and select migrate-text:

npx lifesg-react-design-system

Removed !important from font styles

This makes inheritance easier when using the typography tokens or components. Do make sure that your existing page design remains unaffected.

MediaWidths has been deprecated

V2 usage

import { MediaWidths } from "@lifesg/react-design-system/media";

useMediaQuery({ maxWidth: MediaWidths.mobileL });

V3 usage

Documentation

The viewport widths are now split into min/max values. Pick the correct one based on your desktop-first or mobile-first approach.

import { Breakpoint } from "@lifesg/react-design-system/theme";

useMediaQuery({ minWidth: Breakpoint["lg-min"] }); // mobile-first
useMediaQuery({ maxWidth: Breakpoint["md-max"] }); // desktop-first

MediaQuery has been deprecated

V2 usage

V3 usage

Documentation

import { MediaQuery } from "@lifesg/react-design-system/theme";

const ExampleComponent = styled.div`
    background-color: red;

    ${MediaQuery.MinWidth.xs} {
        background-color: yellow;
    }

    ${MediaQuery.MaxWidth.xs} {
        background-color: purple;
    }
`;

Generally, you can map MediaQuery usage as such:

V2 V3 Max V3 Min
mobileS xxs xs
mobileM xs sm
mobileL sm md
tablet lg xl
desktopM xl xxl
desktopL xl xxl
desktop4k xl xxl

Change to ResourceScheme

base has been renamed to lifesg.

V2 usage

<ErrorDisplay illustrationScheme="base" />
<TimeTable illustrationScheme="base" />

V3 usage

<ErrorDisplay illustrationScheme="lifesg" />
<TimeTable illustrationScheme="lifesg" />

Usage of New Design Components

Layout Component

  • Updated Features: The revised Layout component replaces the deprecated version, integrating new Breakpoint and MediaQuery tokens along with enhanced theming capabilities.
  • Component Integration: -- Container, Section, and Content: ---Utilize updated MediaQuery breakpoint values for layouts such as flex, flex-column, and grid. ---Col-Div: Adopts the new MediaQuery theming for column and breakpoint values, adding margin and gutter specifications from the intended theme. It must be used within the Content component set to a grid type.
  • Props to specify the span will be updated with the new Breakpoint token use.

New props usage mapping for reference:

V2 Prop V3 Prop
desktopCols xlCols
tabletCols lgCols
mobileCols smCols

V2 Layout has been deprecated

V2 usage

import { Layout } from "@lifesg/react-design-system/layout";

<Layout.ColDiv
    mobileCols={[1, 5]}
    tabletCols={[6, 9]}
    desktopCols={[7, 12]}
    style={{
        background: "#FDDDD7",
        textAlign: "center",
        padding: "0.5rem 0",
    }}
>
    One
</Layout.ColDiv>

V3 usage

Use the V3 Layout component with its updated and equivalent new specifications.

<Layout.ColDiv
    smCols={[1, 5]}
    lgCols={[6, 9]}
    xlCols={[7, 12]}
    style={{
        background: "#FDDDD7",
        textAlign: "center",
        padding: "0.5rem 0",
    }}
>
    <Typography.BodySmall>One</Typography.BodySmall>
</Layout.ColDiv>

Custom column specification

In version 3, consumers can customize column spans across various breakpoints in their applications by utilizing Declaration Merging. This feature enhances flexibility while ensuring robust typing security.

In their styled.d.ts file they can declare it as such:

declare module "styled-components" {
    export interface DefaultTheme extends ThemeSpec {
        maxColumns?: {
            xxs: 8;
            xs: 8;
            sm: 8;
            md: 8;
            lg: 12;
            xl: 12;
            xxl: 12;
        };
    }
}