Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions apps/web/src/components/DiffPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,9 @@ export default function DiffPanel({
</Tooltip>
)}
<ToggleGroup
className="shrink-0 gap-1"
size="sm"
aria-label="Diff layout"
className="shrink-0"
variant="segmented"
value={[diffLayout]}
onValueChange={(value) => {
const next = value[0];
Expand All @@ -810,10 +811,10 @@ export default function DiffPanel({
}
}}
>
<Toggle aria-label="Stacked diff view" value="stacked" variant="ghost">
<Toggle aria-label="Stacked diff view" value="stacked">
<Rows3Icon className="size-3.5" />
</Toggle>
<Toggle aria-label="Split diff view" value="split" variant="ghost">
<Toggle aria-label="Split diff view" value="split">
<Columns2Icon className="size-3.5" />
</Toggle>
</ToggleGroup>
Expand Down
42 changes: 20 additions & 22 deletions apps/web/src/components/GitActionsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { Radio as RadioPrimitive } from "@base-ui/react/radio";
import { AzureDevOpsIcon, BitbucketIcon, GitHubIcon, GitLabIcon } from "~/components/Icons";
import { RadioGroup } from "~/components/ui/radio-group";
import { Spinner } from "~/components/ui/spinner";
import { toggleVariants } from "~/components/ui/toggle";
import { cn } from "~/lib/utils";
import {
buildGitActionProgressStages,
Expand Down Expand Up @@ -831,32 +832,29 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) {
Protocol
</span>
<RadioGroup
className="w-fit flex-row gap-0.5 rounded-lg bg-input/40 p-0.5"
Comment thread
maria-rcks marked this conversation as resolved.
value={publishProtocol}
onValueChange={(value) =>
setPublishProtocol(value as SourceControlCloneProtocol)
}
onValueChange={(protocol) => {
if (protocol === "ssh" || protocol === "https") {
setPublishProtocol(protocol);
}
}}
aria-labelledby="publish-protocol-label"
disabled={publishRepositoryAction.isPending}
className="grid grid-cols-2 gap-2"
>
{(["ssh", "https"] as const).map((value) => {
const isSelected = publishProtocol === value;
return (
<RadioPrimitive.Root
key={value}
value={value}
className={cn(
"rounded-md border px-3 py-1.5 text-center text-sm font-medium outline-none transition",
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
isSelected
? "border-primary bg-background ring-2 ring-primary/35 text-foreground dark:border-transparent dark:bg-primary/10 dark:ring-1 dark:ring-primary/30"
: "border-border bg-background text-muted-foreground hover:border-foreground/20 hover:text-foreground dark:border-transparent dark:bg-white/[0.035]",
)}
>
{value === "ssh" ? "SSH" : "HTTPS"}
</RadioPrimitive.Root>
);
})}
{(["ssh", "https"] as const).map((protocol) => (
<RadioPrimitive.Root
key={protocol}
value={protocol}
data-pressed={publishProtocol === protocol ? "" : undefined}
className={toggleVariants({
variant: "segmented",
size: "segmented",
})}
>
{protocol.toUpperCase()}
</RadioPrimitive.Root>
))}
</RadioGroup>
</div>
</div>
Expand Down
9 changes: 5 additions & 4 deletions apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1138,8 +1138,9 @@ export function PullRequestCodeTab({
</Tooltip>
) : null}
<ToggleGroup
className="shrink-0 gap-1"
size="sm"
aria-label="Diff layout"
className="shrink-0"
variant="segmented"
value={[diffLayout]}
onValueChange={(value) => {
const next = value[0];
Expand All @@ -1148,10 +1149,10 @@ export function PullRequestCodeTab({
}
}}
>
<Toggle aria-label="Stacked diff view" value="stacked" variant="ghost">
<Toggle aria-label="Stacked diff view" value="stacked">
<Rows3Icon className="size-3.5" />
</Toggle>
<Toggle aria-label="Split diff view" value="split" variant="ghost">
<Toggle aria-label="Split diff view" value="split">
<Columns2Icon className="size-3.5" />
</Toggle>
</ToggleGroup>
Expand Down
32 changes: 14 additions & 18 deletions apps/web/src/components/pullRequest/PullRequestMarkdownEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { cn } from "~/lib/utils";

import { Button } from "../ui/button";
import { Textarea } from "../ui/textarea";
import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { PullRequestMarkdown } from "./PullRequestMarkdown";

/**
Expand Down Expand Up @@ -64,24 +65,19 @@ export function PullRequestMarkdownEditor({
onCancel();
}}
>
<div className="flex items-center gap-1">
<Button
size="xs"
variant={preview ? "ghost" : "outline"}
disabled={saving}
onClick={() => setPreview(false)}
>
Write
</Button>
<Button
size="xs"
variant={preview ? "outline" : "ghost"}
disabled={saving}
onClick={() => setPreview(true)}
>
Preview
</Button>
</div>
<ToggleGroup
aria-label="Markdown editor mode"
variant="segmented"
value={[preview ? "preview" : "write"]}
disabled={saving}
onValueChange={(next) => {
const mode = next[0];
if (mode === "write" || mode === "preview") setPreview(mode === "preview");
}}
>
<Toggle value="write">Write</Toggle>
<Toggle value="preview">Preview</Toggle>
</ToggleGroup>
{preview ? (
<div className="rounded-lg border border-border/60 px-3 py-2">
{empty ? (
Expand Down
27 changes: 15 additions & 12 deletions apps/web/src/components/settings/DiagnosticsSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { usePrimaryEnvironment } from "../../state/environments";
import { useCopyToClipboard } from "../../hooks/useCopyToClipboard";
import { Button } from "../ui/button";
import { ScrollArea } from "../ui/scroll-area";
import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { toastManager } from "../ui/toast";
import { ExpandableText } from "./ExpandableText";
Expand Down Expand Up @@ -599,21 +600,23 @@ function ResourceHistoryWindowSelector({
onSelect: (windowMs: number) => void;
}) {
return (
<div className="flex items-center rounded-md border border-border/60 p-0.5">
<ToggleGroup
aria-label="Process history period"
variant="segmented"
value={[String(selectedWindowMs)]}
onValueChange={(next) => {
const selected = RESOURCE_HISTORY_WINDOWS.find(
(option) => String(option.windowMs) === next[0],
);
if (selected) onSelect(selected.windowMs);
}}
>
{RESOURCE_HISTORY_WINDOWS.map((option) => (
<button
key={option.windowMs}
type="button"
className={cn(
"cursor-pointer h-6 rounded-sm px-2 text-[11px] font-medium text-muted-foreground hover:text-foreground",
selectedWindowMs === option.windowMs && "bg-muted text-foreground",
)}
onClick={() => onSelect(option.windowMs)}
>
<Toggle key={option.windowMs} value={String(option.windowMs)}>
{option.label}
</button>
</Toggle>
))}
</div>
</ToggleGroup>
);
}

Expand Down
25 changes: 14 additions & 11 deletions apps/web/src/components/settings/ProviderSettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import {
NumberFieldInput,
} from "../ui/number-field";
import { ScrollArea } from "../ui/scroll-area";
import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { stackedThreadToast, toastManager } from "../ui/toast";
import { AddProviderInstanceDialog } from "./AddProviderInstanceDialog";
Expand All @@ -80,7 +81,6 @@ import { ProviderInstanceCard } from "./ProviderInstanceCard";
import { UsageProviderSettings } from "./UsageProviderSettings";
import { ProviderSetupSection, readAntigravityAuthMethod } from "./ProviderSetupSection";
import { DRIVER_OPTIONS, getDriverOption } from "./providerDriverMeta";
import { providerSettingsTabClassName } from "./providerSettingsTabs";
import { searchableSetting } from "./settingsSearch";
import {
backgroundActivityOverrideSettings,
Expand Down Expand Up @@ -326,22 +326,25 @@ function ProviderSettingsPanelContent(target: ProviderSettingsTarget) {
const deviceTabs =
!onlyPrimaryDevice && options.length > 0 ? (
<ScrollArea hideScrollbars scrollFade className="h-11 min-w-0 flex-1 rounded-none">
<div role="group" aria-label="Devices" className="flex h-full w-max min-w-full px-1">
<ToggleGroup
aria-label="Devices"
variant="segmented"
className="my-2"
value={effectiveEnvironmentId ? [effectiveEnvironmentId] : []}
onValueChange={(next) => {
const environment = options.find((option) => option.environmentId === next[0]);
if (environment) setSelectedEnvironmentId(environment.environmentId);
}}
>
{options.map((environment) => {
const machine = resolveEnvironmentMachineKind(environment.serverConfig);
const selected = environment.environmentId === effectiveEnvironmentId;
const detail = providerEnvironmentDetail(environment);
const statusText = connectionStatusTitle(environment.connection);
return (
<Tooltip key={environment.environmentId}>
<TooltipTrigger
render={
<button
type="button"
aria-pressed={selected}
className={cn(providerSettingsTabClassName(selected), "gap-2 text-left")}
onClick={() => setSelectedEnvironmentId(environment.environmentId)}
>
<Toggle value={environment.environmentId} className="gap-2 text-left">
<EnvironmentMachineIcon
kind={machine}
className="size-3.5 shrink-0"
Expand All @@ -357,7 +360,7 @@ function ProviderSettingsPanelContent(target: ProviderSettingsTarget) {
<span className="sr-only">
{detail}, {statusText}
</span>
</button>
</Toggle>
}
/>
<TooltipPopup side="top">
Expand All @@ -366,7 +369,7 @@ function ProviderSettingsPanelContent(target: ProviderSettingsTarget) {
</Tooltip>
);
})}
</div>
</ToggleGroup>
</ScrollArea>
) : null;

Expand Down
25 changes: 13 additions & 12 deletions apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { useAtomCommand } from "../../state/use-atom-command";
import { formatRelativeTime } from "../../timestampFormat";
import { Button } from "../ui/button";
import { ScrollArea } from "../ui/scroll-area";
import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { toastManager } from "../ui/toast";
import {
Expand Down Expand Up @@ -378,21 +379,21 @@ function HistoryWindowSelector({
onSelect: (windowMs: number) => void;
}) {
return (
<div className="flex items-center rounded-md border border-border/60 p-0.5">
<ToggleGroup
aria-label="Resource history period"
variant="segmented"
value={[String(selectedWindowMs)]}
onValueChange={(next) => {
const selected = HISTORY_WINDOWS.find((option) => String(option.windowMs) === next[0]);
if (selected) onSelect(selected.windowMs);
}}
>
{HISTORY_WINDOWS.map((option) => (
<button
key={option.windowMs}
type="button"
className={cn(
"cursor-pointer h-6 rounded-sm px-2 text-[11px] font-medium text-muted-foreground hover:text-foreground",
selectedWindowMs === option.windowMs && "bg-muted text-foreground",
)}
onClick={() => onSelect(option.windowMs)}
>
<Toggle key={option.windowMs} value={String(option.windowMs)}>
{option.label}
</button>
</Toggle>
))}
</div>
</ToggleGroup>
);
}

Expand Down
31 changes: 19 additions & 12 deletions apps/web/src/components/settings/ThemeEditorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { cn } from "../../lib/utils";
import { Button } from "../ui/button";
import { Input } from "../ui/input";
import { Switch } from "../ui/switch";
import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { getThemeRoleLabel, ThemeColorField } from "./ThemeColorPicker";
import {
Expand Down Expand Up @@ -942,24 +943,17 @@ export function ThemeEditorPanel({
);

const renderAppearanceButton = (appearance: ThemeAppearance) => {
const isActive = activeAppearance === appearance;
const lockReason = appearanceLockReason(appearance);
// A locked mode stays hoverable so the tooltip can say why it is off;
// a real disabled attribute would swallow the pointer events.
const button = (
<Button
<Toggle
aria-disabled={lockReason !== null}
aria-pressed={isActive}
size="sm"
value={appearance}
className={lockReason !== null ? "opacity-50" : undefined}
style={isActive ? { boxShadow: "inset 0 0 0 1px var(--ring)" } : undefined}
variant={isActive ? "secondary" : "outline"}
onClick={() => {
if (lockReason === null) setActiveAppearance(appearance);
}}
>
{appearance === "light" ? "Light" : "Dark"}
</Button>
</Toggle>
);
if (lockReason === null) return button;
return (
Expand All @@ -973,10 +967,23 @@ export function ThemeEditorPanel({
const renderAppearanceButtons = () => (
<div className="grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)] items-center gap-3">
<span className="text-sm font-medium">Appearance</span>
<div aria-label="Theme appearance" className="grid grid-cols-2 gap-2" role="group">
<ToggleGroup
aria-label="Theme appearance"
variant="segmented"
value={[activeAppearance]}
onValueChange={(next) => {
const appearance = next[0];
if (
(appearance === "light" || appearance === "dark") &&
appearanceLockReason(appearance) === null
) {
setActiveAppearance(appearance);
}
}}
>
{renderAppearanceButton("light")}
{renderAppearanceButton("dark")}
</div>
</ToggleGroup>
</div>
);

Expand Down
10 changes: 0 additions & 10 deletions apps/web/src/components/settings/providerSettingsTabs.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/web/src/components/ui/toggle-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariant

function ToggleGroup({
className,
variant = "default",
variant = "segmented",
size = variant === "segmented" ? "segmented" : "default",
orientation = "horizontal",
children,
Expand Down
Loading