()
| 156 | * React hook to use size classes in components |
| 157 | */ |
| 158 | export function useSizeClass(): SizeClassInfo { |
| 159 | const [sizeClassInfo, setSizeClassInfo] = useState<SizeClassInfo>(cachedSizeClassInfo); |
| 160 | |
| 161 | useEffect(() => { |
| 162 | let isMounted = true; |
| 163 | |
| 164 | const applySizeClass = (info: SizeClassInfo) => { |
| 165 | if (!isMounted) return; |
| 166 | cachedSizeClassInfo = info; |
| 167 | setSizeClassInfo(info); |
| 168 | console.debug( |
| 169 | `[SizeClass] Updated:`, |
| 170 | `horizontal=${SizeClass[info.horizontalSizeClass]}`, |
| 171 | `vertical=${SizeClass[info.verticalSizeClass]}`, |
| 172 | `orientation=${info.orientation}`, |
| 173 | `isLargeScreen=${info.isLargeScreen}`, |
| 174 | ); |
| 175 | }; |
| 176 | |
| 177 | const updateFromDimensions = () => { |
| 178 | const calculated = calculateFromDimensions(); |
| 179 | applySizeClass(calculated); |
| 180 | }; |
| 181 | |
| 182 | const requestNativeUpdate = async () => { |
| 183 | const nativeInfo = await fetchNativeSizeClass(); |
| 184 | if (nativeInfo) { |
| 185 | applySizeClass(nativeInfo); |
| 186 | } |
| 187 | }; |
| 188 | |
| 189 | const dimensionSubscription = Dimensions.addEventListener('change', () => { |
| 190 | updateFromDimensions(); |
| 191 | requestNativeUpdate(); |
| 192 | }); |
| 193 | |
| 194 | const appStateSubscription = AppState.addEventListener('change', (nextAppState: AppStateStatus) => { |
| 195 | if (nextAppState === 'active') { |
| 196 | requestNativeUpdate(); |
| 197 | } |
| 198 | }); |
| 199 | |
| 200 | const nativeSubscription = sizeClassNativeEmitter?.addListener(NATIVE_EVENT_NAME, (payload: NativeSizeClassPayload) => { |
| 201 | const normalized = normalizeNativePayload(payload); |
| 202 | if (normalized) { |
| 203 | applySizeClass(normalized); |
| 204 | } |
| 205 | }); |
| 206 | |
| 207 | // Kick off an initial native fetch to override the heuristic when available. |
| 208 | requestNativeUpdate(); |
| 209 | |
| 210 | return () => { |
| 211 | isMounted = false; |
| 212 | dimensionSubscription.remove(); |
| 213 | appStateSubscription.remove(); |
| 214 | nativeSubscription?.remove(); |
| 215 | }; |
no test coverage detected