@carbon/react 1.88.0 → 1.89.0-rc.1
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 +848 -848
- package/es/components/AILabel/index.d.ts +2 -5
- package/es/components/AILabel/index.js +2 -42
- package/es/components/ContainedList/ContainedList.d.ts +2 -2
- package/es/components/Copy/Copy.js +1 -0
- package/es/components/Link/Link.js +15 -1
- package/es/components/Menu/MenuContext.d.ts +1 -1
- package/es/components/Menu/MenuContext.js +11 -4
- package/es/components/Menu/MenuItem.js +2 -9
- package/es/components/Modal/Modal.js +15 -7
- package/es/components/MultiSelect/FilterableMultiSelect.js +1 -5
- package/es/components/MultiSelect/MultiSelect.js +3 -7
- package/es/components/Popover/index.d.ts +4 -0
- package/es/components/Popover/index.js +11 -22
- package/es/components/StructuredList/StructuredList.d.ts +16 -0
- package/es/components/StructuredList/StructuredList.js +19 -9
- package/es/components/TextArea/TextArea.js +21 -4
- package/es/components/Toggletip/index.d.ts +13 -36
- package/es/components/Toggletip/index.js +11 -51
- package/es/components/UIShell/Header.d.ts +3 -3
- package/es/components/UIShell/Header.js +7 -4
- package/es/internal/Selection.js +1 -1
- package/es/internal/useMergedRefs.js +4 -3
- package/lib/components/AILabel/index.d.ts +2 -5
- package/lib/components/AILabel/index.js +1 -41
- package/lib/components/ContainedList/ContainedList.d.ts +2 -2
- package/lib/components/Copy/Copy.js +1 -0
- package/lib/components/Link/Link.js +15 -1
- package/lib/components/Menu/MenuContext.d.ts +1 -1
- package/lib/components/Menu/MenuContext.js +11 -4
- package/lib/components/Menu/MenuItem.js +2 -9
- package/lib/components/Modal/Modal.js +15 -7
- package/lib/components/MultiSelect/FilterableMultiSelect.js +1 -5
- package/lib/components/MultiSelect/MultiSelect.js +3 -7
- package/lib/components/Popover/index.d.ts +4 -0
- package/lib/components/Popover/index.js +10 -21
- package/lib/components/StructuredList/StructuredList.d.ts +16 -0
- package/lib/components/StructuredList/StructuredList.js +19 -9
- package/lib/components/TextArea/TextArea.js +21 -4
- package/lib/components/Toggletip/index.d.ts +13 -36
- package/lib/components/Toggletip/index.js +10 -50
- package/lib/components/UIShell/Header.d.ts +3 -3
- package/lib/components/UIShell/Header.js +7 -4
- package/lib/internal/Selection.js +1 -1
- package/lib/internal/useMergedRefs.js +3 -2
- package/package.json +12 -13
- package/telemetry.yml +3 -2
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
+
import { ToggletipBaseProps } from '../Toggletip';
|
|
8
9
|
import type { DeprecatedPopoverAlignment, NewPopoverAlignment, PopoverAlignment } from '../Popover';
|
|
9
10
|
export type AILabelContentProps = React.HTMLAttributes<HTMLSpanElement>;
|
|
10
11
|
export declare const AILabelContent: React.ForwardRefExoticComponent<AILabelContentProps & React.RefAttributes<unknown>>;
|
|
@@ -17,15 +18,11 @@ export declare const AILabelActions: React.ForwardRefExoticComponent<AILabelActi
|
|
|
17
18
|
export type DeprecatedAlignment = DeprecatedPopoverAlignment;
|
|
18
19
|
export type NewAlignment = NewPopoverAlignment;
|
|
19
20
|
export type Alignment = PopoverAlignment;
|
|
20
|
-
export interface AILabelProps {
|
|
21
|
+
export interface AILabelProps extends ToggletipBaseProps {
|
|
21
22
|
AILabelContent?: React.ReactNode;
|
|
22
23
|
aiText?: string;
|
|
23
24
|
aiTextLabel?: string;
|
|
24
25
|
textLabel?: string;
|
|
25
|
-
align?: Alignment;
|
|
26
|
-
autoAlign?: boolean;
|
|
27
|
-
children?: React.ReactNode;
|
|
28
|
-
className?: string;
|
|
29
26
|
kind?: 'default' | 'inline';
|
|
30
27
|
onRevertClick?: (evt: React.MouseEvent<HTMLButtonElement>) => void;
|
|
31
28
|
revertActive?: boolean;
|
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import cx from 'classnames';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
|
-
import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin.js';
|
|
12
11
|
import React from 'react';
|
|
13
12
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
14
|
-
import { ToggletipContent, ToggletipActions,
|
|
13
|
+
import { Toggletip, ToggletipContent, ToggletipActions, ToggletipButton } from '../Toggletip/index.js';
|
|
15
14
|
import { IconButton } from '../IconButton/index.js';
|
|
16
|
-
import { mapPopoverAlign } from '../../tools/mapPopoverAlign.js';
|
|
17
15
|
import { Undo } from '@carbon/icons-react';
|
|
18
16
|
import { useId } from '../../internal/useId.js';
|
|
19
17
|
import { deprecate } from '../../prop-types/deprecate.js';
|
|
@@ -143,6 +141,7 @@ const AILabel = /*#__PURE__*/React.forwardRef(function AILabel({
|
|
|
143
141
|
});
|
|
144
142
|
AILabel.displayName = 'AILabel';
|
|
145
143
|
AILabel.propTypes = {
|
|
144
|
+
...Toggletip.propTypes,
|
|
146
145
|
/**
|
|
147
146
|
* Specify the content you want rendered inside the `AILabel` ToggleTip
|
|
148
147
|
*/
|
|
@@ -156,49 +155,10 @@ AILabel.propTypes = {
|
|
|
156
155
|
* Specify additional text to be rendered next to the AI label in the inline variant
|
|
157
156
|
*/
|
|
158
157
|
aiTextLabel: deprecate(PropTypes.string, '`aiTextLabel` on `AILabel` has been deprecated - Please use the `textLabel` prop instead'),
|
|
159
|
-
/**
|
|
160
|
-
* Specify how the popover should align with the button
|
|
161
|
-
*/
|
|
162
|
-
align: deprecateValuesWithin(PropTypes.oneOf(['top', 'top-left',
|
|
163
|
-
// deprecated use top-start instead
|
|
164
|
-
'top-right',
|
|
165
|
-
// deprecated use top-end instead
|
|
166
|
-
|
|
167
|
-
'bottom', 'bottom-left',
|
|
168
|
-
// deprecated use bottom-start instead
|
|
169
|
-
'bottom-right',
|
|
170
|
-
// deprecated use bottom-end instead
|
|
171
|
-
|
|
172
|
-
'left', 'left-bottom',
|
|
173
|
-
// deprecated use left-end instead
|
|
174
|
-
'left-top',
|
|
175
|
-
// deprecated use left-start instead
|
|
176
|
-
|
|
177
|
-
'right', 'right-bottom',
|
|
178
|
-
// deprecated use right-end instead
|
|
179
|
-
'right-top',
|
|
180
|
-
// deprecated use right-start instead
|
|
181
|
-
|
|
182
|
-
// new values to match floating-ui
|
|
183
|
-
'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign),
|
|
184
158
|
/**
|
|
185
159
|
* Specify the text that will be provided to the aria-label of the `AILabel` button
|
|
186
160
|
*/
|
|
187
161
|
'aria-label': PropTypes.string,
|
|
188
|
-
/**
|
|
189
|
-
* Will auto-align the popover. This prop is currently experimental and is
|
|
190
|
-
* subject to future changes. Requires React v17+
|
|
191
|
-
* @see https://github.com/carbon-design-system/carbon/issues/18714
|
|
192
|
-
*/
|
|
193
|
-
autoAlign: PropTypes.bool,
|
|
194
|
-
/**
|
|
195
|
-
* Specify the content you want rendered inside the `AILabel` ToggleTip
|
|
196
|
-
*/
|
|
197
|
-
children: PropTypes.node,
|
|
198
|
-
/**
|
|
199
|
-
* Specify an optional className to be added to the `AILabel`
|
|
200
|
-
*/
|
|
201
|
-
className: PropTypes.string,
|
|
202
162
|
/**
|
|
203
163
|
* Specify the type of `AILabel`, from the following list of types:
|
|
204
164
|
*/
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import React, { ReactNode } from 'react';
|
|
8
8
|
import ContainedListItem from './ContainedListItem';
|
|
9
9
|
declare const variants: readonly ["on-page", "disclosed"];
|
|
10
|
-
export
|
|
10
|
+
export type ContainedListType = React.FC<ContainedListProps> & {
|
|
11
11
|
ContainedListItem: typeof ContainedListItem;
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
export type Variants = (typeof variants)[number];
|
|
14
14
|
export interface ContainedListProps {
|
|
15
15
|
/**
|
|
@@ -57,6 +57,7 @@ function Copy({
|
|
|
57
57
|
autoAlign: autoAlign,
|
|
58
58
|
className: classNames,
|
|
59
59
|
label: animation ? feedback : initialLabel,
|
|
60
|
+
leaveDelayMs: animation ? feedbackTimeout : undefined,
|
|
60
61
|
onClick: composeEventHandlers([onClick, handleClick]),
|
|
61
62
|
onAnimationEnd: composeEventHandlers([onAnimationEnd, handleAnimationEnd])
|
|
62
63
|
}, other, {
|
|
@@ -48,9 +48,23 @@ const LinkBase = /*#__PURE__*/React.forwardRef(({
|
|
|
48
48
|
linkProps['aria-disabled'] = true;
|
|
49
49
|
}
|
|
50
50
|
const BaseComponentAsAny = BaseComponent ?? 'a';
|
|
51
|
+
const handleOnClick = event => {
|
|
52
|
+
if (disabled) {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
event.stopPropagation();
|
|
55
|
+
} else {
|
|
56
|
+
// If the link is not disabled, we allow the onClick event to propagate
|
|
57
|
+
// so that any parent handlers can also respond to the click.
|
|
58
|
+
if (rest.onClick) {
|
|
59
|
+
rest.onClick(event);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
51
63
|
return /*#__PURE__*/React.createElement(BaseComponentAsAny, _extends({
|
|
52
64
|
ref: ref
|
|
53
|
-
}, linkProps, rest
|
|
65
|
+
}, linkProps, rest, {
|
|
66
|
+
onClick: handleOnClick
|
|
67
|
+
}), children, !inline && Icon && /*#__PURE__*/React.createElement("div", {
|
|
54
68
|
className: `${prefix}--link__icon`
|
|
55
69
|
}, /*#__PURE__*/React.createElement(Icon, null)));
|
|
56
70
|
});
|
|
@@ -28,10 +28,17 @@ function menuReducer(state, action) {
|
|
|
28
28
|
hasSelectableItems: true
|
|
29
29
|
};
|
|
30
30
|
case 'registerItem':
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
items
|
|
34
|
-
|
|
31
|
+
{
|
|
32
|
+
const newItem = action.payload;
|
|
33
|
+
const items = state.items.filter(item => item.ref.current);
|
|
34
|
+
const next = newItem.ref.current?.nextElementSibling;
|
|
35
|
+
const idx = items.findIndex(item => item.ref.current === next);
|
|
36
|
+
items.splice(idx < 0 ? items.length : idx, 0, newItem);
|
|
37
|
+
return {
|
|
38
|
+
...state,
|
|
39
|
+
items
|
|
40
|
+
};
|
|
41
|
+
}
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
const MenuContext = /*#__PURE__*/createContext({
|
|
@@ -128,18 +128,11 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
128
128
|
[`${prefix}--menu-item--disabled`]: isDisabled,
|
|
129
129
|
[`${prefix}--menu-item--danger`]: isDanger
|
|
130
130
|
});
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
// on first render, register this menuitem in the context's state
|
|
133
133
|
// (used for keyboard navigation)
|
|
134
134
|
useEffect(() => {
|
|
135
135
|
registerItem();
|
|
136
|
-
|
|
137
|
-
// Detects if this is the first focusable item
|
|
138
|
-
const currentItems = context.state.items;
|
|
139
|
-
if (!disabled && menuItem.current && currentItems.length === 0) {
|
|
140
|
-
setIsFocusable(true);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
136
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
144
137
|
}, []);
|
|
145
138
|
|
|
@@ -178,7 +171,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
178
171
|
}, rest, {
|
|
179
172
|
ref: ref,
|
|
180
173
|
className: classNames,
|
|
181
|
-
tabIndex:
|
|
174
|
+
tabIndex: !disabled ? 0 : -1,
|
|
182
175
|
"aria-disabled": isDisabled ?? undefined,
|
|
183
176
|
"aria-haspopup": hasChildren ?? undefined,
|
|
184
177
|
"aria-expanded": hasChildren ? submenuOpen : undefined,
|
|
@@ -81,6 +81,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
81
81
|
const innerModal = useRef(null);
|
|
82
82
|
const startTrap = useRef(null);
|
|
83
83
|
const endTrap = useRef(null);
|
|
84
|
+
const wrapFocusTimeout = useRef(null);
|
|
84
85
|
const [isScrollable, setIsScrollable] = useState(false);
|
|
85
86
|
const prevOpen = usePreviousValue(open);
|
|
86
87
|
const modalInstanceId = `modal-${useId()}`;
|
|
@@ -142,13 +143,20 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
|
|
|
142
143
|
const {
|
|
143
144
|
current: endTrapNode
|
|
144
145
|
} = endTrap;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
// use setTimeout to ensure focus is set after all browser default focus behavior. Fixes issue of
|
|
147
|
+
// focus not wrapping in Firefox
|
|
148
|
+
wrapFocusTimeout.current = setTimeout(() => {
|
|
149
|
+
wrapFocus({
|
|
150
|
+
bodyNode,
|
|
151
|
+
startTrapNode,
|
|
152
|
+
endTrapNode,
|
|
153
|
+
currentActiveNode,
|
|
154
|
+
oldActiveNode,
|
|
155
|
+
selectorsFloatingMenus
|
|
156
|
+
});
|
|
157
|
+
if (wrapFocusTimeout.current) {
|
|
158
|
+
clearTimeout(wrapFocusTimeout.current);
|
|
159
|
+
}
|
|
152
160
|
});
|
|
153
161
|
}
|
|
154
162
|
|
|
@@ -122,11 +122,7 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
122
122
|
inputValue
|
|
123
123
|
}), [items, inputValue, itemToString, filterItems]);
|
|
124
124
|
const nonSelectAllItems = useMemo(() => filteredItems.filter(item => !item.isSelectAll), [filteredItems]);
|
|
125
|
-
|
|
126
|
-
if ((selected ?? []).length > 0 && selectAll) {
|
|
127
|
-
console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
|
|
128
|
-
selectAll = false;
|
|
129
|
-
}
|
|
125
|
+
const selectAll = filteredItems.some(item => item.isSelectAll);
|
|
130
126
|
const {
|
|
131
127
|
selectedItems: controlledSelectedItems,
|
|
132
128
|
onItemChange,
|
|
@@ -111,11 +111,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
111
111
|
return true; // Return true if item is not an object with undefined values
|
|
112
112
|
});
|
|
113
113
|
}, [items]);
|
|
114
|
-
|
|
115
|
-
if ((selected ?? []).length > 0 && selectAll) {
|
|
116
|
-
console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
|
|
117
|
-
selectAll = false;
|
|
118
|
-
}
|
|
114
|
+
const selectAll = filteredItems.some(item => item.isSelectAll);
|
|
119
115
|
const prefix = usePrefix();
|
|
120
116
|
const {
|
|
121
117
|
isFluid
|
|
@@ -489,13 +485,13 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
489
485
|
})), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
|
|
490
486
|
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
491
487
|
}, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(ListBox.Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index) => {
|
|
492
|
-
const isChecked = selectedItems.filter(selected => isEqual(selected, item)).length > 0;
|
|
493
488
|
const {
|
|
494
489
|
hasIndividualSelections,
|
|
495
490
|
nonSelectAllSelectedCount,
|
|
496
491
|
totalSelectableCount
|
|
497
492
|
} = getSelectionStats(selectedItems, filteredItems);
|
|
498
|
-
const
|
|
493
|
+
const isChecked = item.isSelectAll ? nonSelectAllSelectedCount === totalSelectableCount && totalSelectableCount > 0 : selectedItems.some(selected => isEqual(selected, item));
|
|
494
|
+
const isIndeterminate = item.isSelectAll && hasIndividualSelections && nonSelectAllSelectedCount < totalSelectableCount;
|
|
499
495
|
const itemProps = getItemProps({
|
|
500
496
|
item,
|
|
501
497
|
// we don't want Downshift to set aria-selected for us
|
|
@@ -25,6 +25,10 @@ export interface PopoverBaseProps {
|
|
|
25
25
|
* Specify how the popover should align with the trigger element.
|
|
26
26
|
*/
|
|
27
27
|
align?: PopoverAlignment;
|
|
28
|
+
/**
|
|
29
|
+
* **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
|
|
30
|
+
*/
|
|
31
|
+
alignmentAxisOffset?: number;
|
|
28
32
|
/**
|
|
29
33
|
* Will auto-align the popover on first render if it is not visible. This prop
|
|
30
34
|
* is currently experimental and is subject to future changes. Requires
|
|
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
|
|
|
9
9
|
import cx from 'classnames';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin.js';
|
|
12
|
-
import React, { useRef,
|
|
12
|
+
import React, { useRef, useMemo, useEffect } from 'react';
|
|
13
13
|
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
14
14
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
15
15
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -17,7 +17,6 @@ import { useEvent, useWindowEvent } from '../../internal/useEvent.js';
|
|
|
17
17
|
import { mapPopoverAlign } from '../../tools/mapPopoverAlign.js';
|
|
18
18
|
import { useFloating, autoUpdate, offset, flip, arrow, hide } from '@floating-ui/react';
|
|
19
19
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
20
|
-
import { ToggletipButton } from '../Toggletip/index.js';
|
|
21
20
|
|
|
22
21
|
const PopoverContext = /*#__PURE__*/React.createContext({
|
|
23
22
|
setFloating: {
|
|
@@ -62,7 +61,10 @@ forwardRef) {
|
|
|
62
61
|
// The `Popover` should close whenever it and its children loses focus
|
|
63
62
|
useEvent(popover, 'focusout', event => {
|
|
64
63
|
const relatedTarget = event.relatedTarget;
|
|
64
|
+
|
|
65
|
+
// No relatedTarget, focus moved to nowhere, so close the popover
|
|
65
66
|
if (!relatedTarget) {
|
|
67
|
+
onRequestClose?.();
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
68
70
|
const isOutsideMainContainer = !popover.current?.contains(relatedTarget);
|
|
@@ -235,7 +237,7 @@ forwardRef) {
|
|
|
235
237
|
// For a toggletip there is a specific trigger component, ToggletipButton.
|
|
236
238
|
// In either of these cases we want to set this as the reference node for floating-ui autoAlign
|
|
237
239
|
// positioning.
|
|
238
|
-
if (enableFloatingStyles && item?.type !== PopoverContent || enableFloatingStyles && item?.type === ToggletipButton) {
|
|
240
|
+
if (enableFloatingStyles && item?.type !== PopoverContent || enableFloatingStyles && item?.type['displayName'] === 'ToggletipButton') {
|
|
239
241
|
// Set the reference element for floating-ui
|
|
240
242
|
refs.setReference(node);
|
|
241
243
|
}
|
|
@@ -292,6 +294,10 @@ Popover.propTypes = {
|
|
|
292
294
|
|
|
293
295
|
// new values to match floating-ui
|
|
294
296
|
'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign),
|
|
297
|
+
/**
|
|
298
|
+
* **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
|
|
299
|
+
*/
|
|
300
|
+
alignmentAxisOffset: PropTypes.number,
|
|
295
301
|
/**
|
|
296
302
|
* Provide a custom element or component to render the top-level node for the
|
|
297
303
|
* component.
|
|
@@ -361,29 +367,12 @@ function PopoverContentRenderFunction(
|
|
|
361
367
|
caretRef,
|
|
362
368
|
autoAlign
|
|
363
369
|
} = React.useContext(PopoverContext);
|
|
364
|
-
const
|
|
365
|
-
const [isMultiLine, setIsMultiLine] = React.useState(false);
|
|
366
|
-
const ref = useMergedRefs([setFloating, textRef, forwardRef]);
|
|
370
|
+
const ref = useMergedRefs([setFloating, forwardRef]);
|
|
367
371
|
const enableFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
|
|
368
|
-
useEffect(() => {
|
|
369
|
-
checkIfMultiLine();
|
|
370
|
-
}, [children]);
|
|
371
|
-
const checkIfMultiLine = () => {
|
|
372
|
-
const el = textRef.current;
|
|
373
|
-
if (el) {
|
|
374
|
-
const style = getComputedStyle(el);
|
|
375
|
-
const lineHeight = parseFloat(style.lineHeight);
|
|
376
|
-
const height = el.offsetHeight;
|
|
377
|
-
const lines = Math.floor(height / lineHeight);
|
|
378
|
-
setIsMultiLine(lines > 1);
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
372
|
return /*#__PURE__*/React.createElement("span", _extends({}, rest, {
|
|
382
373
|
className: `${prefix}--popover`
|
|
383
374
|
}), /*#__PURE__*/React.createElement("span", {
|
|
384
|
-
className: cx(`${prefix}--popover-content`, className,
|
|
385
|
-
[`${prefix}--tooltip-content--multiline`]: isMultiLine
|
|
386
|
-
}),
|
|
375
|
+
className: cx(`${prefix}--popover-content`, className),
|
|
387
376
|
ref: ref
|
|
388
377
|
}, children, enableFloatingStyles && /*#__PURE__*/React.createElement("span", {
|
|
389
378
|
className: cx({
|
|
@@ -32,6 +32,10 @@ export interface StructuredListWrapperProps extends DivAttrs {
|
|
|
32
32
|
* Specify whether your StructuredListWrapper should have selections
|
|
33
33
|
*/
|
|
34
34
|
selection?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Specify which row will be selected initially
|
|
37
|
+
*/
|
|
38
|
+
selectedInitialRow?: string;
|
|
35
39
|
}
|
|
36
40
|
export declare function StructuredListWrapper(props: StructuredListWrapperProps): import("react/jsx-runtime").JSX.Element;
|
|
37
41
|
export declare namespace StructuredListWrapper {
|
|
@@ -65,6 +69,10 @@ export declare namespace StructuredListWrapper {
|
|
|
65
69
|
* Specify whether your StructuredListWrapper should have selections
|
|
66
70
|
*/
|
|
67
71
|
selection: PropTypes.Requireable<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Specify which row will be selected initially
|
|
74
|
+
*/
|
|
75
|
+
selectedInitialRow: PropTypes.Requireable<string>;
|
|
68
76
|
};
|
|
69
77
|
}
|
|
70
78
|
export interface StructuredListHeadProps extends DivAttrs {
|
|
@@ -148,6 +156,10 @@ export interface StructuredListRowProps extends DivAttrs {
|
|
|
148
156
|
* Mark if this row should be selectable
|
|
149
157
|
*/
|
|
150
158
|
selection?: boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Specify row id so that it can be used for initial selection
|
|
161
|
+
*/
|
|
162
|
+
id?: string;
|
|
151
163
|
}
|
|
152
164
|
export declare function StructuredListRow(props: StructuredListRowProps): import("react/jsx-runtime").JSX.Element;
|
|
153
165
|
export declare namespace StructuredListRow {
|
|
@@ -180,6 +192,10 @@ export declare namespace StructuredListRow {
|
|
|
180
192
|
* Mark if this row should be selectable
|
|
181
193
|
*/
|
|
182
194
|
selection: PropTypes.Requireable<boolean>;
|
|
195
|
+
/**
|
|
196
|
+
* Specify row id so that it can be used for initial selection
|
|
197
|
+
*/
|
|
198
|
+
id: PropTypes.Requireable<string>;
|
|
183
199
|
};
|
|
184
200
|
}
|
|
185
201
|
export interface StructuredListInputProps extends DivAttrs {
|
|
@@ -30,6 +30,7 @@ function StructuredListWrapper(props) {
|
|
|
30
30
|
ariaLabel: deprecatedAriaLabel,
|
|
31
31
|
isCondensed,
|
|
32
32
|
isFlush,
|
|
33
|
+
selectedInitialRow,
|
|
33
34
|
...other
|
|
34
35
|
} = props;
|
|
35
36
|
const prefix = usePrefix();
|
|
@@ -38,7 +39,7 @@ function StructuredListWrapper(props) {
|
|
|
38
39
|
[`${prefix}--structured-list--condensed`]: isCondensed,
|
|
39
40
|
[`${prefix}--structured-list--flush`]: isFlush && !selection
|
|
40
41
|
}, className);
|
|
41
|
-
const [selectedRow, setSelectedRow] = React.useState(null);
|
|
42
|
+
const [selectedRow, setSelectedRow] = React.useState(selectedInitialRow ?? null);
|
|
42
43
|
return /*#__PURE__*/React.createElement(GridSelectedRowStateContext.Provider, {
|
|
43
44
|
value: selectedRow
|
|
44
45
|
}, /*#__PURE__*/React.createElement(GridSelectedRowDispatchContext.Provider, {
|
|
@@ -79,7 +80,11 @@ StructuredListWrapper.propTypes = {
|
|
|
79
80
|
/**
|
|
80
81
|
* Specify whether your StructuredListWrapper should have selections
|
|
81
82
|
*/
|
|
82
|
-
selection: PropTypes.bool
|
|
83
|
+
selection: PropTypes.bool,
|
|
84
|
+
/**
|
|
85
|
+
* Specify which row will be selected initially
|
|
86
|
+
*/
|
|
87
|
+
selectedInitialRow: PropTypes.string
|
|
83
88
|
};
|
|
84
89
|
function StructuredListHead(props) {
|
|
85
90
|
const {
|
|
@@ -141,21 +146,22 @@ function StructuredListRow(props) {
|
|
|
141
146
|
head,
|
|
142
147
|
onClick,
|
|
143
148
|
selection,
|
|
149
|
+
id,
|
|
144
150
|
...other
|
|
145
151
|
} = props;
|
|
146
152
|
const [hasFocusWithin, setHasFocusWithin] = useState(false);
|
|
147
|
-
const
|
|
153
|
+
const rowId = id ?? useId('grid-input');
|
|
148
154
|
const selectedRow = React.useContext(GridSelectedRowStateContext);
|
|
149
155
|
const setSelectedRow = React.useContext(GridSelectedRowDispatchContext);
|
|
150
156
|
const prefix = usePrefix();
|
|
151
157
|
const value = {
|
|
152
|
-
id
|
|
158
|
+
id: rowId
|
|
153
159
|
};
|
|
154
160
|
const classes = cx(`${prefix}--structured-list-row`, {
|
|
155
161
|
[`${prefix}--structured-list-row--header-row`]: head,
|
|
156
|
-
[`${prefix}--structured-list-row--focused-within`]: hasFocusWithin && !selection || hasFocusWithin && selection && (selectedRow ===
|
|
162
|
+
[`${prefix}--structured-list-row--focused-within`]: hasFocusWithin && !selection || hasFocusWithin && selection && (selectedRow === rowId || selectedRow === null),
|
|
157
163
|
// Ensure focus on the first item when navigating through Tab keys and no row is selected (selectedRow === null)
|
|
158
|
-
[`${prefix}--structured-list-row--selected`]: selectedRow ===
|
|
164
|
+
[`${prefix}--structured-list-row--selected`]: selectedRow === rowId
|
|
159
165
|
}, className);
|
|
160
166
|
const itemRef = useRef(null);
|
|
161
167
|
const handleClick = () => {
|
|
@@ -176,7 +182,7 @@ function StructuredListRow(props) {
|
|
|
176
182
|
className: classes,
|
|
177
183
|
ref: itemRef,
|
|
178
184
|
onClick: event => {
|
|
179
|
-
setSelectedRow?.(
|
|
185
|
+
setSelectedRow?.(rowId);
|
|
180
186
|
onClick && onClick(event);
|
|
181
187
|
if (selection) {
|
|
182
188
|
// focus items only when selection is enabled
|
|
@@ -192,7 +198,7 @@ function StructuredListRow(props) {
|
|
|
192
198
|
onKeyDown: onKeyDown
|
|
193
199
|
}), /*#__PURE__*/React.createElement(GridRowContext.Provider, {
|
|
194
200
|
value: value
|
|
195
|
-
}, selection && /*#__PURE__*/React.createElement(StructuredListCell, null, selectedRow ===
|
|
201
|
+
}, selection && /*#__PURE__*/React.createElement(StructuredListCell, null, selectedRow === rowId ? /*#__PURE__*/React.createElement(RadioButtonChecked, {
|
|
196
202
|
className: `${prefix}--structured-list__icon`
|
|
197
203
|
}) : /*#__PURE__*/React.createElement(RadioButton, {
|
|
198
204
|
className: `${prefix}--structured-list__icon`
|
|
@@ -226,7 +232,11 @@ StructuredListRow.propTypes = {
|
|
|
226
232
|
/**
|
|
227
233
|
* Mark if this row should be selectable
|
|
228
234
|
*/
|
|
229
|
-
selection: PropTypes.bool
|
|
235
|
+
selection: PropTypes.bool,
|
|
236
|
+
/**
|
|
237
|
+
* Specify row id so that it can be used for initial selection
|
|
238
|
+
*/
|
|
239
|
+
id: PropTypes.string
|
|
230
240
|
};
|
|
231
241
|
function StructuredListInput(props) {
|
|
232
242
|
const defaultId = useId('structureListInput');
|
|
@@ -59,7 +59,11 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
59
59
|
value
|
|
60
60
|
} = other;
|
|
61
61
|
const textAreaInstanceId = useId();
|
|
62
|
+
const wrapperRef = useRef(null);
|
|
62
63
|
const textareaRef = useRef(null);
|
|
64
|
+
const helperTextRef = useRef(null);
|
|
65
|
+
const errorTextRef = useRef(null);
|
|
66
|
+
const warnTextRef = useRef(null);
|
|
63
67
|
const ref = useMergedRefs([forwardRef, textareaRef]);
|
|
64
68
|
function getInitialTextCount() {
|
|
65
69
|
const targetValue = defaultValue || value || textareaRef.current?.value || '';
|
|
@@ -76,13 +80,20 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
76
80
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
77
81
|
}, [value, defaultValue, counterMode]);
|
|
78
82
|
useIsomorphicEffect(() => {
|
|
83
|
+
const measuredWidth = wrapperRef.current?.scrollWidth;
|
|
79
84
|
if (other.cols && textareaRef.current) {
|
|
80
85
|
textareaRef.current.style.width = '';
|
|
81
86
|
textareaRef.current.style.resize = 'none';
|
|
82
87
|
} else if (textareaRef.current) {
|
|
83
88
|
textareaRef.current.style.width = `100%`;
|
|
84
89
|
}
|
|
85
|
-
|
|
90
|
+
[helperTextRef, errorTextRef, warnTextRef].forEach(r => {
|
|
91
|
+
if (r.current) {
|
|
92
|
+
r.current.style.maxWidth = `${measuredWidth}px`;
|
|
93
|
+
r.current.style.overflowWrap = 'break-word';
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}, [other.cols, invalid, warn]);
|
|
86
97
|
const textareaProps = {
|
|
87
98
|
id,
|
|
88
99
|
onKeyDown: evt => {
|
|
@@ -190,21 +201,26 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
190
201
|
const helper = helperText ? /*#__PURE__*/React.createElement(Text, {
|
|
191
202
|
as: "div",
|
|
192
203
|
id: helperId,
|
|
193
|
-
className: helperTextClasses
|
|
204
|
+
className: helperTextClasses,
|
|
205
|
+
ref: helperTextRef
|
|
194
206
|
}, helperText) : null;
|
|
195
207
|
const errorId = id + '-error-msg';
|
|
196
208
|
const error = invalid ? /*#__PURE__*/React.createElement(Text, {
|
|
197
209
|
as: "div",
|
|
198
210
|
role: "alert",
|
|
199
211
|
className: `${prefix}--form-requirement`,
|
|
200
|
-
id: errorId
|
|
212
|
+
id: errorId,
|
|
213
|
+
ref: errorTextRef
|
|
201
214
|
}, invalidText, isFluid && /*#__PURE__*/React.createElement(WarningFilled, {
|
|
202
215
|
className: `${prefix}--text-area__invalid-icon`
|
|
203
216
|
})) : null;
|
|
217
|
+
const warnId = id + '-warn-msg';
|
|
204
218
|
const warning = warn ? /*#__PURE__*/React.createElement(Text, {
|
|
205
219
|
as: "div",
|
|
206
220
|
role: "alert",
|
|
207
|
-
className: `${prefix}--form-requirement
|
|
221
|
+
className: `${prefix}--form-requirement`,
|
|
222
|
+
id: warnId,
|
|
223
|
+
ref: warnTextRef
|
|
208
224
|
}, warnText, isFluid && /*#__PURE__*/React.createElement(WarningAltFilled, {
|
|
209
225
|
className: `${prefix}--text-area__invalid-icon ${prefix}--text-area__invalid-icon--warning`
|
|
210
226
|
})) : null;
|
|
@@ -270,6 +286,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
270
286
|
}, /*#__PURE__*/React.createElement("div", {
|
|
271
287
|
className: `${prefix}--text-area__label-wrapper`
|
|
272
288
|
}, label, counter), /*#__PURE__*/React.createElement("div", {
|
|
289
|
+
ref: wrapperRef,
|
|
273
290
|
className: textAreaWrapperClasses,
|
|
274
291
|
"data-invalid": invalid || null
|
|
275
292
|
}, invalid && !isFluid && /*#__PURE__*/React.createElement(WarningFilled, {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import React, { type ElementType, type ReactNode } from 'react';
|
|
9
|
-
import { type PopoverAlignment } from '../Popover';
|
|
9
|
+
import { type PopoverAlignment, PopoverBaseProps } from '../Popover';
|
|
10
10
|
import { PolymorphicProps } from '../../types/common';
|
|
11
11
|
import { PolymorphicComponentPropWithRef } from '../../internal/PolymorphicProps';
|
|
12
12
|
type ToggletipLabelProps<E extends ElementType> = {
|
|
@@ -36,12 +36,7 @@ export declare namespace ToggletipLabel {
|
|
|
36
36
|
className: PropTypes.Requireable<string>;
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
export interface ToggletipBaseProps {
|
|
40
|
-
align?: PopoverAlignment;
|
|
41
|
-
alignmentAxisOffset?: number;
|
|
42
|
-
autoAlign?: boolean;
|
|
43
|
-
className?: string;
|
|
44
|
-
children?: ReactNode;
|
|
39
|
+
export interface ToggletipBaseProps extends Omit<PopoverBaseProps, 'open'> {
|
|
45
40
|
defaultOpen?: boolean;
|
|
46
41
|
}
|
|
47
42
|
export type ToggletipProps<T extends ElementType> = PolymorphicComponentPropWithRef<T, ToggletipBaseProps>;
|
|
@@ -53,39 +48,21 @@ export type ToggletipProps<T extends ElementType> = PolymorphicComponentPropWith
|
|
|
53
48
|
export declare function Toggletip<E extends ElementType = 'span'>({ align, as, autoAlign, className: customClassName, children, defaultOpen, ...rest }: ToggletipProps<E>): import("react/jsx-runtime").JSX.Element;
|
|
54
49
|
export declare namespace Toggletip {
|
|
55
50
|
var propTypes: {
|
|
56
|
-
/**
|
|
57
|
-
* Specify how the toggletip should align with the button
|
|
58
|
-
*/
|
|
59
|
-
align: PropTypes.Requireable<string>;
|
|
60
|
-
/**
|
|
61
|
-
* **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
|
|
62
|
-
*/
|
|
63
|
-
alignmentAxisOffset: PropTypes.Requireable<number>;
|
|
64
|
-
/**
|
|
65
|
-
* Provide a custom element or component to render the top-level node for the
|
|
66
|
-
* component.
|
|
67
|
-
*/
|
|
68
|
-
as: PropTypes.Requireable<PropTypes.ReactComponentLike>;
|
|
69
|
-
/**
|
|
70
|
-
* Will auto-align the popover on first render if it is not visible. This prop
|
|
71
|
-
* is currently experimental and is subject to future changes. Requires
|
|
72
|
-
* React v17+
|
|
73
|
-
* @see https://github.com/carbon-design-system/carbon/issues/18714
|
|
74
|
-
*/
|
|
75
|
-
autoAlign: PropTypes.Requireable<boolean>;
|
|
76
|
-
/**
|
|
77
|
-
* Custom children to be rendered as the content of the label
|
|
78
|
-
*/
|
|
79
|
-
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
80
|
-
/**
|
|
81
|
-
* Provide a custom class name to be added to the outermost node in the
|
|
82
|
-
* component
|
|
83
|
-
*/
|
|
84
|
-
className: PropTypes.Requireable<string>;
|
|
85
51
|
/**
|
|
86
52
|
* Specify if the toggletip should be open by default
|
|
87
53
|
*/
|
|
88
54
|
defaultOpen: PropTypes.Requireable<boolean>;
|
|
55
|
+
align?: PopoverAlignment;
|
|
56
|
+
alignmentAxisOffset?: number;
|
|
57
|
+
autoAlign?: boolean;
|
|
58
|
+
autoAlignBoundary?: import("@floating-ui/dom").Boundary;
|
|
59
|
+
caret?: boolean;
|
|
60
|
+
children?: React.ReactNode;
|
|
61
|
+
className?: string;
|
|
62
|
+
dropShadow?: boolean;
|
|
63
|
+
highContrast?: boolean;
|
|
64
|
+
isTabTip?: boolean;
|
|
65
|
+
onRequestClose?: () => void;
|
|
89
66
|
};
|
|
90
67
|
}
|
|
91
68
|
export interface ToggletipButtonBaseProps {
|