Skip to content

[WB-1896] Tokens: Add thunderblocks theme to Wonder Blocks #2562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/flat-tables-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/wonder-blocks-theming": minor
"@khanacademy/wonder-blocks-tokens": minor
---

Add `thunderblocks` theme to Wonder Blocks.
7 changes: 7 additions & 0 deletions .storybook/modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ export const allModes = {
wide: {
viewport: "wide",
},
// Theming
themeDefault: {
theme: "default",
},
themeThunderBlocks: {
theme: "thunderblocks",
},
};
24 changes: 24 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from "react";
import wonderBlocksTheme from "./wonder-blocks-theme";
import {Decorator} from "@storybook/react";
import {DocsContainer} from "@storybook/blocks";
import {RenderStateRoot} from "@khanacademy/wonder-blocks-core";
import {semanticColor} from "@khanacademy/wonder-blocks-tokens";
import {initAnnouncer} from "@khanacademy/wonder-blocks-announcer";
Expand Down Expand Up @@ -56,6 +57,22 @@ const wbViewports = {
},
};

/**
* This is a custom DocsContainer that uses the current theme in MDX pages.
*
* It is useful when we want to use the "Theme" toolbar to switch between
* themes in MDX pages (like "Foundations > Using color").
*/
function DocsContainerWithTheme({children, context, ...props}) {
const theme = context.store.userGlobals.globals.theme;

return (
<DocsContainer context={context} {...props}>
<ThemeSwitcher theme={theme}>{children}</ThemeSwitcher>
</DocsContainer>
);
}

const parameters = {
// Enable the RenderStateRoot decorator by default.
enableRenderStateRootDecorator: true,
Expand Down Expand Up @@ -91,6 +108,8 @@ const parameters = {
},
},
docs: {
// Customize the DocsContainer to use the WB theme in MDX pages.
container: DocsContainerWithTheme,
toc: {
// Useful for MDX pages like "Using color".
headingSelector: "h2, h3",
Expand Down Expand Up @@ -215,6 +234,11 @@ const preview: Preview = {
icon: "comment",
title: "Khanmigo",
},
{
value: "thunderblocks",
icon: "lightning",
title: "Thunder Blocks (Classroom)",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also want to include OG in the title for the default theme? In case others are referring to the default theme as OG!

},
],
// Change title based on selected value
dynamicTitle: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {AllVariants} from "../components/all-variants";
import {defaultPseudoStates, StateSheet} from "../components/state-sheet";
import {sizing} from "@khanacademy/wonder-blocks-tokens";
import {View} from "@khanacademy/wonder-blocks-core";
import {allModes} from "../../.storybook/modes";

/**
* The following stories are used to generate the pseudo states for the
Expand All @@ -23,6 +24,14 @@ export default {
actionType: "progressive",
size: "medium",
},
parameters: {
chromatic: {
modes: {
default: allModes.themeDefault,
thunderblocks: allModes.themeThunderBlocks,
},
},
},
} as Meta;

type StoryComponentType = StoryObj<typeof IconButton>;
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,19 @@
"@jest/globals": "^29.7.0",
"@khanacademy/eslint-config": "^5.2.0",
"@khanacademy/eslint-plugin": "^3.1.1",
"@khanacademy/wonder-stuff-testing": "^3.0.5",
"@khanacademy/wonder-blocks-announcer": "workspace:*",
"@khanacademy/wonder-blocks-core": "workspace:*",
"@khanacademy/wonder-blocks-link": "workspace:*",
"@khanacademy/wonder-blocks-tokens": "workspace:*",
"@khanacademy/wonder-blocks-theming": "workspace:*",
"@khanacademy/wonder-blocks-tokens": "workspace:*",
"@khanacademy/wonder-stuff-testing": "^3.0.5",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^16.0.0",
"@storybook/addon-a11y": "^8.5.2",
"@storybook/addon-actions": "^8.5.2",
"@storybook/addon-docs": "^8.5.2",
"@storybook/addon-essentials": "^8.5.2",
"@storybook/blocks": "^8.5.2",
"@storybook/builder-vite": "^8.5.2",
"@storybook/experimental-addon-test": "^8.5.2",
"@storybook/preview-api": "^8.5.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/wonder-blocks-theming/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import {StyleDeclaration} from "aphrodite";

export type ThemedStylesFn<T extends object> = (theme: T) => StyleDeclaration;

export type SupportedThemes = "default" | "khanmigo" | "dark";
export type SupportedThemes = "default" | "khanmigo" | "dark" | "thunderblocks";
export type Themes<T extends object> = Partial<Record<SupportedThemes, T>>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {fade} from "../../../util/utils";

// Base colors
const black = "#191918";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My one thought on working through some font theming is: should the default theme be put into these theme folders to keep similar objects near each other in the codebase? I think it could help reduce some cognitive complexity for theming.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question! My main reasoning for not putting the default color primitives was because those tokens are public (TB primitive colors are not). I left color.ts and spacing.ts inside the tokens package as the goal is to mark them as deprecated at some point in the future (or OG colors are going to be marked as internal at some point).

OG colors are public mostly for historic reasons (we didn't use semanticColor tokens before), and the overall goal is to make these colors private at some point, but I'm not fully sure if we are going to be able to do it. That will happen for sure after completing Polaris and doing all the cleanup work from legacy UIs that won't be used by the Classic Experience anymore (aka things that are deprecated from ka.org and moved to Polaris).... same applies with Spacing -> Sizing.

That said, if you think that it is better to move OG colors to the theme folder, then I can do it without any problem :) (at the end, it is an internal thing, and the public export remains the same).

wdyt?

const white = "#FFFFFF";

/**
* The color primitives for the Thunder Blocks theme.
*
* NOTE: These colors are for internal use only and should not be used directly
* in components. Use the semantic colors instead.
*
* @see semantic-color-thunderblocks.ts
*/
export const color = {
// Red
red_90: "#FEF4F4",
red_80: "#FDE9E9",
red_70: "#FDDFDF",
red_60: "#FBB1B1",
red_50: "#F97F7F",
red_40: "#ED5656",
red_30: "#E22D2D",
red_20: "#BE2626",
red_10: "#8E1C1C",
red_05: "#621414",
// Orange
orange_90: "#FEF4F2",
orange_80: "#FEE9E5",
orange_70: "#FEDFD8",
orange_60: "#FEBFB1",
orange_50: "#FAA185",
orange_40: "#F97B4F",
orange_30: "#F8551A",
orange_20: "#C8481A",
orange_10: "#983C1A",
orange_05: "#672912",
// Yellow
yellow_90: "#FEF8E7",
yellow_80: "#FEF1D0",
yellow_70: "#FEEAB8",
yellow_60: "#FEE7AD",
yellow_50: "#FDD673",
yellow_40: "#FCC539",
yellow_30: "#FCB706",
yellow_20: "#D69900",
yellow_10: "#9B6F00",
yellow_05: "#5F4500",
// Green
green_90: "#F1FBF1",
green_80: "#E3F7E3",
green_70: "#D5F3D5",
green_60: "#BCEBBB",
green_50: "#97D38E",
green_40: "#72BB82",
green_30: "#579F6C",
green_20: "#3C6D4A",
green_10: "#2C5037",
green_05: "#24432D",
// Cyan
cyan_90: "#EEF7FE",
cyan_80: "#DDF0FE",
cyan_70: "#CCE9FE",
cyan_60: "#A9DAFD",
cyan_50: "#87CBFC",
cyan_40: "#57BAFD",
cyan_30: "#28A9FF",
cyan_20: "#2485C7",
cyan_10: "#20628F",
cyan_05: "#1D3F58",
// Blue
blue_90: "#F8F9FB",
blue_80: "#EBF1FD",
blue_70: "#DFEAFF",
blue_60: "#BFCAFF",
blue_50: "#8DA2FF",
blue_40: "#6E78FF",
blue_30: "#5753FA",
blue_20: "#4340D0",
blue_10: "#363498",
blue_05: "#252368",
// Magenta
magenta_90: "#FCEEF7",
magenta_80: "#FFE3F4",
magenta_70: "#FAD4EC",
magenta_60: "#F9BBE1",
magenta_50: "#F8A2D6",
magenta_40: "#F670C1",
magenta_30: "#E83FA4",
magenta_20: "#C03187",
magenta_10: "#84275E",
magenta_05: "#521B3C",
// Gray
gray_90: "#F6F6F6",
gray_80: "#EDEDEE",
gray_70: "#E0E0E1",
gray_60: "#CBCBCD",
gray_50: "#B5B6B9",
gray_40: "#A0A1A4",
gray_30: "#8A8B90",
gray_20: "#75767C",
gray_10: "#4A4C53",
gray_05: "#35373F",
// Black
black_100: black,
black_50: fade(black, 0.5),
// White
white_100: white,
};
Loading
Loading