# stream-permissions-banner _(no submodules)_ ## Purpose `` is the visible counterpart to `useStreamPermissions()`. It renders a `role="status"` ARIA-live region with copy reflecting the current microphone permission state and an explicit request button when the state is actionable (`"prompt"` or `"unknown"`). When the user has already granted access, the banner renders nothing so the room UI is unobstructed. The banner is intentionally opinionated about accessibility — `aria-live="polite"` ensures screen readers announce state transitions without interrupting other speech — but stays unopinionated about styling. The default copy is overridable on a per-state basis via the `messages` prop. ## Features - ARIA-live `role="status"` with `aria-live="polite"`. - Per-state copy with sensible defaults (`granted` / `denied` / `prompt` / `unknown`). - Request button rendered only when the state is `"prompt"` or `"unknown"`. - `onResolved` callback invoked with the next state after `request()` settles. - Renders `null` when permission is already granted. - Throws `REACT_AUDIO_STREAM.NO_PROVIDER` outside a ``. ## Usage: Basic ```tsx ``` ## Usage: Advanced ```tsx { if (state === "granted") void session.connect("lobby").then(() => session.join()); }} /> ``` ## API Reference - `StreamPermissionsBannerProps` — `{ messages?, requestLabel?, onResolved? }` - `StreamPermissionsBanner(props): ReactNode` ## Implementation Notes The `data-state` attribute on the root element mirrors the `MediaPermissionState` string so consumers can target it via CSS attribute selectors (e.g. `[data-state="denied"] { color: red; }`) without re-deriving the state in JS. The request button renders only on `"prompt"` and `"unknown"` because `"denied"` cannot be escalated back to `"prompt"` through `getUserMedia` alone — the user must change browser-level settings, which the copy explicitly tells them.