From 584bd42f871d2e1618ca414749f09c38f0143a44 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Wed, 18 May 2022 22:40:59 +0200 Subject: chore: handle settings change --- src/utils/hooks/use-attributes.tsx | 33 ++++++++++++++++++++++++++ src/utils/hooks/use-code-blocks-theme.tsx | 22 +++++++++++++++++ src/utils/hooks/use-local-storage.tsx | 35 ++++++++++++++++++++++++++++ src/utils/hooks/use-query-selector-all.tsx | 16 +++++++++++++ src/utils/hooks/use-update-ackee-options.tsx | 19 +++++++++++++++ src/utils/providers/prism-theme.tsx | 2 +- 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/utils/hooks/use-attributes.tsx create mode 100644 src/utils/hooks/use-code-blocks-theme.tsx create mode 100644 src/utils/hooks/use-local-storage.tsx create mode 100644 src/utils/hooks/use-query-selector-all.tsx create mode 100644 src/utils/hooks/use-update-ackee-options.tsx (limited to 'src/utils') 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) => { + const [preElements, setPreElements] = useState>(); + const isMounted = useIsMounted(el); + const { setCodeBlocks } = usePrismTheme(); + const { asPath } = useRouter(); + + useEffect(() => { + const result = document.querySelectorAll('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 = { + value: T; + setValue: Dispatch>; +}; + +/** + * Use the local storage. + * + * @param {string} key - The storage local key. + * @param {T} [fallbackValue] - A fallback value if local storage is empty. + * @returns {UseLocalStorageReturn} An object with value and setValue. + */ +const useLocalStorage = ( + key: string, + fallbackValue: T +): UseLocalStorageReturn => { + const getInitialValue = () => { + if (typeof window === 'undefined') return fallbackValue; + const storedValue = LocalStorage.get(key); + return storedValue || fallbackValue; + }; + + const [value, setValue] = useState(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 = ( + query: string +) => { + const [elements, setElements] = + useState>(); + + 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(key); return storageValue && isValidTheme(storageValue) ? (storageValue as PrismTheme) -- cgit v1.2.3