@carbon/react 1.54.0-rc.0 → 1.55.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 (82) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +994 -1023
  2. package/es/components/Button/Button.d.ts +1 -1
  3. package/es/components/Button/Button.js +13 -89
  4. package/es/components/Button/ButtonBase.d.ts +10 -0
  5. package/es/components/Button/ButtonBase.js +110 -0
  6. package/es/components/CodeSnippet/CodeSnippet.Skeleton.d.ts +37 -0
  7. package/es/components/CodeSnippet/CodeSnippet.d.ts +196 -0
  8. package/es/components/CodeSnippet/CodeSnippet.js +20 -18
  9. package/es/components/CodeSnippet/index.d.ts +10 -0
  10. package/es/components/ComboBox/ComboBox.d.ts +2 -2
  11. package/es/components/ComboBox/ComboBox.js +13 -5
  12. package/es/components/ComboButton/index.d.ts +51 -0
  13. package/es/components/ComboButton/index.js +9 -7
  14. package/es/components/ComposedModal/ComposedModal.js +2 -2
  15. package/es/components/DataTable/TableBatchAction.d.ts +1 -5
  16. package/es/components/Dropdown/Dropdown.js +3 -1
  17. package/es/components/IconButton/index.js +2 -3
  18. package/es/components/Menu/Menu.js +2 -0
  19. package/es/components/Modal/Modal.js +2 -2
  20. package/es/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  21. package/es/components/MultiSelect/FilterableMultiSelect.js +31 -0
  22. package/es/components/MultiSelect/MultiSelect.js +37 -7
  23. package/es/components/Slider/Slider.Skeleton.js +6 -2
  24. package/es/components/Slug/index.js +8 -13
  25. package/es/components/StructuredList/StructuredList.d.ts +8 -0
  26. package/es/components/StructuredList/StructuredList.js +28 -10
  27. package/es/components/Tag/DismissibleTag.js +119 -0
  28. package/es/components/Tag/OperationalTag.js +99 -0
  29. package/es/components/Tag/SelectableTag.js +98 -0
  30. package/es/components/Tag/index.d.ts +4 -1
  31. package/es/components/TreeView/TreeNode.js +1 -1
  32. package/es/components/UIShell/SideNavMenu.js +11 -1
  33. package/es/components/UIShell/SideNavMenuItem.d.ts +4 -0
  34. package/es/components/UIShell/SideNavMenuItem.js +8 -1
  35. package/es/components/UIShell/SwitcherItem.d.ts +4 -0
  36. package/es/components/UIShell/SwitcherItem.js +6 -0
  37. package/es/feature-flags.js +2 -1
  38. package/es/index.js +5 -2
  39. package/es/internal/environment.js +5 -1
  40. package/es/internal/keyboard/navigation.js +6 -2
  41. package/es/internal/useOutsideClick.js +31 -0
  42. package/lib/components/Button/Button.d.ts +1 -1
  43. package/lib/components/Button/Button.js +13 -90
  44. package/lib/components/Button/ButtonBase.d.ts +10 -0
  45. package/lib/components/Button/ButtonBase.js +119 -0
  46. package/lib/components/CodeSnippet/CodeSnippet.Skeleton.d.ts +37 -0
  47. package/lib/components/CodeSnippet/CodeSnippet.d.ts +196 -0
  48. package/lib/components/CodeSnippet/CodeSnippet.js +20 -18
  49. package/lib/components/CodeSnippet/index.d.ts +10 -0
  50. package/lib/components/ComboBox/ComboBox.d.ts +2 -2
  51. package/lib/components/ComboBox/ComboBox.js +13 -5
  52. package/lib/components/ComboButton/index.d.ts +51 -0
  53. package/lib/components/ComboButton/index.js +9 -7
  54. package/lib/components/ComposedModal/ComposedModal.js +2 -2
  55. package/lib/components/DataTable/TableBatchAction.d.ts +1 -5
  56. package/lib/components/Dropdown/Dropdown.js +3 -1
  57. package/lib/components/IconButton/index.js +2 -3
  58. package/lib/components/Menu/Menu.js +2 -0
  59. package/lib/components/Modal/Modal.js +2 -2
  60. package/lib/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  61. package/lib/components/MultiSelect/FilterableMultiSelect.js +31 -0
  62. package/lib/components/MultiSelect/MultiSelect.js +37 -7
  63. package/lib/components/Slider/Slider.Skeleton.js +5 -1
  64. package/lib/components/Slug/index.js +8 -13
  65. package/lib/components/StructuredList/StructuredList.d.ts +8 -0
  66. package/lib/components/StructuredList/StructuredList.js +27 -9
  67. package/lib/components/Tag/DismissibleTag.js +129 -0
  68. package/lib/components/Tag/OperationalTag.js +109 -0
  69. package/lib/components/Tag/SelectableTag.js +108 -0
  70. package/lib/components/Tag/index.d.ts +4 -1
  71. package/lib/components/TreeView/TreeNode.js +1 -1
  72. package/lib/components/UIShell/SideNavMenu.js +11 -1
  73. package/lib/components/UIShell/SideNavMenuItem.d.ts +4 -0
  74. package/lib/components/UIShell/SideNavMenuItem.js +8 -1
  75. package/lib/components/UIShell/SwitcherItem.d.ts +4 -0
  76. package/lib/components/UIShell/SwitcherItem.js +6 -0
  77. package/lib/feature-flags.js +2 -1
  78. package/lib/index.js +10 -4
  79. package/lib/internal/environment.js +5 -1
  80. package/lib/internal/keyboard/navigation.js +6 -2
  81. package/lib/internal/useOutsideClick.js +35 -0
  82. package/package.json +6 -6
@@ -31,9 +31,11 @@ const {
31
31
  keyDownArrowUp,
32
32
  keyDownEscape,
33
33
  clickButton,
34
+ clickItem,
34
35
  blurButton,
35
36
  changeInput,
36
- blurInput
37
+ blurInput,
38
+ unknown
37
39
  } = Downshift.stateChangeTypes;
38
40
  const defaultItemToString = item => {
39
41
  if (typeof item === 'string') {
@@ -195,15 +197,16 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
195
197
  switch (type) {
196
198
  case keyDownArrowDown:
197
199
  case keyDownArrowUp:
198
- setHighlightedIndex(changes.highlightedIndex);
200
+ if (changes.isOpen) {
201
+ updateHighlightedIndex(getHighlightedIndex(changes));
202
+ } else {
203
+ setHighlightedIndex(changes.highlightedIndex);
204
+ }
199
205
  break;
200
206
  case blurButton:
201
207
  case keyDownEscape:
202
208
  setHighlightedIndex(changes.highlightedIndex);
203
209
  break;
204
- case clickButton:
205
- setHighlightedIndex(changes.highlightedIndex);
206
- break;
207
210
  case changeInput:
208
211
  updateHighlightedIndex(getHighlightedIndex(changes));
209
212
  break;
@@ -218,6 +221,11 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
218
221
  }
219
222
  }
220
223
  break;
224
+ case clickButton:
225
+ case clickItem:
226
+ case unknown:
227
+ setHighlightedIndex(getHighlightedIndex(changes));
228
+ break;
221
229
  }
222
230
  };
223
231
  const handleToggleClick = isOpen => event => {
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Copyright IBM Corp. 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 React from 'react';
8
+ import { IconButton } from '../IconButton';
9
+ import Button from '../Button';
10
+ import { Menu } from '../Menu';
11
+ interface ComboButtonProps {
12
+ /**
13
+ * A collection of `MenuItems` to be rendered as additional actions for this `ComboButton`.
14
+ */
15
+ children: React.ComponentProps<typeof Menu>['children'];
16
+ /**
17
+ * Additional CSS class names.
18
+ */
19
+ className?: string;
20
+ /**
21
+ * Specify whether the `ComboButton` should be disabled, or not.
22
+ */
23
+ disabled?: boolean;
24
+ /**
25
+ * Provide the label to be rendered on the primary action button.
26
+ */
27
+ label: React.ComponentProps<typeof Button>['title'];
28
+ /**
29
+ * Experimental property. Specify how the menu should align with the button element
30
+ */
31
+ menuAlignment?: React.ComponentProps<typeof Menu>['menuAlignment'];
32
+ /**
33
+ * Provide an optional function to be called when the primary action element is clicked.
34
+ */
35
+ onClick?: React.ComponentProps<typeof Button>['onClick'];
36
+ /**
37
+ * Specify the size of the buttons and menu.
38
+ */
39
+ size?: 'sm' | 'md' | 'lg';
40
+ /**
41
+ * Specify how the trigger tooltip should be aligned.
42
+ */
43
+ tooltipAlignment?: React.ComponentProps<typeof IconButton>['align'];
44
+ /**
45
+ * Optional method that takes in a message `id` and returns an
46
+ * internationalized string.
47
+ */
48
+ translateWithId?: (id: string) => string;
49
+ }
50
+ declare const ComboButton: React.ForwardRefExoticComponent<ComboButtonProps & React.RefAttributes<HTMLDivElement>>;
51
+ export { ComboButton, type ComboButtonProps };
@@ -70,10 +70,12 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
70
70
  }
71
71
  }
72
72
  function handleOpen() {
73
- menuRef.current.style.inlineSize = `${width}px`;
74
- menuRef.current.style.minInlineSize = `${width}px`;
75
- if (menuAlignment !== 'bottom' && menuAlignment !== 'top') {
76
- menuRef.current.style.inlineSize = `fit-content`;
73
+ if (menuRef.current) {
74
+ menuRef.current.style.inlineSize = `${width}px`;
75
+ menuRef.current.style.minInlineSize = `${width}px`;
76
+ if (menuAlignment !== 'bottom' && menuAlignment !== 'top') {
77
+ menuRef.current.style.inlineSize = `fit-content`;
78
+ }
77
79
  }
78
80
  }
79
81
  const containerClasses = cx(`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, {
@@ -85,7 +87,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
85
87
  return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
86
88
  className: containerClasses,
87
89
  ref: ref,
88
- "aria-owns": open ? id : null
90
+ "aria-owns": open ? id : undefined
89
91
  }), /*#__PURE__*/React__default.createElement("div", {
90
92
  className: primaryActionClasses
91
93
  }, /*#__PURE__*/React__default.createElement(Button, {
@@ -103,7 +105,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
103
105
  "aria-expanded": open,
104
106
  onClick: handleTriggerClick,
105
107
  onMouseDown: handleTriggerMousedown,
106
- "aria-controls": open ? id : null
108
+ "aria-controls": open ? id : undefined
107
109
  }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default.createElement(ChevronDown, null))), /*#__PURE__*/React__default.createElement(Menu, {
108
110
  containerRef: containerRef,
109
111
  menuAlignment: menuAlignment,
@@ -134,7 +136,7 @@ ComboButton.propTypes = {
134
136
  */
135
137
  disabled: PropTypes.bool,
136
138
  /**
137
- * Provide the label to be renderd on the primary action button.
139
+ * Provide the label to be rendered on the primary action button.
138
140
  */
139
141
  label: PropTypes.string.isRequired,
140
142
  /**
@@ -242,11 +242,11 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
242
242
  }
243
243
  }, [open, selectorPrimaryFocus, isOpen]);
244
244
 
245
- // Slug is always size `lg`
245
+ // Slug is always size `sm`
246
246
  let normalizedSlug;
247
247
  if (slug && slug['type']?.displayName === 'Slug') {
248
248
  normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
249
- size: 'lg'
249
+ size: 'sm'
250
250
  });
251
251
  }
252
252
  return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
@@ -22,11 +22,7 @@ export interface TableBatchActionProps extends React.ButtonHTMLAttributes<HTMLBu
22
22
  renderIcon?: React.ElementType;
23
23
  }
24
24
  declare const TableBatchAction: {
25
- ({ renderIcon, iconDescription, ...props }: {
26
- [x: string]: any;
27
- renderIcon?: import("@carbon/icons-react").CarbonIconType | undefined;
28
- iconDescription?: string | undefined;
29
- }): import("react/jsx-runtime").JSX.Element;
25
+ ({ renderIcon, iconDescription, ...props }: TableBatchActionProps): import("react/jsx-runtime").JSX.Element;
30
26
  propTypes: {
31
27
  /**
32
28
  * Specify if the button is an icon-only button
@@ -26,7 +26,8 @@ const {
26
26
  ToggleButtonKeyDownArrowUp,
27
27
  ToggleButtonKeyDownHome,
28
28
  ToggleButtonKeyDownEnd,
29
- ItemMouseMove
29
+ ItemMouseMove,
30
+ MenuMouseLeave
30
31
  } = useSelect.stateChangeTypes;
31
32
  const defaultItemToString = item => {
32
33
  if (typeof item === 'string') {
@@ -111,6 +112,7 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
111
112
  }
112
113
  return changes;
113
114
  case ItemMouseMove:
115
+ case MenuMouseLeave:
114
116
  return {
115
117
  ...changes,
116
118
  highlightedIndex: state.highlightedIndex
@@ -8,12 +8,11 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default from 'react';
11
- import Button from '../Button/Button.js';
12
- import '../Button/Button.Skeleton.js';
13
11
  import cx from 'classnames';
14
12
  import '../Tooltip/DefinitionTooltip.js';
15
13
  import { Tooltip } from '../Tooltip/Tooltip.js';
16
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
+ import ButtonBase from '../Button/ButtonBase.js';
17
16
 
18
17
  const IconButtonKinds = ['primary', 'secondary', 'ghost', 'tertiary'];
19
18
  const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_ref, ref) {
@@ -45,7 +44,7 @@ const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_r
45
44
  enterDelayMs: enterDelayMs,
46
45
  label: label,
47
46
  leaveDelayMs: leaveDelayMs
48
- }, /*#__PURE__*/React__default.createElement(Button, _extends({}, rest, {
47
+ }, /*#__PURE__*/React__default.createElement(ButtonBase, _extends({}, rest, {
49
48
  disabled: disabled,
50
49
  kind: kind,
51
50
  ref: ref,
@@ -32,6 +32,8 @@ const Menu = /*#__PURE__*/forwardRef(function Menu(_ref, forwardRef) {
32
32
  onOpen,
33
33
  open,
34
34
  size = 'sm',
35
+ // TODO: #16004
36
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
35
37
  target = document.body,
36
38
  x = 0,
37
39
  y = 0,
@@ -226,11 +226,11 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
226
226
  };
227
227
  }, []);
228
228
 
229
- // Slug is always size `lg`
229
+ // Slug is always size `sm`
230
230
  let normalizedSlug;
231
231
  if (slug && slug['type']?.displayName === 'Slug') {
232
232
  normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
233
- size: 'lg'
233
+ size: 'sm'
234
234
  });
235
235
  }
236
236
  const modalButton = /*#__PURE__*/React__default.createElement("div", {
@@ -59,7 +59,7 @@ export default class ModalWrapper extends React.Component<ModalWrapperProps, Mod
59
59
  shouldCloseAfterSubmit: PropTypes.Requireable<boolean>;
60
60
  status: PropTypes.Requireable<string>;
61
61
  triggerButtonIconDescription: PropTypes.Requireable<string>;
62
- triggerButtonKind: PropTypes.Requireable<"primary" | "secondary" | "ghost" | "tertiary" | "danger" | "danger--primary" | "danger--ghost" | "danger--tertiary">;
62
+ triggerButtonKind: PropTypes.Requireable<"primary" | "secondary" | "danger" | "ghost" | "danger--primary" | "danger--ghost" | "danger--tertiary" | "tertiary">;
63
63
  withHeader: PropTypes.Requireable<boolean>;
64
64
  };
65
65
  triggerButton: React.RefObject<HTMLButtonElement>;
@@ -137,6 +137,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
137
137
  if (onMenuChange) {
138
138
  onMenuChange(nextIsOpen);
139
139
  }
140
+ if (!isOpen) {
141
+ setHighlightedIndex(0);
142
+ }
140
143
  }
141
144
  function handleOnOuterClick() {
142
145
  handleOnMenuChange(false);
@@ -160,6 +163,34 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
160
163
  break;
161
164
  case stateChangeTypes.keyDownEscape:
162
165
  handleOnMenuChange(false);
166
+ setHighlightedIndex(0);
167
+ break;
168
+ case stateChangeTypes.changeInput:
169
+ setHighlightedIndex(0);
170
+ break;
171
+ case stateChangeTypes.keyDownEnter:
172
+ if (!isOpen) {
173
+ setHighlightedIndex(0);
174
+ }
175
+ break;
176
+ case stateChangeTypes.clickItem:
177
+ if (isOpen) {
178
+ const sortedItems = sortItems(filterItems(items, {
179
+ itemToString,
180
+ inputValue
181
+ }), {
182
+ selectedItems: {
183
+ top: changes.selectedItems,
184
+ fixed: [],
185
+ 'top-after-reopen': topItems
186
+ }[selectionFeedback],
187
+ itemToString,
188
+ compareItems,
189
+ locale
190
+ });
191
+ const sortedSelectedIndex = sortedItems.indexOf(changes.selectedItem);
192
+ setHighlightedIndex(sortedSelectedIndex);
193
+ }
163
194
  break;
164
195
  }
165
196
  }
@@ -37,9 +37,11 @@ const {
37
37
  ToggleButtonKeyDownEscape,
38
38
  ToggleButtonKeyDownSpaceButton,
39
39
  ItemMouseMove,
40
+ MenuMouseLeave,
40
41
  ToggleButtonClick,
41
- ToggleButtonKeyDownHome,
42
- ToggleButtonKeyDownEnd
42
+ ToggleButtonKeyDownPageDown,
43
+ ToggleButtonKeyDownPageUp,
44
+ FunctionSetHighlightedIndex
43
45
  } = useSelect.stateChangeTypes;
44
46
  const defaultItemToString = item => {
45
47
  if (typeof item === 'string') {
@@ -135,7 +137,8 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
135
137
  getMenuProps,
136
138
  getItemProps,
137
139
  selectedItem,
138
- highlightedIndex
140
+ highlightedIndex,
141
+ setHighlightedIndex
139
142
  } = useSelect(selectProps);
140
143
  const toggleButtonProps = getToggleButtonProps({
141
144
  onFocus: () => {
@@ -154,6 +157,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
154
157
  setItemsCleared(true);
155
158
  }
156
159
  if ((match(e, Space) || match(e, ArrowDown) || match(e, Enter)) && !isOpen) {
160
+ setHighlightedIndex(0);
157
161
  setItemsCleared(false);
158
162
  setIsOpenWrapper(true);
159
163
  }
@@ -237,7 +241,6 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
237
241
  setTopItems(controlledSelectedItems);
238
242
  }
239
243
  switch (type) {
240
- case ItemClick:
241
244
  case ToggleButtonKeyDownSpaceButton:
242
245
  case ToggleButtonKeyDownEnter:
243
246
  if (changes.selectedItem === undefined) {
@@ -257,11 +260,38 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
257
260
  break;
258
261
  case ToggleButtonClick:
259
262
  setIsOpenWrapper(changes.isOpen || false);
260
- break;
263
+ return {
264
+ ...changes,
265
+ highlightedIndex: 0
266
+ };
267
+ case ItemClick:
268
+ setHighlightedIndex(changes.selectedItem);
269
+ onItemChange(changes.selectedItem);
270
+ return {
271
+ ...changes,
272
+ highlightedIndex: state.highlightedIndex
273
+ };
274
+ case MenuMouseLeave:
275
+ return {
276
+ ...changes,
277
+ highlightedIndex: state.highlightedIndex
278
+ };
279
+ case FunctionSetHighlightedIndex:
280
+ if (!isOpen) {
281
+ return {
282
+ ...changes,
283
+ highlightedIndex: 0
284
+ };
285
+ } else {
286
+ return {
287
+ ...changes,
288
+ highlightedIndex: props.items.indexOf(highlightedIndex)
289
+ };
290
+ }
261
291
  case ToggleButtonKeyDownArrowDown:
262
292
  case ToggleButtonKeyDownArrowUp:
263
- case ToggleButtonKeyDownHome:
264
- case ToggleButtonKeyDownEnd:
293
+ case ToggleButtonKeyDownPageDown:
294
+ case ToggleButtonKeyDownPageUp:
265
295
  if (highlightedIndex > -1) {
266
296
  const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
267
297
  props.scrollIntoView(itemArray[highlightedIndex]);
@@ -7,9 +7,10 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React__default from 'react';
10
+ import React__default, { useState } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { usePrefix } from '../../internal/usePrefix.js';
13
+ import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
13
14
  import { LowerHandle, UpperHandle } from './SliderHandles.js';
14
15
 
15
16
  var _LowerHandle, _UpperHandle, _UpperHandle2, _LowerHandle2;
@@ -21,7 +22,10 @@ const SliderSkeleton = _ref => {
21
22
  ...rest
22
23
  } = _ref;
23
24
  const prefix = usePrefix();
24
- const isRtl = document?.dir === 'rtl';
25
+ const [isRtl, setIsRtl] = useState(false);
26
+ useIsomorphicEffect(() => {
27
+ setIsRtl(document ? document.dir === 'rtl' : false);
28
+ }, []);
25
29
  const containerClasses = cx(`${prefix}--slider-container`, `${prefix}--skeleton`, {
26
30
  [`${prefix}--slider-container--two-handles`]: twoHandles,
27
31
  [`${prefix}--slider-container--rtl`]: isRtl
@@ -138,26 +138,21 @@ Slug.propTypes = {
138
138
  */
139
139
  align: PropTypes.oneOf(['top', 'top-left',
140
140
  // deprecated use top-start instead
141
- 'top-right',
141
+ 'top-start', 'top-right',
142
142
  // deprecated use top-end instead
143
-
144
- 'bottom', 'bottom-left',
143
+ 'top-end', 'bottom', 'bottom-left',
145
144
  // deprecated use bottom-start instead
146
- 'bottom-right',
145
+ 'bottom-start', 'bottom-right',
147
146
  // deprecated use bottom-end instead
148
-
149
- 'left', 'left-bottom',
147
+ 'bottom-end', 'left', 'left-bottom',
150
148
  // deprecated use left-end instead
151
- 'left-top',
149
+ 'left-end', 'left-top',
152
150
  // deprecated use left-start instead
153
-
154
- 'right', 'right-bottom',
151
+ 'left-start', 'right', 'right-bottom',
155
152
  // deprecated use right-end instead
156
- 'right-top',
153
+ 'right-end', 'right-top',
157
154
  // deprecated use right-start instead
158
-
159
- // new values to match floating-ui
160
- 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
155
+ 'right-start']),
161
156
  /**
162
157
  * Will auto-align the popover. This prop is currently experimental and is subject to future changes.
163
158
  */
@@ -144,6 +144,10 @@ export interface StructuredListRowProps extends DivAttrs {
144
144
  * Provide a handler that is invoked on the key down event for the control
145
145
  */
146
146
  onKeyDown?(event: KeyboardEvent): void;
147
+ /**
148
+ * Mark if this row should be selectable
149
+ */
150
+ selection?: boolean;
147
151
  }
148
152
  export declare function StructuredListRow(props: StructuredListRowProps): import("react/jsx-runtime").JSX.Element;
149
153
  export declare namespace StructuredListRow {
@@ -172,6 +176,10 @@ export declare namespace StructuredListRow {
172
176
  * Provide a handler that is invoked on the key down event for the control,
173
177
  */
174
178
  onKeyDown: PropTypes.Requireable<(...args: any[]) => any>;
179
+ /**
180
+ * Mark if this row should be selectable
181
+ */
182
+ selection: PropTypes.Requireable<boolean>;
175
183
  };
176
184
  }
177
185
  export interface StructuredListInputProps extends DivAttrs {
@@ -6,15 +6,18 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useState } from 'react';
9
+ import React__default, { useState, useRef } from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import cx from 'classnames';
12
12
  import { useId } from '../../internal/useId.js';
13
13
  import deprecate from '../../prop-types/deprecate.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import '../Text/index.js';
16
+ import { RadioButtonChecked, RadioButton } from '@carbon/icons-react';
17
+ import { useOutsideClick } from '../../internal/useOutsideClick.js';
16
18
  import { Text } from '../Text/Text.js';
17
19
 
20
+ var _StructuredListCell, _RadioButtonChecked, _RadioButton;
18
21
  const GridSelectedRowStateContext = /*#__PURE__*/React__default.createContext(null);
19
22
  const GridSelectedRowDispatchContext = /*#__PURE__*/React__default.createContext(null);
20
23
  function StructuredListWrapper(props) {
@@ -137,6 +140,7 @@ function StructuredListRow(props) {
137
140
  className,
138
141
  head,
139
142
  onClick,
143
+ selection,
140
144
  ...other
141
145
  } = props;
142
146
  const [hasFocusWithin, setHasFocusWithin] = useState(false);
@@ -149,25 +153,35 @@ function StructuredListRow(props) {
149
153
  };
150
154
  const classes = cx(`${prefix}--structured-list-row`, {
151
155
  [`${prefix}--structured-list-row--header-row`]: head,
152
- [`${prefix}--structured-list-row--focused-within`]: hasFocusWithin,
156
+ [`${prefix}--structured-list-row--focused-within`]: hasFocusWithin && !selection || hasFocusWithin && selection && (selectedRow === id || selectedRow === null),
157
+ // Ensure focus on the first item when navigating through Tab keys and no row is selected (selectedRow === null)
153
158
  [`${prefix}--structured-list-row--selected`]: selectedRow === id
154
159
  }, className);
160
+ const itemRef = useRef(null);
161
+ const handleClick = () => {
162
+ setHasFocusWithin(false);
163
+ };
164
+ useOutsideClick(itemRef, handleClick);
155
165
  return head ? /*#__PURE__*/React__default.createElement("div", _extends({
156
166
  role: "row"
157
167
  }, other, {
158
- className: classes,
159
- "aria-busy": "true"
160
- }), children) :
168
+ className: classes
169
+ }), selection && (_StructuredListCell || (_StructuredListCell = /*#__PURE__*/React__default.createElement(StructuredListCell, {
170
+ head: true
171
+ }))), children) :
161
172
  /*#__PURE__*/
162
173
  // eslint-disable-next-line jsx-a11y/interactive-supports-focus
163
- React__default.createElement("div", _extends({
164
- "aria-busy": "true"
165
- }, other, {
174
+ React__default.createElement("div", _extends({}, other, {
166
175
  role: "row",
167
176
  className: classes,
177
+ ref: itemRef,
168
178
  onClick: event => {
169
179
  setSelectedRow?.(id);
170
180
  onClick && onClick(event);
181
+ if (selection) {
182
+ // focus items only when selection is enabled
183
+ setHasFocusWithin(true);
184
+ }
171
185
  },
172
186
  onFocus: () => {
173
187
  setHasFocusWithin(true);
@@ -178,7 +192,7 @@ function StructuredListRow(props) {
178
192
  onKeyDown: onKeyDown
179
193
  }), /*#__PURE__*/React__default.createElement(GridRowContext.Provider, {
180
194
  value: value
181
- }, children));
195
+ }, selection && /*#__PURE__*/React__default.createElement(StructuredListCell, null, selectedRow === id ? _RadioButtonChecked || (_RadioButtonChecked = /*#__PURE__*/React__default.createElement(RadioButtonChecked, null)) : _RadioButton || (_RadioButton = /*#__PURE__*/React__default.createElement(RadioButton, null))), children));
182
196
  }
183
197
  StructuredListRow.propTypes = {
184
198
  /**
@@ -204,7 +218,11 @@ StructuredListRow.propTypes = {
204
218
  /**
205
219
  * Provide a handler that is invoked on the key down event for the control,
206
220
  */
207
- onKeyDown: PropTypes.func
221
+ onKeyDown: PropTypes.func,
222
+ /**
223
+ * Mark if this row should be selectable
224
+ */
225
+ selection: PropTypes.bool
208
226
  };
209
227
  function StructuredListInput(props) {
210
228
  const defaultId = useId('structureListInput');
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 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
+
8
+ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import PropTypes from 'prop-types';
10
+ import React__default from 'react';
11
+ import cx from 'classnames';
12
+ import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
13
+ import { usePrefix } from '../../internal/usePrefix.js';
14
+ import Tag, { SIZES, TYPES } from './Tag.js';
15
+ import { Close } from '@carbon/icons-react';
16
+
17
+ var _Close;
18
+ const getInstanceId = setupGetInstanceId();
19
+ const DismissibleTag = _ref => {
20
+ let {
21
+ children,
22
+ className,
23
+ disabled,
24
+ id,
25
+ renderIcon,
26
+ title = 'Clear filter',
27
+ onClose,
28
+ slug,
29
+ size,
30
+ type,
31
+ ...other
32
+ } = _ref;
33
+ const prefix = usePrefix();
34
+ const tagId = id || `tag-${getInstanceId()}`;
35
+ const tagClasses = cx(`${prefix}--tag--filter`, className);
36
+ const handleClose = event => {
37
+ if (onClose) {
38
+ event.stopPropagation();
39
+ onClose(event);
40
+ }
41
+ };
42
+ let normalizedSlug;
43
+ if (slug && slug['type']?.displayName === 'Slug') {
44
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
45
+ size: 'sm',
46
+ kind: 'inline'
47
+ });
48
+ }
49
+
50
+ // Removing onClick from the spread operator
51
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
52
+ const {
53
+ onClick,
54
+ ...otherProps
55
+ } = other;
56
+ return /*#__PURE__*/React__default.createElement(Tag, _extends({
57
+ type: type,
58
+ size: size,
59
+ renderIcon: renderIcon,
60
+ disabled: disabled,
61
+ className: tagClasses,
62
+ id: tagId
63
+ }, otherProps), /*#__PURE__*/React__default.createElement("div", {
64
+ className: `${prefix}--interactive--tag-children`
65
+ }, children, normalizedSlug, /*#__PURE__*/React__default.createElement("button", {
66
+ type: "button",
67
+ className: `${prefix}--tag__close-icon`,
68
+ onClick: handleClose,
69
+ disabled: disabled,
70
+ "aria-label": title,
71
+ title: title
72
+ }, _Close || (_Close = /*#__PURE__*/React__default.createElement(Close, null)))));
73
+ };
74
+ DismissibleTag.propTypes = {
75
+ /**
76
+ * Provide content to be rendered inside of a `DismissibleTag`
77
+ */
78
+ children: PropTypes.node,
79
+ /**
80
+ * Provide a custom className that is applied to the containing <span>
81
+ */
82
+ className: PropTypes.string,
83
+ /**
84
+ * Specify if the `DismissibleTag` is disabled
85
+ */
86
+ disabled: PropTypes.bool,
87
+ /**
88
+ * Specify the id for the tag.
89
+ */
90
+ id: PropTypes.string,
91
+ /**
92
+ * Click handler for filter tag close button.
93
+ */
94
+ onClose: PropTypes.func,
95
+ /**
96
+ * Optional prop to render a custom icon.
97
+ * Can be a React component class
98
+ */
99
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
100
+ /**
101
+ * Specify the size of the Tag. Currently supports either `sm`,
102
+ * `md` (default) or `lg` sizes.
103
+ */
104
+ size: PropTypes.oneOf(Object.keys(SIZES)),
105
+ /**
106
+ * **Experimental:** Provide a `Slug` component to be rendered inside the `DismissibleTag` component
107
+ */
108
+ slug: PropTypes.node,
109
+ /**
110
+ * Text to show on clear filters
111
+ */
112
+ title: PropTypes.string,
113
+ /**
114
+ * Specify the type of the `Tag`
115
+ */
116
+ type: PropTypes.oneOf(Object.keys(TYPES))
117
+ };
118
+
119
+ export { DismissibleTag as default };