UNPKG

@kwiz/fluentui

Version:
68 lines (67 loc) 2.98 kB
import { iLoadingProps } from "../controls/loading"; import { iPleaseWaitProps } from "../controls/please-wait"; type queueType = "required" | "optional" | "idle"; type isLoadingType = { type: queueType; label?: string; }; export interface iUseReloadTracker<Scope extends string = "global"> { /** marker to set as dependency when you want to re-run the effect when reload was called */ reloadKey: { [key in withGlobal<Scope>]?: number; }; /** call to reload scope+global, or send global to reload all scopes */ reload: (scope?: Scope) => void; /** state: is there pending promises in the queue */ isLoading: isLoadingType; /** add a loading promise to the queue */ queue: <Result>(promise: () => Promise<Result>, info: { label: string; type?: queueType; /** will use promiseOnce if provided, along with the reload key */ cacheKey?: string; /** switch reloadKey scope for cacheKey. Global will update on any reload. You want to set this if you have a dependency on reloadKey.[scope] that is not global */ cacheScope?: Scope; }) => Promise<Result>; /** render loading animation, or track isLoading to add animation yourself */ reloadElement?: JSX.Element; } type withGlobal<t extends string> = t | "global"; /** a simple reload marker, can be used as a dependency, and called as a function */ export declare function useReloadTracker<Scope extends string = "global">(props?: { requiredElement?: Partial<iLoadingProps> | JSX.Element; optionalElement?: Partial<iPleaseWaitProps> | JSX.Element; }): iUseReloadTracker<Scope>; export {}; /** examples * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ * in your main/top control or in your context provider, call: * const rt = useReloadTracker(); * render its content: * {rt.reloadElement} * * load content that never changes, and cached (type:'required' will cover the page content while this is pending): * useEffect(() => { * queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION', type: "required" }) * .then(result => setResult(result)); * }, [queue]); * * load content that changes based on other state, and cached: * useEffect(() => { * queue(() => ASYNC_ACTION(STATE1), { label:'Loading XXX', cacheKey: `ASYNC_ACTION|${STATE1}` }) * .then(result => setResult(result)); * }, [queue, STATE1]); * * load content that changes when you call reload anywhere: * useEffect(() => { * queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION' }) * .then(result => setResult(result)); * }, [queue, reloadKey.global]); * * load content that changes when you call reload('scope1') anywhere: * useEffect(() => { * queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION', cacheScope: 'scope1' }) * .then(result => setResult(result)); * }, [queue, reloadKey.scope1]); * */