@carbon/react 1.84.0-rc.0 → 1.85.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.
- package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +943 -943
- package/es/components/AILabel/index.js +6 -1
- package/es/components/Checkbox/Checkbox.d.ts +2 -2
- package/es/components/Checkbox/Checkbox.js +8 -8
- package/es/components/CheckboxGroup/CheckboxGroup.d.ts +2 -2
- package/es/components/CheckboxGroup/CheckboxGroup.js +9 -8
- package/es/components/CodeSnippet/CodeSnippet.js +2 -4
- package/es/components/ComboBox/ComboBox.d.ts +1 -1
- package/es/components/ComboBox/ComboBox.js +8 -7
- package/es/components/ComposedModal/ComposedModal.d.ts +1 -1
- package/es/components/ComposedModal/ComposedModal.js +34 -12
- package/es/components/ContainedList/ContainedList.d.ts +1 -1
- package/es/components/ContainedList/ContainedList.js +4 -2
- package/es/components/ContentSwitcher/ContentSwitcher.js +6 -5
- package/es/components/DataTable/DataTable.js +3 -0
- package/es/components/DataTable/TableDecoratorRow.d.ts +2 -2
- package/es/components/DataTable/TableDecoratorRow.js +8 -8
- package/es/components/DataTable/TableExpandRow.d.ts +1 -1
- package/es/components/DataTable/TableExpandRow.js +15 -6
- package/es/components/DataTable/TableHeader.js +10 -10
- package/es/components/DataTable/TableRow.js +12 -4
- package/es/components/DataTable/tools/normalize.js +2 -1
- package/es/components/DatePickerInput/DatePickerInput.js +8 -7
- package/es/components/Dialog/index.d.ts +5 -1
- package/es/components/Dialog/index.js +20 -0
- package/es/components/Dropdown/Dropdown.d.ts +1 -1
- package/es/components/Dropdown/Dropdown.js +8 -10
- package/es/components/FileUploader/FileUploaderButton.js +2 -2
- package/es/components/FileUploader/FileUploaderDropContainer.js +2 -2
- package/es/components/FileUploader/FileUploaderItem.js +2 -2
- package/es/components/Layer/index.d.ts +1 -3
- package/es/components/Layer/index.js +9 -8
- package/es/components/Menu/Menu.js +0 -6
- package/es/components/Modal/Modal.d.ts +2 -2
- package/es/components/Modal/Modal.js +39 -11
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +29 -7
- package/es/components/MultiSelect/MultiSelect.d.ts +1 -1
- package/es/components/MultiSelect/MultiSelect.js +8 -7
- package/es/components/NumberInput/NumberInput.d.ts +1 -1
- package/es/components/NumberInput/NumberInput.js +9 -8
- package/es/components/OverflowMenu/OverflowMenu.js +4 -5
- package/es/components/PageHeader/PageHeader.d.ts +10 -9
- package/es/components/PageHeader/PageHeader.js +94 -34
- package/es/components/PageHeader/index.d.ts +2 -2
- package/es/components/PageHeader/index.js +1 -1
- package/es/components/Popover/index.js +2 -1
- package/es/components/RadioButton/RadioButton.d.ts +2 -2
- package/es/components/RadioButton/RadioButton.js +8 -8
- package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +9 -8
- package/es/components/RadioTile/RadioTile.d.ts +1 -1
- package/es/components/RadioTile/RadioTile.js +8 -7
- package/es/components/Search/Search.js +0 -1
- package/es/components/Select/Select.d.ts +2 -2
- package/es/components/Select/Select.js +8 -7
- package/es/components/Slider/Slider.js +6 -0
- package/es/components/Tag/DismissibleTag.d.ts +1 -1
- package/es/components/Tag/DismissibleTag.js +9 -8
- package/es/components/Tag/Tag.d.ts +1 -1
- package/es/components/Tag/Tag.js +9 -8
- package/es/components/TextArea/TextArea.js +12 -11
- package/es/components/TextInput/TextInput.d.ts +1 -1
- package/es/components/TextInput/TextInput.js +20 -9
- package/es/components/Tile/Tile.d.ts +2 -2
- package/es/components/Tile/Tile.js +30 -36
- package/es/components/TileGroup/TileGroup.d.ts +4 -4
- package/es/components/TileGroup/TileGroup.js +45 -53
- package/es/components/TileGroup/index.d.ts +3 -3
- package/es/components/Toggletip/index.js +2 -2
- package/es/components/Tooltip/DefinitionTooltip.js +1 -0
- package/es/components/TreeView/TreeNode.js +3 -3
- package/es/components/TreeView/TreeView.js +3 -3
- package/es/components/UIShell/Content.d.ts +5 -3
- package/es/components/UIShell/HeaderMenuItem.js +2 -1
- package/es/components/UIShell/HeaderPanel.d.ts +2 -2
- package/es/components/UIShell/HeaderPanel.js +9 -5
- package/es/index.js +1 -1
- package/es/internal/Selection.js +8 -3
- package/es/internal/environment.js +1 -12
- package/es/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
- package/es/internal/useOverflowItems.d.ts +29 -0
- package/es/internal/useOverflowItems.js +122 -0
- package/es/internal/useResizeObserver.d.ts +1 -1
- package/es/internal/utils.d.ts +14 -0
- package/es/internal/utils.js +18 -0
- package/es/tools/uniqueId.d.ts +1 -6
- package/lib/components/AILabel/index.js +6 -1
- package/lib/components/Checkbox/Checkbox.d.ts +2 -2
- package/lib/components/Checkbox/Checkbox.js +7 -7
- package/lib/components/CheckboxGroup/CheckboxGroup.d.ts +2 -2
- package/lib/components/CheckboxGroup/CheckboxGroup.js +8 -7
- package/lib/components/CodeSnippet/CodeSnippet.js +2 -4
- package/lib/components/ComboBox/ComboBox.d.ts +1 -1
- package/lib/components/ComboBox/ComboBox.js +11 -10
- package/lib/components/ComposedModal/ComposedModal.d.ts +1 -1
- package/lib/components/ComposedModal/ComposedModal.js +35 -13
- package/lib/components/ContainedList/ContainedList.d.ts +1 -1
- package/lib/components/ContainedList/ContainedList.js +4 -2
- package/lib/components/ContentSwitcher/ContentSwitcher.js +5 -4
- package/lib/components/DataTable/DataTable.js +3 -0
- package/lib/components/DataTable/TableDecoratorRow.d.ts +2 -2
- package/lib/components/DataTable/TableDecoratorRow.js +8 -8
- package/lib/components/DataTable/TableExpandRow.d.ts +1 -1
- package/lib/components/DataTable/TableExpandRow.js +14 -5
- package/lib/components/DataTable/TableHeader.js +9 -9
- package/lib/components/DataTable/TableRow.js +11 -3
- package/lib/components/DataTable/tools/normalize.js +2 -1
- package/lib/components/DatePickerInput/DatePickerInput.js +7 -6
- package/lib/components/Dialog/index.d.ts +5 -1
- package/lib/components/Dialog/index.js +20 -0
- package/lib/components/Dropdown/Dropdown.d.ts +1 -1
- package/lib/components/Dropdown/Dropdown.js +12 -14
- package/lib/components/FileUploader/FileUploaderButton.js +2 -2
- package/lib/components/FileUploader/FileUploaderDropContainer.js +2 -2
- package/lib/components/FileUploader/FileUploaderItem.js +2 -2
- package/lib/components/Layer/index.d.ts +1 -3
- package/lib/components/Layer/index.js +9 -8
- package/lib/components/Menu/Menu.js +0 -6
- package/lib/components/Modal/Modal.d.ts +2 -2
- package/lib/components/Modal/Modal.js +47 -19
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +33 -11
- package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
- package/lib/components/MultiSelect/MultiSelect.js +13 -12
- package/lib/components/NumberInput/NumberInput.d.ts +1 -1
- package/lib/components/NumberInput/NumberInput.js +8 -7
- package/lib/components/OverflowMenu/OverflowMenu.js +4 -5
- package/lib/components/PageHeader/PageHeader.d.ts +10 -9
- package/lib/components/PageHeader/PageHeader.js +92 -34
- package/lib/components/PageHeader/index.d.ts +2 -2
- package/lib/components/PageHeader/index.js +0 -2
- package/lib/components/Popover/index.js +2 -1
- package/lib/components/RadioButton/RadioButton.d.ts +2 -2
- package/lib/components/RadioButton/RadioButton.js +7 -7
- package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +10 -9
- package/lib/components/RadioTile/RadioTile.d.ts +1 -1
- package/lib/components/RadioTile/RadioTile.js +7 -6
- package/lib/components/Search/Search.js +0 -1
- package/lib/components/Select/Select.d.ts +2 -2
- package/lib/components/Select/Select.js +7 -6
- package/lib/components/Slider/Slider.js +6 -0
- package/lib/components/Tag/DismissibleTag.d.ts +1 -1
- package/lib/components/Tag/DismissibleTag.js +8 -7
- package/lib/components/Tag/Tag.d.ts +1 -1
- package/lib/components/Tag/Tag.js +8 -7
- package/lib/components/TextArea/TextArea.js +11 -10
- package/lib/components/TextInput/TextInput.d.ts +1 -1
- package/lib/components/TextInput/TextInput.js +19 -8
- package/lib/components/Tile/Tile.d.ts +2 -2
- package/lib/components/Tile/Tile.js +29 -35
- package/lib/components/TileGroup/TileGroup.d.ts +4 -4
- package/lib/components/TileGroup/TileGroup.js +44 -52
- package/lib/components/TileGroup/index.d.ts +3 -3
- package/lib/components/Toggletip/index.js +2 -2
- package/lib/components/Tooltip/DefinitionTooltip.js +1 -0
- package/lib/components/TreeView/TreeNode.js +3 -3
- package/lib/components/TreeView/TreeView.js +3 -3
- package/lib/components/UIShell/Content.d.ts +5 -3
- package/lib/components/UIShell/HeaderMenuItem.js +2 -1
- package/lib/components/UIShell/HeaderPanel.d.ts +2 -2
- package/lib/components/UIShell/HeaderPanel.js +8 -4
- package/lib/index.js +1 -1
- package/lib/internal/Selection.js +8 -3
- package/lib/internal/environment.js +1 -12
- package/lib/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
- package/lib/internal/useOverflowItems.d.ts +29 -0
- package/lib/internal/useOverflowItems.js +126 -0
- package/lib/internal/useResizeObserver.d.ts +1 -1
- package/lib/internal/utils.d.ts +14 -0
- package/lib/internal/utils.js +22 -0
- package/lib/tools/uniqueId.d.ts +1 -6
- package/package.json +14 -23
- package/telemetry.yml +3 -0
- package/es/tools/uniqueId.js +0 -14
- package/lib/tools/uniqueId.js +0 -18
|
@@ -35,6 +35,7 @@ const DialogContext = /*#__PURE__*/createContext({});
|
|
|
35
35
|
const unstable__Dialog = /*#__PURE__*/React.forwardRef(({
|
|
36
36
|
children,
|
|
37
37
|
className,
|
|
38
|
+
focusAfterCloseRef,
|
|
38
39
|
modal,
|
|
39
40
|
onCancel = noopFn,
|
|
40
41
|
onClick = noopFn,
|
|
@@ -93,6 +94,19 @@ const unstable__Dialog = /*#__PURE__*/React.forwardRef(({
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
}, [modal, open]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!open && focusAfterCloseRef) {
|
|
99
|
+
// use setTimeout to ensure focus is set after all other default focus behavior
|
|
100
|
+
const moveFocus = setTimeout(() => {
|
|
101
|
+
focusAfterCloseRef.current?.focus();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
//component did unmount equivalent
|
|
105
|
+
return () => {
|
|
106
|
+
clearTimeout(moveFocus);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}, [open, focusAfterCloseRef]);
|
|
96
110
|
const containerClasses = cx(`${prefix}--dialog-container`);
|
|
97
111
|
const contextValue = {
|
|
98
112
|
dialogId,
|
|
@@ -138,6 +152,12 @@ unstable__Dialog.propTypes = {
|
|
|
138
152
|
* Specify an optional className to be applied to the modal root node
|
|
139
153
|
*/
|
|
140
154
|
className: PropTypes.string,
|
|
155
|
+
/**
|
|
156
|
+
* Provide a ref to return focus to once the dialog is closed.
|
|
157
|
+
*/
|
|
158
|
+
focusAfterCloseRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
|
|
159
|
+
current: PropTypes.any
|
|
160
|
+
})]),
|
|
141
161
|
/**
|
|
142
162
|
* Modal specifies whether the Dialog is modal or non-modal. This cannot be
|
|
143
163
|
* changed while open=true
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, {
|
|
7
|
+
import React, { type HTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
8
8
|
import { UseSelectProps } from 'downshift';
|
|
9
9
|
import { type ListBoxMenuIconTranslationKey, type ListBoxSize, type ListBoxType } from '../ListBox';
|
|
10
10
|
import { TranslateWithId } from '../../types/common';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React, { useEffect, useContext, useCallback, useMemo, useState, isValidElement } from 'react';
|
|
9
|
+
import React, { useEffect, useContext, useCallback, useMemo, useState, isValidElement, cloneElement } from 'react';
|
|
10
10
|
import { useSelect } from 'downshift';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
@@ -20,6 +20,8 @@ import { FormContext } from '../FluidForm/FormContext.js';
|
|
|
20
20
|
import { useId } from '../../internal/useId.js';
|
|
21
21
|
import { useFloating, size, flip, hide, autoUpdate } from '@floating-ui/react';
|
|
22
22
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
23
|
+
import { AILabel } from '../AILabel/index.js';
|
|
24
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
23
25
|
import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
|
|
24
26
|
|
|
25
27
|
const {
|
|
@@ -308,15 +310,11 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
|
|
|
308
310
|
}), [autoAlign, getMenuProps, refs.setFloating, enableFloatingStyles]);
|
|
309
311
|
|
|
310
312
|
// AILabel is always size `mini`
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
return /*#__PURE__*/React.isValidElement(element) ? element : null;
|
|
319
|
-
}, [slug, decorator]);
|
|
313
|
+
const candidate = slug ?? decorator;
|
|
314
|
+
const candidateIsAILabel = isComponentElement(candidate, AILabel);
|
|
315
|
+
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
316
|
+
size: 'mini'
|
|
317
|
+
}) : null;
|
|
320
318
|
const allLabelProps = getLabelProps();
|
|
321
319
|
const labelProps = /*#__PURE__*/isValidElement(titleText) ? {
|
|
322
320
|
id: allLabelProps.id
|
|
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
import React, { useState, useRef } from 'react';
|
|
12
12
|
import { Enter, Space } from '../../internal/keyboard/keys.js';
|
|
13
13
|
import { matches } from '../../internal/keyboard/match.js';
|
|
14
|
-
import {
|
|
14
|
+
import { useId } from '../../internal/useId.js';
|
|
15
15
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
16
16
|
import deprecate from '../../prop-types/deprecate.js';
|
|
17
17
|
import { noopFn } from '../../internal/noopFn.js';
|
|
@@ -39,7 +39,7 @@ function FileUploaderButton({
|
|
|
39
39
|
const [prevOwnerLabelText, setPrevOwnerLabelText] = useState(ownerLabelText);
|
|
40
40
|
const {
|
|
41
41
|
current: inputId
|
|
42
|
-
} = useRef(id ||
|
|
42
|
+
} = useRef(id || useId());
|
|
43
43
|
const inputNode = useRef(null);
|
|
44
44
|
const classes = cx(`${prefix}--btn`, className, {
|
|
45
45
|
[`${prefix}--btn--${buttonKind}`]: buttonKind,
|
|
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { Enter, Space } from '../../internal/keyboard/keys.js';
|
|
13
13
|
import { matches } from '../../internal/keyboard/match.js';
|
|
14
|
-
import {
|
|
14
|
+
import { useId } from '../../internal/useId.js';
|
|
15
15
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
16
16
|
import { composeEventHandlers } from '../../tools/events.js';
|
|
17
17
|
import deprecate from '../../prop-types/deprecate.js';
|
|
@@ -36,7 +36,7 @@ function FileUploaderDropContainer({
|
|
|
36
36
|
const inputRef = useRef(null);
|
|
37
37
|
const {
|
|
38
38
|
current: uid
|
|
39
|
-
} = useRef(id ||
|
|
39
|
+
} = useRef(id || useId());
|
|
40
40
|
const [isActive, setActive] = useState(false);
|
|
41
41
|
const dropareaClasses = cx(`${prefix}--file__drop-container`, `${prefix}--file-browse-btn`, {
|
|
42
42
|
[`${prefix}--file__drop-container--drag-over`]: isActive,
|
|
@@ -12,7 +12,7 @@ import React, { useRef, useState, useLayoutEffect } from 'react';
|
|
|
12
12
|
import Filename from './Filename.js';
|
|
13
13
|
import { Enter, Space } from '../../internal/keyboard/keys.js';
|
|
14
14
|
import { matches } from '../../internal/keyboard/match.js';
|
|
15
|
-
import {
|
|
15
|
+
import { useId } from '../../internal/useId.js';
|
|
16
16
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
17
17
|
import { noopFn } from '../../internal/noopFn.js';
|
|
18
18
|
import '../Text/index.js';
|
|
@@ -38,7 +38,7 @@ function FileUploaderItem({
|
|
|
38
38
|
const prefix = usePrefix();
|
|
39
39
|
const {
|
|
40
40
|
current: id
|
|
41
|
-
} = useRef(uuid ||
|
|
41
|
+
} = useRef(uuid || useId());
|
|
42
42
|
const classes = cx(`${prefix}--file__selected-file`, className, {
|
|
43
43
|
[`${prefix}--file__selected-file--invalid`]: invalid,
|
|
44
44
|
[`${prefix}--file__selected-file--md`]: size === 'md',
|
|
@@ -35,7 +35,5 @@ export interface LayerBaseProps {
|
|
|
35
35
|
withBackground?: boolean;
|
|
36
36
|
}
|
|
37
37
|
export type LayerProps<T extends React.ElementType> = PolymorphicComponentPropWithRef<T, LayerBaseProps>;
|
|
38
|
-
declare const Layer: React.ForwardRefExoticComponent<
|
|
39
|
-
as?: React.ElementType;
|
|
40
|
-
} & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<any>>;
|
|
38
|
+
declare const Layer: React.ForwardRefExoticComponent<Omit<LayerProps<React.ElementType<any, keyof React.JSX.IntrinsicElements>>, "ref"> & React.RefAttributes<unknown>>;
|
|
41
39
|
export { Layer };
|
|
@@ -25,14 +25,15 @@ function useLayer() {
|
|
|
25
25
|
level
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
const Layer = /*#__PURE__*/React.forwardRef(({
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
const Layer = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
29
|
+
const {
|
|
30
|
+
as,
|
|
31
|
+
className: customClassName,
|
|
32
|
+
children,
|
|
33
|
+
level: overrideLevel,
|
|
34
|
+
withBackground = false,
|
|
35
|
+
...rest
|
|
36
|
+
} = props;
|
|
36
37
|
const contextLevel = React.useContext(LayerContext);
|
|
37
38
|
const level = overrideLevel ?? contextLevel;
|
|
38
39
|
const prefix = usePrefix();
|
|
@@ -34,12 +34,6 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
|
|
|
34
34
|
open,
|
|
35
35
|
size = 'sm',
|
|
36
36
|
legacyAutoalign = 'true',
|
|
37
|
-
// TODO: `ssr-friendly` doesn't support ESLint v9.
|
|
38
|
-
// https://github.com/kopiro/eslint-plugin-ssr-friendly/issues/30
|
|
39
|
-
// https://github.com/carbon-design-system/carbon/issues/18991
|
|
40
|
-
/*
|
|
41
|
-
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
|
|
42
|
-
*/
|
|
43
37
|
target = canUseDOM && document.body,
|
|
44
38
|
x = 0,
|
|
45
39
|
y = 0,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, { type HTMLAttributes, type ReactNode, type
|
|
7
|
+
import React, { type HTMLAttributes, type ReactNode, type RefObject } from 'react';
|
|
8
8
|
import { InlineLoadingStatus } from '../InlineLoading/InlineLoading';
|
|
9
9
|
export declare const ModalSizes: readonly ["xs", "sm", "md", "lg"];
|
|
10
10
|
export type ModalSize = (typeof ModalSizes)[number];
|
|
@@ -57,7 +57,7 @@ export interface ModalProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
57
57
|
/**
|
|
58
58
|
* Provide a ref to return focus to once the modal is closed.
|
|
59
59
|
*/
|
|
60
|
-
launcherButtonRef?:
|
|
60
|
+
launcherButtonRef?: RefObject<HTMLButtonElement | null>;
|
|
61
61
|
/**
|
|
62
62
|
* Specify the description for the loading text
|
|
63
63
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
|
-
import React, { useRef, useState, useEffect } from 'react';
|
|
10
|
+
import React, { useRef, useState, useEffect, cloneElement } from 'react';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { Close } from '@carbon/icons-react';
|
|
13
13
|
import { toggleClass } from '../../tools/toggleClass.js';
|
|
@@ -31,11 +31,14 @@ import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
|
31
31
|
import { composeEventHandlers } from '../../tools/events.js';
|
|
32
32
|
import deprecate from '../../prop-types/deprecate.js';
|
|
33
33
|
import { unstable__Dialog } from '../Dialog/index.js';
|
|
34
|
+
import { AILabel } from '../AILabel/index.js';
|
|
35
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
34
36
|
import { warning } from '../../internal/warning.js';
|
|
35
37
|
import { debounce } from '../../node_modules/es-toolkit/dist/compat/function/debounce.mjs.js';
|
|
36
38
|
import { Text } from '../Text/Text.js';
|
|
37
39
|
|
|
38
40
|
const ModalSizes = ['xs', 'sm', 'md', 'lg'];
|
|
41
|
+
const invalidOutsideClickMessage = '`Modal`: `preventCloseOnClickOutside` should not be `false` when `passiveModal` is `false`. Non-passive `Modal`s should not be dismissible by clicking outside.';
|
|
39
42
|
const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
40
43
|
'aria-label': ariaLabelProp,
|
|
41
44
|
children,
|
|
@@ -61,7 +64,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
61
64
|
size,
|
|
62
65
|
hasScrollingContent = false,
|
|
63
66
|
closeButtonLabel = 'Close',
|
|
64
|
-
preventCloseOnClickOutside =
|
|
67
|
+
preventCloseOnClickOutside = !passiveModal,
|
|
65
68
|
isFullWidth,
|
|
66
69
|
launcherButtonRef,
|
|
67
70
|
loadingStatus = 'inactive',
|
|
@@ -92,6 +95,9 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
92
95
|
const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
|
|
93
96
|
const enableDialogElement = useFeatureFlag('enable-dialog-element');
|
|
94
97
|
process.env.NODE_ENV !== "production" ? warning(!(focusTrapWithoutSentinels && enableDialogElement), '`<Modal>` detected both `focusTrapWithoutSentinels` and ' + '`enableDialogElement` feature flags are enabled. The native dialog ' + 'element handles focus, so `enableDialogElement` must be off for ' + '`focusTrapWithoutSentinels` to have any effect.') : void 0;
|
|
98
|
+
if (!passiveModal && preventCloseOnClickOutside === false) {
|
|
99
|
+
console.error(invalidOutsideClickMessage);
|
|
100
|
+
}
|
|
95
101
|
function isCloseButton(element) {
|
|
96
102
|
return !onSecondarySubmit && element === secondaryButton.current || element.classList.contains(modalCloseButtonClass);
|
|
97
103
|
}
|
|
@@ -129,7 +135,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
129
135
|
target: oldActiveNode,
|
|
130
136
|
relatedTarget: currentActiveNode
|
|
131
137
|
}) {
|
|
132
|
-
if (open && oldActiveNode instanceof HTMLElement && currentActiveNode instanceof HTMLElement) {
|
|
138
|
+
if (!enableDialogElement && open && oldActiveNode instanceof HTMLElement && currentActiveNode instanceof HTMLElement) {
|
|
133
139
|
const {
|
|
134
140
|
current: bodyNode
|
|
135
141
|
} = innerModal;
|
|
@@ -148,6 +154,23 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
148
154
|
selectorsFloatingMenus
|
|
149
155
|
});
|
|
150
156
|
}
|
|
157
|
+
|
|
158
|
+
// Adjust scroll if needed so that element with focus is not obscured by gradient
|
|
159
|
+
const modalContent = document.querySelector(`.${prefix}--modal-content`);
|
|
160
|
+
if (!modalContent || !modalContent.classList.contains(`${prefix}--modal-scroll-content`) || !currentActiveNode || !modalContent.contains(currentActiveNode)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const lastContent = modalContent.children[modalContent.children.length - 1];
|
|
164
|
+
const gradientSpacing = modalContent.scrollHeight - lastContent.offsetTop - lastContent.clientHeight;
|
|
165
|
+
for (let elem of modalContent.children) {
|
|
166
|
+
if (elem.contains(currentActiveNode)) {
|
|
167
|
+
const spaceBelow = modalContent.clientHeight - elem.offsetTop + modalContent.scrollTop - elem.clientHeight;
|
|
168
|
+
if (spaceBelow < gradientSpacing) {
|
|
169
|
+
modalContent.scrollTop = modalContent.scrollTop + (gradientSpacing - spaceBelow);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
151
174
|
}
|
|
152
175
|
const onSecondaryButtonClick = onSecondarySubmit ? onSecondarySubmit : onRequestClose;
|
|
153
176
|
const modalClasses = cx(`${prefix}--modal`, {
|
|
@@ -248,12 +271,11 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
248
271
|
}, []);
|
|
249
272
|
|
|
250
273
|
// AILabel always size `sm`
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
274
|
+
const candidate = slug ?? decorator;
|
|
275
|
+
const candidateIsAILabel = isComponentElement(candidate, AILabel);
|
|
276
|
+
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
277
|
+
size: 'sm'
|
|
278
|
+
}) : null;
|
|
257
279
|
const modalButton = /*#__PURE__*/React.createElement("div", {
|
|
258
280
|
className: `${prefix}--modal-close-button`
|
|
259
281
|
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
@@ -275,6 +297,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
275
297
|
const isAlertDialog = alert && !passiveModal;
|
|
276
298
|
const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(unstable__Dialog, {
|
|
277
299
|
open: open,
|
|
300
|
+
focusAfterCloseRef: launcherButtonRef,
|
|
278
301
|
modal: true,
|
|
279
302
|
ref: innerModal,
|
|
280
303
|
role: isAlertDialog ? 'alertdialog' : '',
|
|
@@ -404,7 +427,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
404
427
|
level: 0,
|
|
405
428
|
onKeyDown: handleKeyDown,
|
|
406
429
|
onClick: composeEventHandlers([rest?.onClick, handleOnClick]),
|
|
407
|
-
onBlur:
|
|
430
|
+
onBlur: handleBlur,
|
|
408
431
|
className: modalClasses,
|
|
409
432
|
role: "presentation",
|
|
410
433
|
ref: ref
|
|
@@ -521,7 +544,12 @@ Modal.propTypes = {
|
|
|
521
544
|
/**
|
|
522
545
|
* Prevent closing on click outside of modal
|
|
523
546
|
*/
|
|
524
|
-
preventCloseOnClickOutside:
|
|
547
|
+
preventCloseOnClickOutside: (props, propName) => {
|
|
548
|
+
if (!props.passiveModal && props[propName] === false) {
|
|
549
|
+
return new Error(invalidOutsideClickMessage);
|
|
550
|
+
}
|
|
551
|
+
return null;
|
|
552
|
+
},
|
|
525
553
|
/**
|
|
526
554
|
* Specify whether the Button should be disabled, or not
|
|
527
555
|
*/
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { type UseComboboxProps, type UseMultipleSelectionProps } from 'downshift';
|
|
8
|
-
import React, {
|
|
8
|
+
import React, { type FunctionComponent, type ReactElement, type ReactNode } from 'react';
|
|
9
9
|
import { type MultiSelectSortingProps } from './MultiSelectPropTypes';
|
|
10
10
|
import { type ListBoxSize, type ListBoxType } from '../ListBox';
|
|
11
11
|
import { TranslateWithId } from '../../types/common';
|
|
@@ -11,7 +11,7 @@ import cx from 'classnames';
|
|
|
11
11
|
import Downshift, { useCombobox, useMultipleSelection } from 'downshift';
|
|
12
12
|
import isEqual from 'react-fast-compare';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
|
-
import React, { forwardRef, useContext, useRef, useState, useLayoutEffect, useMemo, useEffect } from 'react';
|
|
14
|
+
import React, { forwardRef, useContext, useRef, useState, useLayoutEffect, useMemo, useEffect, cloneElement } from 'react';
|
|
15
15
|
import { defaultFilterItems } from '../ComboBox/tools/filter.js';
|
|
16
16
|
import { sortingPropTypes } from './MultiSelectPropTypes.js';
|
|
17
17
|
import ListBox from '../ListBox/index.js';
|
|
@@ -29,6 +29,8 @@ import '../FluidForm/FluidForm.js';
|
|
|
29
29
|
import { FormContext } from '../FluidForm/FormContext.js';
|
|
30
30
|
import { useSelection } from '../../internal/Selection.js';
|
|
31
31
|
import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
|
|
32
|
+
import { AILabel } from '../AILabel/index.js';
|
|
33
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
32
34
|
import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
|
|
33
35
|
|
|
34
36
|
const {
|
|
@@ -248,6 +250,27 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
248
250
|
onMenuChange?.(isOpen);
|
|
249
251
|
}
|
|
250
252
|
}, [isOpen, onMenuChange, open]);
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
const handleClickOutside = event => {
|
|
255
|
+
const target = event.target;
|
|
256
|
+
const wrapper = document.getElementById(id)?.closest(`.${prefix}--multi-select__wrapper`);
|
|
257
|
+
|
|
258
|
+
// If click is outside our component and menu is open or input is focused
|
|
259
|
+
if (wrapper && !wrapper.contains(target)) {
|
|
260
|
+
if (isOpen || inputFocused) {
|
|
261
|
+
setIsOpen(false);
|
|
262
|
+
setInputFocused(false);
|
|
263
|
+
setInputValue('');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
if (inputFocused || isOpen) {
|
|
268
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
269
|
+
}
|
|
270
|
+
return () => {
|
|
271
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
272
|
+
};
|
|
273
|
+
}, [isOpen, inputFocused]);
|
|
251
274
|
const {
|
|
252
275
|
getToggleButtonProps,
|
|
253
276
|
getLabelProps,
|
|
@@ -423,12 +446,11 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
423
446
|
}
|
|
424
447
|
|
|
425
448
|
// AILabel always size `mini`
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
449
|
+
const candidate = slug ?? decorator;
|
|
450
|
+
const candidateIsAILabel = isComponentElement(candidate, AILabel);
|
|
451
|
+
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
452
|
+
size: 'mini'
|
|
453
|
+
}) : null;
|
|
432
454
|
const className = cx(`${prefix}--multi-select`, `${prefix}--combo-box`, `${prefix}--multi-select--filterable`, {
|
|
433
455
|
[`${prefix}--multi-select--invalid`]: invalid,
|
|
434
456
|
[`${prefix}--multi-select--invalid--focused`]: invalid && inputFocused,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { UseSelectProps } from 'downshift';
|
|
8
|
-
import React, { ReactNode } from 'react';
|
|
8
|
+
import React, { type ReactNode } from 'react';
|
|
9
9
|
import { type ListBoxSize, type ListBoxType } from '../ListBox';
|
|
10
10
|
import { MultiSelectSortingProps } from './MultiSelectPropTypes';
|
|
11
11
|
import { ListBoxProps } from '../ListBox/ListBox';
|
|
@@ -11,7 +11,7 @@ import cx from 'classnames';
|
|
|
11
11
|
import { useSelect } from 'downshift';
|
|
12
12
|
import isEqual from 'react-fast-compare';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
|
-
import React, { useMemo, useContext, useState, useLayoutEffect, isValidElement, useCallback } from 'react';
|
|
14
|
+
import React, { useMemo, useContext, useState, useLayoutEffect, isValidElement, useCallback, cloneElement } from 'react';
|
|
15
15
|
import ListBox from '../ListBox/index.js';
|
|
16
16
|
import { sortingPropTypes } from './MultiSelectPropTypes.js';
|
|
17
17
|
import { defaultSortItems, defaultCompareItems } from './tools/sorting.js';
|
|
@@ -29,6 +29,8 @@ import '../Checkbox/Checkbox.Skeleton.js';
|
|
|
29
29
|
import { noopFn } from '../../internal/noopFn.js';
|
|
30
30
|
import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
|
|
31
31
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
32
|
+
import { AILabel } from '../AILabel/index.js';
|
|
33
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
32
34
|
import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
|
|
33
35
|
|
|
34
36
|
const {
|
|
@@ -409,12 +411,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
409
411
|
} : {};
|
|
410
412
|
|
|
411
413
|
// AILabel always size `mini`
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
414
|
+
const candidate = slug ?? decorator;
|
|
415
|
+
const candidateIsAILabel = isComponentElement(candidate, AILabel);
|
|
416
|
+
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
417
|
+
size: 'mini'
|
|
418
|
+
}) : null;
|
|
418
419
|
const itemsSelectedText = selectedItems.length > 0 && selectedItems.map(item => item?.text);
|
|
419
420
|
const selectedItemsLength = selectAll ? selectedItems.filter(item => !item.isSelectAll).length : selectedItems.length;
|
|
420
421
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, { ReactNode } from 'react';
|
|
7
|
+
import React, { type ReactNode } from 'react';
|
|
8
8
|
import { TranslateWithId } from '../../types/common';
|
|
9
9
|
import { type NumberFormatOptions } from '@carbon/utilities';
|
|
10
10
|
export declare const translationIds: {
|
|
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
|
|
|
9
9
|
import { Subtract, Add } from '@carbon/icons-react';
|
|
10
10
|
import cx from 'classnames';
|
|
11
11
|
import PropTypes from 'prop-types';
|
|
12
|
-
import React, { useContext, useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
12
|
+
import React, { useContext, useState, useMemo, useCallback, useRef, useEffect, cloneElement } from 'react';
|
|
13
13
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
14
14
|
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps.js';
|
|
15
15
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -23,6 +23,8 @@ import { NumberParser, NumberFormatter } from '@carbon/utilities';
|
|
|
23
23
|
import { ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
|
|
24
24
|
import { match } from '../../internal/keyboard/match.js';
|
|
25
25
|
import { NumberFormatOptionsPropType } from './NumberFormatPropTypes.js';
|
|
26
|
+
import { AILabel } from '../AILabel/index.js';
|
|
27
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
26
28
|
import { Text } from '../Text/Text.js';
|
|
27
29
|
|
|
28
30
|
var _Subtract, _Add;
|
|
@@ -262,16 +264,15 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
|
|
|
262
264
|
};
|
|
263
265
|
|
|
264
266
|
// AILabel always size `mini`
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
267
|
+
const candidate = slug ?? decorator;
|
|
268
|
+
const candidateIsAILabel = isComponentElement(candidate, AILabel);
|
|
269
|
+
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
270
|
+
size: 'mini'
|
|
271
|
+
}) : null;
|
|
271
272
|
|
|
272
273
|
// Need to update the internal value when the revert button is clicked
|
|
273
274
|
let isRevertActive;
|
|
274
|
-
if (normalizedDecorator
|
|
275
|
+
if (normalizedDecorator?.type === AILabel) {
|
|
275
276
|
isRevertActive = normalizedDecorator.props.revertActive;
|
|
276
277
|
}
|
|
277
278
|
useEffect(() => {
|
|
@@ -143,14 +143,14 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
|
|
|
143
143
|
setHasMountedTrigger(true);
|
|
144
144
|
}
|
|
145
145
|
}, []);
|
|
146
|
-
|
|
147
|
-
// Call `onClose` when menu closes.
|
|
148
146
|
useEffect(() => {
|
|
149
|
-
if (
|
|
147
|
+
if (open && !prevOpenState.current) {
|
|
148
|
+
onOpen();
|
|
149
|
+
} else if (!open && prevOpenState.current) {
|
|
150
150
|
onClose();
|
|
151
151
|
}
|
|
152
152
|
prevOpenState.current = open;
|
|
153
|
-
}, [open, onClose]);
|
|
153
|
+
}, [open, onClose, onOpen]);
|
|
154
154
|
useOutsideClick(wrapperRef, ({
|
|
155
155
|
target
|
|
156
156
|
}) => {
|
|
@@ -259,7 +259,6 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
|
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
}, !hasFocusin);
|
|
262
|
-
onOpen();
|
|
263
262
|
};
|
|
264
263
|
const getTarget = () => {
|
|
265
264
|
const triggerEl = triggerRef.current;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React, { type ComponentType, type FunctionComponent } from 'react';
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
|
-
import {
|
|
9
|
+
import { TYPES } from '../Tag/Tag';
|
|
10
10
|
/**
|
|
11
11
|
* ----------
|
|
12
12
|
* PageHeader
|
|
@@ -199,16 +199,18 @@ declare const PageHeaderHeroImage: {
|
|
|
199
199
|
* PageHeaderTabBar
|
|
200
200
|
* ----------------
|
|
201
201
|
*/
|
|
202
|
+
interface TagItem {
|
|
203
|
+
type: keyof typeof TYPES;
|
|
204
|
+
text: string;
|
|
205
|
+
size?: 'sm' | 'md' | 'lg';
|
|
206
|
+
id: string;
|
|
207
|
+
}
|
|
202
208
|
interface PageHeaderTabBarProps {
|
|
203
209
|
children?: React.ReactNode;
|
|
204
210
|
className?: string;
|
|
211
|
+
tags?: TagItem[];
|
|
205
212
|
}
|
|
206
213
|
declare const PageHeaderTabBar: React.ForwardRefExoticComponent<PageHeaderTabBarProps & React.RefAttributes<HTMLDivElement>>;
|
|
207
|
-
interface PageHeaderTabsProps extends React.ComponentProps<typeof BaseTabs> {
|
|
208
|
-
children?: React.ReactNode;
|
|
209
|
-
className?: string;
|
|
210
|
-
}
|
|
211
|
-
declare const PageHeaderTabs: React.ForwardRefExoticComponent<PageHeaderTabsProps & React.RefAttributes<HTMLDivElement>>;
|
|
212
214
|
/**
|
|
213
215
|
* -------
|
|
214
216
|
* Exports
|
|
@@ -272,6 +274,5 @@ declare const HeroImage: {
|
|
|
272
274
|
};
|
|
273
275
|
};
|
|
274
276
|
declare const TabBar: React.ForwardRefExoticComponent<PageHeaderTabBarProps & React.RefAttributes<HTMLDivElement>>;
|
|
275
|
-
|
|
276
|
-
export {
|
|
277
|
-
export type { PageHeaderProps, PageHeaderBreadcrumbBarProps, PageHeaderContentProps, PageHeaderContentPageActionsProps, PageHeaderContentTextProps, PageHeaderHeroImageProps, PageHeaderTabBarProps, PageHeaderTabsProps, };
|
|
277
|
+
export { PageHeader, PageHeaderBreadcrumbBar, PageHeaderContent, PageHeaderContentPageActions, PageHeaderContentText, PageHeaderHeroImage, PageHeaderTabBar, Root, BreadcrumbBar, Content, ContentPageActions, ContentText, HeroImage, TabBar, };
|
|
278
|
+
export type { PageHeaderProps, PageHeaderBreadcrumbBarProps, PageHeaderContentProps, PageHeaderContentPageActionsProps, PageHeaderContentTextProps, PageHeaderHeroImageProps, PageHeaderTabBarProps, };
|