Description:
Better Modal is a type-safe modal manager for React applications that allows you to define, organize, and control modals using a registry pattern.
Features
- 🔒 Type Safety. You get full TypeScript support for all your modals and their properties.
- 🎨 Variants. Define multiple modal styles or types and apply them easily.
- ⚡ Lazy Loading. Load modal components dynamically to reduce initial bundle size and improve performance.
- 🚀 Preloading. A plugin allows you to preload lazy-loaded components on user interaction for an instant open experience.
- 🔗 URL Sync. Synchronize modal state with the URL to enable sharing and state persistence on refresh.
- 🖥️ RSC Support. The library includes a plugin for compatibility with React Server Components.
How to Use It
1. Install the component using your preferred package manager.
npm install better-modal2. Create a dedicated file to initialize Better Modal. In this file, you import the main function, define your modal variants, and export the helper functions.
modals/init.js
import { betterModal } from "better-modal";
import { CustomDialog } from "@/components/CustomDialog";
// Define variants for different modal types
const m = betterModal({
variants: {
dialog: CustomDialog,
},
});
// Export the helper functions
export const modal = m.modal;
export const registry = m.registry;3. Create a separate file for your modal definitions. Use the modal function to create a modal by passing a React component and selecting a variant. You can also set default properties with the withDefaults function.
modals/definitions.js
import { modal } from "./init";
import { AddUserForm } from "@/components/AddUserForm";
// Create a modal with default variant properties
const addUserModal = modal(AddUserForm, "dialog").withDefaults({
variant: {
title: "Add New User",
description: "Fill in the details to add a new user.",
},
});4. Combine all your modals into a single registry. This centralizes modal management. You can nest modals to organize them by domain.
modals/registry.js
import { registry } from "./init";
import { addUserModal } from "./definitions";
export const modals = registry({
user: {
add: addUserModal,
},
});5. Create a file to generate the React provider and hook. This setup connects Better Modal to your application’s component tree.
modals/react.js
"use client";
import { createBetterModalReact } from "better-modal/react";
import { modals } from "./registry";
export const { useBetterModal, BetterModalProvider } =
createBetterModalReact(modals);Then, mount the BetterModalProvider at the root of your application, for example, in the root layout file.
app/layout.js
import { BetterModalProvider } from "@/modals/react";
export default function RootLayout({ children }) {
return (
<html>
<body>
<BetterModalProvider>{children}</BetterModalProvider>
</body>
</html>
);
}6. Use the useBetterModal hook within your components to access and open modals.
components/UserActions.js
"use client";
import { useBetterModal } from "@/modals/react";
export function UserActions() {
const bm = useBetterModal();
return (
<button onClick={() => bm.user.add.open()}>
Add User
</button>
);
}7. Better Modal offers 3 plugins for extended functionality. The Preload Plugin works with lazy-loaded components to fetch them before they are needed, such as on a mouse hover event. The RSC Plugin enables you to render modal content on the server with React Server Components. The URL Plugin syncs the modal’s state to the URL, which is useful for persisting state or creating shareable links. You can check out the official documentation for more details.
FAQs
Q: How does Better Modal handle type safety?
A: It uses TypeScript to ensure that the properties you pass when opening a modal match the component’s expected props.
Q: What is the purpose of a modal registry?
A: A modal registry acts as a single source of truth for all your modals. This simplifies management and helps prevent circular dependencies in your imports.
Q: Can I use this library with Next.js?
A: Yes, Better Modal is compatible with Next.js and includes specific plugins for React Server Components and URL synchronization that work well with the App Router.