diff --git a/apps/yaak-proxy/harness/fixtures.ts b/apps/yaak-proxy/harness/fixtures.ts index 0bca85476..333b5d310 100644 --- a/apps/yaak-proxy/harness/fixtures.ts +++ b/apps/yaak-proxy/harness/fixtures.ts @@ -92,10 +92,15 @@ const multipartRequest = [ "Content-Type: application/json", "", '{"pages":12,"draft":false}', + `--${multipartBoundary}`, + 'Content-Disposition: form-data; name="rows"; filename="rows.csv"', + "Content-Type: text/csv", + "", + "region,revenue\nnorth,1200\nsouth,980", `--${multipartBoundary}--`, "", ].join("\r\n"); -const textResponse = "Uploaded 2 parts"; +const textResponse = "Uploaded 3 parts"; const htmlResponse = "

Signed in

You can close this window.

"; // A 24x24 PNG gradient diff --git a/packages/ui/src/components/ActionsBar.tsx b/packages/ui/src/components/ActionsBar.tsx index 891d18395..918a5476b 100644 --- a/packages/ui/src/components/ActionsBar.tsx +++ b/packages/ui/src/components/ActionsBar.tsx @@ -14,7 +14,8 @@ interface Props { /** * A row of actions over the bottom-right corner of the content in an `ACTIONS_BAR_CONTAINER`: - * small bordered buttons on the surface colour, so they read over text. Each fades in while the + * small bordered buttons on the surface colour, so they read over text, each held to the height + * and radius of an `sm` icon button and centred on the row. Each fades in while the * container is hovered or the action has focus, unless it carries `PINNED_ACTION`. The row lets * clicks through to the content between its actions. */ @@ -26,6 +27,8 @@ export function ActionsBar({ children, className }: Props) { "absolute bottom-2 left-0 right-0 z-10 flex items-center justify-end gap-1", "pointer-events-none", "*:pointer-events-auto *:bg-surface *:shadow *:transition-opacity *:transform-gpu", + // Every action as tall and as round as a small icon button, so they line up + "*:h-sm *:rounded-md", "[&>:not([data-pinned])]:opacity-0", "group-hover/actions:*:opacity-100! *:focus-within:opacity-100! *:hover:opacity-100!", )} diff --git a/packages/ui/src/components/http/BodyViewModeSwitch.test.tsx b/packages/ui/src/components/http/BodyViewModeSwitch.test.tsx index ffdb05693..2098d4341 100644 --- a/packages/ui/src/components/http/BodyViewModeSwitch.test.tsx +++ b/packages/ui/src/components/http/BodyViewModeSwitch.test.tsx @@ -72,4 +72,23 @@ describe("ActionsBar", () => { expect(markup).toContain('title="Filter"'); expect(markup).toContain("data-pinned"); }); + + test("holds every action to one height and radius, centred on the row", () => { + const markup = renderToStaticMarkup( + + + , + ); + expect(markup).toContain("items-center"); + expect(markup).toContain("*:h-sm"); + expect(markup).toContain("*:rounded-md"); + }); + + test("the switch is sized to the bar's small icon buttons", () => { + const markup = renderToStaticMarkup( + {}} />, + ); + expect(markup).toContain("h-sm!"); + expect(markup).toContain("[&_[role=radio]]:h-full!"); + }); }); diff --git a/packages/ui/src/components/http/BodyViewModeSwitch.tsx b/packages/ui/src/components/http/BodyViewModeSwitch.tsx index e256b33d6..58d47f605 100644 --- a/packages/ui/src/components/http/BodyViewModeSwitch.tsx +++ b/packages/ui/src/components/http/BodyViewModeSwitch.tsx @@ -1,3 +1,4 @@ +import classNames from "classnames"; import { PINNED_ACTION } from "../ActionsBar"; import { SegmentedControl } from "../SegmentedControl"; import type { ResponseViewMode } from "./ResponseBodyViewer"; @@ -65,8 +66,12 @@ export function BodyViewModeSwitch({ pretty, value, onChange }: Props) { size="2xs" value={value} onChange={onChange} - containerClassName="w-auto" - className="p-0.5! gap-0.5! rounded-md! bg-surface! border border-border-subtle" + containerClassName="w-auto h-full" + // As tall as the bar's `sm` icon buttons, its options filling the height inside the border + className={classNames( + "h-sm! m-0! p-0.5! gap-0.5! rounded-md! bg-surface! border border-border-subtle", + "[&_[role=radio]]:h-full!", + )} options={[ { value: "pretty", ...prettyOption }, { value: "raw", ...RAW_OPTION }, diff --git a/packages/ui/src/components/viewers/MultipartViewer.tsx b/packages/ui/src/components/viewers/MultipartViewer.tsx index 0e5b5a42d..8b61a1e5b 100644 --- a/packages/ui/src/components/viewers/MultipartViewer.tsx +++ b/packages/ui/src/components/viewers/MultipartViewer.tsx @@ -275,7 +275,7 @@ function LeafBody({ } if (mediaType?.match(/csv|tab-separated/i)) { - return ; + return ; } if (mediaType?.match(/^text\/html/i) || (!binary && detectedLanguage === "html")) {