WiFi network list
The WiFi networks in range, to choose which the vessel joins, with each one's signal, details, password and DNS.
On this page
The page receives: nothing yet
Code
import {
WifiNetworkList,
type WifiConnectRequest,
type WifiConnectResult,
} from "@bosunkit/components/wifi-network-list";
import { useState, type Dispatch, type ReactElement, type SetStateAction } from "react";
import { NETWORKS } from "./networks";
export const description: string =
"Choose a network to see its details, type its password and choose its DNS; this example connects nothing.";
/** A connection that succeeds after a moment and changes nothing. */
function pretendConnect(): Promise<WifiConnectResult> {
return new Promise<WifiConnectResult>((resolve: (result: WifiConnectResult) => void): void => {
setTimeout((): void => {
resolve({ status: "connected" });
}, 800);
});
}
export default function Showcase(): ReactElement {
const [last, setLast]: [string, Dispatch<SetStateAction<string>>] = useState<string>("nothing yet");
return (
<div style={{ display: "grid", gap: "var(--space-sm)", maxInlineSize: "36rem" }}>
<WifiNetworkList
networks={NETWORKS}
connectAction={(request: WifiConnectRequest): Promise<WifiConnectResult> => {
setLast(`connect to ${request.ssid} with DNS ${request.dns.mode}`);
return pretendConnect();
}}
disconnectAction={(ssid: string): Promise<void> => {
setLast(`disconnect from ${ssid}`);
return Promise.resolve();
}}
forgetAction={(ssid: string): Promise<void> => {
setLast(`forget ${ssid}`);
return Promise.resolve();
}}
onAutoJoinChange={(ssid: string, on: boolean): void => {
setLast(`join ${ssid} automatically: ${String(on)}`);
}}
rescanAction={(): Promise<void> => new Promise<void>((resolve: () => void): void => void setTimeout(resolve, 1200))}
/>
<p style={{ margin: 0, color: "var(--text-dim)" }}>The page receives: {last}</p>
</div>
);
}
A WiFi network list shows the networks a scan found, to choose which the vessel joins. Each row has the network's name, its signal, its band and whether it needs a password, with the connected network first, then the saved ones, then the rest by strength; access points that share a name show as one network. Choosing a network opens its details (signal, security, band, channel, its access points or the access point's address, and the vessel's address on it when connected) and what can be done with it.
- A network that needs a password shows a password field for the key the marina or the owner gave. The key is
checked before anything is sent, by the rules bosund's
core/passwordpolicyapplies: 8 to 63 printable characters or 64 hex digits for WPA, WPA2 and WPA3, and 5 or 13 characters or 10 or 26 hex digits for WEP; a wrong one says what is wrong and to check it. - An open network warns that anyone nearby can see what goes over it, and connects without a password.
- A saved network connects without asking, can be forgotten, and has a switch for joining it by itself when it is in range, so the crew choose which networks the vessel joins.
- Every network has a DNS picker: the network's own servers, Cloudflare, Google or custom ones, sent with the connection or reported for a saved network.
- Join another network joins one that does not broadcast its name: its name, security, password and DNS.
The list never scans or connects itself. connectAction joins and resolves connected or refused with bosund's reason,
which shows under the password; rescanAction, disconnectAction and forgetAction do the rest, each shown pending
until it settles, and a connection is announced to a screen reader.
Examples
A refused password
Code
import { WifiNetworkList, type WifiConnectResult } from "@bosunkit/components/wifi-network-list";
import type { ReactElement } from "react";
import { NETWORKS } from "./networks";
export const description: string =
"A connection bosund refuses: choose Marina Guest, type a password and connect to see the reason under the field.";
export default function Refused(): ReactElement {
return (
<div style={{ maxInlineSize: "36rem" }}>
<WifiNetworkList
networks={NETWORKS}
connectAction={(): Promise<WifiConnectResult> =>
Promise.resolve({
status: "rejected",
message: "Marina Guest didn't accept that password. Check it with the marina office and try again.",
})
}
/>
</div>
);
}
No networks in range
No networks in range
Code
import { WifiNetworkList } from "@bosunkit/components/wifi-network-list";
import type { ReactElement } from "react";
export const description: string = "A scan that found nothing: it says so and offers to scan again.";
export default function Empty(): ReactElement {
return (
<div style={{ maxInlineSize: "36rem" }}>
<WifiNetworkList networks={[]} rescanAction={(): Promise<void> => Promise.resolve()} />
</div>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| networksrequired | readonly WifiNetwork[] | – | The access points the last scan found, in any order: the list merges those that share a name and sorts them. |
| connectAction | ((request: WifiConnectRequest) => Promise<WifiConnectResult>) | undefined | – | Joins a network; the list shows it pending until the promise settles, and a refusal's message under the field. |
| disconnectAction | ((ssid: string) => Promise<void>) | undefined | – | Leaves the connected network. |
| forgetAction | ((ssid: string) => Promise<void>) | undefined | – | Forgets a saved network's password. |
| onAutoJoinChange | ((ssid: string, on: boolean) => void) | undefined | – | Called when the crew turn a saved network's automatic joining on or off. |
| onDnsChange | ((ssid: string, dns: DnsSetting) => void) | undefined | – | Called when the crew change a saved network's DNS. |
| rescanAction | (() => Promise<void>) | undefined | – | Scans again; the button shows it busy until the promise settles. |
| scanning | boolean | undefined | false | Whether a scan is running now, started elsewhere. |
| allowOther | boolean | undefined | true | Whether the crew can join a network that does not broadcast its name; on unless set. |
| label | string | undefined | – | The list's name, translated by the caller; "WiFi networks" unless set. |
| className | string | undefined | – | Classes added to the root's own. |
| testId | string | undefined | – | Becomes data-testid on the root. |
Related
- Signal strength: the bars each network shows.
- DNS picker: where a network's DNS comes from.
- Password input: the field the key is typed in.