forked from Creditra/Creditra-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNetworkStatus.tsx
More file actions
66 lines (60 loc) · 2.04 KB
/
Copy pathNetworkStatus.tsx
File metadata and controls
66 lines (60 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { useEffect, useRef, useState } from 'react';
import { Wifi, WifiOff } from 'lucide-react';
import { useOnline } from '../hooks/useOnline';
import './NetworkStatus.css';
/**
* Persistent header indicator for browser connectivity (navigator.onLine).
*
* Distinct from wallet Stellar network mismatch UI — this reflects whether the
* device has an internet connection.
*
* Accessibility:
* - Visible dot + icon + label (not color-only)
* - `aria-label` on the indicator for the current state
* - Screen-reader announcements on transitions via live region
* (assertive when offline, polite when restored)
*
* Styling: design tokens only (`--success`, `--error`, `--border`, etc.)
*/
export function NetworkStatus() {
const { isOnline } = useOnline();
const prevOnlineRef = useRef<boolean | null>(null);
const [announcement, setAnnouncement] = useState('');
useEffect(() => {
if (prevOnlineRef.current === null) {
prevOnlineRef.current = isOnline;
return;
}
if (prevOnlineRef.current === isOnline) return;
prevOnlineRef.current = isOnline;
setAnnouncement(
isOnline
? 'Network connection restored.'
: 'Network connection lost. You are offline.',
);
}, [isOnline]);
const statusLabel = isOnline ? 'Online' : 'Offline';
const Icon = isOnline ? Wifi : WifiOff;
return (
<>
<div
className={`network-status network-status--${isOnline ? 'online' : 'offline'}`}
aria-label={`Network status: ${statusLabel.toLowerCase()}`}
title={`Network: ${statusLabel}`}
>
<Icon className="network-status__icon" size={16} strokeWidth={2} aria-hidden="true" />
<span className="network-status__dot" aria-hidden="true" />
<span className="network-status__label">{statusLabel}</span>
</div>
{announcement ? (
<span
className="sr-only"
role={isOnline ? 'status' : 'alert'}
aria-live={isOnline ? 'polite' : 'assertive'}
>
{announcement}
</span>
) : null}
</>
);
}