Skip to content
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

[WB-1853] Button: Refactor theme to support semanticColor tokens #2431

Draft
wants to merge 4 commits into
base: wb-semantic-color-refactor
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/many-apes-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-blocks-button": patch
---

Use `semanticColor` in Button. This replaces the use of `color` primitive tokens in favor of semantic color tokens
22 changes: 19 additions & 3 deletions __docs__/wonder-blocks-button/button-variants.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,29 @@ const KindVariants = ({light}: {light: boolean}) => {
{sizes.map((size) => (
<>
{colors.map((color) => (
<>
<VariantsGroup
size={size}
color={color}
light={light}
/>
{light && (
<VariantsGroup
size={size}
color={color}
disabled={true}
light={light}
/>
)}
</>
))}
{!light && (
<VariantsGroup
size={size}
color={color}
disabled={true}
light={light}
/>
))}
<VariantsGroup size={size} disabled={true} light={light} />
)}
</>
))}
</>
Expand Down
50 changes: 38 additions & 12 deletions __docs__/wonder-blocks-button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,26 +187,28 @@ WithColor.parameters = {
};

export const Dark: StoryComponentType = () => (
<View style={{backgroundColor: color.darkBlue, padding: spacing.medium_16}}>
<View style={{flexDirection: "row"}}>
<View
style={{
backgroundColor: color.darkBlue,
gap: spacing.medium_16,
padding: spacing.medium_16,
}}
>
<View style={{flexDirection: "row", gap: spacing.medium_16}}>
<Button onClick={() => {}} light={true}>
Hello, world!
</Button>
<Strut size={16} />
<Button onClick={() => {}} light={true} kind="secondary">
Hello, world!
</Button>
<Strut size={16} />
<Button onClick={() => {}} light={true} kind="tertiary">
Hello, world!
</Button>
</View>
<Strut size={16} />
<View style={{flexDirection: "row"}}>
<View style={{flexDirection: "row", gap: spacing.medium_16}}>
<Button onClick={() => {}} light={true} disabled={true}>
Hello, world!
</Button>
<Strut size={16} />
<Button
onClick={() => {}}
light={true}
Expand All @@ -215,7 +217,6 @@ export const Dark: StoryComponentType = () => (
>
Hello, world!
</Button>
<Strut size={16} />
<Button
onClick={() => {}}
light={true}
Expand All @@ -225,12 +226,10 @@ export const Dark: StoryComponentType = () => (
Hello, world!
</Button>
</View>
<Strut size={16} />
<View style={{flexDirection: "row"}}>
<View style={{flexDirection: "row", gap: spacing.medium_16}}>
<Button onClick={() => {}} light={true} color="destructive">
Hello, world!
</Button>
<Strut size={16} />
<Button
onClick={() => {}}
light={true}
Expand All @@ -239,7 +238,6 @@ export const Dark: StoryComponentType = () => (
>
Hello, world!
</Button>
<Strut size={16} />
<Button
onClick={() => {}}
light={true}
Expand All @@ -249,6 +247,34 @@ export const Dark: StoryComponentType = () => (
Hello, world!
</Button>
</View>
<View style={{flexDirection: "row", gap: spacing.medium_16}}>
<Button
onClick={() => {}}
disabled={true}
light={true}
color="destructive"
>
Hello, world!
</Button>
<Button
onClick={() => {}}
disabled={true}
light={true}
kind="secondary"
color="destructive"
>
Hello, world!
</Button>
<Button
onClick={() => {}}
disabled={true}
light={true}
kind="tertiary"
color="destructive"
>
Hello, world!
</Button>
</View>
</View>
);

Expand Down
40 changes: 28 additions & 12 deletions packages/wonder-blocks-button/src/components/button-core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,24 @@ export const _generateStyles = (
theme: ButtonThemeContract,
themeName: string,
) => {
const colorToAction = light
? buttonColor === "destructive"
? "destructiveInverse"
: "progressiveInverse"
: buttonColor === "destructive"
? "destructive"
: "progressive";
const themeColorAction = theme.color[colorToAction];
const color: string =
buttonColor === "destructive"
? theme.color.bg.critical.default
: theme.color.bg.action.default;

const buttonType = `${color}-${kind}-${light}-${size}-${themeName}`;
const bgColor = themeColorAction.default.background;
const textColor = themeColorAction.default.foreground;
const borderColor = themeColorAction.default.border;

const buttonType = `${buttonColor}-${kind}-${light}-${size}-${themeName}`;

if (styles[buttonType]) {
return styles[buttonType];
Expand All @@ -369,7 +381,7 @@ export const _generateStyles = (
let newStyles: Record<string, CSSProperties> = {};
if (kind === "primary") {
const focusStyling = {
outlineColor: light ? theme.color.bg.primary.default : color,
outlineColor: light ? theme.color.light.border : borderColor,
outlineOffset: theme.border.offset.primary,
outlineStyle: "solid",
outlineWidth: theme.border.width.focused,
Expand All @@ -380,12 +392,18 @@ export const _generateStyles = (
outlineColor: light ? fadedColor : activeColor,
};

const inverseBgColor = themeColorAction.default.background;
const inverseTextColor = themeColorAction.default.foreground;
const disabledBgColor = themeColorAction.disabled.background;
const disabledInverseBgColor = themeColorAction.disabled.background;
const disabledFgColor = themeColorAction.disabled.foreground;
const disabledInverseFgColor = themeColorAction.disabled.foreground;

newStyles = {
default: {
background: light ? theme.color.bg.primary.default : color,
color: light ? color : theme.color.text.inverse,
paddingLeft: padding,
paddingRight: padding,
background: light ? inverseBgColor : bgColor,
color: light ? inverseTextColor : textColor,
paddingInline: padding,
// TODO(WB-1844): Change this when we get final designs for
// hover.
[":hover:not([aria-disabled=true])" as any]: focusStyling,
Expand All @@ -397,16 +415,14 @@ export const _generateStyles = (
focused: focusStyling,
pressed: activePressedStyling,
disabled: {
background: light
? fadedColor
: theme.color.bg.primary.disabled,
color: light ? color : theme.color.text.primary.disabled,
background: light ? disabledInverseBgColor : disabledBgColor,
color: light ? disabledInverseFgColor : disabledFgColor,
cursor: "default",
":focus-visible": {
...focusStyling,
outlineColor: light
? fadedColor
: theme.color.bg.primary.disabled,
? disabledInverseFgColor
: disabledFgColor,
},
},
};
Expand Down
54 changes: 48 additions & 6 deletions packages/wonder-blocks-button/src/themes/default.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,69 @@
import * as tokens from "@khanacademy/wonder-blocks-tokens";

const {semanticColor} = tokens;

// The underline-offset is the distance between the text baseline and the
// bottom of the underline. This is necessary to prevent the underline from
// breaking with descenders.
const textUnderlineOffset = tokens.spacing.xxxSmall_4;

const theme = {
color: {
progressive: {
...semanticColor.action.progressive,
disabled: {
background: semanticColor.action.disabled.default,
foreground: semanticColor.action.disabled.secondary,
},
},
progressiveInverse: {
...semanticColor.action.progressiveInverse,
disabled: {
background:
semanticColor.action.progressiveInverse.press.background,
foreground:
semanticColor.action.progressiveInverse.press.foreground,
},
},
destructive: {
...semanticColor.action.destructive,
disabled: {
background: semanticColor.action.disabled.default,
foreground: semanticColor.action.disabled.secondary,
},
},
destructiveInverse: {
...semanticColor.action.destructiveInverse,
disabled: {
background:
semanticColor.action.destructiveInverse.press.background,
foreground:
semanticColor.action.destructiveInverse.press.foreground,
},
},
// NOTE: These colors will be removed from WB as soon as we remove the
// light variant.
light: {
border: semanticColor.border.inverse,
},

bg: {
/**
* Color
*/
// color="default"
action: {
default: tokens.color.blue,
active: tokens.color.activeBlue,
inverse: tokens.color.fadedBlue,
default: semanticColor.action.progressive.default.background,
active: semanticColor.action.progressive.press.background,
inverse:
semanticColor.action.progressiveInverse.press.background,
},
// color="destructive"
critical: {
default: tokens.color.red,
active: tokens.color.activeRed,
inverse: tokens.color.fadedRed,
default: semanticColor.action.destructive.default.background,
active: semanticColor.action.destructive.press.background,
inverse:
semanticColor.action.destructiveInverse.press.background,
},

/**
Expand Down
Loading