ui(settings): Quit/Uninstall as real buttons with icons and a busy spinner; code in row descriptions; dimmed unavailable rows; smoother switch
This commit is contained in:
@@ -33,13 +33,16 @@ export function Switch({
|
||||
// On: the solid accent (white knob clears 3:1 in every theme). Off: a
|
||||
// border-light track with an inset fg-muted/80 ring (≥3:1 in every theme), so the control's edge
|
||||
// is visible on any surface (surface-4 alone was ~1:1 on a light card).
|
||||
className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-50 ${
|
||||
checked ? "bg-accent-solid" : "bg-border-light ring-1 ring-inset ring-fg-muted/80"
|
||||
// Hover darkens the track (enabled only), so it reads as clickable.
|
||||
className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 ${
|
||||
checked
|
||||
? "bg-accent-solid enabled:hover:bg-accent-solid-hover"
|
||||
: "bg-border-light ring-1 ring-inset ring-fg-muted/80 enabled:hover:ring-fg-secondary"
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className={`inline-block h-4 w-4 rounded-full bg-white shadow transition-transform ${
|
||||
className={`inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-1 ring-black/10 transition-transform duration-200 ease-out ${
|
||||
checked ? "translate-x-[18px]" : "translate-x-0.5"
|
||||
}`}
|
||||
/>
|
||||
|
||||
@@ -9,17 +9,24 @@
|
||||
* boot/login while the switch is on. Between them, the status-area icon switch
|
||||
* (`GET/PUT /api/settings/tray`, on by default — server/lib/tray.js). Last,
|
||||
* **Uninstall AgentHub**: `POST /api/settings/uninstall` removes AgentHub from
|
||||
* the machine, database included (scripts/uninstall.js).
|
||||
* the machine, database included (scripts/uninstall.js). Quit is a plain
|
||||
* button and Uninstall a danger one, both the same width with an icon, and
|
||||
* each spins while its request runs.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Loader2, Power, Trash2 } from "lucide-react";
|
||||
import { api, type AutostartStatus, type TrayStatus } from "../../lib/api";
|
||||
import { toast } from "../../lib/toast";
|
||||
import { confirmDialog } from "../../lib/confirm";
|
||||
import { SettingsRow, SettingsSection, SettingsSwitchRow } from "./SettingsRow";
|
||||
|
||||
// The two action buttons share one width, so they line up under the switches.
|
||||
const ACTION = "min-w-[6.5rem] justify-center text-xs";
|
||||
const ICON = "h-3.5 w-3.5 shrink-0";
|
||||
|
||||
export function AutostartSettings() {
|
||||
const { t } = useTranslation("settings");
|
||||
const [status, setStatus] = useState<AutostartStatus | null>(null);
|
||||
@@ -126,9 +133,11 @@ export function AutostartSettings() {
|
||||
type="button"
|
||||
data-testid="quit-agenthub"
|
||||
disabled={quitting}
|
||||
aria-busy={quitting}
|
||||
onClick={() => void quit()}
|
||||
className="btn-ghost text-xs text-status-danger disabled:opacity-40"
|
||||
className={`btn-secondary ${ACTION}`}
|
||||
>
|
||||
{quitting ? <Loader2 className={ICON + " animate-spin"} /> : <Power className={ICON} />}
|
||||
{t("quit.button")}
|
||||
</button>
|
||||
}
|
||||
@@ -141,9 +150,15 @@ export function AutostartSettings() {
|
||||
type="button"
|
||||
data-testid="uninstall-agenthub"
|
||||
disabled={uninstalling}
|
||||
aria-busy={uninstalling}
|
||||
onClick={() => void uninstall()}
|
||||
className="btn-ghost text-xs text-status-danger disabled:opacity-40"
|
||||
className={`btn-danger ${ACTION}`}
|
||||
>
|
||||
{uninstalling ? (
|
||||
<Loader2 className={ICON + " animate-spin"} />
|
||||
) : (
|
||||
<Trash2 className={ICON} />
|
||||
)}
|
||||
{t("uninstall.button")}
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
* switch row (`SettingsSwitchRow`) and a segmented radio group
|
||||
* (`SettingsSegmented`, arrow keys + one roving tab stop). Rows divide
|
||||
* themselves with a hairline, none after the last, so a section is just its
|
||||
* rows in order.
|
||||
* rows in order. A string description shows its `backticked` words as code,
|
||||
* and a `disabled` row dims its label, so an unavailable control reads as one.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
@@ -32,30 +33,55 @@ export function SettingsSection({
|
||||
);
|
||||
}
|
||||
|
||||
/** `text` with every `backticked` run drawn as inline code (a command to type). */
|
||||
export function withCode(text: string): ReactNode {
|
||||
const parts = text.split(/`([^`]+)`/);
|
||||
if (parts.length === 1) return text;
|
||||
return parts.map((p, i) =>
|
||||
i % 2 ? (
|
||||
<code
|
||||
key={i}
|
||||
className="whitespace-nowrap rounded border border-border bg-surface-2 px-1 py-px font-mono text-[11px] text-fg-secondary"
|
||||
>
|
||||
{p}
|
||||
</code>
|
||||
) : (
|
||||
p
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function SettingsRow({
|
||||
label,
|
||||
description,
|
||||
control,
|
||||
alignTop = false,
|
||||
disabled = false,
|
||||
id,
|
||||
}: {
|
||||
label: ReactNode;
|
||||
description?: ReactNode;
|
||||
control: ReactNode;
|
||||
alignTop?: boolean;
|
||||
/** The control cannot be used here: the label is dimmed with it. */
|
||||
disabled?: boolean;
|
||||
/** A deep-link anchor (`#id`) for one row inside a grouped section. */
|
||||
id?: string;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
id={id}
|
||||
className={`${id ? "scroll-mt-24 " : ""}flex justify-between gap-4 border-b border-border/60 last:border-b-0 ${
|
||||
className={`${id ? "scroll-mt-24 " : ""}flex justify-between gap-6 border-b border-border/60 last:border-b-0 ${
|
||||
description ? "py-3" : "py-2"
|
||||
} ${alignTop ? "items-start" : "items-center"}`}
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm text-fg-secondary">{label}</p>
|
||||
{description && <p className="mt-0.5 text-xs text-fg-muted">{description}</p>}
|
||||
<p className={`text-sm ${disabled ? "text-fg-muted" : "text-fg-secondary"}`}>{label}</p>
|
||||
{description && (
|
||||
<p className="mt-0.5 text-xs leading-relaxed text-fg-muted">
|
||||
{typeof description === "string" ? withCode(description) : description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="shrink-0">{control}</div>
|
||||
</div>
|
||||
@@ -82,6 +108,7 @@ export function SettingsSwitchRow({
|
||||
id={id}
|
||||
label={label}
|
||||
description={description}
|
||||
disabled={disabled}
|
||||
control={<Switch checked={checked} onChange={onChange} label={label} disabled={disabled} />}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -7022,7 +7022,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
class="mt-2"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7033,7 +7033,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Start AgentHub automatically
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
Run the dashboard as a systemd --user service, so it starts at boot without Claude Code being opened. Turning it off keeps the running server up.
|
||||
</p>
|
||||
@@ -7044,19 +7044,19 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
<button
|
||||
aria-checked="false"
|
||||
aria-label="Start AgentHub automatically"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-50 bg-border-light ring-1 ring-inset ring-fg-muted/80"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 bg-border-light ring-1 ring-inset ring-fg-muted/80 enabled:hover:ring-fg-secondary"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow transition-transform translate-x-0.5"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-1 ring-black/10 transition-transform duration-200 ease-out translate-x-0.5"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7067,7 +7067,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Show AgentHub icon in the status area
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
An AgentHub icon beside the clock (top bar, menu bar or notification area) to open the dashboard, quit it, and start it again after a quit.
|
||||
</p>
|
||||
@@ -7078,19 +7078,19 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
<button
|
||||
aria-checked="true"
|
||||
aria-label="Show AgentHub icon in the status area"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-50 bg-accent-solid"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 bg-accent-solid enabled:hover:bg-accent-solid-hover"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow transition-transform translate-x-[18px]"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-1 ring-black/10 transition-transform duration-200 ease-out translate-x-[18px]"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7101,25 +7101,51 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Quit AgentHub
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
Stop the dashboard so nothing runs in the background. Opening Claude Code no longer starts it; run \`agenthub start\` to bring it back.
|
||||
Stop the dashboard so nothing runs in the background. Opening Claude Code no longer starts it; run
|
||||
<code
|
||||
class="whitespace-nowrap rounded border border-border bg-surface-2 px-1 py-px font-mono text-[11px] text-fg-secondary"
|
||||
>
|
||||
agenthub start
|
||||
</code>
|
||||
to bring it back.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="shrink-0"
|
||||
>
|
||||
<button
|
||||
class="btn-ghost text-xs text-status-danger disabled:opacity-40"
|
||||
aria-busy="false"
|
||||
class="btn-secondary min-w-[6.5rem] justify-center text-xs"
|
||||
data-testid="quit-agenthub"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
class="lucide lucide-power h-3.5 w-3.5 shrink-0"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 2v10"
|
||||
/>
|
||||
<path
|
||||
d="M18.4 6.6a9 9 0 1 1-12.77.04"
|
||||
/>
|
||||
</svg>
|
||||
Quit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7130,7 +7156,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Uninstall AgentHub
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
Remove AgentHub from this computer: the dashboard, its database and settings, its hooks in Claude Code, Codex and Antigravity, and the plugin. Your conversations, workspace folders and repositories are kept.
|
||||
</p>
|
||||
@@ -7139,10 +7165,45 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
class="shrink-0"
|
||||
>
|
||||
<button
|
||||
class="btn-ghost text-xs text-status-danger disabled:opacity-40"
|
||||
aria-busy="false"
|
||||
class="btn-danger min-w-[6.5rem] justify-center text-xs"
|
||||
data-testid="uninstall-agenthub"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
class="lucide lucide-trash2 h-3.5 w-3.5 shrink-0"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 6h18"
|
||||
/>
|
||||
<path
|
||||
d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"
|
||||
/>
|
||||
<path
|
||||
d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"
|
||||
/>
|
||||
<line
|
||||
x1="10"
|
||||
x2="10"
|
||||
y1="11"
|
||||
y2="17"
|
||||
/>
|
||||
<line
|
||||
x1="14"
|
||||
x2="14"
|
||||
y1="11"
|
||||
y2="17"
|
||||
/>
|
||||
</svg>
|
||||
Uninstall
|
||||
</button>
|
||||
</div>
|
||||
@@ -7162,7 +7223,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
class="mt-2"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7173,7 +7234,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Release
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
<span
|
||||
class="text-status-warning/90"
|
||||
@@ -7193,7 +7254,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7215,7 +7276,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7240,7 +7301,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7262,7 +7323,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7284,7 +7345,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7295,7 +7356,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Live connections
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
Browser tabs and tools receiving live updates
|
||||
</p>
|
||||
@@ -7325,7 +7386,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
class="mt-2"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7355,7 +7416,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
class="mt-2"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7366,7 +7427,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
Database file
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
<span
|
||||
class="font-mono break-all"
|
||||
@@ -7386,7 +7447,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -7408,7 +7469,7 @@ exports[`screen snapshots > Settings — about 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -8960,7 +9021,7 @@ exit 0
|
||||
class="mt-2"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-3 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -8971,7 +9032,7 @@ exit 0
|
||||
Redact secrets before storing
|
||||
</p>
|
||||
<p
|
||||
class="mt-0.5 text-xs text-fg-muted"
|
||||
class="mt-0.5 text-xs leading-relaxed text-fg-muted"
|
||||
>
|
||||
API keys and tokens of known shapes, bearer headers, private keys and password=/TOKEN= values in event payloads and summaries become [redacted]. The transcripts on disk are the CLIs' own files and are not changed.
|
||||
</p>
|
||||
@@ -8982,13 +9043,13 @@ exit 0
|
||||
<button
|
||||
aria-checked="false"
|
||||
aria-label="Redact secrets before storing"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-50 bg-border-light ring-1 ring-inset ring-fg-muted/80"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 bg-border-light ring-1 ring-inset ring-fg-muted/80 enabled:hover:ring-fg-secondary"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow transition-transform translate-x-0.5"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-1 ring-black/10 transition-transform duration-200 ease-out translate-x-0.5"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
@@ -9739,7 +9800,7 @@ exports[`screen snapshots > Settings — notifications 1`] = `
|
||||
class="min-w-0 flex-1"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between gap-4 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
class="flex justify-between gap-6 border-b border-border/60 last:border-b-0 py-2 items-center"
|
||||
>
|
||||
<div
|
||||
class="min-w-0"
|
||||
@@ -9756,13 +9817,13 @@ exports[`screen snapshots > Settings — notifications 1`] = `
|
||||
<button
|
||||
aria-checked="false"
|
||||
aria-label="Enable Browser Notifications"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-50 bg-border-light ring-1 ring-inset ring-fg-muted/80"
|
||||
class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 bg-border-light ring-1 ring-inset ring-fg-muted/80 enabled:hover:ring-fg-secondary"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow transition-transform translate-x-0.5"
|
||||
class="inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-1 ring-black/10 transition-transform duration-200 ease-out translate-x-0.5"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user