diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-18 22:40:59 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-05-18 22:40:59 +0200 |
| commit | 584bd42f871d2e1618ca414749f09c38f0143a44 (patch) | |
| tree | 45c821eec2ad9c77d5bccf83057cfc0a7e22ba09 /src/utils | |
| parent | b214baab3e17d92f784b4f782863deafc5558ee4 (diff) | |
chore: handle settings change
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/hooks/use-attributes.tsx | 33 | ||||
| -rw-r--r-- | src/utils/hooks/use-code-blocks-theme.tsx | 22 | ||||
| -rw-r--r-- | src/utils/hooks/use-local-storage.tsx | 35 | ||||
| -rw-r--r-- | src/utils/hooks/use-query-selector-all.tsx | 16 | ||||
| -rw-r--r-- | src/utils/hooks/use-update-ackee-options.tsx | 19 | ||||
| -rw-r--r-- | src/utils/providers/prism-theme.tsx | 2 |
6 files changed, 126 insertions, 1 deletions
diff --git a/src/utils/hooks/use-attributes.tsx b/src/utils/hooks/use-attributes.tsx new file mode 100644 index 0000000..97a7b43 --- /dev/null +++ b/src/utils/hooks/use-attributes.tsx @@ -0,0 +1,33 @@ +import { useEffect } from 'react'; + +export type useAttributesProps = { + /** + * An HTML element. + */ + element?: HTMLElement; + /** + * The attribute name. + */ + attribute: string; + /** + * The attribute value. + */ + value: string; +}; + +/** + * Set HTML attributes to the given element or to the HTML document. + * + * @param props - An object with element, attribute name and value. + */ +const useAttributes = ({ element, attribute, value }: useAttributesProps) => { + useEffect(() => { + if (element) { + element.dataset[attribute] = value; + } else { + document.documentElement.dataset[attribute] = value; + } + }, [attribute, element, value]); +}; + +export default useAttributes; diff --git a/src/utils/hooks/use-code-blocks-theme.tsx b/src/utils/hooks/use-code-blocks-theme.tsx new file mode 100644 index 0000000..beb7b29 --- /dev/null +++ b/src/utils/hooks/use-code-blocks-theme.tsx @@ -0,0 +1,22 @@ +import { usePrismTheme } from '@utils/providers/prism-theme'; +import { useRouter } from 'next/router'; +import { RefObject, useEffect, useState } from 'react'; +import useIsMounted from './use-is-mounted'; + +const useCodeBlocksTheme = (el: RefObject<HTMLDivElement>) => { + const [preElements, setPreElements] = useState<NodeListOf<HTMLPreElement>>(); + const isMounted = useIsMounted(el); + const { setCodeBlocks } = usePrismTheme(); + const { asPath } = useRouter(); + + useEffect(() => { + const result = document.querySelectorAll<HTMLPreElement>('pre'); + setPreElements(result); + }, [asPath]); + + useEffect(() => { + isMounted && preElements && setCodeBlocks(preElements); + }, [isMounted, preElements, setCodeBlocks]); +}; + +export default useCodeBlocksTheme; diff --git a/src/utils/hooks/use-local-storage.tsx b/src/utils/hooks/use-local-storage.tsx new file mode 100644 index 0000000..da0292b --- /dev/null +++ b/src/utils/hooks/use-local-storage.tsx @@ -0,0 +1,35 @@ +import { LocalStorage } from '@services/local-storage'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; + +export type UseLocalStorageReturn<T> = { + value: T; + setValue: Dispatch<SetStateAction<T>>; +}; + +/** + * Use the local storage. + * + * @param {string} key - The storage local key. + * @param {T} [fallbackValue] - A fallback value if local storage is empty. + * @returns {UseLocalStorageReturn<T>} An object with value and setValue. + */ +const useLocalStorage = <T extends unknown>( + key: string, + fallbackValue: T +): UseLocalStorageReturn<T> => { + const getInitialValue = () => { + if (typeof window === 'undefined') return fallbackValue; + const storedValue = LocalStorage.get<T>(key); + return storedValue || fallbackValue; + }; + + const [value, setValue] = useState<T>(getInitialValue); + + useEffect(() => { + LocalStorage.set(key, value); + }, [key, value]); + + return { value, setValue }; +}; + +export default useLocalStorage; diff --git a/src/utils/hooks/use-query-selector-all.tsx b/src/utils/hooks/use-query-selector-all.tsx new file mode 100644 index 0000000..dbeec90 --- /dev/null +++ b/src/utils/hooks/use-query-selector-all.tsx @@ -0,0 +1,16 @@ +import { useEffect, useState } from 'react'; + +const useQuerySelectorAll = <T extends keyof HTMLElementTagNameMap>( + query: string +) => { + const [elements, setElements] = + useState<NodeListOf<HTMLElementTagNameMap[T]>>(); + + useEffect(() => { + setElements(document.querySelectorAll(query)); + }, [query]); + + return elements; +}; + +export default useQuerySelectorAll; diff --git a/src/utils/hooks/use-update-ackee-options.tsx b/src/utils/hooks/use-update-ackee-options.tsx new file mode 100644 index 0000000..7c1d98a --- /dev/null +++ b/src/utils/hooks/use-update-ackee-options.tsx @@ -0,0 +1,19 @@ +import { useAckeeTracker } from '@utils/providers/ackee'; +import { useEffect } from 'react'; + +export type AckeeOptions = 'full' | 'partial'; + +/** + * Update Ackee settings with the given choice. + * + * @param {AckeeOptions} value - Either `full` or `partial`. + */ +const useUpdateAckeeOptions = (value: AckeeOptions) => { + const { setDetailed } = useAckeeTracker(); + + useEffect(() => { + setDetailed(value === 'full'); + }, [value, setDetailed]); +}; + +export default useUpdateAckeeOptions; diff --git a/src/utils/providers/prism-theme.tsx b/src/utils/providers/prism-theme.tsx index 62bcf56..23a2a36 100644 --- a/src/utils/providers/prism-theme.tsx +++ b/src/utils/providers/prism-theme.tsx @@ -55,7 +55,7 @@ const isValidTheme = (theme: string): boolean => { const getTheme = (key: string): PrismTheme | undefined => { if (typeof window === 'undefined') return undefined; - const storageValue = LocalStorage.get(key); + const storageValue = LocalStorage.get<string>(key); return storageValue && isValidTheme(storageValue) ? (storageValue as PrismTheme) |
