-
Notifications
You must be signed in to change notification settings - Fork 13
Migration to V3 (WIP)
npm i @lifesg/react-design-system@latest
+ 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
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.
- 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>
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 {}
}
- Migrate deprecated imports
Color
has been deprecatedTextStyleHelper
has been deprecatedText
has been deprecated- Removed
!important
from font styles MediaWidths
has been deprecatedMediaQuery
has been deprecated- Change to
ResourceScheme
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";
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.
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
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
V2 usage
import { TextStyleHelper } from "@lifesg/react-design-system/text";
export const ExampleComponent = styled.div`
${TextStyleHelper.getTextStyle("Body", "semibold")}
`
V3 usage
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
`
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
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
This makes inheritance easier when using the typography tokens or components. Do make sure that your existing page design remains unaffected.
V2 usage
import { MediaWidths } from "@lifesg/react-design-system/media";
useMediaQuery({ maxWidth: MediaWidths.mobileL });
V3 usage
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
V2 usage
V3 usage
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 |
base
has been renamed to lifesg
.
V2 usage
<ErrorDisplay illustrationScheme="base" />
<TimeTable illustrationScheme="base" />
V3 usage
<ErrorDisplay illustrationScheme="lifesg" />
<TimeTable illustrationScheme="lifesg" />
- 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 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;
};
}
}