@carbon/react 1.97.0-rc.0 → 1.98.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 +1010 -975
- package/es/components/ButtonSet/ButtonSet.d.ts +5 -0
- package/es/components/ButtonSet/ButtonSet.js +68 -4
- package/es/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/es/components/ComposedModal/ComposedModal.js +3 -2
- package/es/components/Copy/Copy.d.ts +1 -1
- package/es/components/CopyButton/CopyButton.d.ts +1 -1
- package/es/components/DataTable/DataTable.d.ts +2 -1
- package/es/components/DataTable/TableContainer.d.ts +10 -2
- package/es/components/DataTable/TableContainer.js +15 -3
- package/es/components/DataTable/state/sorting.d.ts +2 -4
- package/es/components/DataTableSkeleton/DataTableSkeleton.d.ts +1 -1
- package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
- package/es/components/DatePicker/DatePicker.d.ts +3 -2
- package/es/components/DatePicker/DatePicker.js +18 -135
- package/es/components/DatePicker/DatePickerLocales.d.ts +12 -0
- package/es/components/DatePicker/DatePickerLocales.js +135 -0
- package/es/components/DatePickerInput/DatePickerInput.js +50 -28
- package/es/components/Dropdown/Dropdown.js +9 -1
- package/es/components/FileUploader/FileUploader.d.ts +23 -8
- package/es/components/FileUploader/FileUploader.js +53 -33
- package/es/components/FileUploader/FileUploaderButton.js +2 -2
- package/es/components/FileUploader/FileUploaderDropContainer.d.ts +13 -2
- package/es/components/FileUploader/FileUploaderDropContainer.js +15 -6
- package/es/components/FileUploader/FileUploaderItem.js +9 -6
- package/es/components/Menu/index.d.ts +4 -3
- package/es/components/Modal/Modal.js +3 -2
- package/es/components/Notification/Notification.js +3 -2
- package/es/components/Pagination/Pagination.js +5 -5
- package/es/components/Popover/index.js +2 -2
- package/es/components/Select/Select.js +27 -33
- package/es/components/Toggletip/index.d.ts +1 -0
- package/es/components/Toggletip/index.js +1 -1
- package/es/components/Tooltip/index.d.ts +3 -2
- package/es/internal/FloatingMenu.js +8 -6
- package/es/internal/OptimizedResize.js +4 -5
- package/es/internal/wrapFocus.d.ts +4 -2
- package/es/internal/wrapFocus.js +5 -4
- package/es/tools/events.d.ts +1 -1
- package/lib/components/ButtonSet/ButtonSet.d.ts +5 -0
- package/lib/components/ButtonSet/ButtonSet.js +67 -3
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/lib/components/ComposedModal/ComposedModal.js +3 -2
- package/lib/components/Copy/Copy.d.ts +1 -1
- package/lib/components/CopyButton/CopyButton.d.ts +1 -1
- package/lib/components/DataTable/DataTable.d.ts +2 -1
- package/lib/components/DataTable/TableContainer.d.ts +10 -2
- package/lib/components/DataTable/TableContainer.js +15 -3
- package/lib/components/DataTable/state/sorting.d.ts +2 -4
- package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +1 -1
- package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
- package/lib/components/DatePicker/DatePicker.d.ts +3 -2
- package/lib/components/DatePicker/DatePicker.js +18 -135
- package/lib/components/DatePicker/DatePickerLocales.d.ts +12 -0
- package/lib/components/DatePicker/DatePickerLocales.js +137 -0
- package/lib/components/DatePickerInput/DatePickerInput.js +49 -27
- package/lib/components/Dropdown/Dropdown.js +9 -1
- package/lib/components/FileUploader/FileUploader.d.ts +23 -8
- package/lib/components/FileUploader/FileUploader.js +53 -33
- package/lib/components/FileUploader/FileUploaderButton.js +2 -2
- package/lib/components/FileUploader/FileUploaderDropContainer.d.ts +13 -2
- package/lib/components/FileUploader/FileUploaderDropContainer.js +15 -6
- package/lib/components/FileUploader/FileUploaderItem.js +9 -6
- package/lib/components/Menu/index.d.ts +4 -3
- package/lib/components/Modal/Modal.js +3 -2
- package/lib/components/Notification/Notification.js +3 -2
- package/lib/components/Pagination/Pagination.js +5 -5
- package/lib/components/Popover/index.js +2 -2
- package/lib/components/Select/Select.js +27 -33
- package/lib/components/Toggletip/index.d.ts +1 -0
- package/lib/components/Toggletip/index.js +3 -0
- package/lib/components/Tooltip/index.d.ts +3 -2
- package/lib/internal/FloatingMenu.js +8 -6
- package/lib/internal/OptimizedResize.js +4 -5
- package/lib/internal/wrapFocus.d.ts +4 -2
- package/lib/internal/wrapFocus.js +5 -4
- package/lib/tools/events.d.ts +1 -1
- package/package.json +20 -27
- package/telemetry.yml +2 -0
|
@@ -36,10 +36,10 @@ function FileUploaderItem({
|
|
|
36
36
|
const textRef = useRef(null);
|
|
37
37
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
38
38
|
const prefix = usePrefix();
|
|
39
|
-
|
|
39
|
+
const generatedId = useId();
|
|
40
40
|
const {
|
|
41
41
|
current: id
|
|
42
|
-
} = useRef(uuid ||
|
|
42
|
+
} = useRef(uuid || generatedId);
|
|
43
43
|
const classes = cx(`${prefix}--file__selected-file`, className, {
|
|
44
44
|
[`${prefix}--file__selected-file--invalid`]: invalid,
|
|
45
45
|
[`${prefix}--file__selected-file--md`]: size === 'md',
|
|
@@ -49,11 +49,14 @@ function FileUploaderItem({
|
|
|
49
49
|
const filterSpaceName = name => {
|
|
50
50
|
return name?.replace(/\s+/g, '');
|
|
51
51
|
};
|
|
52
|
-
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
54
52
|
const isEllipsisActive = element => {
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
if (!element) {
|
|
54
|
+
setIsEllipsisApplied(false);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const isActive = element.offsetWidth < element.scrollWidth;
|
|
58
|
+
setIsEllipsisApplied(isActive);
|
|
59
|
+
return isActive;
|
|
57
60
|
};
|
|
58
61
|
useLayoutEffect(() => {
|
|
59
62
|
isEllipsisActive(textRef.current);
|
|
@@ -4,6 +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 { Menu } from './Menu';
|
|
8
|
-
import { MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable } from './MenuItem';
|
|
9
|
-
export { Menu, MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable, };
|
|
7
|
+
import { Menu, type MenuProps } from './Menu';
|
|
8
|
+
import { MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable, type MenuItemProps, type MenuItemDividerProps, type MenuItemGroupProps, type MenuItemRadioGroupProps, type MenuItemSelectableProps } from './MenuItem';
|
|
9
|
+
export { Menu, MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable, type MenuProps, type MenuItemProps, type MenuItemDividerProps, type MenuItemGroupProps, type MenuItemRadioGroupProps, type MenuItemSelectableProps, };
|
|
10
|
+
export default Menu;
|
|
@@ -167,7 +167,7 @@ const ModalDialog = /*#__PURE__*/React.forwardRef(function ModalDialog({
|
|
|
167
167
|
// behavior by explicitly setting preventCloseOnClickOutside to false,
|
|
168
168
|
// rather than just leaving it undefined.
|
|
169
169
|
!passiveModal && preventCloseOnClickOutside === false;
|
|
170
|
-
if (shouldCloseOnOutsideClick && target instanceof Node && !elementOrParentIsFloatingMenu(target, selectorsFloatingMenus) && innerModal.current && !innerModal.current.contains(target)) {
|
|
170
|
+
if (shouldCloseOnOutsideClick && target instanceof Node && !elementOrParentIsFloatingMenu(target, selectorsFloatingMenus, prefix) && innerModal.current && !innerModal.current.contains(target)) {
|
|
171
171
|
onRequestClose(evt);
|
|
172
172
|
}
|
|
173
173
|
}
|
|
@@ -194,7 +194,8 @@ const ModalDialog = /*#__PURE__*/React.forwardRef(function ModalDialog({
|
|
|
194
194
|
endTrapNode,
|
|
195
195
|
currentActiveNode,
|
|
196
196
|
oldActiveNode,
|
|
197
|
-
selectorsFloatingMenus
|
|
197
|
+
selectorsFloatingMenus,
|
|
198
|
+
prefix
|
|
198
199
|
});
|
|
199
200
|
if (wrapFocusTimeout.current) {
|
|
200
201
|
clearTimeout(wrapFocusTimeout.current);
|
|
@@ -509,7 +509,7 @@ function ActionableNotification({
|
|
|
509
509
|
const focusTrapWithoutSentinels = focusTrapWithoutSentinelsFlag || deprecatedFlag;
|
|
510
510
|
useIsomorphicEffect(() => {
|
|
511
511
|
if (hasFocus && role === 'alertdialog') {
|
|
512
|
-
const button = document.querySelector(
|
|
512
|
+
const button = document.querySelector(`button.${prefix}--actionable-notification__action-button`);
|
|
513
513
|
button?.focus();
|
|
514
514
|
}
|
|
515
515
|
});
|
|
@@ -532,7 +532,8 @@ function ActionableNotification({
|
|
|
532
532
|
startTrapNode,
|
|
533
533
|
endTrapNode,
|
|
534
534
|
currentActiveNode,
|
|
535
|
-
oldActiveNode
|
|
535
|
+
oldActiveNode,
|
|
536
|
+
prefix
|
|
536
537
|
});
|
|
537
538
|
}
|
|
538
539
|
}
|
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import { CaretLeft, CaretRight } from '@carbon/icons-react';
|
|
10
|
-
import cx from 'classnames';
|
|
11
|
-
import PropTypes from 'prop-types';
|
|
12
10
|
import React, { useRef, useState, useEffect } from 'react';
|
|
11
|
+
import { IconButton } from '../IconButton/index.js';
|
|
12
|
+
import PropTypes from 'prop-types';
|
|
13
13
|
import Select from '../Select/Select.js';
|
|
14
14
|
import '../Select/Select.Skeleton.js';
|
|
15
15
|
import SelectItem from '../SelectItem/SelectItem.js';
|
|
16
|
+
import cx from 'classnames';
|
|
17
|
+
import isEqual from 'react-fast-compare';
|
|
16
18
|
import { useFallbackId } from '../../internal/useId.js';
|
|
17
19
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
18
|
-
import { IconButton } from '../IconButton/index.js';
|
|
19
|
-
import isEqual from 'react-fast-compare';
|
|
20
20
|
|
|
21
21
|
var _CaretLeft, _CaretRight;
|
|
22
22
|
function mapPageSizesToObject(sizes) {
|
|
@@ -266,7 +266,7 @@ const Pagination = /*#__PURE__*/React.forwardRef(({
|
|
|
266
266
|
onClick: decrementPage,
|
|
267
267
|
ref: backBtnRef
|
|
268
268
|
}, _CaretLeft || (_CaretLeft = /*#__PURE__*/React.createElement(CaretLeft, null))), /*#__PURE__*/React.createElement(IconButton, {
|
|
269
|
-
align: "top
|
|
269
|
+
align: "top",
|
|
270
270
|
disabled: forwardButtonDisabled || isLastPage,
|
|
271
271
|
kind: "ghost",
|
|
272
272
|
className: forwardButtonClasses,
|
|
@@ -116,8 +116,8 @@ forwardRef) {
|
|
|
116
116
|
// If a value is not set via a custom property, provide a default value that matches the
|
|
117
117
|
// default values defined in the sass style file
|
|
118
118
|
const getStyle = window.getComputedStyle(popover.current, null);
|
|
119
|
-
const offsetProperty = getStyle.getPropertyValue(
|
|
120
|
-
const caretProperty = getStyle.getPropertyValue(
|
|
119
|
+
const offsetProperty = getStyle.getPropertyValue(`--${prefix}-popover-offset`);
|
|
120
|
+
const caretProperty = getStyle.getPropertyValue(`--${prefix}-popover-caret-height`);
|
|
121
121
|
|
|
122
122
|
// Handle if the property values are in px or rem.
|
|
123
123
|
// We want to store just the base number value without a unit suffix
|
|
@@ -14,12 +14,12 @@ import { deprecate } from '../../prop-types/deprecate.js';
|
|
|
14
14
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
15
15
|
import '../FluidForm/FluidForm.js';
|
|
16
16
|
import { FormContext } from '../FluidForm/FormContext.js';
|
|
17
|
-
import { useId } from '../../internal/useId.js';
|
|
18
17
|
import { composeEventHandlers } from '../../tools/events.js';
|
|
19
18
|
import { Text } from '../Text/Text.js';
|
|
20
19
|
import '../Text/TextDirection.js';
|
|
21
20
|
import { AILabel } from '../AILabel/index.js';
|
|
22
21
|
import { isComponentElement } from '../../internal/utils.js';
|
|
22
|
+
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps.js';
|
|
23
23
|
|
|
24
24
|
const Select = /*#__PURE__*/React.forwardRef(({
|
|
25
25
|
className,
|
|
@@ -49,7 +49,6 @@ const Select = /*#__PURE__*/React.forwardRef(({
|
|
|
49
49
|
isFluid
|
|
50
50
|
} = useContext(FormContext);
|
|
51
51
|
const [isFocused, setIsFocused] = useState(false);
|
|
52
|
-
const selectInstanceId = useId();
|
|
53
52
|
// Convert children to an array of valid elements once using type narrowing
|
|
54
53
|
const validChildren = React.Children.toArray(children).filter(child => /*#__PURE__*/React.isValidElement(child));
|
|
55
54
|
|
|
@@ -61,55 +60,50 @@ const Select = /*#__PURE__*/React.forwardRef(({
|
|
|
61
60
|
// otherwise, fallback to the first option's text
|
|
62
61
|
const initialTitle = other?.title || selectedOption?.props?.text || validChildren[0]?.props?.text || '';
|
|
63
62
|
const [title, setTitle] = useState(initialTitle);
|
|
63
|
+
const normalizedProps = useNormalizedInputProps({
|
|
64
|
+
id,
|
|
65
|
+
disabled,
|
|
66
|
+
readOnly,
|
|
67
|
+
invalid,
|
|
68
|
+
invalidText,
|
|
69
|
+
warn,
|
|
70
|
+
warnText
|
|
71
|
+
});
|
|
64
72
|
const selectClasses = cx({
|
|
65
73
|
[`${prefix}--select`]: true,
|
|
66
74
|
[`${prefix}--select--inline`]: inline,
|
|
67
75
|
[`${prefix}--select--light`]: light,
|
|
68
|
-
[`${prefix}--select--invalid`]: invalid,
|
|
69
|
-
[`${prefix}--select--disabled`]: disabled,
|
|
76
|
+
[`${prefix}--select--invalid`]: normalizedProps.invalid,
|
|
77
|
+
[`${prefix}--select--disabled`]: normalizedProps.disabled,
|
|
70
78
|
[`${prefix}--select--readonly`]: readOnly,
|
|
71
|
-
[`${prefix}--select--warning`]: warn,
|
|
72
|
-
[`${prefix}--select--fluid--invalid`]: isFluid && invalid,
|
|
79
|
+
[`${prefix}--select--warning`]: normalizedProps.warn,
|
|
80
|
+
[`${prefix}--select--fluid--invalid`]: isFluid && normalizedProps.invalid,
|
|
73
81
|
[`${prefix}--select--fluid--focus`]: isFluid && isFocused,
|
|
74
82
|
[`${prefix}--select--slug`]: slug,
|
|
75
83
|
[`${prefix}--select--decorator`]: decorator
|
|
76
84
|
});
|
|
77
85
|
const labelClasses = cx(`${prefix}--label`, {
|
|
78
86
|
[`${prefix}--visually-hidden`]: hideLabel,
|
|
79
|
-
[`${prefix}--label--disabled`]: disabled
|
|
87
|
+
[`${prefix}--label--disabled`]: normalizedProps.disabled
|
|
80
88
|
});
|
|
81
89
|
const inputClasses = cx({
|
|
82
90
|
[`${prefix}--select-input`]: true,
|
|
83
91
|
[`${prefix}--select-input--${size}`]: size
|
|
84
92
|
});
|
|
85
|
-
const
|
|
86
|
-
const errorText = (() => {
|
|
87
|
-
if (invalid) {
|
|
88
|
-
return invalidText;
|
|
89
|
-
}
|
|
90
|
-
if (warn) {
|
|
91
|
-
return warnText;
|
|
92
|
-
}
|
|
93
|
-
})();
|
|
94
|
-
const error = invalid || warn ? /*#__PURE__*/React.createElement(Text, {
|
|
95
|
-
as: "div",
|
|
96
|
-
className: `${prefix}--form-requirement`,
|
|
97
|
-
id: errorId
|
|
98
|
-
}, errorText) : null;
|
|
93
|
+
const error = normalizedProps.validation;
|
|
99
94
|
const helperTextClasses = cx(`${prefix}--form__helper-text`, {
|
|
100
|
-
[`${prefix}--form__helper-text--disabled`]: disabled
|
|
95
|
+
[`${prefix}--form__helper-text--disabled`]: normalizedProps.disabled
|
|
101
96
|
});
|
|
102
|
-
const helperId = !helperText ? undefined : `select-helper-text-${selectInstanceId}`;
|
|
103
97
|
const helper = helperText ? /*#__PURE__*/React.createElement(Text, {
|
|
104
98
|
as: "div",
|
|
105
|
-
id: helperId,
|
|
99
|
+
id: normalizedProps.helperId,
|
|
106
100
|
className: helperTextClasses
|
|
107
101
|
}, helperText) : null;
|
|
108
102
|
const ariaProps = {};
|
|
109
|
-
if (invalid) {
|
|
110
|
-
ariaProps['aria-describedby'] =
|
|
103
|
+
if (normalizedProps.invalid) {
|
|
104
|
+
ariaProps['aria-describedby'] = normalizedProps.invalidId;
|
|
111
105
|
} else if (!inline && !isFluid) {
|
|
112
|
-
ariaProps['aria-describedby'] = helper ? helperId : undefined;
|
|
106
|
+
ariaProps['aria-describedby'] = helper ? normalizedProps.helperId : undefined;
|
|
113
107
|
}
|
|
114
108
|
const handleFocus = evt => {
|
|
115
109
|
setIsFocused(evt.type === 'focus' ? true : false);
|
|
@@ -146,8 +140,8 @@ const Select = /*#__PURE__*/React.forwardRef(({
|
|
|
146
140
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("select", _extends({}, other, ariaProps, {
|
|
147
141
|
id: id,
|
|
148
142
|
className: inputClasses,
|
|
149
|
-
disabled: disabled || undefined,
|
|
150
|
-
"aria-invalid": invalid || undefined,
|
|
143
|
+
disabled: normalizedProps.disabled || undefined,
|
|
144
|
+
"aria-invalid": normalizedProps.invalid || undefined,
|
|
151
145
|
"aria-readonly": readOnly || undefined,
|
|
152
146
|
title: title,
|
|
153
147
|
onChange: composeEventHandlers([onChange, handleChange])
|
|
@@ -155,9 +149,9 @@ const Select = /*#__PURE__*/React.forwardRef(({
|
|
|
155
149
|
ref: ref
|
|
156
150
|
}), children), /*#__PURE__*/React.createElement(ChevronDown, {
|
|
157
151
|
className: `${prefix}--select__arrow`
|
|
158
|
-
}), invalid && /*#__PURE__*/React.createElement(WarningFilled, {
|
|
152
|
+
}), normalizedProps.invalid && /*#__PURE__*/React.createElement(WarningFilled, {
|
|
159
153
|
className: `${prefix}--select__invalid-icon`
|
|
160
|
-
}), !invalid && warn && /*#__PURE__*/React.createElement(WarningAltFilled, {
|
|
154
|
+
}), !normalizedProps.invalid && normalizedProps.warn && /*#__PURE__*/React.createElement(WarningAltFilled, {
|
|
161
155
|
className: `${prefix}--select__invalid-icon ${prefix}--select__invalid-icon--warning`
|
|
162
156
|
}));
|
|
163
157
|
})();
|
|
@@ -173,10 +167,10 @@ const Select = /*#__PURE__*/React.forwardRef(({
|
|
|
173
167
|
className: `${prefix}--select-input--inline__wrapper`
|
|
174
168
|
}, /*#__PURE__*/React.createElement("div", {
|
|
175
169
|
className: `${prefix}--select-input__wrapper`,
|
|
176
|
-
"data-invalid": invalid || null
|
|
170
|
+
"data-invalid": normalizedProps.invalid || null
|
|
177
171
|
}, input), error), !inline && /*#__PURE__*/React.createElement("div", {
|
|
178
172
|
className: `${prefix}--select-input__wrapper`,
|
|
179
|
-
"data-invalid": invalid || null,
|
|
173
|
+
"data-invalid": normalizedProps.invalid || null,
|
|
180
174
|
onFocus: handleFocus,
|
|
181
175
|
onBlur: handleFocus
|
|
182
176
|
}, input, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
|
|
@@ -282,4 +282,4 @@ ToggletipActions.propTypes = {
|
|
|
282
282
|
className: PropTypes.string
|
|
283
283
|
};
|
|
284
284
|
|
|
285
|
-
export { Toggletip, ToggletipActions, ToggletipButton, ToggletipContent, ToggletipLabel };
|
|
285
|
+
export { Toggletip, ToggletipActions, ToggletipButton, ToggletipContent, ToggletipLabel, Toggletip as default };
|
|
@@ -4,6 +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 { DefinitionTooltip } from './DefinitionTooltip';
|
|
7
|
+
import { DefinitionTooltip, type DefinitionTooltipProps } from './DefinitionTooltip';
|
|
8
8
|
import { Tooltip, type TooltipProps } from './Tooltip';
|
|
9
|
-
export { DefinitionTooltip, Tooltip, type TooltipProps };
|
|
9
|
+
export { DefinitionTooltip, Tooltip, type DefinitionTooltipProps, type TooltipProps, };
|
|
10
|
+
export default Tooltip;
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import React, { useContext, useState, useRef, useCallback, useEffect, cloneElement } from 'react';
|
|
9
9
|
import * as FeatureFlags from '@carbon/feature-flags';
|
|
10
10
|
import ReactDOM from 'react-dom';
|
|
11
|
-
import window from 'window-or-global';
|
|
12
11
|
import { Tab } from './keyboard/keys.js';
|
|
13
12
|
import { match } from './keyboard/match.js';
|
|
14
13
|
import { selectorTabbable, selectorFocusable } from './keyboard/navigation.js';
|
|
@@ -109,14 +108,16 @@ const FloatingMenu = ({
|
|
|
109
108
|
const menuSize = menuBody.getBoundingClientRect();
|
|
110
109
|
const refPosition = triggerEl ? triggerEl.getBoundingClientRect() : undefined;
|
|
111
110
|
const offsetValue = typeof menuOffset === 'function' ? menuOffset(menuBody, menuDirection, triggerEl, flipped) : menuOffset;
|
|
111
|
+
const scrollX = globalThis.scrollX ?? 0;
|
|
112
|
+
const scrollY = globalThis.scrollY ?? 0;
|
|
112
113
|
if (updateOrientation) {
|
|
113
114
|
updateOrientation({
|
|
114
115
|
menuSize,
|
|
115
116
|
refPosition,
|
|
116
117
|
direction: menuDirection,
|
|
117
118
|
offset: offsetValue,
|
|
118
|
-
scrollX
|
|
119
|
-
scrollY
|
|
119
|
+
scrollX,
|
|
120
|
+
scrollY,
|
|
120
121
|
container: {
|
|
121
122
|
rect: target().getBoundingClientRect(),
|
|
122
123
|
position: getComputedStyle(target()).position
|
|
@@ -136,8 +137,8 @@ const FloatingMenu = ({
|
|
|
136
137
|
},
|
|
137
138
|
offset: offsetValue,
|
|
138
139
|
direction: menuDirection,
|
|
139
|
-
scrollX
|
|
140
|
-
scrollY
|
|
140
|
+
scrollX,
|
|
141
|
+
scrollY,
|
|
141
142
|
container: {
|
|
142
143
|
rect: target().getBoundingClientRect(),
|
|
143
144
|
position: getComputedStyle(target()).position
|
|
@@ -257,7 +258,8 @@ const FloatingMenu = ({
|
|
|
257
258
|
startTrapNode: startSentinelRef.current,
|
|
258
259
|
endTrapNode: endSentinelRef.current,
|
|
259
260
|
currentActiveNode: relatedTarget,
|
|
260
|
-
oldActiveNode: target
|
|
261
|
+
oldActiveNode: target,
|
|
262
|
+
prefix
|
|
261
263
|
});
|
|
262
264
|
}
|
|
263
265
|
};
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// mdn resize function
|
|
8
|
+
// Use `globalThis` for universal access to global object (browser, workers, Node).
|
|
9
|
+
const win = globalThis;
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* A callback function to be executed on `resize`.
|
|
@@ -25,7 +24,7 @@ const OptimizedResize = (() => {
|
|
|
25
24
|
const handleResize = () => {
|
|
26
25
|
if (!running) {
|
|
27
26
|
running = true;
|
|
28
|
-
|
|
27
|
+
win.requestAnimationFrame(runCallbacks);
|
|
29
28
|
}
|
|
30
29
|
};
|
|
31
30
|
const addCallback = callback => {
|
|
@@ -38,7 +37,7 @@ const OptimizedResize = (() => {
|
|
|
38
37
|
/** Adds a callback function to be executed on window `resize`. */
|
|
39
38
|
add: callback => {
|
|
40
39
|
if (!callbacks.length) {
|
|
41
|
-
|
|
40
|
+
win.addEventListener('resize', handleResize);
|
|
42
41
|
}
|
|
43
42
|
addCallback(callback);
|
|
44
43
|
return {
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
* @returns {boolean} Whether the node or one of its ancestors is in a floating
|
|
15
15
|
* menu.
|
|
16
16
|
*/
|
|
17
|
-
export declare const elementOrParentIsFloatingMenu: (node: Node, selectorsFloatingMenus?: string[]) => boolean;
|
|
17
|
+
export declare const elementOrParentIsFloatingMenu: (node: Node, selectorsFloatingMenus?: string[], prefix?: string) => boolean;
|
|
18
18
|
/**
|
|
19
19
|
* Ensures the focus is kept within the given container by implementing
|
|
20
20
|
* "focus-wrap" behavior.
|
|
21
21
|
*/
|
|
22
|
-
export declare const wrapFocus: ({ bodyNode, startTrapNode, endTrapNode, currentActiveNode, oldActiveNode, selectorsFloatingMenus, }: {
|
|
22
|
+
export declare const wrapFocus: ({ bodyNode, startTrapNode, endTrapNode, currentActiveNode, oldActiveNode, selectorsFloatingMenus, prefix, }: {
|
|
23
23
|
/** The DOM node of the container. */
|
|
24
24
|
bodyNode: HTMLElement | null;
|
|
25
25
|
/** The start sentinel node for focus trapping. */
|
|
@@ -32,6 +32,8 @@ export declare const wrapFocus: ({ bodyNode, startTrapNode, endTrapNode, current
|
|
|
32
32
|
oldActiveNode: HTMLElement;
|
|
33
33
|
/** CSS selectors for floating menus. */
|
|
34
34
|
selectorsFloatingMenus?: string[];
|
|
35
|
+
/** Classname prefix for Carbon selectors. */
|
|
36
|
+
prefix?: string;
|
|
35
37
|
}) => void;
|
|
36
38
|
/**
|
|
37
39
|
* Ensures the focus is kept in the given container, implementing "focus-wrap"
|
package/es/internal/wrapFocus.js
CHANGED
|
@@ -30,9 +30,9 @@ const DOCUMENT_POSITION_BROAD_FOLLOWING = typeof Node !== 'undefined' ? Node.DOC
|
|
|
30
30
|
* @returns {boolean} Whether the node or one of its ancestors is in a floating
|
|
31
31
|
* menu.
|
|
32
32
|
*/
|
|
33
|
-
const elementOrParentIsFloatingMenu = (node, selectorsFloatingMenus = []) => {
|
|
33
|
+
const elementOrParentIsFloatingMenu = (node, selectorsFloatingMenus = [], prefix = 'cds') => {
|
|
34
34
|
if (node instanceof Element && typeof node.closest === 'function') {
|
|
35
|
-
const allSelectorsFloatingMenus = [
|
|
35
|
+
const allSelectorsFloatingMenus = [`.${prefix}--overflow-menu-options`, `.${prefix}--tooltip`, '.flatpickr-calendar', ...selectorsFloatingMenus];
|
|
36
36
|
return allSelectorsFloatingMenus.some(selector => !!node.closest(selector));
|
|
37
37
|
}
|
|
38
38
|
return false;
|
|
@@ -48,9 +48,10 @@ const wrapFocus = ({
|
|
|
48
48
|
endTrapNode,
|
|
49
49
|
currentActiveNode,
|
|
50
50
|
oldActiveNode,
|
|
51
|
-
selectorsFloatingMenus
|
|
51
|
+
selectorsFloatingMenus,
|
|
52
|
+
prefix = 'cds'
|
|
52
53
|
}) => {
|
|
53
|
-
if (bodyNode && currentActiveNode && oldActiveNode && !bodyNode.contains(currentActiveNode) && !elementOrParentIsFloatingMenu(currentActiveNode, selectorsFloatingMenus)) {
|
|
54
|
+
if (bodyNode && currentActiveNode && oldActiveNode && !bodyNode.contains(currentActiveNode) && !elementOrParentIsFloatingMenu(currentActiveNode, selectorsFloatingMenus, prefix)) {
|
|
54
55
|
const comparisonResult = oldActiveNode.compareDocumentPosition(currentActiveNode);
|
|
55
56
|
if (currentActiveNode === startTrapNode || comparisonResult & DOCUMENT_POSITION_BROAD_PRECEDING) {
|
|
56
57
|
const tabbableElement = Array.from(bodyNode.querySelectorAll(selectorTabbable)).reverse().find(({
|
package/es/tools/events.d.ts
CHANGED
|
@@ -14,4 +14,4 @@ import type { SyntheticEvent } from 'react';
|
|
|
14
14
|
* @param handlers - An array of event handler functions.
|
|
15
15
|
* @returns A composite event handler.
|
|
16
16
|
*/
|
|
17
|
-
export declare const composeEventHandlers: <E extends SyntheticEvent = SyntheticEvent
|
|
17
|
+
export declare const composeEventHandlers: <E extends SyntheticEvent = SyntheticEvent<Element, Event>>(handlers: (((event: E, ...args: any[]) => void) | undefined)[]) => (event: E, ...args: any[]) => void;
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
8
|
export interface ButtonSetProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
/**
|
|
10
|
+
* fluid: button set resize to the size of the container up to a maximum dependant on the
|
|
11
|
+
* number of buttons. Overrides `stacked` property.
|
|
12
|
+
*/
|
|
13
|
+
fluid?: boolean;
|
|
9
14
|
/**
|
|
10
15
|
* Specify the button arrangement of the set (vertically stacked or
|
|
11
16
|
* horizontal)
|
|
@@ -14,22 +14,81 @@ var React = require('react');
|
|
|
14
14
|
var PropTypes = require('prop-types');
|
|
15
15
|
var cx = require('classnames');
|
|
16
16
|
var usePrefix = require('../../internal/usePrefix.js');
|
|
17
|
+
var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
|
|
17
18
|
|
|
19
|
+
const buttonOrder = kind => ({
|
|
20
|
+
ghost: 1,
|
|
21
|
+
'danger--ghost': 2,
|
|
22
|
+
tertiary: 3,
|
|
23
|
+
danger: 5,
|
|
24
|
+
primary: 6
|
|
25
|
+
})[kind] ?? 4;
|
|
26
|
+
const getButtonKind = element => {
|
|
27
|
+
if (/*#__PURE__*/React.isValidElement(element) && element.props && typeof element.props === 'object') {
|
|
28
|
+
const props = element.props;
|
|
29
|
+
return props.kind ?? 'primary';
|
|
30
|
+
}
|
|
31
|
+
return 'primary';
|
|
32
|
+
};
|
|
18
33
|
const ButtonSet = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
19
34
|
const {
|
|
20
35
|
children,
|
|
21
36
|
className,
|
|
37
|
+
fluid,
|
|
22
38
|
stacked,
|
|
23
39
|
...rest
|
|
24
40
|
} = props;
|
|
25
41
|
const prefix = usePrefix.usePrefix();
|
|
42
|
+
const fluidInnerRef = React.useRef(null);
|
|
43
|
+
const [isStacked, setIsStacked] = React.useState(false);
|
|
44
|
+
const [sortedChildren, setSortedChildren] = React.useState(React.Children.toArray(children));
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Used to determine if the buttons are currently stacked
|
|
48
|
+
*/
|
|
49
|
+
useIsomorphicEffect.default(() => {
|
|
50
|
+
const checkStacking = () => {
|
|
51
|
+
let newIsStacked = stacked || false;
|
|
52
|
+
if (fluidInnerRef && fluidInnerRef.current) {
|
|
53
|
+
const computedStyle = window.getComputedStyle(fluidInnerRef.current);
|
|
54
|
+
newIsStacked = computedStyle?.getPropertyValue?.('--flex-direction') === 'column';
|
|
55
|
+
}
|
|
56
|
+
return newIsStacked;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/* initial value not dependant on observer */
|
|
60
|
+
setIsStacked(checkStacking());
|
|
61
|
+
if (!fluidInnerRef.current) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
65
|
+
setIsStacked(checkStacking());
|
|
66
|
+
});
|
|
67
|
+
resizeObserver.observe(fluidInnerRef.current);
|
|
68
|
+
return () => resizeObserver.disconnect();
|
|
69
|
+
}, [isStacked, stacked]);
|
|
70
|
+
React.useEffect(() => {
|
|
71
|
+
const newSortedChildren = React.Children.toArray(children);
|
|
72
|
+
newSortedChildren.sort((a, b) => {
|
|
73
|
+
return (buttonOrder(getButtonKind(a)) - buttonOrder(getButtonKind(b))) * (isStacked ? -1 : 1);
|
|
74
|
+
});
|
|
75
|
+
setSortedChildren(newSortedChildren);
|
|
76
|
+
|
|
77
|
+
// adding sortedChildren to deps causes an infinite loop
|
|
78
|
+
}, [children, isStacked]);
|
|
26
79
|
const buttonSetClasses = cx(className, `${prefix}--btn-set`, {
|
|
27
|
-
[`${prefix}--btn-set--stacked`]:
|
|
80
|
+
[`${prefix}--btn-set--stacked`]: isStacked,
|
|
81
|
+
[`${prefix}--btn-set--fluid`]: fluid
|
|
28
82
|
});
|
|
29
83
|
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, {
|
|
30
84
|
className: buttonSetClasses,
|
|
31
85
|
ref: ref
|
|
32
|
-
}),
|
|
86
|
+
}), fluid ? /*#__PURE__*/React.createElement("div", {
|
|
87
|
+
ref: fluidInnerRef,
|
|
88
|
+
className: cx(`${prefix}--btn-set__fluid-inner`, {
|
|
89
|
+
[`${prefix}--btn-set__fluid-inner--auto-stack`]: true
|
|
90
|
+
})
|
|
91
|
+
}, sortedChildren) : children);
|
|
33
92
|
});
|
|
34
93
|
ButtonSet.displayName = 'ButtonSet';
|
|
35
94
|
ButtonSet.propTypes = {
|
|
@@ -41,9 +100,14 @@ ButtonSet.propTypes = {
|
|
|
41
100
|
* Specify an optional className to be added to your ButtonSet
|
|
42
101
|
*/
|
|
43
102
|
className: PropTypes.string,
|
|
103
|
+
/**
|
|
104
|
+
* fluid: button set resize to the size of the container up to a maximum dependant on the
|
|
105
|
+
* number of buttons.
|
|
106
|
+
*/
|
|
107
|
+
fluid: PropTypes.bool,
|
|
44
108
|
/**
|
|
45
109
|
* Specify the button arrangement of the set (vertically stacked or
|
|
46
|
-
* horizontal)
|
|
110
|
+
* horizontal) - ignored when fluid is true
|
|
47
111
|
*/
|
|
48
112
|
stacked: PropTypes.bool
|
|
49
113
|
};
|
|
@@ -111,7 +111,7 @@ declare namespace CodeSnippet {
|
|
|
111
111
|
/**
|
|
112
112
|
* Specify how the trigger should align with the tooltip
|
|
113
113
|
*/
|
|
114
|
-
align: PropTypes.Requireable<
|
|
114
|
+
align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
|
|
115
115
|
/**
|
|
116
116
|
* Specify a label to be read by screen readers on the containing textbox
|
|
117
117
|
* node
|
|
@@ -210,7 +210,7 @@ const ComposedModalDialog = /*#__PURE__*/React.forwardRef(function ComposedModal
|
|
|
210
210
|
// behavior by explicitly setting preventCloseOnClickOutside to false,
|
|
211
211
|
// rather than just leaving it undefined.
|
|
212
212
|
!isPassive && preventCloseOnClickOutside === false;
|
|
213
|
-
if (shouldCloseOnOutsideClick && target instanceof Node && !wrapFocus.elementOrParentIsFloatingMenu(target, selectorsFloatingMenus) && innerModal.current && !innerModal.current.contains(target) && !innerModal.current.contains(mouseDownTarget)) {
|
|
213
|
+
if (shouldCloseOnOutsideClick && target instanceof Node && !wrapFocus.elementOrParentIsFloatingMenu(target, selectorsFloatingMenus, prefix) && innerModal.current && !innerModal.current.contains(target) && !innerModal.current.contains(mouseDownTarget)) {
|
|
214
214
|
closeModal(evt);
|
|
215
215
|
}
|
|
216
216
|
}
|
|
@@ -234,7 +234,8 @@ const ComposedModalDialog = /*#__PURE__*/React.forwardRef(function ComposedModal
|
|
|
234
234
|
endTrapNode: endSentinelNode,
|
|
235
235
|
currentActiveNode,
|
|
236
236
|
oldActiveNode,
|
|
237
|
-
selectorsFloatingMenus: selectorsFloatingMenus?.filter(Boolean)
|
|
237
|
+
selectorsFloatingMenus: selectorsFloatingMenus?.filter(Boolean),
|
|
238
|
+
prefix
|
|
238
239
|
});
|
|
239
240
|
}
|
|
240
241
|
|
|
@@ -50,7 +50,7 @@ declare namespace Copy {
|
|
|
50
50
|
/**
|
|
51
51
|
* Specify how the trigger should align with the tooltip
|
|
52
52
|
*/
|
|
53
|
-
align: PropTypes.Requireable<
|
|
53
|
+
align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
|
|
54
54
|
/**
|
|
55
55
|
* **Experimental**: Will attempt to automatically align the tooltip. Requires
|
|
56
56
|
* React v17+
|
|
@@ -51,7 +51,7 @@ declare namespace CopyButton {
|
|
|
51
51
|
/**
|
|
52
52
|
* Specify how the trigger should align with the tooltip
|
|
53
53
|
*/
|
|
54
|
-
align: PropTypes.Requireable<
|
|
54
|
+
align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
|
|
55
55
|
/**
|
|
56
56
|
* **Experimental**: Will attempt to automatically align the tooltip. Requires
|
|
57
57
|
* React v17+
|
|
@@ -282,11 +282,12 @@ export declare const DataTable: {
|
|
|
282
282
|
};
|
|
283
283
|
TableCell: React.ForwardRefExoticComponent<import("./TableCell").TableCellProps & React.RefAttributes<HTMLTableCellElement>>;
|
|
284
284
|
TableContainer: {
|
|
285
|
-
({ aiEnabled, className, children, title, description, stickyHeader, useStaticWidth, ...rest }: import("./TableContainer").TableContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
285
|
+
({ aiEnabled, className, children, decorator, title, description, stickyHeader, useStaticWidth, ...rest }: import("./TableContainer").TableContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
286
286
|
propTypes: {
|
|
287
287
|
aiEnabled: PropTypes.Requireable<boolean>;
|
|
288
288
|
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
289
289
|
className: PropTypes.Requireable<string>;
|
|
290
|
+
decorator: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
290
291
|
description: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
291
292
|
stickyHeader: PropTypes.Requireable<boolean>;
|
|
292
293
|
title: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
@@ -5,12 +5,16 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import React, { type HTMLAttributes } from 'react';
|
|
8
|
+
import React, { ReactNode, type HTMLAttributes } from 'react';
|
|
9
9
|
export interface TableContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
10
10
|
/**
|
|
11
11
|
* Specify if the entire table has AI generated contents
|
|
12
12
|
*/
|
|
13
13
|
aiEnabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `TableContainer` component
|
|
16
|
+
*/
|
|
17
|
+
decorator?: ReactNode;
|
|
14
18
|
/**
|
|
15
19
|
* Optional description text for the Table
|
|
16
20
|
*/
|
|
@@ -29,7 +33,7 @@ export interface TableContainerProps extends Omit<HTMLAttributes<HTMLDivElement>
|
|
|
29
33
|
title?: React.ReactNode;
|
|
30
34
|
}
|
|
31
35
|
declare const TableContainer: {
|
|
32
|
-
({ aiEnabled, className, children, title, description, stickyHeader, useStaticWidth, ...rest }: TableContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
({ aiEnabled, className, children, decorator, title, description, stickyHeader, useStaticWidth, ...rest }: TableContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
33
37
|
propTypes: {
|
|
34
38
|
/**
|
|
35
39
|
* Specify if the entire table has AI generated contents
|
|
@@ -37,6 +41,10 @@ declare const TableContainer: {
|
|
|
37
41
|
aiEnabled: PropTypes.Requireable<boolean>;
|
|
38
42
|
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
39
43
|
className: PropTypes.Requireable<string>;
|
|
44
|
+
/**
|
|
45
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `TableContainer` component
|
|
46
|
+
*/
|
|
47
|
+
decorator: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
40
48
|
/**
|
|
41
49
|
* Optional description text for the Table
|
|
42
50
|
*/
|