Collapse ServerSettingsForm into accordion and add subtle ListToggle variant

Wraps every section of ServerSettingsForm (Connection Mode, Custom
Headers, Request Metadata, Timeouts, OAuth Settings) in a controlled
Mantine Accordion. The accordion is driven by new required
`expandedSections` / `onExpandedSectionsChange` props so the parent
owns expand/collapse state — consistent with the dumb-component
principle.

Adds a `variant?: "default" | "subtle"` prop to ListToggle. In subtle
mode it renders as an ActionIcon with `variant="subtle"`, `color="gray"`,
and a 16px icon so it visually matches Mantine's CloseButton in modal
headers (transparent until hover).

Adds a WithSettingsModal story on UnconnectedView that presents the
form inside a Mantine Modal with a custom three-column header: subtle
ListToggle on the left (expands/collapses all sections at once),
"Server Settings" Title centered, CloseButton on the right.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-05 09:36:14 -04:00
commit 8483b98c37
2 changed files with 264 additions and 96 deletions

View file

@ -23,3 +23,19 @@ export const Collapsed: Story = {
onToggle: fn(),
},
};
export const SubtleExpanded: Story = {
args: {
compact: false,
variant: "subtle",
onToggle: fn(),
},
};
export const SubtleCollapsed: Story = {
args: {
compact: true,
variant: "subtle",
onToggle: fn(),
},
};

View file

@ -1,14 +1,27 @@
import { Button } from "@mantine/core";
import { ActionIcon, Button } from "@mantine/core";
import { RiExpandVerticalLine, RiCollapseVerticalLine } from "react-icons/ri";
export interface ListToggleProps {
compact: boolean;
onToggle: () => void;
variant?: "default" | "subtle";
}
export function ListToggle({ compact, onToggle }: ListToggleProps) {
export function ListToggle({
compact,
onToggle,
variant = "default",
}: ListToggleProps) {
const Icon = compact ? RiExpandVerticalLine : RiCollapseVerticalLine;
if (variant === "subtle") {
return (
<ActionIcon variant="subtle" color="gray" size="md" onClick={onToggle}>
<Icon size={16} />
</ActionIcon>
);
}
return (
<Button size="sm" onClick={onToggle}>
<Icon size={20} />