From 6c63b52c93b9a41d5ae3b9e2646de8eb0063ed3b Mon Sep 17 00:00:00 2001 From: Masoud Amjadi Date: Fri, 16 Feb 2024 21:17:22 -0500 Subject: [PATCH] feat(defaulttheme): import all figma design tokens into defaultTheme --- .../components/src/core/Accordion/style.ts | 2 +- .../src/core/ButtonIcon/index.stories.tsx | 4 +- .../src/core/Foundations/index.stories.tsx | 8 +- .../components/src/core/Foundations/style.ts | 39 ++ .../core/LoadingIndicator/index.stories.tsx | 4 +- .../src/core/styles/common/SDSAppTheme.ts | 394 +++++++++++++ .../core/styles/common/constants/spaces.ts | 8 +- .../src/core/styles/common/defaultTheme.ts | 553 +----------------- .../core/styles/common/defaultThemeTypes.ts | 157 ----- .../core/styles/common/makeThemeOptions.ts | 297 ++++++++++ .../src/core/styles/common/mixins/fonts.ts | 86 ++- .../src/core/styles/common/selectors/theme.ts | 2 +- .../src/core/styles/common/types.ts | 320 ++++++++++ packages/components/src/core/styles/index.ts | 1 + 14 files changed, 1132 insertions(+), 743 deletions(-) create mode 100644 packages/components/src/core/Foundations/style.ts create mode 100644 packages/components/src/core/styles/common/SDSAppTheme.ts delete mode 100644 packages/components/src/core/styles/common/defaultThemeTypes.ts create mode 100644 packages/components/src/core/styles/common/makeThemeOptions.ts create mode 100644 packages/components/src/core/styles/common/types.ts diff --git a/packages/components/src/core/Accordion/style.ts b/packages/components/src/core/Accordion/style.ts index ec2d2bcf2..b2a3cb367 100644 --- a/packages/components/src/core/Accordion/style.ts +++ b/packages/components/src/core/Accordion/style.ts @@ -32,7 +32,7 @@ export const StyledAccordion = styled(Accordion, { return css` &.MuiAccordion-root { box-shadow: ${shadows?.none}; - font-family: ${typography?.styles?.body?.s?.fontFamily}; + font-family: ${typography?.fontFamily?.body}; border-bottom: ${useDivider ? border?.gray[300] : "none"}; height: fit-content; diff --git a/packages/components/src/core/ButtonIcon/index.stories.tsx b/packages/components/src/core/ButtonIcon/index.stories.tsx index cac65b3ed..8c809303c 100644 --- a/packages/components/src/core/ButtonIcon/index.stories.tsx +++ b/packages/components/src/core/ButtonIcon/index.stories.tsx @@ -1,11 +1,11 @@ import { Args, Meta } from "@storybook/react"; import React from "react"; -import { defaultAppTheme } from "../styles"; import RawButtonIcon from "./index"; import { ButtonIconExtraProps, ButtonIconSizeToTypes } from "./style"; import CustomSvgIcon from "src/common/customSvgIcon"; import CustomSdsIcon from "src/common/customSdsIcon"; import { BADGE } from "@geometricpanda/storybook-addon-badges"; +import { SDSAppTheme } from "../styles"; type SDSTypes = NonNullable< | ButtonIconExtraProps<"small">["sdsType"] @@ -107,7 +107,7 @@ export const Default = { // Live Preview const LivePreviewDemo = (): JSX.Element => { - const spacings = defaultAppTheme?.spacing; + const spacings = SDSAppTheme?.spacing; const livePreviewStyles: React.CSSProperties = { alignItems: "center", diff --git a/packages/components/src/core/Foundations/index.stories.tsx b/packages/components/src/core/Foundations/index.stories.tsx index 8f48c57fd..e4ea7cddf 100644 --- a/packages/components/src/core/Foundations/index.stories.tsx +++ b/packages/components/src/core/Foundations/index.stories.tsx @@ -1,8 +1,14 @@ import { Args, Meta } from "@storybook/react"; import { BADGE } from "../../common/SDSBadges"; +import { StyledDiv, StyledSpan } from "./style"; const DesignTokens = (props: Args): JSX.Element => { - return

Design Tokens go here

; + return ( + + Design Tokens go here + 12343430032 + + ); }; export default { diff --git a/packages/components/src/core/Foundations/style.ts b/packages/components/src/core/Foundations/style.ts new file mode 100644 index 000000000..b6ab1ba3f --- /dev/null +++ b/packages/components/src/core/Foundations/style.ts @@ -0,0 +1,39 @@ +import { styled } from "@mui/material"; +import { + fontCodeXs, + fontTabularXs, + getCorners, + getPalette, + getSpaces, +} from "../styles"; + +export const StyledDiv = styled("div")` + ${fontCodeXs}; + + ${(props) => { + const palette = getPalette(props); + const spaces = getSpaces(props); + const corners = getCorners(props); + + return ` + display: flex; + justify-content: space-between; + background-color: ${palette?.component?.notice?.fill}; + color: ${palette?.component?.notice?.fillOnFill}; + padding: ${spaces?.s}px; + border-radius: ${corners?.m}px; + + &:hover { + background-color: ${palette?.component?.notice?.fillHover}; + } + + &:active { + background-color: ${palette?.component?.notice?.fillPressed}; + } + `; + }}; +`; + +export const StyledSpan = styled("span")` + ${fontTabularXs}; +`; diff --git a/packages/components/src/core/LoadingIndicator/index.stories.tsx b/packages/components/src/core/LoadingIndicator/index.stories.tsx index 795ba5aa7..4c7866568 100644 --- a/packages/components/src/core/LoadingIndicator/index.stories.tsx +++ b/packages/components/src/core/LoadingIndicator/index.stories.tsx @@ -1,6 +1,6 @@ import { Args, Meta } from "@storybook/react"; import React from "react"; -import { defaultAppTheme } from "../styles"; +import { SDSAppTheme } from "../styles"; import RawLoadingIndicator from "./index"; import { BADGE } from "@geometricpanda/storybook-addon-badges"; @@ -41,7 +41,7 @@ export const CustomAriaLabel = { // Live Preview const LivePreviewDemo = (props: Args): JSX.Element => { - const spacings = defaultAppTheme?.spacing; + const spacings = SDSAppTheme?.spacing; const livePreviewStyles = { display: "grid", diff --git a/packages/components/src/core/styles/common/SDSAppTheme.ts b/packages/components/src/core/styles/common/SDSAppTheme.ts new file mode 100644 index 000000000..10e99ce2c --- /dev/null +++ b/packages/components/src/core/styles/common/SDSAppTheme.ts @@ -0,0 +1,394 @@ +import { AppTheme } from "./types"; + +const fontFamily = '"Inter", sans-serif'; +const fontFamilyCode = '"IBM Plex Mono", monospace'; +const tabularNums = "tabular-nums"; + +enum FontWeight { + bold = 700, + light = 300, + medium = 500, + regular = 400, + semibold = 600, +} + +const SDSThemeColors = { + blue: { + "100": "#F5F9FF", + "200": "#E9F1FF", + "300": "#A6C9FF", + "400": "#0B68F8", + "500": "#0142A4", + "600": "#002660", + }, + common: { + black: "#000000", + white: "#FFFFFF", + }, + gray: { + "100": "#F8F8F8", + "200": "#EAEAEA", + "300": "#CCCCCC", + "400": "#999999", + "500": "#767676", + "600": "#545454", + }, + green: { + "100": "#ECF5F0", + "200": "#E6F7ED", + "300": "transparent", + "400": "#3CB371", + "500": "#349A61", + "600": "#1C7F48", + }, + purple: { + "100": "#F4F0F9", + "200": "#F0EBF6", + "300": "transparent", + "400": "#7A41CE", + "500": "#703CBE", + "600": "#693BAC", + }, + red: { + "100": "#FEF2F2", + "200": "#FBE8E8", + "300": "transparent", + "400": "#DC132C", + "500": "#C61128", + "600": "#B70016", + }, + yellow: { + "100": "#FCF6EC", + "200": "#FFF3E1", + "300": "transparent", + "400": "#F5A623", + "500": "#D8921F", + "600": "#946314", + }, +}; + +export const SDSAppTheme: AppTheme = { + colors: SDSThemeColors, + corners: { + l: 20, + m: 4, + none: 0, + s: 2, + }, + fontWeights: { + regular: 400, + semibold: 600, + }, + iconSizes: { + // for use with input icons only (radio and checkbox) + input: { height: 16, width: 16 }, + l: { height: 24, width: 24 }, + s: { height: 16, width: 16 }, + xl: { height: 32, width: 32 }, + xs: { height: 12, width: 12 }, + }, + shadows: { + l: "0 2px 12px 0 rgba(0,0,0, 0.3)", + m: "0 2px 4px 0 rgba(0,0,0, 0.15), 0 2px 10px 0 rgba(0,0,0, 0.15)", + none: "none", + s: "0 2px 4px 0 rgba(0,0,0, 0.25)", + }, + spacing: { + default: 12, + l: 16, + m: 12, + s: 8, + xl: 24, + xs: 6, + xxl: 40, + xxs: 4, + xxxs: 2, + }, + typography: { + fontFamily: { + body: fontFamily, + caps: fontFamily, + code: fontFamilyCode, + header: fontFamily, + tabular: fontFamily, + }, + styles: { + body: { + regular: { + button: { + fontSize: 13, + fontWeight: FontWeight.regular, + letterSpacing: "0.08px", + lineHeight: "20px", + textTransform: "none", + }, + l: { + fontSize: 18, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "28px", + }, + m: { + fontSize: 16, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "26px", + }, + s: { + fontSize: 14, + fontWeight: FontWeight.regular, + letterSpacing: "0.08px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontWeight: FontWeight.regular, + letterSpacing: "0.08px", + lineHeight: "20px", + }, + xxs: { + fontSize: 12, + fontWeight: FontWeight.regular, + letterSpacing: "0.1px", + lineHeight: "18px", + }, + xxxs: { + fontSize: 11, + fontWeight: FontWeight.regular, + letterSpacing: "0.1px", + lineHeight: "16px", + }, + }, + semibold: { + button: { + fontSize: 13, + fontWeight: FontWeight.semibold, + letterSpacing: "0.08px", + lineHeight: "20px", + textTransform: "none", + }, + l: { + fontSize: 18, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "28px", + }, + m: { + fontSize: 16, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "26px", + }, + s: { + fontSize: 14, + fontWeight: FontWeight.semibold, + letterSpacing: "0.08px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontWeight: FontWeight.semibold, + letterSpacing: "0.08px", + lineHeight: "20px", + }, + xxs: { + fontSize: 12, + fontWeight: FontWeight.semibold, + letterSpacing: "0.1px", + lineHeight: "18px", + }, + xxxs: { + fontSize: 11, + fontWeight: FontWeight.semibold, + letterSpacing: "0.1px", + lineHeight: "16px", + }, + }, + }, + caps: { + semibold: { + xxs: { + fontSize: 12, + fontWeight: FontWeight.semibold, + letterSpacing: "0.5px", + lineHeight: "18px", + textTransform: "uppercase", + }, + xxxs: { + fontSize: 11, + fontWeight: FontWeight.semibold, + letterSpacing: "0.5px", + lineHeight: "16px", + textTransform: "uppercase", + }, + xxxxs: { + fontSize: 10, + fontWeight: FontWeight.semibold, + letterSpacing: "0.5px", + lineHeight: "14px", + textTransform: "uppercase", + }, + }, + }, + code: { + regular: { + s: { + fontSize: 14, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "20px", + }, + }, + semibold: { + s: { + fontSize: 14, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "20px", + }, + }, + }, + header: { + semibold: { + l: { + fontSize: 18, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "24px", + }, + m: { + fontSize: 16, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "22px", + }, + s: { + fontSize: 14, + fontWeight: FontWeight.semibold, + letterSpacing: "0.08px", + lineHeight: "20px", + }, + xl: { + fontSize: 22, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "30px", + }, + xs: { + fontSize: 13, + fontWeight: FontWeight.semibold, + letterSpacing: "0.08px", + lineHeight: "18px", + }, + xxl: { + fontSize: 26, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "34px", + }, + xxs: { + fontSize: 12, + fontWeight: FontWeight.semibold, + letterSpacing: "0.1px", + lineHeight: "18px", + }, + xxxs: { + fontSize: 11, + fontWeight: FontWeight.semibold, + letterSpacing: "0.1px", + lineHeight: "16px", + }, + }, + }, + tabular: { + regular: { + s: { + fontSize: 14, + fontVariantNumeric: tabularNums, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontVariantNumeric: tabularNums, + fontWeight: FontWeight.regular, + letterSpacing: "0px", + lineHeight: "20px", + }, + }, + semibold: { + s: { + fontSize: 14, + fontVariantNumeric: tabularNums, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "24px", + }, + xs: { + fontSize: 13, + fontVariantNumeric: tabularNums, + fontWeight: FontWeight.semibold, + letterSpacing: "0px", + lineHeight: "20px", + }, + }, + }, + }, + }, +}; + +// (mlila) whenever our theme uses colors, we need to make sure we allow consuming +// applications to override those colors using their own custom theme. +// By defining borders using SDSAppTheme.colors instead of defaultThemeColors, +// we allow other apps to specify their colors once, and have them apply +// throughout the application, such as in borders, etc without having to manually +// override every theme property that makes use of colors. +SDSAppTheme.borders = { + accent: { + "300": `1px solid ${SDSAppTheme.colors.blue[300]}`, + "400": `1px solid ${SDSAppTheme.colors.blue[400]}`, + "500": `1px solid ${SDSAppTheme.colors.blue[500]}`, + "600": `1px solid${SDSAppTheme.colors.blue[600]}`, + dashed: `2px dashed ${SDSAppTheme.colors.blue[400]}`, + }, + base: { + "100": `1px solid ${SDSAppTheme.colors.gray[100]}`, + "200": `1px solid ${SDSAppTheme.colors.gray[200]}`, + "300": `1px solid ${SDSAppTheme.colors.gray[300]}`, + "400": `1px solid ${SDSAppTheme.colors.gray[400]}`, + "500": `1px solid ${SDSAppTheme.colors.gray[500]}`, + dashed: `2px dashed ${SDSAppTheme.colors.gray[400]}`, + }, + beta: { + "400": `1px solid ${SDSAppTheme.colors.purple[400]}`, + }, + info: { + "400": `1px solid ${SDSAppTheme.colors.blue[400]}`, + }, + link: { + dashed: `1px dashed`, + solid: `1px solid`, + }, + negative: { + "400": `1px solid ${SDSAppTheme.colors.red[400]}`, + }, + notice: { + "400": `1px solid ${SDSAppTheme.colors.yellow[400]}`, + }, + positive: { + "400": `1px solid ${SDSAppTheme.colors.green[400]}`, + }, +}; diff --git a/packages/components/src/core/styles/common/constants/spaces.ts b/packages/components/src/core/styles/common/constants/spaces.ts index 44fe6294d..55bc1dc9e 100644 --- a/packages/components/src/core/styles/common/constants/spaces.ts +++ b/packages/components/src/core/styles/common/constants/spaces.ts @@ -3,9 +3,9 @@ export enum Spaces { XXS = "4px", XS = "6px", S = "8px", - M = "10px", - L = "14px", - XL = "22px", - XXL = "38px", + M = "12px", + L = "16px", + XL = "24px", + XXL = "40px", DEFAULT = M, } diff --git a/packages/components/src/core/styles/common/defaultTheme.ts b/packages/components/src/core/styles/common/defaultTheme.ts index 1d89387af..395055be2 100644 --- a/packages/components/src/core/styles/common/defaultTheme.ts +++ b/packages/components/src/core/styles/common/defaultTheme.ts @@ -1,551 +1,8 @@ -import { colors } from "@mui/material"; import { createTheme } from "@mui/material/styles"; -import { AppTheme, SDSThemeOptions } from "./defaultThemeTypes"; +import { SDSThemeOptions } from "./types"; +import { SDSAppTheme } from "./SDSAppTheme"; +import { makeThemeOptions } from "./makeThemeOptions"; -const createThemeAdaptor = createTheme; +const defaultThemeOptions: SDSThemeOptions = makeThemeOptions(SDSAppTheme); -const { common } = colors; - -const fontFamilyCode = '"IBM Plex Mono", monospace'; -const tabularNums = "tabular-nums"; - -enum FontWeight { - bold = 700, - light = 300, - medium = 500, - regular = 400, - semibold = 600, -} - -const defaultThemeColors = { - blue: { - "100": "#F5F9FF", - "200": "#E9F1FF", - "300": "#A6C9FF", - "400": "#0B68F8", - "500": "#0142A4", - "600": "#002660", - }, - gray: { - "100": "#F8F8F8", - "200": "#EAEAEA", - "300": "#CCCCCC", - "400": "#999999", - "500": "#767676", - "600": "#545454", - }, - green: { - "100": "#ECF5F0", - "200": "#E6F7ED", - "400": "#3CB371", - "500": "#349A61", - "600": "#1C7F48", - }, - purple: { - "100": "#F4F0F9", - "200": "#F0EBF6", - "400": "#7A41CE", - "500": "#703CBE", - "600": "#693BAC", - }, - red: { - "100": "#FEF2F2", - "200": "#FBE8E8", - "400": "#DC132C", - "500": "#C61128", - "600": "#B70016", - }, - yellow: { - "100": "#FCF6EC", - "200": "#FFF3E1", - "400": "#F5A623", - "500": "#D8921F", - "600": "#946314", - }, -}; - -export const defaultAppTheme: AppTheme = { - colors: defaultThemeColors, - corners: { - l: 20, - m: 4, - none: 0, - s: 2, - }, - fontWeights: { - regular: 400, - semibold: 600, - }, - iconSizes: { - // for use with input icons only (radio and checkbox) - input: { height: 16, width: 16 }, - l: { height: 24, width: 24 }, - s: { height: 16, width: 16 }, - xl: { height: 32, width: 32 }, - xs: { height: 12, width: 12 }, - }, - shadows: { - l: "0 2px 12px 0 rgba(0,0,0, 0.3)", - m: "0 2px 4px 0 rgba(0,0,0, 0.15), 0 2px 10px 0 rgba(0,0,0, 0.15)", - none: "none", - s: "0 2px 4px 0 rgba(0,0,0, 0.25)", - }, - spacing: { - default: 12, - l: 16, - m: 12, - s: 8, - xl: 24, - xs: 6, - xxl: 40, - xxs: 4, - xxxs: 2, - }, - typography: { - styles: { - body: { - button: { - fontFamily: "Inter", - fontSize: 13, - fontWeight: FontWeight.regular, - letterSpacing: "0.08px", - lineHeight: "20px", - textTransform: "none", - }, - l: { - fontFamily: "Inter", - fontSize: 18, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "28px", - }, - m: { - fontFamily: "Inter", - fontSize: 16, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "26px", - }, - s: { - fontFamily: "Inter", - fontSize: 14, - fontWeight: FontWeight.regular, - letterSpacing: "0.08px", - lineHeight: "24px", - }, - xs: { - fontFamily: "Inter", - fontSize: 13, - fontWeight: FontWeight.regular, - letterSpacing: "0.08px", - lineHeight: "20px", - }, - xxs: { - fontFamily: "Inter", - fontSize: 12, - fontWeight: FontWeight.regular, - letterSpacing: "0.1px", - lineHeight: "18px", - }, - xxxs: { - fontFamily: "Inter", - fontSize: 11, - fontWeight: FontWeight.regular, - letterSpacing: "0.1px", - lineHeight: "16px", - }, - }, - body2: { - button: { - fontFamily: "Inter", - fontSize: 13, - fontWeight: FontWeight.semibold, - letterSpacing: "0.08px", - lineHeight: "20px", - textTransform: "none", - }, - l: { - fontFamily: "Inter", - fontSize: 18, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "28px", - }, - m: { - fontFamily: "Inter", - fontSize: 16, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "26px", - }, - s: { - fontFamily: "Inter", - fontSize: 14, - fontWeight: FontWeight.semibold, - letterSpacing: "0.08px", - lineHeight: "24px", - }, - xs: { - fontFamily: "Inter", - fontSize: 13, - fontWeight: FontWeight.semibold, - letterSpacing: "0.08px", - lineHeight: "20px", - }, - xxs: { - fontFamily: "Inter", - fontSize: 12, - fontWeight: FontWeight.semibold, - letterSpacing: "0.1px", - lineHeight: "18px", - }, - xxxs: { - fontFamily: "Inter", - fontSize: 11, - fontWeight: FontWeight.semibold, - letterSpacing: "0.1px", - lineHeight: "16px", - }, - }, - caps: { - xxs: { - fontFamily: "Inter", - fontSize: 12, - fontWeight: FontWeight.semibold, - letterSpacing: "0.5px", - lineHeight: "18px", - textTransform: "uppercase", - }, - xxxs: { - fontFamily: "Inter", - fontSize: 11, - fontWeight: FontWeight.semibold, - letterSpacing: "0.5px", - lineHeight: "16px", - textTransform: "uppercase", - }, - xxxxs: { - fontFamily: "Inter", - fontSize: 10, - fontWeight: FontWeight.semibold, - letterSpacing: "0.5px", - lineHeight: "14px", - textTransform: "uppercase", - }, - }, - code: { - s: { - fontFamily: fontFamilyCode, - fontSize: 14, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "24px", - }, - xs: { - fontFamily: fontFamilyCode, - fontSize: 13, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "20px", - }, - }, - code2: { - s: { - fontFamily: fontFamilyCode, - fontSize: 14, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "24px", - }, - xs: { - fontFamily: fontFamilyCode, - fontSize: 13, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "20px", - }, - }, - header: { - l: { - fontFamily: "Inter", - fontSize: 18, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "24px", - }, - m: { - fontFamily: "Inter", - fontSize: 16, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "22px", - }, - s: { - fontFamily: "Inter", - fontSize: 14, - fontWeight: FontWeight.semibold, - letterSpacing: "0.08px", - lineHeight: "20px", - }, - xl: { - fontFamily: "Inter", - fontSize: 22, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "30px", - }, - xs: { - fontFamily: "Inter", - fontSize: 13, - fontWeight: FontWeight.semibold, - letterSpacing: "0.08px", - lineHeight: "18px", - }, - xxl: { - fontFamily: "Inter", - fontSize: 26, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "34px", - }, - xxs: { - fontFamily: "Inter", - fontSize: 12, - fontWeight: FontWeight.semibold, - letterSpacing: "0.1px", - lineHeight: "18px", - }, - xxxs: { - fontFamily: "Inter", - fontSize: 11, - fontWeight: FontWeight.semibold, - letterSpacing: "0.1px", - lineHeight: "16px", - }, - }, - tabular: { - s: { - fontFamily: "Inter", - fontSize: 14, - fontVariantNumeric: tabularNums, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "24px", - }, - xs: { - fontFamily: "Inter", - fontSize: 13, - fontVariantNumeric: tabularNums, - fontWeight: FontWeight.regular, - letterSpacing: "0px", - lineHeight: "20px", - }, - }, - tabular2: { - s: { - fontFamily: "Inter", - fontSize: 14, - fontVariantNumeric: tabularNums, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "24px", - }, - xs: { - fontFamily: "Inter", - fontSize: 13, - fontVariantNumeric: tabularNums, - fontWeight: FontWeight.semibold, - letterSpacing: "0px", - lineHeight: "20px", - }, - }, - }, - }, -}; - -// (mlila) whenever our theme uses colors, we need to make sure we allow consuming -// applications to override those colors using their own custom theme. -// By defining borders using defaultAppTheme.colors instead of defaultThemeColors, -// we allow other apps to specify their colors once, and have them apply -// throughout the application, such as in borders, etc without having to manually -// override every theme property that makes use of colors. -defaultAppTheme.borders = { - error: { - "400": `1px solid ${defaultAppTheme.colors.red[400]}`, - }, - gray: { - "100": `1px solid ${defaultAppTheme.colors.gray[100]}`, - "200": `1px solid ${defaultAppTheme.colors.gray[200]}`, - "300": `1px solid ${defaultAppTheme.colors.gray[300]}`, - "400": `1px solid ${defaultAppTheme.colors.gray[400]}`, - "500": `1px solid ${defaultAppTheme.colors.gray[500]}`, - dashed: `2px dashed ${defaultAppTheme.colors.gray[400]}`, - }, - link: { - dashed: `1px dashed`, - solid: `1px solid`, - }, - primary: { - "300": `1px solid ${defaultAppTheme.colors.blue[300]}`, - "400": `1px solid ${defaultAppTheme.colors.blue[400]}`, - "500": `1px solid ${defaultAppTheme.colors.blue[500]}`, - "600": `1px solid${defaultAppTheme.colors.blue[600]}`, - dashed: `2px dashed ${defaultAppTheme.colors.blue[400]}`, - }, - success: { - "400": `1px solid ${defaultAppTheme.colors.green[400]}`, - }, - warning: { - "400": `1px solid ${defaultAppTheme.colors.yellow[400]}`, - }, -}; - -export function makeThemeOptions(appTheme: AppTheme): SDSThemeOptions { - return { - app: appTheme, - components: { - MuiButtonBase: { - defaultProps: { - disableRipple: true, - }, - }, - MuiLink: { - defaultProps: { - underline: "hover", - }, - }, - MuiTab: { - defaultProps: { - disableRipple: true, - }, - }, - }, - palette: { - action: { - disabled: appTheme.colors.gray[400], - disabledBackground: appTheme.colors.gray[300], - }, - divider: appTheme.colors.gray[200], - error: { - dark: appTheme.colors.red[600], - light: appTheme.colors.red[200], - main: appTheme.colors.red[400], - }, - grey: { - "100": appTheme.colors.gray[100], - "200": appTheme.colors.gray[200], - "300": appTheme.colors.gray[300], - "400": appTheme.colors.gray[400], - "500": appTheme.colors.gray[500], - "600": appTheme.colors.gray[600], - }, - info: { - dark: appTheme.colors.blue[600], - light: appTheme.colors.blue[200], - main: appTheme.colors.blue[400], - }, - mode: "light", - primary: { - dark: appTheme.colors.blue[600], - light: appTheme.colors.blue[300], - main: appTheme.colors.blue[400], - }, - secondary: { - main: appTheme.colors.green[400], - }, - success: { - dark: appTheme.colors.green[600], - light: appTheme.colors.green[200], - main: appTheme.colors.green[400], - }, - text: { - disabled: appTheme.colors.gray[400], - primary: common.black, - secondary: appTheme.colors.gray[500], - }, - warning: { - dark: appTheme.colors.yellow[600], - light: appTheme.colors.yellow[200], - main: appTheme.colors.yellow[400], - }, - }, - shadows: [ - appTheme.shadows.none, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.s, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.m, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - appTheme.shadows.l, - ], - shape: { - borderRadius: appTheme.corners.m, - }, - spacing: [ - appTheme.spacing.default, - appTheme.spacing.xxxs, - appTheme.spacing.xxs, - appTheme.spacing.xs, - appTheme.spacing.s, - appTheme.spacing.m, - appTheme.spacing.l, - appTheme.spacing.xl, - appTheme.spacing.xxl, - ], - transitions: { - duration: { - complex: 200, - enteringScreen: 20, - leavingScreen: 10, - short: 150, - shorter: 100, - shortest: 50, - standard: 200, - }, - easing: { - easeIn: "cubic-bezier(0, 0, 0.2, 1)", - easeInOut: "cubic-bezier(0, 0, 0.2, 1)", - easeOut: "cubic-bezier(0.0, 0, 0.2, 1)", - sharp: "cubic-bezier(0, 0.2, 0.6, 1)", - }, - }, - typography: { - body1: appTheme.typography.styles.body.xs, - body2: appTheme.typography.styles.body.xxs, - button: appTheme.typography.styles.body.button, - caption: appTheme.typography.styles.body.xxxs, - fontFamily: `${appTheme.typography.styles.body.s.fontFamily}, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Helvetica, Arial, sans-serif`, - h1: appTheme.typography.styles.header.xxl, - h2: appTheme.typography.styles.header.xl, - h3: appTheme.typography.styles.header.l, - h4: appTheme.typography.styles.header.m, - h5: appTheme.typography.styles.header.s, - h6: appTheme.typography.styles.header.xs, - overline: appTheme.typography.styles.caps.xxxs, - subtitle1: appTheme.typography.styles.body.xs, - subtitle2: appTheme.typography.styles.header.xxs, - }, - }; -} - -const defaultThemeOptions: SDSThemeOptions = makeThemeOptions(defaultAppTheme); - -export const defaultTheme = createThemeAdaptor(defaultThemeOptions); +export const defaultTheme = createTheme(defaultThemeOptions); diff --git a/packages/components/src/core/styles/common/defaultThemeTypes.ts b/packages/components/src/core/styles/common/defaultThemeTypes.ts deleted file mode 100644 index 5ceb902d8..000000000 --- a/packages/components/src/core/styles/common/defaultThemeTypes.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Theme, ThemeOptions, TypographyStyle } from "@mui/material/styles"; - -export interface SDSTheme extends Theme { - app?: AppTheme; -} - -export interface SDSThemeOptions extends ThemeOptions { - app?: AppTheme; -} - -export interface AppTheme { - borders?: Borders; - colors: Colors; - corners: Corners; - fontWeights: FontWeights; - iconSizes: IconSizes; - shadows: Shadows; - spacing: Spacings; - typography: Typography; -} - -export interface Shadows { - none: "none"; - s: string; - m: string; - l: string; -} - -export interface Typography { - styles: { - header: { - xxl: TypographyStyle; - xl: TypographyStyle; - l: TypographyStyle; - m: TypographyStyle; - s: TypographyStyle; - xs: TypographyStyle; - xxs: TypographyStyle; - xxxs: TypographyStyle; - }; - body: { - button: TypographyStyle; - l: TypographyStyle; - m: TypographyStyle; - s: TypographyStyle; - xs: TypographyStyle; - xxs: TypographyStyle; - xxxs: TypographyStyle; - }; - body2: { - button: TypographyStyle; - l: TypographyStyle; - m: TypographyStyle; - s: TypographyStyle; - xs: TypographyStyle; - xxs: TypographyStyle; - xxxs: TypographyStyle; - }; - caps: { - xxs: TypographyStyle; - xxxs: TypographyStyle; - xxxxs: TypographyStyle; - }; - code: { - s: TypographyStyle; - xs: TypographyStyle; - }; - code2: { - s: TypographyStyle; - xs: TypographyStyle; - }; - tabular: { - s: TypographyStyle; - xs: TypographyStyle; - }; - tabular2: { - s: TypographyStyle; - xs: TypographyStyle; - }; - }; -} - -export interface FontWeights { - regular: number; - semibold: number; -} - -export interface Corners { - none: number; - s: number; - m: number; - l: number; -} - -export interface Spaces { - default: number; - xxxs: number; - xxs: number; - xs: number; - s: number; - m: number; - l: number; - xl: number; - xxl: number; -} -export type Spacings = Spaces; - -export interface Color { - 600?: string; - 500?: string; - 400: string; - 300?: string; - 200?: string; - 100?: string; -} - -export interface Colors { - blue: Color; - gray: Color; - green: Color; - purple: Color; - red: Color; - yellow: Color; -} - -export interface IconSize { - height: number; - width: number; -} - -export interface IconSizes { - xs: IconSize; - s: IconSize; - l: IconSize; - xl: IconSize; - input: IconSize; -} - -export interface Border { - 600?: string; - 500?: string; - 400?: string; - 300?: string; - 200?: string; - 100?: string; - dashed?: string; - solid?: string; -} - -export interface Borders { - error: Border; - gray: Border; - link: Border; - primary: Border; - success: Border; - warning: Border; -} diff --git a/packages/components/src/core/styles/common/makeThemeOptions.ts b/packages/components/src/core/styles/common/makeThemeOptions.ts new file mode 100644 index 000000000..c3d4def3d --- /dev/null +++ b/packages/components/src/core/styles/common/makeThemeOptions.ts @@ -0,0 +1,297 @@ +import { colors } from "@mui/material"; +import { AppTheme, SDSThemeOptions } from "./types"; + +const { common } = colors; + +/** + * This function creates the theme options for the MUI theme provider + */ +export function makeThemeOptions(appTheme: AppTheme): SDSThemeOptions { + return { + app: appTheme, + components: { + MuiButtonBase: { + defaultProps: { + disableRipple: true, + }, + }, + MuiLink: { + defaultProps: { + underline: "hover", + }, + }, + MuiTab: { + defaultProps: { + disableRipple: true, + }, + }, + }, + palette: { + action: { + disabled: appTheme.colors.gray[400], + disabledBackground: appTheme.colors.gray[300], + }, + component: { + accent: { + border: appTheme.colors.blue[400], + borderDisabled: appTheme.colors.blue[300], + borderFocus: appTheme.colors.blue[400], + borderHover: appTheme.colors.blue[500], + borderOpen: appTheme.colors.blue[400], + borderSelected: appTheme.colors.blue[400], + fill: appTheme.colors.blue[400], + fillDisabled: appTheme.colors.blue[300], + fillHover: appTheme.colors.blue[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.blue[600], + icon: appTheme.colors.blue[400], + surface: appTheme.colors.blue[200], + }, + base: { + border: appTheme.colors.gray[400], + borderDisabled: appTheme.colors.gray[300], + borderHover: appTheme.colors.common.black, + divider: appTheme.colors.gray[200], + fill: appTheme.colors.common.white, + fillDisabled: appTheme.colors.gray[300], + fillHover: appTheme.colors.gray[100], + fillOpen: appTheme.colors.gray[100], + fillPressed: appTheme.colors.gray[100], + fillSelected: appTheme.colors.common.black, + icon: appTheme.colors.gray[500], + iconDisabled: appTheme.colors.gray[300], + iconHover: appTheme.colors.common.black, + iconPressed: appTheme.colors.common.black, + onFillDisabled: appTheme.colors.gray[400], + surfacePrimary: appTheme.colors.common.white, + surfaceSecondary: appTheme.colors.gray[100], + surfaceTertiary: appTheme.colors.gray[200], + }, + beta: { + border: appTheme.colors.purple[400], + fill: appTheme.colors.purple[400], + fillHover: appTheme.colors.purple[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.purple[600], + icon: appTheme.colors.purple[400], + surface: appTheme.colors.purple[200], + }, + info: { + border: appTheme.colors.blue[400], + fill: appTheme.colors.blue[400], + fillHover: appTheme.colors.blue[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.blue[600], + icon: appTheme.colors.blue[400], + surface: appTheme.colors.blue[200], + }, + negative: { + border: appTheme.colors.red[400], + fill: appTheme.colors.red[400], + fillHover: appTheme.colors.red[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.red[600], + icon: appTheme.colors.red[400], + surface: appTheme.colors.red[200], + }, + notice: { + border: appTheme.colors.yellow[400], + fill: appTheme.colors.yellow[400], + fillHover: appTheme.colors.yellow[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.yellow[600], + icon: appTheme.colors.yellow[400], + surface: appTheme.colors.yellow[200], + }, + positive: { + border: appTheme.colors.green[400], + fill: appTheme.colors.green[400], + fillHover: appTheme.colors.green[500], + fillOnFill: appTheme.colors.common.white, + fillPressed: appTheme.colors.green[600], + icon: appTheme.colors.green[400], + surface: appTheme.colors.green[200], + }, + }, + divider: appTheme.colors.gray[200], + error: { + "100": appTheme.colors.red[100], + "200": appTheme.colors.red[200], + "300": appTheme.colors.red[300], + "400": appTheme.colors.red[400], + "500": appTheme.colors.red[500], + "600": appTheme.colors.red[600], + contrastText: common.white, + dark: appTheme.colors.red[600], + light: appTheme.colors.red[200], + main: appTheme.colors.red[400], + }, + grey: { + "100": appTheme.colors.gray[100], + "200": appTheme.colors.gray[200], + "300": appTheme.colors.gray[300], + "400": appTheme.colors.gray[400], + "500": appTheme.colors.gray[500], + "600": appTheme.colors.gray[600], + }, + info: { + "100": appTheme.colors.blue[100], + "200": appTheme.colors.blue[200], + "300": appTheme.colors.blue[300], + "400": appTheme.colors.blue[400], + "500": appTheme.colors.blue[500], + "600": appTheme.colors.blue[600], + contrastText: common.white, + dark: appTheme.colors.blue[600], + light: appTheme.colors.blue[200], + main: appTheme.colors.blue[400], + }, + mode: "light", + primary: { + "100": appTheme.colors.blue[100], + "200": appTheme.colors.blue[200], + "300": appTheme.colors.blue[300], + "400": appTheme.colors.blue[400], + "500": appTheme.colors.blue[500], + "600": appTheme.colors.blue[600], + contrastText: common.white, + dark: appTheme.colors.blue[600], + light: appTheme.colors.blue[200], + main: appTheme.colors.blue[400], + }, + secondary: { + "100": appTheme.colors.green[100], + "200": appTheme.colors.green[200], + "300": appTheme.colors.green[300], + "400": appTheme.colors.green[400], + "500": appTheme.colors.green[500], + "600": appTheme.colors.green[600], + contrastText: common.white, + dark: appTheme.colors.green[600], + light: appTheme.colors.green[200], + main: appTheme.colors.green[400], + }, + success: { + "100": appTheme.colors.green[100], + "200": appTheme.colors.green[200], + "300": appTheme.colors.green[300], + "400": appTheme.colors.green[400], + "500": appTheme.colors.green[500], + "600": appTheme.colors.green[600], + contrastText: common.white, + dark: appTheme.colors.green[600], + light: appTheme.colors.green[200], + main: appTheme.colors.green[400], + }, + text: { + action: { + default: appTheme.colors.blue[400], + hover: appTheme.colors.blue[500], + pressed: appTheme.colors.blue[600], + }, + base: { + accent: appTheme.colors.blue[600], + disabled: appTheme.colors.gray[300], + onFill: appTheme.colors.common.white, + onFillDisabled: appTheme.colors.gray[400], + primary: appTheme.colors.common.black, + secondary: appTheme.colors.gray[500], + }, + beta: appTheme.colors.purple[600], + disabled: appTheme.colors.gray[300], + info: appTheme.colors.blue[600], + negative: appTheme.colors.red[600], + notice: appTheme.colors.yellow[600], + positive: appTheme.colors.green[600], + primary: appTheme.colors.common.black, + secondary: appTheme.colors.gray[500], + }, + warning: { + "100": appTheme.colors.yellow[100], + "200": appTheme.colors.yellow[200], + "300": appTheme.colors.yellow[300], + "400": appTheme.colors.yellow[400], + "500": appTheme.colors.yellow[500], + "600": appTheme.colors.yellow[600], + contrastText: common.black, + dark: appTheme.colors.yellow[600], + light: appTheme.colors.yellow[200], + main: appTheme.colors.yellow[400], + }, + }, + shadows: [ + appTheme.shadows.none, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.s, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.m, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + appTheme.shadows.l, + ], + shape: { + borderRadius: appTheme.corners.m, + }, + spacing: [ + appTheme.spacing.default, + appTheme.spacing.xxxs, + appTheme.spacing.xxs, + appTheme.spacing.xs, + appTheme.spacing.s, + appTheme.spacing.m, + appTheme.spacing.l, + appTheme.spacing.xl, + appTheme.spacing.xxl, + ], + transitions: { + duration: { + complex: 200, + enteringScreen: 20, + leavingScreen: 10, + short: 150, + shorter: 100, + shortest: 50, + standard: 200, + }, + easing: { + easeIn: "cubic-bezier(0, 0, 0.2, 1)", + easeInOut: "cubic-bezier(0, 0, 0.2, 1)", + easeOut: "cubic-bezier(0.0, 0, 0.2, 1)", + sharp: "cubic-bezier(0, 0.2, 0.6, 1)", + }, + }, + typography: { + body1: appTheme.typography.styles.body.regular.xs, + body2: appTheme.typography.styles.body.regular.xxs, + button: appTheme.typography.styles.body.regular.button, + caption: appTheme.typography.styles.body.regular.xxxs, + fontFamily: `${appTheme.typography.fontFamily.body}, sans-serif`, + h1: appTheme.typography.styles.header.semibold.xxl, + h2: appTheme.typography.styles.header.semibold.xl, + h3: appTheme.typography.styles.header.semibold.l, + h4: appTheme.typography.styles.header.semibold.m, + h5: appTheme.typography.styles.header.semibold.s, + h6: appTheme.typography.styles.header.semibold.xs, + overline: appTheme.typography.styles.caps.semibold.xxxs, + subtitle1: appTheme.typography.styles.body.regular.xs, + subtitle2: appTheme.typography.styles.header.semibold.xxs, + }, + }; +} diff --git a/packages/components/src/core/styles/common/mixins/fonts.ts b/packages/components/src/core/styles/common/mixins/fonts.ts index 310562076..12b84168c 100644 --- a/packages/components/src/core/styles/common/mixins/fonts.ts +++ b/packages/components/src/core/styles/common/mixins/fonts.ts @@ -1,13 +1,16 @@ import { css, SerializedStyles } from "@emotion/react"; import { TypographyStyle } from "@mui/material"; -import { Typography } from "../defaultThemeTypes"; +import { Typography } from "../types"; import { CommonThemeProps, getTypography } from "../selectors/theme"; -// Font Body +type FontBodyWeight = keyof Typography["styles"]["body"]; +type FontBodySize = + keyof Typography["styles"]["body"][T]; -type FontBodySize = keyof Typography["styles"]["body"]; - -export const fontBody = (fontSize: FontBodySize) => { +export const fontBody = ( + fontSize: FontBodySize, + fontWeight: FontBodyWeight +) => { return (props: CommonThemeProps): SerializedStyles | null => { const typography = getTypography(props); @@ -15,22 +18,29 @@ export const fontBody = (fontSize: FontBodySize) => { const { styles: { body }, + fontFamily: { body: bodyFontFamily }, } = typography; - return themeToCss(body[fontSize]); + return themeToCss(body[fontWeight][fontSize], bodyFontFamily); }; }; -export const fontBodyL = fontBody("l"); -export const fontBodyM = fontBody("m"); -export const fontBodyS = fontBody("s"); -export const fontBodyXs = fontBody("xs"); -export const fontBodyXxs = fontBody("xxs"); -export const fontBodyXxxs = fontBody("xxxs"); +export const fontBodyL = fontBody("l", "regular"); +export const fontBodyM = fontBody("m", "regular"); +export const fontBodyS = fontBody("s", "regular"); +export const fontBodyXs = fontBody("xs", "regular"); +export const fontBodyXxs = fontBody("xxs", "regular"); +export const fontBodyXxxs = fontBody("xxxs", "regular"); +export const fontBodySemiboldL = fontBody("l", "semibold"); +export const fontBodySemiboldM = fontBody("m", "semibold"); +export const fontBodySemiboldS = fontBody("s", "semibold"); +export const fontBodySemiboldXs = fontBody("xs", "semibold"); +export const fontBodySemiboldXxs = fontBody("xxs", "semibold"); +export const fontBodySemiboldXxxs = fontBody("xxxs", "semibold"); // Font Caps -type FontCapsSize = keyof Typography["styles"]["caps"]; +type FontCapsSize = keyof Typography["styles"]["caps"]["semibold"]; export const fontCaps = (fontSize: FontCapsSize) => { return (props: CommonThemeProps): SerializedStyles | null => { @@ -40,10 +50,11 @@ export const fontCaps = (fontSize: FontCapsSize) => { const { styles: { caps }, + fontFamily: { caps: capsFontFamily }, } = typography; return css` - ${themeToCss(caps[fontSize])} + ${themeToCss(caps.semibold[fontSize], capsFontFamily)} text-transform: uppercase; `; }; @@ -55,7 +66,7 @@ export const fontCapsXxxxs = fontCaps("xxxxs"); // Font Header -type FontHeaderSize = keyof Typography["styles"]["header"]; +type FontHeaderSize = keyof Typography["styles"]["header"]["semibold"]; export const fontHeader = (fontSize: FontHeaderSize) => { return (props: CommonThemeProps): SerializedStyles | null => { @@ -65,9 +76,10 @@ export const fontHeader = (fontSize: FontHeaderSize) => { const { styles: { header }, + fontFamily: { header: headerFontFamily }, } = typography; - return themeToCss(header[fontSize]); + return themeToCss(header.semibold[fontSize], headerFontFamily); }; }; @@ -82,9 +94,14 @@ export const fontHeaderXxxs = fontHeader("xxxs"); // Font Code -type FontCodeSize = keyof Typography["styles"]["code"]; +type FontCodeWeight = keyof Typography["styles"]["code"]; +type FontCodeSize = + keyof Typography["styles"]["code"][T]; -export const fontCode = (fontSize: FontCodeSize) => { +export const fontCode = ( + fontSize: FontCodeSize, + fontWeight: FontCodeWeight +) => { return (props: CommonThemeProps): SerializedStyles | null => { const typography = getTypography(props); @@ -92,22 +109,30 @@ export const fontCode = (fontSize: FontCodeSize) => { const { styles: { code }, + fontFamily: { code: codeFontFamily }, } = typography; return css` - ${themeToCss(code[fontSize])} + ${themeToCss(code[fontWeight][fontSize], codeFontFamily)} `; }; }; -export const fontCodeXs = fontCode("xs"); -export const fontCodeS = fontCode("s"); +export const fontCodeXs = fontCode("xs", "regular"); +export const fontCodeS = fontCode("s", "regular"); +export const fontCodeSemiboldXs = fontCode("xs", "semibold"); +export const fontCodeSemiboldS = fontCode("s", "semibold"); // Font Tabular -type FontTabularSize = keyof Typography["styles"]["tabular"]; +type FontTabularWeight = keyof Typography["styles"]["tabular"]; +type FontTabularSize = + keyof Typography["styles"]["tabular"][T]; -export const fontTabular = (fontSize: FontTabularSize) => { +export const fontTabular = ( + fontSize: FontTabularSize, + fontWeight: FontTabularWeight +) => { return (props: CommonThemeProps): SerializedStyles | null => { const typography = getTypography(props); @@ -115,20 +140,27 @@ export const fontTabular = (fontSize: FontTabularSize) => { const { styles: { tabular }, + fontFamily: { tabular: tabularFontFamily }, } = typography; return css` - ${themeToCss(tabular[fontSize])} + ${themeToCss(tabular[fontWeight][fontSize], tabularFontFamily)} font-variant-numeric: "tabular-nums", `; }; }; -export const fontTabularXs = fontTabular("xs"); -export const fontTabularS = fontTabular("s"); +export const fontTabularXs = fontTabular("xs", "regular"); +export const fontTabularS = fontTabular("s", "regular"); +export const fontTabularSemiboldXs = fontTabular("xs", "semibold"); +export const fontTabularSemiboldS = fontTabular("s", "semibold"); -function themeToCss(fontTheme: TypographyStyle) { +function themeToCss( + fontTheme: TypographyStyle, + fontFamily: React.CSSProperties["fontFamily"] = "inherit" +) { return css` + font-family: ${fontFamily}; font-size: ${fontTheme.fontSize}px; line-height: ${fontTheme.lineHeight}; letter-spacing: ${fontTheme.letterSpacing}; diff --git a/packages/components/src/core/styles/common/selectors/theme.ts b/packages/components/src/core/styles/common/selectors/theme.ts index efa9d9adb..9a0285cd9 100644 --- a/packages/components/src/core/styles/common/selectors/theme.ts +++ b/packages/components/src/core/styles/common/selectors/theme.ts @@ -10,7 +10,7 @@ import { Spaces, Spacings, Typography, -} from "../defaultTheme"; +} from "../types"; // (thuang): Somehow this namespace needs to be globally unique to prevent // namespace collisions. diff --git a/packages/components/src/core/styles/common/types.ts b/packages/components/src/core/styles/common/types.ts new file mode 100644 index 000000000..69ed54931 --- /dev/null +++ b/packages/components/src/core/styles/common/types.ts @@ -0,0 +1,320 @@ +import { Theme, ThemeOptions, TypographyStyle } from "@mui/material/styles"; +import { CSSProperties } from "react"; + +/** + * (masoudmanson): The SDSComponentPalette is a custom palette based on + * the semantic design tokens for the SDS components. + */ +export interface SDSComponentPalette { + base: { + fill: string; + fillHover: string; + fillPressed: string; + fillOpen: string; + fillSelected: string; + fillDisabled: string; + onFillDisabled: string; + surfacePrimary: string; + surfaceSecondary: string; + surfaceTertiary: string; + divider: string; + border: string; + borderHover: string; + borderDisabled: string; + icon: string; + iconHover: string; + iconPressed: string; + iconDisabled: string; + }; + accent: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + fillDisabled: string; + surface: string; + border: string; + borderHover: string; + borderOpen: string; + borderFocus: string; + borderSelected: string; + borderDisabled: string; + icon: string; + }; + beta: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + surface: string; + border: string; + icon: string; + }; + info: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + surface: string; + border: string; + icon: string; + }; + negative: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + surface: string; + border: string; + icon: string; + }; + notice: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + surface: string; + border: string; + icon: string; + }; + positive: { + fill: string; + fillHover: string; + fillPressed: string; + fillOnFill: string; + surface: string; + border: string; + icon: string; + }; +} + +/** + * (masoudmanson): The SDSTextPalette is a custom palette based on the + * semantic design tokens for the SDS text based components. + */ +export interface SDSTextPalette { + base: { + primary: string; + secondary: string; + disabled: string; + onFill: string; + onFillDisabled: string; + accent: string; + }; + action: { + default: string; + hover: string; + pressed: string; + }; + beta: string; + info: string; + negative: string; + notice: string; + positive: string; +} + +/** + * (masoudmanson): Using module augmentation to extend the MUI Palette + * https://mui.com/material-ui/customization/palette/#typescript + */ +declare module "@mui/material/styles" { + // (masoudmanson): Extends the MUI TypeText to include the SDSTextPalette + export interface TypeText extends SDSTextPalette {} + + // (masoudmanson): Extends the MUI Palette to include the SDSComponentPalette and the SDSTextPalette + export interface Palette { + component: SDSComponentPalette; + text: TypeText; + } + + export interface PaletteOptions { + component?: SDSComponentPalette; + text?: Partial; + } +} + +export interface SDSTheme extends Theme { + app?: AppTheme; +} + +export interface SDSThemeOptions extends ThemeOptions { + app?: AppTheme; +} + +export interface AppTheme { + borders?: Borders; + colors: Colors; + corners: Corners; + fontWeights: FontWeights; + iconSizes: IconSizes; + shadows: Shadows; + spacing: Spacings; + typography: Typography; +} + +export interface Shadows { + none: "none"; + s: string; + m: string; + l: string; +} + +export interface Typography { + fontFamily: { + body: CSSProperties["fontFamily"]; + caps?: CSSProperties["fontFamily"]; + code?: CSSProperties["fontFamily"]; + header?: CSSProperties["fontFamily"]; + tabular?: CSSProperties["fontFamily"]; + }; + styles: { + body: { + regular: { + button: TypographyStyle; + l: TypographyStyle; + m: TypographyStyle; + s: TypographyStyle; + xs: TypographyStyle; + xxs: TypographyStyle; + xxxs: TypographyStyle; + }; + semibold: { + button: TypographyStyle; + l: TypographyStyle; + m: TypographyStyle; + s: TypographyStyle; + xs: TypographyStyle; + xxs: TypographyStyle; + xxxs: TypographyStyle; + }; + }; + caps: { + semibold: { + xxs: TypographyStyle; + xxxs: TypographyStyle; + xxxxs: TypographyStyle; + }; + }; + code: { + regular: { + s: TypographyStyle; + xs: TypographyStyle; + }; + semibold: { + s: TypographyStyle; + xs: TypographyStyle; + }; + }; + header: { + semibold: { + xxl: TypographyStyle; + xl: TypographyStyle; + l: TypographyStyle; + m: TypographyStyle; + s: TypographyStyle; + xs: TypographyStyle; + xxs: TypographyStyle; + xxxs: TypographyStyle; + }; + }; + tabular: { + regular: { + s: TypographyStyle; + xs: TypographyStyle; + }; + semibold: { + s: TypographyStyle; + xs: TypographyStyle; + }; + }; + }; +} + +export interface FontWeights { + regular: number; + semibold: number; +} + +export interface Corners { + none: number; + s: number; + m: number; + l: number; +} + +export interface Spaces { + default: number; + xxxs: number; + xxs: number; + xs: number; + s: number; + m: number; + l: number; + xl: number; + xxl: number; +} + +/** + * @deprecated + * + * (masoudmanson): The Spacings type is an alias for the Spaces type and + * is deprecated. It is recommended to use the Spaces type instead. + */ +export type Spacings = Spaces; + +export interface Color { + 600: string; + 500: string; + 400: string; + 300: string; + 200: string; + 100: string; +} + +export interface Colors { + common: { + white: string; + black: string; + }; + blue: Color; + gray: Color; + green: Color; + purple: Color; + red: Color; + yellow: Color; +} + +export interface IconSize { + height: number; + width: number; +} + +export interface IconSizes { + xs: IconSize; + s: IconSize; + l: IconSize; + xl: IconSize; + input: IconSize; +} + +export interface Border { + 600?: string; + 500?: string; + 400?: string; + 300?: string; + 200?: string; + 100?: string; + dashed?: string; + solid?: string; +} + +export interface Borders { + accent: Border; + base: Border; + beta: Border; + info: Border; + link: Border; + negative: Border; + notice: Border; + positive: Border; +} diff --git a/packages/components/src/core/styles/index.ts b/packages/components/src/core/styles/index.ts index 88785684d..699d6a96e 100644 --- a/packages/components/src/core/styles/index.ts +++ b/packages/components/src/core/styles/index.ts @@ -1,4 +1,5 @@ export * from "./common/defaultTheme"; +export * from "./common/SDSAppTheme"; export * from "./common/mixins/a11y"; export * from "./common/mixins/fonts"; export * from "./common/selectors/theme";