@spaced-out/ui-design-system 0.1.6 → 0.1.8

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.1.8](https://github.com/spaced-out/ui-design-system/compare/v0.1.7...v0.1.8) (2023-04-05)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * modal scroll fix ([47a2349](https://github.com/spaced-out/ui-design-system/commit/47a23496c8b9328ab6cbe3f7736635776fb4f797))
11
+ * modal scroll fix ([c33b8bd](https://github.com/spaced-out/ui-design-system/commit/c33b8bd6b4a7cf4c4a51c2abe8a3211c829b054b))
12
+
13
+ ### [0.1.7](https://github.com/spaced-out/ui-design-system/compare/v0.1.6...v0.1.7) (2023-04-05)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * added documentation for link ([b233ce2](https://github.com/spaced-out/ui-design-system/commit/b233ce236a2ef4d8297bf4a333cf280d24fb6c87))
19
+ * modal fix ([a8bcb31](https://github.com/spaced-out/ui-design-system/commit/a8bcb318f23006c502f74b569fa268c44856bb9c))
20
+
5
21
  ### [0.1.6](https://github.com/spaced-out/ui-design-system/compare/v0.1.5...v0.1.6) (2023-04-05)
6
22
 
7
23
 
@@ -10,6 +10,7 @@ var _reactDomInteractions = require("@floating-ui/react-dom-interactions");
10
10
  var _useMountTransition = _interopRequireDefault(require("../../hooks/useMountTransition"));
11
11
  var _motion = require("../../styles/variables/_motion");
12
12
  var _classify = _interopRequireDefault(require("../../utils/classify"));
13
+ var _helpers = require("../../utils/helpers");
13
14
  var _Button = require("../Button/Button");
14
15
  var _Truncate = require("../Truncate/Truncate");
15
16
  var _ModalModule = _interopRequireDefault(require("./Modal.module.css"));
@@ -60,11 +61,40 @@ const ModalFooter = _ref3 => {
60
61
  }, children)));
61
62
  };
62
63
  exports.ModalFooter = ModalFooter;
63
- const createPortalRoot = () => {
64
+ const createPortalRoot = id => {
64
65
  const modalRoot = document.createElement('div');
65
- modalRoot.setAttribute('id', 'modal-root');
66
+ modalRoot.setAttribute('id', `modal-root-${id}`);
66
67
  return modalRoot;
67
68
  };
69
+ const getModalRoot = id => document.getElementById(`modal-root-${id}`);
70
+ function hasChildNode(nodeList) {
71
+ for (let i = 0, len = nodeList.length; i < len; i++) {
72
+ if (nodeList[i].firstChild !== null) {
73
+ return true;
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+ const fixBody = bodyEl => {
79
+ document.getElementsByTagName('body')[0].classList.add('fixed');
80
+ bodyEl.style.overflow = 'hidden';
81
+ };
82
+ const unfixBody = bodyEl => {
83
+ document.getElementsByTagName('body')[0].classList.remove('fixed');
84
+ bodyEl.style.overflow = '';
85
+ };
86
+ const checkAndAddBodyOverflow = bodyEl => {
87
+ const nodes = document.querySelectorAll('[id^="modal-root"]');
88
+ let isParentModalPresent = false;
89
+ if (nodes.length) {
90
+ isParentModalPresent = hasChildNode(nodes);
91
+ }
92
+ if (isParentModalPresent) {
93
+ fixBody(bodyEl);
94
+ } else {
95
+ unfixBody(bodyEl);
96
+ }
97
+ };
68
98
  const Modal = _ref4 => {
69
99
  let {
70
100
  classNames,
@@ -72,7 +102,6 @@ const Modal = _ref4 => {
72
102
  isOpen = false,
73
103
  onClose,
74
104
  hideBackdrop = false,
75
- removeWhenClosed = true,
76
105
  tapOutsideToClose = true,
77
106
  initialFocus = -1
78
107
  } = _ref4;
@@ -80,8 +109,9 @@ const Modal = _ref4 => {
80
109
  floating,
81
110
  context
82
111
  } = (0, _reactDomInteractions.useFloating)();
112
+ const modalId = (0, _helpers.uuid)();
83
113
  const bodyRef = React.useRef(document.querySelector('body'));
84
- const portalRootRef = React.useRef(document.getElementById('modal-root') || createPortalRoot());
114
+ const portalRootRef = React.useRef(getModalRoot(modalId) || createPortalRoot(modalId));
85
115
  const isTransitioning = (0, _useMountTransition.default)(isOpen, parseInt(_motion.motionDurationNormal));
86
116
 
87
117
  // Append portal root on mount
@@ -94,7 +124,7 @@ const Modal = _ref4 => {
94
124
  portal.remove();
95
125
  // Ensure scroll overflow is removed
96
126
  if (bodyEl) {
97
- bodyEl.style.overflow = '';
127
+ unfixBody(bodyEl);
98
128
  }
99
129
  };
100
130
  }, []);
@@ -104,11 +134,11 @@ const Modal = _ref4 => {
104
134
  const updatePageScroll = () => {
105
135
  if (isOpen) {
106
136
  if (bodyRef.current) {
107
- bodyRef.current.style.overflow = 'hidden';
137
+ fixBody(bodyRef.current);
108
138
  }
109
139
  } else {
110
140
  if (bodyRef.current) {
111
- bodyRef.current.style.overflow = '';
141
+ unfixBody(bodyRef.current);
112
142
  }
113
143
  }
114
144
  };
@@ -129,7 +159,14 @@ const Modal = _ref4 => {
129
159
  window.removeEventListener('keyup', onKeyPress);
130
160
  };
131
161
  }, [isOpen, onClose]);
132
- if (!isTransitioning && removeWhenClosed && !isOpen) {
162
+ if (!isTransitioning && !isOpen) {
163
+ // Check overflow after resetting the DOM for modal. This should always happen after DOM reset
164
+ // TODO(Nishant): Better way to do this?
165
+ setTimeout(() => {
166
+ if (bodyRef && !!bodyRef.current) {
167
+ checkAndAddBodyOverflow(bodyRef.current);
168
+ }
169
+ });
133
170
  return null;
134
171
  }
135
172
  const onBackdropClick = e => {
@@ -13,6 +13,7 @@ import {
13
13
  import useMountTransition from '../../hooks/useMountTransition';
14
14
  import {motionDurationNormal} from '../../styles/variables/_motion';
15
15
  import classify from '../../utils/classify';
16
+ import {uuid} from '../../utils/helpers';
16
17
  import {Button} from '../Button/Button';
17
18
  import {Truncate} from '../Truncate/Truncate';
18
19
 
@@ -36,6 +37,7 @@ export type ModalProps = {
36
37
  isOpen?: boolean,
37
38
  onClose?: ?(SyntheticEvent<HTMLElement>) => mixed,
38
39
  hideBackdrop?: boolean,
40
+ // This prop is removed now
39
41
  removeWhenClosed?: boolean,
40
42
  tapOutsideToClose?: boolean,
41
43
  initialFocus?: number,
@@ -105,28 +107,63 @@ export const ModalFooter = ({
105
107
  </>
106
108
  );
107
109
 
108
- const createPortalRoot = () => {
110
+ const createPortalRoot = (id: string) => {
109
111
  const modalRoot = document.createElement('div');
110
- modalRoot.setAttribute('id', 'modal-root');
112
+ modalRoot.setAttribute('id', `modal-root-${id}`);
111
113
 
112
114
  return modalRoot;
113
115
  };
114
116
 
117
+ const getModalRoot = (id: string) =>
118
+ document.getElementById(`modal-root-${id}`);
119
+
120
+ function hasChildNode(nodeList) {
121
+ for (let i = 0, len = nodeList.length; i < len; i++) {
122
+ if (nodeList[i].firstChild !== null) {
123
+ return true;
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+
129
+ const fixBody = (bodyEl: HTMLBodyElement) => {
130
+ document.getElementsByTagName('body')[0].classList.add('fixed');
131
+ bodyEl.style.overflow = 'hidden';
132
+ };
133
+
134
+ const unfixBody = (bodyEl: HTMLBodyElement) => {
135
+ document.getElementsByTagName('body')[0].classList.remove('fixed');
136
+ bodyEl.style.overflow = '';
137
+ };
138
+
139
+ const checkAndAddBodyOverflow = (bodyEl: HTMLBodyElement) => {
140
+ const nodes = document.querySelectorAll('[id^="modal-root"]');
141
+ let isParentModalPresent = false;
142
+ if (nodes.length) {
143
+ isParentModalPresent = hasChildNode(nodes);
144
+ }
145
+ if (isParentModalPresent) {
146
+ fixBody(bodyEl);
147
+ } else {
148
+ unfixBody(bodyEl);
149
+ }
150
+ };
151
+
115
152
  export const Modal = ({
116
153
  classNames,
117
154
  children,
118
155
  isOpen = false,
119
156
  onClose,
120
157
  hideBackdrop = false,
121
- removeWhenClosed = true,
122
158
  tapOutsideToClose = true,
123
159
  initialFocus = -1,
124
160
  }: ModalProps): React.Node => {
125
161
  const {floating, context} = useFloating();
162
+ const modalId = uuid();
126
163
 
127
164
  const bodyRef = React.useRef(document.querySelector('body'));
128
165
  const portalRootRef = React.useRef(
129
- document.getElementById('modal-root') || createPortalRoot(),
166
+ getModalRoot(modalId) || createPortalRoot(modalId),
130
167
  );
131
168
 
132
169
  const isTransitioning = useMountTransition(
@@ -145,7 +182,7 @@ export const Modal = ({
145
182
  portal.remove();
146
183
  // Ensure scroll overflow is removed
147
184
  if (bodyEl) {
148
- bodyEl.style.overflow = '';
185
+ unfixBody(bodyEl);
149
186
  }
150
187
  };
151
188
  }, []);
@@ -155,11 +192,11 @@ export const Modal = ({
155
192
  const updatePageScroll = () => {
156
193
  if (isOpen) {
157
194
  if (bodyRef.current) {
158
- bodyRef.current.style.overflow = 'hidden';
195
+ fixBody(bodyRef.current);
159
196
  }
160
197
  } else {
161
198
  if (bodyRef.current) {
162
- bodyRef.current.style.overflow = '';
199
+ unfixBody(bodyRef.current);
163
200
  }
164
201
  }
165
202
  };
@@ -184,7 +221,15 @@ export const Modal = ({
184
221
  };
185
222
  }, [isOpen, onClose]);
186
223
 
187
- if (!isTransitioning && removeWhenClosed && !isOpen) {
224
+ if (!isTransitioning && !isOpen) {
225
+ // Check overflow after resetting the DOM for modal. This should always happen after DOM reset
226
+ // TODO(Nishant): Better way to do this?
227
+ setTimeout(() => {
228
+ if (bodyRef && !!bodyRef.current) {
229
+ checkAndAddBodyOverflow(bodyRef.current);
230
+ }
231
+ });
232
+
188
233
  return null;
189
234
  }
190
235
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {