diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-24 19:35:12 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-24 19:35:12 +0200 | 
| commit | c85ab5ad43ccf52881ee224672c41ec30021cf48 (patch) | |
| tree | 8058808d9bfca19383f120c46b34d99ff2f89f63 /src/utils/providers | |
| parent | 52404177c07a2aab7fc894362fb3060dff2431a0 (diff) | |
| parent | 11b9de44a4b2f305a6a484187805e429b2767118 (diff) | |
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/utils/providers')
| -rw-r--r-- | src/utils/providers/ackee.tsx | 3 | ||||
| -rw-r--r-- | src/utils/providers/prism-theme.tsx | 80 | 
2 files changed, 35 insertions, 48 deletions
| diff --git a/src/utils/providers/ackee.tsx b/src/utils/providers/ackee.tsx index c103668..0cb0166 100644 --- a/src/utils/providers/ackee.tsx +++ b/src/utils/providers/ackee.tsx @@ -1,5 +1,5 @@  import { useRouter } from 'next/router'; -import { createContext, FC, useContext, useState } from 'react'; +import { createContext, FC, ReactNode, useContext, useState } from 'react';  import useAckee from 'use-ackee';  export type AckeeProps = { @@ -10,6 +10,7 @@ export type AckeeProps = {  };  export type AckeeProviderProps = { +  children: ReactNode;    domain: string;    siteId: string;    ignoreLocalhost?: boolean; diff --git a/src/utils/providers/prism-theme.tsx b/src/utils/providers/prism-theme.tsx index 2ed8454..dd8feb7 100644 --- a/src/utils/providers/prism-theme.tsx +++ b/src/utils/providers/prism-theme.tsx @@ -1,7 +1,10 @@ -import { LocalStorage } from '@services/local-storage'; +import useAttributes from '@utils/hooks/use-attributes'; +import useLocalStorage from '@utils/hooks/use-local-storage'; +import useQuerySelectorAll from '@utils/hooks/use-query-selector-all';  import {    createContext,    FC, +  ReactNode,    useCallback,    useContext,    useEffect, @@ -9,7 +12,7 @@ import {  } from 'react';  export type PrismTheme = 'dark' | 'light' | 'system'; -export type ResolvedPrismTheme = 'dark' | 'light'; +export type ResolvedPrismTheme = Exclude<PrismTheme, 'system'>;  export type UsePrismThemeProps = {    themes: PrismTheme[]; @@ -17,11 +20,11 @@ export type UsePrismThemeProps = {    setTheme: (theme: PrismTheme) => void;    resolvedTheme?: ResolvedPrismTheme;    codeBlocks?: NodeListOf<HTMLPreElement>; -  setCodeBlocks: (codeBlocks: NodeListOf<HTMLPreElement>) => void;  };  export type PrismThemeProviderProps = {    attribute?: string; +  children: ReactNode;    storageKey?: string;    themes?: PrismTheme[];  }; @@ -31,14 +34,16 @@ export const PrismThemeContext = createContext<UsePrismThemeProps>({    setTheme: (_) => {      // This is intentional.    }, -  setCodeBlocks: (_) => { -    // This is intentional. -  },  });  export const usePrismTheme = () => useContext(PrismThemeContext); -const prefersDarkScheme = () => { +/** + * Check if user prefers dark color scheme. + * + * @returns {boolean|undefined} True if `prefers-color-scheme` is set to `dark`. + */ +const prefersDarkScheme = (): boolean | undefined => {    if (typeof window === 'undefined') return;    return ( @@ -47,40 +52,35 @@ const prefersDarkScheme = () => {    );  }; +/** + * Check if a given string is a Prism theme name. + * + * @param {string} theme - A string. + * @returns {boolean} True if the given string match a Prism theme name. + */  const isValidTheme = (theme: string): boolean => {    return theme === 'dark' || theme === 'light' || theme === 'system';  }; -const getTheme = (key: string): PrismTheme | undefined => { -  if (typeof window === 'undefined') return undefined; -  const storageValue = LocalStorage.get(key); - -  return storageValue && isValidTheme(storageValue) -    ? (storageValue as PrismTheme) -    : undefined; -}; -  export const PrismThemeProvider: FC<PrismThemeProviderProps> = ({    attribute = 'data-prismjs-color-scheme-current',    storageKey = 'prismjs-color-scheme',    themes = ['dark', 'light', 'system'],    children,  }) => { +  /** +   * Retrieve the theme to use depending on `prefers-color-scheme`. +   */    const getThemeFromSystem = useCallback(() => {      return prefersDarkScheme() ? 'dark' : 'light';    }, []); -  const [prismTheme, setPrismTheme] = useState<PrismTheme>( -    getTheme(storageKey) || 'system' -  ); - -  const updateTheme = (theme: PrismTheme) => { -    setPrismTheme(theme); -  }; +  const { value: prismTheme, setValue: setPrismTheme } = +    useLocalStorage<PrismTheme>(storageKey, 'system');    useEffect(() => { -    LocalStorage.set(storageKey, prismTheme); -  }, [prismTheme, storageKey]); +    if (!isValidTheme(prismTheme)) setPrismTheme('system'); +  }, [prismTheme, setPrismTheme]);    const [resolvedTheme, setResolvedTheme] = useState<ResolvedPrismTheme>(); @@ -107,22 +107,12 @@ export const PrismThemeProvider: FC<PrismThemeProviderProps> = ({          .removeEventListener('change', updateResolvedTheme);    }, [updateResolvedTheme]); -  const [preTags, setPreTags] = useState<NodeListOf<HTMLPreElement>>(); - -  const updatePreTags = useCallback((tags: NodeListOf<HTMLPreElement>) => { -    setPreTags(tags); -  }, []); - -  const updatePreTagsAttribute = useCallback(() => { -    preTags?.forEach((pre) => { -      pre.setAttribute(attribute, prismTheme); -    }); -  }, [attribute, preTags, prismTheme]); - -  useEffect(() => { -    updatePreTagsAttribute(); -  }, [updatePreTagsAttribute, prismTheme]); +  const preTags = useQuerySelectorAll<'pre'>('pre'); +  useAttributes({ elements: preTags, attribute, value: prismTheme }); +  /** +   * Listen for changes on pre attributes and update theme. +   */    const listenAttributeChange = useCallback(      (pre: HTMLPreElement) => {        var observer = new MutationObserver(function (mutations) { @@ -137,15 +127,12 @@ export const PrismThemeProvider: FC<PrismThemeProviderProps> = ({          attributeFilter: [attribute],        });      }, -    [attribute] +    [attribute, setPrismTheme]    );    useEffect(() => {      if (!preTags) return; - -    preTags.forEach((pre) => { -      listenAttributeChange(pre); -    }); +    preTags.forEach(listenAttributeChange);    }, [preTags, listenAttributeChange]);    return ( @@ -153,9 +140,8 @@ export const PrismThemeProvider: FC<PrismThemeProviderProps> = ({        value={{          themes,          theme: prismTheme, -        setTheme: updateTheme, +        setTheme: setPrismTheme,          codeBlocks: preTags, -        setCodeBlocks: updatePreTags,          resolvedTheme,        }}      > | 
