From 475ebfb324df3218be4d70fcc1b30d6cf2bf43a2 Mon Sep 17 00:00:00 2001 From: dame-is Date: Fri, 8 May 2026 15:01:08 -0400 Subject: [PATCH] Refactor options page layout and styles for improved usability and accessibility. Update tab structure to simplify labels and enhance navigation. Modify header and sidebar elements for better visual hierarchy and responsiveness. Add meta tag to ensure options page opens in a new tab for compatibility with certain browsers. --- extension/entrypoints/options/App.tsx | 20 +++--- extension/entrypoints/options/index.html | 7 ++ extension/entrypoints/options/options.css | 82 ++++++++++++++--------- extension/entrypoints/popup/App.tsx | 26 +++++-- 4 files changed, 92 insertions(+), 43 deletions(-) diff --git a/extension/entrypoints/options/App.tsx b/extension/entrypoints/options/App.tsx index 536788e..76e9300 100644 --- a/extension/entrypoints/options/App.tsx +++ b/extension/entrypoints/options/App.tsx @@ -26,11 +26,11 @@ function AturiMark() { ); } -const TABS: { id: TabId; label: string; sub: string }[] = [ - { id: 'defaults', label: 'General', sub: 'Auto-redirect & popup' }, - { id: 'visibility', label: 'Waypoints', sub: 'Hide or show apps' }, - { id: 'custom', label: 'Custom waypoints', sub: 'Add your own sites' }, - { id: 'about', label: 'About', sub: 'Project, credits, feedback' }, +const TABS: { id: TabId; label: string }[] = [ + { id: 'defaults', label: 'General' }, + { id: 'visibility', label: 'Waypoints' }, + { id: 'custom', label: 'Custom' }, + { id: 'about', label: 'About' }, ]; export default function App() { @@ -58,7 +58,7 @@ export default function App() { return (
- +
{tab === 'defaults' && } diff --git a/extension/entrypoints/options/index.html b/extension/entrypoints/options/index.html index c343e2e..fb0515b 100644 --- a/extension/entrypoints/options/index.html +++ b/extension/entrypoints/options/index.html @@ -3,6 +3,13 @@ + + Aturi Settings diff --git a/extension/entrypoints/options/options.css b/extension/entrypoints/options/options.css index 2ff7860..0fe5f96 100644 --- a/extension/entrypoints/options/options.css +++ b/extension/entrypoints/options/options.css @@ -4,36 +4,40 @@ body { } .options-root { - display: grid; - /* `minmax(0, 1fr)` lets the content column actually shrink — a plain `1fr` - uses min-content as its floor, which a long un-breakable URL inside the - custom-waypoint preview can blow past, forcing horizontal scroll. */ - grid-template-columns: 188px minmax(0, 1fr); + display: flex; + flex-direction: column; max-width: 1100px; margin: 0 auto; min-height: 100vh; + /* Prevent intrinsic min-content of nested grids/long URLs from forcing the + whole page to grow horizontally. */ + min-width: 0; } -.options-sidebar { - border-right: 1px solid var(--border-subtle); - padding: 28px 0; - background: var(--bg-secondary); +.options-header { position: sticky; top: 0; - align-self: start; - min-height: 100vh; + z-index: 5; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-subtle); + padding: 14px 24px 0; + display: flex; + flex-direction: column; + gap: 10px; } .options-brand { - padding: 0 18px 18px; - border-bottom: 1px solid var(--border-subtle); - margin-bottom: 12px; + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; } .options-brand-title { font-family: var(--font-serif); font-weight: 500; font-size: 20px; + line-height: 1; letter-spacing: -0.02em; display: inline-flex; align-items: center; @@ -46,24 +50,24 @@ body { } .options-brand-sub { - font-size: 11px; + font-size: 10px; + line-height: 1; color: var(--text-tertiary); text-transform: uppercase; - letter-spacing: 0.1em; - margin-top: 2px; + letter-spacing: 0.14em; + /* Nudge down so the small caps optically center with the cap-height of + "Aturi" rather than its full ascender-to-descender box. */ + transform: translateY(1px); } .options-nav { display: flex; - flex-direction: column; + flex-wrap: wrap; + gap: 2px; + margin: 0 -6px; } .options-nav-item { - display: flex; - align-items: center; - justify-content: space-between; - padding: 10px 18px; - text-align: left; background: transparent; border: none; color: var(--text-secondary); @@ -71,30 +75,48 @@ body { font-family: var(--font-serif); font-size: 13.5px; font-weight: 400; - border-left: 2px solid transparent; - transition: all 0.2s ease; - position: relative; + padding: 8px 12px 10px; + border-bottom: 2px solid transparent; + margin-bottom: -1px; + transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; + white-space: nowrap; } .options-nav-item:hover { - background: var(--bg-tertiary); color: var(--text-primary); + background: var(--bg-tertiary); } .options-nav-item.active { - background: var(--bg-tertiary); - border-left-color: var(--text-accent); color: var(--text-primary); + border-bottom-color: var(--text-accent); font-weight: 500; } .options-content { - padding: 32px 36px; + padding: 28px 28px 40px; max-width: 880px; + width: 100%; /* Same reason as .options-root: prevent intrinsic min-content of children from forcing this block to grow beyond its container. */ min-width: 0; overflow-x: hidden; + box-sizing: border-box; +} + +@media (max-width: 560px) { + .options-header { + padding: 12px 16px 0; + } + + .options-content { + padding: 22px 16px 32px; + } + + .options-nav-item { + font-size: 13px; + padding: 8px 10px 10px; + } } .options-h1 { diff --git a/extension/entrypoints/popup/App.tsx b/extension/entrypoints/popup/App.tsx index 40444cf..8be8a72 100644 --- a/extension/entrypoints/popup/App.tsx +++ b/extension/entrypoints/popup/App.tsx @@ -24,6 +24,24 @@ type PopupState = | { phase: 'unsupported'; prefs: Prefs; tabId: number | null; isKnownHost: boolean } | { phase: 'ready'; match: ReverseMatch; prefs: Prefs; tabId: number | null }; +// Open the extension's options page. We prefer browser.runtime.openOptionsPage() +// because it focuses an existing options tab when one is already open. Some +// Chromium-derived browsers (notably Arc) do not implement the chrome://extensions +// surface that hosts embedded options, so the call can silently no-op. If it +// throws or never resolves, fall back to opening options.html in a new tab. +async function openOptionsPage() { + const fallbackUrl = browser.runtime.getURL('/options.html'); + try { + const result = browser.runtime.openOptionsPage(); + if (result && typeof (result as Promise).then === 'function') { + await (result as Promise); + } + } catch { + await browser.tabs.create({ url: fallbackUrl }); + } + window.close(); +} + export default function App() { const [state, setState] = useState({ phase: 'loading' }); const [pendingId, setPendingId] = useState(null); @@ -288,7 +306,7 @@ function NoAtmosphereView({
No destinations are visible. Add waypoints to a group in Settings.
-
@@ -334,7 +352,7 @@ function NoAtmosphereView({ @@ -492,7 +510,7 @@ function Ready({ match, prefs, pendingId, copiedId, onOpen, onCopy }: ReadyProps
-
@@ -581,7 +599,7 @@ function HeaderSettingsButton() {