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;
};
/**