import React, { PropsWithChildren, createContext, useContext, useReducer } from 'react'; export interface StoreContextValue extends InitialState { dispatch: React.Dispatch>>; } export type BlockTagType = keyof JSX.IntrinsicElements; export type Index = Record; export type Fields = React.ReactElement; export type Buttons = React.ReactElement; export type Blocks = React.ReactElement; export interface RenderStateProps { $$index?: Record; fields?: Record; buttons?: Record; blocks?: Record | null>; extra?: Record; [keyname: string]: any; } interface Control { name: string; index: number; children?: T | null; } export interface InitialState extends RenderStateProps { data: { fields: Control[]; buttons: Control[]; blocks: Control>[]; }; } export const initialState: InitialState = { index: {}, fields: {}, buttons: {}, blocks: {}, extra: {}, data: { fields: [], buttons: [], blocks: [], }, }; export const Context = createContext>(initialState as StoreContextValue<'div'>); Context.displayName = 'Login.Context'; export function reducer(state: InitialState, action: Partial): InitialState { const result = { ...state, ...action, $$index: { ...state.$$index, ...action.$$index }, fields: { ...state.fields, ...action.fields }, buttons: { ...state.buttons, ...action.buttons }, blocks: { ...state.blocks, ...action.blocks }, extra: { ...state.extra, ...action.extra }, }; const fieldsArray = Object.keys(result.fields).map((key) => ({ name: key, index: result.fields[key]?.props?.index || (result.$$index || {})[key] || 0, children: result.fields[key], })); const buttonsArray = Object.keys(result.buttons).map((key) => ({ name: key, index: result.buttons[key]?.props?.index || (result.$$index || {})[key] || 0, children: result.buttons[key], })); const blocksArray = Object.keys(result.blocks).map((key) => ({ name: key, index: result.blocks[key]?.props?.index || (result.$$index || {})[key] || 0, children: result.blocks[key], })); return { ...result, data: { ...result.data, fields: fieldsArray, buttons: buttonsArray, blocks: blocksArray } }; } export const useStore = () => { return useContext(Context); }; interface ProviderProps { render?: any; } export const Provider: React.FC> = ({ children, render }) => { const [state, dispatch] = useReducer(reducer, initialState); return {children}; }; Provider.displayName = 'Login.Provider';