-
Notifications
You must be signed in to change notification settings - Fork 22
Migrating to V4
We have moved away from Styled Components (CSS-in-JS) to Linaria (build-time CSS extraction). This improves compatibility with projects that:
- rely on SSR
- use strict CSP
- prefer to use another styling framework
If your project uses V3, follow these steps to install V4.
Recommended step:
Upgrade to the latest V3 release and ensure your build and unit tests are passing first. This will help us with troubleshooting V4-specific issues.
npm i @lifesg/react-design-system@3
1. Upgrade to the V4 Design System
npm i @lifesg/react-design-system@4
2. Import the theme stylesheet
In your application's JavaScript entrypoint (e.g. pages/_app.tsx or app/layout.tsx in a NextJS project):
import "@lifesg/react-design-system/theme/styles/lifesg.css";Or in an existing .css file:
@import "@lifesg/react-design-system/theme/styles/lifesg.css";3. Set up the new ThemeProvider
Replace the Styled Components ThemeProvider or DSThemeProvider with the new ThemeProvider from @lifesg/react-design-system/theme:
- import { DSThemeProvider, LifeSGTheme } from "@lifesg/react-design-system/theme";
- import { ThemeProvider } from "styled-components";
+ import { ThemeProvider } from "@lifesg/react-design-system/theme";
- <ThemeProvider theme={LifeSGTheme}>{children}</ThemeProvider>
- <DSThemeProvider theme={LifeSGTheme}>{children}</DSThemeProvider>
+ <ThemeProvider theme="lifesg">{children}</ThemeProvider>Important
If DSThemeProvider was not previously used, add mode="light" to avoid issues with the default dark mode in V4.
<ThemeProvider theme="lifesg" mode="light">
{children}
</ThemeProvider>4. Migrate design token usages
Refer to the Design tokens in styling and Design tokens at runtime sections.
General
- Design tokens in styling
- Design tokens at runtime
- Breakpoint tokens
- Dark mode
- ThemeProvider
- ThemeSpec and customisation
- Subpath imports
Components
In V3, design tokens could be called as functions that accepted props.
V3 usage
import { Colour } from "@lifesg/react-design-system/theme";
const ExampleComponent = styled.div`
background: ${(props) => Colour["bg"](props)};
`;V4 usage
In V4, design tokens are CSS variable strings. Update usages depending on the context:
-
In Styled Components:
import { Colour } from "@lifesg/react-design-system/theme"; const ExampleComponent = styled.div` background: ${Colour["bg"]}; `;
-
In inline styles:
<div style={{ color: Colour["text"] }} />
If you need the resolved CSS value at runtime (e.g. to pass to a third-party library or perform calculations), use the useDesignToken hook:
import { Colour, useDesignToken } from "@lifesg/react-design-system/theme";
const ExampleComponent = () => {
const color = useDesignToken(Colour["text"]);
// color is a resolved CSS value e.g. "#1d2939"
return <ThirdPartyChart color={color} />;
};For tokens that resolve to a numeric length unit (e.g. radius, spacing or breakpoints), use parsePxOrRemValue to get a number:
import { Spacing, useDesignToken } from "@lifesg/react-design-system/theme";
import { parsePxOrRemValue } from "@lifesg/react-design-system/theme";
const ExampleComponent = () => {
const gap = parsePxOrRemValue(useDesignToken(Spacing["spacing-16"]));
// gap is a number e.g. 16
return <ThirdPartyChart gap={gap} />;
};In V3, you had to extract the breakpoint value at runtime by invoking the design token.
V3 usage
import { Breakpoint } from "@lifesg/react-design-system/theme";
import { useTheme } from "styled-components";
const ExampleComponent = () => {
const theme = useTheme();
const tablet = Breakpoint["lg-max"]({ theme });
const isTablet = useMediaQuery({ maxWidth: tablet });
};V4 usage
In V4, media query hooks are provided out of the box:
import {
Breakpoint,
useSafeMaxWidthMediaQuery,
} from "@lifesg/react-design-system/theme";
const ExampleComponent = () => {
const isTablet = useSafeMaxWidthMediaQuery(Breakpoint["lg-max"]);
};If the actual pixel value is required at runtime:
import { Breakpoint, useDesignToken } from "@lifesg/react-design-system/theme";
import { parsePxOrRemValue } from "@lifesg/react-design-system/theme";
const ExampleComponent = () => {
const tablet = parsePxOrRemValue(useDesignToken(Breakpoint["lg-max"]));
const handleResize = () => {
if (window.innerWidth <= tablet) {
// do something
}
};
};In V4, dark mode is enabled by default. ThemeProvider follows the user's system preference unless a mode is explicitly set.
If your project does not support dark mode, set mode="light" to opt out:
import { ThemeProvider } from "@lifesg/react-design-system/theme";
<ThemeProvider theme="lifesg" mode="light">
{children}
</ThemeProvider>;The Styled Components ThemeProvider should be replaced with the new ThemeProvider from @lifesg/react-design-system/theme.
V3 usage
import { LifeSGTheme } from "@lifesg/react-design-system/theme";
import { ThemeProvider } from "styled-components";
<ThemeProvider theme={LifeSGTheme}>
<Component />
</ThemeProvider>;V4 usage
import { ThemeProvider } from "@lifesg/react-design-system/theme";
<ThemeProvider theme="lifesg">
<Component />
</ThemeProvider>;Import the corresponding theme stylesheet in your entrypoint:
import "@lifesg/react-design-system/theme/styles/lifesg.css";The ThemeSpec object and the overrides and componentOverrides API have been removed in V4.
V3 usage
import { LifeSGTheme, ThemeSpec } from "@lifesg/react-design-system/theme";
import { ThemeProvider } from "styled-components";
const customTheme: ThemeSpec = {
...LifeSGTheme,
overrides: {
primitiveColour: {
"primary-10": "#F3C85C",
},
font: {
"heading-size-xxl": "4rem",
"heading-lh-xxl": "4.5rem",
"heading-ls-xxl": "0.056rem",
},
},
};
const App = () => {
return (
<ThemeProvider theme={customTheme}>
<Component />
</ThemeProvider>
);
};The V3 ThemeSpec object can be mapped to the V4 theme prop as follows:
V3 ThemeSpec
|
V4 theme
|
|---|---|
LifeSGTheme |
lifesg |
BookingSGTheme |
bookingsg |
RBSTheme |
rbs |
MyLegacyTheme |
mylegacy |
CCubeTheme |
ccube |
OneServiceTheme |
oneservice |
PATheme |
pa |
A11yPlaygroundTheme |
a11y-playground |
SupportGoWhereTheme |
supportgowhere |
SGWDigitalLobbyTheme |
sgw-digital-lobby |
IMDATheme |
imda |
SPFTheme |
spf |
SMGSTheme |
(not available yet) |
V4 usage
For ad hoc customisation, override CSS variables directly. Choose an approach based on your project's constraints:
-
Option 1: CSS stylesheet — override entire theme
Override the theme globally by targeting the
data-fds-themeattribute set byThemeProvider.[data-fds-theme="lifesg"] { --fds-colour-bg-primary: #0043ce; --fds-colour-text-inverse: #ffffff; } [data-fds-theme="lifesg"][data-fds-theme-mode="dark"] { --fds-colour-bg-primary: #0043ce; --fds-colour-text-inverse: #000000; }
-
Option 2: Inline style
Suitable for dynamic overrides driven by runtime values.
const App = ({ customTheme }) => { return ( <ThemeProvider style={ { "--fds-colour-bg-primary": customTheme.primaryColour, "--fds-colour-text-inverse": "#ffffff", } as React.CSSProperties } > <Component /> </ThemeProvider> ); };
-
Option 3:
useApplyStyleUse this if your project enforces a strict Content Security Policy that disallows inline styles.
import { useRef } from "react"; import { useApplyStyle } from "@lifesg/react-design-system/theme/utils"; const App = ({ customTheme }) => { const themeRef = useRef<HTMLDivElement>(null); useApplyStyle(themeRef, { "--fds-colour-bg-primary": customTheme.primaryColour, "--fds-colour-text-inverse": "#ffffff", }); return ( <ThemeProvider ref={themeRef}> <Component /> </ThemeProvider> ); };
A mapping of V3 design tokens to the corresponding CSS variable is provided in the following sections:
primitiveColour, primitiveColourDark
| V3 | V4 |
|---|---|
brand-10 |
--fds-colour-brand-10 |
brand-20 |
--fds-colour-brand-20 |
brand-30 |
--fds-colour-brand-30 |
brand-40 |
--fds-colour-brand-40 |
brand-50 |
--fds-colour-brand-50 |
brand-60 |
--fds-colour-brand-60 |
brand-70 |
--fds-colour-brand-70 |
brand-80 |
--fds-colour-brand-80 |
brand-90 |
--fds-colour-brand-90 |
brand-95 |
--fds-colour-brand-95 |
brand-100 |
--fds-colour-brand-100 |
primary-10 |
--fds-colour-primary-10 |
primary-20 |
--fds-colour-primary-20 |
primary-30 |
--fds-colour-primary-30 |
primary-40 |
--fds-colour-primary-40 |
primary-50 |
--fds-colour-primary-50 |
primary-60 |
--fds-colour-primary-60 |
primary-70 |
--fds-colour-primary-70 |
primary-80 |
--fds-colour-primary-80 |
primary-90 |
--fds-colour-primary-90 |
primary-95 |
--fds-colour-primary-95 |
primary-100 |
--fds-colour-primary-100 |
secondary-10 |
--fds-colour-secondary-10 |
secondary-20 |
--fds-colour-secondary-20 |
secondary-30 |
--fds-colour-secondary-30 |
secondary-40 |
--fds-colour-secondary-40 |
secondary-50 |
--fds-colour-secondary-50 |
secondary-60 |
--fds-colour-secondary-60 |
secondary-70 |
--fds-colour-secondary-70 |
secondary-80 |
--fds-colour-secondary-80 |
secondary-90 |
--fds-colour-secondary-90 |
secondary-95 |
--fds-colour-secondary-95 |
secondary-100 |
--fds-colour-secondary-100 |
neutral-10 |
--fds-colour-neutral-10 |
neutral-20 |
--fds-colour-neutral-20 |
neutral-30 |
--fds-colour-neutral-30 |
neutral-40 |
--fds-colour-neutral-40 |
neutral-50 |
--fds-colour-neutral-50 |
neutral-60 |
--fds-colour-neutral-60 |
neutral-70 |
--fds-colour-neutral-70 |
neutral-80 |
--fds-colour-neutral-80 |
neutral-90 |
--fds-colour-neutral-90 |
neutral-95 |
--fds-colour-neutral-95 |
neutral-100 |
--fds-colour-neutral-100 |
success-10 |
--fds-colour-success-10 |
success-20 |
--fds-colour-success-20 |
success-30 |
--fds-colour-success-30 |
success-40 |
--fds-colour-success-40 |
success-50 |
--fds-colour-success-50 |
success-60 |
--fds-colour-success-60 |
success-70 |
--fds-colour-success-70 |
success-80 |
--fds-colour-success-80 |
success-90 |
--fds-colour-success-90 |
success-95 |
--fds-colour-success-95 |
success-100 |
--fds-colour-success-100 |
warning-10 |
--fds-colour-warning-10 |
warning-20 |
--fds-colour-warning-20 |
warning-30 |
--fds-colour-warning-30 |
warning-40 |
--fds-colour-warning-40 |
warning-50 |
--fds-colour-warning-50 |
warning-60 |
--fds-colour-warning-60 |
warning-70 |
--fds-colour-warning-70 |
warning-80 |
--fds-colour-warning-80 |
warning-90 |
--fds-colour-warning-90 |
warning-95 |
--fds-colour-warning-95 |
warning-100 |
--fds-colour-warning-100 |
error-10 |
--fds-colour-error-10 |
error-20 |
--fds-colour-error-20 |
error-30 |
--fds-colour-error-30 |
error-40 |
--fds-colour-error-40 |
error-50 |
--fds-colour-error-50 |
error-60 |
--fds-colour-error-60 |
error-70 |
--fds-colour-error-70 |
error-80 |
--fds-colour-error-80 |
error-90 |
--fds-colour-error-90 |
error-95 |
--fds-colour-error-95 |
error-100 |
--fds-colour-error-100 |
info-10 |
--fds-colour-info-10 |
info-20 |
--fds-colour-info-20 |
info-30 |
--fds-colour-info-30 |
info-40 |
--fds-colour-info-40 |
info-50 |
--fds-colour-info-50 |
info-60 |
--fds-colour-info-60 |
info-70 |
--fds-colour-info-70 |
info-80 |
--fds-colour-info-80 |
info-90 |
--fds-colour-info-90 |
info-95 |
--fds-colour-info-95 |
info-100 |
--fds-colour-info-100 |
white |
--fds-colour-white |
black |
--fds-colour-black |
primary-inverse |
--fds-colour-primary-inverse |
semanticColour, semanticColourDark
| V3 | V4 |
|---|---|
text |
--fds-colour-text |
text-subtle |
--fds-colour-text-subtle |
text-subtler |
--fds-colour-text-subtler |
text-subtlest |
--fds-colour-text-subtlest |
text-primary |
--fds-colour-text-primary |
text-primary-strongest |
--fds-colour-text-primary-strongest |
text-hover |
--fds-colour-text-hover |
text-selected |
--fds-colour-text-selected |
text-selected-hover |
--fds-colour-text-selected-hover |
text-disabled |
--fds-colour-text-disabled |
text-disabled-subtle |
--fds-colour-text-disabled-subtle |
text-disabled-subtlest |
--fds-colour-text-disabled-subtlest |
text-selected-disabled |
--fds-colour-text-selected-disabled |
text-success |
--fds-colour-text-success |
text-warning |
--fds-colour-text-warning |
text-error |
--fds-colour-text-error |
text-info |
--fds-colour-text-info |
text-inverse |
--fds-colour-text-inverse |
icon |
--fds-colour-icon |
icon-subtle |
--fds-colour-icon-subtle |
icon-strongest |
--fds-colour-icon-strongest |
icon-primary |
--fds-colour-icon-primary |
icon-primary-subtle |
--fds-colour-icon-primary-subtle |
icon-primary-subtlest |
--fds-colour-icon-primary-subtlest |
icon-hover |
--fds-colour-icon-hover |
icon-selected |
--fds-colour-icon-selected |
icon-selected-hover |
--fds-colour-icon-selected-hover |
icon-disabled |
--fds-colour-icon-disabled |
icon-disabled-subtle |
--fds-colour-icon-disabled-subtle |
icon-selected-disabled |
--fds-colour-icon-selected-disabled |
icon-success |
--fds-colour-icon-success |
icon-warning |
--fds-colour-icon-warning |
icon-error |
--fds-colour-icon-error |
icon-error-strong |
--fds-colour-icon-error-strong |
icon-info |
--fds-colour-icon-info |
icon-inverse |
--fds-colour-icon-inverse |
icon-primary-inverse |
--fds-colour-icon-primary-inverse |
border |
--fds-colour-border |
border-strong |
--fds-colour-border-strong |
border-stronger |
--fds-colour-border-stronger |
border-primary |
--fds-colour-border-primary |
border-primary-subtle |
--fds-colour-border-primary-subtle |
border-hover |
--fds-colour-border-hover |
border-hover-strong |
--fds-colour-border-hover-strong |
border-selected |
--fds-colour-border-selected |
border-selected-subtle |
--fds-colour-border-selected-subtle |
border-selected-subtlest |
--fds-colour-border-selected-subtlest |
border-selected-hover |
--fds-colour-border-selected-hover |
border-focus |
--fds-colour-border-focus |
border-focus-strong |
--fds-colour-border-focus-strong |
border-disabled |
--fds-colour-border-disabled |
border-selected-disabled |
--fds-colour-border-selected-disabled |
border-success |
--fds-colour-border-success |
border-warning |
--fds-colour-border-warning |
border-error |
--fds-colour-border-error |
border-error-focus |
--fds-colour-border-error-focus |
border-error-focus-strong |
--fds-colour-border-error-focus-strong |
border-error-strong |
--fds-colour-border-error-strong |
border-info |
--fds-colour-border-info |
bg |
--fds-colour-bg |
bg-strong |
--fds-colour-bg-strong |
bg-stronger |
--fds-colour-bg-stronger |
bg-strongest |
--fds-colour-bg-strongest |
bg-hover |
--fds-colour-bg-hover |
bg-hover-strong |
--fds-colour-bg-hover-strong |
bg-hover-subtle |
--fds-colour-bg-hover-subtle |
bg-hover-neutral |
--fds-colour-bg-hover-neutral |
bg-hover-neutral-strong |
--fds-colour-bg-hover-neutral-strong |
bg-selected |
--fds-colour-bg-selected |
bg-selected-hover |
--fds-colour-bg-selected-hover |
bg-selected-strong |
--fds-colour-bg-selected-strong |
bg-selected-stronger |
--fds-colour-bg-selected-stronger |
bg-selected-strongest |
--fds-colour-bg-selected-strongest |
bg-selected-strongest-hover |
--fds-colour-bg-selected-strongest-hover |
bg-disabled |
--fds-colour-bg-disabled |
bg-selected-disabled |
--fds-colour-bg-selected-disabled |
bg-selected-stronger-disabled |
--fds-colour-bg-selected-stronger-disabled |
bg-success |
--fds-colour-bg-success |
bg-success-hover |
--fds-colour-bg-success-hover |
bg-success-strong |
--fds-colour-bg-success-strong |
bg-success-strong-hover |
--fds-colour-bg-success-strong-hover |
bg-warning |
--fds-colour-bg-warning |
bg-warning-hover |
--fds-colour-bg-warning-hover |
bg-warning-strong |
--fds-colour-bg-warning-strong |
bg-warning-strong-hover |
--fds-colour-bg-warning-strong-hover |
bg-info |
--fds-colour-bg-info |
bg-info-hover |
--fds-colour-bg-info-hover |
bg-info-strong |
--fds-colour-bg-info-strong |
bg-info-strong-hover |
--fds-colour-bg-info-strong-hover |
bg-error |
--fds-colour-bg-error |
bg-error-hover |
--fds-colour-bg-error-hover |
bg-error-strong |
--fds-colour-bg-error-strong |
bg-error-strong-hover |
--fds-colour-bg-error-strong-hover |
bg-inverse |
--fds-colour-bg-inverse |
bg-inverse-subtle |
--fds-colour-bg-inverse-subtle |
bg-inverse-subtler |
--fds-colour-bg-inverse-subtler |
bg-inverse-subtlest |
--fds-colour-bg-inverse-subtlest |
bg-inverse-hover |
--fds-colour-bg-inverse-hover |
bg-primary |
--fds-colour-bg-primary |
bg-primary-subtle |
--fds-colour-bg-primary-subtle |
bg-primary-subtler |
--fds-colour-bg-primary-subtler |
bg-primary-subtlest |
--fds-colour-bg-primary-subtlest |
bg-available |
--fds-colour-bg-available |
bg-primary-hover |
--fds-colour-bg-primary-hover |
bg-primary-subtlest-hover |
--fds-colour-bg-primary-subtlest-hover |
bg-primary-subtlest-selected |
--fds-colour-bg-primary-subtlest-selected |
overlay-strong |
--fds-colour-overlay-strong |
overlay-subtle |
--fds-colour-overlay-subtle |
hyperlink |
--fds-colour-hyperlink |
hyperlink-hover |
--fds-colour-hyperlink-hover |
hyperlink-visited |
--fds-colour-hyperlink-visited |
hyperlink-inverse |
--fds-colour-hyperlink-inverse |
focus-ring |
--fds-colour-focus-ring |
focus-ring-inverse |
--fds-colour-focus-ring-inverse |
fontSpec
| V3 | V4 |
|---|---|
heading-size-xxl |
--fds-font-heading-size-xxl |
heading-size-xl |
--fds-font-heading-size-xl |
heading-size-lg |
--fds-font-heading-size-lg |
heading-size-md |
--fds-font-heading-size-md |
heading-size-sm |
--fds-font-heading-size-sm |
heading-size-xs |
--fds-font-heading-size-xs |
heading-lh-xxl |
--fds-font-heading-lh-xxl |
heading-lh-xl |
--fds-font-heading-lh-xl |
heading-lh-lg |
--fds-font-heading-lh-lg |
heading-lh-md |
--fds-font-heading-lh-md |
heading-lh-sm |
--fds-font-heading-lh-sm |
heading-lh-xs |
--fds-font-heading-lh-xs |
heading-ls-xxl |
--fds-font-heading-ls-xxl |
heading-ls-xl |
--fds-font-heading-ls-xl |
heading-ls-lg |
--fds-font-heading-ls-lg |
heading-ls-md |
--fds-font-heading-ls-md |
heading-ls-sm |
--fds-font-heading-ls-sm |
heading-ls-xs |
--fds-font-heading-ls-xs |
weight-light |
--fds-font-weight-light |
weight-regular |
--fds-font-weight-regular |
weight-semibold |
--fds-font-weight-semibold |
weight-bold |
--fds-font-weight-bold |
font-family |
Removed |
heading-font-family |
--fds-font-family-heading |
body-font-family |
--fds-font-family-body |
body-size-baseline |
--fds-font-body-size-baseline |
body-size-md |
--fds-font-body-size-md |
body-size-sm |
--fds-font-body-size-sm |
body-size-xs |
--fds-font-body-size-xs |
body-lh-baseline |
--fds-font-body-lh-baseline |
body-lh-md |
--fds-font-body-lh-md |
body-lh-sm |
--fds-font-body-lh-sm |
body-lh-xs |
--fds-font-body-lh-xs |
body-ls-baseline |
--fds-font-body-ls-baseline |
body-ls-md |
--fds-font-body-ls-md |
body-ls-sm |
--fds-font-body-ls-sm |
body-ls-xs |
--fds-font-body-ls-xs |
form-label-size |
--fds-font-form-label-size |
form-description-size |
--fds-font-form-description-size |
form-label-lh |
--fds-font-form-label-lh |
form-description-lh |
--fds-font-form-description-lh |
form-label-ls |
--fds-font-form-label-ls |
form-description-ls |
--fds-font-form-description-ls |
| - | --fds-font-variant |
font
fontSpec
breakpoint
| V3 | V4 |
|---|---|
xxs-min |
--fds-breakpoint-xxs-min |
xxs-max |
--fds-breakpoint-xxs-max |
xs-min |
--fds-breakpoint-xs-min |
xs-max |
--fds-breakpoint-xs-max |
sm-min |
--fds-breakpoint-sm-min |
sm-max |
--fds-breakpoint-sm-max |
md-min |
--fds-breakpoint-md-min |
md-max |
--fds-breakpoint-md-max |
lg-min |
--fds-breakpoint-lg-min |
lg-max |
--fds-breakpoint-lg-max |
xl-min |
--fds-breakpoint-xl-min |
xl-max |
--fds-breakpoint-xl-max |
xxl-min |
--fds-breakpoint-xxl-min |
xxs-column |
--fds-breakpoint-column-xxs |
xs-column |
--fds-breakpoint-column-xs |
sm-column |
--fds-breakpoint-column-sm |
md-column |
--fds-breakpoint-column-md |
lg-column |
--fds-breakpoint-column-lg |
xl-column |
--fds-breakpoint-column-xl |
xxl-column |
--fds-breakpoint-column-xxl |
xxs-gutter |
--fds-breakpoint-gutter-xxs |
xs-gutter |
--fds-breakpoint-gutter-xs |
sm-gutter |
--fds-breakpoint-gutter-sm |
md-gutter |
--fds-breakpoint-gutter-md |
lg-gutter |
--fds-breakpoint-gutter-lg |
xl-gutter |
--fds-breakpoint-gutter-xl |
xxl-gutter |
--fds-breakpoint-gutter-xxl |
xxs-margin |
--fds-breakpoint-margin-xxs |
xs-margin |
--fds-breakpoint-margin-xs |
sm-margin |
--fds-breakpoint-margin-sm |
md-margin |
--fds-breakpoint-margin-md |
lg-margin |
--fds-breakpoint-margin-lg |
xl-margin |
--fds-breakpoint-margin-xl |
xxl-margin |
--fds-breakpoint-margin-xxl |
motion
| V3 | V4 |
|---|---|
duration-150 |
--fds-motion-duration-150 |
duration-250 |
--fds-motion-duration-250 |
duration-350 |
--fds-motion-duration-350 |
duration-500 |
--fds-motion-duration-500 |
duration-800 |
--fds-motion-duration-800 |
duration-1000 |
--fds-motion-duration-1000 |
ease-default |
--fds-motion-timing-ease-default |
ease-standard |
--fds-motion-timing-ease-standard |
ease-entrance |
--fds-motion-timing-ease-entrance |
ease-exit |
--fds-motion-timing-ease-exit |
spacing
| V3 | V4 |
|---|---|
spacing-0 |
--fds-spacing-0 |
spacing-4 |
--fds-spacing-4 |
spacing-8 |
--fds-spacing-8 |
spacing-12 |
--fds-spacing-12 |
spacing-16 |
--fds-spacing-16 |
spacing-20 |
--fds-spacing-20 |
spacing-24 |
--fds-spacing-24 |
spacing-32 |
--fds-spacing-32 |
spacing-40 |
--fds-spacing-40 |
spacing-48 |
--fds-spacing-48 |
spacing-64 |
--fds-spacing-64 |
spacing-72 |
--fds-spacing-72 |
layout-xs |
--fds-layout-xs |
layout-sm |
--fds-layout-sm |
layout-md |
--fds-layout-md |
layout-lg |
--fds-layout-lg |
layout-xl |
--fds-layout-xl |
layout-xxl |
--fds-layout-xxl |
layout-xxxl |
--fds-layout-xxxl |
border
| V3 | V4 |
|---|---|
width-005 |
--fds-border-width-005 |
width-010 |
--fds-border-width-010 |
width-020 |
--fds-border-width-020 |
width-040 |
--fds-border-width-040 |
solid |
--fds-border-style-solid |
radius
| V3 | V4 |
|---|---|
none |
--fds-radius-none |
xs |
--fds-radius-xs |
sm |
--fds-radius-sm |
md |
--fds-radius-md |
lg |
--fds-radius-lg |
full |
--fds-radius-full |
shadow
| V3 | V4 |
|---|---|
xs-subtle |
--fds-shadow-xs-subtle |
xs-strong |
--fds-shadow-xs-strong |
xs-focus-strong |
--fds-shadow-xs-focus-strong |
xs-error-strong |
--fds-shadow-xs-error-strong |
sm-subtle |
--fds-shadow-sm-subtle |
sm-strong |
--fds-shadow-sm-strong |
md-subtle |
--fds-shadow-md-subtle |
md-strong |
--fds-shadow-md-strong |
lg-subtle |
--fds-shadow-lg-subtle |
lg-strong |
--fds-shadow-lg-strong |
resourceScheme
Button
| V3 | V4 |
|---|---|
button-radius |
--fds-button-radius |
button-default-colour-bg |
--fds-button-default-colour-bg |
button-default-colour-bg-hover |
--fds-button-default-colour-bg-hover |
button-default-colour-text |
--fds-button-default-colour-text |
button-secondary-colour-border |
--fds-button-secondary-colour-border |
button-secondary-colour-text |
--fds-button-secondary-colour-text |
button-light-colour-text |
--fds-button-light-colour-text |
button-link-colour-text |
--fds-button-link-colour-text |
Animation
| V3 | V4 |
|---|---|
loading-dots-spinner-colour |
--fds-animation-loading-dots-spinner-colour |
Navbar
| V3 | V4 |
|---|---|
navbar-full-height |
--fds-navbar-full-height |
navbar-full-logo-height |
--fds-navbar-full-logo-height |
navbar-compressed-height |
--fds-navbar-compressed-height |
navbar-compressed-logo-height |
--fds-navbar-compressed-logo-height |
navbar-mobile-height |
--fds-navbar-mobile-height |
navbar-mobile-logo-height |
--fds-navbar-mobile-logo-height |
navbar-colour-bg |
--fds-navbar-colour-bg |
navbar-colour-icon |
--fds-navbar-colour-icon |
navbar-link-colour-text |
--fds-navbar-link-colour-text |
navbar-link-colour-text-hover |
--fds-navbar-link-colour-text-hover |
navbar-link-colour-text-selected-hover |
--fds-navbar-link-colour-text-selected-hover |
Footer
| V3 | V4 |
|---|---|
footer-colour-bg |
--fds-footer-colour-bg |
footer-colour-text |
--fds-footer-colour-text |
footer-link-colour-text |
--fds-footer-link-colour-text |
footer-link-colour-text-hover |
--fds-footer-link-colour-text-hover |
footer-disclaimer-link-colour-text |
--fds-footer-disclaimer-link-colour-text |
footer-disclaimer-link-colour-text-hover |
--fds-footer-disclaimer-link-colour-text-hover |
V4 restricts imports to the root @lifesg/react-design-system or pre-defined subpath entrypoints i.e. @lifesg/react-design-system/<component>. Internal file paths that were previously accessible (e.g. deep imports into @lifesg/react-design-system/<component>/*) are no longer reachable.
If you were importing a type directly from an internal path, update it to use the nearest public entrypoint instead:
- import type { AlertProps } from "@lifesg/react-design-system/alert/types";
+ import type { AlertProps } from "@lifesg/react-design-system/alert";If the type you need is not yet exported from any public entrypoint, raise a PR to expose it.
Border.Util has been removed. For dashed border styling, use the DashedBorder utility component instead.
V3 usage
Border.Util["dashed-default"] could be applied directly in Styled Components declarations.
import { Border } from "@lifesg/react-design-system/theme";
const ExampleComponent = styled.div`
${Border.Util["dashed-default"]({
radius: Radius["sm"],
thickness: Border["width-040"],
colour: Colour["border"],
})}
`;V4 usage
A generic utility component is provided.
import { DashedBorder } from "@lifesg/react-design-system/dashed-border";
<DashedBorder
radius={Radius["sm"]}
thickness={Border["width-040"]}
colour={Colour["border"]}
>
{/* original children here */}
</DashedBorder>;Button.Default, Button.Small and Button.Large have been deprecated. Use Button with the sizeType prop instead.
- <Button.Large>Click me</Button.Large>
- <Button.Small>Click me</Button.Small>
- <Button.Default>Click me</Button.Default>
+ <Button sizeType="large">Click me</Button>
+ <Button sizeType="small">Click me</Button>
+ <Button>Click me</Button>| Deprecated |
sizeType value |
|---|---|
Button.Large |
large |
Button.Small |
small |
Button.Default |
default (or omit) |
ButtonWithIcon has been merged into Button. Update the import and replace the component.
- import { ButtonWithIcon } from "@lifesg/react-design-system/button-with-icon";
+ import { Button } from "@lifesg/react-design-system/button";
- <ButtonWithIcon icon={<Icon />}>Label</ButtonWithIcon>
+ <Button icon={<Icon />}>Label</Button>DSThemeProvider has been removed. Replace with the new ThemeProvider. See ThemeProvider.
ErrorDisplay.ImagePathAttributes has been renamed to ErrorDisplayImagePathAttributes.
- import { ErrorDisplay } from "@lifesg/react-design-system/error-display";
- type MyProps = ErrorDisplay.ImagePathAttributes;
+ import { ErrorDisplayImagePathAttributes } from "@lifesg/react-design-system/error-display";
+ type MyProps = ErrorDisplayImagePathAttributes;IconButton has been merged into Button. Update the import and replace the component.
- import { IconButton } from "@lifesg/react-design-system/icon-button";
+ import { Button } from "@lifesg/react-design-system/button";
- <IconButton icon={<Icon />} />
+ <Button icon={<Icon />} />The underlying baseTextSize prop type has been moved from the internal TypographySizeType to FontSize.
- import type { TypographySizeType } from "@lifesg/react-design-system/theme/font/types";
+ import type { FontSize } from "@lifesg/react-design-system/theme";The accepted values are unchanged:
"heading-xxl" | "heading-xl" | "heading-lg" | "heading-md" | "heading-sm" | "heading-xs"
| "body-baseline" | "body-md" | "body-sm" | "body-xs"
The underlying size prop type has been moved from the internal TypographySizeType to TextListSize.
- import type { TypographySizeType } from "@lifesg/react-design-system/theme/font/types";
+ import type { TextListSize } from "@lifesg/react-design-system/text-list";The accepted values are unchanged:
"heading-xxl" | "heading-xl" | "heading-lg" | "heading-md" | "heading-sm" | "heading-xs"
| "body-baseline" | "body-md" | "body-sm" | "body-xs"
Removed disabled prop
Removed disabled prop