All files / src store.tsx

90.9% Statements 20/22
100% Branches 0/0
57.14% Functions 4/7
90.47% Lines 19/21

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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94                                                22x             22x 22x   22x 22x     49x           22x 3008x     22x                 22x         123x 123x 123x 123x 123x 123x 123x 123x                                             22x  
import React, { PropsWithChildren, createContext, useContext, useEffect, useReducer } from 'react';
import { JsonViewProps } from './';
import { useShowTools, ShowTools } from './store/ShowTools';
import { useExpands, Expands } from './store/Expands';
import { useTypes, Types, type InitialTypesState, type TagType } from './store/Types';
import { useSymbols, Symbols } from './store/Symbols';
import { useSection, Section } from './store/Section';
 
export type BlockTagType = keyof JSX.IntrinsicElements;
 
export interface InitialState<T extends object> {
  value?: object;
  onExpand?: JsonViewProps<object>['onExpand'];
  onCopied?: JsonViewProps<object>['onCopied'];
  objectSortKeys?: JsonViewProps<T>['objectSortKeys'];
  displayObjectSize?: JsonViewProps<T>['displayObjectSize'];
  shortenTextAfterLength?: JsonViewProps<T>['shortenTextAfterLength'];
  enableClipboard?: JsonViewProps<T>['enableClipboard'];
  highlightUpdates?: JsonViewProps<T>['highlightUpdates'];
  collapsed?: JsonViewProps<T>['collapsed'];
  shouldExpandNodeInitially?: JsonViewProps<T>['shouldExpandNodeInitially'];
  indentWidth?: number;
}
 
export const initialState: InitialState<object> = {
  objectSortKeys: false,
  indentWidth: 15,
};
 
type Dispatch = React.Dispatch<InitialState<object>>;
 
export const Context = createContext<InitialState<object>>(initialState);
Context.displayName = 'JVR.Context';
 
const DispatchContext = createContext<Dispatch>(() => {});
DispatchContext.displayName = 'JVR.DispatchContext';
 
export function reducer(state: InitialState<object>, action: InitialState<object>): InitialState<object> {
  return {
    ...state,
    ...action,
  };
}
 
export const useStore = () => {
  return useContext(Context);
};
 
export const useDispatchStore = () => {
  return useContext(DispatchContext);
};
 
export interface ProviderProps<T extends TagType> {
  initialState?: InitialState<object>;
  initialTypes?: InitialTypesState<T>;
}
 
export const Provider = <T extends TagType>({
  children,
  initialState: init,
  initialTypes,
}: PropsWithChildren<ProviderProps<T>>) => {
  const [state, dispatch] = useReducer(reducer, Object.assign({}, initialState, init));
  const [showTools, showToolsDispatch] = useShowTools();
  const [expands, expandsDispatch] = useExpands();
  const [types, typesDispatch] = useTypes();
  const [symbols, symbolsDispatch] = useSymbols();
  const [section, sectionDispatch] = useSection();
  useEffect(() => dispatch({ ...init }), [init]);
  return (
    <Context.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>
        <ShowTools initial={showTools} dispatch={showToolsDispatch}>
          <Expands initial={expands} dispatch={expandsDispatch}>
            <Types initial={{ ...types, ...initialTypes }} dispatch={typesDispatch}>
              <Symbols initial={symbols} dispatch={symbolsDispatch}>
                <Section initial={section} dispatch={sectionDispatch}>
                  {children}
                </Section>
              </Symbols>
            </Types>
          </Expands>
        </ShowTools>
      </DispatchContext.Provider>
    </Context.Provider>
  );
};
 
export function useDispatch() {
  return useContext(DispatchContext);
}
 
Provider.displayName = 'JVR.Provider';