@itcase/ui 1.8.169 → 1.8.170

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.
@@ -170,7 +170,9 @@ const Modal = React.forwardRef(function Modal(props, ref) {
170
170
  }, [isOpen, isScrollOnOpen, isSetFocusOnOpen]);
171
171
  // Show modal with children content
172
172
  const openModal = React.useCallback(() => {
173
- setIsOpen(true);
173
+ React.startTransition(() => {
174
+ setIsOpen(true);
175
+ });
174
176
  // Callback
175
177
  if (typeof onOpenModal === 'function') {
176
178
  onOpenModal();
@@ -204,6 +206,12 @@ const Modal = React.forwardRef(function Modal(props, ref) {
204
206
  // Callback
205
207
  onCloseModal && onCloseModal();
206
208
  }, [modalElement, onCloseModal]);
209
+ const handleClickOverlay = React.useCallback(() => {
210
+ if (isCloseOnBlur) {
211
+ closeModal();
212
+ }
213
+ onClickOverlay && onClickOverlay();
214
+ }, [closeModal, isCloseOnBlur, onClickOverlay]);
207
215
  React.useEffect(() => {
208
216
  if (!modalElement) {
209
217
  return;
@@ -222,26 +230,25 @@ const Modal = React.forwardRef(function Modal(props, ref) {
222
230
  }
223
231
  }, [addModalProps, className, modalIdQuerySelector]);
224
232
  React.useEffect(() => {
225
- if (!isCloseOnBlur) {
233
+ if (!isCloseOnBlur || !isOpen) {
226
234
  return;
227
235
  }
228
236
  const handleClickOutside = (event) => {
229
237
  const target = event.target;
230
- const modal = modalContentRef.current;
231
- if (!modal || !target || !target.isConnected) {
238
+ if (!modalElement || !target || !target.isConnected) {
232
239
  return;
233
240
  }
234
- const isOutside = !modal.contains(target);
241
+ const isOutside = !modalElement.contains(target);
235
242
  if (isOutside) {
236
243
  setIsOpen(false);
237
244
  onCloseModal && onCloseModal();
238
245
  }
239
246
  };
240
- document.addEventListener('click', handleClickOutside);
247
+ window.addEventListener('click', handleClickOutside);
241
248
  return () => {
242
- document.removeEventListener('click', handleClickOutside);
249
+ window.removeEventListener('click', handleClickOutside);
243
250
  };
244
- }, [onCloseModal, isCloseOnBlur]);
251
+ }, [onCloseModal, isCloseOnBlur, isOpen, modalElement]);
245
252
  // Save ref things
246
253
  React.useImperativeHandle(ref, () => ({ modalElement, openModal, closeModal, isOpen }), [isOpen, openModal, closeModal, modalElement]);
247
254
  const appearanceConfig = useAppearanceConfig.useAppearanceConfig(appearance, modalConfig, isDisabled);
@@ -255,7 +262,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
255
262
  // Any valid React child: JSX, strings, arrays, etc.
256
263
  isOpen ? (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("div", { id: id, className: clsx('modal__content', absoluteHeader && 'modal__content-absolute-header', !title && !closeIcon && 'modal__content-no-header', fillClass && `fill_${fillClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderTypeClass && `border_type_${borderTypeClass}`, shapeClass && `shape_${shapeClass}`, sizeClass && `modal_size_${sizeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderTypeClass && `border_type_${borderTypeClass}`, elevationClass && `elevation_${elevationClass}`, scroll && `modal-scroll_${scroll}`, stickyHeader && 'modal-scroll_header_sticky', isSkeleton && 'modal_skeleton'), ref: modalContentRef, "data-test-id": dataTestId, "data-tour": dataTour, style: modalStyles, tabIndex: 0, children: [(title || closeIcon) && (jsxRuntime.jsxs("div", { className: clsx('modal__header', fillClass && `fill_${fillClass}`), children: [title && (jsxRuntime.jsx(Icon.Title, { width: titleTextWidth, flex: "1", size: titleTextSize, textColor: titleTextColor, textColorHover: titleTextColorHover, textTruncate: titleTextTruncate, textWeight: titleTextWeight, textWrap: titleTextWrap, children: title })), closeIcon && (jsxRuntime.jsx("div", { className: "modal__close", onClick: closeModal, children: jsxRuntime.jsx(Icon.Icon, { appearance: `${closeIconAppearance} ${closeIconAppearanceSize}`, fillSize: closeIconFillSize, iconSize: closeIconSize, shape: closeIconShape, SvgImage: closeIconImage ?? _default.icons24.Action.Close }) }))] })), jsxRuntime.jsx("div", { className: "modal__content-wrapper", children: children })] }), jsxRuntime.jsx(Overlay.Overlay, { className: "modal__overlay",
257
264
  // ref={modalOverlayRef}
258
- fill: overlayFill, opacity: overlayOpacity, isOverlay: isOverlay, onClick: onClickOverlay })] })) : null,
265
+ fill: overlayFill, opacity: overlayOpacity, isOverlay: isOverlay, onClick: handleClickOverlay })] })) : null,
259
266
  // A DOM element
260
267
  modalElement));
261
268
  });
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import React, { useState, useRef, useCallback, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
2
+ import React, { useState, useRef, useCallback, startTransition, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
3
3
  import clsx from 'clsx';
4
4
  import ReactDOM from 'react-dom';
5
5
  import { icons24, icons32, icons40 } from '@itcase/icons/default';
@@ -168,7 +168,9 @@ const Modal = React.forwardRef(function Modal(props, ref) {
168
168
  }, [isOpen, isScrollOnOpen, isSetFocusOnOpen]);
169
169
  // Show modal with children content
170
170
  const openModal = useCallback(() => {
171
- setIsOpen(true);
171
+ startTransition(() => {
172
+ setIsOpen(true);
173
+ });
172
174
  // Callback
173
175
  if (typeof onOpenModal === 'function') {
174
176
  onOpenModal();
@@ -202,6 +204,12 @@ const Modal = React.forwardRef(function Modal(props, ref) {
202
204
  // Callback
203
205
  onCloseModal && onCloseModal();
204
206
  }, [modalElement, onCloseModal]);
207
+ const handleClickOverlay = useCallback(() => {
208
+ if (isCloseOnBlur) {
209
+ closeModal();
210
+ }
211
+ onClickOverlay && onClickOverlay();
212
+ }, [closeModal, isCloseOnBlur, onClickOverlay]);
205
213
  useEffect(() => {
206
214
  if (!modalElement) {
207
215
  return;
@@ -220,26 +228,25 @@ const Modal = React.forwardRef(function Modal(props, ref) {
220
228
  }
221
229
  }, [addModalProps, className, modalIdQuerySelector]);
222
230
  useEffect(() => {
223
- if (!isCloseOnBlur) {
231
+ if (!isCloseOnBlur || !isOpen) {
224
232
  return;
225
233
  }
226
234
  const handleClickOutside = (event) => {
227
235
  const target = event.target;
228
- const modal = modalContentRef.current;
229
- if (!modal || !target || !target.isConnected) {
236
+ if (!modalElement || !target || !target.isConnected) {
230
237
  return;
231
238
  }
232
- const isOutside = !modal.contains(target);
239
+ const isOutside = !modalElement.contains(target);
233
240
  if (isOutside) {
234
241
  setIsOpen(false);
235
242
  onCloseModal && onCloseModal();
236
243
  }
237
244
  };
238
- document.addEventListener('click', handleClickOutside);
245
+ window.addEventListener('click', handleClickOutside);
239
246
  return () => {
240
- document.removeEventListener('click', handleClickOutside);
247
+ window.removeEventListener('click', handleClickOutside);
241
248
  };
242
- }, [onCloseModal, isCloseOnBlur]);
249
+ }, [onCloseModal, isCloseOnBlur, isOpen, modalElement]);
243
250
  // Save ref things
244
251
  useImperativeHandle(ref, () => ({ modalElement, openModal, closeModal, isOpen }), [isOpen, openModal, closeModal, modalElement]);
245
252
  const appearanceConfig = useAppearanceConfig(appearance, modalConfig, isDisabled);
@@ -253,7 +260,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
253
260
  // Any valid React child: JSX, strings, arrays, etc.
254
261
  isOpen ? (jsxs(React.Fragment, { children: [jsxs("div", { id: id, className: clsx('modal__content', absoluteHeader && 'modal__content-absolute-header', !title && !closeIcon && 'modal__content-no-header', fillClass && `fill_${fillClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderTypeClass && `border_type_${borderTypeClass}`, shapeClass && `shape_${shapeClass}`, sizeClass && `modal_size_${sizeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderTypeClass && `border_type_${borderTypeClass}`, elevationClass && `elevation_${elevationClass}`, scroll && `modal-scroll_${scroll}`, stickyHeader && 'modal-scroll_header_sticky', isSkeleton && 'modal_skeleton'), ref: modalContentRef, "data-test-id": dataTestId, "data-tour": dataTour, style: modalStyles, tabIndex: 0, children: [(title || closeIcon) && (jsxs("div", { className: clsx('modal__header', fillClass && `fill_${fillClass}`), children: [title && (jsx(Title, { width: titleTextWidth, flex: "1", size: titleTextSize, textColor: titleTextColor, textColorHover: titleTextColorHover, textTruncate: titleTextTruncate, textWeight: titleTextWeight, textWrap: titleTextWrap, children: title })), closeIcon && (jsx("div", { className: "modal__close", onClick: closeModal, children: jsx(Icon, { appearance: `${closeIconAppearance} ${closeIconAppearanceSize}`, fillSize: closeIconFillSize, iconSize: closeIconSize, shape: closeIconShape, SvgImage: closeIconImage ?? icons24.Action.Close }) }))] })), jsx("div", { className: "modal__content-wrapper", children: children })] }), jsx(Overlay, { className: "modal__overlay",
255
262
  // ref={modalOverlayRef}
256
- fill: overlayFill, opacity: overlayOpacity, isOverlay: isOverlay, onClick: onClickOverlay })] })) : null,
263
+ fill: overlayFill, opacity: overlayOpacity, isOverlay: isOverlay, onClick: handleClickOverlay })] })) : null,
257
264
  // A DOM element
258
265
  modalElement));
259
266
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itcase/ui",
3
- "version": "1.8.169",
3
+ "version": "1.8.170",
4
4
  "description": "UI components (Modal, Loader, Popup, etc)",
5
5
  "keywords": [
6
6
  "Modal",