API Reference
grunfeld.add()#
The grunfeld.add() method is the core API for creating new dialogs. It provides two overloads to support various use cases.
Alert Overload#
Using a factory function without parameters creates a simple alert:
grunfeld.add(() => React.ReactNode | GrunfeldProps): void
This overload returns void and executes immediately. You can return a React element directly or return a GrunfeldProps object.
// Direct React element return
grunfeld.add(() => <div>Simple alert</div>);
// With options
grunfeld.add(() => ({
element: <div>Positioned alert</div>,
position: "top-right",
lightDismiss: false,
}));
Response Overload#
Using a factory function that receives the removeWith parameter allows you to receive user responses:
grunfeld.add<T>((removeWith: (data: T) => void) => GrunfeldProps): Promise<T | undefined>
This overload returns Promise<T | undefined>. When the user calls removeWith(value), the Promise resolves with that value.
const result = await grunfeld.add<boolean>((removeWith) => ({
element: (
<div>
<p>Are you sure?</p>
<button onClick={() => removeWith(true)}>Yes</button>
<button onClick={() => removeWith(false)}>No</button>
</div>
),
}));
// Receive string input
const input = await grunfeld.add<string>((removeWith) => ({
element: <InputForm onSubmit={removeWith} />,
}));
GrunfeldProps#
An object specifying dialog options:
interface GrunfeldProps {
element: React.ReactNode;
position?: Position;
lightDismiss?: boolean;
backdropStyle?: React.CSSProperties;
dismissCallback?: () => unknown;
renderMode?: "inline" | "top-layer";
}
element: The React element to display in the dialogposition: The position of the dialog (default: 'center')lightDismiss: Whether to close on backdrop click (default: true)renderMode: Rendering mode ('inline' | 'top-layer', default: 'inline')backdropStyle: CSS styles for the backdropdismissCallback: Callback executed when the dialog closes
Promise Interruption#
When a dialog is forcibly closed by grunfeld.remove() or grunfeld.clear(), the Promise resolves with undefined:
const promise = grunfeld.add<boolean>((removeWith) => ({
element: (
<div>
<p>Are you sure?</p>
<button onClick={() => removeWith(true)}>Yes</button>
<button onClick={() => removeWith(false)}>No</button>
</div>
),
}));
// Force remove dialog from elsewhere
setTimeout(() => {
grunfeld.remove(); // promise resolves to undefined
}, 1000);
const result = await promise; // result is undefined
if (result === undefined) {
console.log("Dialog was interrupted");
}
You can use this to handle interruptions due to timeouts or external events.
remove & clear#
Grunfeld provides two methods for removing dialogs.
grunfeld.remove()#
Removes the most recently added dialog. Dialogs are removed in LIFO (Last In First Out) order:
// Remove most recent dialog
grunfeld.remove();
// Usage example
grunfeld.add(() => <div>First</div>);
grunfeld.add(() => <div>Second</div>);
grunfeld.add(() => <div>Third</div>);
grunfeld.remove(); // "Third" is removed
grunfeld.remove(); // "Second" is removed
This method resolves the dialog's Promise with undefined. When multiple dialogs are stacked, only the topmost dialog is removed.
grunfeld.clear()#
Removes all dialogs at once:
// Remove all dialogs
grunfeld.clear();
// Usage example
grunfeld.add(() => <div>First</div>);
grunfeld.add(() => <div>Second</div>);
grunfeld.add(() => <div>Third</div>);
grunfeld.clear(); // All dialogs are removed
This method resolves all dialogs' Promises with undefined. Useful in emergencies or during route changes.
ESC Key and Light Dismiss#
Users can also close dialogs using the following methods:
- ESC Key: Closes the most recent dialog (same as grunfeld.remove())
- Backdrop Click: Closes the dialog if
lightDismiss: true
These user actions also resolve the Promise with undefined.
TypeScript Types#
Grunfeld provides full TypeScript support. All types can be imported from the package.
Core Types#
Main type definitions:
import type {
GrunfeldProps,
Position,
RenderMode
} from "@ilokesto/grunfeld";
interface GrunfeldProps {
element: React.ReactNode;
position?: Position;
lightDismiss?: boolean;
backdropStyle?: React.CSSProperties;
dismissCallback?: () => unknown;
renderMode?: RenderMode;
}
type RenderMode = "inline" | "top-layer";
Position Type#
A type that specifies the dialog's position. You can specify exact positions using a 9-grid system:
type PositionX = "left" | "center" | "right";
type PositionY = "top" | "center" | "bottom";
type Position = `${PositionY}-${PositionX}` | "center";
// All available Position values:
// "top-left", "top-center", "top-right",
// "center-left", "center", "center-right",
// "bottom-left", "bottom-center", "bottom-right"
Generic Type Parameters#
The generic parameter of grunfeld.add<T>() determines the argument type of the removeWith function and the type of the returned Promise:
// Return boolean
const result = await grunfeld.add<boolean>((removeWith) => ({
element: <ConfirmDialog onConfirm={removeWith} />,
}));
// result type: boolean | undefined
// Return custom object
interface FormData {
email: string;
password: string;
}
const data = await grunfeld.add<FormData>((removeWith) => ({
element: <LoginForm onSubmit={removeWith} />,
}));
// data type: FormData | undefined
For type safety, it's recommended to always explicitly specify the generic type.