react-pure-modal 2.3.4 → 3.0.1

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.
Files changed (43) hide show
  1. package/README.md +94 -78
  2. package/dist/index.js +1 -0
  3. package/dist/rslib.config.d.ts +2 -0
  4. package/dist/src/compounds/Backdrop.d.ts +3 -0
  5. package/dist/src/compounds/Close.d.ts +5 -0
  6. package/dist/src/compounds/Content.d.ts +5 -0
  7. package/dist/src/compounds/Footer.d.ts +5 -0
  8. package/dist/src/compounds/Header.d.ts +5 -0
  9. package/dist/src/compounds/Modal.d.ts +15 -0
  10. package/dist/src/compounds/Modal.types.d.ts +15 -0
  11. package/dist/src/compounds/ModalContext.d.ts +4 -0
  12. package/dist/src/index.d.ts +1 -0
  13. package/package.json +40 -49
  14. package/.babelrc.js +0 -12
  15. package/.eslintrc +0 -22
  16. package/.github/release-drafter-config.yml +0 -20
  17. package/.github/workflows/build.yml +0 -24
  18. package/.github/workflows/npm-publish.yml +0 -35
  19. package/.github/workflows/release-drafter.yml +0 -16
  20. package/.prettierrc +0 -19
  21. package/.travis.yml +0 -16
  22. package/@types/scheduler/tracing.d.ts +0 -22
  23. package/__tests__/__snapshots__/react-pure-modal-test.js.snap +0 -92
  24. package/__tests__/react-pure-modal-test.js +0 -44
  25. package/dist/pure-modal-content.d.ts +0 -25
  26. package/dist/react-pure-modal.d.ts +0 -20
  27. package/dist/react-pure-modal.min.css +0 -1
  28. package/dist/react-pure-modal.min.js +0 -1
  29. package/dist/types.d.ts +0 -1
  30. package/example/content.ts +0 -50
  31. package/example/example.min.js +0 -2
  32. package/example/example.min.js.LICENSE.txt +0 -109
  33. package/example/example.tsx +0 -109
  34. package/index.html +0 -22
  35. package/screencast/scrollable.gif +0 -0
  36. package/screencast/simple.gif +0 -0
  37. package/src/pure-modal-content.tsx +0 -74
  38. package/src/react-pure-modal.css +0 -123
  39. package/src/react-pure-modal.tsx +0 -256
  40. package/tsconfig.json +0 -25
  41. package/webpack.config.dev.js +0 -65
  42. package/webpack.config.js +0 -62
  43. /package/{src/types.ts → dist/@types/types.d.ts} +0 -0
@@ -1,109 +0,0 @@
1
- /*! !!../node_modules/css-loader/dist/cjs.js!./react-pure-modal.min.css */
2
-
3
- /*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */
4
-
5
- /*! ../dist/react-pure-modal.min.css */
6
-
7
- /*! ../dist/react-pure-modal.min.js */
8
-
9
- /*! ../node_modules/css-loader/dist/runtime/api.js */
10
-
11
- /*! ./cjs/react-dom.development.js */
12
-
13
- /*! ./cjs/react.development.js */
14
-
15
- /*! ./cjs/scheduler.development.js */
16
-
17
- /*! ./content */
18
-
19
- /*! react */
20
-
21
- /*! react-dom */
22
-
23
- /*! scheduler */
24
-
25
- /*!****************************!*\
26
- !*** ./example/content.ts ***!
27
- \****************************/
28
-
29
- /*!*****************************!*\
30
- !*** ./example/example.tsx ***!
31
- \*****************************/
32
-
33
- /*!*************************************!*\
34
- !*** ./node_modules/react/index.js ***!
35
- \*************************************/
36
-
37
- /*!**************************************!*\
38
- !*** ./dist/react-pure-modal.min.js ***!
39
- \**************************************/
40
-
41
- /*!***************************************!*\
42
- !*** ./dist/react-pure-modal.min.css ***!
43
- \***************************************/
44
-
45
- /*!*****************************************!*\
46
- !*** ./node_modules/react-dom/index.js ***!
47
- \*****************************************/
48
-
49
- /*!*****************************************!*\
50
- !*** ./node_modules/scheduler/index.js ***!
51
- \*****************************************/
52
-
53
- /*!*****************************************************!*\
54
- !*** ./node_modules/css-loader/dist/runtime/api.js ***!
55
- \*****************************************************/
56
-
57
- /*!*****************************************************!*\
58
- !*** ./node_modules/react/cjs/react.development.js ***!
59
- \*****************************************************/
60
-
61
- /*!*************************************************************!*\
62
- !*** ./node_modules/react-dom/cjs/react-dom.development.js ***!
63
- \*************************************************************/
64
-
65
- /*!*************************************************************!*\
66
- !*** ./node_modules/scheduler/cjs/scheduler.development.js ***!
67
- \*************************************************************/
68
-
69
- /*!****************************************************************************!*\
70
- !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
71
- \****************************************************************************/
72
-
73
- /*!*****************************************************************************!*\
74
- !*** ./node_modules/css-loader/dist/cjs.js!./dist/react-pure-modal.min.css ***!
75
- \*****************************************************************************/
76
-
77
- /**
78
- * @license React
79
- * react-dom.development.js
80
- *
81
- * Copyright (c) Facebook, Inc. and its affiliates.
82
- *
83
- * This source code is licensed under the MIT license found in the
84
- * LICENSE file in the root directory of this source tree.
85
- */
86
-
87
- /**
88
- * @license React
89
- * scheduler.development.js
90
- *
91
- * Copyright (c) Facebook, Inc. and its affiliates.
92
- *
93
- * This source code is licensed under the MIT license found in the
94
- * LICENSE file in the root directory of this source tree.
95
- */
96
-
97
- /**
98
- * Checks if an event is supported in the current execution environment.
99
- *
100
- * NOTE: This will not work correctly for non-generic events such as `change`,
101
- * `reset`, `load`, `error`, and `select`.
102
- *
103
- * Borrows from Modernizr.
104
- *
105
- * @param {string} eventNameSuffix Event name, e.g. "click".
106
- * @return {boolean} True if the event is supported.
107
- * @internal
108
- * @license Modernizr 3.0.0pre (Custom Build) | MIT
109
- */
@@ -1,109 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { render } from 'react-dom';
3
- import PureModal from '../dist/react-pure-modal.min.js';
4
- import { smallContent, largeContent } from './content';
5
- import '../dist/react-pure-modal.min.css';
6
-
7
- function ModalContainer() {
8
- const [modal, setModal] = useState(false);
9
- const [modalInnerScroll, setModalInnerScroll] = useState(false);
10
- const [modalCenter, setModalCenter] = useState(false);
11
- const [modalDrag, setModalDrag] = useState(false);
12
- const [modalNoScrollable, setModalNoScrollable] = useState(false);
13
-
14
- return (
15
- <div>
16
- <button type="button" className="button" onClick={() => setModal(true)}>
17
- Open simple modal
18
- </button>
19
- <button type="button" className="button" onClick={() => setModalInnerScroll(true)}>
20
- Open modal with inner scroll
21
- </button>
22
- <button type="button" className="button" onClick={() => setModalCenter(true)}>
23
- Open small modal on center scrollable or not
24
- </button>
25
- <button type="button" className="button" onClick={() => setModalDrag(true)}>
26
- Draggable
27
- </button>
28
- <button type="button" className="button" onClick={() => setModalNoScrollable(true)}>
29
- Open large modal on center without scroll
30
- </button>
31
- <PureModal
32
- header="Custom header with a lot of symbols. It's very important to have a dynamic header height and this modal supports it"
33
- footer="Buttons?"
34
- isOpen={modalInnerScroll}
35
- closeButtonPosition="bottom"
36
- onClose={() => {
37
- setModalInnerScroll(false);
38
- return true;
39
- }}
40
- >
41
- <input type="text" placeholder="with input" value="" />
42
- {largeContent}
43
- </PureModal>
44
- <PureModal
45
- header="Custom heading"
46
- footer="Buttons?"
47
- width="800px"
48
- scrollable={false}
49
- isOpen={modal}
50
- onClose={() => {
51
- setModal(false);
52
- return true;
53
- }}
54
- >
55
- {largeContent}
56
- </PureModal>
57
- <PureModal
58
- header="Custom heading"
59
- footer="Buttons?"
60
- scrollable={false}
61
- isOpen={modalCenter}
62
- closeButtonPosition="bottom"
63
- portal
64
- closeButton={<div>&#10007;</div>}
65
- onClose={() => {
66
- setModalCenter(false);
67
- return true;
68
- }}
69
- >
70
- <p>Center</p>
71
- </PureModal>
72
-
73
- <PureModal
74
- header="Custom heading"
75
- draggable
76
- footer="Buttons?"
77
- scrollable={false}
78
- isOpen={modalDrag}
79
- closeButtonPosition="bottom"
80
- portal
81
- closeButton={<div>&#10007;</div>}
82
- onClose={() => {
83
- setModalDrag(false);
84
- return true;
85
- }}
86
- >
87
- <p>Center</p>
88
- </PureModal>
89
-
90
- <PureModal
91
- header="Custom heading"
92
- footer="Buttons?"
93
- isOpen={modalNoScrollable}
94
- closeButtonPosition="bottom"
95
- scrollable={false}
96
- portal
97
- closeButton={<div>&#10007;</div>}
98
- onClose={() => {
99
- setModalNoScrollable(false);
100
- return true;
101
- }}
102
- >
103
- {largeContent}
104
- </PureModal>
105
- </div>
106
- );
107
- }
108
-
109
- render(<ModalContainer />, document.getElementById('js--modals'));
package/index.html DELETED
@@ -1,22 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta http-equiv="x-ua-compatible" content="ie=edge" />
6
- <title></title>
7
- <title>Example 1</title>
8
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
9
- <style>
10
- .button {
11
- padding: 10px 15px;
12
- background-color: #ffd34f;
13
- border: none;
14
- margin: 20px;
15
- }
16
- </style>
17
- </head>
18
- <body style="height: 150vh">
19
- <div id="js--modals"></div>
20
- <script src="./example/example.min.js"></script>
21
- </body>
22
- </html>
Binary file
Binary file
@@ -1,74 +0,0 @@
1
- import React from 'react';
2
-
3
- import type { MouseOrTouch } from './types';
4
-
5
- type Props = {
6
- replace: boolean;
7
- children: JSX.Element;
8
- onDragStart?: (event: MouseOrTouch) => unknown;
9
- onDragEnd?: (event: MouseOrTouch) => unknown;
10
- onClose?: (event: React.MouseEvent<HTMLDivElement>) => void;
11
- bodyClass?: string;
12
- header?: JSX.Element | string;
13
- footer?: JSX.Element | string;
14
- closeButton: JSX.Element | string;
15
- closeButtonPosition: string;
16
- draggable: boolean;
17
- };
18
-
19
- const defaultProps = {
20
- closeButton: '×',
21
- closeButtonPosition: 'header',
22
- replace: false,
23
- draggable: false,
24
- };
25
-
26
- function PureModalContent(props: Props): JSX.Element {
27
- const {
28
- children,
29
- replace,
30
- bodyClass,
31
- header,
32
- footer,
33
- onDragStart,
34
- onDragEnd,
35
- onClose,
36
- closeButton,
37
- closeButtonPosition,
38
- } = props;
39
-
40
- return replace ? (
41
- children
42
- ) : (
43
- <div
44
- className={`panel panel-default ${closeButtonPosition === 'bottom' ? 'additional-row' : ''}`}
45
- >
46
- <div
47
- className="panel-heading"
48
- onTouchStart={onDragStart}
49
- onMouseDown={onDragStart}
50
- onTouchEnd={onDragEnd}
51
- onMouseUp={onDragEnd}
52
- >
53
- {header && <h3 className="panel-title">{header}</h3>}
54
- </div>
55
-
56
- <div className={bodyClass}>{children}</div>
57
- {footer && <div className="panel-footer">{footer}</div>}
58
- <div
59
- className="close"
60
- onClick={onClose}
61
- style={{
62
- position: closeButtonPosition === 'header' ? 'absolute' : 'static',
63
- margin: closeButtonPosition === 'bottom' ? '10px auto' : '',
64
- }}
65
- >
66
- {closeButton}
67
- </div>
68
- </div>
69
- );
70
- }
71
-
72
- PureModalContent.defaultProps = defaultProps;
73
-
74
- export default PureModalContent;
@@ -1,123 +0,0 @@
1
- .body-modal-fix {
2
- height: 100%;
3
- width: 100%;
4
- overflow: hidden;
5
- }
6
-
7
- .pure-modal-backdrop {
8
- position: fixed;
9
- top: 0;
10
- right: 0;
11
- bottom: 0;
12
- left: 0;
13
- z-index: 1040;
14
- background-color: rgba(0, 0, 0, 0.4);
15
- display: flex;
16
- flex-direction: column;
17
- justify-content: center;
18
- align-items: center;
19
- }
20
-
21
- .backdrop-overflow-hidden {
22
- overflow: hidden !important;
23
- }
24
-
25
- .pure-modal-backdrop .pure-modal {
26
- width: 300px;
27
- max-width: 100%;
28
- box-sizing: border-box;
29
- transition: all 0.2s ease-in-out;
30
- max-height: 100%;
31
- }
32
-
33
- .pure-modal.auto-height {
34
- position: static;
35
- }
36
-
37
- .pure-modal-backdrop.scrollable {
38
- overflow-y: auto;
39
- }
40
-
41
- .pure-modal-backdrop .panel {
42
- display: grid;
43
- grid-template-rows: repeat(3, min-content);
44
- }
45
- .pure-modal-backdrop:not(.scrollable) .panel {
46
- grid-template-rows: min-content minmax(0, 1fr) min-content;
47
- max-height: -moz-available;
48
- max-height: -webkit-fill-available;
49
- max-height: fill-available;
50
- height: 100%;
51
- }
52
-
53
- .pure-modal > * > * {
54
- flex: 0 0 auto;
55
- }
56
-
57
- .pure-modal > * > .scrollable {
58
- overflow-x: hidden;
59
- overflow-scrolling: touch;
60
- }
61
-
62
- @media (max-width: 480px) {
63
- .pure-modal-backdrop .pure-modal {
64
- width: 100%;
65
- }
66
- }
67
-
68
- .pure-modal .panel-body {
69
- background-color: #fff;
70
- }
71
-
72
- .pure-modal .panel-heading {
73
- background: rgb(240, 240, 240);
74
- }
75
-
76
- .pure-modal .panel-title {
77
- padding: 12px 45px 12px 15px;
78
- margin: 0;
79
- }
80
-
81
- .pure-modal .close {
82
- right: 10px;
83
- top: 10px;
84
- z-index: 1;
85
- background: rgba(240, 240, 240, 0.8);
86
- width: 30px;
87
- color: rgb(140, 140, 140);
88
- transition: color ease-in-out 0.1s;
89
- height: 30px;
90
- border-radius: 15px;
91
- text-align: center;
92
- line-height: 30px;
93
- cursor: pointer;
94
- }
95
-
96
- .pure-modal .panel-heading .close:hover {
97
- color: #000;
98
- }
99
-
100
- .pure-modal .panel-body {
101
- padding: 15px;
102
- }
103
-
104
- .pure-modal .panel-footer {
105
- padding: 12px 45px 12px 15px;
106
- background: rgb(240, 240, 240);
107
- }
108
-
109
- .pure-modal .panel-body,
110
- .pure-modal .panel-footer,
111
- .pure-modal .panel-title {
112
- word-break: break-all;
113
- }
114
-
115
- .pure-modal-backdrop .additional-row {
116
- display: grid;
117
- grid-template-rows: min-content minmax(0, 1fr) min-content min-content;
118
- }
119
-
120
- .pure-modal-backdrop:not(.scrollable) .additional-row {
121
- display: grid;
122
- grid-template-rows: min-content minmax(0, 1fr) min-content min-content;
123
- }
@@ -1,256 +0,0 @@
1
- import React, { useState, useEffect, useCallback, useId } 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
- type CloseInteractionEvent = MouseOrTouch | KeyboardEvent;
30
-
31
- function PureModal(props: Props) {
32
- const hash = useId();
33
- const [isDragged, setIsDragged] = useState(false);
34
- const [x, setX] = useState<number | null>(null);
35
- const [y, setY] = useState<number | null>(null);
36
- const [deltaX, setDeltaX] = useState(0);
37
- const [deltaY, setDeltaY] = useState(0);
38
- const [mouseOffsetX, setMouseOffsetX] = useState(0);
39
- const [mouseOffsetY, setMouseOffsetY] = useState(0);
40
-
41
- const { isOpen, onClose } = props;
42
-
43
- const removeClassBody = useCallback(() => {
44
- document.body.classList.remove('body-modal-fix');
45
- }, []);
46
-
47
- /**
48
- * useEffect to setup popup OR perform a cleanup after popup was closed
49
- */
50
- useEffect(() => {
51
- /**
52
- * if popup was opened:
53
- * - add esc event listener
54
- * - add overflow fix class to body
55
- * - remove focus from focused element (e.g. remove focus from btn after click, cuz popup was opened)
56
- */
57
- if (isOpen) {
58
- document.addEventListener('keydown', handleEsc);
59
- if (document.activeElement instanceof HTMLElement) document.activeElement.blur();
60
- document.body.classList.add('body-modal-fix');
61
- }
62
-
63
- return () => {
64
- /**
65
- * if popup was closed:
66
- * - remove esc event listener
67
- * - remove overflow fix class from body
68
- * - reset popup states
69
- */
70
- if (!document.querySelector('.pure-modal')) {
71
- document.removeEventListener('keydown', handleEsc);
72
- removeClassBody();
73
- setX(null);
74
- setY(null);
75
- setDeltaX(0);
76
- setDeltaY(0);
77
- setMouseOffsetX(0);
78
- setMouseOffsetY(0);
79
- }
80
- };
81
- }, [isOpen]);
82
-
83
- const handleEsc = useCallback(
84
- (event: KeyboardEvent) => {
85
- const allModals = document.querySelectorAll('.pure-modal');
86
- const isManyModalsOpen = allModals.length > 1; // open modal in modal
87
- const firstModalData = allModals[allModals.length - 1];
88
-
89
- if (isManyModalsOpen && !firstModalData.className.includes(hash)) {
90
- return false; // closing only current modal
91
- }
92
-
93
- if (event.key === 'Escape' && document.activeElement) {
94
- close(event);
95
- return true;
96
- }
97
-
98
- return false;
99
- },
100
- [close, hash],
101
- );
102
-
103
- if (!isOpen) {
104
- return null;
105
- }
106
-
107
- /**
108
- * method that will be called when some of the closing elements are beeing interacted with
109
- *
110
- * click on close btn, click on backdrop, press on esc
111
- */
112
- function close(event?: CloseInteractionEvent) {
113
- if (event) {
114
- event.stopPropagation();
115
- event.preventDefault();
116
- }
117
-
118
- onClose?.({ isPassive: Boolean(event) });
119
- }
120
-
121
- function getCoords(e: MouseOrTouch) {
122
- if (e instanceof TouchEvent && e.changedTouches.length > 0) {
123
- return {
124
- pageX: e.changedTouches[0].pageX,
125
- pageY: e.changedTouches[0].pageY,
126
- };
127
- }
128
- if (e instanceof MouseEvent) {
129
- return {
130
- pageX: e.pageX,
131
- pageY: e.pageY,
132
- };
133
- }
134
- return {
135
- pageX: 0,
136
- pageY: 0,
137
- };
138
- }
139
-
140
- function handleStartDrag(e: MouseOrTouch) {
141
- if (e instanceof TouchEvent && e.changedTouches && e.changedTouches.length > 1) return;
142
-
143
- e.preventDefault();
144
-
145
- const { pageX, pageY } = getCoords(e);
146
- const { top, left } = e.currentTarget.getBoundingClientRect();
147
-
148
- setIsDragged(true);
149
- setX(typeof x === 'number' ? x : left);
150
- setY(typeof y === 'number' ? y : top);
151
- setMouseOffsetX(pageX - left);
152
- setMouseOffsetY(pageY - top);
153
- }
154
-
155
- function handleDrag(e: MouseOrTouch) {
156
- if (e instanceof TouchEvent && e.changedTouches && e.changedTouches.length > 1) {
157
- return handleEndDrag();
158
- }
159
-
160
- e.preventDefault();
161
-
162
- const { pageX, pageY } = getCoords(e);
163
-
164
- if (typeof x === 'number' && typeof y === 'number') {
165
- setDeltaX(pageX - x - mouseOffsetX);
166
- setDeltaY(pageY - y - mouseOffsetY);
167
- }
168
- }
169
-
170
- function handleEndDrag() {
171
- return setIsDragged(false);
172
- }
173
-
174
- function handleBackdropClick(event: MouseOrTouch) {
175
- if (event) {
176
- if (!(event.target as Element).classList.contains('pure-modal-backdrop')) {
177
- return;
178
- }
179
- event.stopPropagation();
180
- event.preventDefault();
181
- }
182
- close(event);
183
- }
184
-
185
- const {
186
- children,
187
- replace = false,
188
- className,
189
- header,
190
- footer,
191
- scrollable = true,
192
- draggable = false,
193
- width,
194
- closeButton,
195
- closeButtonPosition,
196
- portal = false,
197
- } = props;
198
-
199
- let backdropclasses = ['pure-modal-backdrop'];
200
- let modalclasses = ['pure-modal', hash];
201
- let bodyClasses = ['panel-body'];
202
-
203
- if (className) {
204
- modalclasses = modalclasses.concat(className);
205
- }
206
-
207
- if (scrollable) {
208
- bodyClasses = bodyClasses.concat('scrollable');
209
- } else {
210
- backdropclasses = backdropclasses.concat('scrollable');
211
- modalclasses = modalclasses.concat('auto-height');
212
- }
213
-
214
- if (draggable) {
215
- backdropclasses = backdropclasses.concat('backdrop-overflow-hidden');
216
- }
217
-
218
- const modalContent = (
219
- <div
220
- className={backdropclasses.join(' ')}
221
- onMouseDown={handleBackdropClick}
222
- onTouchMove={isDragged ? handleDrag : undefined}
223
- onMouseMove={isDragged ? handleDrag : undefined}
224
- >
225
- <div
226
- className={modalclasses.join(' ')}
227
- style={{
228
- transform: `translate(${deltaX}px, ${deltaY}px)`,
229
- transition: 'none',
230
- width,
231
- }}
232
- >
233
- <PureModalContent
234
- replace={replace}
235
- header={header}
236
- footer={footer}
237
- onDragStart={draggable ? handleStartDrag : undefined}
238
- onDragEnd={draggable ? handleEndDrag : undefined}
239
- onClose={close}
240
- bodyClass={bodyClasses.join(' ')}
241
- closeButton={closeButton}
242
- closeButtonPosition={closeButtonPosition}
243
- >
244
- {children}
245
- </PureModalContent>
246
- </div>
247
- </div>
248
- );
249
-
250
- if (portal) {
251
- return createPortal(modalContent, document.body);
252
- }
253
- return modalContent;
254
- }
255
-
256
- export default React.memo(PureModal);