@carbon/react 1.53.1 → 1.54.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 +1009 -1096
- package/es/components/ComboBox/ComboBox.js +13 -4
- package/es/components/ComboButton/index.js +1 -1
- package/es/components/ComposedModal/ComposedModal.js +19 -10
- package/es/components/DataTable/DataTable.js +1 -1
- package/es/components/DataTable/TableBatchAction.d.ts +1 -1
- package/es/components/DataTable/TableToolbarMenu.d.ts +5 -1
- package/es/components/DataTable/TableToolbarMenu.js +7 -0
- package/es/components/DatePicker/DatePicker.d.ts +4 -0
- package/es/components/DatePicker/DatePicker.js +37 -0
- package/es/components/IconButton/index.d.ts +1 -1
- package/es/components/IconButton/index.js +1 -1
- package/es/components/ListBox/ListBox.d.ts +8 -0
- package/es/components/ListBox/ListBox.js +15 -3
- package/es/components/Loading/Loading.d.ts +1 -1
- package/es/components/Modal/Modal.js +14 -5
- package/es/components/Notification/Notification.js +18 -6
- package/es/components/Pagination/Pagination.Skeleton.d.ts +25 -0
- package/es/components/Pagination/Pagination.d.ts +102 -0
- package/es/components/Pagination/Pagination.js +13 -14
- package/es/components/Pagination/index.d.ts +10 -0
- package/es/components/Popover/index.d.ts +1 -1
- package/es/components/Popover/index.js +175 -108
- package/es/components/RadioTile/RadioTile.d.ts +55 -0
- package/es/components/RadioTile/RadioTile.js +17 -17
- package/es/components/RadioTile/index.d.ts +10 -0
- package/es/components/Slug/index.js +23 -2
- package/es/components/Stack/HStack.d.ts +10 -0
- package/es/components/Stack/HStack.js +23 -0
- package/es/components/Stack/Stack.d.ts +1 -1
- package/es/components/Stack/Stack.js +2 -2
- package/es/components/Stack/VStack.d.ts +10 -0
- package/es/components/Stack/{index.js → VStack.js} +1 -8
- package/es/components/Stack/index.d.ts +3 -6
- package/es/components/TileGroup/TileGroup.js +30 -24
- package/es/components/Toggletip/index.d.ts +1 -18
- package/es/components/Toggletip/index.js +27 -4
- package/es/components/Tooltip/Tooltip.js +23 -5
- package/es/index.d.ts +1 -0
- package/es/index.js +5 -4
- package/es/internal/FloatingMenu.js +26 -5
- package/es/internal/wrapFocus.js +51 -1
- package/es/tools/createPropAdapter.js +40 -0
- package/lib/components/ComboBox/ComboBox.js +13 -4
- package/lib/components/ComboButton/index.js +1 -1
- package/lib/components/ComposedModal/ComposedModal.js +17 -8
- package/lib/components/DataTable/DataTable.js +1 -1
- package/lib/components/DataTable/TableBatchAction.d.ts +1 -1
- package/lib/components/DataTable/TableToolbarMenu.d.ts +5 -1
- package/lib/components/DataTable/TableToolbarMenu.js +7 -0
- package/lib/components/DatePicker/DatePicker.d.ts +4 -0
- package/lib/components/DatePicker/DatePicker.js +37 -0
- package/lib/components/IconButton/index.d.ts +1 -1
- package/lib/components/IconButton/index.js +1 -1
- package/lib/components/ListBox/ListBox.d.ts +8 -0
- package/lib/components/ListBox/ListBox.js +15 -3
- package/lib/components/Loading/Loading.d.ts +1 -1
- package/lib/components/Modal/Modal.js +14 -5
- package/lib/components/Notification/Notification.js +15 -3
- package/lib/components/Pagination/Pagination.Skeleton.d.ts +25 -0
- package/lib/components/Pagination/Pagination.d.ts +102 -0
- package/lib/components/Pagination/Pagination.js +13 -14
- package/lib/components/Pagination/index.d.ts +10 -0
- package/lib/components/Popover/index.d.ts +1 -1
- package/lib/components/Popover/index.js +174 -107
- package/lib/components/RadioTile/RadioTile.d.ts +55 -0
- package/lib/components/RadioTile/RadioTile.js +17 -17
- package/lib/components/RadioTile/index.d.ts +10 -0
- package/lib/components/Slug/index.js +23 -2
- package/lib/components/Stack/HStack.d.ts +10 -0
- package/lib/components/Stack/HStack.js +31 -0
- package/lib/components/Stack/Stack.d.ts +1 -1
- package/lib/components/Stack/Stack.js +3 -3
- package/lib/components/Stack/VStack.d.ts +10 -0
- package/lib/components/Stack/{index.js → VStack.js} +0 -8
- package/lib/components/Stack/index.d.ts +3 -6
- package/lib/components/TileGroup/TileGroup.js +30 -24
- package/lib/components/Toggletip/index.d.ts +1 -18
- package/lib/components/Toggletip/index.js +27 -4
- package/lib/components/Tooltip/Tooltip.js +23 -5
- package/lib/index.d.ts +1 -0
- package/lib/index.js +15 -14
- package/lib/internal/FloatingMenu.js +44 -4
- package/lib/internal/wrapFocus.js +51 -0
- package/lib/tools/createPropAdapter.js +44 -0
- package/package.json +9 -7
|
@@ -238,7 +238,9 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
238
238
|
const titleClasses = cx(`${prefix}--label`, {
|
|
239
239
|
[`${prefix}--label--disabled`]: disabled
|
|
240
240
|
});
|
|
241
|
-
const
|
|
241
|
+
const helperTextId = `combobox-helper-text-${comboBoxInstanceId}`;
|
|
242
|
+
const warnTextId = `combobox-warn-text-${comboBoxInstanceId}`;
|
|
243
|
+
const invalidTextId = `combobox-invalid-text-${comboBoxInstanceId}`;
|
|
242
244
|
const helperClasses = cx(`${prefix}--form__helper-text`, {
|
|
243
245
|
[`${prefix}--form__helper-text--disabled`]: disabled
|
|
244
246
|
});
|
|
@@ -376,6 +378,11 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
376
378
|
}
|
|
377
379
|
}
|
|
378
380
|
} : {};
|
|
381
|
+
|
|
382
|
+
// The input should be described by the appropriate message text id
|
|
383
|
+
// when both the message is supplied *and* when the component is in
|
|
384
|
+
// the matching state (invalid, warn, etc).
|
|
385
|
+
const ariaDescribedBy = invalid && invalidText && invalidTextId || warn && warnText && warnTextId || helperText && !isFluid && helperTextId || undefined;
|
|
379
386
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
380
387
|
className: wrapperClasses
|
|
381
388
|
}, titleText && /*#__PURE__*/React__default.createElement(Text, _extends({
|
|
@@ -388,11 +395,13 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
388
395
|
disabled: disabled,
|
|
389
396
|
invalid: invalid,
|
|
390
397
|
invalidText: invalidText,
|
|
398
|
+
invalidTextId: invalidTextId,
|
|
391
399
|
isOpen: isOpen,
|
|
392
400
|
light: light,
|
|
393
401
|
size: size,
|
|
394
402
|
warn: warn,
|
|
395
|
-
warnText: warnText
|
|
403
|
+
warnText: warnText,
|
|
404
|
+
warnTextId: warnTextId
|
|
396
405
|
}, /*#__PURE__*/React__default.createElement("div", {
|
|
397
406
|
className: `${prefix}--list-box__field`
|
|
398
407
|
}, /*#__PURE__*/React__default.createElement("input", _extends({
|
|
@@ -410,7 +419,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
410
419
|
}, inputProps, rest, readOnlyEventHandlers, {
|
|
411
420
|
readOnly: readOnly,
|
|
412
421
|
ref: mergeRefs(textInput, ref),
|
|
413
|
-
"aria-describedby":
|
|
422
|
+
"aria-describedby": ariaDescribedBy
|
|
414
423
|
})), invalid && /*#__PURE__*/React__default.createElement(WarningFilled, {
|
|
415
424
|
className: `${prefix}--list-box__invalid-icon`
|
|
416
425
|
}), showWarning && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
|
|
@@ -449,7 +458,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
449
458
|
}));
|
|
450
459
|
}) : null)), helperText && !invalid && !warn && !isFluid && (_Text || (_Text = /*#__PURE__*/React__default.createElement(Text, {
|
|
451
460
|
as: "div",
|
|
452
|
-
id:
|
|
461
|
+
id: helperTextId,
|
|
453
462
|
className: helperClasses
|
|
454
463
|
}, helperText))));
|
|
455
464
|
});
|
|
@@ -152,7 +152,7 @@ ComboButton.propTypes = {
|
|
|
152
152
|
/**
|
|
153
153
|
* Specify how the trigger tooltip should be aligned.
|
|
154
154
|
*/
|
|
155
|
-
tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
|
|
155
|
+
tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-start', 'top-right', 'top-end', 'bottom', 'bottom-left', 'bottom-start', 'bottom-right', 'bottom-end', 'left', 'right']),
|
|
156
156
|
/**
|
|
157
157
|
* Optional method that takes in a message id and returns an
|
|
158
158
|
* internationalized string.
|
|
@@ -17,10 +17,11 @@ import mergeRefs from '../../tools/mergeRefs.js';
|
|
|
17
17
|
import cx from 'classnames';
|
|
18
18
|
import toggleClass from '../../tools/toggleClass.js';
|
|
19
19
|
import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
|
|
20
|
-
import wrapFocus from '../../internal/wrapFocus.js';
|
|
20
|
+
import wrapFocus, { wrapFocusWithoutSentinels } from '../../internal/wrapFocus.js';
|
|
21
21
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
22
|
+
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
22
23
|
import { match } from '../../internal/keyboard/match.js';
|
|
23
|
-
import { Escape } from '../../internal/keyboard/keys.js';
|
|
24
|
+
import { Escape, Tab } from '../../internal/keyboard/keys.js';
|
|
24
25
|
|
|
25
26
|
const ModalBody = /*#__PURE__*/React__default.forwardRef(function ModalBody(_ref, ref) {
|
|
26
27
|
let {
|
|
@@ -114,6 +115,7 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
|
|
|
114
115
|
const button = useRef(null);
|
|
115
116
|
const startSentinel = useRef(null);
|
|
116
117
|
const endSentinel = useRef(null);
|
|
118
|
+
const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
|
|
117
119
|
|
|
118
120
|
// Keep track of modal open/close state
|
|
119
121
|
// and propagate it to the document.body
|
|
@@ -131,12 +133,19 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
|
|
|
131
133
|
};
|
|
132
134
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
133
135
|
|
|
134
|
-
function handleKeyDown(
|
|
135
|
-
|
|
136
|
-
if (match(
|
|
137
|
-
closeModal(
|
|
136
|
+
function handleKeyDown(event) {
|
|
137
|
+
event.stopPropagation();
|
|
138
|
+
if (match(event, Escape)) {
|
|
139
|
+
closeModal(event);
|
|
140
|
+
}
|
|
141
|
+
if (focusTrapWithoutSentinels && open && match(event, Tab) && innerModal.current) {
|
|
142
|
+
wrapFocusWithoutSentinels({
|
|
143
|
+
containerNode: innerModal.current,
|
|
144
|
+
currentActiveNode: event.target,
|
|
145
|
+
event: event
|
|
146
|
+
});
|
|
138
147
|
}
|
|
139
|
-
onKeyDown?.(
|
|
148
|
+
onKeyDown?.(event);
|
|
140
149
|
}
|
|
141
150
|
function handleMousedown(evt) {
|
|
142
151
|
evt.stopPropagation();
|
|
@@ -244,7 +253,7 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
|
|
|
244
253
|
role: "presentation",
|
|
245
254
|
ref: ref,
|
|
246
255
|
"aria-hidden": !open,
|
|
247
|
-
onBlur: handleBlur,
|
|
256
|
+
onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
|
|
248
257
|
onMouseDown: handleMousedown,
|
|
249
258
|
onKeyDown: handleKeyDown,
|
|
250
259
|
className: modalClass
|
|
@@ -254,14 +263,14 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
|
|
|
254
263
|
"aria-modal": "true",
|
|
255
264
|
"aria-label": ariaLabel ? ariaLabel : generatedAriaLabel,
|
|
256
265
|
"aria-labelledby": ariaLabelledBy
|
|
257
|
-
}, /*#__PURE__*/React__default.createElement("button", {
|
|
266
|
+
}, !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("button", {
|
|
258
267
|
type: "button",
|
|
259
268
|
ref: startSentinel,
|
|
260
269
|
className: `${prefix}--visually-hidden`
|
|
261
270
|
}, "Focus sentinel"), /*#__PURE__*/React__default.createElement("div", {
|
|
262
271
|
ref: innerModal,
|
|
263
272
|
className: `${prefix}--modal-container-body`
|
|
264
|
-
}, normalizedSlug, childrenWithProps), /*#__PURE__*/React__default.createElement("button", {
|
|
273
|
+
}, normalizedSlug, childrenWithProps), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("button", {
|
|
265
274
|
type: "button",
|
|
266
275
|
ref: endSentinel,
|
|
267
276
|
className: `${prefix}--visually-hidden`
|
|
@@ -24,7 +24,7 @@ export interface TableBatchActionProps extends React.ButtonHTMLAttributes<HTMLBu
|
|
|
24
24
|
declare const TableBatchAction: {
|
|
25
25
|
({ renderIcon, iconDescription, ...props }: {
|
|
26
26
|
[x: string]: any;
|
|
27
|
-
renderIcon?: import("@carbon/icons-react
|
|
27
|
+
renderIcon?: import("@carbon/icons-react").CarbonIconType | undefined;
|
|
28
28
|
iconDescription?: string | undefined;
|
|
29
29
|
}): import("react/jsx-runtime").JSX.Element;
|
|
30
30
|
propTypes: {
|
|
@@ -8,13 +8,17 @@ import React from 'react';
|
|
|
8
8
|
export interface TableToolbarMenuProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
9
9
|
children: React.ReactNode;
|
|
10
10
|
/**
|
|
11
|
-
* Provide an optional class name for the toolbar menu
|
|
11
|
+
* Provide an optional class name for the toolbar menu trigger button
|
|
12
12
|
*/
|
|
13
13
|
className?: string;
|
|
14
14
|
/**
|
|
15
15
|
* The description of the menu icon.
|
|
16
16
|
*/
|
|
17
17
|
iconDescription?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Provide an optional class name for the toolbar menu
|
|
20
|
+
*/
|
|
21
|
+
menuOptionsClass?: string;
|
|
18
22
|
/**
|
|
19
23
|
* Optional prop to allow overriding the default menu icon
|
|
20
24
|
*/
|
|
@@ -20,16 +20,19 @@ const TableToolbarMenu = _ref => {
|
|
|
20
20
|
renderIcon = Settings,
|
|
21
21
|
iconDescription = defaultIconDescription,
|
|
22
22
|
children,
|
|
23
|
+
menuOptionsClass,
|
|
23
24
|
...rest
|
|
24
25
|
} = _ref;
|
|
25
26
|
const prefix = usePrefix();
|
|
26
27
|
const toolbarActionClasses = cx(className, `${prefix}--toolbar-action ${prefix}--overflow-menu`);
|
|
28
|
+
const menuOptionsClasses = cx(menuOptionsClass, `${prefix}--toolbar-action__menu`);
|
|
27
29
|
return /*#__PURE__*/React__default.createElement(OverflowMenu, _extends({
|
|
28
30
|
"aria-label": iconDescription,
|
|
29
31
|
renderIcon: renderIcon,
|
|
30
32
|
className: toolbarActionClasses,
|
|
31
33
|
title: iconDescription,
|
|
32
34
|
iconDescription: iconDescription,
|
|
35
|
+
menuOptionsClass: menuOptionsClasses,
|
|
33
36
|
flipped: true
|
|
34
37
|
}, rest), children);
|
|
35
38
|
};
|
|
@@ -43,6 +46,10 @@ TableToolbarMenu.propTypes = {
|
|
|
43
46
|
* The description of the menu icon.
|
|
44
47
|
*/
|
|
45
48
|
iconDescription: PropTypes.string,
|
|
49
|
+
/**
|
|
50
|
+
* Provide an optional class name for the toolbar menu
|
|
51
|
+
*/
|
|
52
|
+
menuOptionsClass: PropTypes.string,
|
|
46
53
|
/**
|
|
47
54
|
* Optional prop to allow overriding the default menu icon
|
|
48
55
|
*/
|
|
@@ -102,6 +102,10 @@ interface DatePickerProps {
|
|
|
102
102
|
* The `open` event handler.
|
|
103
103
|
*/
|
|
104
104
|
onOpen?: flatpickr.Options.Hook;
|
|
105
|
+
/**
|
|
106
|
+
* flatpickr prop passthrough. Controls how dates are parsed.
|
|
107
|
+
*/
|
|
108
|
+
parseDate?: (date: string) => Date | false;
|
|
105
109
|
/**
|
|
106
110
|
* whether the DatePicker is to be readOnly
|
|
107
111
|
* if boolean applies to all inputs
|
|
@@ -158,6 +158,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
158
158
|
readOnly = false,
|
|
159
159
|
short = false,
|
|
160
160
|
value,
|
|
161
|
+
parseDate: parseDateProp,
|
|
161
162
|
...rest
|
|
162
163
|
} = _ref;
|
|
163
164
|
const prefix = usePrefix();
|
|
@@ -267,6 +268,37 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
267
268
|
} else {
|
|
268
269
|
localeData = l10n[locale];
|
|
269
270
|
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* parseDate is called before the date is actually set.
|
|
274
|
+
* It attempts to parse the input value and return a valid date string.
|
|
275
|
+
* Flatpickr's default parser results in odd dates when given invalid
|
|
276
|
+
* values, so instead here we normalize the month/day to `1` if given
|
|
277
|
+
* a value outside the acceptable range.
|
|
278
|
+
*/
|
|
279
|
+
let parseDate;
|
|
280
|
+
if (!parseDateProp && dateFormat === 'm/d/Y') {
|
|
281
|
+
// This function only supports the default dateFormat.
|
|
282
|
+
parseDate = date => {
|
|
283
|
+
// Month must be 1-12. If outside these bounds, `1` should be used.
|
|
284
|
+
const month = date.split('/')[0] <= 12 && date.split('/')[0] > 0 ? parseInt(date.split('/')[0]) : 1;
|
|
285
|
+
const year = parseInt(date.split('/')[2]);
|
|
286
|
+
if (month && year) {
|
|
287
|
+
// The month and year must be provided to be able to determine
|
|
288
|
+
// the number of days in the month.
|
|
289
|
+
const daysInMonth = new Date(year, month, 0).getDate();
|
|
290
|
+
// If the day does not fall within the days in the month, `1` should be used.
|
|
291
|
+
const day = date.split('/')[1] <= daysInMonth && date.split('/')[1] > 0 ? parseInt(date.split('/')[1]) : 1;
|
|
292
|
+
return new Date(`${year}/${month}/${day}`);
|
|
293
|
+
} else {
|
|
294
|
+
// With no month and year, we cannot calculate anything.
|
|
295
|
+
// Returning false gives flatpickr an invalid date, which will clear the input
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
} else if (parseDateProp) {
|
|
300
|
+
parseDate = parseDateProp;
|
|
301
|
+
}
|
|
270
302
|
const {
|
|
271
303
|
current: start
|
|
272
304
|
} = startInputField;
|
|
@@ -285,6 +317,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
285
317
|
[enableOrDisable]: enableOrDisableArr,
|
|
286
318
|
minDate: minDate,
|
|
287
319
|
maxDate: maxDate,
|
|
320
|
+
parseDate: parseDate,
|
|
288
321
|
plugins: [datePickerType === 'range' ? carbonFlatpickrRangePlugin({
|
|
289
322
|
input: endInputField.current
|
|
290
323
|
}) : () => {}, appendTo ? carbonFlatpickrAppendToPlugin({
|
|
@@ -696,6 +729,10 @@ DatePicker.propTypes = {
|
|
|
696
729
|
* `(dates: Date[], dStr: string, fp: Instance, data?: any):void;`
|
|
697
730
|
*/
|
|
698
731
|
onOpen: PropTypes.func,
|
|
732
|
+
/**
|
|
733
|
+
* flatpickr prop passthrough. Controls how dates are parsed.
|
|
734
|
+
*/
|
|
735
|
+
parseDate: PropTypes.func,
|
|
699
736
|
/**
|
|
700
737
|
* whether the DatePicker is to be readOnly
|
|
701
738
|
* if boolean applies to all inputs
|
|
@@ -13,7 +13,7 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
13
13
|
/**
|
|
14
14
|
* Specify how the trigger should align with the tooltip
|
|
15
15
|
*/
|
|
16
|
-
align?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
|
|
16
|
+
align?: 'top' | 'top-left' | 'top-start' | 'top-right' | 'top-end' | 'bottom' | 'bottom-left' | 'bottom-start' | 'bottom-right' | 'bottom-end' | 'left' | 'right';
|
|
17
17
|
/**
|
|
18
18
|
* Provide an icon or asset to be rendered inside of the IconButton
|
|
19
19
|
*/
|
|
@@ -59,7 +59,7 @@ IconButton.propTypes = {
|
|
|
59
59
|
/**
|
|
60
60
|
* Specify how the trigger should align with the tooltip
|
|
61
61
|
*/
|
|
62
|
-
align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
|
|
62
|
+
align: PropTypes.oneOf(['top', 'top-left', 'top-start', 'top-right', 'top-end', 'bottom', 'bottom-left', 'bottom-start', 'bottom-right', 'bottom-end', 'left', 'right']),
|
|
63
63
|
/**
|
|
64
64
|
* Provide an icon or asset to be rendered inside of the IconButton
|
|
65
65
|
*/
|
|
@@ -21,6 +21,10 @@ export interface ListBoxProps extends Omit<ReactAttr<HTMLDivElement>, ExcludedAt
|
|
|
21
21
|
* Specify the text to be displayed when the control is invalid
|
|
22
22
|
*/
|
|
23
23
|
invalidText?: React.ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Specify the id to be applied to the element containing the invalid text
|
|
26
|
+
*/
|
|
27
|
+
invalidTextId?: string;
|
|
24
28
|
/**
|
|
25
29
|
* Specify if the control should render open
|
|
26
30
|
*/
|
|
@@ -50,6 +54,10 @@ export interface ListBoxProps extends Omit<ReactAttr<HTMLDivElement>, ExcludedAt
|
|
|
50
54
|
* Provide the text that is displayed when the control is in warning state
|
|
51
55
|
*/
|
|
52
56
|
warnText?: React.ReactNode;
|
|
57
|
+
/**
|
|
58
|
+
* Specify the id to be applied to the element containing the warn text
|
|
59
|
+
*/
|
|
60
|
+
warnTextId?: string;
|
|
53
61
|
}
|
|
54
62
|
export type ListBoxComponent = ForwardRefReturn<HTMLDivElement, ListBoxProps>;
|
|
55
63
|
/**
|
|
@@ -37,8 +37,10 @@ const ListBox = /*#__PURE__*/React__default.forwardRef(function ListBox(_ref, re
|
|
|
37
37
|
size,
|
|
38
38
|
invalid,
|
|
39
39
|
invalidText,
|
|
40
|
+
invalidTextId,
|
|
40
41
|
warn,
|
|
41
42
|
warnText,
|
|
43
|
+
warnTextId,
|
|
42
44
|
light,
|
|
43
45
|
isOpen,
|
|
44
46
|
...rest
|
|
@@ -70,9 +72,11 @@ const ListBox = /*#__PURE__*/React__default.forwardRef(function ListBox(_ref, re
|
|
|
70
72
|
}), children), isFluid && /*#__PURE__*/React__default.createElement("hr", {
|
|
71
73
|
className: `${prefix}--list-box__divider`
|
|
72
74
|
}), invalid ? /*#__PURE__*/React__default.createElement("div", {
|
|
73
|
-
className: `${prefix}--form-requirement
|
|
75
|
+
className: `${prefix}--form-requirement`,
|
|
76
|
+
id: invalidTextId
|
|
74
77
|
}, invalidText) : null, showWarning ? /*#__PURE__*/React__default.createElement("div", {
|
|
75
|
-
className: `${prefix}--form-requirement
|
|
78
|
+
className: `${prefix}--form-requirement`,
|
|
79
|
+
id: warnTextId
|
|
76
80
|
}, warnText) : null);
|
|
77
81
|
});
|
|
78
82
|
ListBox.displayName = 'ListBox';
|
|
@@ -97,6 +101,10 @@ ListBox.propTypes = {
|
|
|
97
101
|
* Specify the text to be displayed when the control is invalid
|
|
98
102
|
*/
|
|
99
103
|
invalidText: PropTypes.node,
|
|
104
|
+
/**
|
|
105
|
+
* Specify the id to be applied to the element containing the invalid text
|
|
106
|
+
*/
|
|
107
|
+
invalidTextId: PropTypes.string,
|
|
100
108
|
/**
|
|
101
109
|
* Specify if the control should render open
|
|
102
110
|
*/
|
|
@@ -122,7 +130,11 @@ ListBox.propTypes = {
|
|
|
122
130
|
/**
|
|
123
131
|
* Provide the text that is displayed when the control is in warning state
|
|
124
132
|
*/
|
|
125
|
-
warnText: PropTypes.
|
|
133
|
+
warnText: PropTypes.string,
|
|
134
|
+
/**
|
|
135
|
+
* Specify the id to be applied to the element containing the warn text
|
|
136
|
+
*/
|
|
137
|
+
warnTextId: PropTypes.string
|
|
126
138
|
};
|
|
127
139
|
|
|
128
140
|
export { ListBox as default };
|
|
@@ -30,7 +30,7 @@ export interface LoadingProps extends ReactAttr<HTMLDivElement> {
|
|
|
30
30
|
/**
|
|
31
31
|
* Specify whether you want the loader to be applied with an overlay
|
|
32
32
|
*/
|
|
33
|
-
withOverlay
|
|
33
|
+
withOverlay?: boolean;
|
|
34
34
|
}
|
|
35
35
|
declare function Loading({ active, className: customClassName, withOverlay, small, description, ...rest }: LoadingProps): import("react/jsx-runtime").JSX.Element;
|
|
36
36
|
declare namespace Loading {
|
|
@@ -16,7 +16,7 @@ import '../Button/Button.Skeleton.js';
|
|
|
16
16
|
import ButtonSet from '../ButtonSet/ButtonSet.js';
|
|
17
17
|
import InlineLoading from '../InlineLoading/InlineLoading.js';
|
|
18
18
|
import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
|
|
19
|
-
import wrapFocus, { elementOrParentIsFloatingMenu } from '../../internal/wrapFocus.js';
|
|
19
|
+
import wrapFocus, { wrapFocusWithoutSentinels, elementOrParentIsFloatingMenu } from '../../internal/wrapFocus.js';
|
|
20
20
|
import debounce from 'lodash.debounce';
|
|
21
21
|
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
22
22
|
import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
|
|
@@ -24,9 +24,10 @@ import { usePrefix } from '../../internal/usePrefix.js';
|
|
|
24
24
|
import { IconButton } from '../IconButton/index.js';
|
|
25
25
|
import { noopFn } from '../../internal/noopFn.js';
|
|
26
26
|
import '../Text/index.js';
|
|
27
|
+
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
27
28
|
import { Text } from '../Text/Text.js';
|
|
28
29
|
import { match } from '../../internal/keyboard/match.js';
|
|
29
|
-
import { Escape, Enter } from '../../internal/keyboard/keys.js';
|
|
30
|
+
import { Escape, Enter, Tab } from '../../internal/keyboard/keys.js';
|
|
30
31
|
|
|
31
32
|
const getInstanceId = setupGetInstanceId();
|
|
32
33
|
const ModalSizes = ['xs', 'sm', 'md', 'lg'];
|
|
@@ -82,6 +83,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
|
|
|
82
83
|
[`${prefix}--btn--loading`]: loadingStatus !== 'inactive'
|
|
83
84
|
});
|
|
84
85
|
const loadingActive = loadingStatus !== 'inactive';
|
|
86
|
+
const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
|
|
85
87
|
function isCloseButton(element) {
|
|
86
88
|
return !onSecondarySubmit && element === secondaryButton.current || element.classList.contains(modalCloseButtonClass);
|
|
87
89
|
}
|
|
@@ -94,6 +96,13 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
|
|
|
94
96
|
if (match(evt, Enter) && shouldSubmitOnEnter && !isCloseButton(evt.target)) {
|
|
95
97
|
onRequestSubmit(evt);
|
|
96
98
|
}
|
|
99
|
+
if (focusTrapWithoutSentinels && match(evt, Tab) && innerModal.current) {
|
|
100
|
+
wrapFocusWithoutSentinels({
|
|
101
|
+
containerNode: innerModal.current,
|
|
102
|
+
currentActiveNode: evt.target,
|
|
103
|
+
event: evt
|
|
104
|
+
});
|
|
105
|
+
}
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
108
|
function handleMousedown(evt) {
|
|
@@ -295,16 +304,16 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
|
|
|
295
304
|
return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
|
|
296
305
|
onKeyDown: handleKeyDown,
|
|
297
306
|
onMouseDown: handleMousedown,
|
|
298
|
-
onBlur: handleBlur,
|
|
307
|
+
onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
|
|
299
308
|
className: modalClasses,
|
|
300
309
|
role: "presentation",
|
|
301
310
|
ref: ref
|
|
302
|
-
}), /*#__PURE__*/React__default.createElement("span", {
|
|
311
|
+
}), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
|
|
303
312
|
ref: startTrap,
|
|
304
313
|
tabIndex: 0,
|
|
305
314
|
role: "link",
|
|
306
315
|
className: `${prefix}--visually-hidden`
|
|
307
|
-
}, "Focus sentinel"), modalBody, /*#__PURE__*/React__default.createElement("span", {
|
|
316
|
+
}, "Focus sentinel"), modalBody, !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
|
|
308
317
|
ref: endTrap,
|
|
309
318
|
tabIndex: 0,
|
|
310
319
|
role: "link",
|
|
@@ -19,10 +19,11 @@ import { useNoInteractiveChildren, useInteractiveChildrenNeedDescription } from
|
|
|
19
19
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
20
20
|
import { useId } from '../../internal/useId.js';
|
|
21
21
|
import { noopFn } from '../../internal/noopFn.js';
|
|
22
|
-
import wrapFocus from '../../internal/wrapFocus.js';
|
|
22
|
+
import wrapFocus, { wrapFocusWithoutSentinels } from '../../internal/wrapFocus.js';
|
|
23
|
+
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
23
24
|
import { Text } from '../Text/Text.js';
|
|
24
|
-
import { matches } from '../../internal/keyboard/match.js';
|
|
25
|
-
import { Escape } from '../../internal/keyboard/keys.js';
|
|
25
|
+
import { match, matches } from '../../internal/keyboard/match.js';
|
|
26
|
+
import { Tab, Escape } from '../../internal/keyboard/keys.js';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Conditionally call a callback when the escape key is pressed
|
|
@@ -511,6 +512,7 @@ function ActionableNotification(_ref6) {
|
|
|
511
512
|
const startTrap = useRef(null);
|
|
512
513
|
const endTrap = useRef(null);
|
|
513
514
|
const ref = useRef(null);
|
|
515
|
+
const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
|
|
514
516
|
useIsomorphicEffect(() => {
|
|
515
517
|
if (hasFocus) {
|
|
516
518
|
const button = document.querySelector('button.cds--actionable-notification__action-button');
|
|
@@ -541,6 +543,15 @@ function ActionableNotification(_ref6) {
|
|
|
541
543
|
});
|
|
542
544
|
}
|
|
543
545
|
}
|
|
546
|
+
function handleKeyDown(event) {
|
|
547
|
+
if (isOpen && match(event, Tab) && ref.current) {
|
|
548
|
+
wrapFocusWithoutSentinels({
|
|
549
|
+
containerNode: ref.current,
|
|
550
|
+
currentActiveNode: event.target,
|
|
551
|
+
event
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
}
|
|
544
555
|
const handleClose = evt => {
|
|
545
556
|
if (!onClose || onClose(evt) !== false) {
|
|
546
557
|
setIsOpen(false);
|
|
@@ -559,8 +570,9 @@ function ActionableNotification(_ref6) {
|
|
|
559
570
|
role: role,
|
|
560
571
|
className: containerClassName,
|
|
561
572
|
"aria-labelledby": title ? id : subtitleId,
|
|
562
|
-
onBlur: handleBlur
|
|
563
|
-
|
|
573
|
+
onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
|
|
574
|
+
onKeyDown: focusTrapWithoutSentinels ? handleKeyDown : () => {}
|
|
575
|
+
}), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
|
|
564
576
|
ref: startTrap,
|
|
565
577
|
tabIndex: 0,
|
|
566
578
|
role: "link",
|
|
@@ -593,7 +605,7 @@ function ActionableNotification(_ref6) {
|
|
|
593
605
|
"aria-label": deprecatedAriaLabel || ariaLabel,
|
|
594
606
|
notificationType: "actionable",
|
|
595
607
|
onClick: handleCloseButtonClick
|
|
596
|
-
})), /*#__PURE__*/React__default.createElement("span", {
|
|
608
|
+
})), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
|
|
597
609
|
ref: endTrap,
|
|
598
610
|
tabIndex: 0,
|
|
599
611
|
role: "link",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
export interface PaginationSkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
10
|
+
/**
|
|
11
|
+
* Specify an optional className to add.
|
|
12
|
+
*/
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
declare function PaginationSkeleton({ className, ...rest }: PaginationSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
declare namespace PaginationSkeleton {
|
|
17
|
+
var propTypes: {
|
|
18
|
+
/**
|
|
19
|
+
* Specify an optional className to add.
|
|
20
|
+
*/
|
|
21
|
+
className: PropTypes.Requireable<string>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export default PaginationSkeleton;
|
|
25
|
+
export { PaginationSkeleton };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
type ExcludedAttributes = 'id' | 'onChange';
|
|
9
|
+
export interface PaginationPageSize {
|
|
10
|
+
text: string;
|
|
11
|
+
value: number;
|
|
12
|
+
}
|
|
13
|
+
export interface PaginationProps extends Omit<React.HTMLAttributes<HTMLDivElement>, ExcludedAttributes> {
|
|
14
|
+
/**
|
|
15
|
+
* The description for the backward icon.
|
|
16
|
+
*/
|
|
17
|
+
backwardText?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The CSS class names.
|
|
20
|
+
*/
|
|
21
|
+
className?: string;
|
|
22
|
+
/**
|
|
23
|
+
* `true` if the backward/forward buttons, as well as the page select elements, should be disabled.
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The description for the forward icon.
|
|
28
|
+
*/
|
|
29
|
+
forwardText?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The unique ID of this component instance.
|
|
32
|
+
*/
|
|
33
|
+
id?: string | number;
|
|
34
|
+
/**
|
|
35
|
+
* `true` if the current page should be the last page.
|
|
36
|
+
*/
|
|
37
|
+
isLastPage?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The function returning a translatable text showing where the current page is,
|
|
40
|
+
* in a manner of the range of items.
|
|
41
|
+
*/
|
|
42
|
+
itemRangeText?: (min: number, max: number, total: number) => string;
|
|
43
|
+
/**
|
|
44
|
+
* A variant of `itemRangeText`, used if the total number of items is unknown.
|
|
45
|
+
*/
|
|
46
|
+
itemText?: (min: number, max: number) => string;
|
|
47
|
+
/**
|
|
48
|
+
* The translatable text indicating the number of items per page.
|
|
49
|
+
*/
|
|
50
|
+
itemsPerPageText?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The callback function called when the current page changes.
|
|
53
|
+
*/
|
|
54
|
+
onChange?: (data: {
|
|
55
|
+
page: number;
|
|
56
|
+
pageSize: number;
|
|
57
|
+
ref?: React.RefObject<any>;
|
|
58
|
+
}) => void;
|
|
59
|
+
/**
|
|
60
|
+
* The current page.
|
|
61
|
+
*/
|
|
62
|
+
page?: number;
|
|
63
|
+
/**
|
|
64
|
+
* `true` if the select box to change the page should be disabled.
|
|
65
|
+
*/
|
|
66
|
+
pageInputDisabled?: boolean;
|
|
67
|
+
pageNumberText?: string;
|
|
68
|
+
/**
|
|
69
|
+
* A function returning PII showing where the current page is.
|
|
70
|
+
*/
|
|
71
|
+
pageRangeText?: (current: number, total: number) => string;
|
|
72
|
+
/**
|
|
73
|
+
* The number dictating how many items a page contains.
|
|
74
|
+
*/
|
|
75
|
+
pageSize?: number;
|
|
76
|
+
/**
|
|
77
|
+
* `true` if the select box to change the items per page should be disabled.
|
|
78
|
+
*/
|
|
79
|
+
pageSizeInputDisabled?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* The choices for `pageSize`.
|
|
82
|
+
*/
|
|
83
|
+
pageSizes: number[] | PaginationPageSize[];
|
|
84
|
+
/**
|
|
85
|
+
* The translatable text showing the current page.
|
|
86
|
+
*/
|
|
87
|
+
pageText?: (page: number, pagesUnknown?: boolean) => string;
|
|
88
|
+
/**
|
|
89
|
+
* `true` if the total number of items is unknown.
|
|
90
|
+
*/
|
|
91
|
+
pagesUnknown?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Specify the size of the Pagination.
|
|
94
|
+
*/
|
|
95
|
+
size?: 'sm' | 'md' | 'lg';
|
|
96
|
+
/**
|
|
97
|
+
* The total number of items.
|
|
98
|
+
*/
|
|
99
|
+
totalItems?: number;
|
|
100
|
+
}
|
|
101
|
+
declare const Pagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLDivElement>>;
|
|
102
|
+
export default Pagination;
|