From 50cf89b20ab4c19b62c4810ed5f89e00f59c0d96 Mon Sep 17 00:00:00 2001 From: Roland Date: Thu, 30 Jul 2026 15:12:18 -0600 Subject: [PATCH] ui: PathInput, and the media directory stops printing over the value The five Special Directories fields on the Settings page were unreadable: the media directory printed straight through the value, so Archive Directory showed `a/media/wrolpi/hain_tag)s/%(domain)s`. Cause: `leftSectionWidth='auto'`. Mantine turns that prop into `--input-padding-inline-start`, and `padding-inline-start: auto` is not valid CSS -- it resolves to zero, so the input reserved no room for the section positioned on top of it. It fails only in CSS, only at runtime, and nothing warns. Fixed by expressing the field in the library instead of computing a width. PathInput puts the prefix and the input side by side in a flex row sharing one outline, so there is no width to get wrong and nothing to overlap -- the failure is structurally impossible rather than merely corrected. It also sizes to any prefix, which matters because the media directory is `/media/wrolpi` on a Pi and something else under Docker. Written test-first, and the tests need no mocks at all -- no context, no fetch, no router, just the provider test-utils already supplies. That is the point: Settings.js needs a pile of provider and API mocks, so its inputs were never covered, which is how five broken fields shipped. The tests assert the things that actually matter and can be checked without layout: the prefix is a sibling rather than a child, the value never contains it, onChange reports only what was typed, the prefix is the field's accessible description so a screen-reader user knows what the path is relative to, and disabled reaches the input rather than just the wrapper. Plus a source guard, since jsdom cannot see an overlap: nothing may pass `leftSectionWidth='auto'` or `rightSectionWidth='auto'`. It strips comments first -- PathInput documents the mistake by name, and prose about a mistake is not the mistake. --- app/src/components/ThemeSamplePage.js | 9 +++ app/src/components/admin/Settings.js | 26 +++---- app/src/components/ui/Inputs.tsx | 62 ++++++++++++++- app/src/components/ui/ui.css | 85 +++++++++++++++++++++ app/src/components/ui/ui.test.js | 106 ++++++++++++++++++++++++++ 5 files changed, 272 insertions(+), 16 deletions(-) diff --git a/app/src/components/ThemeSamplePage.js b/app/src/components/ThemeSamplePage.js index fc898fd9..bde6a425 100644 --- a/app/src/components/ThemeSamplePage.js +++ b/app/src/components/ThemeSamplePage.js @@ -16,6 +16,7 @@ import { Modal, Pagination, Panel, + PathInput, Placeholder, Progress, SearchBox, @@ -281,6 +282,14 @@ export function ThemeSamplePage() {