@carbon/react 1.69.0-rc.0 → 1.70.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +864 -864
  2. package/es/components/Checkbox/Checkbox.js +1 -1
  3. package/es/components/ContextMenu/index.d.ts +8 -0
  4. package/es/components/ContextMenu/useContextMenu.d.ts +21 -0
  5. package/es/components/ContextMenu/useContextMenu.js +9 -8
  6. package/es/components/DataTable/DataTable.d.ts +3 -2
  7. package/es/components/Dropdown/Dropdown.d.ts +2 -2
  8. package/es/components/FeatureFlags/index.d.ts +3 -1
  9. package/es/components/FeatureFlags/index.js +5 -2
  10. package/es/components/FluidComboBox/FluidComboBox.Skeleton.js +5 -5
  11. package/es/components/FluidDropdown/FluidDropdown.Skeleton.d.ts +15 -0
  12. package/es/components/FluidDropdown/FluidDropdown.Skeleton.js +6 -8
  13. package/es/components/FluidDropdown/FluidDropdown.d.ts +101 -0
  14. package/es/components/FluidDropdown/FluidDropdown.js +1 -2
  15. package/es/components/FluidDropdown/index.d.ts +13 -0
  16. package/es/components/FluidMultiSelect/FluidMultiSelect.Skeleton.js +5 -5
  17. package/es/components/FluidSelect/FluidSelect.Skeleton.js +5 -5
  18. package/es/components/FluidTextArea/FluidTextArea.Skeleton.d.ts +2 -13
  19. package/es/components/FluidTextArea/FluidTextArea.Skeleton.js +22 -5
  20. package/es/components/Grid/CSSGrid.js +8 -1
  21. package/es/components/Grid/Grid.js +4 -0
  22. package/es/components/ListBox/next/ListBoxSelection.d.ts +9 -1
  23. package/es/components/ListBox/next/ListBoxSelection.js +12 -5
  24. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
  25. package/es/components/MultiSelect/FilterableMultiSelect.js +32 -6
  26. package/es/components/Notification/Notification.js +2 -6
  27. package/es/components/NumberInput/NumberInput.Skeleton.d.ts +9 -1
  28. package/es/components/NumberInput/NumberInput.Skeleton.js +7 -2
  29. package/es/components/Popover/index.js +2 -0
  30. package/es/components/Tabs/Tabs.js +47 -21
  31. package/es/components/Tag/SelectableTag.d.ts +17 -1
  32. package/es/components/Tag/SelectableTag.js +21 -13
  33. package/es/components/UIShell/HeaderPanel.js +1 -1
  34. package/es/feature-flags.js +2 -1
  35. package/es/index.js +3 -3
  36. package/lib/components/Checkbox/Checkbox.js +1 -1
  37. package/lib/components/ContextMenu/index.d.ts +8 -0
  38. package/lib/components/ContextMenu/useContextMenu.d.ts +21 -0
  39. package/lib/components/ContextMenu/useContextMenu.js +9 -8
  40. package/lib/components/DataTable/DataTable.d.ts +3 -2
  41. package/lib/components/Dropdown/Dropdown.d.ts +2 -2
  42. package/lib/components/FeatureFlags/index.d.ts +3 -1
  43. package/lib/components/FeatureFlags/index.js +5 -2
  44. package/lib/components/FluidComboBox/FluidComboBox.Skeleton.js +5 -5
  45. package/lib/components/FluidDropdown/FluidDropdown.Skeleton.d.ts +15 -0
  46. package/lib/components/FluidDropdown/FluidDropdown.Skeleton.js +6 -8
  47. package/lib/components/FluidDropdown/FluidDropdown.d.ts +101 -0
  48. package/lib/components/FluidDropdown/FluidDropdown.js +1 -2
  49. package/lib/components/FluidDropdown/index.d.ts +13 -0
  50. package/lib/components/FluidMultiSelect/FluidMultiSelect.Skeleton.js +5 -5
  51. package/lib/components/FluidSelect/FluidSelect.Skeleton.js +5 -5
  52. package/lib/components/FluidTextArea/FluidTextArea.Skeleton.d.ts +2 -13
  53. package/lib/components/FluidTextArea/FluidTextArea.Skeleton.js +24 -5
  54. package/lib/components/Grid/CSSGrid.js +8 -1
  55. package/lib/components/Grid/Grid.js +4 -0
  56. package/lib/components/ListBox/next/ListBoxSelection.d.ts +9 -1
  57. package/lib/components/ListBox/next/ListBoxSelection.js +12 -5
  58. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
  59. package/lib/components/MultiSelect/FilterableMultiSelect.js +32 -6
  60. package/lib/components/Notification/Notification.js +2 -6
  61. package/lib/components/NumberInput/NumberInput.Skeleton.d.ts +9 -1
  62. package/lib/components/NumberInput/NumberInput.Skeleton.js +7 -2
  63. package/lib/components/Popover/index.js +2 -0
  64. package/lib/components/Tabs/Tabs.js +47 -21
  65. package/lib/components/Tag/SelectableTag.d.ts +17 -1
  66. package/lib/components/Tag/SelectableTag.js +21 -13
  67. package/lib/components/UIShell/HeaderPanel.js +1 -1
  68. package/lib/feature-flags.js +2 -1
  69. package/lib/index.js +6 -6
  70. package/package.json +12 -10
  71. package/telemetry.yml +765 -710
@@ -90,6 +90,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
90
90
  onChange,
91
91
  onMenuChange,
92
92
  placeholder,
93
+ readOnly,
93
94
  titleText,
94
95
  type,
95
96
  selectionFeedback = 'top-after-reopen',
@@ -232,9 +233,11 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
232
233
  }
233
234
  };
234
235
  function handleMenuChange(forceIsOpen) {
235
- const nextIsOpen = forceIsOpen ?? !isOpen;
236
- setIsOpen(nextIsOpen);
237
- validateHighlightFocus();
236
+ if (!readOnly) {
237
+ const nextIsOpen = forceIsOpen ?? !isOpen;
238
+ setIsOpen(nextIsOpen);
239
+ validateHighlightFocus();
240
+ }
238
241
  }
239
242
  useEffect(() => {
240
243
  onMenuChange?.(isOpen);
@@ -423,7 +426,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
423
426
  [`${prefix}--multi-select--open`]: isOpen,
424
427
  [`${prefix}--multi-select--inline`]: inline,
425
428
  [`${prefix}--multi-select--selected`]: controlledSelectedItems?.length > 0,
426
- [`${prefix}--multi-select--filterable--input-focused`]: inputFocused
429
+ [`${prefix}--multi-select--filterable--input-focused`]: inputFocused,
430
+ [`${prefix}--multi-select--readonly`]: readOnly
427
431
  });
428
432
  const labelProps = getLabelProps();
429
433
  const buttonProps = getToggleButtonProps({
@@ -510,6 +514,24 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
510
514
  setIsFocused(evt?.type === 'focus' ? true : false);
511
515
  }
512
516
  };
517
+ const mergedRef = mergeRefs(textInput, inputProps.ref);
518
+ const readOnlyEventHandlers = readOnly ? {
519
+ onClick: evt => {
520
+ // NOTE: does not prevent click
521
+ evt.preventDefault();
522
+ // focus on the element as per readonly input behavior
523
+ if (mergedRef.current !== undefined) {
524
+ mergedRef.current.focus();
525
+ }
526
+ },
527
+ onKeyDown: evt => {
528
+ const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
529
+ // This prevents the select from opening for the above keys
530
+ if (selectAccessKeys.includes(evt.key)) {
531
+ evt.preventDefault();
532
+ }
533
+ }
534
+ } : {};
513
535
  const clearSelectionContent = controlledSelectedItems.length > 0 ? /*#__PURE__*/React__default.createElement("span", {
514
536
  className: `${prefix}--visually-hidden`
515
537
  }, clearSelectionDescription, " ", controlledSelectedItems.length, ",", clearSelectionText) : /*#__PURE__*/React__default.createElement("span", {
@@ -533,12 +555,13 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
533
555
  invalidText: invalidText,
534
556
  warn: warn,
535
557
  warnText: warnText,
536
- isOpen: isOpen,
558
+ isOpen: !readOnly && isOpen,
537
559
  size: size$1
538
560
  }, /*#__PURE__*/React__default.createElement("div", {
539
561
  className: `${prefix}--list-box__field`,
540
562
  ref: autoAlign ? refs.setReference : null
541
563
  }, controlledSelectedItems.length > 0 && /*#__PURE__*/React__default.createElement(ListBoxSelection, {
564
+ readOnly: readOnly,
542
565
  clearSelection: () => {
543
566
  clearSelection();
544
567
  if (textInput.current) {
@@ -551,7 +574,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
551
574
  }), /*#__PURE__*/React__default.createElement("input", _extends({
552
575
  className: inputClasses
553
576
  }, inputProps, {
554
- ref: mergeRefs(textInput, inputProps.ref)
577
+ ref: mergedRef
578
+ }, readOnlyEventHandlers, {
579
+ readOnly: readOnly
555
580
  })), invalid && /*#__PURE__*/React__default.createElement(WarningFilled, {
556
581
  className: `${prefix}--list-box__invalid-icon`
557
582
  }), showWarning && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
@@ -560,6 +585,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
560
585
  clearSelection: clearInputValue,
561
586
  disabled: disabled,
562
587
  translateWithId: translateWithId,
588
+ readOnly: readOnly,
563
589
  onMouseUp: event => {
564
590
  // If we do not stop this event from propagating,
565
591
  // it seems like Downshift takes our event and
@@ -278,9 +278,7 @@ function ToastNotification(_ref4) {
278
278
  }, caption), children), !hideCloseButton && /*#__PURE__*/React__default.createElement(NotificationButton, {
279
279
  notificationType: "toast",
280
280
  onClick: handleCloseButtonClick,
281
- "aria-hidden": "true",
282
- "aria-label": deprecatedAriaLabel || ariaLabel,
283
- tabIndex: -1
281
+ "aria-label": deprecatedAriaLabel || ariaLabel
284
282
  }));
285
283
  }
286
284
  ToastNotification.propTypes = {
@@ -415,9 +413,7 @@ function InlineNotification(_ref5) {
415
413
  }, subtitle), children)), !hideCloseButton && /*#__PURE__*/React__default.createElement(NotificationButton, {
416
414
  notificationType: "inline",
417
415
  onClick: handleCloseButtonClick,
418
- "aria-hidden": "true",
419
- "aria-label": ariaLabel,
420
- tabIndex: -1
416
+ "aria-label": ariaLabel
421
417
  }));
422
418
  }
423
419
  InlineNotification.propTypes = {
@@ -15,8 +15,12 @@ export interface NumberInputSkeletonProps extends HTMLAttributes<HTMLDivElement>
15
15
  * Specify whether the label should be hidden, or not
16
16
  */
17
17
  hideLabel?: boolean;
18
+ /**
19
+ * Specify the size of the Number Input.
20
+ */
21
+ size?: 'sm' | 'md' | 'lg';
18
22
  }
19
- declare function NumberInputSkeleton({ hideLabel, className, ...rest }: NumberInputSkeletonProps): import("react/jsx-runtime").JSX.Element;
23
+ declare function NumberInputSkeleton({ hideLabel, className, size, ...rest }: NumberInputSkeletonProps): import("react/jsx-runtime").JSX.Element;
20
24
  declare namespace NumberInputSkeleton {
21
25
  var propTypes: {
22
26
  /**
@@ -27,6 +31,10 @@ declare namespace NumberInputSkeleton {
27
31
  * Specify whether the label should be hidden, or not
28
32
  */
29
33
  hideLabel: PropTypes.Requireable<boolean>;
34
+ /**
35
+ * Specify the size of the Number Input.
36
+ */
37
+ size: PropTypes.Requireable<string>;
30
38
  };
31
39
  }
32
40
  export default NumberInputSkeleton;
@@ -15,6 +15,7 @@ function NumberInputSkeleton(_ref) {
15
15
  let {
16
16
  hideLabel,
17
17
  className,
18
+ size = 'md',
18
19
  ...rest
19
20
  } = _ref;
20
21
  const prefix = usePrefix();
@@ -23,7 +24,7 @@ function NumberInputSkeleton(_ref) {
23
24
  }, rest), !hideLabel && /*#__PURE__*/React__default.createElement("span", {
24
25
  className: `${prefix}--label ${prefix}--skeleton`
25
26
  }), /*#__PURE__*/React__default.createElement("div", {
26
- className: `${prefix}--number ${prefix}--skeleton`
27
+ className: `${prefix}--number ${prefix}--skeleton ${prefix}--number--${size}`
27
28
  }));
28
29
  }
29
30
  NumberInputSkeleton.propTypes = {
@@ -34,7 +35,11 @@ NumberInputSkeleton.propTypes = {
34
35
  /**
35
36
  * Specify whether the label should be hidden, or not
36
37
  */
37
- hideLabel: PropTypes.bool
38
+ hideLabel: PropTypes.bool,
39
+ /**
40
+ * Specify the size of the Number Input.
41
+ */
42
+ size: PropTypes.oneOf(['sm', 'md', 'lg'])
38
43
  };
39
44
 
40
45
  export { NumberInputSkeleton as default };
@@ -128,6 +128,8 @@ const Popover = /*#__PURE__*/React__default.forwardRef(function PopoverRenderFun
128
128
  strategy: 'fixed',
129
129
  // Middleware order matters, arrow should be last
130
130
  middleware: [offset(!isTabTip ? popoverDimensions?.current?.offset : 0), autoAlign && flip({
131
+ fallbackPlacements: align.includes('bottom') ? ['bottom', 'bottom-start', 'bottom-end', 'right', 'right-start', 'right-end', 'left', 'left-start', 'left-end', 'top', 'top-start', 'top-end'] : ['top', 'top-start', 'top-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end'],
132
+ fallbackStrategy: 'initialPlacement',
131
133
  fallbackAxisSideDirection: 'start'
132
134
  }), arrow({
133
135
  element: caretRef
@@ -322,8 +322,8 @@ function TabList(_ref4) {
322
322
  function onKeyDown(event) {
323
323
  if (matches(event, [ArrowRight, ArrowLeft, Home, End])) {
324
324
  event.preventDefault();
325
- const filtredTabs = tabs.current.filter(tab => tab !== null);
326
- const activeTabs = filtredTabs.filter(tab => !tab.disabled);
325
+ const filteredTabs = tabs.current.filter(tab => tab !== null);
326
+ const activeTabs = filteredTabs.filter(tab => !tab.disabled);
327
327
  const currentIndex = activeTabs.indexOf(tabs.current[activation === 'automatic' ? selectedIndex : activeIndex]);
328
328
  const nextIndex = tabs.current.indexOf(activeTabs[getNextIndex(event, activeTabs.length, currentIndex)]);
329
329
  if (activation === 'automatic') {
@@ -334,6 +334,18 @@ function TabList(_ref4) {
334
334
  tabs.current[nextIndex]?.focus();
335
335
  }
336
336
  }
337
+ function handleBlur(_ref5) {
338
+ let {
339
+ relatedTarget: currentActiveNode
340
+ } = _ref5;
341
+ if (ref.current?.contains(currentActiveNode)) {
342
+ return;
343
+ }
344
+ // reset active index to selected tab index for manual activation
345
+ if (activation === 'manual') {
346
+ setActiveIndex(selectedIndex);
347
+ }
348
+ }
337
349
  useEffectOnce(() => {
338
350
  const tab = tabs.current[selectedIndex];
339
351
  if (scrollIntoView && tab) {
@@ -419,10 +431,10 @@ function TabList(_ref4) {
419
431
  }
420
432
  }, [activation, activeIndex, selectedIndex, isScrollable, children]);
421
433
  usePressable(previousButton, {
422
- onPress(_ref5) {
434
+ onPress(_ref6) {
423
435
  let {
424
436
  longPress
425
- } = _ref5;
437
+ } = _ref6;
426
438
  if (!longPress && ref.current) {
427
439
  setScrollLeft(Math.max(scrollLeft - ref.current.scrollWidth / tabs.current.length * 1.5, 0));
428
440
  }
@@ -432,10 +444,10 @@ function TabList(_ref4) {
432
444
  }
433
445
  });
434
446
  usePressable(nextButton, {
435
- onPress(_ref6) {
447
+ onPress(_ref7) {
436
448
  let {
437
449
  longPress
438
- } = _ref6;
450
+ } = _ref7;
439
451
  if (!longPress && ref.current) {
440
452
  setScrollLeft(Math.min(scrollLeft + ref.current.scrollWidth / tabs.current.length * 1.5, ref.current.scrollWidth - ref.current.clientWidth));
441
453
  }
@@ -459,7 +471,8 @@ function TabList(_ref4) {
459
471
  role: "tablist",
460
472
  className: `${prefix}--tab--list`,
461
473
  onScroll: debouncedOnScroll,
462
- onKeyDown: onKeyDown
474
+ onKeyDown: onKeyDown,
475
+ onBlur: handleBlur
463
476
  }), React__default.Children.map(children, (child, index) => {
464
477
  return !isElement(child) ? null : /*#__PURE__*/React__default.createElement(TabContext.Provider, {
465
478
  value: {
@@ -544,7 +557,7 @@ TabList.propTypes = {
544
557
 
545
558
  // type TabElement = HTMLElement & { disabled?: boolean };
546
559
 
547
- function TabListVertical(_ref7) {
560
+ function TabListVertical(_ref8) {
548
561
  let {
549
562
  activation = 'automatic',
550
563
  'aria-label': label,
@@ -552,7 +565,7 @@ function TabListVertical(_ref7) {
552
565
  className: customClassName,
553
566
  scrollIntoView,
554
567
  ...rest
555
- } = _ref7;
568
+ } = _ref8;
556
569
  const {
557
570
  activeIndex,
558
571
  selectedIndex,
@@ -569,8 +582,8 @@ function TabListVertical(_ref7) {
569
582
  function onKeyDown(event) {
570
583
  if (matches(event, [ArrowDown, ArrowUp, Home, End])) {
571
584
  event.preventDefault();
572
- const filtredTabs = tabs.current.filter(tab => tab !== null);
573
- const activeTabs = filtredTabs.filter(tab => !tab.disabled);
585
+ const filteredTabs = tabs.current.filter(tab => tab !== null);
586
+ const activeTabs = filteredTabs.filter(tab => !tab.disabled);
574
587
  const currentIndex = activeTabs.indexOf(tabs.current[activation === 'automatic' ? selectedIndex : activeIndex]);
575
588
  const nextIndex = tabs.current.indexOf(activeTabs[getNextIndexVertical(event, activeTabs.length, currentIndex)]);
576
589
  if (activation === 'automatic') {
@@ -581,6 +594,18 @@ function TabListVertical(_ref7) {
581
594
  tabs.current[nextIndex]?.focus();
582
595
  }
583
596
  }
597
+ function handleBlur(_ref9) {
598
+ let {
599
+ relatedTarget: currentActiveNode
600
+ } = _ref9;
601
+ if (ref.current?.contains(currentActiveNode)) {
602
+ return;
603
+ }
604
+ // reset active index to selected tab index for manual activation
605
+ if (activation === 'manual') {
606
+ setActiveIndex(selectedIndex);
607
+ }
608
+ }
584
609
  useEffectOnce(() => {
585
610
  if (tabs.current[selectedIndex]?.disabled) {
586
611
  const activeTabs = tabs.current.filter(tab => {
@@ -647,7 +672,8 @@ function TabListVertical(_ref7) {
647
672
  ref: ref,
648
673
  role: "tablist",
649
674
  className: `${prefix}--tab--list`,
650
- onKeyDown: onKeyDown
675
+ onKeyDown: onKeyDown,
676
+ onBlur: handleBlur
651
677
  }), React__default.Children.map(children, (child, index) => {
652
678
  return !isElement(child) ? null : /*#__PURE__*/React__default.createElement(TabContext.Provider, {
653
679
  value: {
@@ -730,7 +756,7 @@ function createLongPressBehavior(ref, direction, setScrollLeft) {
730
756
  * Tab
731
757
  */
732
758
 
733
- const Tab = /*#__PURE__*/forwardRef(function Tab(_ref8, forwardRef) {
759
+ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref10, forwardRef) {
734
760
  let {
735
761
  as = 'button',
736
762
  children,
@@ -741,7 +767,7 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref8, forwardRef) {
741
767
  secondaryLabel,
742
768
  renderIcon: Icon,
743
769
  ...rest
744
- } = _ref8;
770
+ } = _ref10;
745
771
  const prefix = usePrefix();
746
772
  const {
747
773
  selectedIndex,
@@ -983,7 +1009,7 @@ Tab.propTypes = {
983
1009
  * IconTab
984
1010
  */
985
1011
 
986
- const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref9, ref) {
1012
+ const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref11, ref) {
987
1013
  let {
988
1014
  children,
989
1015
  className: customClassName,
@@ -992,7 +1018,7 @@ const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref9, r
992
1018
  leaveDelayMs,
993
1019
  label,
994
1020
  ...rest
995
- } = _ref9;
1021
+ } = _ref11;
996
1022
  const prefix = usePrefix();
997
1023
  const classNames = cx(`${prefix}--tabs__nav-item--icon-only`, customClassName);
998
1024
  return /*#__PURE__*/React__default.createElement(Tooltip, {
@@ -1041,12 +1067,12 @@ IconTab.propTypes = {
1041
1067
  * TabPanel
1042
1068
  */
1043
1069
 
1044
- const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref10, forwardRef) {
1070
+ const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref12, forwardRef) {
1045
1071
  let {
1046
1072
  children,
1047
1073
  className: customClassName,
1048
1074
  ...rest
1049
- } = _ref10;
1075
+ } = _ref12;
1050
1076
  const prefix = usePrefix();
1051
1077
  const panel = useRef(null);
1052
1078
  const ref = useMergedRefs([forwardRef, panel]);
@@ -1121,10 +1147,10 @@ TabPanel.propTypes = {
1121
1147
  * TabPanels
1122
1148
  */
1123
1149
 
1124
- function TabPanels(_ref11) {
1150
+ function TabPanels(_ref13) {
1125
1151
  let {
1126
1152
  children
1127
- } = _ref11;
1153
+ } = _ref13;
1128
1154
  const prefix = usePrefix();
1129
1155
  const refs = useRef([]);
1130
1156
  const hiddenStates = useRef([]);
@@ -1158,7 +1184,7 @@ function TabPanels(_ref11) {
1158
1184
  }
1159
1185
  });
1160
1186
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, React__default.Children.map(children, (child, index) => {
1161
- return /*#__PURE__*/React__default.createElement(TabPanelContext.Provider, {
1187
+ return !isElement(child) ? null : /*#__PURE__*/React__default.createElement(TabPanelContext.Provider, {
1162
1188
  value: index
1163
1189
  }, /*#__PURE__*/React__default.cloneElement(child, {
1164
1190
  ref: element => {
@@ -26,6 +26,14 @@ export interface SelectableTagBaseProps {
26
26
  * Can be a React component class
27
27
  */
28
28
  renderIcon?: React.ElementType;
29
+ /**
30
+ * Provide an optional hook that is called when selected is changed
31
+ */
32
+ onChange?: (selected: boolean) => void;
33
+ /**
34
+ * Provide an optional function to be called when the tag is clicked.
35
+ */
36
+ onClick?: (e: Event) => void;
29
37
  /**
30
38
  * Specify the state of the selectable tag.
31
39
  */
@@ -42,7 +50,7 @@ export interface SelectableTagBaseProps {
42
50
  }
43
51
  export type SelectableTagProps<T extends React.ElementType> = PolymorphicProps<T, SelectableTagBaseProps>;
44
52
  declare const SelectableTag: {
45
- <T extends React.ElementType<any, keyof React.JSX.IntrinsicElements>>({ className, disabled, id, renderIcon, selected, size, text, ...other }: SelectableTagProps<T>): import("react/jsx-runtime").JSX.Element;
53
+ <T extends React.ElementType<any, keyof React.JSX.IntrinsicElements>>({ className, disabled, id, renderIcon, onChange, onClick, selected, size, text, ...other }: SelectableTagProps<T>): import("react/jsx-runtime").JSX.Element;
46
54
  propTypes: {
47
55
  /**
48
56
  * Provide a custom className that is applied to the containing <span>
@@ -61,6 +69,14 @@ declare const SelectableTag: {
61
69
  * Can be a React component class
62
70
  */
63
71
  renderIcon: PropTypes.Requireable<object>;
72
+ /**
73
+ * Provide an optional hook that is called when selected is changed
74
+ */
75
+ onChange: PropTypes.Requireable<(...args: any[]) => any>;
76
+ /**
77
+ * Provide an optional function to be called when the tag is clicked.
78
+ */
79
+ onClick: PropTypes.Requireable<(...args: any[]) => any>;
64
80
  /**
65
81
  * Specify the state of the selectable tag.
66
82
  */
@@ -24,6 +24,8 @@ const SelectableTag = _ref => {
24
24
  disabled,
25
25
  id,
26
26
  renderIcon,
27
+ onChange,
28
+ onClick,
27
29
  selected = false,
28
30
  size,
29
31
  text,
@@ -42,13 +44,11 @@ const SelectableTag = _ref => {
42
44
  setIsEllipsisApplied(isEllipsisActive(newElement));
43
45
  }, [prefix, tagRef]);
44
46
  const tooltipClasses = cx(`${prefix}--icon-tooltip`, `${prefix}--tag-label-tooltip`);
45
-
46
- // Removing onClick from the spread operator
47
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
- const {
49
- onClick,
50
- ...otherProps
51
- } = other;
47
+ const handleClick = e => {
48
+ setSelectedTag(!selectedTag);
49
+ onChange?.(!selectedTag);
50
+ onClick?.(e);
51
+ };
52
52
  if (isEllipsisApplied) {
53
53
  return /*#__PURE__*/React__default.createElement(Tooltip, {
54
54
  label: text,
@@ -57,29 +57,29 @@ const SelectableTag = _ref => {
57
57
  leaveDelayMs: 0,
58
58
  onMouseEnter: () => false
59
59
  }, /*#__PURE__*/React__default.createElement(Tag, _extends({
60
- "aria-pressed": selectedTag,
60
+ "aria-pressed": selectedTag !== false,
61
61
  ref: tagRef,
62
62
  size: size,
63
63
  renderIcon: renderIcon,
64
64
  disabled: disabled,
65
65
  className: tagClasses,
66
66
  id: tagId,
67
- onClick: () => setSelectedTag(!selectedTag)
68
- }, otherProps), /*#__PURE__*/React__default.createElement(Text, {
67
+ onClick: handleClick
68
+ }, other), /*#__PURE__*/React__default.createElement(Text, {
69
69
  title: text,
70
70
  className: `${prefix}--tag__label`
71
71
  }, text)));
72
72
  }
73
73
  return /*#__PURE__*/React__default.createElement(Tag, _extends({
74
- "aria-pressed": selectedTag,
74
+ "aria-pressed": selectedTag !== false,
75
75
  ref: tagRef,
76
76
  size: size,
77
77
  renderIcon: renderIcon,
78
78
  disabled: disabled,
79
79
  className: tagClasses,
80
80
  id: tagId,
81
- onClick: () => setSelectedTag(!selectedTag)
82
- }, otherProps), /*#__PURE__*/React__default.createElement(Text, {
81
+ onClick: handleClick
82
+ }, other), /*#__PURE__*/React__default.createElement(Text, {
83
83
  title: text,
84
84
  className: `${prefix}--tag__label`
85
85
  }, text));
@@ -102,6 +102,14 @@ SelectableTag.propTypes = {
102
102
  * Can be a React component class
103
103
  */
104
104
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
105
+ /**
106
+ * Provide an optional hook that is called when selected is changed
107
+ */
108
+ onChange: PropTypes.func,
109
+ /**
110
+ * Provide an optional function to be called when the tag is clicked.
111
+ */
112
+ onClick: PropTypes.func,
105
113
  /**
106
114
  * Specify the state of the selectable tag.
107
115
  */
@@ -62,7 +62,7 @@ const HeaderPanel = /*#__PURE__*/React__default.forwardRef(function HeaderPanel(
62
62
  const focusedElement = document.activeElement;
63
63
  setLastClickedElement(focusedElement);
64
64
  const childJsxElement = children;
65
- if (childJsxElement.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
65
+ if (childJsxElement?.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
66
66
  setExpandedState(false);
67
67
  onHeaderPanelFocus();
68
68
  }
@@ -13,5 +13,6 @@ FeatureFlags.merge({
13
13
  'enable-v11-release': true,
14
14
  'enable-experimental-tile-contrast': false,
15
15
  'enable-v12-tile-radio-icons': false,
16
- 'enable-v12-structured-list-visible-icons': false
16
+ 'enable-v12-structured-list-visible-icons': false,
17
+ 'enable-v12-dynamic-floating-styles': false
17
18
  });
package/es/index.js CHANGED
@@ -29,6 +29,7 @@ export { ModalHeader } from './components/ComposedModal/ModalHeader.js';
29
29
  export { ModalFooter } from './components/ComposedModal/ModalFooter.js';
30
30
  import './components/ContainedList/index.js';
31
31
  export { default as ContentSwitcher } from './components/ContentSwitcher/index.js';
32
+ export { default as useContextMenu } from './components/ContextMenu/useContextMenu.js';
32
33
  export { default as Copy } from './components/Copy/Copy.js';
33
34
  export { default as CopyButton } from './components/CopyButton/CopyButton.js';
34
35
  export { default as DangerButton } from './components/DangerButton/DangerButton.js';
@@ -165,6 +166,8 @@ export { default as unstable__FluidComboBoxSkeleton } from './components/FluidCo
165
166
  export { default as unstable__FluidDatePicker } from './components/FluidDatePicker/FluidDatePicker.js';
166
167
  export { default as unstable__FluidDatePickerSkeleton } from './components/FluidDatePicker/FluidDatePicker.Skeleton.js';
167
168
  export { default as unstable__FluidDatePickerInput } from './components/FluidDatePickerInput/FluidDatePickerInput.js';
169
+ export { default as unstable__FluidDropdown } from './components/FluidDropdown/FluidDropdown.js';
170
+ export { default as unstable__FluidDropdownSkeleton } from './components/FluidDropdown/FluidDropdown.Skeleton.js';
168
171
  export { default as unstable__FluidMultiSelect } from './components/FluidMultiSelect/FluidMultiSelect.js';
169
172
  export { default as unstable__FluidMultiSelectSkeleton } from './components/FluidMultiSelect/FluidMultiSelect.Skeleton.js';
170
173
  export { default as unstable__FluidSelect } from './components/FluidSelect/FluidSelect.js';
@@ -202,12 +205,9 @@ export { default as unstable_PageSelector } from './components/Pagination/experi
202
205
  export { default as unstable_Pagination } from './components/Pagination/experimental/Pagination.js';
203
206
  export { default as ContainedListItem } from './components/ContainedList/ContainedListItem/ContainedListItem.js';
204
207
  export { default as ContainedList } from './components/ContainedList/ContainedList.js';
205
- export { default as useContextMenu } from './components/ContextMenu/useContextMenu.js';
206
208
  export { default as SliderSkeleton } from './components/Slider/Slider.Skeleton.js';
207
209
  export { default as TextInputSkeleton } from './components/TextInput/TextInput.Skeleton.js';
208
210
  export { default as TextInput } from './components/TextInput/TextInput.js';
209
- export { default as unstable__FluidDropdown } from './components/FluidDropdown/FluidDropdown.js';
210
- export { default as unstable__FluidDropdownSkeleton } from './components/FluidDropdown/FluidDropdown.Skeleton.js';
211
211
  export { LayoutDirection as unstable_LayoutDirection } from './components/LayoutDirection/LayoutDirection.js';
212
212
  export { useLayoutDirection as unstable_useLayoutDirection } from './components/LayoutDirection/useLayoutDirection.js';
213
213
  export { Text as unstable_Text } from './components/Text/Text.js';
@@ -91,7 +91,7 @@ const Checkbox = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
91
91
  }
92
92
  if (typeof ref === 'function') {
93
93
  ref(el);
94
- } else if (ref && Object(ref) === ref) {
94
+ } else if (ref && 'current' in ref) {
95
95
  ref.current = el;
96
96
  }
97
97
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright IBM Corp. 2020, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import useContextMenu from './useContextMenu';
8
+ export { useContextMenu };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright IBM Corp. 2020, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ /// <reference types="react" />
8
+ type TriggerType = Element | Document | Window | React.RefObject<Element>;
9
+ interface ContextMenuProps {
10
+ open: boolean;
11
+ x: number;
12
+ y: number;
13
+ onClose: () => void;
14
+ mode: string;
15
+ }
16
+ /**
17
+ * @param {TriggerType} [trigger=document] The element or ref which should trigger the Menu on right-click
18
+ * @returns {ContextMenuProps} Props object to pass onto Menu component
19
+ */
20
+ declare function useContextMenu(trigger?: TriggerType): ContextMenuProps;
21
+ export default useContextMenu;
@@ -12,8 +12,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
12
12
  var React = require('react');
13
13
 
14
14
  /**
15
- * @param {Element|Document|Window|object} [trigger=document] The element or ref which should trigger the Menu on right-click
16
- * @returns {object} Props object to pass onto Menu component
15
+ * @param {TriggerType} [trigger=document] The element or ref which should trigger the Menu on right-click
16
+ * @returns {ContextMenuProps} Props object to pass onto Menu component
17
17
  */
18
18
  function useContextMenu() {
19
19
  let trigger = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
@@ -22,8 +22,8 @@ function useContextMenu() {
22
22
  function openContextMenu(e) {
23
23
  e.preventDefault();
24
24
  const {
25
- x,
26
- y
25
+ clientX: x,
26
+ clientY: y
27
27
  } = e;
28
28
  setPosition([x, y]);
29
29
  setOpen(true);
@@ -32,11 +32,12 @@ function useContextMenu() {
32
32
  setOpen(false);
33
33
  }
34
34
  React.useEffect(() => {
35
- const el = trigger?.current ?? trigger;
36
- if (el && el instanceof Element || el instanceof Document || el instanceof Window) {
37
- el.addEventListener('contextmenu', openContextMenu);
35
+ const el = trigger instanceof Element || trigger instanceof Document || trigger instanceof Window ? trigger : trigger.current;
36
+ if (el) {
37
+ const eventListener = e => openContextMenu(e);
38
+ el.addEventListener('contextmenu', eventListener);
38
39
  return () => {
39
- el.removeEventListener('contextmenu', openContextMenu);
40
+ el.removeEventListener('contextmenu', eventListener);
40
41
  };
41
42
  }
42
43
  }, [trigger]);
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
8
  import React from 'react';
9
+ import type { MouseEvent } from 'react';
9
10
  import type { DataTableSortState } from './state/sortStates';
10
11
  import Table from './Table';
11
12
  import TableActionList from './TableActionList';
@@ -131,13 +132,13 @@ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
131
132
  }) => {
132
133
  ariaLabel: string;
133
134
  'aria-label': string;
134
- checked?: boolean;
135
+ checked?: boolean | undefined;
135
136
  disabled?: boolean | undefined;
136
137
  id: string;
137
138
  indeterminate?: boolean;
138
139
  name: string;
139
140
  onSelect: (e: React.MouseEvent<HTMLInputElement>) => void;
140
- radio?: boolean;
141
+ radio?: boolean | undefined;
141
142
  [key: string]: unknown;
142
143
  };
143
144
  getToolbarProps: (getToolbarPropsArgs?: {
@@ -12,7 +12,7 @@ type ExcludedAttributes = 'id' | 'onChange';
12
12
  export interface OnChangeData<ItemType> {
13
13
  selectedItem: ItemType | null;
14
14
  }
15
- export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>, ExcludedAttributes>, TranslateWithId<ListBoxMenuIconTranslationKey> {
15
+ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>, ExcludedAttributes>, TranslateWithId<ListBoxMenuIconTranslationKey>, React.RefAttributes<HTMLDivElement> {
16
16
  /**
17
17
  * Specify a label to be read by screen readers on the container node
18
18
  * 'aria-label' of the ListBox component.
@@ -127,7 +127,7 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
127
127
  * Provide the title text that will be read by a screen reader when
128
128
  * visiting this control
129
129
  */
130
- titleText?: ReactNode;
130
+ titleText: ReactNode;
131
131
  /**
132
132
  * The dropdown type, `default` or `inline`
133
133
  */