@carbon/react 1.54.0-rc.0 → 1.54.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 (32) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +822 -822
  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.js +1 -0
  7. package/es/components/IconButton/index.js +2 -3
  8. package/es/components/Menu/Menu.js +2 -0
  9. package/es/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  10. package/es/components/Slider/Slider.Skeleton.js +6 -2
  11. package/es/components/StructuredList/StructuredList.d.ts +8 -0
  12. package/es/components/StructuredList/StructuredList.js +28 -10
  13. package/es/feature-flags.js +2 -1
  14. package/es/internal/environment.js +5 -1
  15. package/es/internal/keyboard/navigation.js +6 -2
  16. package/es/internal/useOutsideClick.js +31 -0
  17. package/lib/components/Button/Button.d.ts +1 -1
  18. package/lib/components/Button/Button.js +13 -90
  19. package/lib/components/Button/ButtonBase.d.ts +10 -0
  20. package/lib/components/Button/ButtonBase.js +119 -0
  21. package/lib/components/CodeSnippet/CodeSnippet.js +1 -0
  22. package/lib/components/IconButton/index.js +2 -3
  23. package/lib/components/Menu/Menu.js +2 -0
  24. package/lib/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  25. package/lib/components/Slider/Slider.Skeleton.js +5 -1
  26. package/lib/components/StructuredList/StructuredList.d.ts +8 -0
  27. package/lib/components/StructuredList/StructuredList.js +27 -9
  28. package/lib/feature-flags.js +2 -1
  29. package/lib/internal/environment.js +5 -1
  30. package/lib/internal/keyboard/navigation.js +6 -2
  31. package/lib/internal/useOutsideClick.js +35 -0
  32. package/package.json +6 -6
@@ -14,7 +14,7 @@ export declare const ButtonTooltipAlignments: readonly ["start", "center", "end"
14
14
  export type ButtonTooltipAlignment = (typeof ButtonTooltipAlignments)[number];
15
15
  export declare const ButtonTooltipPositions: string[];
16
16
  export type ButtonTooltipPosition = (typeof ButtonTooltipPositions)[number];
17
- interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
17
+ export interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
18
18
  /**
19
19
  * Specify the message read by screen readers for the danger button variant
20
20
  */
@@ -8,11 +8,9 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default, { useRef } from 'react';
11
- import cx from 'classnames';
12
11
  import { IconButton } from '../IconButton/index.js';
13
12
  import { composeEventHandlers } from '../../tools/events.js';
14
- import { usePrefix } from '../../internal/usePrefix.js';
15
- import { useId } from '../../internal/useId.js';
13
+ import ButtonBase from './ButtonBase.js';
16
14
 
17
15
  const ButtonKinds = ['primary', 'secondary', 'danger', 'ghost', 'danger--primary', 'danger--ghost', 'danger--tertiary', 'tertiary'];
18
16
  const ButtonSizes = ['sm', 'md', 'lg', 'xl', '2xl'];
@@ -24,18 +22,13 @@ function isIconOnlyButton(hasIconOnly, _kind) {
24
22
  }
25
23
  return false;
26
24
  }
27
- const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref) {
28
- let {
25
+ const Button = /*#__PURE__*/React__default.forwardRef(function Button(props, ref) {
26
+ const tooltipRef = useRef(null);
27
+ const {
29
28
  as,
30
29
  children,
31
- className,
32
- dangerDescription = 'danger',
33
- disabled = false,
34
30
  hasIconOnly = false,
35
- href,
36
31
  iconDescription,
37
- isExpressive = false,
38
- isSelected,
39
32
  kind = 'primary',
40
33
  onBlur,
41
34
  onClick,
@@ -44,92 +37,21 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
44
37
  onMouseLeave,
45
38
  renderIcon: ButtonImageElement,
46
39
  size,
47
- tabIndex,
48
40
  tooltipAlignment = 'center',
49
41
  tooltipPosition = 'top',
50
- type = 'button',
51
42
  ...rest
52
- } = _ref;
53
- const tooltipRef = useRef(null);
54
- const prefix = usePrefix();
43
+ } = props;
55
44
  const handleClick = evt => {
56
45
  // Prevent clicks on the tooltip from triggering the button click event
57
46
  if (evt.target === tooltipRef.current) {
58
47
  evt.preventDefault();
59
48
  }
60
49
  };
61
- const buttonClasses = cx(className, {
62
- [`${prefix}--btn`]: true,
63
- [`${prefix}--btn--sm`]: size === 'sm' && !isExpressive,
64
- // TODO: V12 - Remove this class
65
- [`${prefix}--btn--md`]: size === 'md' && !isExpressive,
66
- // TODO: V12 - Remove this class
67
- [`${prefix}--btn--xl`]: size === 'xl',
68
- // TODO: V12 - Remove this class
69
- [`${prefix}--btn--2xl`]: size === '2xl',
70
- // TODO: V12 - Remove this class
71
- [`${prefix}--layout--size-${size}`]: size,
72
- [`${prefix}--btn--${kind}`]: kind,
73
- [`${prefix}--btn--disabled`]: disabled,
74
- [`${prefix}--btn--expressive`]: isExpressive,
75
- [`${prefix}--btn--icon-only`]: hasIconOnly,
76
- [`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost'
77
- });
78
- const commonProps = {
79
- tabIndex,
80
- className: buttonClasses,
81
- ref
82
- };
83
- const buttonImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, {
84
- "aria-label": iconDescription,
85
- className: `${prefix}--btn__icon`,
86
- "aria-hidden": "true"
87
- });
88
50
  const iconOnlyImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, null);
89
- const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost'];
90
- let component = 'button';
91
- const assistiveId = useId('danger-description');
92
- const {
93
- 'aria-pressed': ariaPressed,
94
- 'aria-describedby': ariaDescribedBy
95
- } = rest;
96
- let otherProps = {
97
- disabled,
98
- type,
99
- 'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : ariaDescribedBy || undefined,
100
- 'aria-pressed': ariaPressed ?? (hasIconOnly && kind === 'ghost' ? isSelected : undefined)
101
- };
102
- const anchorProps = {
103
- href
104
- };
105
- let assistiveText = null;
106
- if (dangerButtonVariants.includes(kind)) {
107
- assistiveText = /*#__PURE__*/React__default.createElement("span", {
108
- id: assistiveId,
109
- className: `${prefix}--visually-hidden`
110
- }, dangerDescription);
111
- }
112
- if (as) {
113
- component = as;
114
- otherProps = {
115
- ...otherProps,
116
- ...anchorProps
117
- };
118
- } else if (href && !disabled) {
119
- component = 'a';
120
- otherProps = anchorProps;
121
- }
122
51
  if (!isIconOnlyButton(hasIconOnly)) {
123
- return /*#__PURE__*/React__default.createElement(component, {
124
- onMouseEnter,
125
- onMouseLeave,
126
- onFocus,
127
- onBlur,
128
- onClick,
129
- ...rest,
130
- ...commonProps,
131
- ...otherProps
132
- }, assistiveText, children, buttonImage);
52
+ return /*#__PURE__*/React__default.createElement(ButtonBase, _extends({
53
+ ref: ref
54
+ }, props));
133
55
  } else {
134
56
  let align = undefined;
135
57
  if (tooltipPosition === 'top' || tooltipPosition === 'bottom') {
@@ -146,7 +68,8 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
146
68
  if (tooltipPosition === 'right' || tooltipPosition === 'left') {
147
69
  align = tooltipPosition;
148
70
  }
149
- return /*#__PURE__*/React__default.createElement(IconButton, _extends({
71
+ return /*#__PURE__*/React__default.createElement(IconButton, _extends({}, rest, {
72
+ ref: ref,
150
73
  as: as,
151
74
  align: align,
152
75
  label: iconDescription,
@@ -156,8 +79,9 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
156
79
  onMouseLeave: onMouseLeave,
157
80
  onFocus: onFocus,
158
81
  onBlur: onBlur,
159
- onClick: composeEventHandlers([onClick, handleClick])
160
- }, rest, commonProps, otherProps), iconOnlyImage ?? children);
82
+ onClick: composeEventHandlers([onClick, handleClick]),
83
+ renderIcon: iconOnlyImage ? null : ButtonImageElement // avoid doubling the icon.
84
+ }), iconOnlyImage ?? children);
161
85
  }
162
86
  });
163
87
  Button.displayName = 'Button';
@@ -0,0 +1,10 @@
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
+ import React from 'react';
8
+ import { ButtonProps } from './Button';
9
+ declare const ButtonBase: React.ForwardRefExoticComponent<Omit<ButtonProps<React.ElementType<any>>, "ref"> & React.RefAttributes<unknown>>;
10
+ export default ButtonBase;
@@ -0,0 +1,110 @@
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 React__default from 'react';
9
+ import cx from 'classnames';
10
+ import { usePrefix } from '../../internal/usePrefix.js';
11
+ import { useId } from '../../internal/useId.js';
12
+
13
+ const ButtonBase = /*#__PURE__*/React__default.forwardRef(function ButtonBase(_ref, ref) {
14
+ let {
15
+ as,
16
+ children,
17
+ className,
18
+ dangerDescription = 'danger',
19
+ disabled = false,
20
+ hasIconOnly = false,
21
+ href,
22
+ iconDescription,
23
+ isExpressive = false,
24
+ isSelected,
25
+ kind = 'primary',
26
+ onBlur,
27
+ onClick,
28
+ onFocus,
29
+ onMouseEnter,
30
+ onMouseLeave,
31
+ renderIcon: ButtonImageElement,
32
+ size,
33
+ tabIndex,
34
+ type = 'button',
35
+ ...rest
36
+ } = _ref;
37
+ const prefix = usePrefix();
38
+ const buttonClasses = cx(className, {
39
+ [`${prefix}--btn`]: true,
40
+ [`${prefix}--btn--sm`]: size === 'sm' && !isExpressive,
41
+ // TODO: V12 - Remove this class
42
+ [`${prefix}--btn--md`]: size === 'md' && !isExpressive,
43
+ // TODO: V12 - Remove this class
44
+ [`${prefix}--btn--xl`]: size === 'xl',
45
+ // TODO: V12 - Remove this class
46
+ [`${prefix}--btn--2xl`]: size === '2xl',
47
+ // TODO: V12 - Remove this class
48
+ [`${prefix}--layout--size-${size}`]: size,
49
+ [`${prefix}--btn--${kind}`]: kind,
50
+ [`${prefix}--btn--disabled`]: disabled,
51
+ [`${prefix}--btn--expressive`]: isExpressive,
52
+ [`${prefix}--btn--icon-only`]: hasIconOnly && !className?.includes(`${prefix}--btn--icon-only`),
53
+ [`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost'
54
+ });
55
+ const commonProps = {
56
+ tabIndex,
57
+ className: buttonClasses,
58
+ ref
59
+ };
60
+ const buttonImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, {
61
+ "aria-label": iconDescription,
62
+ className: `${prefix}--btn__icon`,
63
+ "aria-hidden": "true"
64
+ });
65
+ const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost'];
66
+ let component = 'button';
67
+ const assistiveId = useId('danger-description');
68
+ const {
69
+ 'aria-pressed': ariaPressed,
70
+ 'aria-describedby': ariaDescribedBy
71
+ } = rest;
72
+ let otherProps = {
73
+ disabled,
74
+ type,
75
+ 'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : ariaDescribedBy || undefined,
76
+ 'aria-pressed': ariaPressed ?? (hasIconOnly && kind === 'ghost' ? isSelected : undefined)
77
+ };
78
+ const anchorProps = {
79
+ href
80
+ };
81
+ let assistiveText = null;
82
+ if (dangerButtonVariants.includes(kind)) {
83
+ assistiveText = /*#__PURE__*/React__default.createElement("span", {
84
+ id: assistiveId,
85
+ className: `${prefix}--visually-hidden`
86
+ }, dangerDescription);
87
+ }
88
+ if (as) {
89
+ component = as;
90
+ otherProps = {
91
+ ...otherProps,
92
+ ...anchorProps
93
+ };
94
+ } else if (href && !disabled) {
95
+ component = 'a';
96
+ otherProps = anchorProps;
97
+ }
98
+ return /*#__PURE__*/React__default.createElement(component, {
99
+ onMouseEnter,
100
+ onMouseLeave,
101
+ onFocus,
102
+ onBlur,
103
+ onClick,
104
+ ...rest,
105
+ ...commonProps,
106
+ ...otherProps
107
+ }, assistiveText, children, buttonImage);
108
+ });
109
+
110
+ export { ButtonBase as default };
@@ -155,6 +155,7 @@ function CodeSnippet(_ref) {
155
155
  feedback: feedback,
156
156
  feedbackTimeout: feedbackTimeout
157
157
  }), /*#__PURE__*/React__default.createElement("code", {
158
+ "aria-live": "assertive",
158
159
  id: uid,
159
160
  ref: innerCodeRef
160
161
  }, children));
@@ -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,
@@ -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>;
@@ -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
@@ -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');
@@ -12,5 +12,6 @@ FeatureFlags.merge({
12
12
  'enable-css-grid': true,
13
13
  'enable-v11-release': true,
14
14
  'enable-experimental-tile-contrast': false,
15
- 'enable-v12-tile-radio-icons': false
15
+ 'enable-v12-tile-radio-icons': false,
16
+ 'enable-v12-structured-list-visible-icons': false
16
17
  });
@@ -10,6 +10,10 @@
10
10
  *
11
11
  * @see https://github.com/facebook/fbjs/blob/4d1751311d3f67af2dcce2e40df8512a23c7b9c6/packages/fbjs/src/core/ExecutionEnvironment.js#L12
12
12
  */
13
- const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
13
+ const canUseDOM = !!(typeof window !== 'undefined' &&
14
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
15
+ window.document &&
16
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
17
+ window.document.createElement);
14
18
 
15
19
  export { canUseDOM };
@@ -39,7 +39,9 @@ const getNextIndex = (key, index, arrayLength) => {
39
39
  */
40
40
  const DOCUMENT_POSITION_BROAD_PRECEDING =
41
41
  // Checks `typeof Node` for `react-docgen`
42
- typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS;
42
+ typeof Node !== 'undefined' &&
43
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
44
+ Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS;
43
45
 
44
46
  /**
45
47
  * A flag `node.compareDocumentPosition(target)` returns,
@@ -47,7 +49,9 @@ typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_
47
49
  */
48
50
  const DOCUMENT_POSITION_BROAD_FOLLOWING =
49
51
  // Checks `typeof Node` for `react-docgen`
50
- typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY;
52
+ typeof Node !== 'undefined' &&
53
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
54
+ Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY;
51
55
 
52
56
  /**
53
57
  * CSS selector that selects major nodes that are sequential-focusable.
@@ -0,0 +1,31 @@
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 { useRef, useEffect } from 'react';
9
+ import { useEvent } from './useEvent.js';
10
+ import { canUseDOM } from './environment.js';
11
+
12
+ function useOutsideClick(ref, callback) {
13
+ const savedCallback = useRef(callback);
14
+ useEffect(() => {
15
+ savedCallback.current = callback;
16
+ });
17
+
18
+ // We conditionally guard the `useEvent` hook for SSR. `canUseDOM` can be
19
+ // treated as a constant as it will be false when executed in a Node.js
20
+ // environment and true when executed in the browser
21
+ if (canUseDOM) {
22
+ // eslint-disable-next-line react-hooks/rules-of-hooks
23
+ useEvent(window, 'click', event => {
24
+ if (ref.current && !ref.current.contains(event.target)) {
25
+ savedCallback.current(event);
26
+ }
27
+ });
28
+ }
29
+ }
30
+
31
+ export { useOutsideClick };
@@ -14,7 +14,7 @@ export declare const ButtonTooltipAlignments: readonly ["start", "center", "end"
14
14
  export type ButtonTooltipAlignment = (typeof ButtonTooltipAlignments)[number];
15
15
  export declare const ButtonTooltipPositions: string[];
16
16
  export type ButtonTooltipPosition = (typeof ButtonTooltipPositions)[number];
17
- interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
17
+ export interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
18
18
  /**
19
19
  * Specify the message read by screen readers for the danger button variant
20
20
  */