import React, { Dispatch, createContext, useContext, useReducer } from 'react'; import { languagesData } from './data'; type State = { text: string; visible: string[]; expanded: string[]; textTransform: 'normal' | 'uppercase' | 'lowercase'; }; type Action = | { type: 'set-text'; text: string; } | { type: 'set-text-transform'; textTransform: 'normal' | 'uppercase' | 'lowercase'; } | { type: 'toggle-visibility'; lang: string; } | { type: 'toggle-expand'; lang: string; } | { type: 'expand-all'; } | { type: 'collapse-all'; } | { type: 'reset'; }; const initialState: State = { text: '', textTransform: 'normal', visible: languagesData.map(lang => lang.code), expanded: [], }; function reducer(state: State, action: Action): State { const newState = structuredClone(state); switch (action.type) { case 'set-text': { newState.text = action.text; return newState; } case 'set-text-transform': { newState.textTransform = action.textTransform; return newState; } case 'toggle-visibility': { if (newState.visible.includes(action.lang)) { newState.visible = newState.visible.filter(lang => lang !== action.lang); } else { newState.visible.push(action.lang); } return newState; } case 'toggle-expand': { if (newState.expanded.includes(action.lang)) { newState.expanded = newState.expanded.filter(lang => lang !== action.lang); } else { newState.expanded.push(action.lang); } return newState; } case 'expand-all': { newState.expanded = languagesData.map(lang => lang.code); return newState; } case 'collapse-all': { newState.expanded = []; return newState; } case 'reset': { return initialState; } default: { return state; } } } const stateCtx = createContext(initialState); const dispatchCtx = createContext>(() => {}); export function FontsExplorerProvider({ children }: { children: React.ReactNode }) { const [state, dispatch] = useReducer(reducer, initialState); return ( {children} ); } export function useFontsExplorerState() { const state = useContext(stateCtx); const dispatch = useContext(dispatchCtx); return [state, dispatch] as const; }