diff --git a/src/Web/autopilot-monitor-web/components/members/AddMemberForm.tsx b/src/Web/autopilot-monitor-web/components/members/AddMemberForm.tsx
index a080c578..7e194e5e 100644
--- a/src/Web/autopilot-monitor-web/components/members/AddMemberForm.tsx
+++ b/src/Web/autopilot-monitor-web/components/members/AddMemberForm.tsx
@@ -15,8 +15,10 @@ interface AddMemberFormProps {
/** Read-only caller: the form stays visible but cannot submit. */
disabled?: boolean;
/**
- * The input always takes a line of its own. For narrow hosts such as the GA tenant editor modal,
- * where the viewport breakpoint says "wide" but the type switch, role and button leave the input no room.
+ * The input always takes a line of its own (the GA tenant editor modal). Without it the input keeps a
+ * minimum width and wraps to the next line when the row has no room; the layout follows the space the
+ * host gives it, never a viewport breakpoint, because the same viewport can mean a wide page or a narrow
+ * column next to the sidebar.
*/
stacked?: boolean;
}
@@ -73,7 +75,7 @@ export function AddMemberForm({
placeholder={addingApplication ? "Application (client) ID, e.g. 00000000-0000-0000-0000-000000000000" : "user@tenant.com"}
aria-label={addingApplication ? "Application (client) ID" : "User email (UPN)"}
autoComplete="off"
- className={`${stacked ? "w-full" : "w-full sm:w-auto sm:flex-1"} min-w-0 px-4 py-2 border border-gray-300 rounded-lg text-gray-900 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors`}
+ className={`${stacked ? "basis-full" : "grow basis-72"} min-w-0 px-4 py-2 border border-gray-300 rounded-lg text-gray-900 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors`}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
@@ -81,40 +83,42 @@ export function AddMemberForm({
}
}}
/>
-
-
+
+
+
+
);
diff --git a/src/Web/autopilot-monitor-web/components/members/__tests__/AddMemberForm.test.ts b/src/Web/autopilot-monitor-web/components/members/__tests__/AddMemberForm.test.ts
index 4b10e574..ea653ebe 100644
--- a/src/Web/autopilot-monitor-web/components/members/__tests__/AddMemberForm.test.ts
+++ b/src/Web/autopilot-monitor-web/components/members/__tests__/AddMemberForm.test.ts
@@ -5,8 +5,8 @@ import { AddMemberForm } from "../AddMemberForm";
const noop = () => {};
-function inputClass(stacked?: boolean): string {
- const html = renderToStaticMarkup(
+function render(stacked?: boolean): string {
+ return renderToStaticMarkup(
createElement(AddMemberForm, {
value: "",
onValueChange: noop,
@@ -19,19 +19,29 @@ function inputClass(stacked?: boolean): string {
stacked,
}),
);
+}
+
+function inputClasses(html: string): string[] {
const input = html.match(/]*name="new-member"[^>]*>/)?.[0] ?? "";
- return input.match(/class="([^"]*)"/)?.[1] ?? "";
+ return (input.match(/class="([^"]*)"/)?.[1] ?? "").split(" ");
}
describe("AddMemberForm", () => {
- it("shares a row with the type switch, role and button from the sm breakpoint by default", () => {
- expect(inputClass().split(" ")).toEqual(expect.arrayContaining(["w-full", "sm:w-auto", "sm:flex-1"]));
+ it("keeps a minimum width for the input and wraps instead of squeezing it, whatever the viewport", () => {
+ const classes = inputClasses(render());
+ expect(classes).toEqual(expect.arrayContaining(["grow", "basis-72", "min-w-0"]));
+ // No viewport breakpoint decides the layout: a wide window can still host a narrow column.
+ expect(classes.filter((c) => /^(sm|md|lg|xl):/.test(c))).toEqual([]);
});
- it("gives the input a line of its own when stacked (narrow hosts like the GA tenant editor)", () => {
- const classes = inputClass(true).split(" ");
- expect(classes).toContain("w-full");
- expect(classes).not.toContain("sm:w-auto");
- expect(classes).not.toContain("sm:flex-1");
+ it("gives the input a line of its own when stacked (the GA tenant editor modal)", () => {
+ const classes = inputClasses(render(true));
+ expect(classes).toContain("basis-full");
+ expect(classes).not.toContain("basis-72");
+ });
+
+ it("keeps role and Add together, so they wrap as one unit", () => {
+ const html = render();
+ expect(html).toMatch(/