react-simpler-modal
Version:
a lightweight, hook-based modal management library for React. It leverages React Context and custom hooks to offer an intuitive, type-safe API for handling multiple modals—making it easy to show, hide, update, and persist modal state across your app.
102 lines (98 loc) • 3.54 kB
TypeScript
import * as react_jsx_runtime from 'react/jsx-runtime';
import { ReactNode } from 'react';
/**
* Options for modal actions that support merging data.
*/
interface MergeOptions {
/**
* If true, merge new data with the existing data (when both are objects)
*/
mergeData?: boolean;
}
/**
* Options for hiding a modal.
*/
interface HideOptions {
/**
* If true, retain the modal's data after hiding it.
*/
persistData?: boolean;
}
/**
* Represents the state for all modals.
*
* Each property in the state corresponds to a modal key defined in the generic type `M`.
* Each modal has:
* - `isShowing`: A boolean indicating whether the modal is currently open.
* - `data`: Optional data associated with the modal, whose type is defined by `M[K]`.
*
* @template M - A mapping from modal keys to their corresponding data types.
*/
type ModalState<M extends Record<string, any>> = {
[K in keyof M]: {
isShowing: boolean;
data?: M[K];
};
};
/**
* Represents an action that can be dispatched to the modal reducer.
*
* This union type supports the following actions:
*
* - **SHOW_MODAL**: Opens a modal with the provided data.
* - Uses MergeOptions: If mergeData is true and both existing and new data are objects, they are merged.
*
* - **HIDE_MODAL**: Closes a modal.
* - Uses HideOptions: If persistData is true, the modal’s data is retained.
*
* - **TOGGLE_MODAL**: Toggles the open state of a modal.
* - When opening, accepts data with an optional MergeOptions.
*
* - **UPDATE_MODAL_DATA**: Updates the modal’s data without changing its open/closed state.
* - Uses MergeOptions: If mergeData is true and both current and new data are objects, they will be merged.
*
* @template M - A mapping from modal keys to their corresponding data types.
*/
type ModalAction<M extends Record<string, any>> = {
type: 'SHOW_MODAL';
modalType: keyof M;
data?: M[keyof M];
options?: MergeOptions;
} | {
type: 'HIDE_MODAL';
modalType: keyof M;
options?: HideOptions;
} | {
type: 'TOGGLE_MODAL';
modalType: keyof M;
data?: M[keyof M];
options?: MergeOptions;
} | {
type: 'UPDATE_MODAL_DATA';
modalType: keyof M;
data: Partial<M[keyof M]>;
options?: MergeOptions;
};
/**
* Factory for creating a modal context with a strongly typed API.
*
* @template M - A mapping from modal keys to their corresponding data types.
* @param initialState - The initial modal state.
* @returns An object containing:
* - ModalProvider: The context provider component.
* - useModal: A hook to access modal actions and state.
*/
declare function simplerModalFactory<M extends Record<string, any>>(initialState: ModalState<M>): {
ModalProvider: ({ children }: {
children: ReactNode;
}) => react_jsx_runtime.JSX.Element;
useModal: () => {
showModal: <K extends keyof M>(modalType: K, data?: M[K], options?: MergeOptions) => void;
hideModal: <K extends keyof M>(modalType: K, options?: HideOptions) => void;
toggleModal: <K extends keyof M>(modalType: K, data: M[K], options?: MergeOptions) => void;
updateModalData: <K extends keyof M>(modalType: K, data: Partial<M[K]>, options?: MergeOptions) => void;
isModalOpen: <K extends keyof M>(modalType: K) => boolean;
getModalData: <K extends keyof M>(modalType: K) => M[K] | undefined;
};
};
export { type HideOptions, type MergeOptions, type ModalAction, type ModalState, simplerModalFactory };