kz-react-modal 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -0
- package/package.json +41 -0
- package/src/Modal.css +46 -0
- package/src/Modal.jsx +51 -0
- package/src/index.js +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# kz-react-modal
|
|
2
|
+
|
|
3
|
+
A simple accessible and reusable **React modal component**.
|
|
4
|
+
|
|
5
|
+
This plugin provides a lightweight modal with keyboard accessibility and easy integration into any React project.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Installation
|
|
10
|
+
|
|
11
|
+
Install the package with npm:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install kz-react-modal
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
or with pnpm:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add kz-react-modal
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Usage
|
|
26
|
+
|
|
27
|
+
Import the modal component in your React application:
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import Modal from "kz-react-modal";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Example usage:
|
|
34
|
+
|
|
35
|
+
```jsx
|
|
36
|
+
import { useState } from "react";
|
|
37
|
+
import Modal from "kz-react-modal";
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<button onClick={() => setIsOpen(true)}>
|
|
45
|
+
Open modal
|
|
46
|
+
</button>
|
|
47
|
+
|
|
48
|
+
<Modal
|
|
49
|
+
isOpen={isOpen}
|
|
50
|
+
onClose={() => setIsOpen(false)}
|
|
51
|
+
title="Employee created"
|
|
52
|
+
>
|
|
53
|
+
<p>Your Text/p>
|
|
54
|
+
</Modal>
|
|
55
|
+
</>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default App;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
# Props
|
|
65
|
+
|
|
66
|
+
| Prop | Type | Description |
|
|
67
|
+
|-----|-----|-----|
|
|
68
|
+
| `isOpen` | boolean | Controls whether the modal is visible |
|
|
69
|
+
| `onClose` | function | Function called when the modal is closed |
|
|
70
|
+
| `title` | string | Optional title displayed in the modal |
|
|
71
|
+
| `children` | ReactNode | Content displayed inside the modal |
|
|
72
|
+
| `className` | string | Optional class to customize the modal styles |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
# Features
|
|
77
|
+
|
|
78
|
+
- Simple React modal component
|
|
79
|
+
- Keyboard accessible (ESC key closes the modal)
|
|
80
|
+
- Overlay click closes the modal
|
|
81
|
+
- Accessible with `role="dialog"` and `aria-modal`
|
|
82
|
+
- Customizable with CSS
|
|
83
|
+
- Lightweight and dependency-free
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
# Customization
|
|
88
|
+
|
|
89
|
+
You can customize the modal style by using the `className` prop.
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
|
|
93
|
+
```jsx
|
|
94
|
+
<Modal
|
|
95
|
+
isOpen={isOpen}
|
|
96
|
+
onClose={closeModal}
|
|
97
|
+
className="custom-modal"
|
|
98
|
+
>
|
|
99
|
+
<p>Custom content</p>
|
|
100
|
+
</Modal>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Example CSS:
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
.custom-modal {
|
|
107
|
+
background: #2d2d2d;
|
|
108
|
+
color: white;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
# Accessibility
|
|
115
|
+
|
|
116
|
+
This modal component includes basic accessibility features:
|
|
117
|
+
|
|
118
|
+
- ESC key closes the modal
|
|
119
|
+
- `role="dialog"` for screen readers
|
|
120
|
+
- `aria-modal="true"` support
|
|
121
|
+
- Click outside to close the modal
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
# Development
|
|
126
|
+
|
|
127
|
+
To run the project locally:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pnpm install
|
|
131
|
+
pnpm dev
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The modal can be tested using the local development environment provided by Vite.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
# Author
|
|
139
|
+
|
|
140
|
+
Created by **KZKO** as part of the **HRnet modernization project**.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
# License
|
|
145
|
+
|
|
146
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kz-react-modal",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple accessible React modal component",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"module": "src/index.js",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"src"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "vite build",
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"preview": "vite preview"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
19
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@eslint/js": "^9.39.4",
|
|
23
|
+
"@types/react": "^19.2.14",
|
|
24
|
+
"@types/react-dom": "^19.2.3",
|
|
25
|
+
"@vitejs/plugin-react": "^6.0.0",
|
|
26
|
+
"eslint": "^9.39.4",
|
|
27
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
28
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
29
|
+
"globals": "^17.4.0",
|
|
30
|
+
"vite": "^8.0.0"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"react",
|
|
34
|
+
"modal",
|
|
35
|
+
"react-modal",
|
|
36
|
+
"hrnet",
|
|
37
|
+
"component"
|
|
38
|
+
],
|
|
39
|
+
"author": "KZ",
|
|
40
|
+
"license": "MIT"
|
|
41
|
+
}
|
package/src/Modal.css
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.kz-modal-overlay {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset: 0;
|
|
4
|
+
background: rgba(0, 0, 0, 0.5);
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
align-items: center;
|
|
8
|
+
z-index: 1000;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.kz-modal {
|
|
12
|
+
position: relative;
|
|
13
|
+
background: white;
|
|
14
|
+
padding: 2rem;
|
|
15
|
+
border-radius: 8px;
|
|
16
|
+
max-width: 500px;
|
|
17
|
+
width: 90%;
|
|
18
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
|
19
|
+
animation: modalFadeIn 0.25s ease;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.kz-modal-close {
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: 10px;
|
|
25
|
+
right: 15px;
|
|
26
|
+
border: none;
|
|
27
|
+
background: transparent;
|
|
28
|
+
font-size: 1.5rem;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.kz-modal-close:hover {
|
|
33
|
+
opacity: 0.6;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes modalFadeIn {
|
|
37
|
+
from {
|
|
38
|
+
opacity: 0;
|
|
39
|
+
transform: translateY(15px);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
to {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
transform: translateY(0);
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/Modal.jsx
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import "./Modal.css";
|
|
3
|
+
|
|
4
|
+
function Modal({ isOpen, onClose, title, children, className = "" }) {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const handleKeyDown = (event) => {
|
|
7
|
+
if (event.key === "Escape") {
|
|
8
|
+
onClose();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
if (isOpen) {
|
|
13
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
18
|
+
};
|
|
19
|
+
}, [isOpen, onClose]);
|
|
20
|
+
|
|
21
|
+
if (!isOpen) return null;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className="kz-modal-overlay" onClick={onClose}>
|
|
25
|
+
<div
|
|
26
|
+
className={`kz-modal ${className}`}
|
|
27
|
+
role="dialog"
|
|
28
|
+
aria-modal="true"
|
|
29
|
+
aria-labelledby="kz-modal-title"
|
|
30
|
+
onClick={(event) => event.stopPropagation()}
|
|
31
|
+
>
|
|
32
|
+
<button
|
|
33
|
+
className="kz-modal-close"
|
|
34
|
+
onClick={onClose}
|
|
35
|
+
aria-label="Close modal"
|
|
36
|
+
type="button"
|
|
37
|
+
>
|
|
38
|
+
×
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
{title && <h2 id="kz-modal-title">{title}</h2>}
|
|
42
|
+
|
|
43
|
+
<div className="kz-modal-content">
|
|
44
|
+
{children}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default Modal;
|
package/src/index.js
ADDED