Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 5x 5x 87x 86x 2x 84x 5x 47x 5x 40x 5x 5x 5x 16x 16x 16x 16x 16x 16x | import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import { createContext, useContextSelector } from 'use-context-selector';
export interface FabState {
fabOffset: number;
fabHidden: boolean;
}
export interface FabActions {
setFabOffset: (offset: number) => void;
setFabHidden: (hidden: boolean) => void;
}
interface FabContextValue {
state: FabState;
actions: FabActions;
}
const FabContext = createContext<FabContextValue | null>(null);
const useFabSelector = <T,>(selector: (ctx: FabContextValue) => T): T => {
return useContextSelector(FabContext, ctx => {
if (!ctx) {
throw new Error('useFabSelector must be used within a FabProvider');
}
return selector(ctx);
});
};
export const useFabStateSelector = <T,>(selector: (state: FabState) => T): T =>
useFabSelector(ctx => selector(ctx.state));
export const useFabActionsSelector = <T,>(selector: (actions: FabActions) => T): T =>
useFabSelector(ctx => selector(ctx.actions));
/** Setter passed down to remotes so they can anchor the FAB above their bottom button. */
export const useSetFabOffset = (): ((offset: number) => void) =>
useFabActionsSelector(a => a.setFabOffset);
/** Hides the chat FAB while `hidden` is true; always restores it on unmount. */
export const useFabHidden = (hidden: boolean): void => {
const setFabHidden = useFabActionsSelector(a => a.setFabHidden);
useEffect(() => {
setFabHidden(hidden);
return () => setFabHidden(false);
}, [hidden, setFabHidden]);
};
export const FabProvider = ({ children }: { children: ReactNode }) => {
const [fabOffset, setFabOffset] = useState(0);
const [fabHidden, setFabHidden] = useState(false);
const state = useMemo<FabState>(() => ({ fabOffset, fabHidden }), [fabOffset, fabHidden]);
const actions = useMemo<FabActions>(() => ({ setFabOffset, setFabHidden }), []);
const value = useMemo<FabContextValue>(() => ({ state, actions }), [state, actions]);
return <FabContext.Provider value={value}>{children}</FabContext.Provider>;
};
|