From 1538fcfb4219b0a78c536f2963973f8a98d90833 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 13:19:25 -0700 Subject: [PATCH 01/25] [wb-1797] Add CompactCell variant stories --- .../compact-cell-variants.stories.tsx | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 __docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx diff --git a/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx new file mode 100644 index 000000000..b6bdbe830 --- /dev/null +++ b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx @@ -0,0 +1,120 @@ +import * as React from "react"; +import {StyleSheet} from "aphrodite"; +import type {Meta, StoryObj} from "@storybook/react"; + +import {PropsFor, View} from "@khanacademy/wonder-blocks-core"; +import {spacing} from "@khanacademy/wonder-blocks-tokens"; +import {CompactCell} from "@khanacademy/wonder-blocks-cell"; +import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon"; +import {IconMappings} from "../wonder-blocks-icon/phosphor-icon.argtypes"; +import {LabelSmall} from "@khanacademy/wonder-blocks-typography"; + +/** + * The following stories are used to generate the pseudo states for the + * CompactCell component. This is only used for visual testing in Chromatic. + */ +export default { + title: "Packages / Cell / CompactCell / All Variants", + parameters: { + docs: { + autodocs: false, + }, + backgrounds: { + default: "offWhite", + }, + }, +} as Meta; + +type StoryComponentType = StoryObj; + +const states = [ + { + label: "Default", + props: {}, + }, + { + label: "Disabled", + props: {disabled: true}, + }, + { + label: "Active", + props: {active: true}, + }, +]; + +const defaultProps = { + title: "Title for article item", + leftAccessory: ( + + ), + rightAccessory: , +}; + +const States = (props: {label: string} & PropsFor) => { + return ( + + + {states.map((scenario) => { + return ( + + + {props.label} ({scenario.label}) + + + + ); + })} + + + ); +}; + +const AllVariants = () => ( + + + {}} /> + + +); + +export const Default: StoryComponentType = { + render: AllVariants, +}; + +export const Hover: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {hover: true}}, +}; + +export const Focus: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {focusVisible: true}}, +}; + +export const HoverFocus: StoryComponentType = { + name: "Hover + Focus", + render: AllVariants, + parameters: {pseudo: {hover: true, focusVisible: true}}, +}; + +export const Active: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {active: true}}, +}; + +const styles = StyleSheet.create({ + statesContainer: { + padding: spacing.medium_16, + }, + scenarios: { + display: "flex", + flexDirection: "row", + alignItems: "center", + gap: spacing.xxxLarge_64, + flexWrap: "wrap", + }, + scenario: { + gap: spacing.small_12, + overflow: "hidden", + }, +}); From f2e611a01496cfe9a8f19e3a993d769b12a8b9fe Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 13:31:33 -0700 Subject: [PATCH 02/25] [wb-1797] use semantic icon token for right accessory --- .../wonder-blocks-cell/src/components/internal/cell-core.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 35c5d6bdd..82ee25c11 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -6,7 +6,7 @@ import type {StyleType} from "@khanacademy/wonder-blocks-core"; import Clickable from "@khanacademy/wonder-blocks-clickable"; import {View} from "@khanacademy/wonder-blocks-core"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; +import {color, semanticColor, spacing} from "@khanacademy/wonder-blocks-tokens"; import {CellMeasurements, getHorizontalRuleStyles} from "./common"; @@ -264,7 +264,7 @@ const styles = StyleSheet.create({ accessoryRight: { // The right accessory will have this color by default. Unless the // accessory element overrides that color internally. - color: color.offBlack64, + color: semanticColor.icon.primary, }, /** From 20fc4194788a9b78f42466e5b33aaeaa982f5f58 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 13:31:49 -0700 Subject: [PATCH 03/25] [wb-1797] use new gray value for subtitle --- packages/wonder-blocks-cell/src/components/detail-cell.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wonder-blocks-cell/src/components/detail-cell.tsx b/packages/wonder-blocks-cell/src/components/detail-cell.tsx index 1b1661c0e..abe38e6b5 100644 --- a/packages/wonder-blocks-cell/src/components/detail-cell.tsx +++ b/packages/wonder-blocks-cell/src/components/detail-cell.tsx @@ -94,7 +94,7 @@ const DetailCell = function (props: DetailCellProps): React.ReactElement { const styles = StyleSheet.create({ subtitle: { - color: color.offBlack64, + color: "#6D6F74", // TODO: use token }, // This is to override the default padding of the CellCore innerWrapper. From 5149ed04aabfa86fec89c1a6592641846b16d680 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 14:40:34 -0700 Subject: [PATCH 04/25] [wb-1797] Add :before pseudo selector to aphrodite type --- types/aphrodite.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/aphrodite.d.ts b/types/aphrodite.d.ts index b061466ae..ed21bfa8f 100644 --- a/types/aphrodite.d.ts +++ b/types/aphrodite.d.ts @@ -68,6 +68,7 @@ declare module "aphrodite" { "::placeholder"?: _CSSProperties; ":active"?: _CSSProperties; ":after"?: _CSSProperties; + ":before"?: _CSSProperties; ":first-child"?: _CSSProperties; ":focus-visible"?: _CSSProperties; ":focus:not(:focus-visible)"?: _CSSProperties; From 7b6efb00ce8266223dc206bbab5811d2f38ab499 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 14:41:24 -0700 Subject: [PATCH 05/25] [wb-1797] set up active state --- .../src/components/internal/cell-core.tsx | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 82ee25c11..98a88e0d4 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -6,7 +6,12 @@ import type {StyleType} from "@khanacademy/wonder-blocks-core"; import Clickable from "@khanacademy/wonder-blocks-clickable"; import {View} from "@khanacademy/wonder-blocks-core"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {color, semanticColor, spacing} from "@khanacademy/wonder-blocks-tokens"; +import { + border, + color, + semanticColor, + spacing, +} from "@khanacademy/wonder-blocks-tokens"; import {CellMeasurements, getHorizontalRuleStyles} from "./common"; @@ -118,6 +123,7 @@ function CellInner(props: CellCoreProps): React.ReactElement { // custom styles style, horizontalRuleStyles, + active && styles.activeInnerWrapper, ]} > {/* Left accessory */} @@ -244,6 +250,18 @@ const styles = StyleSheet.create({ }px`, }, }, + activeInnerWrapper: { + position: "relative", + ":before": { + content: "''", + position: "absolute", + top: 0, + left: 0, + bottom: 0, + width: border.width.thick, + backgroundColor: semanticColor.surface.emphasis, + }, + }, content: { alignSelf: "center", From 142f54658227f24a7022b59dc36eb46e6965c78c Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 14:43:21 -0700 Subject: [PATCH 06/25] [wb-1797] update terminology in variants story --- __docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx | 2 +- __docs__/wonder-blocks-cell/detail-cell-variants.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx index b6bdbe830..f194fb837 100644 --- a/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx +++ b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx @@ -37,7 +37,7 @@ const states = [ props: {disabled: true}, }, { - label: "Active", + label: "Selected using active: true", props: {active: true}, }, ]; diff --git a/__docs__/wonder-blocks-cell/detail-cell-variants.stories.tsx b/__docs__/wonder-blocks-cell/detail-cell-variants.stories.tsx index a22f4b190..c7b391bb4 100644 --- a/__docs__/wonder-blocks-cell/detail-cell-variants.stories.tsx +++ b/__docs__/wonder-blocks-cell/detail-cell-variants.stories.tsx @@ -37,7 +37,7 @@ const states = [ props: {disabled: true}, }, { - label: "Active", + label: "Selected using active: true", props: {active: true}, }, ]; From 20d256ddb71ba29b41b44a18dc33d03285197905 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 14:46:56 -0700 Subject: [PATCH 07/25] [wb-1797] update text color when it is active --- .../wonder-blocks-cell/src/components/internal/cell-core.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 98a88e0d4..18ffc903a 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -341,7 +341,7 @@ const styles = StyleSheet.create({ active: { background: color.fadedBlue8, - color: color.blue, + color: semanticColor.action.primary.active, [":hover[aria-disabled=false]" as any]: { background: color.fadedBlue16, From 0d21574d565f4f95b4303fbb3ddd085b77f3f436 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 15:00:17 -0700 Subject: [PATCH 08/25] [wb-1797] use light blue for hover and press states --- .../src/components/internal/cell-core.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 18ffc903a..503bd672e 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -330,25 +330,26 @@ const styles = StyleSheet.create({ // hover + enabled [":hover[aria-disabled=false]" as any]: { - background: color.offBlack8, + background: color.fadedBlue8, }, // pressed + enabled [":active[aria-disabled=false]" as any]: { - background: color.offBlack16, + background: color.fadedBlue8, }, }, active: { background: color.fadedBlue8, color: semanticColor.action.primary.active, + cursor: "default", [":hover[aria-disabled=false]" as any]: { - background: color.fadedBlue16, + background: color.fadedBlue8, }, [":active[aria-disabled=false]" as any]: { - background: color.fadedBlue24, + background: color.fadedBlue8, }, }, From a66356b98c8288a34503fb4042ae01a0747dd4ce Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 15:16:45 -0700 Subject: [PATCH 09/25] [wb-1797] pressed indicator --- .../src/components/internal/cell-core.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 503bd672e..ceb79edd9 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -336,6 +336,16 @@ const styles = StyleSheet.create({ // pressed + enabled [":active[aria-disabled=false]" as any]: { background: color.fadedBlue8, + position: "relative", + ":before": { + content: "''", + position: "absolute", + top: 0, + left: 0, + bottom: 0, + width: border.width.thin, + backgroundColor: semanticColor.surface.emphasis, + }, }, }, From e9b73bc2c8e8f49381911573f101a800a6d5f57e Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 15:21:30 -0700 Subject: [PATCH 10/25] [wb-1797] use disabled border color --- .../wonder-blocks-cell/src/components/internal/cell-core.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index ceb79edd9..f1b315a82 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -327,6 +327,9 @@ const styles = StyleSheet.create({ border: `${spacing.xxxxSmall_2}px solid ${color.blue}`, borderRadius: spacing.xxxSmall_4, }, + [":focus-visible[aria-disabled=true]:after" as any]: { + borderColor: semanticColor.action.disabled.default, + }, // hover + enabled [":hover[aria-disabled=false]" as any]: { From ce980f33c181ff6b656dd1cc3e65b566a215385c Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 13:19:25 -0700 Subject: [PATCH 11/25] [wb-1797] Add CompactCell variant stories --- .../compact-cell-variants.stories.tsx | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 __docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx diff --git a/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx new file mode 100644 index 000000000..b6bdbe830 --- /dev/null +++ b/__docs__/wonder-blocks-cell/compact-cell-variants.stories.tsx @@ -0,0 +1,120 @@ +import * as React from "react"; +import {StyleSheet} from "aphrodite"; +import type {Meta, StoryObj} from "@storybook/react"; + +import {PropsFor, View} from "@khanacademy/wonder-blocks-core"; +import {spacing} from "@khanacademy/wonder-blocks-tokens"; +import {CompactCell} from "@khanacademy/wonder-blocks-cell"; +import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon"; +import {IconMappings} from "../wonder-blocks-icon/phosphor-icon.argtypes"; +import {LabelSmall} from "@khanacademy/wonder-blocks-typography"; + +/** + * The following stories are used to generate the pseudo states for the + * CompactCell component. This is only used for visual testing in Chromatic. + */ +export default { + title: "Packages / Cell / CompactCell / All Variants", + parameters: { + docs: { + autodocs: false, + }, + backgrounds: { + default: "offWhite", + }, + }, +} as Meta; + +type StoryComponentType = StoryObj; + +const states = [ + { + label: "Default", + props: {}, + }, + { + label: "Disabled", + props: {disabled: true}, + }, + { + label: "Active", + props: {active: true}, + }, +]; + +const defaultProps = { + title: "Title for article item", + leftAccessory: ( + + ), + rightAccessory: , +}; + +const States = (props: {label: string} & PropsFor) => { + return ( + + + {states.map((scenario) => { + return ( + + + {props.label} ({scenario.label}) + + + + ); + })} + + + ); +}; + +const AllVariants = () => ( + + + {}} /> + + +); + +export const Default: StoryComponentType = { + render: AllVariants, +}; + +export const Hover: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {hover: true}}, +}; + +export const Focus: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {focusVisible: true}}, +}; + +export const HoverFocus: StoryComponentType = { + name: "Hover + Focus", + render: AllVariants, + parameters: {pseudo: {hover: true, focusVisible: true}}, +}; + +export const Active: StoryComponentType = { + render: AllVariants, + parameters: {pseudo: {active: true}}, +}; + +const styles = StyleSheet.create({ + statesContainer: { + padding: spacing.medium_16, + }, + scenarios: { + display: "flex", + flexDirection: "row", + alignItems: "center", + gap: spacing.xxxLarge_64, + flexWrap: "wrap", + }, + scenario: { + gap: spacing.small_12, + overflow: "hidden", + }, +}); From 27c29412be3686b7a9cb528de562efb738224f98 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 15:48:45 -0700 Subject: [PATCH 12/25] [wb-1797-cell-color-contrast] linting --- packages/wonder-blocks-cell/src/components/detail-cell.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wonder-blocks-cell/src/components/detail-cell.tsx b/packages/wonder-blocks-cell/src/components/detail-cell.tsx index abe38e6b5..ed1f49245 100644 --- a/packages/wonder-blocks-cell/src/components/detail-cell.tsx +++ b/packages/wonder-blocks-cell/src/components/detail-cell.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import {StyleSheet} from "aphrodite"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; +import {spacing} from "@khanacademy/wonder-blocks-tokens"; import {LabelSmall, LabelMedium} from "@khanacademy/wonder-blocks-typography"; import CellCore from "./internal/cell-core"; From 962fe64e0c89d7ed75cb020e8724e4a7b1fad5be Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Mon, 20 Jan 2025 15:49:49 -0700 Subject: [PATCH 13/25] [wb-1797-cell-color-contrast] docs(changeset): DetailCell and CompactCell: update styling to address color contrast accessibility issues --- .changeset/wise-actors-peel.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .changeset/wise-actors-peel.md diff --git a/.changeset/wise-actors-peel.md b/.changeset/wise-actors-peel.md new file mode 100644 index 000000000..dc794422b --- /dev/null +++ b/.changeset/wise-actors-peel.md @@ -0,0 +1,20 @@ +--- +"@khanacademy/wonder-blocks-cell": patch +--- + +DetailCell and CompactCell: update styling to address accessibility issues (color contrast and using color as the only visual indicator). Updated styles include: + +- General: + - Changing the grey used for subtitles + - Using `icon.primary` for the right accessory +- Press state: + - Changing the background to `fadedBlue8` + - Adding a thin left border when clickable cells are pressed +- Hover state: + - Changing the background to `fadedBlue8` +- Disabled state: + - Changing the focus outline to `action.disabled.default` +- Selected state (cells with `active=true`): + - Adding a thick left border + - Changing the text color to `action.primary.active` + - The styling no longer changes when a selected cell is hovered or pressed on From 6d0b1d5d3bbb14a8ef3b00262ec66c93102fad5e Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Tue, 21 Jan 2025 14:34:13 -0700 Subject: [PATCH 14/25] [wb-1797-cell-color-contrast] exploring other potential fadedOffBlack shades for text on light blue backgrounds --- .../wonder-blocks-tokens/colors.stories.tsx | 98 +++++++++++++++++++ .../src/components/detail-cell.tsx | 5 +- .../wonder-blocks-tokens/src/tokens/color.ts | 3 +- 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 __docs__/wonder-blocks-tokens/colors.stories.tsx diff --git a/__docs__/wonder-blocks-tokens/colors.stories.tsx b/__docs__/wonder-blocks-tokens/colors.stories.tsx new file mode 100644 index 000000000..a618f7108 --- /dev/null +++ b/__docs__/wonder-blocks-tokens/colors.stories.tsx @@ -0,0 +1,98 @@ +import * as React from "react"; +import type {Meta, StoryObj} from "@storybook/react"; +import {color} from "@khanacademy/wonder-blocks-tokens"; +import {HeadingSmall} from "@khanacademy/wonder-blocks-typography"; +import {fadedColorWithWhite} from "../../packages/wonder-blocks-tokens/src/tokens/color"; + +export default { + title: "Grays", +} as Meta; + +type StoryComponentType = StoryObj; + +const Colors = ({colors}) => { + return colors.map(({name, hex}) => { + return ( +
+
{name}
+
{hex}
+
+ text +
+
+
+ ); + }); +}; +export const Default: StoryComponentType = { + args: {}, + render() { + const existingGrays = Object.keys(color) + .filter( + (key) => + key.startsWith("fadedOffBlack") || + key.startsWith("offBlack"), + ) + .reverse() + .map((key) => ({name: key, hex: color[key]})); + const alternativeGrays = [ + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 90, 95, 99, + ].map((key) => ({ + name: `fadedOffBlack${key}`, + hex: fadedColorWithWhite(color.offBlack, key / 100), + })); + const proposed = "#6D6F74"; + return ( +
+
+ Existing grays + + Alternative Grays + + Proposed + +
+
+ Proposed: {proposed} + +
+
+
+ ); + }, +}; diff --git a/packages/wonder-blocks-cell/src/components/detail-cell.tsx b/packages/wonder-blocks-cell/src/components/detail-cell.tsx index ed1f49245..7ca9c3612 100644 --- a/packages/wonder-blocks-cell/src/components/detail-cell.tsx +++ b/packages/wonder-blocks-cell/src/components/detail-cell.tsx @@ -2,13 +2,14 @@ import * as React from "react"; import {StyleSheet} from "aphrodite"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {spacing} from "@khanacademy/wonder-blocks-tokens"; +import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; import {LabelSmall, LabelMedium} from "@khanacademy/wonder-blocks-typography"; import CellCore from "./internal/cell-core"; import {CellMeasurements} from "./internal/common"; import type {CellProps, TypographyText} from "../util/types"; +import {fadedColorWithWhite} from "../../../wonder-blocks-tokens/src/tokens/color"; type SubtitleProps = { subtitle?: TypographyText; @@ -94,7 +95,7 @@ const DetailCell = function (props: DetailCellProps): React.ReactElement { const styles = StyleSheet.create({ subtitle: { - color: "#6D6F74", // TODO: use token + color: fadedColorWithWhite(color.offBlack, 0.72), // TODO use semantic token }, // This is to override the default padding of the CellCore innerWrapper. diff --git a/packages/wonder-blocks-tokens/src/tokens/color.ts b/packages/wonder-blocks-tokens/src/tokens/color.ts index e9730a951..00c234f82 100644 --- a/packages/wonder-blocks-tokens/src/tokens/color.ts +++ b/packages/wonder-blocks-tokens/src/tokens/color.ts @@ -55,7 +55,7 @@ const baseColors: ColorType = { teal: "#14bf96", }; -const fadedColorWithWhite = (color: string, alpha: number) => +export const fadedColorWithWhite = (color: string, alpha: number) => mix(fade(color, alpha), baseColors.white); export const color = { @@ -90,6 +90,7 @@ export const color = { eggplant: eggplant, fadedEggplant8: fadedColorWithWhite(eggplant, 0.08), // Faded versions of offBlack + // fadedOffBlack72: fadedColorWithWhite(offBlack, 0.72), fadedOffBlack64: fadedColorWithWhite(offBlack, 0.64), fadedOffBlack50: fadedColorWithWhite(offBlack, 0.5), fadedOffBlack32: fadedColorWithWhite(offBlack, 0.32), From dc57eece1360896714bc064dc57fa23d8021d158 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Tue, 21 Jan 2025 16:40:18 -0700 Subject: [PATCH 15/25] [wb-1797-cell-color-contrast] Address overflow of left bar indicator --- .../detail-cell.stories.tsx | 20 ++++++++++++++++++- .../src/components/internal/cell-core.tsx | 3 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/__docs__/wonder-blocks-cell/detail-cell.stories.tsx b/__docs__/wonder-blocks-cell/detail-cell.stories.tsx index 4d7a13790..980ba16de 100644 --- a/__docs__/wonder-blocks-cell/detail-cell.stories.tsx +++ b/__docs__/wonder-blocks-cell/detail-cell.stories.tsx @@ -4,7 +4,7 @@ import {MemoryRouter, Route, Switch} from "react-router-dom"; import type {Meta, StoryObj} from "@storybook/react"; import {View} from "@khanacademy/wonder-blocks-core"; -import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; +import {border, color, spacing} from "@khanacademy/wonder-blocks-tokens"; import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon"; import {DetailCell} from "@khanacademy/wonder-blocks-cell"; @@ -469,6 +469,24 @@ export const Scenarios = () => { ); }; +/** + * Custom styling can be applied to the root using the `rootStyle` prop. + */ +export const CustomRootStyle = { + args: { + rootStyle: { + borderRadius: border.radius.large_6, + }, + active: true, + title: "Title for article item", + subtitle1: "Subtitle for article item", + subtitle2: "Subtitle for article item", + leftAccessory: ( + + ), + }, +}; + const styles = StyleSheet.create({ example: { backgroundColor: color.offWhite, diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index f1b315a82..a0e75cfec 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -234,6 +234,9 @@ const styles = StyleSheet.create({ minHeight: CellMeasurements.cellMinHeight, textAlign: "left", width: "100%", + // Hide overflow so that if custom styling applies a border radius, the + // left visual indicator for press/active states does not overflow + overflow: "hidden", }, innerWrapper: { From 8cd75b853ddef0615e23b3e012ab39305dbf9b6f Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 10:47:08 -0700 Subject: [PATCH 16/25] Revert "[wb-1797-cell-color-contrast] exploring other potential fadedOffBlack shades for text on light blue backgrounds" This reverts commit 6d0b1d5d3bbb14a8ef3b00262ec66c93102fad5e. --- .../wonder-blocks-tokens/colors.stories.tsx | 98 ------------------- .../src/components/detail-cell.tsx | 5 +- .../wonder-blocks-tokens/src/tokens/color.ts | 3 +- 3 files changed, 3 insertions(+), 103 deletions(-) delete mode 100644 __docs__/wonder-blocks-tokens/colors.stories.tsx diff --git a/__docs__/wonder-blocks-tokens/colors.stories.tsx b/__docs__/wonder-blocks-tokens/colors.stories.tsx deleted file mode 100644 index a618f7108..000000000 --- a/__docs__/wonder-blocks-tokens/colors.stories.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import * as React from "react"; -import type {Meta, StoryObj} from "@storybook/react"; -import {color} from "@khanacademy/wonder-blocks-tokens"; -import {HeadingSmall} from "@khanacademy/wonder-blocks-typography"; -import {fadedColorWithWhite} from "../../packages/wonder-blocks-tokens/src/tokens/color"; - -export default { - title: "Grays", -} as Meta; - -type StoryComponentType = StoryObj; - -const Colors = ({colors}) => { - return colors.map(({name, hex}) => { - return ( -
-
{name}
-
{hex}
-
- text -
-
-
- ); - }); -}; -export const Default: StoryComponentType = { - args: {}, - render() { - const existingGrays = Object.keys(color) - .filter( - (key) => - key.startsWith("fadedOffBlack") || - key.startsWith("offBlack"), - ) - .reverse() - .map((key) => ({name: key, hex: color[key]})); - const alternativeGrays = [ - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 90, 95, 99, - ].map((key) => ({ - name: `fadedOffBlack${key}`, - hex: fadedColorWithWhite(color.offBlack, key / 100), - })); - const proposed = "#6D6F74"; - return ( -
-
- Existing grays - - Alternative Grays - - Proposed - -
-
- Proposed: {proposed} - -
-
-
- ); - }, -}; diff --git a/packages/wonder-blocks-cell/src/components/detail-cell.tsx b/packages/wonder-blocks-cell/src/components/detail-cell.tsx index 7ca9c3612..ed1f49245 100644 --- a/packages/wonder-blocks-cell/src/components/detail-cell.tsx +++ b/packages/wonder-blocks-cell/src/components/detail-cell.tsx @@ -2,14 +2,13 @@ import * as React from "react"; import {StyleSheet} from "aphrodite"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; +import {spacing} from "@khanacademy/wonder-blocks-tokens"; import {LabelSmall, LabelMedium} from "@khanacademy/wonder-blocks-typography"; import CellCore from "./internal/cell-core"; import {CellMeasurements} from "./internal/common"; import type {CellProps, TypographyText} from "../util/types"; -import {fadedColorWithWhite} from "../../../wonder-blocks-tokens/src/tokens/color"; type SubtitleProps = { subtitle?: TypographyText; @@ -95,7 +94,7 @@ const DetailCell = function (props: DetailCellProps): React.ReactElement { const styles = StyleSheet.create({ subtitle: { - color: fadedColorWithWhite(color.offBlack, 0.72), // TODO use semantic token + color: "#6D6F74", // TODO: use token }, // This is to override the default padding of the CellCore innerWrapper. diff --git a/packages/wonder-blocks-tokens/src/tokens/color.ts b/packages/wonder-blocks-tokens/src/tokens/color.ts index 00c234f82..e9730a951 100644 --- a/packages/wonder-blocks-tokens/src/tokens/color.ts +++ b/packages/wonder-blocks-tokens/src/tokens/color.ts @@ -55,7 +55,7 @@ const baseColors: ColorType = { teal: "#14bf96", }; -export const fadedColorWithWhite = (color: string, alpha: number) => +const fadedColorWithWhite = (color: string, alpha: number) => mix(fade(color, alpha), baseColors.white); export const color = { @@ -90,7 +90,6 @@ export const color = { eggplant: eggplant, fadedEggplant8: fadedColorWithWhite(eggplant, 0.08), // Faded versions of offBlack - // fadedOffBlack72: fadedColorWithWhite(offBlack, 0.72), fadedOffBlack64: fadedColorWithWhite(offBlack, 0.64), fadedOffBlack50: fadedColorWithWhite(offBlack, 0.5), fadedOffBlack32: fadedColorWithWhite(offBlack, 0.32), From 072e006cc828724095240b7de4daedfdf22152c2 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 10:49:18 -0700 Subject: [PATCH 17/25] [wb-1797-cell-color-contrast] Add fadedOffBlack72 color token. Update semantic text secondary token to new darker gray so it works with fadedBlue8 backgrounds --- packages/wonder-blocks-tokens/src/tokens/color.ts | 1 + packages/wonder-blocks-tokens/src/tokens/semantic-color.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/wonder-blocks-tokens/src/tokens/color.ts b/packages/wonder-blocks-tokens/src/tokens/color.ts index e9730a951..0df5f15a7 100644 --- a/packages/wonder-blocks-tokens/src/tokens/color.ts +++ b/packages/wonder-blocks-tokens/src/tokens/color.ts @@ -90,6 +90,7 @@ export const color = { eggplant: eggplant, fadedEggplant8: fadedColorWithWhite(eggplant, 0.08), // Faded versions of offBlack + fadedOffBlack72: fadedColorWithWhite(offBlack, 0.72), fadedOffBlack64: fadedColorWithWhite(offBlack, 0.64), fadedOffBlack50: fadedColorWithWhite(offBlack, 0.5), fadedOffBlack32: fadedColorWithWhite(offBlack, 0.32), diff --git a/packages/wonder-blocks-tokens/src/tokens/semantic-color.ts b/packages/wonder-blocks-tokens/src/tokens/semantic-color.ts index 0f9248497..6b9d82750 100644 --- a/packages/wonder-blocks-tokens/src/tokens/semantic-color.ts +++ b/packages/wonder-blocks-tokens/src/tokens/semantic-color.ts @@ -62,7 +62,7 @@ export const semanticColor = { */ text: { primary: color.offBlack, - secondary: color.fadedOffBlack64, + secondary: color.fadedOffBlack72, disabled: color.fadedOffBlack32, inverse: color.white, }, From c3e0408e3374ff3c5511cb4bc6050a715559da8c Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 10:49:35 -0700 Subject: [PATCH 18/25] [wb-1797-cell-color-contrast] use semantic text secondary token for detail cell subtitle text --- packages/wonder-blocks-cell/src/components/detail-cell.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wonder-blocks-cell/src/components/detail-cell.tsx b/packages/wonder-blocks-cell/src/components/detail-cell.tsx index ed1f49245..cc0e92bbb 100644 --- a/packages/wonder-blocks-cell/src/components/detail-cell.tsx +++ b/packages/wonder-blocks-cell/src/components/detail-cell.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import {StyleSheet} from "aphrodite"; import {Strut} from "@khanacademy/wonder-blocks-layout"; -import {spacing} from "@khanacademy/wonder-blocks-tokens"; +import {semanticColor, spacing} from "@khanacademy/wonder-blocks-tokens"; import {LabelSmall, LabelMedium} from "@khanacademy/wonder-blocks-typography"; import CellCore from "./internal/cell-core"; @@ -94,7 +94,7 @@ const DetailCell = function (props: DetailCellProps): React.ReactElement { const styles = StyleSheet.create({ subtitle: { - color: "#6D6F74", // TODO: use token + color: semanticColor.text.secondary, }, // This is to override the default padding of the CellCore innerWrapper. From e3bc9b855385bafc3350f95db41695b83bca1a5a Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 10:51:09 -0700 Subject: [PATCH 19/25] [wb-1797-cell-color-contrast] docs(changeset): Adds `fadedOffBlack72` color primitive token and sets the text secondary token to this primitive. The slightly darker gray has better color contrast on a variety of backgrounds, including the fadedBlue8 background --- .changeset/shiny-chicken-speak.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/shiny-chicken-speak.md diff --git a/.changeset/shiny-chicken-speak.md b/.changeset/shiny-chicken-speak.md new file mode 100644 index 000000000..3b2c665ed --- /dev/null +++ b/.changeset/shiny-chicken-speak.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/wonder-blocks-tokens": minor +--- + +Adds `fadedOffBlack72` color primitive token and sets the `semanticColor.text.secondary` token to this primitive. The slightly darker gray has better color contrast on a variety of backgrounds, including the fadedBlue8 background From 01a6addc8feb44a83e7d3392a5f2808cd1859359 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 13:26:14 -0700 Subject: [PATCH 20/25] [wb-1797-cell-color-contrast] update token usage for active color with new token structure --- .../wonder-blocks-cell/src/components/internal/cell-core.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index a0e75cfec..89a7b6fa1 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -357,7 +357,7 @@ const styles = StyleSheet.create({ active: { background: color.fadedBlue8, - color: semanticColor.action.primary.active, + color: color.activeBlue, cursor: "default", [":hover[aria-disabled=false]" as any]: { From 31a2073e10f0dce10310a728581d7cad0e3c4b16 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 13:33:17 -0700 Subject: [PATCH 21/25] [wb-1797-cell-color-contrast] update changeset --- .changeset/wise-actors-peel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wise-actors-peel.md b/.changeset/wise-actors-peel.md index dc794422b..89dfa13a4 100644 --- a/.changeset/wise-actors-peel.md +++ b/.changeset/wise-actors-peel.md @@ -16,5 +16,5 @@ DetailCell and CompactCell: update styling to address accessibility issues (colo - Changing the focus outline to `action.disabled.default` - Selected state (cells with `active=true`): - Adding a thick left border - - Changing the text color to `action.primary.active` + - Changing the text color to `activeBlue` - The styling no longer changes when a selected cell is hovered or pressed on From 018a3b965a74b21628cb56916fb8096a5a4586f1 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Wed, 22 Jan 2025 16:31:43 -0700 Subject: [PATCH 22/25] [wb-1797-cell-color-contrast] rework styling for the left bar indicator so that we don't set overflow: hidden on clickable items since that was causing layout issues in OptionItems for dropdown components --- .../detail-cell.stories.tsx | 16 +++++++-- .../src/components/internal/cell-core.tsx | 35 ++++++++++++------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/__docs__/wonder-blocks-cell/detail-cell.stories.tsx b/__docs__/wonder-blocks-cell/detail-cell.stories.tsx index 980ba16de..869219bf9 100644 --- a/__docs__/wonder-blocks-cell/detail-cell.stories.tsx +++ b/__docs__/wonder-blocks-cell/detail-cell.stories.tsx @@ -3,7 +3,7 @@ import {StyleSheet} from "aphrodite"; import {MemoryRouter, Route, Switch} from "react-router-dom"; import type {Meta, StoryObj} from "@storybook/react"; -import {View} from "@khanacademy/wonder-blocks-core"; +import {PropsFor, View} from "@khanacademy/wonder-blocks-core"; import {border, color, spacing} from "@khanacademy/wonder-blocks-tokens"; import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon"; @@ -475,9 +475,8 @@ export const Scenarios = () => { export const CustomRootStyle = { args: { rootStyle: { - borderRadius: border.radius.large_6, + borderRadius: border.radius.xLarge_12, }, - active: true, title: "Title for article item", subtitle1: "Subtitle for article item", subtitle2: "Subtitle for article item", @@ -485,6 +484,17 @@ export const CustomRootStyle = { ), }, + render(args: PropsFor) { + return ( + + Active: + + Pressed: + + + ); + }, + parameters: {pseudo: {active: true}}, }; const styles = StyleSheet.create({ diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index 89a7b6fa1..e28b7b86a 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -234,9 +234,6 @@ const styles = StyleSheet.create({ minHeight: CellMeasurements.cellMinHeight, textAlign: "left", width: "100%", - // Hide overflow so that if custom styling applies a border radius, the - // left visual indicator for press/active states does not overflow - overflow: "hidden", }, innerWrapper: { @@ -244,6 +241,10 @@ const styles = StyleSheet.create({ padding: `${CellMeasurements.cellPadding.paddingVertical}px ${CellMeasurements.cellPadding.paddingHorizontal}px`, flexDirection: "row", flex: 1, + borderRadius: "inherit", + // Hide overflow so that if custom styling applies a border radius, the + // left visual indicator for press/active states does not overflow + overflow: "hidden", // Reduce the padding of the innerWrapper when the focus ring is // visible. @@ -342,17 +343,25 @@ const styles = StyleSheet.create({ // pressed + enabled [":active[aria-disabled=false]" as any]: { background: color.fadedBlue8, - position: "relative", - ":before": { - content: "''", - position: "absolute", - top: 0, - left: 0, - bottom: 0, - width: border.width.thin, - backgroundColor: semanticColor.surface.emphasis, - }, }, + // press + enabled + not currently selected (active prop: false) + // Using the first child to apply the left bar indicator on the pressed + // state because setting the styles on the clickable element + // directly causes issues since overflow must be hidden for cases where + // the border is rounded + [":active[aria-disabled=false]:not([aria-current=true]) > *:first-child" as any]: + { + position: "relative", + ":before": { + content: "''", + position: "absolute", + top: 0, + left: 0, + bottom: 0, + width: border.width.thin, + backgroundColor: semanticColor.surface.emphasis, + }, + }, }, active: { From 862e3c3b1c4d88d94d66186717a5efeab15cffbc Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Thu, 23 Jan 2025 15:34:32 -0700 Subject: [PATCH 23/25] [wb-1797-cell-color-contrast] Set inner wrapper styles using a class instead --- .../src/components/internal/cell-core.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx index e28b7b86a..7faec4683 100644 --- a/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx +++ b/packages/wonder-blocks-cell/src/components/internal/cell-core.tsx @@ -125,6 +125,9 @@ function CellInner(props: CellCoreProps): React.ReactElement { horizontalRuleStyles, active && styles.activeInnerWrapper, ]} + // Set className so we can set styles on the inner wrapper directly + // when the clickable element is pressed + className="inner-wrapper" > {/* Left accessory */}