diff --git a/src/themes/DiamondDSTheme.test.ts b/src/themes/DiamondDSTheme.test.ts index 57ac82cf..1d7b8677 100644 --- a/src/themes/DiamondDSTheme.test.ts +++ b/src/themes/DiamondDSTheme.test.ts @@ -494,16 +494,18 @@ describe("DiamondDS component overrides", () => { ); }); - it("uses semantic roles for toggle button borders and selected state", () => { + it("uses neutral toggle button styles by default", () => { const root = DiamondDSTheme.components?.MuiToggleButton?.styleOverrides?.root; const styles = getStyleOverride(root, { + ownerState: {}, theme: DiamondDSTheme, }); expect(styles.textTransform).toBe("none"); expect(styles.border).toBe("1px solid var(--ds-border-emphasis)"); + expect(styles.color).toBe("inherit"); expect(styles["&:hover"]).toEqual( expect.objectContaining({ @@ -513,9 +515,16 @@ describe("DiamondDS component overrides", () => { expect(styles["&.Mui-selected"]).toEqual( expect.objectContaining({ - backgroundColor: "var(--ds-primary-container)", - color: "var(--ds-on-primary-container)", - borderColor: "var(--ds-primary-accent)", + backgroundColor: "var(--ds-overlay-selected)", + color: "inherit", + borderColor: "var(--ds-border-strong)", + }), + ); + + expect(styles["&.Mui-selected:hover"]).toEqual( + expect.objectContaining({ + backgroundColor: "var(--ds-overlay-selected)", + borderColor: "var(--ds-border-strong)", }), ); @@ -523,6 +532,34 @@ describe("DiamondDS component overrides", () => { expect.objectContaining({ color: "var(--ds-on-surface-disabled)", borderColor: "var(--ds-border-subtle)", + boxShadow: "none", + }), + ); + }); + + it("uses primary semantic roles for selected toggle button states", () => { + const root = + DiamondDSTheme.components?.MuiToggleButton?.styleOverrides?.root; + + const styles = getStyleOverride(root, { + ownerState: { + color: "primary", + }, + theme: DiamondDSTheme, + }); + + expect(styles["&.Mui-selected"]).toEqual( + expect.objectContaining({ + backgroundColor: "var(--ds-primary-container)", + color: "var(--ds-on-primary-container)", + borderColor: "var(--ds-primary-accent)", + }), + ); + + expect(styles["&.Mui-selected:hover"]).toEqual( + expect.objectContaining({ + backgroundColor: "var(--ds-primary-container)", + borderColor: "var(--ds-primary)", }), ); }); diff --git a/src/themes/DiamondDSTheme.ts b/src/themes/DiamondDSTheme.ts index 9fd27e66..a6326fe2 100644 --- a/src/themes/DiamondDSTheme.ts +++ b/src/themes/DiamondDSTheme.ts @@ -27,6 +27,7 @@ import type { CSSObject, PaletteColor, Theme } from "@mui/material/styles"; */ import type { AlertProps } from "@mui/material/Alert"; import type { ButtonProps } from "@mui/material/Button"; +import type { ToggleButtonProps } from "@mui/material/ToggleButton"; import type { CheckboxProps } from "@mui/material/Checkbox"; import type { ChipProps } from "@mui/material/Chip"; import type { CircularProgressProps } from "@mui/material/CircularProgress"; @@ -715,6 +716,7 @@ const DiamondDSTheme = extendTheme({ * MuiButton → contained, outlined and text variants * MuiIconButton → intent-aware icon actions * MuiToggleButton → selection, border and hover states + * MuiButtonGroup → selection, border and hover states * * Inputs and forms: * MuiInputBase → placeholder behaviour @@ -782,9 +784,49 @@ const DiamondDSTheme = extendTheme({ const rawColour = ownerState.color ?? "primary"; if (rawColour === "inherit") { + if (variant === "outlined") { + return { + ...base, + ...getFocusOutline(), + + color: "inherit", + backgroundColor: "transparent", + border: "1px solid var(--ds-border-emphasis)", + + "&:hover": { + backgroundColor: "var(--ds-overlay-hover)", + borderColor: "var(--ds-border-strong)", + boxShadow: getOverlayInset(), + }, + + "&:active": { + borderColor: "var(--ds-border-strong)", + boxShadow: getOverlayInset("var(--ds-overlay-selected)"), + }, + + "&.Mui-disabled": { + ...getDisabledControlStyles(), + borderColor: "var(--ds-border-subtle)", + }, + }; + } + + if (variant === "contained") { + return { + ...base, + ...getFocusOutline(), + }; + } + return { ...base, ...getFocusOutline(), + + color: "inherit", + + "&.Mui-disabled": { + color: "var(--ds-on-surface-disabled)", + }, }; } @@ -935,31 +977,89 @@ const DiamondDSTheme = extendTheme({ MuiToggleButton: { styleOverrides: { - root: (): CSSObject => ({ - textTransform: "none", - border: `1px solid ${"var(--ds-border-emphasis)"}`, + root: ({ ownerState }: OverrideArgs): CSSObject => { + const colour = ownerState?.color ?? "standard"; + const isPrimary = colour === "primary"; - "&:hover": { - borderColor: "var(--ds-border-strong)", + return { + textTransform: "none", + border: "1px solid var(--ds-border-emphasis)", + + color: "inherit", + + "&:hover": { + borderColor: "var(--ds-border-strong)", + boxShadow: getOverlayInset(), + }, + + "&.Mui-selected": { + backgroundColor: isPrimary + ? "var(--ds-primary-container)" + : "var(--ds-overlay-selected)", + + color: isPrimary ? "var(--ds-on-primary-container)" : "inherit", + + borderColor: isPrimary + ? "var(--ds-primary-accent)" + : "var(--ds-border-strong)", + }, + + "&.Mui-selected:hover": { + backgroundColor: isPrimary + ? "var(--ds-primary-container)" + : "var(--ds-overlay-selected)", + + borderColor: isPrimary + ? "var(--ds-primary)" + : "var(--ds-border-strong)", + + boxShadow: getOverlayInset(), + }, + + "&.Mui-disabled": { + color: "var(--ds-on-surface-disabled)", + borderColor: "var(--ds-border-subtle)", + boxShadow: "none", + }, + }; + }, + }, + }, + + MuiButtonGroup: { + styleOverrides: { + root: { + boxShadow: "none", + }, + + contained: { + boxShadow: "none", + }, + + grouped: { + boxShadow: "none", + + "&.Mui-disabled": { + boxShadow: "none", }, + }, - "&.Mui-selected": { - backgroundColor: "var(--ds-primary-container)", - color: "var(--ds-on-primary-container)", - borderColor: "var(--ds-primary-accent)", + groupedContained: { + boxShadow: "none", + + "&:hover": { + boxShadow: getOverlayInset("var(--ds-overlay-hover-solid)"), }, - "&.Mui-selected:hover": { - backgroundColor: "var(--ds-primary-container)", - borderColor: "var(--ds-primary)", - boxShadow: getOverlayInset(), + "&:active": { + boxShadow: getOverlayInset("var(--ds-overlay-selected)"), }, "&.Mui-disabled": { color: "var(--ds-on-surface-disabled)", borderColor: "var(--ds-border-subtle)", }, - }), + }, }, },