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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user