style: format Radio component boundary

This commit is contained in:
Sameh Khamis committed 2026-09-12 23:25:09 -07:00
1 parent 7b9aca8597
commit bd6cc5abe8
7 files changed
+1393 -883

No files matched your search

+100 -31
View File
@@ -31,17 +31,24 @@ export class RadioControls {
}
listen(target, type, handler, options = {}) {
target?.addEventListener(type, handler, { ...options, signal: this.listeners.signal });
target?.addEventListener(type, handler, {
...options,
signal: this.listeners.signal,
});
}
connect() {
this._radioUnsubscribe?.();
this._radioUnsubscribe = null;
if (this.destroyed) return;
this._radioUnsubscribe = this.radio.subscribe?.((state) => this._renderRadioState(state));
this._radioUnsubscribe = this.radio.subscribe?.((state) =>
this._renderRadioState(state),
);
}
_renderRadioState(state) { renderRadioState.call(this, state); }
_renderRadioState(state) {
renderRadioState.call(this, state);
}
/**
* Reveal the newly enabled directory and transport inside Context without
@@ -55,28 +62,46 @@ export class RadioControls {
const scroller = contextPanel?.querySelector('.global-context-panel-inner');
const directory = this._radioPanel?.querySelector('.radio-directory-row');
const transport = this._radioPanel?.querySelector('.radio-transport');
if (!contextPanel || contextPanel.classList.contains('collapsed')
|| !scroller || !directory || !transport || !this._radioState?.enabled) return false;
if (
!contextPanel ||
contextPanel.classList.contains('collapsed') ||
!scroller ||
!directory ||
!transport ||
!this._radioState?.enabled
)
return false;
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
if (this.destroyed || !this._radioState?.enabled || !trigger?.isConnected) return false;
await new Promise((resolve) =>
requestAnimationFrame(() => requestAnimationFrame(resolve)),
);
if (this.destroyed || !this._radioState?.enabled || !trigger?.isConnected)
return false;
const viewport = scroller.getBoundingClientRect();
const directoryRect = directory.getBoundingClientRect();
const transportRect = transport.getBoundingClientRect();
const margin = 10;
const minimum = scroller.scrollTop + transportRect.bottom - (viewport.bottom - margin);
const maximum = scroller.scrollTop + directoryRect.top - (viewport.top + margin);
const desired = minimum <= maximum
? Math.min(Math.max(scroller.scrollTop, minimum), maximum)
: minimum;
const minimum =
scroller.scrollTop + transportRect.bottom - (viewport.bottom - margin);
const maximum =
scroller.scrollTop + directoryRect.top - (viewport.top + margin);
const desired =
minimum <= maximum
? Math.min(Math.max(scroller.scrollTop, minimum), maximum)
: minimum;
const next = Math.min(
Math.max(0, scroller.scrollHeight - scroller.clientHeight),
Math.max(0, desired),
);
if (Math.abs(next - scroller.scrollTop) < 1) return false;
const reducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
scroller.scrollTo({ top: next, behavior: reducedMotion ? 'auto' : 'smooth' });
const reducedMotion = window.matchMedia?.(
'(prefers-reduced-motion: reduce)',
)?.matches;
scroller.scrollTo({
top: next,
behavior: reducedMotion ? 'auto' : 'smooth',
});
return true;
}
@@ -89,11 +114,24 @@ export class RadioControls {
async _revealRadioPanelInsideContext({ focusTarget = null } = {}) {
const contextPanel = document.getElementById('global-context-panel');
const scroller = contextPanel?.querySelector('.global-context-panel-inner');
if (!contextPanel || contextPanel.classList.contains('collapsed')
|| !scroller || !this._radioPanel || this._radioPanel.classList.contains('collapsed')) return false;
if (
!contextPanel ||
contextPanel.classList.contains('collapsed') ||
!scroller ||
!this._radioPanel ||
this._radioPanel.classList.contains('collapsed')
)
return false;
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
if (this.destroyed || contextPanel.classList.contains('collapsed') || this._radioPanel.classList.contains('collapsed')) return false;
await new Promise((resolve) =>
requestAnimationFrame(() => requestAnimationFrame(resolve)),
);
if (
this.destroyed ||
contextPanel.classList.contains('collapsed') ||
this._radioPanel.classList.contains('collapsed')
)
return false;
const viewport = scroller.getBoundingClientRect();
const radioRect = this._radioPanel.getBoundingClientRect();
@@ -104,8 +142,13 @@ export class RadioControls {
);
const moved = Math.abs(next - scroller.scrollTop) >= 1;
if (moved) {
const reducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
scroller.scrollTo({ top: next, behavior: reducedMotion ? 'auto' : 'smooth' });
const reducedMotion = window.matchMedia?.(
'(prefers-reduced-motion: reduce)',
)?.matches;
scroller.scrollTo({
top: next,
behavior: reducedMotion ? 'auto' : 'smooth',
});
}
focusTarget?.focus?.({ preventScroll: true });
return moved;
@@ -115,25 +158,44 @@ export class RadioControls {
_syncContextRadioLauncherState() {
if (!this._contextRadioToggleBtn) return;
const contextPanel = document.getElementById('global-context-panel');
const contextExpanded = Boolean(contextPanel && !contextPanel.classList.contains('collapsed'));
const contextExpanded = Boolean(
contextPanel && !contextPanel.classList.contains('collapsed'),
);
if (contextExpanded) {
const radioExpanded = Boolean(this._radioPanel && !this._radioPanel.classList.contains('collapsed'));
const radioExpanded = Boolean(
this._radioPanel && !this._radioPanel.classList.contains('collapsed'),
);
this._contextRadioToggleBtn.setAttribute('aria-controls', 'radio-panel');
this._contextRadioToggleBtn.setAttribute('aria-expanded', String(radioExpanded));
const label = radioExpanded ? 'Go to expanded Radio section' : 'Expand Radio section in Context';
this._contextRadioToggleBtn.setAttribute(
'aria-expanded',
String(radioExpanded),
);
const label = radioExpanded
? 'Go to expanded Radio section'
: 'Expand Radio section in Context';
this._contextRadioToggleBtn.setAttribute('aria-label', label);
this._contextRadioToggleBtn.title = label;
return;
}
const compactOpen = Boolean(this._contextRadioDock?.classList.contains('disclosure-open'));
this._contextRadioToggleBtn.setAttribute('aria-controls', 'context-radio-mini');
this._contextRadioToggleBtn.setAttribute('aria-expanded', String(compactOpen));
const compactOpen = Boolean(
this._contextRadioDock?.classList.contains('disclosure-open'),
);
this._contextRadioToggleBtn.setAttribute(
'aria-controls',
'context-radio-mini',
);
this._contextRadioToggleBtn.setAttribute(
'aria-expanded',
String(compactOpen),
);
const action = compactOpen ? 'Close' : 'Open';
this._contextRadioToggleBtn.setAttribute('aria-label', `${action} compact Radio controls`);
this._contextRadioToggleBtn.setAttribute(
'aria-label',
`${action} compact Radio controls`,
);
this._contextRadioToggleBtn.title = `${action} compact Radio controls`;
}
destroy() {
if (this.destroyed) return;
this.destroyed = true;
@@ -148,9 +210,16 @@ export class RadioControls {
this._radioTunerPool = [];
this._radioTunerStations = [];
this._radioTunerBandPinnedForNavigation = false;
try { if (pointer !== null) this._radioTunerSlider?.releasePointerCapture(pointer); } catch { /* capture already released */ }
try {
if (pointer !== null)
this._radioTunerSlider?.releasePointerCapture(pointer);
} catch {
/* capture already released */
}
this._radioTuner?.classList.remove('is-dragging', 'is-static');
document.getElementById('title-bar')?.classList.remove('radio-broadcasting');
document
.getElementById('title-bar')
?.classList.remove('radio-broadcasting');
this.radio.endTuning();
}
}