@carbon/react 1.65.0 → 1.66.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 (58) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +964 -888
  2. package/es/components/ChatButton/ChatButton.Skeleton.d.ts +31 -0
  3. package/es/components/ChatButton/ChatButton.Skeleton.js +1 -2
  4. package/es/components/ChatButton/ChatButton.d.ts +46 -0
  5. package/es/components/ChatButton/ChatButton.js +3 -3
  6. package/es/components/ChatButton/index.d.ts +12 -0
  7. package/es/components/Checkbox/index.js +10 -0
  8. package/es/components/ComboBox/ComboBox.js +12 -7
  9. package/es/components/ComboButton/index.js +8 -3
  10. package/es/components/ComposedModal/index.d.ts +2 -0
  11. package/es/components/DataTable/TableSlugRow.d.ts +1 -0
  12. package/es/components/DataTable/TableSlugRow.js +1 -0
  13. package/es/components/Grid/Column.js +3 -3
  14. package/es/components/ListBox/ListBoxMenuItem.d.ts +10 -1
  15. package/es/components/ListBox/next/ListBoxSelection.d.ts +106 -0
  16. package/es/components/ListBox/next/ListBoxSelection.js +12 -16
  17. package/es/components/ListBox/next/ListBoxTrigger.d.ts +31 -0
  18. package/es/components/ListBox/next/ListBoxTrigger.js +2 -4
  19. package/es/components/ListBox/next/index.d.ts +8 -0
  20. package/es/components/MultiSelect/FilterableMultiSelect.js +12 -14
  21. package/es/components/MultiSelect/MultiSelect.js +64 -49
  22. package/es/components/MultiSelect/tools/sorting.js +5 -8
  23. package/es/components/OverflowMenu/OverflowMenu.js +1 -1
  24. package/es/components/Popover/index.js +21 -4
  25. package/es/components/TreeView/TreeNode.js +41 -33
  26. package/es/components/TreeView/TreeView.d.ts +5 -3
  27. package/es/index.js +2 -2
  28. package/es/internal/Selection.js +30 -18
  29. package/es/internal/useMergedRefs.d.ts +1 -1
  30. package/lib/components/ChatButton/ChatButton.Skeleton.d.ts +31 -0
  31. package/lib/components/ChatButton/ChatButton.Skeleton.js +1 -2
  32. package/lib/components/ChatButton/ChatButton.d.ts +46 -0
  33. package/lib/components/ChatButton/ChatButton.js +4 -4
  34. package/lib/components/ChatButton/index.d.ts +12 -0
  35. package/lib/components/Checkbox/index.js +19 -0
  36. package/lib/components/ComboBox/ComboBox.js +12 -7
  37. package/lib/components/ComboButton/index.js +8 -3
  38. package/lib/components/ComposedModal/index.d.ts +2 -0
  39. package/lib/components/DataTable/TableSlugRow.d.ts +1 -0
  40. package/lib/components/DataTable/TableSlugRow.js +1 -0
  41. package/lib/components/Grid/Column.js +3 -3
  42. package/lib/components/ListBox/ListBoxMenuItem.d.ts +10 -1
  43. package/lib/components/ListBox/next/ListBoxSelection.d.ts +106 -0
  44. package/lib/components/ListBox/next/ListBoxSelection.js +11 -16
  45. package/lib/components/ListBox/next/ListBoxTrigger.d.ts +31 -0
  46. package/lib/components/ListBox/next/ListBoxTrigger.js +2 -4
  47. package/lib/components/ListBox/next/index.d.ts +8 -0
  48. package/lib/components/MultiSelect/FilterableMultiSelect.js +12 -14
  49. package/lib/components/MultiSelect/MultiSelect.js +63 -48
  50. package/lib/components/MultiSelect/tools/sorting.js +5 -8
  51. package/lib/components/OverflowMenu/OverflowMenu.js +1 -1
  52. package/lib/components/Popover/index.js +21 -4
  53. package/lib/components/TreeView/TreeNode.js +41 -33
  54. package/lib/components/TreeView/TreeView.d.ts +5 -3
  55. package/lib/index.js +4 -4
  56. package/lib/internal/Selection.js +30 -18
  57. package/lib/internal/useMergedRefs.d.ts +1 -1
  58. package/package.json +23 -20
@@ -26,8 +26,11 @@ var deprecate = require('../../prop-types/deprecate.js');
26
26
  var usePrefix = require('../../internal/usePrefix.js');
27
27
  require('../FluidForm/FluidForm.js');
28
28
  var FormContext = require('../FluidForm/FormContext.js');
29
+ var Checkbox = require('../Checkbox/Checkbox.js');
30
+ require('../Checkbox/Checkbox.Skeleton.js');
29
31
  var noopFn = require('../../internal/noopFn.js');
30
32
  var react = require('@floating-ui/react');
33
+ var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js');
31
34
  var match = require('../../internal/keyboard/match.js');
32
35
  var ListBoxPropTypes = require('../ListBox/ListBoxPropTypes.js');
33
36
  var keys = require('../../internal/keyboard/keys.js');
@@ -105,6 +108,23 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
105
108
  locale = 'en',
106
109
  slug
107
110
  } = _ref;
111
+ const filteredItems = React.useMemo(() => {
112
+ return items.filter(item => {
113
+ if (typeof item === 'object' && item !== null) {
114
+ for (const key in item) {
115
+ if (Object.hasOwn(item, key) && item[key] === undefined) {
116
+ return false; // Return false if any property has an undefined value
117
+ }
118
+ }
119
+ }
120
+ return true; // Return true if item is not an object with undefined values
121
+ });
122
+ }, [items]);
123
+ let selectAll = filteredItems.some(item => item.isSelectAll);
124
+ if ((selected ?? []).length > 0 && selectAll) {
125
+ console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
126
+ selectAll = false;
127
+ }
108
128
  const prefix = usePrefix.usePrefix();
109
129
  const {
110
130
  isFluid
@@ -116,16 +136,6 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
116
136
  const [prevOpenProp, setPrevOpenProp] = React.useState(open);
117
137
  const [topItems, setTopItems] = React.useState([]);
118
138
  const [itemsCleared, setItemsCleared] = React.useState(false);
119
- const {
120
- selectedItems: controlledSelectedItems,
121
- onItemChange,
122
- clearSelection
123
- } = Selection.useSelection({
124
- disabled,
125
- initialSelectedItems,
126
- onChange,
127
- selectedItems: selected
128
- });
129
139
  const {
130
140
  refs,
131
141
  floatingStyles,
@@ -150,32 +160,40 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
150
160
  width: `${rects.reference.width}px`
151
161
  });
152
162
  }
153
- })],
163
+ }), floatingUi_core.hide()],
154
164
  whileElementsMounted: react.autoUpdate
155
165
  } : {});
156
166
  React.useLayoutEffect(() => {
157
167
  if (autoAlign) {
158
- Object.keys(floatingStyles).forEach(style => {
168
+ const updatedFloatingStyles = {
169
+ ...floatingStyles,
170
+ visibility: middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'
171
+ };
172
+ Object.keys(updatedFloatingStyles).forEach(style => {
159
173
  if (refs.floating.current) {
160
- refs.floating.current.style[style] = floatingStyles[style];
174
+ refs.floating.current.style[style] = updatedFloatingStyles[style];
161
175
  }
162
176
  });
163
177
  }
164
178
  }, [autoAlign, floatingStyles, refs.floating, middlewareData, open]);
165
-
166
- // Filter out items with an object having undefined values
167
- const filteredItems = React.useMemo(() => {
168
- return items.filter(item => {
169
- if (typeof item === 'object' && item !== null) {
170
- for (const key in item) {
171
- if (Object.hasOwn(item, key) && item[key] === undefined) {
172
- return false; // Return false if any property has an undefined value
173
- }
174
- }
175
- }
176
- return true; // Return true if item is not an object with undefined values
177
- });
178
- }, [items]);
179
+ const {
180
+ selectedItems: controlledSelectedItems,
181
+ onItemChange,
182
+ clearSelection
183
+ } = Selection.useSelection({
184
+ disabled,
185
+ initialSelectedItems,
186
+ onChange,
187
+ selectedItems: selected,
188
+ selectAll,
189
+ filteredItems
190
+ });
191
+ const sortOptions = {
192
+ selectedItems: controlledSelectedItems,
193
+ itemToString,
194
+ compareItems,
195
+ locale
196
+ };
179
197
  const selectProps = {
180
198
  stateReducer,
181
199
  isOpen,
@@ -271,18 +289,13 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
271
289
  [`${prefix}--multi-select--inline`]: inline,
272
290
  [`${prefix}--multi-select--selected`]: selectedItems && selectedItems.length > 0,
273
291
  [`${prefix}--list-box--up`]: direction === 'top',
274
- [`${prefix}--multi-select--readonly`]: readOnly
292
+ [`${prefix}--multi-select--readonly`]: readOnly,
293
+ [`${prefix}--multi-select--selectall`]: selectAll
275
294
  });
276
295
 
277
296
  // needs to be capitalized for react to render it correctly
278
297
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
279
298
  const ItemToElement = itemToElement;
280
- const sortOptions = {
281
- selectedItems: controlledSelectedItems,
282
- itemToString,
283
- compareItems,
284
- locale
285
- };
286
299
  if (selectionFeedback === 'fixed') {
287
300
  sortOptions.selectedItems = [];
288
301
  } else if (selectionFeedback === 'top-after-reopen') {
@@ -345,7 +358,7 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
345
358
  } else {
346
359
  return {
347
360
  ...changes,
348
- highlightedIndex: props.items.indexOf(highlightedIndex)
361
+ highlightedIndex: filteredItems.indexOf(highlightedIndex)
349
362
  };
350
363
  }
351
364
  case ToggleButtonKeyDownArrowDown:
@@ -403,11 +416,12 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
403
416
  });
404
417
  }
405
418
  const itemsSelectedText = selectedItems.length > 0 && selectedItems.map(item => item?.text);
419
+ const selectedItemsLength = selectAll ? selectedItems.filter(item => !item.isSelectAll).length : selectedItems.length;
406
420
 
407
421
  // Memoize the value of getMenuProps to avoid an infinite loop
408
422
  const menuProps = React.useMemo(() => getMenuProps({
409
423
  ref: autoAlign ? refs.setFloating : null
410
- }), [autoAlign]);
424
+ }), [autoAlign, getMenuProps, refs.setFloating]);
411
425
  return /*#__PURE__*/React__default["default"].createElement("div", {
412
426
  className: wrapperClasses
413
427
  }, /*#__PURE__*/React__default["default"].createElement("label", _rollupPluginBabelHelpers["extends"]({
@@ -438,7 +452,7 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
438
452
  }, selectedItems.length > 0 && /*#__PURE__*/React__default["default"].createElement(index["default"].Selection, {
439
453
  readOnly: readOnly,
440
454
  clearSelection: !disabled && !readOnly ? clearSelection : noopFn.noopFn,
441
- selectionCount: selectedItems.length
455
+ selectionCount: selectedItemsLength
442
456
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
443
457
  ,
444
458
  translateWithId: translateWithId,
@@ -457,10 +471,9 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
457
471
  }, label), /*#__PURE__*/React__default["default"].createElement(index["default"].MenuIcon, {
458
472
  isOpen: isOpen,
459
473
  translateWithId: translateWithId
460
- })), normalizedSlug), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, isOpen &&
461
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
462
- sortItems(filteredItems, sortOptions).map((item, index$1) => {
474
+ })), normalizedSlug), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index$1) => {
463
475
  const isChecked = selectedItems.filter(selected => isEqual__default["default"](selected, item)).length > 0;
476
+ const isIndeterminate = selectedItems.length !== 0 && item['isSelectAll'] && !isChecked;
464
477
  const itemProps = getItemProps({
465
478
  item,
466
479
  // we don't want Downshift to set aria-selected for us
@@ -470,21 +483,23 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
470
483
  const itemText = itemToString(item);
471
484
  return /*#__PURE__*/React__default["default"].createElement(index["default"].MenuItem, _rollupPluginBabelHelpers["extends"]({
472
485
  key: itemProps.id,
473
- isActive: isChecked,
486
+ isActive: isChecked && !item['isSelectAll'],
474
487
  "aria-label": itemText,
475
488
  isHighlighted: highlightedIndex === index$1,
476
489
  title: itemText,
477
490
  disabled: itemProps['aria-disabled']
478
491
  }, itemProps), /*#__PURE__*/React__default["default"].createElement("div", {
479
492
  className: `${prefix}--checkbox-wrapper`
480
- }, /*#__PURE__*/React__default["default"].createElement("span", {
493
+ }, /*#__PURE__*/React__default["default"].createElement(Checkbox["default"], {
494
+ id: `${itemProps.id}__checkbox`,
495
+ labelText: itemToElement ? /*#__PURE__*/React__default["default"].createElement(ItemToElement, _rollupPluginBabelHelpers["extends"]({
496
+ key: itemProps.id
497
+ }, item)) : itemText,
498
+ checked: isChecked,
481
499
  title: useTitleInItem ? itemText : undefined,
482
- className: `${prefix}--checkbox-label`,
483
- "data-contained-checkbox-state": isChecked,
484
- id: `${itemProps.id}__checkbox`
485
- }, itemToElement ? /*#__PURE__*/React__default["default"].createElement(ItemToElement, _rollupPluginBabelHelpers["extends"]({
486
- key: itemProps.id
487
- }, item)) : itemText)));
500
+ indeterminate: isIndeterminate,
501
+ disabled: disabled
502
+ })));
488
503
  })), itemsCleared && /*#__PURE__*/React__default["default"].createElement("span", {
489
504
  "aria-live": "assertive",
490
505
  "aria-label": clearAnnouncement
@@ -39,16 +39,13 @@ const defaultSortItems = (items, _ref2) => {
39
39
  locale = 'en'
40
40
  } = _ref2;
41
41
  return items.sort((itemA, itemB) => {
42
+ // Always place "select all" option at the beginning
43
+ if (itemA.isSelectAll) return -1;
44
+ if (itemB.isSelectAll) return 1;
42
45
  const hasItemA = selectedItems.includes(itemA);
43
46
  const hasItemB = selectedItems.includes(itemB);
44
-
45
- // Prefer whichever item is in the `selectedItems` array first
46
- if (hasItemA && !hasItemB) {
47
- return -1;
48
- }
49
- if (hasItemB && !hasItemA) {
50
- return 1;
51
- }
47
+ if (hasItemA && !hasItemB) return -1;
48
+ if (hasItemB && !hasItemA) return 1;
52
49
  return compareItems(itemToString(itemA), itemToString(itemB), {
53
50
  locale
54
51
  });
@@ -262,7 +262,7 @@ class OverflowMenu extends React__default["default"].Component {
262
262
  } = this.props;
263
263
  if (menuBody) {
264
264
  this._menuBody = menuBody;
265
- const hasFocusin = ('onfocusin' in window);
265
+ const hasFocusin = 'onfocusin' in window;
266
266
  const focusinEventName = hasFocusin ? 'focusin' : 'focus';
267
267
  this._hFocusIn = on(menuBody.ownerDocument, focusinEventName, event => {
268
268
  const target = ClickListener["default"].getEventTarget(event);
@@ -20,6 +20,7 @@ var usePrefix = require('../../internal/usePrefix.js');
20
20
  var useEvent = require('../../internal/useEvent.js');
21
21
  var createPropAdapter = require('../../tools/createPropAdapter.js');
22
22
  var react = require('@floating-ui/react');
23
+ var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js');
23
24
 
24
25
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
25
26
 
@@ -138,7 +139,7 @@ const Popover = /*#__PURE__*/React__default["default"].forwardRef(function Popov
138
139
  fallbackAxisSideDirection: 'start'
139
140
  }), react.arrow({
140
141
  element: caretRef
141
- })],
142
+ }), floatingUi_core.hide()],
142
143
  whileElementsMounted: react.autoUpdate
143
144
  } : {} // When autoAlign is turned off, floating-ui will not be used
144
145
  );
@@ -158,9 +159,13 @@ const Popover = /*#__PURE__*/React__default["default"].forwardRef(function Popov
158
159
  }
159
160
  React.useEffect(() => {
160
161
  if (autoAlign) {
161
- Object.keys(floatingStyles).forEach(style => {
162
+ const updatedFloatingStyles = {
163
+ ...floatingStyles,
164
+ visibility: middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'
165
+ };
166
+ Object.keys(updatedFloatingStyles).forEach(style => {
162
167
  if (refs.floating.current) {
163
- refs.floating.current.style[style] = floatingStyles[style];
168
+ refs.floating.current.style[style] = updatedFloatingStyles[style];
164
169
  }
165
170
  });
166
171
  if (caret && middlewareData && middlewareData.arrow && caretRef?.current) {
@@ -200,7 +205,19 @@ const Popover = /*#__PURE__*/React__default["default"].forwardRef(function Popov
200
205
  }, customClassName);
201
206
  const mappedChildren = React__default["default"].Children.map(children, child => {
202
207
  const item = child;
203
- if ((item?.type === 'button' || autoAlign && item?.type?.displayName !== 'PopoverContent' || autoAlign && item?.type?.displayName === 'ToggletipButton') && /*#__PURE__*/React__default["default"].isValidElement(item)) {
208
+ const displayName = item?.type?.displayName;
209
+
210
+ /**
211
+ * Only trigger elements (button) or trigger components (ToggletipButton) should be
212
+ * cloned because these will be decorated with a trigger-specific className and ref.
213
+ *
214
+ * There are also some specific components that should not be cloned when autoAlign
215
+ * is on, even if they are a trigger element.
216
+ */
217
+ const isTriggerElement = item?.type === 'button';
218
+ const isTriggerComponent = autoAlign && displayName && ['ToggletipButton'].includes(displayName);
219
+ const isAllowedTriggerComponent = autoAlign && displayName && !['ToggletipContent', 'PopoverContent'].includes(displayName);
220
+ if ( /*#__PURE__*/React__default["default"].isValidElement(item) && (isTriggerElement || isTriggerComponent || isAllowedTriggerComponent)) {
204
221
  const className = item?.props?.className;
205
222
  const ref = (item?.props).ref;
206
223
  const tabTipClasses = cx__default["default"](`${prefix}--popover--tab-tip__button`, className);
@@ -27,7 +27,7 @@ var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
27
27
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
28
28
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
29
29
 
30
- const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) => {
30
+ const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, forwardedRef) => {
31
31
  let {
32
32
  active,
33
33
  children,
@@ -64,6 +64,14 @@ const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
64
64
  const currentNode = React.useRef(null);
65
65
  const currentNodeLabel = React.useRef(null);
66
66
  const prefix = usePrefix.usePrefix();
67
+ const setRefs = element => {
68
+ currentNode.current = element;
69
+ if (typeof forwardedRef === 'function') {
70
+ forwardedRef(element);
71
+ } else if (forwardedRef) {
72
+ forwardedRef.current = element;
73
+ }
74
+ };
67
75
  const nodesWithProps = React__default["default"].Children.map(children, node => {
68
76
  if ( /*#__PURE__*/React__default["default"].isValidElement(node)) {
69
77
  return /*#__PURE__*/React__default["default"].cloneElement(node, {
@@ -131,13 +139,14 @@ const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
131
139
  }
132
140
  if (match.match(event, keys.ArrowLeft)) {
133
141
  const findParentTreeNode = node => {
142
+ if (!node) return null;
134
143
  if (node.classList.contains(`${prefix}--tree-parent-node`)) {
135
144
  return node;
136
145
  }
137
146
  if (node.classList.contains(`${prefix}--tree`)) {
138
147
  return null;
139
148
  }
140
- return findParentTreeNode(node.parentNode);
149
+ return findParentTreeNode(node.parentElement);
141
150
  };
142
151
  if (children && expanded) {
143
152
  if (!enableTreeviewControllable) {
@@ -154,7 +163,10 @@ const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
154
163
  * When focus is on a leaf node or a closed parent node, move focus to
155
164
  * its parent node (unless its depth is level 1)
156
165
  */
157
- findParentTreeNode(currentNode.current?.parentNode)?.focus();
166
+ const parentNode = findParentTreeNode(currentNode.current?.parentElement || null);
167
+ if (parentNode instanceof HTMLElement) {
168
+ parentNode.focus();
169
+ }
158
170
  }
159
171
  }
160
172
  if (children && match.match(event, keys.ArrowRight)) {
@@ -239,44 +251,40 @@ const TreeNode = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
239
251
  onClick: handleClick,
240
252
  onFocus: handleFocusEvent,
241
253
  onKeyDown: handleKeyDown,
242
- role: 'treeitem',
243
- // @ts-ignore
244
- ref: currentNode
254
+ role: 'treeitem'
245
255
  };
246
256
  if (!children) {
247
- return /*#__PURE__*/React__default["default"].createElement("li", treeNodeProps, /*#__PURE__*/React__default["default"].createElement("div", {
257
+ return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({}, treeNodeProps, {
258
+ ref: setRefs
259
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
248
260
  className: `${prefix}--tree-node__label`,
249
261
  ref: currentNodeLabel
250
262
  }, Icon && /*#__PURE__*/React__default["default"].createElement(Icon, {
251
263
  className: `${prefix}--tree-node__icon`
252
264
  }), label));
253
265
  }
254
- return (
255
- /*#__PURE__*/
256
- // eslint-disable-next-line jsx-a11y/role-supports-aria-props
257
- React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({}, treeNodeProps, {
258
- "aria-expanded": !!expanded,
259
- ref: ref
260
- }), /*#__PURE__*/React__default["default"].createElement("div", {
261
- className: `${prefix}--tree-node__label`,
262
- ref: currentNodeLabel
263
- }, /*#__PURE__*/React__default["default"].createElement("span", {
264
- className: `${prefix}--tree-parent-node__toggle`
265
- // @ts-ignore
266
- ,
267
- disabled: disabled,
268
- onClick: handleToggleClick
269
- }, /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretDown, {
270
- className: toggleClasses
271
- })), /*#__PURE__*/React__default["default"].createElement("span", {
272
- className: `${prefix}--tree-node__label__details`
273
- }, Icon && /*#__PURE__*/React__default["default"].createElement(Icon, {
274
- className: `${prefix}--tree-node__icon`
275
- }), label)), expanded && /*#__PURE__*/React__default["default"].createElement("ul", {
276
- role: "group",
277
- className: `${prefix}--tree-node__children`
278
- }, nodesWithProps))
279
- );
266
+ return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({}, treeNodeProps, {
267
+ "aria-expanded": !!expanded,
268
+ ref: setRefs
269
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
270
+ className: `${prefix}--tree-node__label`,
271
+ ref: currentNodeLabel
272
+ }, /*#__PURE__*/React__default["default"].createElement("span", {
273
+ className: `${prefix}--tree-parent-node__toggle`
274
+ // @ts-ignore
275
+ ,
276
+ disabled: disabled,
277
+ onClick: handleToggleClick
278
+ }, /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretDown, {
279
+ className: toggleClasses
280
+ })), /*#__PURE__*/React__default["default"].createElement("span", {
281
+ className: `${prefix}--tree-node__label__details`
282
+ }, Icon && /*#__PURE__*/React__default["default"].createElement(Icon, {
283
+ className: `${prefix}--tree-node__icon`
284
+ }), label)), expanded && /*#__PURE__*/React__default["default"].createElement("ul", {
285
+ role: "group",
286
+ className: `${prefix}--tree-node__children`
287
+ }, nodesWithProps));
280
288
  });
281
289
  TreeNode.propTypes = {
282
290
  /**
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React from 'react';
8
- import TreeNode from './TreeNode';
8
+ import TreeNode, { TreeNodeProps } from './TreeNode';
9
9
  export type TreeViewProps = {
10
10
  /**
11
11
  * Mark the active node in the tree, represented by its ID
@@ -40,7 +40,9 @@ export type TreeViewProps = {
40
40
  /**
41
41
  * Callback function that is called when any node is selected
42
42
  */
43
- onSelect?: (selected: Array<string | number>, payload: any) => void;
43
+ onSelect?: (event: React.SyntheticEvent<HTMLUListElement>, payload?: Partial<TreeNodeProps> & {
44
+ activeNodeId?: string | number;
45
+ }) => void;
44
46
  /**
45
47
  * Array representing all selected node IDs in the tree
46
48
  */
@@ -49,7 +51,7 @@ export type TreeViewProps = {
49
51
  * Specify the size of the tree from a list of available sizes.
50
52
  */
51
53
  size?: 'xs' | 'sm';
52
- } & React.HTMLAttributes<HTMLUListElement>;
54
+ } & Omit<React.HTMLAttributes<HTMLUListElement>, 'onSelect'>;
53
55
  type TreeViewComponent = {
54
56
  (props: TreeViewProps): JSX.Element;
55
57
  propTypes?: any;
package/lib/index.js CHANGED
@@ -171,6 +171,8 @@ var index$2 = require('./components/OverflowMenuV2/index.js');
171
171
  var index$f = require('./components/Popover/index.js');
172
172
  var ProgressBar = require('./components/ProgressBar/ProgressBar.js');
173
173
  var index$3 = require('./components/AILabel/index.js');
174
+ var ChatButton = require('./components/ChatButton/ChatButton.js');
175
+ var ChatButton_Skeleton = require('./components/ChatButton/ChatButton.Skeleton.js');
174
176
  var AISkeletonPlaceholder = require('./components/AISkeleton/AISkeletonPlaceholder.js');
175
177
  var AISkeletonIcon = require('./components/AISkeleton/AISkeletonIcon.js');
176
178
  var AISkeletonText = require('./components/AISkeleton/AISkeletonText.js');
@@ -210,8 +212,6 @@ var FluidTimePicker_Skeleton = require('./components/FluidTimePicker/FluidTimePi
210
212
  var FluidTimePickerSelect = require('./components/FluidTimePickerSelect/FluidTimePickerSelect.js');
211
213
  var LayoutDirection = require('./components/LayoutDirection/LayoutDirection.js');
212
214
  var useLayoutDirection = require('./components/LayoutDirection/useLayoutDirection.js');
213
- var ChatButton = require('./components/ChatButton/ChatButton.js');
214
- var ChatButton_Skeleton = require('./components/ChatButton/ChatButton.Skeleton.js');
215
215
  var Text = require('./components/Text/Text.js');
216
216
  var TextDirection = require('./components/Text/TextDirection.js');
217
217
  var CheckboxGroup = require('./components/CheckboxGroup/CheckboxGroup.js');
@@ -446,6 +446,8 @@ exports.AILabelContent = index$3.AILabelContent;
446
446
  exports.unstable__Slug = index$3.AILabel;
447
447
  exports.unstable__SlugActions = index$3.AILabelActions;
448
448
  exports.unstable__SlugContent = index$3.AILabelContent;
449
+ exports.unstable__ChatButton = ChatButton["default"];
450
+ exports.unstable__ChatButtonSkeleton = ChatButton_Skeleton["default"];
449
451
  exports.AISkeletonPlaceholder = AISkeletonPlaceholder["default"];
450
452
  exports.unstable__AiSkeletonPlaceholder = AISkeletonPlaceholder["default"];
451
453
  exports.AISkeletonIcon = AISkeletonIcon["default"];
@@ -492,8 +494,6 @@ exports.unstable__FluidTimePickerSkeleton = FluidTimePicker_Skeleton["default"];
492
494
  exports.unstable__FluidTimePickerSelect = FluidTimePickerSelect["default"];
493
495
  exports.unstable_LayoutDirection = LayoutDirection.LayoutDirection;
494
496
  exports.unstable_useLayoutDirection = useLayoutDirection.useLayoutDirection;
495
- exports.unstable__ChatButton = ChatButton["default"];
496
- exports.unstable__ChatButtonSkeleton = ChatButton_Skeleton["default"];
497
497
  exports.unstable_Text = Text.Text;
498
498
  exports.unstable_TextDirection = TextDirection.TextDirection;
499
499
  exports.CheckboxGroup = CheckboxGroup["default"];
@@ -43,7 +43,9 @@ function useSelection(_ref2) {
43
43
  disabled,
44
44
  onChange,
45
45
  initialSelectedItems = [],
46
- selectedItems: controlledItems
46
+ selectedItems: controlledItems,
47
+ selectAll = false,
48
+ filteredItems = []
47
49
  } = _ref2;
48
50
  const isMounted = React.useRef(false);
49
51
  const savedOnChange = React.useRef(onChange);
@@ -54,25 +56,35 @@ function useSelection(_ref2) {
54
56
  if (disabled) {
55
57
  return;
56
58
  }
57
- let selectedIndex;
58
- selectedItems.forEach((selectedItem, index) => {
59
- if (isEqual__default["default"](selectedItem, item)) {
60
- selectedIndex = index;
61
- }
62
- });
59
+ const allSelectableItems = filteredItems.filter(item => !item.disabled);
60
+ const disabledItemCount = filteredItems.filter(item => item.disabled).length;
63
61
  let newSelectedItems;
64
- if (selectedIndex === undefined) {
65
- newSelectedItems = selectedItems.concat(item);
66
- callOnChangeHandler({
67
- isControlled,
68
- isMounted: isMounted.current,
69
- onChangeHandlerControlled: savedOnChange.current,
70
- onChangeHandlerUncontrolled: setUncontrolledItems,
71
- selectedItems: newSelectedItems
62
+
63
+ //deselect all on click to All/indeterminate option
64
+ if (item && item.isSelectAll && selectedItems.length > 0) {
65
+ newSelectedItems = [];
66
+ }
67
+ //select all option
68
+ else if (item && item.isSelectAll && selectedItems.length == 0) {
69
+ newSelectedItems = allSelectableItems;
70
+ } else {
71
+ let selectedIndex;
72
+ selectedItems.forEach((selectedItem, index) => {
73
+ if (isEqual__default["default"](selectedItem, item)) {
74
+ selectedIndex = index;
75
+ }
72
76
  });
73
- return;
77
+ if (selectedIndex === undefined) {
78
+ newSelectedItems = selectedItems.concat(item);
79
+ // checking if all items are selected then We should select mark the 'select All' option as well
80
+ if (selectAll && filteredItems.length - 1 === newSelectedItems.length + disabledItemCount) {
81
+ newSelectedItems = allSelectableItems;
82
+ }
83
+ } else {
84
+ newSelectedItems = removeAtIndex(selectedItems, selectedIndex);
85
+ newSelectedItems = newSelectedItems.filter(item => !item.isSelectAll);
86
+ }
74
87
  }
75
- newSelectedItems = removeAtIndex(selectedItems, selectedIndex);
76
88
  callOnChangeHandler({
77
89
  isControlled,
78
90
  isMounted: isMounted.current,
@@ -80,7 +92,7 @@ function useSelection(_ref2) {
80
92
  onChangeHandlerUncontrolled: setUncontrolledItems,
81
93
  selectedItems: newSelectedItems
82
94
  });
83
- }, [disabled, isControlled, selectedItems]);
95
+ }, [disabled, selectedItems, filteredItems, selectAll, isControlled]);
84
96
  const clearSelection = React.useCallback(() => {
85
97
  if (disabled) {
86
98
  return;
@@ -10,4 +10,4 @@ import { Ref, ForwardedRef } from 'react';
10
10
  * refs from both `React.forwardRef` and `useRef` that you would like to add to
11
11
  * the same node.
12
12
  */
13
- export declare const useMergedRefs: <T>(refs: ForwardedRef<T>[]) => Ref<T>;
13
+ export declare const useMergedRefs: <T extends unknown>(refs: ForwardedRef<T>[]) => Ref<T>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/react",
3
3
  "description": "React components for the Carbon Design System",
4
- "version": "1.65.0",
4
+ "version": "1.66.0-rc.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "module": "es/index.js",
@@ -49,9 +49,9 @@
49
49
  "dependencies": {
50
50
  "@babel/runtime": "^7.24.7",
51
51
  "@carbon/feature-flags": "^0.22.0",
52
- "@carbon/icons-react": "^11.48.0",
53
- "@carbon/layout": "^11.25.0",
54
- "@carbon/styles": "^1.64.0",
52
+ "@carbon/icons-react": "^11.49.0-rc.0",
53
+ "@carbon/layout": "^11.26.0-rc.0",
54
+ "@carbon/styles": "^1.65.0-rc.0",
55
55
  "@floating-ui/react": "^0.26.0",
56
56
  "@ibm/telemetry-js": "^1.5.0",
57
57
  "classnames": "2.5.1",
@@ -79,22 +79,25 @@
79
79
  "@babel/preset-env": "^7.24.7",
80
80
  "@babel/preset-react": "^7.24.7",
81
81
  "@babel/preset-typescript": "^7.24.7",
82
- "@carbon/test-utils": "^10.31.0",
83
- "@carbon/themes": "^11.39.0",
82
+ "@carbon/test-utils": "^10.32.0-rc.0",
83
+ "@carbon/themes": "^11.40.0-rc.0",
84
84
  "@figma/code-connect": "^1.0.4",
85
85
  "@rollup/plugin-babel": "^6.0.0",
86
86
  "@rollup/plugin-commonjs": "^26.0.0",
87
87
  "@rollup/plugin-node-resolve": "^15.0.0",
88
88
  "@rollup/plugin-typescript": "^11.0.0",
89
- "@storybook/addon-a11y": "^7.1.0",
90
- "@storybook/addon-actions": "^7.1.0",
91
- "@storybook/addon-docs": "^7.1.0",
92
- "@storybook/addon-essentials": "^7.1.0",
93
- "@storybook/addon-links": "^7.4.5",
94
- "@storybook/addon-storysource": "^7.1.0",
95
- "@storybook/react": "^7.1.0",
96
- "@storybook/react-webpack5": "^7.1.0",
97
- "@storybook/theming": "^7.1.0",
89
+ "@storybook/addon-a11y": "^8.2.8",
90
+ "@storybook/addon-actions": "^8.2.8",
91
+ "@storybook/addon-docs": "^8.2.8",
92
+ "@storybook/addon-essentials": "^8.2.8",
93
+ "@storybook/addon-links": "^8.1.10",
94
+ "@storybook/addon-storysource": "^8.2.8",
95
+ "@storybook/addon-webpack5-compiler-babel": "^3.0.3",
96
+ "@storybook/blocks": "^8.2.8",
97
+ "@storybook/manager-api": "^8.2.8",
98
+ "@storybook/react": "^8.2.8",
99
+ "@storybook/react-webpack5": "^8.2.8",
100
+ "@storybook/theming": "^8.2.8",
98
101
  "@types/react-is": "~18.3.0",
99
102
  "autoprefixer": "^10.4.0",
100
103
  "babel-loader": "^9.0.0",
@@ -115,14 +118,14 @@
115
118
  "prop-types": "^15.7.2",
116
119
  "react": "^18.2.0",
117
120
  "react-dom": "^18.2.0",
118
- "remark-gfm": "^3.0.1",
121
+ "remark-gfm": "^4.0.0",
119
122
  "requestanimationframe": "^0.0.23",
120
123
  "rimraf": "^6.0.0",
121
124
  "rollup": "^2.79.1",
122
125
  "rollup-plugin-strip-banner": "^3.0.0",
123
- "sass": "^1.51.0",
124
- "sass-loader": "^14.0.0",
125
- "storybook": "^7.1.0",
126
+ "sass": "^1.77.7",
127
+ "sass-loader": "^16.0.0",
128
+ "storybook": "^8.2.8",
126
129
  "storybook-addon-accessibility-checker": "^3.1.61-rc.3",
127
130
  "stream-browserify": "^3.0.0",
128
131
  "style-loader": "^4.0.0",
@@ -141,5 +144,5 @@
141
144
  "**/*.scss",
142
145
  "**/*.css"
143
146
  ],
144
- "gitHead": "2e82ab9625d65b607a7510b70d2cb4bacf209378"
147
+ "gitHead": "3bea42a9cef74114dc19f12d48519865bd8a4a17"
145
148
  }