|
import isEqual from 'lodash/isEqual'; |
|
import { useEffect, useRef, useState } from 'react'; |
|
|
|
export const useSetModalState = () => { |
|
const [visible, setVisible] = useState(false); |
|
|
|
const showModal = () => { |
|
setVisible(true); |
|
}; |
|
const hideModal = () => { |
|
setVisible(false); |
|
}; |
|
|
|
const switchVisible = () => { |
|
setVisible(!visible); |
|
}; |
|
|
|
return { visible, showModal, hideModal, switchVisible }; |
|
}; |
|
|
|
export const useDeepCompareEffect = ( |
|
effect: React.EffectCallback, |
|
deps: React.DependencyList, |
|
) => { |
|
const ref = useRef<React.DependencyList>(); |
|
let callback: ReturnType<React.EffectCallback> = () => {}; |
|
if (!isEqual(deps, ref.current)) { |
|
callback = effect(); |
|
ref.current = deps; |
|
} |
|
useEffect(() => { |
|
return () => { |
|
if (callback) { |
|
callback(); |
|
} |
|
}; |
|
}, []); |
|
}; |
|
|
|
export interface UseDynamicSVGImportOptions { |
|
onCompleted?: ( |
|
name: string, |
|
SvgIcon: React.FC<React.SVGProps<SVGSVGElement>> | undefined, |
|
) => void; |
|
onError?: (err: Error) => void; |
|
} |
|
|
|
export function useDynamicSVGImport( |
|
name: string, |
|
options: UseDynamicSVGImportOptions = {}, |
|
) { |
|
const ImportedIconRef = useRef<React.FC<React.SVGProps<SVGSVGElement>>>(); |
|
const [loading, setLoading] = useState(false); |
|
const [error, setError] = useState<Error>(); |
|
|
|
const { onCompleted, onError } = options; |
|
useEffect(() => { |
|
setLoading(true); |
|
const importIcon = async (): Promise<void> => { |
|
try { |
|
ImportedIconRef.current = (await import(name)).ReactComponent; |
|
onCompleted?.(name, ImportedIconRef.current); |
|
} catch (err: any) { |
|
onError?.(err); |
|
setError(err); |
|
} finally { |
|
setLoading(false); |
|
} |
|
}; |
|
importIcon(); |
|
}, [name, onCompleted, onError]); |
|
|
|
return { error, loading, SvgIcon: ImportedIconRef.current }; |
|
} |
|
|