Improve operational UX, recovery flows, and action safety

Implement the approved UX review across Fleet, Betas, Library, deployments, and Settings. Add reviewed promotion and reconciliation plans, atomic queued-removal cancellation, recoverable beta drafts and launch inputs, accessible controls, and mobile improvements.

Validated with 473 tests, a clean typecheck, production build, and isolated desktop/mobile browser walkthroughs. Include the review and implementation coverage notes.
This commit is contained in:
2026-09-19 21:34:34 -04:00
parent 940f81e6ca
commit 8ac420fe61
83 changed files with 2574 additions and 1190 deletions
+28 -1
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { tick } from 'svelte';
interface Tab {
id: string;
label: string;
@@ -18,6 +19,32 @@
const uid = $props.id();
let { tabs, value = $bindable(), onchange, ariaLabel, size = 'md', panelId, idPrefix = uid }: Props = $props();
let tablist = $state<HTMLDivElement | null>(null);
// Keep a deep-linked or keyboard-selected tab visible without scrolling the page.
$effect(() => {
const selected = value;
const node = tablist;
if (!node) return;
let cancelled = false;
let observer: ResizeObserver | undefined;
void tick().then(() => {
if (cancelled) return;
const tab = document.getElementById(`${idPrefix}-${selected}`);
if (!tab) return;
const reveal = () => {
const bounds = node.getBoundingClientRect();
const target = tab.getBoundingClientRect();
if (target.left < bounds.left + 4) node.scrollLeft -= bounds.left + 4 - target.left;
else if (target.right > bounds.right - 4) node.scrollLeft += target.right - bounds.right + 4;
};
reveal();
observer = new ResizeObserver(reveal);
observer.observe(node);
observer.observe(tab);
});
return () => { cancelled = true; observer?.disconnect(); };
});
function onKey(event: KeyboardEvent) {
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;
@@ -38,7 +65,7 @@
}
</script>
<div class="tabs s-{size}" role="tablist" aria-label={ariaLabel}>
<div class="tabs s-{size}" role="tablist" aria-label={ariaLabel} bind:this={tablist}>
{#each tabs as t (t.id)}
<button
type="button"