From c6e6657086c6a249e3defa98ac3197967433d21e Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 17:49:48 +0000 Subject: [PATCH] feat(islands): add CopyPrompt and ReadingProgress for full-guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two islands extracted from app.js for the full-guide migration (15d): - CopyPrompt: one instance per button. Reads #.textContent, copies via navigator.clipboard.writeText with a document.execCommand textarea fallback (kept because workshop venues serve the site over plain HTTP, where the clipboard API is undefined — deleting the fallback silently breaks the lab). Writes a bilingual result string to the page-owned #copy-status live region and swaps the to COPIED/COPIADO for 1800ms. Language comes from document.documentElement .lang via a MutationObserver, so 15c's toggle stays the single mechanism. - ReadingProgress: renders .reading-progress span and attaches a passive scroll listener that mirrors the existing app.js line 406 handler. Both scripts use + + diff --git a/src/components/islands/ReadingProgress.astro b/src/components/islands/ReadingProgress.astro new file mode 100644 index 0000000..ad6d2f1 --- /dev/null +++ b/src/components/islands/ReadingProgress.astro @@ -0,0 +1,57 @@ +--- +// ReadingProgress — scroll-position bar. One instance per page. +// +// Renders the same markup the legacy `full-guide/index.html` line 13 +// carried: ``. +// The scroll listener is registered with `{ passive: true }`, matching +// app.js line 406 and the rule in `.agents/rules/animation.md` that a +// passive listener is required for any handler bound to a frequently +// fired event like scroll. Animating `width` here is fine — the bar +// is a 3px element at the very top of the viewport, so layout cost +// is negligible compared to the alternative of subscribing to +// IntersectionObserver and computing progress from a single sentinel +// per section. +// +// Language: this island does not read language. It has no string +// labels and the same progress semantics apply to EN and PT. + +interface Props { + // Optional override selector. Defaults to `.reading-progress span` + // to match the legacy app.js query, in case a page renders the bar + // with a different class name. + target?: string; +} + +const { target = '.reading-progress span' } = Astro.props; +--- + + + +