Skip to content

fix(theme): match outlined Select height to TextField at 56px - #1878

Merged
pontusringblom merged 2 commits into
masterfrom
fm/sistent-field-height-consistency
Oct 17, 2026
Merged

pontusringblom merged 2 commits into
masterfrom
fm/sistent-field-height-consistency

Conversation

@jijillery

@jijillery jijillery commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Intent

When end-to-end testing, be picky about the UI you see and be obsessed with pixel perfection. Adhere to and honor the design system. If something looks off, even if it is not directly related to what you are doing, try to get it fixed along the way. If the design system is not being followed, flag it and get it fixed.

With the Sistent theme, Select-based fields render 61px tall while TextField renders 56px, so forms that mix them misalign.

What Changed

  • MuiOutlinedInput root (src/theme/components/outlinedinput.modifier.ts) now resets lineHeight to MUI's InputBase value 1.4375em after spreading textB1Regular. It does this at the root and again at the sm breakpoint, where it also keeps the rest of the typography's sm overrides. Before this, the 1.75rem body line-height reached the field and made outlined Selects 61px tall while TextFields were 56px.
  • Added a theme.test.ts case that checks the 1.4375em line-height in light and dark mode, at both the root and the sm breakpoint.
  • DESIGN.md now sets height: 56px on the input-field and input-field-dark component tokens.

Risk Assessment

✅ Low: This is a small, theme-scoped CSS override that restores MUI's own InputBase line-height for outlined fields. The open sibling (the standard variant) and the multiline side effect are visual only and can be fixed as follow-ups.

Testing

I built disposable base and head harness pages that render the real Sistent theme provider and fields, then drove them in headless Chromium in light and dark mode at 1280px and 420px. On base, all three Select forms (bare, FormControl, TextField select) were 61/45px while TextField and Autocomplete were 56/40px. On head, every single-line field is 56/40px with a 23px line-height. Before/after screenshots and the measured heights are saved as evidence. A Select still opens its menu normally on head, and the focused theme unit test passes. The multiline TextField gets shorter (89 to 79px). That is the already-accepted, MUI-default side effect. The harness, browser and server were torn down, and the worktree is clean.

  • Live validation: ✅ go - 6 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Form mixing a medium outlined Select and a TextField: the Select now matches TextField at 56px (was 61px) ✅ pass live run2-heights.txt (base select 61 vs head 56; textfield 56 in both); run2-base-light-1280.png vs run2-head-light-1280.png
All Select entry points (bare Select, FormControl+InputLabel Select, TextField select) align with TextField and Autocomplete ✅ pass live run2-heights.txt: head medium select/formcontrolselect/selectprop/autocomplete/textfield all 56
Small-size fields: the Select matches the 40px TextField (was 45px) ✅ pass live run2-heights.txt: base small select 45 vs head 40; small textfield 40
Adversarial: narrow viewport below the sm breakpoint (420px), where typography swaps the responsive line-height, keeps Select at 56/40px ✅ pass live run2-heights.txt 420 rows; run2-head-light-420.png, run2-head-dark-420.png
Dark mode renders the same aligned heights as light mode ✅ pass live run2-head-dark-1280.png, run2-head-dark-420.png; run2-heights.txt dark rows
Adversarial: the shorter line-height does not clip the Select value or break interaction - clicking opens the menu with its options ✅ pass live run2-head-light-1280-select-open.png; listbox with options Kubernetes/Istio in the axi snapshot; select display scroll/client height 56/56
Theme unit guard pins MuiOutlinedInput line-height at the root and the sm breakpoint ⏸️ untested no The prior payload recorded only a jest unit test run against the theme object (2 passed), which is not a live product run, so it did not establish a live result for this scenario
Evidence: Measured field heights, base vs head, all modes and widths

base medium: textfield 56, select 61, formcontrolselect 61, selectprop 61, autocomplete 56 | small: 40/45/45/45/40 head medium: textfield 56, select 56, formcontrolselect 56, selectprop 56, autocomplete 56 | small: 40/40/40/40/40 (same in light/dark, 1280/420)

base/light/1280(innerW=1280): {"medium:textfield":"56/lh=28px","medium:select":"61/lh=28px","medium:formcontrolselect":"61/lh=28px","medium:autocomplete":"56/lh=28px","medium:multiline":"89/lh=28px","medium:selectprop":"61/lh=28px","small:textfield":"40/lh=28px","small:select":"45/lh=28px","small:formcontrolselect":"45/lh=28px","small:autocomplete":"40/lh=28px","small:multiline":"73/lh=28px","small:selectprop":"45/lh=28px"}
base/dark/1280(innerW=1280): {"medium:textfield":"56/lh=28px","medium:select":"61/lh=28px","medium:formcontrolselect":"61/lh=28px","medium:autocomplete":"56/lh=28px","medium:multiline":"89/lh=28px","medium:selectprop":"61/lh=28px","small:textfield":"40/lh=28px","small:select":"45/lh=28px","small:formcontrolselect":"45/lh=28px","small:autocomplete":"40/lh=28px","small:multiline":"73/lh=28px","small:selectprop":"45/lh=28px"}
head/light/1280(innerW=1280): {"medium:textfield":"56/lh=23px","medium:select":"56/lh=23px","medium:formcontrolselect":"56/lh=23px","medium:autocomplete":"56/lh=23px","medium:multiline":"79/lh=23px","medium:selectprop":"56/lh=23px","small:textfield":"40/lh=23px","small:select":"40/lh=23px","small:formcontrolselect":"40/lh=23px","small:autocomplete":"40/lh=23px","small:multiline":"63/lh=23px","small:selectprop":"40/lh=23px"}
head/dark/1280(innerW=1280): {"medium:textfield":"56/lh=23px","medium:select":"56/lh=23px","medium:formcontrolselect":"56/lh=23px","medium:autocomplete":"56/lh=23px","medium:multiline":"79/lh=23px","medium:selectprop":"56/lh=23px","small:textfield":"40/lh=23px","small:select":"40/lh=23px","small:formcontrolselect":"40/lh=23px","small:autocomplete":"40/lh=23px","small:multiline":"63/lh=23px","small:selectprop":"40/lh=23px"}
base/light/420(innerW=420): {"medium:textfield":"56/lh=28px","medium:select":"61/lh=28px","medium:formcontrolselect":"61/lh=28px","medium:autocomplete":"56/lh=28px","medium:multiline":"89/lh=28px","medium:selectprop":"61/lh=28px","small:textfield":"40/lh=28px","small:select":"45/lh=28px","small:formcontrolselect":"45/lh=28px","small:autocomplete":"40/lh=28px","small:multiline":"73/lh=28px","small:selectprop":"45/lh=28px"}
base/dark/420(innerW=420): {"medium:textfield":"56/lh=28px","medium:select":"61/lh=28px","medium:formcontrolselect":"61/lh=28px","medium:autocomplete":"56/lh=28px","medium:multiline":"89/lh=28px","medium:selectprop":"61/lh=28px","small:textfield":"40/lh=28px","small:select":"45/lh=28px","small:formcontrolselect":"45/lh=28px","small:autocomplete":"40/lh=28px","small:multiline":"73/lh=28px","small:selectprop":"45/lh=28px"}
head/light/420(innerW=420): {"medium:textfield":"56/lh=23px","medium:select":"56/lh=23px","medium:formcontrolselect":"56/lh=23px","medium:autocomplete":"56/lh=23px","medium:multiline":"79/lh=23px","medium:selectprop":"56/lh=23px","small:textfield":"40/lh=23px","small:select":"40/lh=23px","small:formcontrolselect":"40/lh=23px","small:autocomplete":"40/lh=23px","small:multiline":"63/lh=23px","small:selectprop":"40/lh=23px"}
head/dark/420(innerW=420): {"medium:textfield":"56/lh=23px","medium:select":"56/lh=23px","medium:formcontrolselect":"56/lh=23px","medium:autocomplete":"56/lh=23px","medium:multiline":"79/lh=23px","medium:selectprop":"56/lh=23px","small:textfield":"40/lh=23px","small:select":"40/lh=23px","small:formcontrolselect":"40/lh=23px","small:autocomplete":"40/lh=23px","small:multiline":"63/lh=23px","small:selectprop":"40/lh=23px"}
base/light/1280-final: {"wrap":"wrap","medium:textfield":56,"medium:select":61,"medium:formcontrolselect":61,"medium:autocomplete":56,"medium:multiline":89,"medium:selectprop":61,"small:textfield":40,"small:select":45,"small:formcontrolselect":45,"small:autocomplete":40,"small:multiline":73,"small:selectprop":45}
base/dark/1280-final: {"wrap":"wrap","medium:textfield":56,"medium:select":61,"medium:formcontrolselect":61,"medium:autocomplete":56,"medium:multiline":89,"medium:selectprop":61,"small:textfield":40,"small:select":45,"small:formcontrolselect":45,"small:autocomplete":40,"small:multiline":73,"small:selectprop":45}
head/light/1280-final: {"wrap":"wrap","medium:textfield":56,"medium:select":56,"medium:formcontrolselect":56,"medium:autocomplete":56,"medium:multiline":79,"medium:selectprop":56,"small:textfield":40,"small:select":40,"small:formcontrolselect":40,"small:autocomplete":40,"small:multiline":63,"small:selectprop":40}
head/dark/1280-final: {"wrap":"wrap","medium:textfield":56,"medium:select":56,"medium:formcontrolselect":56,"medium:autocomplete":56,"medium:multiline":79,"medium:selectprop":56,"small:textfield":40,"small:select":40,"small:formcontrolselect":40,"small:autocomplete":40,"small:multiline":63,"small:selectprop":40}
base/light/420-final: {"wrap":"wrap","medium:textfield":56,"medium:select":61,"medium:formcontrolselect":61,"medium:autocomplete":56,"medium:multiline":89,"medium:selectprop":61,"small:textfield":40,"small:select":45,"small:formcontrolselect":45,"small:autocomplete":40,"small:multiline":73,"small:selectprop":45}
base/dark/420-final: {"wrap":"wrap","medium:textfield":56,"medium:select":61,"medium:formcontrolselect":61,"medium:autocomplete":56,"medium:multiline":89,"medium:selectprop":61,"small:textfield":40,"small:select":45,"small:formcontrolselect":45,"small:autocomplete":40,"small:multiline":73,"small:selectprop":45}
head/light/420-final: {"wrap":"wrap","medium:textfield":56,"medium:select":56,"medium:formcontrolselect":56,"medium:autocomplete":56,"medium:multiline":79,"medium:selectprop":56,"small:textfield":40,"small:select":40,"small:formcontrolselect":40,"small:autocomplete":40,"small:multiline":63,"small:selectprop":40}
head/dark/420-final: {"wrap":"wrap","medium:textfield":56,"medium:select":56,"medium:formcontrolselect":56,"medium:autocomplete":56,"medium:multiline":79,"medium:selectprop":56,"small:textfield":40,"small:select":40,"small:formcontrolselect":40,"small:autocomplete":40,"small:multiline":63,"small:selectprop":40}
![Base light 1280 - Selects visibly taller than TextField](https://github.com/user-attachments/assets/1f1a59ac-907a-4837-b13a-06273f975d6d) ![Head light 1280 - all single-line fields aligned](https://github.com/user-attachments/assets/a9178ac7-e2e1-449e-817b-7111fa5f0cbf) ![Base dark 1280](https://github.com/user-attachments/assets/a3e9668e-fb9f-4945-8494-72debff7a858) ![Head dark 1280](https://github.com/user-attachments/assets/1d7c2995-7849-489b-9f53-a1ecd9af17c6) ![Base light 420 (below sm breakpoint)](https://github.com/user-attachments/assets/8bbf2d49-7737-42cd-a692-b1e7ee02961b) ![Head light 420 (below sm breakpoint)](https://github.com/user-attachments/assets/2ae3a561-a761-4783-88d0-4ca521143c30) ![Base dark 420](https://github.com/user-attachments/assets/7c2e3f5c-748a-4c54-8ab3-5bfd161d6abb) ![Head dark 420](https://github.com/user-attachments/assets/76a55e43-7d48-4ee1-ac76-14e9a458d08a) ![Head - Select menu opened, options render](https://github.com/user-attachments/assets/dfa9f8a7-e728-4149-8e1a-1236bd9f396f) - Outcome: 🔧 1 issue found ✅ across 2 runs (11m1s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 2 issues (1 warning, 1 info)

✅ No issues found.

  • ⚠️ src/theme/components/input.modifier.ts:13 - The same bug is still present for the standard (underlined) variant. MuiInput.styleOverrides.root spreads textB1Regular (lineHeight 1.75rem = 28px) and does not restore MUI InputBase's lineHeight: '1.4375em'. A Select's display div gets its height from the inherited line-height, but a TextField <input> has a fixed 1.4375em height. So <Select variant="standard"> still renders 5px taller than <TextField variant="standard">. That is the exact 61-vs-56 mismatch this change fixes for outlined fields, moved to the underlined variant. In-repo standard-variant consumers: src/custom/DashboardWidgets/WorkspaceActivityWidget.tsx:133 (standard Select) and src/custom/SearchBar.tsx:149 (standard TextField). Fix: apply the same lineHeight: FIELD_LINE_HEIGHT override, plus the sm-breakpoint override, in MuiInput, and share the constant from one module so both stay in sync. Extend the theme.test.ts case to cover MuiInput too.
  • ℹ️ src/theme/components/outlinedinput.modifier.ts:27 - Side effect consumers will see: MUI's InputBase input/textarea uses font: inherit, so multiline outlined TextFields now inherit 1.4375em (about 23px) per line instead of 1.75rem (28px). A rows={4} textarea gets about 20px shorter, with tighter line spacing. This matches MUI's own default, and it also makes a single-row multiline field 56px. Mention it in the PR description so downstream UIs (Meshery, Kanvas) expect the visual change.
🔧 **Test** - 1 issue found ✅
  • ℹ️ src/theme/components/outlinedinput.modifier.ts:27 - Side effect of the fix: the multiline outlined TextField also inherits the new 1.4375em line-height, so its lines are 23px apart instead of 28px and a 2-row field shrinks from 89px to 79px. That matches MUI's default and renders cleanly. If the 28px body spacing was intentional for textareas, it could be restored on the multiline input alone.
  • Live validation: ✅ go - 6 of 6 scenarios driven live against the product
Scenario Result Live Evidence
Medium outlined Select next to a TextField renders the same 56px height ✅ pass live heights.json and head-light-1280.png: medium select 56.00px vs textfield 56.00px (base: 61.00px vs 56.00px)
Small outlined Select next to a small TextField renders the same 40px height ✅ pass live heights.json: small select 40.00px vs textfield 40.00px (base: 45.00px vs 40.00px)
Heights stay matched below the sm breakpoint (420px viewport), where the theme applies its own line-height override ✅ pass live head-light-420.png, head-dark-420.png and heights.json head/*/420: computed line-height 23px, select 56/40px
Dark mode fields stay aligned ✅ pass live head-dark-1280.png, head-dark-420.png
Adversarial: Autocomplete and native Select keep their height and Select text (with descenders) is not clipped at the tighter line-height ✅ pass live heights.json: autocomplete and nativeselect 56/40px; the select display has scrollHeight == clientHeight; 'gyp' descenders fully visible in head-light-1280.png
Adversarial: multiline TextField still renders legibly after the line-height change ✅ pass live head-light-1280.png: lines now 23px apart (base 28px), no clipping; field 79px vs 89px
  • Bundled a disposable test page with esbuild against the worktree src/ (SistentThemeProvider plus Sistent's TextField, Select, Autocomplete, native Select and multiline TextField, each in medium and small sizes). Built it twice: once with the head theme and once with the base commit's outlinedinput.modifier.ts swapped in.
  • Drove both builds in headless Chromium (playwright-core) at 1280px and 420px widths (420px is below the sm breakpoint), in light and dark mode. Measured the .MuiOutlinedInput-root heights, computed line-heights and scroll versus client heights, and took full-page screenshots.
  • npx jest src/__testing__/theme.test.ts

✅ No issues found.

  • Live validation: ✅ go - 6 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Form mixing a medium outlined Select and a TextField: the Select now matches TextField at 56px (was 61px) ✅ pass live run2-heights.txt (base select 61 vs head 56; textfield 56 in both); run2-base-light-1280.png vs run2-head-light-1280.png
All Select entry points (bare Select, FormControl+InputLabel Select, TextField select) align with TextField and Autocomplete ✅ pass live run2-heights.txt: head medium select/formcontrolselect/selectprop/autocomplete/textfield all 56
Small-size fields: the Select matches the 40px TextField (was 45px) ✅ pass live run2-heights.txt: base small select 45 vs head 40; small textfield 40
Adversarial: narrow viewport below the sm breakpoint (420px), where typography swaps the responsive line-height, keeps Select at 56/40px ✅ pass live run2-heights.txt 420 rows; run2-head-light-420.png, run2-head-dark-420.png
Dark mode renders the same aligned heights as light mode ✅ pass live run2-head-dark-1280.png, run2-head-dark-420.png; run2-heights.txt dark rows
Adversarial: the shorter line-height does not clip the Select value or break interaction - clicking opens the menu with its options ✅ pass live run2-head-light-1280-select-open.png; listbox with options Kubernetes/Istio in the axi snapshot; select display scroll/client height 56/56
Theme unit guard pins MuiOutlinedInput line-height at the root and the sm breakpoint ⏸️ untested no The prior payload recorded only a jest unit test run against the theme object (2 passed), which is not a live product run, so it did not establish a live result for this scenario
  • Built disposable esbuild harness pages from base (b2d92173) and head (git archive) src, each rendering SistentThemeProvider with TextField, bare Select, FormControl+InputLabel+Select, Autocomplete, multiline TextField and TextField select at medium and small sizes
  • Served the pages on a local port and drove them in headless Chromium through chrome-devtools-axi (CHROME_DEVTOOLS_AXI_BROWSER_URL pointing at a throwaway profile)
  • Measured each .MuiInputBase-root height and computed line-height via chrome-devtools-axi eval for {base, head} x {light, dark} x {1280px, 420px}
  • Took full-page screenshots of all 8 combinations
  • Clicked a Select on head, confirmed the listbox options appear, and took a screenshot of the open menu
  • npx jest src/__testing__/theme.test.ts -t "line-height" (2 passed)
✅ **Document** - passed

✅ No issues found.

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

✅ No issues found.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: afbb0d26-772b-4834-abbc-863f2a0966f5
📥 Commits

Reviewing files that changed from the base of the PR and between d77ca12 and fdd4c50.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 46ef6e09-24d7-4153-8a25-8fe9c58be676
📥 Commits

Reviewing files that changed from the base of the PR and between b2d9217 and d77ca12.

📒 Files selected for processing: 3
  • DESIGN.md
  • src/__testing__/theme.test.ts
  • src/theme/components/outlinedinput.modifier.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

📝 Walkthrough

The input-field design specifications now set height to 56px. The outlined input theme now sets line height to 1.4375em at the root and small breakpoint. Tests check the line-height value in light and dark themes.

Changes: Input field styling

Layer / File(s) Summary
Input-field design dimensions
DESIGN.md
The light and dark input-field specifications now set height to 56px.
Outlined input line height
src/theme/components/outlinedinput.modifier.ts, src/__testing__/theme.test.ts
The outlined input theme sets root and small-breakpoint line height to 1.4375em. Tests check this value in light and dark modes.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: winkletinkle

Merge Risk: ⚪ Minimal · up to d77ca

The change restores MUI’s standard outlined-field line-height and documents the 56px input-field height. No concrete merge-blocking risk remains.

Pre-merge checks: Passed 5
Check name Status Explanation
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: aligning outlined Select height with TextField at 56px through the MuiOutlinedInput line-height update and design token changes.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ld height

textB1Regular's 1.75rem body line-height was spread onto the MuiOutlinedInput
root. Select sizes its display div from the inherited line-height while the
TextField input has a fixed 1.4375em height, so outlined Selects rendered
61px (small: 45px) against 56px (small: 40px) TextFields. Restore MUI's
InputBase line-height on the root and the sm breakpoint.

Signed-off-by: Cooper Fitzgerald <182300328+fitzergerald@users.noreply.github.com>
Signed-off-by: Cooper Fitzgerald <182300328+fitzergerald@users.noreply.github.com>
@fitzergerald
fitzergerald force-pushed the fm/sistent-field-height-consistency branch from d77ca12 to fdd4c50 Compare October 17, 2026 22:00
@fitzergerald

Copy link
Copy Markdown
Contributor

Visual proof

TextField / Select / Autocomplete side by side, every variant and size, measured as the .MuiInputBase-root height (px) in Chrome. Light and dark measure the same.

variant/size TextField Select Autocomplete
outlined/medium (before) 56 61 56
outlined/small (before) 40 45 40
outlined/medium (after) 56 56 56
outlined/small (after) 40 40 40
filled medium/small (unchanged) 56/48 56/48 56/48
standard medium/small (unchanged) 32/29 32/29 32/29
Before (light) After (light)
before light after light
Before (dark) After (dark)
before dark after dark

Consumer note: multiline outlined TextFields now use MUI's default 1.4375em line spacing instead of 1.75rem, so a rows={4} field is about 20px shorter.

@pontusringblom
pontusringblom merged commit f3122af into master Oct 17, 2026
6 checks passed
@pontusringblom
pontusringblom deleted the fm/sistent-field-height-consistency branch October 17, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants