react-pure-modal 2.2.7 → 3.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.
@@ -1,254 +0,0 @@
1
- import React, { useState, useEffect, useCallback } from 'react';
2
- import { createPortal } from 'react-dom';
3
-
4
- // components
5
- import PureModalContent from './pure-modal-content';
6
-
7
- // types
8
- import type { MouseOrTouch } from './types';
9
-
10
- // styles
11
- import './react-pure-modal.css';
12
-
13
- type Props = {
14
- children: JSX.Element;
15
- replace?: boolean;
16
- className?: string;
17
- header?: JSX.Element | string;
18
- footer?: JSX.Element | string;
19
- scrollable?: boolean;
20
- draggable?: boolean;
21
- width?: string;
22
- isOpen?: boolean;
23
- onClose?: Function;
24
- closeButton?: JSX.Element | string;
25
- closeButtonPosition?: string;
26
- portal?: boolean;
27
- };
28
-
29
- function PureModal(props: Props) {
30
- let hash = Math.random().toString();
31
- const [isDragged, setIsDragged] = useState(false);
32
- const [x, setX] = useState<number | null>(null);
33
- const [y, setY] = useState<number | null>(null);
34
- const [deltaX, setDeltaX] = useState(0);
35
- const [deltaY, setDeltaY] = useState(0);
36
- const [mouseOffsetX, setMouseOffsetX] = useState(0);
37
- const [mouseOffsetY, setMouseOffsetY] = useState(0);
38
-
39
- const { isOpen, onClose } = props;
40
-
41
- const removeClassBody = useCallback(() => {
42
- document.body.classList.remove('body-modal-fix');
43
- }, []);
44
-
45
- /**
46
- * useEffect to setup popup OR perform a cleanup after popup was closed
47
- */
48
- useEffect(() => {
49
- /**
50
- * if popup was opened:
51
- * - add esc event listener
52
- * - add overflow fix class to body
53
- * - remove focus from focused element (e.g. remove focus from btn after click, cuz popup was opened)
54
- */
55
- if (isOpen) {
56
- document.addEventListener('keydown', handleEsc);
57
- if (document.activeElement instanceof HTMLElement) document.activeElement.blur();
58
- document.body.classList.add('body-modal-fix');
59
- }
60
-
61
- return () => {
62
- /**
63
- * if popup was closed:
64
- * - remove esc event listener
65
- * - remove overflow fix class from body
66
- * - reset popup states
67
- */
68
- if (!document.querySelector('.pure-modal')) {
69
- document.removeEventListener('keydown', handleEsc);
70
- removeClassBody();
71
- setX(null);
72
- setY(null);
73
- setDeltaX(0);
74
- setDeltaY(0);
75
- setMouseOffsetX(0);
76
- setMouseOffsetY(0);
77
- }
78
- };
79
- }, [isOpen]);
80
-
81
- const handleEsc = useCallback(
82
- event => {
83
- const allModals = document.querySelectorAll('.pure-modal');
84
- const isManyModalsOpen = allModals.length > 1; // open modal in modal
85
- const firstModalData = allModals[allModals.length - 1];
86
-
87
- if (isManyModalsOpen && !firstModalData.className.includes(hash)) {
88
- return false; // closing only current modal
89
- }
90
-
91
- if (event.key === 'Escape' && document.activeElement) {
92
- close(event);
93
- return true;
94
- }
95
-
96
- return false;
97
- },
98
- [close, hash],
99
- );
100
-
101
- if (!isOpen) {
102
- return null;
103
- }
104
-
105
- /**
106
- * method that will be called when some of the closing elements are beeing interacted with
107
- *
108
- * click on close btn, click on backdrop, press on esc
109
- */
110
- function close(event?: MouseOrTouch) {
111
- if (event) {
112
- event.stopPropagation();
113
- event.preventDefault();
114
- }
115
-
116
- onClose?.({ isPassive: Boolean(event) });
117
- }
118
-
119
- function getCoords(e: MouseOrTouch) {
120
- if (e instanceof TouchEvent && e.changedTouches.length > 0) {
121
- return {
122
- pageX: e.changedTouches[0].pageX,
123
- pageY: e.changedTouches[0].pageY,
124
- };
125
- }
126
- if (e instanceof MouseEvent) {
127
- return {
128
- pageX: e.pageX,
129
- pageY: e.pageY,
130
- };
131
- }
132
- return {
133
- pageX: 0,
134
- pageY: 0,
135
- };
136
- }
137
-
138
- function handleStartDrag(e: MouseOrTouch) {
139
- if (e instanceof TouchEvent && e.changedTouches && e.changedTouches.length > 1) return;
140
-
141
- e.preventDefault();
142
-
143
- const { pageX, pageY } = getCoords(e);
144
- const { top, left } = e.currentTarget.getBoundingClientRect();
145
-
146
- setIsDragged(true);
147
- setX(typeof x === 'number' ? x : left);
148
- setY(typeof y === 'number' ? y : top);
149
- setMouseOffsetX(pageX - left);
150
- setMouseOffsetY(pageY - top);
151
- }
152
-
153
- function handleDrag(e: MouseOrTouch) {
154
- if (e instanceof TouchEvent && e.changedTouches && e.changedTouches.length > 1) {
155
- return handleEndDrag();
156
- }
157
-
158
- e.preventDefault();
159
-
160
- const { pageX, pageY } = getCoords(e);
161
-
162
- if (typeof x === 'number' && typeof y === 'number') {
163
- setDeltaX(pageX - x - mouseOffsetX);
164
- setDeltaY(pageY - y - mouseOffsetY);
165
- }
166
- }
167
-
168
- function handleEndDrag() {
169
- return setIsDragged(false);
170
- }
171
-
172
- function handleBackdropClick(event: MouseOrTouch) {
173
- if (event) {
174
- if (!(event.target as Element).classList.contains('pure-modal-backdrop')) {
175
- return;
176
- }
177
- event.stopPropagation();
178
- event.preventDefault();
179
- }
180
- close(event);
181
- }
182
-
183
- const {
184
- children,
185
- replace = false,
186
- className,
187
- header,
188
- footer,
189
- scrollable = true,
190
- draggable = false,
191
- width,
192
- closeButton,
193
- closeButtonPosition,
194
- portal = false,
195
- } = props;
196
-
197
- let backdropclasses = ['pure-modal-backdrop'];
198
- let modalclasses = ['pure-modal', hash];
199
- let bodyClasses = ['panel-body'];
200
-
201
- if (className) {
202
- modalclasses = modalclasses.concat(className);
203
- }
204
-
205
- if (scrollable) {
206
- bodyClasses = bodyClasses.concat('scrollable');
207
- } else {
208
- backdropclasses = backdropclasses.concat('scrollable');
209
- modalclasses = modalclasses.concat('auto-height');
210
- }
211
-
212
- if (draggable) {
213
- backdropclasses = backdropclasses.concat('backdrop-overflow-hidden');
214
- }
215
-
216
- const modalContent = (
217
- <div
218
- className={backdropclasses.join(' ')}
219
- onMouseDown={handleBackdropClick}
220
- onTouchMove={isDragged ? handleDrag : undefined}
221
- onMouseMove={isDragged ? handleDrag : undefined}
222
- >
223
- <div
224
- className={modalclasses.join(' ')}
225
- style={{
226
- transform: `translate(${deltaX}px, ${deltaY}px)`,
227
- transition: 'none',
228
- width,
229
- }}
230
- >
231
- <PureModalContent
232
- replace={replace}
233
- header={header}
234
- footer={footer}
235
- onDragStart={draggable ? handleStartDrag : undefined}
236
- onDragEnd={draggable ? handleEndDrag : undefined}
237
- onClose={close}
238
- bodyClass={bodyClasses.join(' ')}
239
- closeButton={closeButton}
240
- closeButtonPosition={closeButtonPosition}
241
- >
242
- {children}
243
- </PureModalContent>
244
- </div>
245
- </div>
246
- );
247
-
248
- if (portal) {
249
- return createPortal(modalContent, document.body);
250
- }
251
- return modalContent;
252
- }
253
-
254
- export default React.memo(PureModal);
package/src/types.ts DELETED
@@ -1 +0,0 @@
1
- export type MouseOrTouch = React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>;
package/tsconfig.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "include": ["src/*.tsx"],
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "declaration": true,
6
- "emitDeclarationOnly": true,
7
- "sourceMap": true,
8
- "noImplicitAny": true,
9
- "module": "commonjs",
10
- "target": "es2016",
11
- "jsx": "react",
12
- "lib": ["es2018", "dom"],
13
- "esModuleInterop": true,
14
- "strict": true,
15
- "importsNotUsedAsValues": "error",
16
- "resolveJsonModule": true,
17
- "allowSyntheticDefaultImports": true,
18
- "typeRoots": ["./@types/**", "./node_modules/@types"],
19
- "types": ["node", "jest"]
20
- }
21
- }
@@ -1,65 +0,0 @@
1
- const TerserPlugin = require('terser-webpack-plugin');
2
- const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
3
- const path = require('path');
4
- const webpack = require('webpack');
5
-
6
- const config = {
7
- mode: process.env.NODE_ENV || 'development',
8
- optimization: {
9
- minimize: process.env.NODE_ENV !== 'development',
10
- minimizer:
11
- process.env.NODE_ENV !== 'development'
12
- ? [
13
- new TerserPlugin({
14
- cache: true,
15
- parallel: true,
16
- sourceMap: true, // Must be set to true if using source-maps in production
17
- terserOptions: {},
18
- }),
19
- new CssMinimizerPlugin(),
20
- ]
21
- : [],
22
- },
23
- entry: {
24
- example: path.join(__dirname, 'example/example.tsx'),
25
- },
26
- devtool: process.env.NODE_ENV !== 'development' ? false : 'inline-source-map',
27
- module: {
28
- rules: [
29
- {
30
- test: /\.(js|ts|tsx)$/,
31
- exclude: /(node_modules)/,
32
- use: {
33
- loader: 'babel-loader',
34
- },
35
- },
36
- {
37
- test: /\.css$/,
38
- exclude: /(node_modules)/,
39
- use: ['style-loader', 'css-loader'],
40
- },
41
- ],
42
- },
43
- devServer: {
44
- contentBase: path.resolve(__dirname, 'examples/'),
45
- compress: true,
46
- port: 8000,
47
- stats: 'errors-only',
48
- open: true,
49
- },
50
- output: {
51
- path: path.join(__dirname, 'example/'),
52
- filename: '[name].min.js',
53
- },
54
- plugins: [
55
- new webpack.DefinePlugin({
56
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
57
- }),
58
- ],
59
- resolve: {
60
- extensions: ['.tsx', '.ts', '.js'],
61
- modules: [path.join(__dirname, './src'), path.join(__dirname, './node_modules')],
62
- },
63
- };
64
-
65
- module.exports = config;
package/webpack.config.js DELETED
@@ -1,62 +0,0 @@
1
- const TerserPlugin = require('terser-webpack-plugin');
2
- const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
3
- const path = require('path');
4
- const webpack = require('webpack');
5
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
-
7
- const config = {
8
- mode: 'production',
9
- optimization: {
10
- minimize: true,
11
- minimizer: [
12
- new TerserPlugin({
13
- cache: true,
14
- parallel: true,
15
- sourceMap: true, // Must be set to true if using source-maps in production
16
- terserOptions: {},
17
- }),
18
- new CssMinimizerPlugin(),
19
- ],
20
- },
21
- entry: {
22
- 'react-pure-modal': path.join(__dirname, './src/react-pure-modal.tsx'),
23
- },
24
- module: {
25
- rules: [
26
- {
27
- test: /\.(js|jsx|tsx|ts)$/,
28
- exclude: /(node_modules|dist)/,
29
- use: {
30
- loader: 'babel-loader',
31
- },
32
- },
33
- {
34
- test: /\.css$/,
35
- exclude: /(node_modules|dist)/,
36
- use: [MiniCssExtractPlugin.loader, 'css-loader'],
37
- },
38
- ],
39
- },
40
- output: {
41
- path: path.join(__dirname, 'dist/'),
42
- filename: '[name].min.js',
43
- libraryTarget: 'umd',
44
- globalObject: 'this',
45
- },
46
- plugins: [
47
- new webpack.DefinePlugin({
48
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
49
- }),
50
- new MiniCssExtractPlugin({ filename: '[name].min.css' }),
51
- ],
52
- resolve: {
53
- modules: ['node_modules'],
54
- extensions: ['.tsx', '.ts', '.js'],
55
- },
56
- externals: {
57
- react: 'umd react',
58
- 'react-dom': 'umd react-dom',
59
- },
60
- };
61
-
62
- module.exports = config;