diff --git a/.changeset/few-paws-speak.md b/.changeset/few-paws-speak.md new file mode 100644 index 000000000..59a3decb6 --- /dev/null +++ b/.changeset/few-paws-speak.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/wonder-blocks-tokens": minor +--- + +Add mediaQuery tokens for viewport sizing diff --git a/__docs__/wonder-blocks-tokens/__overview__.mdx b/__docs__/wonder-blocks-tokens/__overview__.mdx index 4c1d99355..e663a7d7c 100644 --- a/__docs__/wonder-blocks-tokens/__overview__.mdx +++ b/__docs__/wonder-blocks-tokens/__overview__.mdx @@ -25,6 +25,7 @@ These represent the design decisions at Khan Academy, such as: - Color Primitives - Spacing - Typography +- Media Queries ## Usage diff --git a/__docs__/wonder-blocks-tokens/tokens-media-queries.mdx b/__docs__/wonder-blocks-tokens/tokens-media-queries.mdx new file mode 100644 index 000000000..86af53b25 --- /dev/null +++ b/__docs__/wonder-blocks-tokens/tokens-media-queries.mdx @@ -0,0 +1,82 @@ +import {Meta, Source} from "@storybook/blocks"; + +import TokenTable from "../../.storybook/components/token-table"; + +import {View} from "@khanacademy/wonder-blocks-core"; +import * as tokens from "@khanacademy/wonder-blocks-tokens"; + +import ComponentInfo from "../../.storybook/components/component-info"; +import packageConfig from "../../packages/wonder-blocks-tokens/package.json"; + + + +# Media Queries + + + +All the available media query breakpoint values and pure widths that can be used for min-width, +max-width, width, etc. + +## Usage + +### Media Queries + +You can use mediaQuery conditions by importing `breakpoint` from the +`wonder-blocks-tokens` package and accessing its object properties for sizing like so: +`breakpoint.mediaQuery.sm`. + +```js +import {breakpoint} from "@khanacademy/wonder-blocks-tokens"; +const styles = { + [breakpoint.mediaQuery.sm]: { + flexDirection: "column" + } +}; +``` + +### Pure widths + +You can also use pure width values by importing `breakpoint` from the +`wonder-blocks-tokens` package and accessing the `width` object: +`breakpoint.width.sm`. These can be useful for tooling or in CSS where a number value +is needed. Therefore, pixel values are returned without a unit. You can interpolate +a string to add the `px` unit like so: + +```js +import {breakpoint} from "@khanacademy/wonder-blocks-tokens"; +const styles = { + element: { + maxWidth: `${breakpoint.width.lg}px` + } +}; +``` + +## Tokens + + breakpoint.mediaQuery.{row.label}, + }, + { + label: "Value", + cell: "value", + }, + ]} + tokens={tokens.breakpoint.mediaQuery} +/> + + breakpoint.width.{row.label}, + }, + { + label: "Value (px)", + cell: "value", + }, + ]} + tokens={tokens.breakpoint.width} +/> \ No newline at end of file diff --git a/packages/wonder-blocks-tokens/src/index.ts b/packages/wonder-blocks-tokens/src/index.ts index 9349e53c9..e56376a31 100644 --- a/packages/wonder-blocks-tokens/src/index.ts +++ b/packages/wonder-blocks-tokens/src/index.ts @@ -4,6 +4,8 @@ import {color} from "./tokens/color"; import {font} from "./tokens/font"; import {spacing} from "./tokens/spacing"; +// media queries +import {breakpoint} from "./tokens/media-queries"; // semantic tokens import {semanticColor} from "./tokens/semantic-color"; @@ -18,6 +20,10 @@ export { color, font, spacing, + /** + * Media query breakpoints. + */ + breakpoint, /** * Semantic tokens. */ diff --git a/packages/wonder-blocks-tokens/src/tokens/media-queries.ts b/packages/wonder-blocks-tokens/src/tokens/media-queries.ts new file mode 100644 index 000000000..a0d79b844 --- /dev/null +++ b/packages/wonder-blocks-tokens/src/tokens/media-queries.ts @@ -0,0 +1,40 @@ +/** + * A default set of media queries to use for different screen sizes. + * + * Breakpoint documentation: https://khanacademy.atlassian.net/wiki/spaces/WB/pages/2099970518/Layout+Breakpoints + * + */ + +/* Pure width values */ +const width = { + xsMax: 567, + smMin: 568, + smMax: 681, + mdMin: 682, + mdMax: 1023, + lgMin: 1024, +} as const; + +/* Named mediaQuery conditions */ +const mediaQuery = { + // Note: any updates to this will need to be replicated in /types/aphrodite.d.ts + xs: `@media screen and (max-width: ${width.xsMax}px) /* breakpoint.mediaQuery.xs */`, + sm: `@media screen and (min-width: ${width.smMin}px) and (max-width: ${width.smMax}px) /* breakpoint.mediaQuery.sm */`, + md: `@media screen and (min-width: ${width.mdMin}px) and (max-width: ${width.mdMax}px) /* breakpoint.mediaQuery.md */`, + lg: `@media screen and (min-width: ${width.mdMin}px) and (max-width: ${width.lgMin}px) /* breakpoint.mediaQuery.lg */`, + xl: `@media screen and (min-width: ${width.lgMin}px) /* breakpoint.mediaQuery.xl */`, + + xsOrSmaller: `@media screen and (max-width: ${width.xsMax}px) /* breakpoint.mediaQuery.xsOrSmaller */`, + smOrSmaller: `@media screen and (max-width: ${width.smMax}px) /* breakpoint.mediaQuery.smOrSmaller */`, + mdOrSmaller: `@media screen and (max-width: ${width.mdMax}px) /* breakpoint.mediaQuery.mdOrSmaller */`, + lgOrSmaller: `@media screen and (max-width: ${width.lgMin}px) /* breakpoint.mediaQuery.lgOrSmaller */`, + + smOrLarger: `@media screen and (min-width: ${width.smMin}px) /* breakpoint.mediaQuery.smOrLarger */`, + mdOrLarger: `@media screen and (min-width: ${width.mdMin}px) /* breakpoint.mediaQuery.mdOrLarger */`, + lgOrLarger: `@media screen and (min-width: ${width.lgMin}px) /* breakpoint.mediaQuery.lgOrLarger */`, +} as const; + +export const breakpoint = { + width, + mediaQuery, +}; diff --git a/types/aphrodite.d.ts b/types/aphrodite.d.ts index 19c3abf98..b061466ae 100644 --- a/types/aphrodite.d.ts +++ b/types/aphrodite.d.ts @@ -1,6 +1,32 @@ declare module "aphrodite" { import * as React from "react"; + // Note: Updates here are also needed in /wonder-blocks-tokens/src/tokens/media-queries.ts + const xs = + "@media screen and (max-width: 567px) /* breakpoint.mediaQuery.xs */"; + const sm = + "@media screen and (min-width: 568px) and (max-width: 681px) /* breakpoint.mediaQuery.sm */"; + const md = + "@media screen and (min-width: 682px) and (max-width: 1023px) /* breakpoint.mediaQuery.md */"; + const lg = + "@media screen and (min-width: 682px) and (max-width: 1024px) /* breakpoint.mediaQuery.lg */"; + const xl = + "@media screen and (min-width: 1024px) /* breakpoint.mediaQuery.xl */"; + const xsOrSmaller = + "@media screen and (max-width: 567px) /* breakpoint.mediaQuery.xsOrSmaller */"; + const smOrSmaller = + "@media screen and (max-width: 681px) /* breakpoint.mediaQuery.smOrSmaller */"; + const mdOrSmaller = + "@media screen and (max-width: 1023px) /* breakpoint.mediaQuery.mdOrSmaller */"; + const lgOrSmaller = + "@media screen and (min-width: 1024px) /* breakpoint.mediaQuery.lgOrLarger */"; + const smOrLarger = + "@media screen and (min-width: 568px) /* breakpoint.mediaQuery.smOrLarger */"; + const mdOrLarger = + "@media screen and (min-width: 682px) /* breakpoint.mediaQuery.mdOrLarger */"; + const lgOrLarger = + "@media screen and (min-width: 1024px) /* breakpoint.mediaQuery.lgOrLarger */"; + type _CSSProperties = React.CSSProperties & { /** * Browser Specific @@ -17,6 +43,19 @@ declare module "aphrodite" { "@media (max-width: 1023px)"?: React.CSSProperties; "@media (min-width: 1024px)"?: React.CSSProperties; "@media (min-width: 1168px)"?: React.CSSProperties; + + [xs]?: React.CSSProperties; + [sm]?: React.CSSProperties; + [md]?: React.CSSProperties; + [lg]?: React.CSSProperties; + [xl]?: React.CSSProperties; + [xsOrSmaller]?: React.CSSProperties; + [smOrSmaller]?: React.CSSProperties; + [mdOrSmaller]?: React.CSSProperties; + [lgOrSmaller]?: React.CSSProperties; + [smOrLarger]?: React.CSSProperties; + [mdOrLarger]?: React.CSSProperties; + [lgOrLarger]?: React.CSSProperties; }; /**