carbon-react 123.0.1 → 123.1.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/esm/components/action-popover/action-popover-item/action-popover-item.component.js +2 -0
- package/esm/components/action-popover/action-popover-menu/action-popover-menu.component.js +56 -16
- package/esm/components/action-popover/action-popover.component.js +2 -2
- package/esm/components/action-popover/action-popover.style.js +8 -0
- package/esm/components/carousel/carousel.component.js +6 -0
- package/lib/components/action-popover/action-popover-item/action-popover-item.component.js +2 -0
- package/lib/components/action-popover/action-popover-menu/action-popover-menu.component.js +55 -15
- package/lib/components/action-popover/action-popover.component.js +2 -2
- package/lib/components/action-popover/action-popover.style.js +8 -0
- package/lib/components/carousel/carousel.component.js +6 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
-
import React, { useCallback, useMemo, useContext, useState } from "react";
|
|
2
|
+
import React, { useCallback, useMemo, useContext, useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import invariant from "invariant";
|
|
5
5
|
import { Menu } from "../action-popover.style";
|
|
@@ -32,7 +32,7 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef(({
|
|
|
32
32
|
if (! /*#__PURE__*/React.isValidElement(child)) {
|
|
33
33
|
return true;
|
|
34
34
|
}
|
|
35
|
-
return child.type !== ActionPopoverItem && child.type !== ActionPopoverDivider;
|
|
35
|
+
return child.type.displayName !== ActionPopoverItem.displayName && child.type.displayName !== ActionPopoverDivider.displayName;
|
|
36
36
|
});
|
|
37
37
|
return !incorrectChild;
|
|
38
38
|
}, [children]);
|
|
@@ -42,42 +42,82 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef(({
|
|
|
42
42
|
return /*#__PURE__*/React.isValidElement(child) && child.type === ActionPopoverItem;
|
|
43
43
|
});
|
|
44
44
|
}, [children]);
|
|
45
|
+
const isItemDisabled = useCallback(value => {
|
|
46
|
+
const item = items[value];
|
|
47
|
+
// The invariant will be triggered before this else path can be explored, hence the ignore else.
|
|
48
|
+
// istanbul ignore else
|
|
49
|
+
return /*#__PURE__*/React.isValidElement(item) && item.props.disabled;
|
|
50
|
+
}, [items]);
|
|
51
|
+
const firstFocusableItem = items.findIndex((_, index) => !isItemDisabled(index));
|
|
52
|
+
|
|
53
|
+
// FIX-ME: FE-6248
|
|
54
|
+
// Once we no longer support Node 16, this function can be removed and `findLastIndex()` can be used in it's place.
|
|
55
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex
|
|
56
|
+
function findLastFocusableItem() {
|
|
57
|
+
let lastFocusableItem = -1;
|
|
58
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
59
|
+
if (!isItemDisabled(i)) {
|
|
60
|
+
lastFocusableItem = i;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return lastFocusableItem;
|
|
65
|
+
}
|
|
66
|
+
const lastFocusableItem = findLastFocusableItem();
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (isOpen && firstFocusableItem !== -1) setFocusIndex(firstFocusableItem);
|
|
69
|
+
}, [isOpen, firstFocusableItem, setFocusIndex]);
|
|
45
70
|
const onKeyDown = useCallback(e => {
|
|
46
71
|
if (Events.isTabKey(e)) {
|
|
47
72
|
e.preventDefault();
|
|
48
|
-
// TAB: close menu and allow focus to change to next focusable element
|
|
73
|
+
// TAB: close menu and allow focus to change to the next focusable element
|
|
49
74
|
focusButton();
|
|
50
75
|
setOpen(false);
|
|
51
76
|
} else if (Events.isDownKey(e)) {
|
|
52
|
-
// DOWN: focus next item or first
|
|
77
|
+
// DOWN: focus on the next item or first non-disabled item
|
|
53
78
|
e.preventDefault();
|
|
54
79
|
e.stopPropagation();
|
|
55
|
-
|
|
80
|
+
let indexValue = focusIndex + 1;
|
|
81
|
+
while (indexValue < items.length && isItemDisabled(indexValue)) {
|
|
82
|
+
indexValue += 1;
|
|
83
|
+
}
|
|
84
|
+
if (indexValue >= items.length) {
|
|
85
|
+
indexValue = firstFocusableItem;
|
|
86
|
+
}
|
|
56
87
|
setFocusIndex(indexValue);
|
|
57
88
|
} else if (Events.isUpKey(e)) {
|
|
58
|
-
// UP: focus previous item or last
|
|
89
|
+
// UP: focus on the previous item or last non-disabled item
|
|
59
90
|
e.preventDefault();
|
|
60
91
|
e.stopPropagation();
|
|
61
|
-
|
|
92
|
+
let indexValue = focusIndex - 1;
|
|
93
|
+
while (indexValue >= firstFocusableItem && isItemDisabled(indexValue)) {
|
|
94
|
+
indexValue -= 1;
|
|
95
|
+
}
|
|
96
|
+
if (indexValue < firstFocusableItem) {
|
|
97
|
+
indexValue = lastFocusableItem;
|
|
98
|
+
}
|
|
62
99
|
setFocusIndex(indexValue);
|
|
63
100
|
} else if (Events.isHomeKey(e)) {
|
|
64
|
-
// HOME: focus first item
|
|
101
|
+
// HOME: focus on the first non-disabled item
|
|
65
102
|
e.preventDefault();
|
|
66
103
|
e.stopPropagation();
|
|
67
|
-
|
|
104
|
+
const indexValue = firstFocusableItem;
|
|
105
|
+
setFocusIndex(indexValue);
|
|
68
106
|
} else if (Events.isEndKey(e)) {
|
|
69
|
-
// END: focus last item
|
|
107
|
+
// END: focus on the last non-disabled item
|
|
70
108
|
e.preventDefault();
|
|
71
109
|
e.stopPropagation();
|
|
72
|
-
|
|
110
|
+
const indexValue = lastFocusableItem;
|
|
111
|
+
setFocusIndex(indexValue);
|
|
73
112
|
} else if (e.key.length === 1) {
|
|
74
|
-
//
|
|
75
|
-
//
|
|
113
|
+
// Any printable character: focus on the next non-disabled item on the list that starts with that character
|
|
114
|
+
// Selection should wrap to the start of the list
|
|
76
115
|
e.stopPropagation();
|
|
77
116
|
let firstMatch;
|
|
78
117
|
let nextMatch;
|
|
79
|
-
|
|
80
|
-
if ( /*#__PURE__*/React.isValidElement(
|
|
118
|
+
items.forEach((item, index) => {
|
|
119
|
+
if ( /*#__PURE__*/React.isValidElement(item) && !isItemDisabled(index) && item.props.children.toLowerCase().startsWith(e.key.toLowerCase())) {
|
|
120
|
+
// istanbul ignore else
|
|
81
121
|
if (firstMatch === undefined) {
|
|
82
122
|
firstMatch = index;
|
|
83
123
|
}
|
|
@@ -92,7 +132,7 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef(({
|
|
|
92
132
|
setFocusIndex(firstMatch);
|
|
93
133
|
}
|
|
94
134
|
}
|
|
95
|
-
}, [focusButton, setOpen, focusIndex, items, setFocusIndex]);
|
|
135
|
+
}, [focusButton, setOpen, focusIndex, items, isItemDisabled, setFocusIndex, firstFocusableItem, lastFocusableItem]);
|
|
96
136
|
const [childHasSubmenu, setChildHasSubmenu] = useState(false);
|
|
97
137
|
const [childHasIcon, setChildHasIcon] = useState(false);
|
|
98
138
|
const [currentSubmenuPosition, setCurrentSubmenuPosition] = useState(submenuPosition);
|
|
@@ -118,8 +118,8 @@ export const ActionPopover = ({
|
|
|
118
118
|
// There will be multiple document click listeners but we cant prevent propagation because it will interfere with
|
|
119
119
|
// other instances on the same page
|
|
120
120
|
|
|
121
|
-
const isInMenu = menu
|
|
122
|
-
const isInButton = buttonRef
|
|
121
|
+
const isInMenu = menu?.current?.contains(target);
|
|
122
|
+
const isInButton = buttonRef?.current?.contains(target);
|
|
123
123
|
if (!isInMenu && !isInButton) {
|
|
124
124
|
setOpen(false);
|
|
125
125
|
}
|
|
@@ -131,6 +131,14 @@ const StyledMenuItem = styled.button`
|
|
|
131
131
|
cursor: not-allowed;
|
|
132
132
|
color: var(--colorsUtilityYin030);
|
|
133
133
|
}
|
|
134
|
+
|
|
135
|
+
:focus {
|
|
136
|
+
border: none;
|
|
137
|
+
outline: none;
|
|
138
|
+
-webkit-appearance: none;
|
|
139
|
+
-webkit-box-shadow: none;
|
|
140
|
+
box-shadow: none;
|
|
141
|
+
}
|
|
134
142
|
`}
|
|
135
143
|
|
|
136
144
|
${({
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
2
|
import React, { useCallback, useEffect, useRef, useState, useMemo } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import Logger from "../../__internal__/utils/logger";
|
|
4
5
|
import tagComponent from "../../__internal__/utils/helpers/tags/tags";
|
|
5
6
|
import { CarouselPreviousButtonWrapperStyle, CarouselNextButtonWrapperStyle, CarouselButtonStyle, CarouselStyledIconRight, CarouselStyledIconLeft, CarouselSelectorWrapperStyle, CarouselSelectorInputWrapperStyle, CarouselSelectorInputStyle, CarouselSelectorLabelStyle, CarouselWrapperStyle, CarouselSliderWrapper } from "./carousel.style";
|
|
6
7
|
import guid from "../../__internal__/utils/helpers/guid";
|
|
8
|
+
let deprecateWarnTriggered = false;
|
|
7
9
|
const NEXT = "next";
|
|
8
10
|
const PREVIOUS = "previous";
|
|
9
11
|
export const Carousel = ({
|
|
@@ -17,6 +19,10 @@ export const Carousel = ({
|
|
|
17
19
|
slideIndex,
|
|
18
20
|
...props
|
|
19
21
|
}) => {
|
|
22
|
+
if (!deprecateWarnTriggered) {
|
|
23
|
+
deprecateWarnTriggered = true;
|
|
24
|
+
Logger.deprecate("The Carousel component is deprecated and will soon be removed.");
|
|
25
|
+
}
|
|
20
26
|
const [selectedSlideIndex, setSelectedSlideIndex] = useState(Number(slideIndex) || Number(initialSlideIndex));
|
|
21
27
|
const transitionDirection = useRef(NEXT);
|
|
22
28
|
const lastSlideIndexProp = useRef(slideIndex);
|
|
@@ -41,7 +41,7 @@ const ActionPopoverMenu = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
41
41
|
if (! /*#__PURE__*/_react.default.isValidElement(child)) {
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
|
-
return child.type !== _actionPopoverItem.default && child.type !== _actionPopoverDivider.default;
|
|
44
|
+
return child.type.displayName !== _actionPopoverItem.default.displayName && child.type.displayName !== _actionPopoverDivider.default.displayName;
|
|
45
45
|
});
|
|
46
46
|
return !incorrectChild;
|
|
47
47
|
}, [children]);
|
|
@@ -51,42 +51,82 @@ const ActionPopoverMenu = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
51
51
|
return /*#__PURE__*/_react.default.isValidElement(child) && child.type === _actionPopoverItem.default;
|
|
52
52
|
});
|
|
53
53
|
}, [children]);
|
|
54
|
+
const isItemDisabled = (0, _react.useCallback)(value => {
|
|
55
|
+
const item = items[value];
|
|
56
|
+
// The invariant will be triggered before this else path can be explored, hence the ignore else.
|
|
57
|
+
// istanbul ignore else
|
|
58
|
+
return /*#__PURE__*/_react.default.isValidElement(item) && item.props.disabled;
|
|
59
|
+
}, [items]);
|
|
60
|
+
const firstFocusableItem = items.findIndex((_, index) => !isItemDisabled(index));
|
|
61
|
+
|
|
62
|
+
// FIX-ME: FE-6248
|
|
63
|
+
// Once we no longer support Node 16, this function can be removed and `findLastIndex()` can be used in it's place.
|
|
64
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex
|
|
65
|
+
function findLastFocusableItem() {
|
|
66
|
+
let lastFocusableItem = -1;
|
|
67
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
68
|
+
if (!isItemDisabled(i)) {
|
|
69
|
+
lastFocusableItem = i;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return lastFocusableItem;
|
|
74
|
+
}
|
|
75
|
+
const lastFocusableItem = findLastFocusableItem();
|
|
76
|
+
(0, _react.useEffect)(() => {
|
|
77
|
+
if (isOpen && firstFocusableItem !== -1) setFocusIndex(firstFocusableItem);
|
|
78
|
+
}, [isOpen, firstFocusableItem, setFocusIndex]);
|
|
54
79
|
const onKeyDown = (0, _react.useCallback)(e => {
|
|
55
80
|
if (_events.default.isTabKey(e)) {
|
|
56
81
|
e.preventDefault();
|
|
57
|
-
// TAB: close menu and allow focus to change to next focusable element
|
|
82
|
+
// TAB: close menu and allow focus to change to the next focusable element
|
|
58
83
|
focusButton();
|
|
59
84
|
setOpen(false);
|
|
60
85
|
} else if (_events.default.isDownKey(e)) {
|
|
61
|
-
// DOWN: focus next item or first
|
|
86
|
+
// DOWN: focus on the next item or first non-disabled item
|
|
62
87
|
e.preventDefault();
|
|
63
88
|
e.stopPropagation();
|
|
64
|
-
|
|
89
|
+
let indexValue = focusIndex + 1;
|
|
90
|
+
while (indexValue < items.length && isItemDisabled(indexValue)) {
|
|
91
|
+
indexValue += 1;
|
|
92
|
+
}
|
|
93
|
+
if (indexValue >= items.length) {
|
|
94
|
+
indexValue = firstFocusableItem;
|
|
95
|
+
}
|
|
65
96
|
setFocusIndex(indexValue);
|
|
66
97
|
} else if (_events.default.isUpKey(e)) {
|
|
67
|
-
// UP: focus previous item or last
|
|
98
|
+
// UP: focus on the previous item or last non-disabled item
|
|
68
99
|
e.preventDefault();
|
|
69
100
|
e.stopPropagation();
|
|
70
|
-
|
|
101
|
+
let indexValue = focusIndex - 1;
|
|
102
|
+
while (indexValue >= firstFocusableItem && isItemDisabled(indexValue)) {
|
|
103
|
+
indexValue -= 1;
|
|
104
|
+
}
|
|
105
|
+
if (indexValue < firstFocusableItem) {
|
|
106
|
+
indexValue = lastFocusableItem;
|
|
107
|
+
}
|
|
71
108
|
setFocusIndex(indexValue);
|
|
72
109
|
} else if (_events.default.isHomeKey(e)) {
|
|
73
|
-
// HOME: focus first item
|
|
110
|
+
// HOME: focus on the first non-disabled item
|
|
74
111
|
e.preventDefault();
|
|
75
112
|
e.stopPropagation();
|
|
76
|
-
|
|
113
|
+
const indexValue = firstFocusableItem;
|
|
114
|
+
setFocusIndex(indexValue);
|
|
77
115
|
} else if (_events.default.isEndKey(e)) {
|
|
78
|
-
// END: focus last item
|
|
116
|
+
// END: focus on the last non-disabled item
|
|
79
117
|
e.preventDefault();
|
|
80
118
|
e.stopPropagation();
|
|
81
|
-
|
|
119
|
+
const indexValue = lastFocusableItem;
|
|
120
|
+
setFocusIndex(indexValue);
|
|
82
121
|
} else if (e.key.length === 1) {
|
|
83
|
-
//
|
|
84
|
-
//
|
|
122
|
+
// Any printable character: focus on the next non-disabled item on the list that starts with that character
|
|
123
|
+
// Selection should wrap to the start of the list
|
|
85
124
|
e.stopPropagation();
|
|
86
125
|
let firstMatch;
|
|
87
126
|
let nextMatch;
|
|
88
|
-
|
|
89
|
-
if ( /*#__PURE__*/_react.default.isValidElement(
|
|
127
|
+
items.forEach((item, index) => {
|
|
128
|
+
if ( /*#__PURE__*/_react.default.isValidElement(item) && !isItemDisabled(index) && item.props.children.toLowerCase().startsWith(e.key.toLowerCase())) {
|
|
129
|
+
// istanbul ignore else
|
|
90
130
|
if (firstMatch === undefined) {
|
|
91
131
|
firstMatch = index;
|
|
92
132
|
}
|
|
@@ -101,7 +141,7 @@ const ActionPopoverMenu = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
101
141
|
setFocusIndex(firstMatch);
|
|
102
142
|
}
|
|
103
143
|
}
|
|
104
|
-
}, [focusButton, setOpen, focusIndex, items, setFocusIndex]);
|
|
144
|
+
}, [focusButton, setOpen, focusIndex, items, isItemDisabled, setFocusIndex, firstFocusableItem, lastFocusableItem]);
|
|
105
145
|
const [childHasSubmenu, setChildHasSubmenu] = (0, _react.useState)(false);
|
|
106
146
|
const [childHasIcon, setChildHasIcon] = (0, _react.useState)(false);
|
|
107
147
|
const [currentSubmenuPosition, setCurrentSubmenuPosition] = (0, _react.useState)(submenuPosition);
|
|
@@ -127,8 +127,8 @@ const ActionPopover = ({
|
|
|
127
127
|
// There will be multiple document click listeners but we cant prevent propagation because it will interfere with
|
|
128
128
|
// other instances on the same page
|
|
129
129
|
|
|
130
|
-
const isInMenu = menu
|
|
131
|
-
const isInButton = buttonRef
|
|
130
|
+
const isInMenu = menu?.current?.contains(target);
|
|
131
|
+
const isInButton = buttonRef?.current?.contains(target);
|
|
132
132
|
if (!isInMenu && !isInButton) {
|
|
133
133
|
setOpen(false);
|
|
134
134
|
}
|
|
@@ -143,6 +143,14 @@ const StyledMenuItem = _styledComponents.default.button`
|
|
|
143
143
|
cursor: not-allowed;
|
|
144
144
|
color: var(--colorsUtilityYin030);
|
|
145
145
|
}
|
|
146
|
+
|
|
147
|
+
:focus {
|
|
148
|
+
border: none;
|
|
149
|
+
outline: none;
|
|
150
|
+
-webkit-appearance: none;
|
|
151
|
+
-webkit-box-shadow: none;
|
|
152
|
+
box-shadow: none;
|
|
153
|
+
}
|
|
146
154
|
`}
|
|
147
155
|
|
|
148
156
|
${({
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = exports.Carousel = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
+
var _logger = _interopRequireDefault(require("../../__internal__/utils/logger"));
|
|
9
10
|
var _tags = _interopRequireDefault(require("../../__internal__/utils/helpers/tags/tags"));
|
|
10
11
|
var _carousel = require("./carousel.style");
|
|
11
12
|
var _guid = _interopRequireDefault(require("../../__internal__/utils/helpers/guid"));
|
|
@@ -13,6 +14,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
13
14
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
14
15
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
16
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
17
|
+
let deprecateWarnTriggered = false;
|
|
16
18
|
const NEXT = "next";
|
|
17
19
|
const PREVIOUS = "previous";
|
|
18
20
|
const Carousel = ({
|
|
@@ -26,6 +28,10 @@ const Carousel = ({
|
|
|
26
28
|
slideIndex,
|
|
27
29
|
...props
|
|
28
30
|
}) => {
|
|
31
|
+
if (!deprecateWarnTriggered) {
|
|
32
|
+
deprecateWarnTriggered = true;
|
|
33
|
+
_logger.default.deprecate("The Carousel component is deprecated and will soon be removed.");
|
|
34
|
+
}
|
|
29
35
|
const [selectedSlideIndex, setSelectedSlideIndex] = (0, _react.useState)(Number(slideIndex) || Number(initialSlideIndex));
|
|
30
36
|
const transitionDirection = (0, _react.useRef)(NEXT);
|
|
31
37
|
const lastSlideIndexProp = (0, _react.useRef)(slideIndex);
|