@@ -0,0 +1,36 @@
|
||||
type RadioControlsProps = {
|
||||
status: string;
|
||||
isPlaying: boolean;
|
||||
onPlay: () => void | Promise<void>;
|
||||
onStop: () => void;
|
||||
};
|
||||
|
||||
export function RadioControls({ status, isPlaying, onPlay, onStop }: RadioControlsProps) {
|
||||
return (
|
||||
<section className="radio-controls" aria-label="Radio playback controls">
|
||||
<p className="radio-controls__status" aria-live="polite">
|
||||
{status}
|
||||
</p>
|
||||
<div className="radio-controls__buttons">
|
||||
<button
|
||||
type="button"
|
||||
className="playpause"
|
||||
onClick={() => void onPlay()}
|
||||
disabled={isPlaying}
|
||||
aria-label="Start live stream"
|
||||
>
|
||||
▶️
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="playpause"
|
||||
onClick={onStop}
|
||||
disabled={!isPlaying}
|
||||
aria-label="Stop live stream"
|
||||
>
|
||||
⏹️
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
type WebsitePanelProps = {
|
||||
label: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
export function WebsitePanel({ label, url }: WebsitePanelProps) {
|
||||
return (
|
||||
<section className="website-panel" aria-label={label}>
|
||||
<header className="website-panel__header">
|
||||
<p className="website-panel__label">{label}</p>
|
||||
<p className="website-panel__url" title={url}>
|
||||
{url}
|
||||
</p>
|
||||
</header>
|
||||
<div className="website-panel__content">
|
||||
<iframe
|
||||
className="website-panel__frame"
|
||||
src={url}
|
||||
title={label}
|
||||
loading="lazy"
|
||||
referrerPolicy="strict-origin-when-cross-origin"
|
||||
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user