From cd9603f09891f2efc2f367ca5ef0e47b3551b4bc Mon Sep 17 00:00:00 2001 From: Zohar Manor-Abel Date: Thu, 15 Oct 2026 10:37:58 +0100 Subject: [PATCH 1/2] Give outlined inputs a surface background - Fill `MuiOutlinedInput` with `--ds-surface` so TextField, Select and Autocomplete stay distinct on container or elevated surfaces - Add "On surfaces" stories for TextField and Select - Assert the rest-state background in the theme test --- changelog.md | 1 + src/components/MUI/Inputs/Select.stories.tsx | 18 ++++++++++++++ .../MUI/Inputs/TextField.stories.tsx | 24 +++++++++++++++++++ src/themes/DiamondDSTheme.test.ts | 1 + src/themes/DiamondDSTheme.ts | 3 +++ 5 files changed, 47 insertions(+) diff --git a/changelog.md b/changelog.md index 8b94370f..d2b0273e 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ ### Changed +- Outlined inputs (TextField, Select, Autocomplete) now have a `surface` background, so they stay distinct on container or elevated surfaces. - _Dialog_ now defaults to elevation 16 (`surface.strong`'s tone) instead of MUI's 24, and temporary _Drawer_ to elevation 4 instead of 16, so floating surfaces order Drawer < Menu < Dialog and dialog text keeps more contrast. - **Breaking** _Dialog_'s deprecated `PaperProps` is now ignored. Move it to `slotProps.paper`, e.g. with `npx @mui/codemod@latest deprecations/dialog-props `. If you use MRT, also check `muiEditRowDialogProps` and `muiCreateRowModalProps` by hand, as the codemod won't reach them. diff --git a/src/components/MUI/Inputs/Select.stories.tsx b/src/components/MUI/Inputs/Select.stories.tsx index d75dcfae..d7d0543a 100644 --- a/src/components/MUI/Inputs/Select.stories.tsx +++ b/src/components/MUI/Inputs/Select.stories.tsx @@ -88,6 +88,24 @@ export const FilledAndStandard: Story = { ), }; +export const OnSurfaces: Story = { + name: "On surfaces", + render: (args: SelectArgs) => ( + + {[ + ["Background", "var(--ds-background)"], + ["Surface", "var(--ds-surface)"], + ["Surface container", "var(--ds-surface-container)"], + ["Surface container high", "var(--ds-surface-container-high)"], + ].map(([name, background]) => ( + + {renderSelectWithLabel({ ...args, variant: "outlined", label: name })} + + ))} + + ), +}; + export const States: Story = { render: (args: SelectArgs) => ( diff --git a/src/components/MUI/Inputs/TextField.stories.tsx b/src/components/MUI/Inputs/TextField.stories.tsx index 725027c0..f88b56e7 100644 --- a/src/components/MUI/Inputs/TextField.stories.tsx +++ b/src/components/MUI/Inputs/TextField.stories.tsx @@ -184,6 +184,30 @@ export const States: Story = { }, }; +export const OnSurfaces: Story = { + name: "On surfaces", + render: (_args) => ( + + {[ + ["Background", "var(--ds-background)"], + ["Surface", "var(--ds-surface)"], + ["Surface container", "var(--ds-surface-container)"], + ["Surface container high", "var(--ds-surface-container-high)"], + ].map(([name, background]) => ( + + + + ))} + + ), +}; + export const Validation: Story = { render: (_args) => ( diff --git a/src/themes/DiamondDSTheme.test.ts b/src/themes/DiamondDSTheme.test.ts index 26610117..3ffaa979 100644 --- a/src/themes/DiamondDSTheme.test.ts +++ b/src/themes/DiamondDSTheme.test.ts @@ -787,6 +787,7 @@ describe("DiamondDS component overrides", () => { }); // Rest + expect(styles.backgroundColor).toBe("var(--ds-surface)"); expect(styles["& .MuiOutlinedInput-notchedOutline"]).toEqual( expect.objectContaining({ borderColor: "var(--ds-border-emphasis)", diff --git a/src/themes/DiamondDSTheme.ts b/src/themes/DiamondDSTheme.ts index c367f79c..f1374230 100644 --- a/src/themes/DiamondDSTheme.ts +++ b/src/themes/DiamondDSTheme.ts @@ -1453,6 +1453,9 @@ const DiamondDSTheme = extendTheme({ const accent = `var(--ds-${tokenName}-accent)`; return { + /** Opaque fill so the field stays distinct on container or elevated surfaces. */ + backgroundColor: "var(--ds-surface)", + "& .MuiOutlinedInput-notchedOutline": { borderColor: "var(--ds-border-emphasis)", }, From 7f55b6b752bd8a72b8a15b95247c4219b4d2aed0 Mon Sep 17 00:00:00 2001 From: Zohar Manor-Abel Date: Thu, 15 Oct 2026 10:57:40 +0100 Subject: [PATCH 2/2] Fill the outlined input label notch - Paint the notch with the field background so the floating label sits on one tone, with rounded top corners - Use the read-only and disabled wash tokens for those states, above the field edge only - Make the notch 2px higher and 4px taller and shift the shrunk label down 1px for space above the text --- src/themes/DiamondDSTheme.test.ts | 5 ++++ src/themes/DiamondDSTheme.ts | 45 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/themes/DiamondDSTheme.test.ts b/src/themes/DiamondDSTheme.test.ts index 3ffaa979..57c77bdd 100644 --- a/src/themes/DiamondDSTheme.test.ts +++ b/src/themes/DiamondDSTheme.test.ts @@ -788,6 +788,11 @@ describe("DiamondDS component overrides", () => { // Rest expect(styles.backgroundColor).toBe("var(--ds-surface)"); + expect( + styles[ + "&:not(.Mui-disabled):not(.MuiInputBase-readOnly) .MuiOutlinedInput-notchedOutline legend > span" + ], + ).toEqual(expect.objectContaining({ backgroundColor: "inherit" })); expect(styles["& .MuiOutlinedInput-notchedOutline"]).toEqual( expect.objectContaining({ borderColor: "var(--ds-border-emphasis)", diff --git a/src/themes/DiamondDSTheme.ts b/src/themes/DiamondDSTheme.ts index f1374230..89d8fe65 100644 --- a/src/themes/DiamondDSTheme.ts +++ b/src/themes/DiamondDSTheme.ts @@ -1458,6 +1458,46 @@ const DiamondDSTheme = extendTheme({ "& .MuiOutlinedInput-notchedOutline": { borderColor: "var(--ds-border-emphasis)", + top: -7, + }, + + /** Notch 2px higher and 4px taller than MUI's, so the border line stays put. */ + "& .MuiOutlinedInput-notchedOutline legend": { + height: 15, + }, + + /** + * Fills the notch so the straddling label sits on one tone. Editable + * fields inherit the field background; `background-clip: text` keeps + * the fieldset and legend from painting it over the value. + */ + "& .MuiOutlinedInput-notchedOutline legend > span": { + borderRadius: "4px 4px 0 0", + color: "transparent", + opacity: 1, + }, + + "&:not(.Mui-disabled):not(.MuiInputBase-readOnly) .MuiOutlinedInput-notchedOutline, &:not(.Mui-disabled):not(.MuiInputBase-readOnly) .MuiOutlinedInput-notchedOutline legend": + { + backgroundColor: "inherit", + backgroundClip: "text", + }, + + "&:not(.Mui-disabled):not(.MuiInputBase-readOnly) .MuiOutlinedInput-notchedOutline legend > span": + { + backgroundColor: "inherit", + }, + + /** Washes are translucent, so paint only above the field edge to avoid doubling. */ + "&.MuiInputBase-readOnly:not(.Mui-disabled) .MuiOutlinedInput-notchedOutline legend > span": + { + backgroundColor: "var(--ds-surface-readonly)", + height: 7, + }, + + "&.Mui-disabled .MuiOutlinedInput-notchedOutline legend > span": { + backgroundColor: "var(--ds-surface-disabled)", + height: 7, }, "&:hover:not(.Mui-disabled):not(.Mui-error):not(.Mui-focused):not(.MuiInputBase-readOnly) .MuiOutlinedInput-notchedOutline": @@ -1652,6 +1692,11 @@ const DiamondDSTheme = extendTheme({ color: "var(--ds-on-surface-disabled)", }, + /** 1px below MUI's -9px, for room above the label in the filled notch. */ + "&.MuiInputLabel-outlined.MuiInputLabel-shrink": { + transform: "translate(14px, -8px) scale(0.75)", + }, + "&.Mui-focused": { color: "var(--ds-primary)", },