Gathering detailed insights and metrics for @ebay/nice-modal-react
Gathering detailed insights and metrics for @ebay/nice-modal-react
Gathering detailed insights and metrics for @ebay/nice-modal-react
Gathering detailed insights and metrics for @ebay/nice-modal-react
nice-modal-vue
这是个方便管理、调用弹窗、抽屉的 Vue 工具包,适用于 Ant Design Vue、Element Plus 等常用的 Vue 组件库。 代码逻辑~~抄袭~~借鉴自[@ebay/nice-modal-react](https://github.com/eBay/nice-modal-react)。
@whop-core/modal-manager
A simple utility for managing modals in React. Based on [nice-modal-react](https://github.com/eBay/nice-modal-react)
vfup-nice-modal-react
此项目基于 [@ebay/nice-modal-react](https://github.com/eBay/nice-modal-react)。
nice-modal-antd
## 基于@ebay/nice-modal-react修改
npm install @ebay/nice-modal-react
Typescript
Module System
Node Version
NPM Version
TypeScript (57.7%)
JavaScript (42.3%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
2,200 Stars
282 Commits
124 Forks
10 Watchers
4 Branches
40 Contributors
Updated on Jul 15, 2025
Latest Version
1.2.13
Package Id
@ebay/nice-modal-react@1.2.13
Unpacked Size
124.95 kB
Size
23.05 kB
File Count
12
NPM Version
8.19.3
Node Version
18.13.0
Published on
Oct 03, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
22
This is a small, zero dependency utility to manage modals in a natural way for React. It uses context to persist state of modals globally so that you can show/hide a modal easily either by the modal component or id.
You can also see the introduction at eBay tech blog.
For example, you can use below code to show a modal anywhere:
1import NiceModal from '@ebay/nice-modal-react'; 2import MyModal from './MyModal'; 3 4//... 5NiceModal.show(MyModal, { someProp: 'hello' }).then(() => { 6 // do something if the task in the modal finished. 7}); 8//...
Or you can register the modal with an id so that you don't need to import the modal component to use it:
1import NiceModal from '@ebay/nice-modal-react'; 2import MyModal from './MyModal'; 3 4NiceModal.register('my-modal', MyModal); 5 6// you can use the string id to show/hide the modal anywhere 7NiceModal.show('my-modal', { someProp: 'hello' }).then(() => { 8 // do something if the task in the modal finished. 9}); 10//... 11
NOTE: @ebay/nice-modal-react
is not a React modal component but should be used with other modal/dialog implementions by UI libraries like Material UI, Ant.Design, Bootstrap React, etc.
You can see a list of examples at: https://ebay.github.io/nice-modal-react
Using modals in React is a bit frustrating. Think of that if you need to implement below UI:
The dialog is used to create a JIRA ticket. It could be shown from many places, from the header, to the context menu, to the list page. Traditionally, we had declared modal components with a JSX tag. But then the question became, “Where should we declare the tag?”
The most common option was to declare it wherever it was being used. But using modals in a declarative way is not only about a JSX tag, but also about maintaining the modal’s state like visibility, parameters in the container component. Declaring it everywehre means managing state everywhere. It's frustrating.
The other option put it in the Root component, for example:
1const Root = () => { 2 const [visible, setVisible] = useState(false); 3 // other logic ... 4 return ( 5 <> 6 <Main /> 7 <NewTicketModal visible={visible} /> 8 </> 9 ); 10}
However, when you declare the modal in the root component, there are some issues:
setVisible
down to the place where you need to show or hide the modal. It makes things too complicated.Unfortunately, most examples of using modals just follow this practice, it causes such confusions when managing modals in React.
I believe you must once encountered with the scenario that originally you only needed to show a modal when click a button, then when requirements changed, you need to open the same modal from a different place. Then you have to refactor your code to re-consider where to declare the modal. The root cause of such annoying things is just because we have not understood the essential of a modal.
According to the wikipedia, a modal can be described as:
A window that prevents the user from interacting with your application until he closes the window.
From the definition we can get a conclusion: a modal is a global view that's not necessarily related with a specific context.
This is very similar with the page concept in a single page UI application. The visibility/ state of modals should be managed globally because, from the UI perspective, a modal could be showed above any page/component. The only difference between modal and page is: a modal allows you to not leave the current page to do some separate tasks.
For pages management, we already have router framework like React Router, it helps to navigate to a page by URL. Actually, you can think URL a global id for a page. So, similarly, what if you assign a uniq id to a modal then show/hide it by the id? This is just how we designed NiceModal.
However, besides using id, NiceModal allows to use the modal component directly to manage it.
1# with yarn 2yarn add @ebay/nice-modal-react 3 4# or with npm 5npm install @ebay/nice-modal-react
With NiceModal you can create a separate modal component easily. It's just the same as you create a normal component but wrap it with high order compponent by NiceModal.create
. For example, below code shows how to create a dialog with Ant.Design:
1import { Modal } from 'antd'; 2import NiceModal, { useModal } from '@ebay/nice-modal-react'; 3 4export default NiceModal.create(({ name }) => { 5 // Use a hook to manage the modal state 6 const modal = useModal(); 7 return ( 8 <Modal 9 title="Hello Antd" 10 onOk={() => modal.hide()} 11 visible={modal.visible} 12 onCancel={() => modal.hide()} 13 afterClose={() => modal.remove()} 14 > 15 Hello {name}! 16 </Modal> 17 ); 18});
From the code, we can see:
NiceModal.create
ensures your component is not executed before it becomes visible.modal.remove
to remove your modal component from the React component tree to reserve transitions.Next, let's see how to use the modal.
There are very flexible APIs for you to manage modals. See below for the introduction.
NiceModal.Provider
:Since we will manage status of modals globally, the first thing is embedding your app with NiceModal provider, for example:
1import NiceModal from '@ebay/nice-modal-react'; 2ReactDOM.render( 3 <React.StrictMode> 4 <NiceModal.Provider> 5 <App /> 6 </NiceModal.Provider> 7 </React.StrictMode>, 8 document.getElementById('root'), 9);
The provider will use React context to maintain all modals' state.
You can control a nice modal by the component itself.
1import NiceModal from '@ebay/nice-modal-react'; 2import MyAntdModal from './my-antd-modal'; // created by above code 3 4function App() { 5 const showAntdModal = () => { 6 // Show a modal with arguments passed to the component as props 7 NiceModal.show(MyAntdModal, { name: 'Nate' }) 8 }; 9 return ( 10 <div className="app"> 11 <h1>Nice Modal Examples</h1> 12 <div className="demo-buttons"> 13 <button onClick={showAntdModal}>Antd Modal</button> 14 </div> 15 </div> 16 ); 17}
You can also control a nice modal by id:
1import NiceModal from '@ebay/nice-modal-react'; 2import MyAntdModal from './my-antd-modal'; // created by above code 3 4// If use by id, need to register the modal component. 5// Normally you create a modals.js file in your project 6// and register all modals there. 7NiceModal.register('my-antd-modal', MyAntdModal); 8 9function App() { 10 const showAntdModal = () => { 11 // Show a modal with arguments passed to the component as props 12 NiceModal.show('my-antd-modal', { name: 'Nate' }) 13 }; 14 return ( 15 <div className="app"> 16 <h1>Nice Modal Examples</h1> 17 <div className="demo-buttons"> 18 <button onClick={showAntdModal}>Antd Modal</button> 19 </div> 20 </div> 21 ); 22}
The useModal
hook can not only be used inside a modal component but also any component by passing it a modal id/component:
1import NiceModal, { useModal } from '@ebay/nice-modal-react'; 2import MyAntdModal from './my-antd-modal'; // created by above code 3 4NiceModal.register('my-antd-modal', MyAntdModal); 5//... 6// if use with id, need to register it first 7const modal = useModal('my-antd-modal'); 8// or if with component, no need to register 9const modal = useModal(MyAntdModal); 10 11//... 12modal.show({ name: 'Nate' }); // show the modal 13modal.hide(); // hide the modal 14//...
register
The nice modal component you created can be also used as a normal component by JSX, then you don't need to register it. For example:
1import NiceModal, { useModal } from '@ebay/nice-modal-react'; 2import MyAntdModal from './my-antd-modal'; // created by above code 3 4function App() { 5 const showAntdModal = () => { 6 // Show a modal with arguments passed to the component as props 7 NiceModal.show('my-antd-modal') 8 }; 9 return ( 10 <div className="app"> 11 <h1>Nice Modal Examples</h1> 12 <div className="demo-buttons"> 13 <button onClick={showAntdModal}>Antd Modal</button> 14 </div> 15 <MyAntdModal id="my-antd-modal" name="Nate" /> 16 </div> 17 ); 18}
With this approach, you can get the benifits:
NOTE: if you show the component by id but the modal is not declared or registered. Nothing will happen but only a warning message in the dev console.
Besides using props to interact with the modal from the parent component, you can do it easier by promise. For example, we have a user list page with a add user button to show a dialog to add user. After user is added the list should refresh itself to reflect the change, then we can use below code:
1NiceModal.show(AddUserModal) 2 .then(() => { 3 // When call modal.resolve(payload) in the modal component 4 // it will resolve the promise returned by `show` method. 5 // fetchUsers will call the rest API and update the list 6 fetchUsers() 7 }) 8 .catch(err=> { 9 // if modal.reject(new Error('something went wrong')), it will reject the promise 10 });
You can see the live example on codesandbox.
Though not necessary, you can integrate Redux to manage state of nice modals. Then you can use Redux dev tools to track/debug state change of modals. Here is how to do it:
1// First combine the reducer 2import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; 3import { Provider, useSelector, useDispatch } from 'react-redux'; 4import NiceModal from '@ebay/nice-modal-react'; 5import { Button } from 'antd'; 6import { MyAntdModal } from './MyAntdModal'; 7import logger from 'redux-logger'; 8 9const composeEnhancers = (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose; 10const enhancer = composeEnhancers(applyMiddleware(logger)); 11 12const store = createStore( 13 combineReducers({ 14 modals: NiceModal.reducer, 15 // other reducers... 16 }), 17 enhancer, 18); 19 20// Passing Redux state to the nice modal provider 21const ModalsProvider = ({ children }) => { 22 const modals = useSelector((s) => s.modals); 23 const dispatch = useDispatch(); 24 return ( 25 <NiceModal.Provider modals={modals} dispatch={dispatch}> 26 {children} 27 </NiceModal.Provider> 28 ); 29}; 30 31export default function ReduxProvider({ children }) { 32 return ( 33 <Provider store={store}> 34 <ModalsProvider>{children}</ModalsProvider> 35 </Provider> 36 ); 37}
NiceModal provides lifecyle methods to manage the state of modals. You can use modal handler returned by useModal
hook to bind any modal like component to the state. Below are typical state and methods you will use:
modal.visible
to false.modal.remove
based on value of keepMounted
.Based on these properties/methods, you can easily use NiceModal with any modal-like component provided by any UI libraries.
As you already saw, we use code similar with below to manage the modal state:
1//... 2const modal = useModal(); 3return ( 4 <Modal 5 visible={modal.visible} 6 title="Hello Antd" 7 onOk={() => modal.hide()} 8 onCancel={() => modal.hide()} 9 afterClose={() => modal.remove()} 10 > 11 Hello NiceModal! 12 </Modal> 13); 14//...
It binds visible
property to the modal
handler, and use modal.hide
to hide the modal when close button is clicked. And after the close transition it calls modal.remove
to remove the modal from dom node.
For every modal implementation we always need to these binding manually. So, to make it easier to use we provides helper methods for 3 popular UI libraries Material UI, Ant.Design and Bootstrap React.
1import NiceModal, {
2 muiDialog,
3 muiDialogV5,
4 antdModal,
5 antdModalV5,
6 antdDrawer,
7 antdDrawerV5,
8 bootstrapDialog
9} from '@ebay/nice-modal-react';
10
11//...
12const modal = useModal();
13// For MUI
14<Dialog {...muiDialog(modal)}>
15
16// For MUI V5
17<Dialog {...muiDialogV5(modal)}>
18
19// For ant.design
20<Modal {...antdModal(modal)}>
21
22// For ant.design v4.23.0 or later
23<Modal {...antdModalV5(modal)}>
24
25// For antd drawer
26<Drawer {...antdDrawer(modal)}>
27
28// For antd drawer v4.23.0 or later
29<Drawer {...antdDrawerV5(modal)}>
30
31// For bootstrap dialog
32<Dialog {...bootstrapDialog(modal)}>
33
These helpers will bind modal's common actions to correct properties of the component. However you can always override the property after the helpers property. For example:
1const handleSubmit = () => { 2 doSubmit().then(() => { 3 modal.hide(); 4 }); 5} 6<Modal {...antdModal(modal)} onOk={handleSubmit}>
In the example, the onOk
property will override the result from antdModal
helper.
https://ebay.github.io/nice-modal-react/api/
You can test your nice modals with tools like @testing-library/react
.
1import NiceModal from '@ebay/nice-modal-react'; 2import { render, act, screen } from '@testing-library/react'; 3import { MyNiceModal } from '../MyNiceModal'; 4 5test('My nice modal works!', () => { 6 render(<NiceModal.Provider /> 7 8 act(() => { 9 NiceModal.show(MyNiceModal); 10 }); 11 12 expect(screen.getByRole('dialog')).toBeVisible(); 13});
1# 1. Clone repo 2git clone https://github.com/eBay/nice-modal-react.git 3 4# 2. Install deps 5cd nice-modal-react 6yarn 7 8# 3. Make local repo as linked 9yarn link 10 11# 4. Start dev server 12yarn dev 13 14# 5. Install examples deps 15cd example 16yarn 17 18# 6. Use local linked lib 19yarn link @ebay/nice-modal-react 20 21# 7. Start examples dev server 22yarn start
Then you can access http://localhost:3000 to see the examples.
Yes. To get the data from context in the component tree you need to use the declarative way. For example:
1export default function AntdSample() { 2 return ( 3 <> 4 <Button type="primary" onClick={() => NiceModal.show('my-antd-modal', { name: 'Nate' })}> 5 Show Modal 6 </Button> 7 <MyAntdModal id="my-antd-modal" {...otherProps} /> 8 </> 9 ); 10}
See more here.
MIT
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
security policy file detected
Details
Reason
Found 2/5 approved changesets -- score normalized to 4
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
29 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More