@itcase/ui 1.8.169 → 1.8.171

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.
@@ -108,7 +108,7 @@ const datePeriodConfig = {
108
108
  },
109
109
  };
110
110
  function DatePeriod(props) {
111
- const { appearance, className, datePeriodIntervalsList = Object.values(common.DATE_PERIOD_INTERVALS), datePeriodValueEnd, datePeriodValueStart, monthsShown, selectsRange = true, isDisabled, isSkeleton, onChangeDatePeriod, onKeyDown, } = props;
111
+ const { appearance, className, datePeriodIntervalsList = Object.values(common.DATE_PERIOD_INTERVALS), datePeriodValueEnd, datePeriodValueStart, monthsShown, selectsRange = true, showWeekNumbers = true, isDisabled, isSkeleton, onChangeDatePeriod, onKeyDown, } = props;
112
112
  const appearanceConfig = useAppearanceConfig.useAppearanceConfig(appearance, datePeriodConfig, isDisabled);
113
113
  const propsGenerator = useDevicePropsGenerator.useDevicePropsGenerator(props, appearanceConfig);
114
114
  const { fillClass, chipsAppearance, chipsAppearanceSize, chipsShape, datePickerAppearance, datePickerAppearanceSize, datePickerInputAppearance, datePickerInputAppearanceSize, datePickerInputFillHover, datePickerInputSize, datePickerInputTextSize, shapeClass, shapeStrengthClass, sizeClass, } = propsGenerator;
@@ -131,26 +131,12 @@ function DatePeriod(props) {
131
131
  return (dateStartIso === normalizedDatePeriodValueStart &&
132
132
  dateEndIso === normalizedDatePeriodValueEnd);
133
133
  }, [datePeriodValueEnd, datePeriodValueStart]);
134
- // const onChangeDatePicker = useCallback(
135
- // (dateStart: Date | null, dateEnd: Date | null) => {
136
- // let dateStartIso = null
137
- // let dateEndIso = null
138
- // if (dateStart) {
139
- // dateStartIso = DateTime.fromJSDate(dateStart).toISODate()
140
- // }
141
- // if (dateEnd) {
142
- // dateEndIso = DateTime.fromJSDate(dateEnd).toISODate()
143
- // }
144
- // onChangeDatePeriod(dateStartIso, dateEndIso)
145
- // },
146
- // [onChangeDatePeriod],
147
- // )
148
134
  return (jsxRuntime.jsx("div", { className: clsx(className, 'date-period', shapeClass && `shape_${shapeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`, sizeClass && `date-period_size_${sizeClass}`, isSkeleton && `date-period_skeleton`, fillClass && `fill_${fillClass}`, 'cursor_type_pointer'), children: jsxRuntime.jsxs(ChipsGroup.ChipsGroup, { className: "date-period__choice", direction: "horizontal", children: [datePeriodIntervalsList.map((datePeriodItem) => (jsxRuntime.jsx(ChipsGroup.Chips, { appearance: `${chipsAppearance} ${chipsAppearanceSize}`, label: datePeriodItem.label, shape: chipsShape, isActive: checkIsChipsActive(datePeriodItem), onClick: () => onClickPeriodChips(datePeriodItem) }, datePeriodItem.value))), jsxRuntime.jsx(DatePicker.DatePickerInput, { className: "date-period__datepicker", datePickerProps: {
149
135
  appearance: `${datePickerAppearance} ${datePickerAppearanceSize}`,
150
136
  dateFormat: 'dd/MM/yyyy',
151
137
  monthsShown: monthsShown,
152
138
  selectsRange: selectsRange,
153
- showWeekNumbers: true,
139
+ showWeekNumbers: showWeekNumbers,
154
140
  isClearable: false,
155
141
  isStartDefaultNull: true,
156
142
  onKeyDown: onKeyDown,
@@ -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
  });
@@ -106,7 +106,7 @@ const datePeriodConfig = {
106
106
  },
107
107
  };
108
108
  function DatePeriod(props) {
109
- const { appearance, className, datePeriodIntervalsList = Object.values(DATE_PERIOD_INTERVALS), datePeriodValueEnd, datePeriodValueStart, monthsShown, selectsRange = true, isDisabled, isSkeleton, onChangeDatePeriod, onKeyDown, } = props;
109
+ const { appearance, className, datePeriodIntervalsList = Object.values(DATE_PERIOD_INTERVALS), datePeriodValueEnd, datePeriodValueStart, monthsShown, selectsRange = true, showWeekNumbers = true, isDisabled, isSkeleton, onChangeDatePeriod, onKeyDown, } = props;
110
110
  const appearanceConfig = useAppearanceConfig(appearance, datePeriodConfig, isDisabled);
111
111
  const propsGenerator = useDevicePropsGenerator(props, appearanceConfig);
112
112
  const { fillClass, chipsAppearance, chipsAppearanceSize, chipsShape, datePickerAppearance, datePickerAppearanceSize, datePickerInputAppearance, datePickerInputAppearanceSize, datePickerInputFillHover, datePickerInputSize, datePickerInputTextSize, shapeClass, shapeStrengthClass, sizeClass, } = propsGenerator;
@@ -129,26 +129,12 @@ function DatePeriod(props) {
129
129
  return (dateStartIso === normalizedDatePeriodValueStart &&
130
130
  dateEndIso === normalizedDatePeriodValueEnd);
131
131
  }, [datePeriodValueEnd, datePeriodValueStart]);
132
- // const onChangeDatePicker = useCallback(
133
- // (dateStart: Date | null, dateEnd: Date | null) => {
134
- // let dateStartIso = null
135
- // let dateEndIso = null
136
- // if (dateStart) {
137
- // dateStartIso = DateTime.fromJSDate(dateStart).toISODate()
138
- // }
139
- // if (dateEnd) {
140
- // dateEndIso = DateTime.fromJSDate(dateEnd).toISODate()
141
- // }
142
- // onChangeDatePeriod(dateStartIso, dateEndIso)
143
- // },
144
- // [onChangeDatePeriod],
145
- // )
146
132
  return (jsx("div", { className: clsx(className, 'date-period', shapeClass && `shape_${shapeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`, sizeClass && `date-period_size_${sizeClass}`, isSkeleton && `date-period_skeleton`, fillClass && `fill_${fillClass}`, 'cursor_type_pointer'), children: jsxs(ChipsGroup, { className: "date-period__choice", direction: "horizontal", children: [datePeriodIntervalsList.map((datePeriodItem) => (jsx(Chips, { appearance: `${chipsAppearance} ${chipsAppearanceSize}`, label: datePeriodItem.label, shape: chipsShape, isActive: checkIsChipsActive(datePeriodItem), onClick: () => onClickPeriodChips(datePeriodItem) }, datePeriodItem.value))), jsx(DatePickerInput, { className: "date-period__datepicker", datePickerProps: {
147
133
  appearance: `${datePickerAppearance} ${datePickerAppearanceSize}`,
148
134
  dateFormat: 'dd/MM/yyyy',
149
135
  monthsShown: monthsShown,
150
136
  selectsRange: selectsRange,
151
- showWeekNumbers: true,
137
+ showWeekNumbers: showWeekNumbers,
152
138
  isClearable: false,
153
139
  isStartDefaultNull: true,
154
140
  onKeyDown: onKeyDown,
@@ -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
  });
@@ -29,5 +29,6 @@ type DatePeriodProps = DatePeriodThemeColor & StyleAttributes & {
29
29
  datePickerInputTextSize?: TextSizeProps;
30
30
  isSkeleton?: boolean;
31
31
  onChangeDatePeriod: (dateStart: Date | null, dateEnd: Date | null) => void;
32
+ showWeekNumbers?: boolean;
32
33
  };
33
34
  export type { DatePeriodAppearanceType, DatePeriodConfig, DatePeriodProps, DatePeriodThemeColor, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itcase/ui",
3
- "version": "1.8.169",
3
+ "version": "1.8.171",
4
4
  "description": "UI components (Modal, Loader, Popup, etc)",
5
5
  "keywords": [
6
6
  "Modal",