carbon-addons-iot-react 4.1.39 → 4.1.41

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.
@@ -16,7 +16,7 @@ import 'core-js/modules/es.string.includes.js';
16
16
  import 'core-js/modules/es.string.replace.js';
17
17
  import 'core-js/modules/es.string.split.js';
18
18
  import 'core-js/modules/web.dom-collections.for-each.js';
19
- import React__default, { useRef, useMemo, useEffect, useState, useCallback } from 'react';
19
+ import React__default, { useRef, useMemo, useEffect, useState } from 'react';
20
20
  import ReactDOM__default from 'react-dom';
21
21
  import PropTypes from 'prop-types';
22
22
  import { OrderedList, ListItem, FormGroup, RadioButtonGroup, RadioButton, Layer, NumberInput, Select, SelectItem, DatePicker, DatePickerInput } from '@carbon/react';
@@ -277,96 +277,148 @@ var CalendarPortal = function CalendarPortal(_ref) {
277
277
  _ref$onClose = _ref.onClose,
278
278
  onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
279
279
  children = _ref.children;
280
- var portalContentRef = useRef(null); // Reference to the calendar portal content element
281
- var _useState = useState({
280
+ var _React$useState = React__default.useState(null),
281
+ _React$useState2 = _slicedToArray(_React$useState, 2),
282
+ container = _React$useState2[0],
283
+ setContainer = _React$useState2[1];
284
+ var portalContentRef = React__default.useRef(null);
285
+ var _React$useState3 = React__default.useState({
282
286
  top: 0,
283
287
  left: 0
284
288
  }),
285
- _useState2 = _slicedToArray(_useState, 2),
286
- position = _useState2[0],
287
- setPosition = _useState2[1]; // State to store the position of the calendar portal
288
-
289
- var portalWidth = 316; // Width of the calendar portal
290
-
291
- var updatePosition = useCallback(function () {
292
- var anchor = anchorRef.current; // Reference to the anchor element
293
- var portal = portalContentRef.current; // Reference to the calendar portal content element
294
-
295
- if (!anchor || !portal) return false; // Return early if anchor or portal references are null
289
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
290
+ position = _React$useState4[0],
291
+ setPosition = _React$useState4[1];
292
+ var portalWidth = 316;
296
293
 
297
- var rect = anchor.getBoundingClientRect(); // Get the bounding client rectangle of the anchor element
298
- var scrollY = window.scrollY || document.documentElement.scrollTop; // Get the current scroll position vertically
299
- var scrollX = window.scrollX || document.documentElement.scrollLeft; // Get the current scroll position horizontally
294
+ // Decide container once the anchor exists (modal or body)
295
+ React__default.useEffect(function () {
296
+ var anchor = anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current;
297
+ if (!anchor) {
298
+ setContainer(document.body);
299
+ return;
300
+ }
301
+ var modal = anchor.closest('.cds--modal-container');
302
+ setContainer(modal || document.body);
303
+ }, [anchorRef, isOpen]);
304
+ var updatePosition = React__default.useCallback(function () {
305
+ var anchor = anchorRef.current;
306
+ var portal = portalContentRef.current;
307
+ var cont = container;
308
+ if (!anchor || !portal || !cont) return false;
309
+ var rect = anchor.getBoundingClientRect();
300
310
  var _window = window,
301
311
  innerWidth = _window.innerWidth,
302
- innerHeight = _window.innerHeight; // Get the inner width and height of the window
312
+ innerHeight = _window.innerHeight;
313
+ var portalHeight = portal.offsetHeight;
314
+ var inModal = cont !== document.body;
315
+ var top;
316
+ var left;
317
+ if (inModal) {
318
+ // ----- inside modal: absolute, relative to modal rect -----
319
+ var modalRect = cont.getBoundingClientRect();
320
+ var topSpace = rect.top - modalRect.top;
321
+ var bottomSpace = modalRect.bottom - rect.bottom;
322
+ var fitsBelow = bottomSpace >= portalHeight;
323
+ var fitsAbove = topSpace >= portalHeight;
324
+ top = fitsBelow ? rect.bottom - modalRect.top : fitsAbove ? rect.top - portalHeight - modalRect.top : rect.bottom - portalHeight - modalRect.top;
325
+ left = rect.right - portalWidth - modalRect.left;
303
326
 
304
- var portalHeight = portal.offsetHeight; // Get the height of the calendar portal content element
305
-
306
- var topSpace = rect.top; // Top space available above the anchor element
307
- var bottomSpace = innerHeight - rect.bottom; // Bottom space available below the anchor element
327
+ // clamp within modal width
328
+ var modalWidth = cont.clientWidth;
329
+ left = Math.max(0, Math.min(left, modalWidth - portalWidth));
330
+ } else {
331
+ // ----- in body: FIXED, relative to viewport (no scroll offsets) -----
332
+ var _topSpace = rect.top;
333
+ var _bottomSpace = innerHeight - rect.bottom;
334
+ var _fitsBelow = _bottomSpace >= portalHeight;
335
+ var _fitsAbove = _topSpace >= portalHeight;
336
+ top = _fitsBelow ? rect.bottom : _fitsAbove ? rect.top - portalHeight : Math.max(0, innerHeight - portalHeight);
337
+ left = rect.right - portalWidth;
338
+ left = Math.max(0, Math.min(left, innerWidth - portalWidth));
339
+ }
340
+ setPosition(function (prev) {
341
+ return prev.top === top && prev.left === left ? prev : {
342
+ top: top,
343
+ left: left
344
+ };
345
+ });
346
+ return true;
347
+ }, [anchorRef, container]);
308
348
 
309
- var fitsBelow = bottomSpace >= portalHeight; // Check if the calendar portal fits below the anchor element
310
- var fitsAbove = topSpace >= portalHeight; // Check if the calendar portal fits above the anchor element
349
+ // Run after open + after content lays out
350
+ React__default.useLayoutEffect(function () {
351
+ if (!isOpen) return;
352
+ updatePosition();
353
+ }, [isOpen, updatePosition]);
311
354
 
312
- var top = fitsBelow ? rect.bottom + scrollY : fitsAbove ? rect.top + scrollY - portalHeight : Math.max(scrollY, scrollY + rect.bottom - portalHeight); // Calculate the top position of the calendar portal
355
+ // Reposition on resize/scroll. In modal, listen to modal scroller too.
356
+ React__default.useEffect(function () {
357
+ if (!isOpen || !container) return;
358
+ var inModal = container !== document.body;
359
+ var modalScroller = inModal ? container.querySelector('.cds--modal-content') || container : null;
360
+ var onRescroll = function onRescroll() {
361
+ return updatePosition();
362
+ };
363
+ window.addEventListener('resize', onRescroll);
364
+ window.addEventListener('scroll', onRescroll, {
365
+ capture: true
366
+ });
367
+ if (modalScroller) modalScroller.addEventListener('scroll', onRescroll, {
368
+ capture: true
369
+ });
313
370
 
314
- var left = rect.right - portalWidth + scrollX; // Calculate the left position of the calendar portal
315
- left = Math.max(0, Math.min(left, scrollX + innerWidth - portalWidth)); // Ensure the left position is within the viewport
371
+ // If the calendar's size changes (months switch), keep it stuck to the anchor
372
+ var ro = new ResizeObserver(onRescroll);
373
+ if (portalContentRef.current) ro.observe(portalContentRef.current);
316
374
 
317
- setPosition({
318
- top: top,
319
- left: left
320
- }); // Update the position state
321
- return true;
322
- });
323
- useEffect(function () {
324
- if (isOpen) {
325
- var frame = requestAnimationFrame(updatePosition); // Request an animation frame to update the position
326
- return function () {
327
- return cancelAnimationFrame(frame);
328
- }; // Cancel the animation frame when the component unmounts
329
- }
330
- return undefined;
331
- }, [isOpen, updatePosition]); // Depend on the isOpen prop to re-run the effect when it changes
375
+ // eslint-disable-next-line consistent-return
376
+ return function () {
377
+ window.removeEventListener('resize', onRescroll);
378
+ window.removeEventListener('scroll', onRescroll, {
379
+ capture: true
380
+ });
381
+ if (modalScroller) modalScroller.removeEventListener('scroll', onRescroll, {
382
+ capture: true
383
+ });
384
+ ro.disconnect();
385
+ };
386
+ }, [isOpen, container, updatePosition]);
332
387
 
333
- useEffect(function () {
388
+ // Close on outside click
389
+ React__default.useEffect(function () {
390
+ if (!isOpen) return;
334
391
  var handleClickOutside = function handleClickOutside(e) {
335
- var anchor = anchorRef.current; // Reference to the anchor element
392
+ var anchor = anchorRef.current;
336
393
  if (portalContentRef.current && !portalContentRef.current.contains(e.target) && anchor && !anchor.contains(e.target)) {
337
- onClose(); // Call the onClose callback when clicking outside the calendar portal
394
+ onClose();
338
395
  }
339
396
  };
340
- window.addEventListener('scroll', updatePosition, true); // Listen for scroll events and update the position
341
- window.addEventListener('resize', updatePosition); // Listen for resize events and update the position
342
- document.addEventListener('mousedown', handleClickOutside); // Listen for mousedown events and handle click outside the calendar portal
343
-
397
+ document.addEventListener('mousedown', handleClickOutside);
398
+ // eslint-disable-next-line consistent-return
344
399
  return function () {
345
- window.removeEventListener('scroll', updatePosition, true); // Remove the scroll event listener
346
- window.removeEventListener('resize', updatePosition); // Remove the resize event listener
347
- document.removeEventListener('mousedown', handleClickOutside); // Remove the click outside event listener
400
+ return document.removeEventListener('mousedown', handleClickOutside);
348
401
  };
349
- }, [anchorRef, onClose, updatePosition]); // Depend on the anchorRef and onClose props to re-run the effect when they change
350
-
351
- if (!isOpen) return null; // Return null if the calendar portal is not open
352
-
402
+ }, [isOpen, onClose, anchorRef]);
403
+ if (!isOpen || !container) return null;
404
+ var inModal = container !== document.body;
405
+ var stylePosition = inModal ? 'absolute' : 'fixed';
353
406
  return /*#__PURE__*/ReactDOM__default.createPortal(/*#__PURE__*/React__default.createElement("div", {
354
407
  ref: portalContentRef,
355
408
  className: "datetime-picker-portal",
356
409
  style: {
357
- position: 'absolute',
358
- top: "".concat(position.top, "px"),
359
- left: "".concat(position.left, "px"),
360
- width: "".concat(portalWidth, "px"),
410
+ position: stylePosition,
411
+ top: position.top,
412
+ left: position.left,
413
+ width: portalWidth,
361
414
  backgroundColor: 'white',
362
- padding: '10px',
415
+ padding: 10,
363
416
  zIndex: 9999,
364
417
  overflowY: 'auto',
365
418
  overflowX: 'hidden',
366
- maxHeight: '400px'
419
+ maxHeight: 400
367
420
  }
368
- }, children), document.body // Attach the calendar portal to the document body
369
- );
421
+ }, children), container);
370
422
  };
371
423
  var DateTimePicker = function DateTimePicker(_ref2) {
372
424
  var _style$zIndex2;
@@ -430,34 +482,34 @@ var DateTimePicker = function DateTimePicker(_ref2) {
430
482
  customRangeKind = _useDateTimePickerRan2[0],
431
483
  setCustomRangeKind = _useDateTimePickerRan2[1],
432
484
  onCustomRangeChange = _useDateTimePickerRan2[2];
433
- var _useState3 = useState(false),
485
+ var _useState = useState(false),
486
+ _useState2 = _slicedToArray(_useState, 2),
487
+ isCustomRange = _useState2[0],
488
+ setIsCustomRange = _useState2[1];
489
+ var _useState3 = useState(null),
434
490
  _useState4 = _slicedToArray(_useState3, 2),
435
- isCustomRange = _useState4[0],
436
- setIsCustomRange = _useState4[1];
491
+ selectedPreset = _useState4[0],
492
+ setSelectedPreset = _useState4[1];
437
493
  var _useState5 = useState(null),
438
494
  _useState6 = _slicedToArray(_useState5, 2),
439
- selectedPreset = _useState6[0],
440
- setSelectedPreset = _useState6[1];
495
+ currentValue = _useState6[0],
496
+ setCurrentValue = _useState6[1];
441
497
  var _useState7 = useState(null),
442
498
  _useState8 = _slicedToArray(_useState7, 2),
443
- currentValue = _useState8[0],
444
- setCurrentValue = _useState8[1];
499
+ lastAppliedValue = _useState8[0],
500
+ setLastAppliedValue = _useState8[1];
445
501
  var _useState9 = useState(null),
446
502
  _useState10 = _slicedToArray(_useState9, 2),
447
- lastAppliedValue = _useState10[0],
448
- setLastAppliedValue = _useState10[1];
449
- var _useState11 = useState(null),
503
+ humanValue = _useState10[0],
504
+ setHumanValue = _useState10[1];
505
+ var _useState11 = useState(false),
450
506
  _useState12 = _slicedToArray(_useState11, 2),
451
- humanValue = _useState12[0],
452
- setHumanValue = _useState12[1];
453
- var _useState13 = useState(false),
507
+ defaultTimeValueUpdate = _useState12[0],
508
+ setDefaultTimeValueUpdate = _useState12[1];
509
+ var _useState13 = useState(invalid),
454
510
  _useState14 = _slicedToArray(_useState13, 2),
455
- defaultTimeValueUpdate = _useState14[0],
456
- setDefaultTimeValueUpdate = _useState14[1];
457
- var _useState15 = useState(invalid),
458
- _useState16 = _slicedToArray(_useState15, 2),
459
- invalidState = _useState16[0],
460
- setInvalidState = _useState16[1];
511
+ invalidState = _useState14[0],
512
+ setInvalidState = _useState14[1];
461
513
  var relativeSelect = useRef(null);
462
514
  var containerRef = useRef();
463
515
  var dropdownRef = useRef();
@@ -498,34 +550,34 @@ var DateTimePicker = function DateTimePicker(_ref2) {
498
550
  onNavigateRadioButton = _useDateTimePickerKey.onNavigateRadioButton,
499
551
  onNavigatePresets = _useDateTimePickerKey.onNavigatePresets,
500
552
  onFieldClick = _useDateTimePickerKey.onFieldClick;
553
+ var _useState15 = useState(null),
554
+ _useState16 = _slicedToArray(_useState15, 2),
555
+ singleDateValue = _useState16[0],
556
+ setSingleDateValue = _useState16[1];
501
557
  var _useState17 = useState(null),
502
558
  _useState18 = _slicedToArray(_useState17, 2),
503
- singleDateValue = _useState18[0],
504
- setSingleDateValue = _useState18[1];
559
+ singleTimeValue = _useState18[0],
560
+ setSingleTimeValue = _useState18[1];
505
561
  var _useState19 = useState(null),
506
562
  _useState20 = _slicedToArray(_useState19, 2),
507
- singleTimeValue = _useState20[0],
508
- setSingleTimeValue = _useState20[1];
563
+ rangeStartTimeValue = _useState20[0],
564
+ setRangeStartTimeValue = _useState20[1];
509
565
  var _useState21 = useState(null),
510
566
  _useState22 = _slicedToArray(_useState21, 2),
511
- rangeStartTimeValue = _useState22[0],
512
- setRangeStartTimeValue = _useState22[1];
513
- var _useState23 = useState(null),
567
+ rangeEndTimeValue = _useState22[0],
568
+ setRangeEndTimeValue = _useState22[1];
569
+ var _useState23 = useState(false),
514
570
  _useState24 = _slicedToArray(_useState23, 2),
515
- rangeEndTimeValue = _useState24[0],
516
- setRangeEndTimeValue = _useState24[1];
571
+ invalidRangeStartTime = _useState24[0],
572
+ setInvalidRangeStartTime = _useState24[1];
517
573
  var _useState25 = useState(false),
518
574
  _useState26 = _slicedToArray(_useState25, 2),
519
- invalidRangeStartTime = _useState26[0],
520
- setInvalidRangeStartTime = _useState26[1];
575
+ invalidRangeEndTime = _useState26[0],
576
+ setInvalidRangeEndTime = _useState26[1];
521
577
  var _useState27 = useState(false),
522
578
  _useState28 = _slicedToArray(_useState27, 2),
523
- invalidRangeEndTime = _useState28[0],
524
- setInvalidRangeEndTime = _useState28[1];
525
- var _useState29 = useState(false),
526
- _useState30 = _slicedToArray(_useState29, 2),
527
- invalidRangeStartDate = _useState30[0],
528
- setInvalidRangeStartDate = _useState30[1];
579
+ invalidRangeStartDate = _useState28[0],
580
+ setInvalidRangeStartDate = _useState28[1];
529
581
  var dateTimePickerBaseValue = {
530
582
  kind: '',
531
583
  preset: {
@@ -220,6 +220,7 @@ var SideNav = function SideNav(_ref) {
220
220
  * @returns ReactElement
221
221
  */
222
222
  var renderLinkMenu = function renderLinkMenu(link, index) {
223
+ var _link$metaData;
223
224
  var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
224
225
  var searchValue = arguments.length > 3 ? arguments[3] : undefined;
225
226
  var isFiltering = searchValue !== undefined;
@@ -243,7 +244,7 @@ var SideNav = function SideNav(_ref) {
243
244
  "data-testid": "".concat(testId, "-menu-item-").concat(index)
244
245
  }, childLink.metaData), content);
245
246
  });
246
- return /*#__PURE__*/React__default.createElement(FilterableSideNavMenu, {
247
+ return /*#__PURE__*/React__default.createElement(FilterableSideNavMenu, _extends({
247
248
  isFiltering: isFiltering,
248
249
  isActive: parentActive,
249
250
  renderIcon: link.icon,
@@ -252,7 +253,7 @@ var SideNav = function SideNav(_ref) {
252
253
  title: link.linkContent,
253
254
  testId: "".concat(testId, "-menu-").concat(index),
254
255
  className: "".concat(iotPrefix, "--side-nav__item--depth-").concat(level)
255
- }, children);
256
+ }, (_link$metaData = link.metaData) !== null && _link$metaData !== void 0 ? _link$metaData : {}), children);
256
257
  };
257
258
  var renderLinks = function renderLinks(linkConfigurations, searchValue) {
258
259
  return linkConfigurations.map(function (link, index) {
@@ -511,6 +511,10 @@ var TimePickerSpinner = /*#__PURE__*/React__default.forwardRef(function (_ref2,
511
511
  is24hours = _ref2.is24hours,
512
512
  amString = _ref2.amString,
513
513
  pmString = _ref2.pmString;
514
+ var _useState15 = useState(null),
515
+ _useState16 = _slicedToArray(_useState15, 2),
516
+ container = _useState16[0],
517
+ setContainer = _useState16[1];
514
518
  var currentTime = dayjs().format(AVAILABLE_FORMATS);
515
519
  var updatedStyle = useMemo(function () {
516
520
  var _style$zIndex;
@@ -527,20 +531,25 @@ var TimePickerSpinner = /*#__PURE__*/React__default.forwardRef(function (_ref2,
527
531
  var thirdVal = useMemo(function () {
528
532
  return is24hours ? '' : timeUtils.getMeridiem(value, currentTime, amString, pmString) === amString ? 'AM' : 'PM';
529
533
  }, [is24hours, value, currentTime, amString, pmString]);
530
- var _useState15 = useState([firstVal, secondVal, thirdVal]),
531
- _useState16 = _slicedToArray(_useState15, 2),
532
- selected = _useState16[0],
533
- setSelected = _useState16[1];
534
- var _useState17 = useState(value),
534
+ var _useState17 = useState([firstVal, secondVal, thirdVal]),
535
535
  _useState18 = _slicedToArray(_useState17, 2),
536
- callbackValue = _useState18[0],
537
- setCallbackValue = _useState18[1];
538
- var _useState19 = useState(0),
536
+ selected = _useState18[0],
537
+ setSelected = _useState18[1];
538
+ var _useState19 = useState(value),
539
539
  _useState20 = _slicedToArray(_useState19, 2),
540
- setFocusedSpinner = _useState20[1];
540
+ callbackValue = _useState20[0],
541
+ setCallbackValue = _useState20[1];
542
+ var _useState21 = useState(0),
543
+ _useState22 = _slicedToArray(_useState21, 2),
544
+ setFocusedSpinner = _useState22[1];
541
545
  var secondSpinnerRef = useRef();
542
546
  var thirdSpinnerRef = useRef();
543
547
  var numberOfSpinners = is24hours ? 2 : 3;
548
+ useEffect(function () {
549
+ var active = document.activeElement; // currently focused element
550
+ var nearestModal = active === null || active === void 0 ? void 0 : active.closest('.cds--modal');
551
+ setContainer(nearestModal || document.body);
552
+ }, []);
544
553
  useEffect(function () {
545
554
  setSelected([firstVal, secondVal, thirdVal]);
546
555
  }, [firstVal, secondVal, thirdVal]);
@@ -636,6 +645,7 @@ var TimePickerSpinner = /*#__PURE__*/React__default.forwardRef(function (_ref2,
636
645
  }, /* eslint-disable-next-line react-hooks/exhaustive-deps */
637
646
  [selected[2]]);
638
647
  var dropdown = /*#__PURE__*/React__default.createElement("div", {
648
+ ref: ref,
639
649
  "data-testid": testId,
640
650
  className: classnames("".concat(iotPrefix, "--time-picker-spinner"), _defineProperty({}, "".concat(iotPrefix, "--time-picker-spinner--24h"), is24hours)),
641
651
  style: _objectSpread(_objectSpread({}, updatedStyle), {}, {
@@ -643,7 +653,8 @@ var TimePickerSpinner = /*#__PURE__*/React__default.forwardRef(function (_ref2,
643
653
  top: "".concat(position[1], "px")
644
654
  })
645
655
  }, listSpinner1, listSpinner2, is24hours ? null : listSpinner3);
646
- return /*#__PURE__*/ReactDOM__default.createPortal(dropdown, document.body);
656
+ if (!container) return null;
657
+ return /*#__PURE__*/ReactDOM__default.createPortal(dropdown, container);
647
658
  });
648
659
  TimePickerSpinner.propTypes = spinnerPropTypes;
649
660
  TimePickerSpinner.defaultProps = defaultSpinnerProps;
@@ -293,96 +293,148 @@ var CalendarPortal = function CalendarPortal(_ref) {
293
293
  _ref$onClose = _ref.onClose,
294
294
  onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
295
295
  children = _ref.children;
296
- var portalContentRef = React.useRef(null); // Reference to the calendar portal content element
297
- var _useState = React.useState({
296
+ var _React$useState = React__default.default.useState(null),
297
+ _React$useState2 = _slicedToArray__default.default(_React$useState, 2),
298
+ container = _React$useState2[0],
299
+ setContainer = _React$useState2[1];
300
+ var portalContentRef = React__default.default.useRef(null);
301
+ var _React$useState3 = React__default.default.useState({
298
302
  top: 0,
299
303
  left: 0
300
304
  }),
301
- _useState2 = _slicedToArray__default.default(_useState, 2),
302
- position = _useState2[0],
303
- setPosition = _useState2[1]; // State to store the position of the calendar portal
304
-
305
- var portalWidth = 316; // Width of the calendar portal
306
-
307
- var updatePosition = React.useCallback(function () {
308
- var anchor = anchorRef.current; // Reference to the anchor element
309
- var portal = portalContentRef.current; // Reference to the calendar portal content element
310
-
311
- if (!anchor || !portal) return false; // Return early if anchor or portal references are null
305
+ _React$useState4 = _slicedToArray__default.default(_React$useState3, 2),
306
+ position = _React$useState4[0],
307
+ setPosition = _React$useState4[1];
308
+ var portalWidth = 316;
312
309
 
313
- var rect = anchor.getBoundingClientRect(); // Get the bounding client rectangle of the anchor element
314
- var scrollY = window.scrollY || document.documentElement.scrollTop; // Get the current scroll position vertically
315
- var scrollX = window.scrollX || document.documentElement.scrollLeft; // Get the current scroll position horizontally
310
+ // Decide container once the anchor exists (modal or body)
311
+ React__default.default.useEffect(function () {
312
+ var anchor = anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current;
313
+ if (!anchor) {
314
+ setContainer(document.body);
315
+ return;
316
+ }
317
+ var modal = anchor.closest('.cds--modal-container');
318
+ setContainer(modal || document.body);
319
+ }, [anchorRef, isOpen]);
320
+ var updatePosition = React__default.default.useCallback(function () {
321
+ var anchor = anchorRef.current;
322
+ var portal = portalContentRef.current;
323
+ var cont = container;
324
+ if (!anchor || !portal || !cont) return false;
325
+ var rect = anchor.getBoundingClientRect();
316
326
  var _window = window,
317
327
  innerWidth = _window.innerWidth,
318
- innerHeight = _window.innerHeight; // Get the inner width and height of the window
328
+ innerHeight = _window.innerHeight;
329
+ var portalHeight = portal.offsetHeight;
330
+ var inModal = cont !== document.body;
331
+ var top;
332
+ var left;
333
+ if (inModal) {
334
+ // ----- inside modal: absolute, relative to modal rect -----
335
+ var modalRect = cont.getBoundingClientRect();
336
+ var topSpace = rect.top - modalRect.top;
337
+ var bottomSpace = modalRect.bottom - rect.bottom;
338
+ var fitsBelow = bottomSpace >= portalHeight;
339
+ var fitsAbove = topSpace >= portalHeight;
340
+ top = fitsBelow ? rect.bottom - modalRect.top : fitsAbove ? rect.top - portalHeight - modalRect.top : rect.bottom - portalHeight - modalRect.top;
341
+ left = rect.right - portalWidth - modalRect.left;
319
342
 
320
- var portalHeight = portal.offsetHeight; // Get the height of the calendar portal content element
321
-
322
- var topSpace = rect.top; // Top space available above the anchor element
323
- var bottomSpace = innerHeight - rect.bottom; // Bottom space available below the anchor element
343
+ // clamp within modal width
344
+ var modalWidth = cont.clientWidth;
345
+ left = Math.max(0, Math.min(left, modalWidth - portalWidth));
346
+ } else {
347
+ // ----- in body: FIXED, relative to viewport (no scroll offsets) -----
348
+ var _topSpace = rect.top;
349
+ var _bottomSpace = innerHeight - rect.bottom;
350
+ var _fitsBelow = _bottomSpace >= portalHeight;
351
+ var _fitsAbove = _topSpace >= portalHeight;
352
+ top = _fitsBelow ? rect.bottom : _fitsAbove ? rect.top - portalHeight : Math.max(0, innerHeight - portalHeight);
353
+ left = rect.right - portalWidth;
354
+ left = Math.max(0, Math.min(left, innerWidth - portalWidth));
355
+ }
356
+ setPosition(function (prev) {
357
+ return prev.top === top && prev.left === left ? prev : {
358
+ top: top,
359
+ left: left
360
+ };
361
+ });
362
+ return true;
363
+ }, [anchorRef, container]);
324
364
 
325
- var fitsBelow = bottomSpace >= portalHeight; // Check if the calendar portal fits below the anchor element
326
- var fitsAbove = topSpace >= portalHeight; // Check if the calendar portal fits above the anchor element
365
+ // Run after open + after content lays out
366
+ React__default.default.useLayoutEffect(function () {
367
+ if (!isOpen) return;
368
+ updatePosition();
369
+ }, [isOpen, updatePosition]);
327
370
 
328
- var top = fitsBelow ? rect.bottom + scrollY : fitsAbove ? rect.top + scrollY - portalHeight : Math.max(scrollY, scrollY + rect.bottom - portalHeight); // Calculate the top position of the calendar portal
371
+ // Reposition on resize/scroll. In modal, listen to modal scroller too.
372
+ React__default.default.useEffect(function () {
373
+ if (!isOpen || !container) return;
374
+ var inModal = container !== document.body;
375
+ var modalScroller = inModal ? container.querySelector('.cds--modal-content') || container : null;
376
+ var onRescroll = function onRescroll() {
377
+ return updatePosition();
378
+ };
379
+ window.addEventListener('resize', onRescroll);
380
+ window.addEventListener('scroll', onRescroll, {
381
+ capture: true
382
+ });
383
+ if (modalScroller) modalScroller.addEventListener('scroll', onRescroll, {
384
+ capture: true
385
+ });
329
386
 
330
- var left = rect.right - portalWidth + scrollX; // Calculate the left position of the calendar portal
331
- left = Math.max(0, Math.min(left, scrollX + innerWidth - portalWidth)); // Ensure the left position is within the viewport
387
+ // If the calendar's size changes (months switch), keep it stuck to the anchor
388
+ var ro = new ResizeObserver(onRescroll);
389
+ if (portalContentRef.current) ro.observe(portalContentRef.current);
332
390
 
333
- setPosition({
334
- top: top,
335
- left: left
336
- }); // Update the position state
337
- return true;
338
- });
339
- React.useEffect(function () {
340
- if (isOpen) {
341
- var frame = requestAnimationFrame(updatePosition); // Request an animation frame to update the position
342
- return function () {
343
- return cancelAnimationFrame(frame);
344
- }; // Cancel the animation frame when the component unmounts
345
- }
346
- return undefined;
347
- }, [isOpen, updatePosition]); // Depend on the isOpen prop to re-run the effect when it changes
391
+ // eslint-disable-next-line consistent-return
392
+ return function () {
393
+ window.removeEventListener('resize', onRescroll);
394
+ window.removeEventListener('scroll', onRescroll, {
395
+ capture: true
396
+ });
397
+ if (modalScroller) modalScroller.removeEventListener('scroll', onRescroll, {
398
+ capture: true
399
+ });
400
+ ro.disconnect();
401
+ };
402
+ }, [isOpen, container, updatePosition]);
348
403
 
349
- React.useEffect(function () {
404
+ // Close on outside click
405
+ React__default.default.useEffect(function () {
406
+ if (!isOpen) return;
350
407
  var handleClickOutside = function handleClickOutside(e) {
351
- var anchor = anchorRef.current; // Reference to the anchor element
408
+ var anchor = anchorRef.current;
352
409
  if (portalContentRef.current && !portalContentRef.current.contains(e.target) && anchor && !anchor.contains(e.target)) {
353
- onClose(); // Call the onClose callback when clicking outside the calendar portal
410
+ onClose();
354
411
  }
355
412
  };
356
- window.addEventListener('scroll', updatePosition, true); // Listen for scroll events and update the position
357
- window.addEventListener('resize', updatePosition); // Listen for resize events and update the position
358
- document.addEventListener('mousedown', handleClickOutside); // Listen for mousedown events and handle click outside the calendar portal
359
-
413
+ document.addEventListener('mousedown', handleClickOutside);
414
+ // eslint-disable-next-line consistent-return
360
415
  return function () {
361
- window.removeEventListener('scroll', updatePosition, true); // Remove the scroll event listener
362
- window.removeEventListener('resize', updatePosition); // Remove the resize event listener
363
- document.removeEventListener('mousedown', handleClickOutside); // Remove the click outside event listener
416
+ return document.removeEventListener('mousedown', handleClickOutside);
364
417
  };
365
- }, [anchorRef, onClose, updatePosition]); // Depend on the anchorRef and onClose props to re-run the effect when they change
366
-
367
- if (!isOpen) return null; // Return null if the calendar portal is not open
368
-
418
+ }, [isOpen, onClose, anchorRef]);
419
+ if (!isOpen || !container) return null;
420
+ var inModal = container !== document.body;
421
+ var stylePosition = inModal ? 'absolute' : 'fixed';
369
422
  return /*#__PURE__*/ReactDOM__default.default.createPortal(/*#__PURE__*/React__default.default.createElement("div", {
370
423
  ref: portalContentRef,
371
424
  className: "datetime-picker-portal",
372
425
  style: {
373
- position: 'absolute',
374
- top: "".concat(position.top, "px"),
375
- left: "".concat(position.left, "px"),
376
- width: "".concat(portalWidth, "px"),
426
+ position: stylePosition,
427
+ top: position.top,
428
+ left: position.left,
429
+ width: portalWidth,
377
430
  backgroundColor: 'white',
378
- padding: '10px',
431
+ padding: 10,
379
432
  zIndex: 9999,
380
433
  overflowY: 'auto',
381
434
  overflowX: 'hidden',
382
- maxHeight: '400px'
435
+ maxHeight: 400
383
436
  }
384
- }, children), document.body // Attach the calendar portal to the document body
385
- );
437
+ }, children), container);
386
438
  };
387
439
  var DateTimePicker = function DateTimePicker(_ref2) {
388
440
  var _style$zIndex2;
@@ -446,34 +498,34 @@ var DateTimePicker = function DateTimePicker(_ref2) {
446
498
  customRangeKind = _useDateTimePickerRan2[0],
447
499
  setCustomRangeKind = _useDateTimePickerRan2[1],
448
500
  onCustomRangeChange = _useDateTimePickerRan2[2];
449
- var _useState3 = React.useState(false),
501
+ var _useState = React.useState(false),
502
+ _useState2 = _slicedToArray__default.default(_useState, 2),
503
+ isCustomRange = _useState2[0],
504
+ setIsCustomRange = _useState2[1];
505
+ var _useState3 = React.useState(null),
450
506
  _useState4 = _slicedToArray__default.default(_useState3, 2),
451
- isCustomRange = _useState4[0],
452
- setIsCustomRange = _useState4[1];
507
+ selectedPreset = _useState4[0],
508
+ setSelectedPreset = _useState4[1];
453
509
  var _useState5 = React.useState(null),
454
510
  _useState6 = _slicedToArray__default.default(_useState5, 2),
455
- selectedPreset = _useState6[0],
456
- setSelectedPreset = _useState6[1];
511
+ currentValue = _useState6[0],
512
+ setCurrentValue = _useState6[1];
457
513
  var _useState7 = React.useState(null),
458
514
  _useState8 = _slicedToArray__default.default(_useState7, 2),
459
- currentValue = _useState8[0],
460
- setCurrentValue = _useState8[1];
515
+ lastAppliedValue = _useState8[0],
516
+ setLastAppliedValue = _useState8[1];
461
517
  var _useState9 = React.useState(null),
462
518
  _useState10 = _slicedToArray__default.default(_useState9, 2),
463
- lastAppliedValue = _useState10[0],
464
- setLastAppliedValue = _useState10[1];
465
- var _useState11 = React.useState(null),
519
+ humanValue = _useState10[0],
520
+ setHumanValue = _useState10[1];
521
+ var _useState11 = React.useState(false),
466
522
  _useState12 = _slicedToArray__default.default(_useState11, 2),
467
- humanValue = _useState12[0],
468
- setHumanValue = _useState12[1];
469
- var _useState13 = React.useState(false),
523
+ defaultTimeValueUpdate = _useState12[0],
524
+ setDefaultTimeValueUpdate = _useState12[1];
525
+ var _useState13 = React.useState(invalid),
470
526
  _useState14 = _slicedToArray__default.default(_useState13, 2),
471
- defaultTimeValueUpdate = _useState14[0],
472
- setDefaultTimeValueUpdate = _useState14[1];
473
- var _useState15 = React.useState(invalid),
474
- _useState16 = _slicedToArray__default.default(_useState15, 2),
475
- invalidState = _useState16[0],
476
- setInvalidState = _useState16[1];
527
+ invalidState = _useState14[0],
528
+ setInvalidState = _useState14[1];
477
529
  var relativeSelect = React.useRef(null);
478
530
  var containerRef = React.useRef();
479
531
  var dropdownRef = React.useRef();
@@ -514,34 +566,34 @@ var DateTimePicker = function DateTimePicker(_ref2) {
514
566
  onNavigateRadioButton = _useDateTimePickerKey.onNavigateRadioButton,
515
567
  onNavigatePresets = _useDateTimePickerKey.onNavigatePresets,
516
568
  onFieldClick = _useDateTimePickerKey.onFieldClick;
569
+ var _useState15 = React.useState(null),
570
+ _useState16 = _slicedToArray__default.default(_useState15, 2),
571
+ singleDateValue = _useState16[0],
572
+ setSingleDateValue = _useState16[1];
517
573
  var _useState17 = React.useState(null),
518
574
  _useState18 = _slicedToArray__default.default(_useState17, 2),
519
- singleDateValue = _useState18[0],
520
- setSingleDateValue = _useState18[1];
575
+ singleTimeValue = _useState18[0],
576
+ setSingleTimeValue = _useState18[1];
521
577
  var _useState19 = React.useState(null),
522
578
  _useState20 = _slicedToArray__default.default(_useState19, 2),
523
- singleTimeValue = _useState20[0],
524
- setSingleTimeValue = _useState20[1];
579
+ rangeStartTimeValue = _useState20[0],
580
+ setRangeStartTimeValue = _useState20[1];
525
581
  var _useState21 = React.useState(null),
526
582
  _useState22 = _slicedToArray__default.default(_useState21, 2),
527
- rangeStartTimeValue = _useState22[0],
528
- setRangeStartTimeValue = _useState22[1];
529
- var _useState23 = React.useState(null),
583
+ rangeEndTimeValue = _useState22[0],
584
+ setRangeEndTimeValue = _useState22[1];
585
+ var _useState23 = React.useState(false),
530
586
  _useState24 = _slicedToArray__default.default(_useState23, 2),
531
- rangeEndTimeValue = _useState24[0],
532
- setRangeEndTimeValue = _useState24[1];
587
+ invalidRangeStartTime = _useState24[0],
588
+ setInvalidRangeStartTime = _useState24[1];
533
589
  var _useState25 = React.useState(false),
534
590
  _useState26 = _slicedToArray__default.default(_useState25, 2),
535
- invalidRangeStartTime = _useState26[0],
536
- setInvalidRangeStartTime = _useState26[1];
591
+ invalidRangeEndTime = _useState26[0],
592
+ setInvalidRangeEndTime = _useState26[1];
537
593
  var _useState27 = React.useState(false),
538
594
  _useState28 = _slicedToArray__default.default(_useState27, 2),
539
- invalidRangeEndTime = _useState28[0],
540
- setInvalidRangeEndTime = _useState28[1];
541
- var _useState29 = React.useState(false),
542
- _useState30 = _slicedToArray__default.default(_useState29, 2),
543
- invalidRangeStartDate = _useState30[0],
544
- setInvalidRangeStartDate = _useState30[1];
595
+ invalidRangeStartDate = _useState28[0],
596
+ setInvalidRangeStartDate = _useState28[1];
545
597
  var dateTimePickerBaseValue = {
546
598
  kind: '',
547
599
  preset: {
@@ -235,6 +235,7 @@ var SideNav = function SideNav(_ref) {
235
235
  * @returns ReactElement
236
236
  */
237
237
  var renderLinkMenu = function renderLinkMenu(link, index) {
238
+ var _link$metaData;
238
239
  var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
239
240
  var searchValue = arguments.length > 3 ? arguments[3] : undefined;
240
241
  var isFiltering = searchValue !== undefined;
@@ -258,7 +259,7 @@ var SideNav = function SideNav(_ref) {
258
259
  "data-testid": "".concat(testId, "-menu-item-").concat(index)
259
260
  }, childLink.metaData), content);
260
261
  });
261
- return /*#__PURE__*/React__default.default.createElement(FilterableSideNavMenu, {
262
+ return /*#__PURE__*/React__default.default.createElement(FilterableSideNavMenu, _extends__default.default({
262
263
  isFiltering: isFiltering,
263
264
  isActive: parentActive,
264
265
  renderIcon: link.icon,
@@ -267,7 +268,7 @@ var SideNav = function SideNav(_ref) {
267
268
  title: link.linkContent,
268
269
  testId: "".concat(testId, "-menu-").concat(index),
269
270
  className: "".concat(iotPrefix, "--side-nav__item--depth-").concat(level)
270
- }, children);
271
+ }, (_link$metaData = link.metaData) !== null && _link$metaData !== void 0 ? _link$metaData : {}), children);
271
272
  };
272
273
  var renderLinks = function renderLinks(linkConfigurations, searchValue) {
273
274
  return linkConfigurations.map(function (link, index) {
@@ -527,6 +527,10 @@ var TimePickerSpinner = /*#__PURE__*/React__default.default.forwardRef(function
527
527
  is24hours = _ref2.is24hours,
528
528
  amString = _ref2.amString,
529
529
  pmString = _ref2.pmString;
530
+ var _useState15 = React.useState(null),
531
+ _useState16 = _slicedToArray__default.default(_useState15, 2),
532
+ container = _useState16[0],
533
+ setContainer = _useState16[1];
530
534
  var currentTime = dayjs__default.default().format(AVAILABLE_FORMATS);
531
535
  var updatedStyle = React.useMemo(function () {
532
536
  var _style$zIndex;
@@ -543,20 +547,25 @@ var TimePickerSpinner = /*#__PURE__*/React__default.default.forwardRef(function
543
547
  var thirdVal = React.useMemo(function () {
544
548
  return is24hours ? '' : timeUtils.getMeridiem(value, currentTime, amString, pmString) === amString ? 'AM' : 'PM';
545
549
  }, [is24hours, value, currentTime, amString, pmString]);
546
- var _useState15 = React.useState([firstVal, secondVal, thirdVal]),
547
- _useState16 = _slicedToArray__default.default(_useState15, 2),
548
- selected = _useState16[0],
549
- setSelected = _useState16[1];
550
- var _useState17 = React.useState(value),
550
+ var _useState17 = React.useState([firstVal, secondVal, thirdVal]),
551
551
  _useState18 = _slicedToArray__default.default(_useState17, 2),
552
- callbackValue = _useState18[0],
553
- setCallbackValue = _useState18[1];
554
- var _useState19 = React.useState(0),
552
+ selected = _useState18[0],
553
+ setSelected = _useState18[1];
554
+ var _useState19 = React.useState(value),
555
555
  _useState20 = _slicedToArray__default.default(_useState19, 2),
556
- setFocusedSpinner = _useState20[1];
556
+ callbackValue = _useState20[0],
557
+ setCallbackValue = _useState20[1];
558
+ var _useState21 = React.useState(0),
559
+ _useState22 = _slicedToArray__default.default(_useState21, 2),
560
+ setFocusedSpinner = _useState22[1];
557
561
  var secondSpinnerRef = React.useRef();
558
562
  var thirdSpinnerRef = React.useRef();
559
563
  var numberOfSpinners = is24hours ? 2 : 3;
564
+ React.useEffect(function () {
565
+ var active = document.activeElement; // currently focused element
566
+ var nearestModal = active === null || active === void 0 ? void 0 : active.closest('.cds--modal');
567
+ setContainer(nearestModal || document.body);
568
+ }, []);
560
569
  React.useEffect(function () {
561
570
  setSelected([firstVal, secondVal, thirdVal]);
562
571
  }, [firstVal, secondVal, thirdVal]);
@@ -652,6 +661,7 @@ var TimePickerSpinner = /*#__PURE__*/React__default.default.forwardRef(function
652
661
  }, /* eslint-disable-next-line react-hooks/exhaustive-deps */
653
662
  [selected[2]]);
654
663
  var dropdown = /*#__PURE__*/React__default.default.createElement("div", {
664
+ ref: ref,
655
665
  "data-testid": testId,
656
666
  className: classnames__default.default("".concat(iotPrefix, "--time-picker-spinner"), _defineProperty__default.default({}, "".concat(iotPrefix, "--time-picker-spinner--24h"), is24hours)),
657
667
  style: _objectSpread(_objectSpread({}, updatedStyle), {}, {
@@ -659,7 +669,8 @@ var TimePickerSpinner = /*#__PURE__*/React__default.default.forwardRef(function
659
669
  top: "".concat(position[1], "px")
660
670
  })
661
671
  }, listSpinner1, listSpinner2, is24hours ? null : listSpinner3);
662
- return /*#__PURE__*/ReactDOM__default.default.createPortal(dropdown, document.body);
672
+ if (!container) return null;
673
+ return /*#__PURE__*/ReactDOM__default.default.createPortal(dropdown, container);
663
674
  });
664
675
  TimePickerSpinner.propTypes = spinnerPropTypes;
665
676
  TimePickerSpinner.defaultProps = defaultSpinnerProps;
package/package.json CHANGED
@@ -344,11 +344,11 @@
344
344
  "whatwg-fetch": "^3.0.0"
345
345
  },
346
346
  "sideEffects": false,
347
- "version": "4.1.39",
347
+ "version": "4.1.41",
348
348
  "resolutions": {
349
349
  "chokidar": "3.3.1",
350
350
  "react-grid-layout": "1.2.2",
351
351
  "got": "11.8.5"
352
352
  },
353
- "gitHead": "684013cf3c84601a361e2acf84eb0282307670ea"
353
+ "gitHead": "29f21ee25169abc1e95d846e0eb39faf414ca97b"
354
354
  }
@@ -269009,6 +269009,10 @@ React keys must be passed directly to JSX without using spread:
269009
269009
  is24hours = _ref2.is24hours,
269010
269010
  amString = _ref2.amString,
269011
269011
  pmString = _ref2.pmString;
269012
+ var _useState15 = React$1.useState(null),
269013
+ _useState16 = _slicedToArray$9(_useState15, 2),
269014
+ container = _useState16[0],
269015
+ setContainer = _useState16[1];
269012
269016
  var currentTime = dayjs_min().format(AVAILABLE_FORMATS);
269013
269017
  var updatedStyle = React$1.useMemo(function () {
269014
269018
  var _style$zIndex;
@@ -269025,20 +269029,25 @@ React keys must be passed directly to JSX without using spread:
269025
269029
  var thirdVal = React$1.useMemo(function () {
269026
269030
  return is24hours ? '' : timeUtils.getMeridiem(value, currentTime, amString, pmString) === amString ? 'AM' : 'PM';
269027
269031
  }, [is24hours, value, currentTime, amString, pmString]);
269028
- var _useState15 = React$1.useState([firstVal, secondVal, thirdVal]),
269029
- _useState16 = _slicedToArray$9(_useState15, 2),
269030
- selected = _useState16[0],
269031
- setSelected = _useState16[1];
269032
- var _useState17 = React$1.useState(value),
269032
+ var _useState17 = React$1.useState([firstVal, secondVal, thirdVal]),
269033
269033
  _useState18 = _slicedToArray$9(_useState17, 2),
269034
- callbackValue = _useState18[0],
269035
- setCallbackValue = _useState18[1];
269036
- var _useState19 = React$1.useState(0),
269034
+ selected = _useState18[0],
269035
+ setSelected = _useState18[1];
269036
+ var _useState19 = React$1.useState(value),
269037
269037
  _useState20 = _slicedToArray$9(_useState19, 2),
269038
- setFocusedSpinner = _useState20[1];
269038
+ callbackValue = _useState20[0],
269039
+ setCallbackValue = _useState20[1];
269040
+ var _useState21 = React$1.useState(0),
269041
+ _useState22 = _slicedToArray$9(_useState21, 2),
269042
+ setFocusedSpinner = _useState22[1];
269039
269043
  var secondSpinnerRef = React$1.useRef();
269040
269044
  var thirdSpinnerRef = React$1.useRef();
269041
269045
  var numberOfSpinners = is24hours ? 2 : 3;
269046
+ React$1.useEffect(function () {
269047
+ var active = document.activeElement; // currently focused element
269048
+ var nearestModal = active === null || active === void 0 ? void 0 : active.closest('.cds--modal');
269049
+ setContainer(nearestModal || document.body);
269050
+ }, []);
269042
269051
  React$1.useEffect(function () {
269043
269052
  setSelected([firstVal, secondVal, thirdVal]);
269044
269053
  }, [firstVal, secondVal, thirdVal]);
@@ -269134,6 +269143,7 @@ React keys must be passed directly to JSX without using spread:
269134
269143
  }, /* eslint-disable-next-line react-hooks/exhaustive-deps */
269135
269144
  [selected[2]]);
269136
269145
  var dropdown = /*#__PURE__*/React$1.createElement("div", {
269146
+ ref: ref,
269137
269147
  "data-testid": testId,
269138
269148
  className: classnames("".concat(iotPrefix$1g, "--time-picker-spinner"), _defineProperty$c({}, "".concat(iotPrefix$1g, "--time-picker-spinner--24h"), is24hours)),
269139
269149
  style: _objectSpread$1i(_objectSpread$1i({}, updatedStyle), {}, {
@@ -269141,7 +269151,8 @@ React keys must be passed directly to JSX without using spread:
269141
269151
  top: "".concat(position[1], "px")
269142
269152
  })
269143
269153
  }, listSpinner1, listSpinner2, is24hours ? null : listSpinner3);
269144
- return /*#__PURE__*/ReactDOM.createPortal(dropdown, document.body);
269154
+ if (!container) return null;
269155
+ return /*#__PURE__*/ReactDOM.createPortal(dropdown, container);
269145
269156
  });
269146
269157
  TimePickerSpinner.propTypes = spinnerPropTypes;
269147
269158
  TimePickerSpinner.defaultProps = defaultSpinnerProps;
@@ -271175,96 +271186,148 @@ React keys must be passed directly to JSX without using spread:
271175
271186
  _ref$onClose = _ref.onClose,
271176
271187
  onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
271177
271188
  children = _ref.children;
271178
- var portalContentRef = React$1.useRef(null); // Reference to the calendar portal content element
271179
- var _useState = React$1.useState({
271189
+ var _React$useState = React$1.useState(null),
271190
+ _React$useState2 = _slicedToArray$9(_React$useState, 2),
271191
+ container = _React$useState2[0],
271192
+ setContainer = _React$useState2[1];
271193
+ var portalContentRef = React$1.useRef(null);
271194
+ var _React$useState3 = React$1.useState({
271180
271195
  top: 0,
271181
271196
  left: 0
271182
271197
  }),
271183
- _useState2 = _slicedToArray$9(_useState, 2),
271184
- position = _useState2[0],
271185
- setPosition = _useState2[1]; // State to store the position of the calendar portal
271186
-
271187
- var portalWidth = 316; // Width of the calendar portal
271198
+ _React$useState4 = _slicedToArray$9(_React$useState3, 2),
271199
+ position = _React$useState4[0],
271200
+ setPosition = _React$useState4[1];
271201
+ var portalWidth = 316;
271188
271202
 
271203
+ // Decide container once the anchor exists (modal or body)
271204
+ React$1.useEffect(function () {
271205
+ var anchor = anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current;
271206
+ if (!anchor) {
271207
+ setContainer(document.body);
271208
+ return;
271209
+ }
271210
+ var modal = anchor.closest('.cds--modal-container');
271211
+ setContainer(modal || document.body);
271212
+ }, [anchorRef, isOpen]);
271189
271213
  var updatePosition = React$1.useCallback(function () {
271190
- var anchor = anchorRef.current; // Reference to the anchor element
271191
- var portal = portalContentRef.current; // Reference to the calendar portal content element
271192
-
271193
- if (!anchor || !portal) return false; // Return early if anchor or portal references are null
271194
-
271195
- var rect = anchor.getBoundingClientRect(); // Get the bounding client rectangle of the anchor element
271196
- var scrollY = window.scrollY || document.documentElement.scrollTop; // Get the current scroll position vertically
271197
- var scrollX = window.scrollX || document.documentElement.scrollLeft; // Get the current scroll position horizontally
271214
+ var anchor = anchorRef.current;
271215
+ var portal = portalContentRef.current;
271216
+ var cont = container;
271217
+ if (!anchor || !portal || !cont) return false;
271218
+ var rect = anchor.getBoundingClientRect();
271198
271219
  var _window = window,
271199
271220
  innerWidth = _window.innerWidth,
271200
- innerHeight = _window.innerHeight; // Get the inner width and height of the window
271201
-
271202
- var portalHeight = portal.offsetHeight; // Get the height of the calendar portal content element
271203
-
271204
- var topSpace = rect.top; // Top space available above the anchor element
271205
- var bottomSpace = innerHeight - rect.bottom; // Bottom space available below the anchor element
271221
+ innerHeight = _window.innerHeight;
271222
+ var portalHeight = portal.offsetHeight;
271223
+ var inModal = cont !== document.body;
271224
+ var top;
271225
+ var left;
271226
+ if (inModal) {
271227
+ // ----- inside modal: absolute, relative to modal rect -----
271228
+ var modalRect = cont.getBoundingClientRect();
271229
+ var topSpace = rect.top - modalRect.top;
271230
+ var bottomSpace = modalRect.bottom - rect.bottom;
271231
+ var fitsBelow = bottomSpace >= portalHeight;
271232
+ var fitsAbove = topSpace >= portalHeight;
271233
+ top = fitsBelow ? rect.bottom - modalRect.top : fitsAbove ? rect.top - portalHeight - modalRect.top : rect.bottom - portalHeight - modalRect.top;
271234
+ left = rect.right - portalWidth - modalRect.left;
271235
+
271236
+ // clamp within modal width
271237
+ var modalWidth = cont.clientWidth;
271238
+ left = Math.max(0, Math.min(left, modalWidth - portalWidth));
271239
+ } else {
271240
+ // ----- in body: FIXED, relative to viewport (no scroll offsets) -----
271241
+ var _topSpace = rect.top;
271242
+ var _bottomSpace = innerHeight - rect.bottom;
271243
+ var _fitsBelow = _bottomSpace >= portalHeight;
271244
+ var _fitsAbove = _topSpace >= portalHeight;
271245
+ top = _fitsBelow ? rect.bottom : _fitsAbove ? rect.top - portalHeight : Math.max(0, innerHeight - portalHeight);
271246
+ left = rect.right - portalWidth;
271247
+ left = Math.max(0, Math.min(left, innerWidth - portalWidth));
271248
+ }
271249
+ setPosition(function (prev) {
271250
+ return prev.top === top && prev.left === left ? prev : {
271251
+ top: top,
271252
+ left: left
271253
+ };
271254
+ });
271255
+ return true;
271256
+ }, [anchorRef, container]);
271206
271257
 
271207
- var fitsBelow = bottomSpace >= portalHeight; // Check if the calendar portal fits below the anchor element
271208
- var fitsAbove = topSpace >= portalHeight; // Check if the calendar portal fits above the anchor element
271258
+ // Run after open + after content lays out
271259
+ React$1.useLayoutEffect(function () {
271260
+ if (!isOpen) return;
271261
+ updatePosition();
271262
+ }, [isOpen, updatePosition]);
271209
271263
 
271210
- var top = fitsBelow ? rect.bottom + scrollY : fitsAbove ? rect.top + scrollY - portalHeight : Math.max(scrollY, scrollY + rect.bottom - portalHeight); // Calculate the top position of the calendar portal
271264
+ // Reposition on resize/scroll. In modal, listen to modal scroller too.
271265
+ React$1.useEffect(function () {
271266
+ if (!isOpen || !container) return;
271267
+ var inModal = container !== document.body;
271268
+ var modalScroller = inModal ? container.querySelector('.cds--modal-content') || container : null;
271269
+ var onRescroll = function onRescroll() {
271270
+ return updatePosition();
271271
+ };
271272
+ window.addEventListener('resize', onRescroll);
271273
+ window.addEventListener('scroll', onRescroll, {
271274
+ capture: true
271275
+ });
271276
+ if (modalScroller) modalScroller.addEventListener('scroll', onRescroll, {
271277
+ capture: true
271278
+ });
271211
271279
 
271212
- var left = rect.right - portalWidth + scrollX; // Calculate the left position of the calendar portal
271213
- left = Math.max(0, Math.min(left, scrollX + innerWidth - portalWidth)); // Ensure the left position is within the viewport
271280
+ // If the calendar's size changes (months switch), keep it stuck to the anchor
271281
+ var ro = new ResizeObserver(onRescroll);
271282
+ if (portalContentRef.current) ro.observe(portalContentRef.current);
271214
271283
 
271215
- setPosition({
271216
- top: top,
271217
- left: left
271218
- }); // Update the position state
271219
- return true;
271220
- });
271221
- React$1.useEffect(function () {
271222
- if (isOpen) {
271223
- var frame = requestAnimationFrame(updatePosition); // Request an animation frame to update the position
271224
- return function () {
271225
- return cancelAnimationFrame(frame);
271226
- }; // Cancel the animation frame when the component unmounts
271227
- }
271228
- return undefined;
271229
- }, [isOpen, updatePosition]); // Depend on the isOpen prop to re-run the effect when it changes
271284
+ // eslint-disable-next-line consistent-return
271285
+ return function () {
271286
+ window.removeEventListener('resize', onRescroll);
271287
+ window.removeEventListener('scroll', onRescroll, {
271288
+ capture: true
271289
+ });
271290
+ if (modalScroller) modalScroller.removeEventListener('scroll', onRescroll, {
271291
+ capture: true
271292
+ });
271293
+ ro.disconnect();
271294
+ };
271295
+ }, [isOpen, container, updatePosition]);
271230
271296
 
271297
+ // Close on outside click
271231
271298
  React$1.useEffect(function () {
271299
+ if (!isOpen) return;
271232
271300
  var handleClickOutside = function handleClickOutside(e) {
271233
- var anchor = anchorRef.current; // Reference to the anchor element
271301
+ var anchor = anchorRef.current;
271234
271302
  if (portalContentRef.current && !portalContentRef.current.contains(e.target) && anchor && !anchor.contains(e.target)) {
271235
- onClose(); // Call the onClose callback when clicking outside the calendar portal
271303
+ onClose();
271236
271304
  }
271237
271305
  };
271238
- window.addEventListener('scroll', updatePosition, true); // Listen for scroll events and update the position
271239
- window.addEventListener('resize', updatePosition); // Listen for resize events and update the position
271240
- document.addEventListener('mousedown', handleClickOutside); // Listen for mousedown events and handle click outside the calendar portal
271241
-
271306
+ document.addEventListener('mousedown', handleClickOutside);
271307
+ // eslint-disable-next-line consistent-return
271242
271308
  return function () {
271243
- window.removeEventListener('scroll', updatePosition, true); // Remove the scroll event listener
271244
- window.removeEventListener('resize', updatePosition); // Remove the resize event listener
271245
- document.removeEventListener('mousedown', handleClickOutside); // Remove the click outside event listener
271309
+ return document.removeEventListener('mousedown', handleClickOutside);
271246
271310
  };
271247
- }, [anchorRef, onClose, updatePosition]); // Depend on the anchorRef and onClose props to re-run the effect when they change
271248
-
271249
- if (!isOpen) return null; // Return null if the calendar portal is not open
271250
-
271311
+ }, [isOpen, onClose, anchorRef]);
271312
+ if (!isOpen || !container) return null;
271313
+ var inModal = container !== document.body;
271314
+ var stylePosition = inModal ? 'absolute' : 'fixed';
271251
271315
  return /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React$1.createElement("div", {
271252
271316
  ref: portalContentRef,
271253
271317
  className: "datetime-picker-portal",
271254
271318
  style: {
271255
- position: 'absolute',
271256
- top: "".concat(position.top, "px"),
271257
- left: "".concat(position.left, "px"),
271258
- width: "".concat(portalWidth, "px"),
271319
+ position: stylePosition,
271320
+ top: position.top,
271321
+ left: position.left,
271322
+ width: portalWidth,
271259
271323
  backgroundColor: 'white',
271260
- padding: '10px',
271324
+ padding: 10,
271261
271325
  zIndex: 9999,
271262
271326
  overflowY: 'auto',
271263
271327
  overflowX: 'hidden',
271264
- maxHeight: '400px'
271328
+ maxHeight: 400
271265
271329
  }
271266
- }, children), document.body // Attach the calendar portal to the document body
271267
- );
271330
+ }, children), container);
271268
271331
  };
271269
271332
  var DateTimePicker$2 = function DateTimePicker(_ref2) {
271270
271333
  var _style$zIndex2;
@@ -271328,34 +271391,34 @@ React keys must be passed directly to JSX without using spread:
271328
271391
  customRangeKind = _useDateTimePickerRan2[0],
271329
271392
  setCustomRangeKind = _useDateTimePickerRan2[1],
271330
271393
  onCustomRangeChange = _useDateTimePickerRan2[2];
271331
- var _useState3 = React$1.useState(false),
271394
+ var _useState = React$1.useState(false),
271395
+ _useState2 = _slicedToArray$9(_useState, 2),
271396
+ isCustomRange = _useState2[0],
271397
+ setIsCustomRange = _useState2[1];
271398
+ var _useState3 = React$1.useState(null),
271332
271399
  _useState4 = _slicedToArray$9(_useState3, 2),
271333
- isCustomRange = _useState4[0],
271334
- setIsCustomRange = _useState4[1];
271400
+ selectedPreset = _useState4[0],
271401
+ setSelectedPreset = _useState4[1];
271335
271402
  var _useState5 = React$1.useState(null),
271336
271403
  _useState6 = _slicedToArray$9(_useState5, 2),
271337
- selectedPreset = _useState6[0],
271338
- setSelectedPreset = _useState6[1];
271404
+ currentValue = _useState6[0],
271405
+ setCurrentValue = _useState6[1];
271339
271406
  var _useState7 = React$1.useState(null),
271340
271407
  _useState8 = _slicedToArray$9(_useState7, 2),
271341
- currentValue = _useState8[0],
271342
- setCurrentValue = _useState8[1];
271408
+ lastAppliedValue = _useState8[0],
271409
+ setLastAppliedValue = _useState8[1];
271343
271410
  var _useState9 = React$1.useState(null),
271344
271411
  _useState10 = _slicedToArray$9(_useState9, 2),
271345
- lastAppliedValue = _useState10[0],
271346
- setLastAppliedValue = _useState10[1];
271347
- var _useState11 = React$1.useState(null),
271412
+ humanValue = _useState10[0],
271413
+ setHumanValue = _useState10[1];
271414
+ var _useState11 = React$1.useState(false),
271348
271415
  _useState12 = _slicedToArray$9(_useState11, 2),
271349
- humanValue = _useState12[0],
271350
- setHumanValue = _useState12[1];
271351
- var _useState13 = React$1.useState(false),
271416
+ defaultTimeValueUpdate = _useState12[0],
271417
+ setDefaultTimeValueUpdate = _useState12[1];
271418
+ var _useState13 = React$1.useState(invalid),
271352
271419
  _useState14 = _slicedToArray$9(_useState13, 2),
271353
- defaultTimeValueUpdate = _useState14[0],
271354
- setDefaultTimeValueUpdate = _useState14[1];
271355
- var _useState15 = React$1.useState(invalid),
271356
- _useState16 = _slicedToArray$9(_useState15, 2),
271357
- invalidState = _useState16[0],
271358
- setInvalidState = _useState16[1];
271420
+ invalidState = _useState14[0],
271421
+ setInvalidState = _useState14[1];
271359
271422
  var relativeSelect = React$1.useRef(null);
271360
271423
  var containerRef = React$1.useRef();
271361
271424
  var dropdownRef = React$1.useRef();
@@ -271396,34 +271459,34 @@ React keys must be passed directly to JSX without using spread:
271396
271459
  onNavigateRadioButton = _useDateTimePickerKey.onNavigateRadioButton,
271397
271460
  onNavigatePresets = _useDateTimePickerKey.onNavigatePresets,
271398
271461
  onFieldClick = _useDateTimePickerKey.onFieldClick;
271462
+ var _useState15 = React$1.useState(null),
271463
+ _useState16 = _slicedToArray$9(_useState15, 2),
271464
+ singleDateValue = _useState16[0],
271465
+ setSingleDateValue = _useState16[1];
271399
271466
  var _useState17 = React$1.useState(null),
271400
271467
  _useState18 = _slicedToArray$9(_useState17, 2),
271401
- singleDateValue = _useState18[0],
271402
- setSingleDateValue = _useState18[1];
271468
+ singleTimeValue = _useState18[0],
271469
+ setSingleTimeValue = _useState18[1];
271403
271470
  var _useState19 = React$1.useState(null),
271404
271471
  _useState20 = _slicedToArray$9(_useState19, 2),
271405
- singleTimeValue = _useState20[0],
271406
- setSingleTimeValue = _useState20[1];
271472
+ rangeStartTimeValue = _useState20[0],
271473
+ setRangeStartTimeValue = _useState20[1];
271407
271474
  var _useState21 = React$1.useState(null),
271408
271475
  _useState22 = _slicedToArray$9(_useState21, 2),
271409
- rangeStartTimeValue = _useState22[0],
271410
- setRangeStartTimeValue = _useState22[1];
271411
- var _useState23 = React$1.useState(null),
271476
+ rangeEndTimeValue = _useState22[0],
271477
+ setRangeEndTimeValue = _useState22[1];
271478
+ var _useState23 = React$1.useState(false),
271412
271479
  _useState24 = _slicedToArray$9(_useState23, 2),
271413
- rangeEndTimeValue = _useState24[0],
271414
- setRangeEndTimeValue = _useState24[1];
271480
+ invalidRangeStartTime = _useState24[0],
271481
+ setInvalidRangeStartTime = _useState24[1];
271415
271482
  var _useState25 = React$1.useState(false),
271416
271483
  _useState26 = _slicedToArray$9(_useState25, 2),
271417
- invalidRangeStartTime = _useState26[0],
271418
- setInvalidRangeStartTime = _useState26[1];
271484
+ invalidRangeEndTime = _useState26[0],
271485
+ setInvalidRangeEndTime = _useState26[1];
271419
271486
  var _useState27 = React$1.useState(false),
271420
271487
  _useState28 = _slicedToArray$9(_useState27, 2),
271421
- invalidRangeEndTime = _useState28[0],
271422
- setInvalidRangeEndTime = _useState28[1];
271423
- var _useState29 = React$1.useState(false),
271424
- _useState30 = _slicedToArray$9(_useState29, 2),
271425
- invalidRangeStartDate = _useState30[0],
271426
- setInvalidRangeStartDate = _useState30[1];
271488
+ invalidRangeStartDate = _useState28[0],
271489
+ setInvalidRangeStartDate = _useState28[1];
271427
271490
  var dateTimePickerBaseValue = {
271428
271491
  kind: '',
271429
271492
  preset: {
@@ -276541,6 +276604,7 @@ React keys must be passed directly to JSX without using spread:
276541
276604
  * @returns ReactElement
276542
276605
  */
276543
276606
  var renderLinkMenu = function renderLinkMenu(link, index) {
276607
+ var _link$metaData;
276544
276608
  var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
276545
276609
  var searchValue = arguments.length > 3 ? arguments[3] : undefined;
276546
276610
  var isFiltering = searchValue !== undefined;
@@ -276564,7 +276628,7 @@ React keys must be passed directly to JSX without using spread:
276564
276628
  "data-testid": "".concat(testId, "-menu-item-").concat(index)
276565
276629
  }, childLink.metaData), content);
276566
276630
  });
276567
- return /*#__PURE__*/React$1.createElement(FilterableSideNavMenu$1, {
276631
+ return /*#__PURE__*/React$1.createElement(FilterableSideNavMenu$1, _extends$3({
276568
276632
  isFiltering: isFiltering,
276569
276633
  isActive: parentActive,
276570
276634
  renderIcon: link.icon,
@@ -276573,7 +276637,7 @@ React keys must be passed directly to JSX without using spread:
276573
276637
  title: link.linkContent,
276574
276638
  testId: "".concat(testId, "-menu-").concat(index),
276575
276639
  className: "".concat(iotPrefix$14, "--side-nav__item--depth-").concat(level)
276576
- }, children);
276640
+ }, (_link$metaData = link.metaData) !== null && _link$metaData !== void 0 ? _link$metaData : {}), children);
276577
276641
  };
276578
276642
  var renderLinks = function renderLinks(linkConfigurations, searchValue) {
276579
276643
  return linkConfigurations.map(function (link, index) {