refactor: move @theme/hooks to @docusaurus/theme-common (#6289)

This commit is contained in:
Sébastien Lorber 2022-01-07 19:19:35 +01:00 committed by GitHub
parent 024f2bf49b
commit f87a3ead46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 245 additions and 401 deletions

View file

@ -0,0 +1,90 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, {
useState,
useCallback,
useEffect,
createContext,
useMemo,
useContext,
type ReactNode,
} from 'react';
import {createStorageSlot, listStorageKeys} from './storageUtils';
const TAB_CHOICE_PREFIX = 'docusaurus.tab.';
type TabGroupChoiceContextValue = {
readonly tabGroupChoices: {readonly [groupId: string]: string};
readonly setTabGroupChoices: (groupId: string, newChoice: string) => void;
};
const TabGroupChoiceContext = createContext<
TabGroupChoiceContextValue | undefined
>(undefined);
function useTabGroupChoiceContextValue(): TabGroupChoiceContextValue {
const [tabGroupChoices, setChoices] = useState<{
readonly [groupId: string]: string;
}>({});
const setChoiceSyncWithLocalStorage = useCallback((groupId, newChoice) => {
createStorageSlot(`${TAB_CHOICE_PREFIX}${groupId}`).set(newChoice);
}, []);
useEffect(() => {
try {
const localStorageChoices: Record<string, string> = {};
listStorageKeys().forEach((storageKey) => {
if (storageKey.startsWith(TAB_CHOICE_PREFIX)) {
const groupId = storageKey.substring(TAB_CHOICE_PREFIX.length);
localStorageChoices[groupId] = createStorageSlot(storageKey).get()!;
}
});
setChoices(localStorageChoices);
} catch (err) {
console.error(err);
}
}, []);
return {
tabGroupChoices,
setTabGroupChoices: (groupId: string, newChoice: string) => {
setChoices((oldChoices) => ({...oldChoices, [groupId]: newChoice}));
setChoiceSyncWithLocalStorage(groupId, newChoice);
},
};
}
export function TabGroupChoiceProvider({
children,
}: {
children: ReactNode;
}): JSX.Element {
const {tabGroupChoices, setTabGroupChoices} = useTabGroupChoiceContextValue();
const contextValue = useMemo(
() => ({
tabGroupChoices,
setTabGroupChoices,
}),
[tabGroupChoices, setTabGroupChoices],
);
return (
<TabGroupChoiceContext.Provider value={contextValue}>
{children}
</TabGroupChoiceContext.Provider>
);
}
export function useTabGroupChoice(): TabGroupChoiceContextValue {
const context = useContext(TabGroupChoiceContext);
if (context == null) {
throw new Error(
'"useUserPreferencesContext" is used outside of "Layout" component.',
);
}
return context;
}