|
import { detect } from 'detect-browser'; |
|
import { useEffect } from 'react'; |
|
|
|
let browser = detect(); |
|
let supported = !!browser && browser.name !== 'ie'; |
|
|
|
/** |
|
* Supported versions of browsers |
|
*/ |
|
const supportedVersions: { [key: string]: number } = { |
|
chrome: 88, |
|
firefox: 89, |
|
edge: 88, |
|
safari: 14, |
|
opera: 74, |
|
}; |
|
|
|
/** |
|
* Callable from anywhere to check if the browser is supported |
|
* @returns true if browser is supported |
|
*/ |
|
export const checkVersion = () => { |
|
browser = detect(); |
|
if (browser && browser.name && browser.version) { |
|
const version = parseInt(browser.version, 10); |
|
console.log('Got browser ', browser, version); |
|
// handle the case where we don't detect the browser |
|
supported = !!supportedVersions[browser.name] && version >= supportedVersions[browser.name]; |
|
} else { |
|
supported = false; |
|
} |
|
return supported; |
|
}; |
|
checkVersion(); |
|
|
|
export type BrowserSupportedProps = { |
|
/** |
|
* The children to render if the browser is supported |
|
*/ |
|
supportedChildren?: JSX.Element; |
|
/** |
|
* The children to render if the browser is not supported |
|
*/ |
|
unsupportedChildren?: JSX.Element; |
|
/** |
|
* Called in useEffect with the result of the browser detection. Use isSupportedDeps to control when this is called. |
|
*/ |
|
isSupported?: (yes: boolean) => void; |
|
/** |
|
* The dependencies for the isSupported callback. If this changes, the callback will be called again. |
|
*/ |
|
isSupportedDeps?: React.DependencyList; |
|
}; |
|
|
|
/** |
|
* React hook component to check if the browser is supported from the above browser/version map. |
|
* Usage: |
|
* ```typescript |
|
* <BrowserSupported |
|
isSupported={(supported) => { |
|
if (!supported) { |
|
showNotification({ |
|
id: 'browser-not-supported', |
|
title: 'Browser not supported', |
|
autoClose: false, |
|
message: 'Please update your browser.', |
|
color: 'red', |
|
}); |
|
} |
|
}} |
|
supportedChildren={ |
|
<Text> |
|
<BiCheckCircle |
|
style={{ |
|
display: 'inline-flex', |
|
}} |
|
size={24} |
|
/>{' '} |
|
Browser Supported |
|
</Text> |
|
} |
|
unsupportedChildren={ |
|
<Text size="xl"> |
|
<BiErrorCircle |
|
style={{ |
|
display: 'inline-flex', |
|
}} |
|
size={24} |
|
/>{' '} |
|
Browser Unsupported |
|
</Text> |
|
} |
|
/> |
|
* ``` |
|
* @param props @BrowserSupportedProps |
|
* @returns supportedChildren or unsupportedChildren depending on the browser |
|
*/ |
|
export function BrowserSupported(props: BrowserSupportedProps) { |
|
const { supportedChildren, unsupportedChildren, isSupported, isSupportedDeps } = props; |
|
|
|
useEffect(() => { |
|
if (isSupported) { |
|
isSupported(checkVersion()); |
|
} |
|
// eslint-disable-next-line react-hooks/exhaustive-deps |
|
}, [isSupported, isSupportedDeps, ...(isSupportedDeps || [])]); |
|
|
|
if (supported) { |
|
return supportedChildren || null; |
|
} |
|
|
|
return unsupportedChildren || null; |
|
} |