Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alekseymakhankov/hyper-modal
Fully customizable and accessible react modal component
https://github.com/alekseymakhankov/hyper-modal
accessible-modal accessible-react dialog modal react react-component react-dialog react-modal-component reactjs rollup typescript
Last synced: 18 days ago
JSON representation
Fully customizable and accessible react modal component
- Host: GitHub
- URL: https://github.com/alekseymakhankov/hyper-modal
- Owner: alekseymakhankov
- License: mit
- Created: 2019-01-27T12:18:10.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-02-04T10:04:50.000Z (almost 2 years ago)
- Last Synced: 2024-11-25T05:30:40.388Z (27 days ago)
- Topics: accessible-modal, accessible-react, dialog, modal, react, react-component, react-dialog, react-modal-component, reactjs, rollup, typescript
- Language: TypeScript
- Size: 2.89 MB
- Stars: 19
- Watchers: 3
- Forks: 3
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# React hyper modal
#### Fully customizable and accessible modal react componentWelcome to the react hyper modal repository 😄
I want to introduce you to an awesome react component for displaying modal windows![license](https://img.shields.io/badge/license-MIT-brightgreen.svg)
[![Coverage Status](https://coveralls.io/repos/github/alekseymakhankov/hyper-modal/badge.svg?branch=master&service=github)](https://coveralls.io/github/alekseymakhankov/hyper-modal?branch=master&service=github)
[![Build Status](https://travis-ci.org/alekseymakhankov/hyper-modal.svg?branch=master)](https://travis-ci.org/alekseymakhankov/hyper-modal)
![min](https://img.shields.io/bundlephobia/min/react-hyper-modal.svg)
![minzip](https://img.shields.io/bundlephobia/minzip/react-hyper-modal.svg)## [Live demo](https://alekseymakhankov.github.io/packages/?package=hyper-modal)
### Check also the new stackable content feature!
## Table of contents
- [Installation](#installation)
- [Usage](#usage)
- [Properties](#properties)
- [Default properties](#default-properties)
- [Types](#types)
- [Contributing](#contributing)
- [License](#license)###### You can use [![npm](https://api.iconify.design/logos:npm.svg?height=14)](https://www.npmjs.com/get-npm) or [![yarn](https://api.iconify.design/logos:yarn.svg?height=14)](https://yarnpkg.com/lang/en/docs/install) package managers
```console
$ npm i --save react-hyper-modal
```
__or__
```console
$ yarn add react-hyper-modal
```#### Controlled modal component
```javascript
import React from 'react';
import HyperModal from 'react-hyper-modal';...
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isModalOpen: false,
};
}...
openModal => this.setState({ isModalOpen: true });
closeModal => this.setState({ isModalOpen: false });...
render() {
const { isModalOpen } = this.state;
return (
Your awesome modal content
);
}
}
```#### Uncontrolled modal component
```javascript
import React from 'react';
import HyperModal from 'react-hyper-modal';...
const MyComponent = () => {
return (
{
return (
Open uncontrolled modal
);
}
/>
);
}
```#### Stackable content example
To use stackable content you should use `ModalStack` component and children as function. Every child of `ModalStack` will represent a different layout.
```javascript
import React from 'react';
import HyperModal, { ModalStack, ModalStackProps } from 'react-hyper-modal';...
const Component = () => {
const [index, setIndex] = React.useState(0)
return (
(
Open stackable modal
)}
>
{(props: ModalStackProps) => (
// !!! It's very important to provide props to ModalStack
1
setIndex(1)}>open nested
props.handleClose()}>close
2
setIndex(2)}>open nested
setIndex(0)}>close nested
close
3
setIndex(1)}>close nested
props.handleClose()}>close
)}
)
}
```### That's it! 🍰✨
## Properties
You can find props types and default props below the table.##### **\*** - required for controlled modal component
Props | Description
------------ | -------------
afterClose | callback that is called after closing
ariaEnabled | enable [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) properties
ariaProps | custom [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) properties
beforeClose | callback that is called before closing
childrenMode | describing if the modal content should be rendered as [React Children](https://reactjs.org/docs/react-api.html#reactchildren)
classes | overriding default modal class names
closeDebounceTimeout | time to close modal
closeIconPosition | position of close button
closeOnCloseIconClick | close the modal by pressing close button
closeOnDimmerClick | close the modal by pressing on dimmer
closeOnEscClick | close the modal by pressing ESC
dimmerEnabled | describing if the dimmer should be shown or not
isFullscreen | describing if the modal should be shown in full screen or not
isOpen **\*** | describing if the modal should be shown or not
modalContentRef | [reference](https://reactjs.org/docs/refs-and-the-dom.html) to the modal content `div`
modalWrapperRef | [reference](https://reactjs.org/docs/refs-and-the-dom.html) to the modal wrapper `div`
portalMode | describing if the modal should be rendered in [React Portal](https://reactjs.org/docs/portals.html) or not
portalNode | HTML node to create [React Portal](https://reactjs.org/docs/portals.html)
position | setting the modal position
renderCloseIcon | callback for rendering custom close button
renderContent | callback for rendering custom modal content
renderOpenButton | callback or boolean describing if the modal should be uncontrolled component
requestClose **\*** | callback to close the modal
stackable | make content stackable
stackableIndex | stack length
stackContentSettings | stackable content settings
unmountOnClose | describing if the modal should be unmounted when close### Default properties
```javascript
{
ariaEnabled: true,
ariaProps: {
'aria-describedby': 'hyper-modal-description',
'aria-labelledby': 'hyper-modal-title',
role: 'dialog',
},
disableScroll: true,
childrenMode: true,
closeDebounceTimeout: 0,
closeIconPosition: {
vertical: 'top' as const,
horizontal: 'right' as const,
},
closeOnCloseIconClick: true,
closeOnDimmerClick: true,
closeOnEscClick: true,
dimmerEnabled: true,
isFullscreen: false,
portalMode: false,
position: {
alignItems: 'center' as const,
justifyContent: 'center' as const,
},
stackable: false,
stackableIndex: 0,
stackContentSettings: {
widthRatio: 4,
topOffsetRatio: 2,
transition: 'all 0.3s ease',
opacityRatio: 0.2,
}
}
```### Types
```typescript
type TModalPosition = 'flex-start' | 'center' | 'flex-end';
type THorizontalPosition = 'left' | 'center' | 'right';
type TVerticalPosition = 'top' | 'middle' | 'bottom';interface IClassNamesProps {
closeIconClassName?: string;
contentClassName?: string;
dimmerClassName?: string;
portalWrapperClassName?: string;
wrapperClassName?: string;
}interface IARIAProps {
'aria-describedby'?: string;
'aria-labelledby'?: string;
role?: string;
}interface IPositionProps {
alignItems?: TModalPosition;
justifyContent?: TModalPosition;
}interface ICloseIconPosition {
horizontal?: THorizontalPosition;
vertical?: TVerticalPosition;
}interface IModalProps {
afterClose?: () => void;
ariaEnabled?: boolean;
ariaProps?: IARIAProps;
beforeClose?: () => void;
childrenMode?: boolean;
classes?: IClassNamesProps;
closeDebounceTimeout?: number;
closeIconPosition?: ICloseIconPosition;
closeOnCloseIconClick?: boolean;
closeOnDimmerClick?: boolean;
closeOnEscClick?: boolean;
dimmerEnabled?: boolean;
isFullscreen?: boolean;
isOpen: boolean;
modalContentRef?: React.RefObject;
modalWrapperRef?: React.RefObject;
portalMode?: boolean;
portalNode?: HTMLElement;
position?: IPositionProps;
renderCloseIcon?: () => JSX.Element | null | string;
renderContent?: () => JSX.Element | JSX.Element[] | null | string;
renderOpenButton?: boolean | ((requestOpen: () => void) => JSX.Element | string);
requestClose: () => void;
unmountOnClose?: boolean;
}
```## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.Please make sure to update tests as appropriate.