@carbon/ibm-products 2.67.0-rc.0 → 2.68.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/css/index-full-carbon.css +252 -261
- package/css/index-full-carbon.css.map +1 -1
- package/css/index-full-carbon.min.css +1 -1
- package/css/index-full-carbon.min.css.map +1 -1
- package/css/index-without-carbon-released-only.css +13 -31
- package/css/index-without-carbon-released-only.css.map +1 -1
- package/css/index-without-carbon-released-only.min.css +1 -1
- package/css/index-without-carbon-released-only.min.css.map +1 -1
- package/css/index-without-carbon.css +252 -261
- package/css/index-without-carbon.css.map +1 -1
- package/css/index-without-carbon.min.css +1 -1
- package/css/index-without-carbon.min.css.map +1 -1
- package/css/index.css +26 -35
- package/css/index.css.map +1 -1
- package/css/index.min.css +1 -1
- package/css/index.min.css.map +1 -1
- package/es/components/Carousel/Carousel.d.ts +6 -0
- package/es/components/Carousel/Carousel.js +45 -0
- package/es/components/CreateFullPage/CreateFullPage.d.ts +3 -2
- package/es/components/Datagrid/Datagrid/DraggableElement.d.ts +3 -0
- package/es/components/Datagrid/Datagrid/DraggableElement.js +23 -15
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.d.ts +16 -20
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.js +3 -5
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/Columns.js +1 -3
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.d.ts +2 -1
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +2 -0
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/DraggableItemsList.js +4 -11
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.d.ts +2 -1
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.js +3 -1
- package/es/components/Datagrid/useCustomizeColumns.js +29 -22
- package/es/components/Guidebanner/Guidebanner.js +2 -1
- package/es/components/InterstitialScreen/InterstitialScreen.d.ts +4 -0
- package/es/components/InterstitialScreen/InterstitialScreen.js +16 -4
- package/es/components/InterstitialScreen/InterstitialScreenBody.js +7 -7
- package/es/components/InterstitialScreen/InterstitialScreenFooter.js +8 -1
- package/es/components/InterstitialScreen/InterstitialScreenHeader.js +10 -4
- package/es/components/PageHeader/PageHeaderUtils.js +2 -1
- package/es/components/Tearsheet/TearsheetShell.js +0 -1
- package/es/global/js/hooks/useResizeObserver.d.ts +8 -1
- package/es/global/js/hooks/useResizeObserver.js +12 -13
- package/lib/components/Carousel/Carousel.d.ts +6 -0
- package/lib/components/Carousel/Carousel.js +45 -0
- package/lib/components/CreateFullPage/CreateFullPage.d.ts +3 -2
- package/lib/components/Datagrid/Datagrid/DraggableElement.d.ts +3 -0
- package/lib/components/Datagrid/Datagrid/DraggableElement.js +23 -15
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.d.ts +16 -20
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.js +3 -5
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/Columns.js +1 -3
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.d.ts +2 -1
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +2 -0
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/DraggableItemsList.js +4 -11
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.d.ts +2 -1
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.js +3 -1
- package/lib/components/Datagrid/useCustomizeColumns.js +29 -22
- package/lib/components/Guidebanner/Guidebanner.js +2 -1
- package/lib/components/InterstitialScreen/InterstitialScreen.d.ts +4 -0
- package/lib/components/InterstitialScreen/InterstitialScreen.js +15 -3
- package/lib/components/InterstitialScreen/InterstitialScreenBody.js +7 -7
- package/lib/components/InterstitialScreen/InterstitialScreenFooter.js +7 -0
- package/lib/components/InterstitialScreen/InterstitialScreenHeader.js +9 -3
- package/lib/components/PageHeader/PageHeaderUtils.js +2 -1
- package/lib/components/Tearsheet/TearsheetShell.js +0 -1
- package/lib/global/js/hooks/useResizeObserver.d.ts +8 -1
- package/lib/global/js/hooks/useResizeObserver.js +12 -13
- package/package.json +5 -5
- package/scss/components/AboutModal/_about-modal.scss +3 -1
- package/scss/components/BreadcrumbWithOverflow/_breadcrumb-with-overflow.scss +0 -1
- package/scss/components/Carousel/_carousel.scss +5 -0
- package/scss/components/Datagrid/styles/_draggableElement.scss +14 -8
- package/scss/components/Datagrid/styles/addons/_CustomizeColumnsTearsheet.scss +0 -7
- package/scss/components/FilterSummary/_filter-summary.scss +0 -5
- package/scss/components/InterstitialScreen/_interstitial-screen.scss +2 -2
- package/scss/global/styles/_display-box.scss +1 -3
- package/telemetry.yml +1 -0
- package/scss/components/FilterSummary/_animations.scss +0 -20
@@ -7,24 +7,23 @@
|
|
7
7
|
|
8
8
|
import { useState, useRef, useEffect, useLayoutEffect } from 'react';
|
9
9
|
|
10
|
-
const useResizeObserver =
|
11
|
-
let deps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
10
|
+
const useResizeObserver = (ref, onResize) => {
|
12
11
|
const [width, setWidth] = useState(-1);
|
13
12
|
const [height, setHeight] = useState(-1);
|
14
13
|
const entriesToHandle = useRef(null);
|
15
|
-
const cb = useRef(
|
14
|
+
const cb = useRef(onResize);
|
16
15
|
useEffect(() => {
|
17
|
-
// ref for
|
16
|
+
// ref for onResize removes it as dependency from useLayoutEffect
|
18
17
|
// This significantly reduces repeated calls if a function is redefined on every
|
19
18
|
// render
|
20
|
-
cb.current =
|
21
|
-
}, [
|
19
|
+
cb.current = onResize;
|
20
|
+
}, [onResize]);
|
22
21
|
useEffect(() => {
|
23
22
|
const getInitialSize = () => {
|
24
23
|
if (ref.current) {
|
25
24
|
const refComputedStyle = window.getComputedStyle(ref.current);
|
26
|
-
const initialWidth = (ref.current?.offsetWidth
|
27
|
-
const initialHeight = (ref.current?.offsetHeight
|
25
|
+
const initialWidth = (ref.current?.offsetWidth ?? 0) - (typeof refComputedStyle?.paddingLeft === 'string' && refComputedStyle?.paddingLeft.length ? parseFloat(refComputedStyle?.paddingLeft) : 0) - (typeof refComputedStyle?.paddingRight === 'string' && refComputedStyle?.paddingRight.length ? parseFloat(refComputedStyle?.paddingRight) : 0);
|
26
|
+
const initialHeight = (ref.current?.offsetHeight ?? 0) - (typeof refComputedStyle?.paddingTop === 'string' && refComputedStyle?.paddingTop.length ? parseFloat(refComputedStyle?.paddingTop) : 0) - (typeof refComputedStyle?.paddingBottom === 'string' && refComputedStyle?.paddingBottom.length ? parseFloat(refComputedStyle?.paddingBottom) : 0);
|
28
27
|
setWidth(initialWidth);
|
29
28
|
setHeight(initialHeight);
|
30
29
|
}
|
@@ -33,8 +32,9 @@ const useResizeObserver = function (ref, callback) {
|
|
33
32
|
return;
|
34
33
|
}
|
35
34
|
getInitialSize();
|
35
|
+
// Ignoring exhaustive-deps as we do NOT want to include the ref in dep array
|
36
36
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
37
|
-
}, [width, height
|
37
|
+
}, [width, height]);
|
38
38
|
useLayoutEffect(() => {
|
39
39
|
if (!ref?.current) {
|
40
40
|
return;
|
@@ -48,7 +48,7 @@ const useResizeObserver = function (ref, callback) {
|
|
48
48
|
setHeight(entry.contentRect.height);
|
49
49
|
cb.current && cb.current(entry.contentRect);
|
50
50
|
};
|
51
|
-
|
51
|
+
const observer = new ResizeObserver(entries => {
|
52
52
|
// always update entriesToHandle
|
53
53
|
entriesToHandle.current = entries;
|
54
54
|
window.requestAnimationFrame(() => {
|
@@ -60,11 +60,10 @@ const useResizeObserver = function (ref, callback) {
|
|
60
60
|
// observe all refs passed
|
61
61
|
observer.observe(ref.current);
|
62
62
|
return () => {
|
63
|
-
observer
|
64
|
-
observer = null;
|
63
|
+
observer.disconnect();
|
65
64
|
};
|
66
65
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
67
|
-
}, [ref.current
|
66
|
+
}, [ref.current]);
|
68
67
|
return {
|
69
68
|
width,
|
70
69
|
height
|
@@ -45,6 +45,12 @@ export interface CarouselProps {
|
|
45
45
|
* Additional props passed to the component.
|
46
46
|
*/
|
47
47
|
[key: string]: any;
|
48
|
+
/**
|
49
|
+
* enable scroll mode when only scroll functionality is required, more than one items will be visible at a time
|
50
|
+
* when isScrollMode is false, component behaves like a carousal and on item will be active at a time
|
51
|
+
* and other items will be hidden and inactive.
|
52
|
+
*/
|
53
|
+
isScrollMode?: boolean;
|
48
54
|
}
|
49
55
|
/**
|
50
56
|
* The Carousel acts as a scaffold for other Onboarding content.
|
@@ -14,6 +14,7 @@ var CarouselItem = require('./CarouselItem.js');
|
|
14
14
|
var cx = require('classnames');
|
15
15
|
var devtools = require('../../global/js/utils/devtools.js');
|
16
16
|
var settings = require('../../settings.js');
|
17
|
+
var react = require('@carbon/react');
|
17
18
|
var useIsomorphicEffect = require('../../global/js/hooks/useIsomorphicEffect.js');
|
18
19
|
|
19
20
|
// The block part of our conventional BEM class names (blockClass__E--M).
|
@@ -51,6 +52,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
51
52
|
fadedEdgeColor,
|
52
53
|
onChangeIsScrollable = defaults.onChangeIsScrollable,
|
53
54
|
onScroll = defaults.onScroll,
|
55
|
+
isScrollMode = false,
|
54
56
|
...rest
|
55
57
|
} = props;
|
56
58
|
const carouselRef = React.useRef(null);
|
@@ -61,6 +63,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
61
63
|
const childElementsRef = React.useRef(Array(React.Children.count(children)).fill(React.useRef(null)));
|
62
64
|
const leftFadedEdgeColor = typeof fadedEdgeColor === 'object' ? fadedEdgeColor?.left : fadedEdgeColor;
|
63
65
|
const rightFadedEdgeColor = typeof fadedEdgeColor === 'object' ? fadedEdgeColor?.right : fadedEdgeColor;
|
66
|
+
const carbonPrefix = react.usePrefix();
|
64
67
|
|
65
68
|
// Trigger callbacks to report state of the carousel
|
66
69
|
const handleOnScroll = React.useCallback(() => {
|
@@ -158,8 +161,42 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
158
161
|
handleOnScroll();
|
159
162
|
}, [handleOnScroll]);
|
160
163
|
const handleScrollToView = React.useCallback(itemNumber => {
|
164
|
+
updateAriaHiddenTabIndex(itemNumber);
|
161
165
|
childElementsRef.current[itemNumber].scrollIntoView();
|
166
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
162
167
|
}, []);
|
168
|
+
const getFocusableElements = container => {
|
169
|
+
const notQuery = `:not(.${carbonPrefix}--visually-hidden,.${carbonPrefix}--btn--disabled,[aria-hidden="true"],[disabled])`;
|
170
|
+
// Queries to include element types button, input, select, textarea
|
171
|
+
const queryButton = `button${notQuery}`;
|
172
|
+
const queryInput = `input${notQuery}`;
|
173
|
+
const querySelect = `select${notQuery}`;
|
174
|
+
const queryTextarea = `textarea${notQuery}`;
|
175
|
+
const queryLink = `[href]${notQuery}`;
|
176
|
+
const queryAnchor = `a${notQuery}`;
|
177
|
+
const queryTabIndex = `[tabindex="0"]${notQuery}`;
|
178
|
+
// Final query
|
179
|
+
const query = `${queryButton},${queryLink},${queryAnchor},${queryInput},${querySelect},${queryTextarea},${queryTabIndex}`;
|
180
|
+
return container?.querySelectorAll(`${query}`) ?? [];
|
181
|
+
};
|
182
|
+
const updateAriaHiddenTabIndex = itemNumber => {
|
183
|
+
//aria-hidden need to updated based on the active item, otherwise screen reader will reset to first item while
|
184
|
+
//interact with element via Control + Option + Down Arrow
|
185
|
+
// aria-hidden is set to true to inactive carousal items
|
186
|
+
// tab-index is set to -1 for all inputs in in active elements
|
187
|
+
|
188
|
+
!isScrollMode && childElementsRef.current?.forEach((item, idx) => {
|
189
|
+
const isActive = idx === itemNumber;
|
190
|
+
// Set aria-hidden based on active state
|
191
|
+
item?.setAttribute('aria-hidden', String(!isActive));
|
192
|
+
|
193
|
+
// Update tabIndex for all focusable elements within the item
|
194
|
+
const focusableElements = getFocusableElements(item);
|
195
|
+
focusableElements.forEach(el => {
|
196
|
+
el.tabIndex = isActive ? 0 : -1;
|
197
|
+
});
|
198
|
+
});
|
199
|
+
};
|
163
200
|
|
164
201
|
// Trigger a callback after first render (and applied CSS).
|
165
202
|
React.useEffect(() => {
|
@@ -170,6 +207,8 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
170
207
|
setTimeout(() => {
|
171
208
|
// But, because we are making calculations based on the final,
|
172
209
|
// applied CSS, we must wait for one more "tick".
|
210
|
+
|
211
|
+
updateAriaHiddenTabIndex(0);
|
173
212
|
handleOnScroll();
|
174
213
|
}, 0);
|
175
214
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
@@ -318,6 +357,12 @@ Carousel.propTypes = {
|
|
318
357
|
left: index.default.string,
|
319
358
|
right: index.default.string
|
320
359
|
})]),
|
360
|
+
/**
|
361
|
+
* enable scroll mode when only scroll functionality is required, more than one items will be visible at a time
|
362
|
+
* when isScrollMode is false, component behaves like a carousal and on item will be active at a time
|
363
|
+
* and other items will be hidden and inactive.
|
364
|
+
*/
|
365
|
+
isScrollMode: index.default.bool,
|
321
366
|
/**
|
322
367
|
* An optional callback function that returns `true`
|
323
368
|
* when the carousel has enough content to be scrollable,
|
@@ -20,6 +20,7 @@ interface HeaderBreadcrumb {
|
|
20
20
|
/** Provide if this breadcrumb item represents the current page */
|
21
21
|
isCurrentPage?: boolean;
|
22
22
|
}
|
23
|
+
type MaybePromise<T> = Promise<T> | T;
|
23
24
|
type CreateFullPageBreadcrumbsProps = {
|
24
25
|
/** The header breadcrumbs */
|
25
26
|
breadcrumbs?: null | undefined;
|
@@ -107,9 +108,9 @@ type CreateFullPageBaseProps = {
|
|
107
108
|
*
|
108
109
|
* @returns Object - if you want to prevent the modal from closing, return an object with the property preventClose set to true
|
109
110
|
*/
|
110
|
-
onRequestSubmit: () => {
|
111
|
+
onRequestSubmit: () => MaybePromise<{
|
111
112
|
preventClose?: boolean;
|
112
|
-
} | void
|
113
|
+
} | void>;
|
113
114
|
/**
|
114
115
|
* A secondary title of the full page, displayed in the influencer area
|
115
116
|
*/
|
@@ -15,6 +15,9 @@ interface DraggableElementProps extends PropsWithChildren {
|
|
15
15
|
isSticky?: boolean;
|
16
16
|
selected?: boolean;
|
17
17
|
}
|
18
|
+
/**
|
19
|
+
* Single row in the DraggableItemsList used by CustomizeColumnsTearsheet.
|
20
|
+
*/
|
18
21
|
declare const DraggableElement: {
|
19
22
|
({ id, elementId, children, classList, disabled, ariaLabel, isSticky, selected, }: DraggableElementProps): React.JSX.Element;
|
20
23
|
propTypes: {
|
@@ -20,6 +20,9 @@ var sortable = require('@dnd-kit/sortable');
|
|
20
20
|
|
21
21
|
var _Locked, _DraggableIcon;
|
22
22
|
const blockClass = `${settings.pkg.prefix}--datagrid`;
|
23
|
+
/**
|
24
|
+
* Single row in the DraggableItemsList used by CustomizeColumnsTearsheet.
|
25
|
+
*/
|
23
26
|
const DraggableElement = _ref => {
|
24
27
|
let {
|
25
28
|
id,
|
@@ -42,20 +45,33 @@ const DraggableElement = _ref => {
|
|
42
45
|
disabled,
|
43
46
|
id
|
44
47
|
});
|
45
|
-
|
48
|
+
|
49
|
+
// Most of the attributes (ex: role, tabIndex, aria-disabled) are unnecessary for a <button>, so just get the ones we need.
|
50
|
+
const {
|
51
|
+
'aria-pressed': ariaPressed,
|
52
|
+
'aria-describedby': ariaDescribedby
|
53
|
+
} = attributes;
|
54
|
+
const dragHandle = isSticky ? /*#__PURE__*/React.createElement("div", {
|
46
55
|
className: cx({
|
47
56
|
disabled
|
48
57
|
}, `${blockClass}__draggable-handleStyle`)
|
49
|
-
},
|
58
|
+
}, _Locked || (_Locked = /*#__PURE__*/React.createElement(icons.Locked, {
|
50
59
|
size: 16
|
51
|
-
}))
|
60
|
+
})), ' ') : /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({
|
61
|
+
className: `${blockClass}__draggable-handleStyle`,
|
62
|
+
type: "button",
|
63
|
+
"aria-label": ariaLabel,
|
64
|
+
"aria-describedby": ariaDescribedby,
|
65
|
+
"aria-pressed": ariaPressed
|
66
|
+
}, listeners), _DraggableIcon || (_DraggableIcon = /*#__PURE__*/React.createElement(icons.Draggable, {
|
52
67
|
size: 16
|
53
|
-
})))
|
68
|
+
})));
|
69
|
+
const content = /*#__PURE__*/React.createElement(React.Fragment, null, dragHandle, children);
|
54
70
|
const style = {
|
55
71
|
transform: !disabled ? utilities.CSS.Transform.toString(transform) : undefined,
|
56
72
|
transition
|
57
73
|
};
|
58
|
-
return /*#__PURE__*/React.createElement("li",
|
74
|
+
return /*#__PURE__*/React.createElement("li", {
|
59
75
|
className: cx(classList, `${blockClass}__draggable-handleHolder`, {
|
60
76
|
[`${blockClass}__draggable-handleHolder--selected`]: selected,
|
61
77
|
[`${blockClass}__draggable-handleHolder--sticky`]: isSticky,
|
@@ -64,16 +80,8 @@ const DraggableElement = _ref => {
|
|
64
80
|
id: elementId ? elementId : id,
|
65
81
|
ref: setNodeRef,
|
66
82
|
style: style
|
67
|
-
},
|
68
|
-
|
69
|
-
"aria-selected": selected,
|
70
|
-
role: "option"
|
71
|
-
}), /*#__PURE__*/React.createElement("span", {
|
72
|
-
className: `${blockClass}__shared-ui--assistive-text`
|
73
|
-
}, ariaLabel), /*#__PURE__*/React.createElement("div", {
|
74
|
-
className: cx({
|
75
|
-
[`${blockClass}__draggable-handleStyle`]: !disabled
|
76
|
-
}, [`${blockClass}__draggable-handleHolder-droppable`])
|
83
|
+
}, /*#__PURE__*/React.createElement("div", {
|
84
|
+
className: cx([`${blockClass}__draggable-handleHolder-droppable`])
|
77
85
|
}, content));
|
78
86
|
};
|
79
87
|
DraggableElement.propTypes = {
|
@@ -1,21 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
iconTooltipLabel?: string | undefined;
|
8
|
-
}): React.JSX.Element;
|
9
|
-
declare namespace ButtonWrapper {
|
10
|
-
namespace defaultProps {
|
11
|
-
function onClick(): void;
|
12
|
-
}
|
13
|
-
namespace propTypes {
|
14
|
-
export let iconTooltipLabel: any;
|
15
|
-
export let isTearsheetOpen: any;
|
16
|
-
let onClick_1: any;
|
17
|
-
export { onClick_1 as onClick };
|
18
|
-
export let setIsTearsheetOpen: any;
|
19
|
-
}
|
20
|
-
}
|
1
|
+
/**
|
2
|
+
* Copyright IBM Corp. 2022, 2024
|
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
|
+
*/
|
21
7
|
import * as React from 'react';
|
8
|
+
import { Button } from '@carbon/react';
|
9
|
+
import { ComponentProps } from 'react';
|
10
|
+
interface ButtonWrapperProps extends ComponentProps<typeof Button> {
|
11
|
+
isTearsheetOpen: boolean;
|
12
|
+
iconTooltipLabel?: string;
|
13
|
+
onClick?: () => void;
|
14
|
+
setIsTearsheetOpen: (open: boolean) => void;
|
15
|
+
}
|
16
|
+
declare const ButtonWrapper: React.ForwardRefExoticComponent<ButtonWrapperProps & React.RefAttributes<HTMLButtonElement>>;
|
17
|
+
export default ButtonWrapper;
|
@@ -36,7 +36,7 @@ function _interopNamespaceDefault(e) {
|
|
36
36
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
37
37
|
|
38
38
|
const blockClass = `${settings.pkg.prefix}--datagrid`;
|
39
|
-
const ButtonWrapper = _ref => {
|
39
|
+
const ButtonWrapper = /*#__PURE__*/React__namespace.forwardRef((_ref, ref) => {
|
40
40
|
let {
|
41
41
|
onClick,
|
42
42
|
setIsTearsheetOpen,
|
@@ -53,6 +53,7 @@ const ButtonWrapper = _ref => {
|
|
53
53
|
kind: "ghost",
|
54
54
|
hasIconOnly: true,
|
55
55
|
"test-id": `${blockClass}__customize-columns-trigger`,
|
56
|
+
ref: ref,
|
56
57
|
onClick: () => {
|
57
58
|
setIsTearsheetOpen(!isTearsheetOpen);
|
58
59
|
if (typeof onClick === 'function') {
|
@@ -60,10 +61,7 @@ const ButtonWrapper = _ref => {
|
|
60
61
|
}
|
61
62
|
}
|
62
63
|
}));
|
63
|
-
};
|
64
|
-
ButtonWrapper.defaultProps = {
|
65
|
-
onClick: () => {}
|
66
|
-
};
|
64
|
+
});
|
67
65
|
ButtonWrapper.propTypes = {
|
68
66
|
iconTooltipLabel: index.default.string,
|
69
67
|
isTearsheetOpen: index.default.bool.isRequired,
|
@@ -49,10 +49,8 @@ const Columns = _ref => {
|
|
49
49
|
ref: listRef
|
50
50
|
}, /*#__PURE__*/React.createElement("ol", {
|
51
51
|
className: `${blockClass}__customize-columns-column-list--focus`,
|
52
|
-
role: "listbox",
|
53
52
|
"aria-label": customizeTearsheetHeadingLabel,
|
54
|
-
"aria-describedby": `${blockClass}__customize-columns--instructions
|
55
|
-
tabIndex: 0
|
53
|
+
"aria-describedby": `${blockClass}__customize-columns--instructions`
|
56
54
|
}, /*#__PURE__*/React.createElement("span", {
|
57
55
|
"aria-live": "assertive",
|
58
56
|
className: `${blockClass}__shared-ui--assistive-text`
|
package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.d.ts
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
export default CustomizeColumnsTearsheet;
|
2
|
-
declare function CustomizeColumnsTearsheet({ isOpen, setIsTearsheetOpen, onSaveColumnPrefs, columnDefinitions, originalColumnDefinitions, customizeTearsheetHeadingLabel, primaryButtonTextLabel, secondaryButtonTextLabel, instructionsLabel, findColumnPlaceholderLabel, resetToDefaultLabel, assistiveTextInstructionsLabel, assistiveTextDisabledInstructionsLabel, selectAllLabel, }: {
|
2
|
+
declare function CustomizeColumnsTearsheet({ isOpen, setIsTearsheetOpen, launcherButtonRef, onSaveColumnPrefs, columnDefinitions, originalColumnDefinitions, customizeTearsheetHeadingLabel, primaryButtonTextLabel, secondaryButtonTextLabel, instructionsLabel, findColumnPlaceholderLabel, resetToDefaultLabel, assistiveTextInstructionsLabel, assistiveTextDisabledInstructionsLabel, selectAllLabel, }: {
|
3
3
|
isOpen: any;
|
4
4
|
setIsTearsheetOpen: any;
|
5
|
+
launcherButtonRef: any;
|
5
6
|
onSaveColumnPrefs: any;
|
6
7
|
columnDefinitions: any;
|
7
8
|
originalColumnDefinitions: any;
|
package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js
CHANGED
@@ -22,6 +22,7 @@ const CustomizeColumnsTearsheet = _ref => {
|
|
22
22
|
let {
|
23
23
|
isOpen,
|
24
24
|
setIsTearsheetOpen,
|
25
|
+
launcherButtonRef,
|
25
26
|
onSaveColumnPrefs,
|
26
27
|
columnDefinitions,
|
27
28
|
originalColumnDefinitions,
|
@@ -110,6 +111,7 @@ const CustomizeColumnsTearsheet = _ref => {
|
|
110
111
|
open: isOpen,
|
111
112
|
title: `${customizeTearsheetHeadingLabel} (${visibleColumnsCount}/${totalColumns})`,
|
112
113
|
description: instructionsLabel,
|
114
|
+
launcherButtonRef: launcherButtonRef,
|
113
115
|
actions: [{
|
114
116
|
kind: 'secondary',
|
115
117
|
label: secondaryButtonTextLabel,
|
@@ -150,10 +150,10 @@ const DraggableItemsList = _ref => {
|
|
150
150
|
}, visibleCols.map(colDef => {
|
151
151
|
const colHeaderTitle = getNodeTextContent.getNodeTextContent(colDef.Header);
|
152
152
|
const parts = colHeaderTitle.split(new RegExp(`(${filterString})`, 'gi'));
|
153
|
-
const highlightedText = parts.map(part => part.toLowerCase() === filterString.toLowerCase() ?
|
153
|
+
const highlightedText = parts.map(part => part.toLowerCase() === filterString.toLowerCase() ? /*#__PURE__*/React.createElement("strong", null, part) : part);
|
154
154
|
const isFrozenColumn = !!colDef.sticky;
|
155
155
|
const isDisabled = colDef.disabled;
|
156
|
-
const listContents = /*#__PURE__*/React.createElement(
|
156
|
+
const listContents = /*#__PURE__*/React.createElement(react.Checkbox, {
|
157
157
|
checked: common.isColumnVisible(colDef),
|
158
158
|
disabled: isDisabled || isFrozenColumn,
|
159
159
|
onChange: (_, _ref2) => {
|
@@ -163,17 +163,10 @@ const DraggableItemsList = _ref => {
|
|
163
163
|
return onSelectColumn(colDef, checked);
|
164
164
|
},
|
165
165
|
id: `${blockClass}__customization-column-${colDef.id}`,
|
166
|
-
labelText:
|
167
|
-
title: colHeaderTitle,
|
166
|
+
labelText: highlightedText,
|
168
167
|
className: `${blockClass}__customize-columns-checkbox`,
|
169
|
-
hideLabel: true,
|
170
168
|
onKeyDown: event => handleCheckboxKeydown(event, colDef)
|
171
|
-
})
|
172
|
-
dangerouslySetInnerHTML: {
|
173
|
-
__html: highlightedText
|
174
|
-
},
|
175
|
-
className: `${blockClass}__customize-columns-checkbox-visible-label`
|
176
|
-
}));
|
169
|
+
});
|
177
170
|
return /*#__PURE__*/React.createElement(DraggableElement.default, {
|
178
171
|
classList: draggableClass,
|
179
172
|
key: colDef.id,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
export default TearsheetWrapper;
|
2
|
-
declare function TearsheetWrapper({ instance }: {
|
2
|
+
declare function TearsheetWrapper({ instance, launcherButtonRef }: {
|
3
3
|
instance: any;
|
4
|
+
launcherButtonRef: any;
|
4
5
|
}): React.JSX.Element;
|
5
6
|
declare namespace TearsheetWrapper {
|
6
7
|
namespace propTypes {
|
@@ -18,7 +18,8 @@ var InlineEditContext = require('../InlineEdit/InlineEditContext/InlineEditConte
|
|
18
18
|
|
19
19
|
const TearsheetWrapper = _ref => {
|
20
20
|
let {
|
21
|
-
instance
|
21
|
+
instance,
|
22
|
+
launcherButtonRef
|
22
23
|
} = _ref;
|
23
24
|
const {
|
24
25
|
onSaveColumnPrefs,
|
@@ -41,6 +42,7 @@ const TearsheetWrapper = _ref => {
|
|
41
42
|
return /*#__PURE__*/React.createElement(CustomizeColumnsTearsheet.default, _rollupPluginBabelHelpers.extends({}, rest, labels, {
|
42
43
|
isOpen: isTearsheetOpen,
|
43
44
|
setIsTearsheetOpen: setIsTearsheetOpen,
|
45
|
+
launcherButtonRef: launcherButtonRef,
|
44
46
|
columnDefinitions: instance.allColumns,
|
45
47
|
originalColumnDefinitions: instance.columns,
|
46
48
|
onSaveColumnPrefs: updatedColDefs => {
|
@@ -11,8 +11,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
11
11
|
|
12
12
|
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
|
13
13
|
var React = require('react');
|
14
|
-
var TearsheetWrapper = require('./Datagrid/addons/CustomizeColumns/TearsheetWrapper.js');
|
15
14
|
var ButtonWrapper = require('./Datagrid/addons/CustomizeColumns/ButtonWrapper.js');
|
15
|
+
var TearsheetWrapper = require('./Datagrid/addons/CustomizeColumns/TearsheetWrapper.js');
|
16
16
|
|
17
17
|
function _interopNamespaceDefault(e) {
|
18
18
|
var n = Object.create(null);
|
@@ -33,29 +33,36 @@ function _interopNamespaceDefault(e) {
|
|
33
33
|
|
34
34
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
35
35
|
|
36
|
-
const
|
36
|
+
const useInstance = instance => {
|
37
|
+
const {
|
38
|
+
customizeColumnsProps
|
39
|
+
} = instance;
|
40
|
+
const {
|
41
|
+
labels
|
42
|
+
} = customizeColumnsProps || {};
|
37
43
|
const [isTearsheetOpen, setIsTearsheetOpen] = React__namespace.useState(false);
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
CustomizeColumnsTearsheet: TearsheetWrapper.default
|
57
|
-
});
|
44
|
+
const launcherButtonRef = React__namespace.useRef(null);
|
45
|
+
const CustomizeColumnsButton = React__namespace.useCallback(props => /*#__PURE__*/React__namespace.createElement(ButtonWrapper.default, _rollupPluginBabelHelpers.extends({}, props, {
|
46
|
+
iconTooltipLabel: labels?.iconTooltipLabel,
|
47
|
+
isTearsheetOpen: isTearsheetOpen,
|
48
|
+
setIsTearsheetOpen: setIsTearsheetOpen,
|
49
|
+
ref: launcherButtonRef
|
50
|
+
})), [isTearsheetOpen, labels?.iconTooltipLabel]);
|
51
|
+
const CustomizeColumnsTearsheet = React__namespace.useCallback(props => /*#__PURE__*/React__namespace.createElement(TearsheetWrapper.default, _rollupPluginBabelHelpers.extends({}, props, {
|
52
|
+
launcherButtonRef: launcherButtonRef
|
53
|
+
})), [launcherButtonRef]);
|
54
|
+
Object.assign(instance, {
|
55
|
+
customizeColumnsProps: {
|
56
|
+
...customizeColumnsProps,
|
57
|
+
isTearsheetOpen,
|
58
|
+
setIsTearsheetOpen
|
59
|
+
},
|
60
|
+
CustomizeColumnsButton,
|
61
|
+
CustomizeColumnsTearsheet
|
58
62
|
});
|
59
63
|
};
|
64
|
+
const useCustomizeColumns = hooks => {
|
65
|
+
hooks.useInstance.push(useInstance);
|
66
|
+
};
|
60
67
|
|
61
68
|
exports.default = useCustomizeColumns;
|
@@ -90,7 +90,8 @@ exports.Guidebanner = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
90
90
|
},
|
91
91
|
onScroll: scrollPercent => {
|
92
92
|
setScrollPosition(scrollPercent);
|
93
|
-
}
|
93
|
+
},
|
94
|
+
isScrollMode: true
|
94
95
|
}, children), /*#__PURE__*/React.createElement("div", {
|
95
96
|
className: cx([collapsible || showNavigation ? `${blockClass}__navigation` : null])
|
96
97
|
}, collapsible && /*#__PURE__*/React.createElement(react.Button, {
|
@@ -35,6 +35,10 @@ export interface InterstitialScreenProps {
|
|
35
35
|
* Function to call when the close button is clicked.
|
36
36
|
*/
|
37
37
|
onClose?: (value: ActionType) => void;
|
38
|
+
/**
|
39
|
+
* Provide a ref to return focus to once the interstitial is closed.
|
40
|
+
*/
|
41
|
+
launcherButtonRef?: RefObject<HTMLElement>;
|
38
42
|
}
|
39
43
|
type InterstitialScreenComponent = React.ForwardRefExoticComponent<InterstitialScreenProps & React.RefAttributes<HTMLDivElement>> & {
|
40
44
|
Header: React.FC<InterstitialScreenHeaderProps>;
|
@@ -52,6 +52,7 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
52
52
|
interstitialAriaLabel = 'Interstitial screen',
|
53
53
|
isFullScreen = false,
|
54
54
|
isOpen = false,
|
55
|
+
launcherButtonRef,
|
55
56
|
onClose,
|
56
57
|
...rest
|
57
58
|
} = props;
|
@@ -86,7 +87,12 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
86
87
|
// for modal only, "is-visible" triggers animation
|
87
88
|
setIsVisibleClass(!isFullScreen && isOpen ? 'is-visible' : null);
|
88
89
|
nextButtonRef?.current?.focus();
|
89
|
-
|
90
|
+
if (!isOpen && launcherButtonRef) {
|
91
|
+
setTimeout(() => {
|
92
|
+
launcherButtonRef.current.focus();
|
93
|
+
}, 0);
|
94
|
+
}
|
95
|
+
}, [launcherButtonRef, isFullScreen, isOpen]);
|
90
96
|
|
91
97
|
// hitting escape key also closes this component
|
92
98
|
React.useEffect(() => {
|
@@ -105,7 +111,9 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
105
111
|
return null;
|
106
112
|
}
|
107
113
|
const renderModal = () => {
|
108
|
-
return /*#__PURE__*/React.createElement(react.
|
114
|
+
return /*#__PURE__*/React.createElement(react.unstable_FeatureFlags, {
|
115
|
+
enableExperimentalFocusWrapWithoutSentinels: true
|
116
|
+
}, /*#__PURE__*/React.createElement(react.ComposedModal, _rollupPluginBabelHelpers.extends({}, rest, {
|
109
117
|
preventCloseOnClickOutside: true,
|
110
118
|
className: cx(blockClass,
|
111
119
|
// Apply the block class to the main HTML element
|
@@ -116,7 +124,7 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
116
124
|
open: isOpen,
|
117
125
|
ref: _forwardedRef,
|
118
126
|
"aria-label": interstitialAriaLabel
|
119
|
-
}, devtools.getDevtoolsProps(componentName)), children);
|
127
|
+
}, devtools.getDevtoolsProps(componentName)), children));
|
120
128
|
};
|
121
129
|
const renderFullScreen = () => {
|
122
130
|
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, {
|
@@ -197,6 +205,10 @@ exports.InterstitialScreen.propTypes = {
|
|
197
205
|
* Specifies whether the component is currently open.
|
198
206
|
*/
|
199
207
|
isOpen: index.default.bool,
|
208
|
+
/**
|
209
|
+
* Provide a ref to return focus to once the interstitial is closed.
|
210
|
+
*/
|
211
|
+
launcherButtonRef: index.default.any,
|
200
212
|
/**
|
201
213
|
* Function to call when the close button is clicked.
|
202
214
|
*/
|
@@ -26,7 +26,7 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
|
|
26
26
|
} = props;
|
27
27
|
const blockClass = `${settings.pkg.prefix}--interstitial-screen`;
|
28
28
|
const bodyBlockClass = `${blockClass}--internal-body`;
|
29
|
-
const [
|
29
|
+
const [stepType, setStepType] = React.useState();
|
30
30
|
const {
|
31
31
|
setBodyChildrenData,
|
32
32
|
bodyChildrenData,
|
@@ -52,12 +52,12 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
|
|
52
52
|
|
53
53
|
// Set body children data
|
54
54
|
setBodyChildrenData?.(children);
|
55
|
-
|
56
55
|
// If the children is an array, treat it as a multiStep
|
57
56
|
if (isElement && Array.isArray(children)) {
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
setStepType('multi');
|
58
|
+
setStepCount?.(children.length);
|
59
|
+
} else {
|
60
|
+
setStepType('single');
|
61
61
|
}
|
62
62
|
|
63
63
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
@@ -82,13 +82,13 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
|
|
82
82
|
ref: bodyScrollRef
|
83
83
|
}, rest), /*#__PURE__*/React.createElement("div", {
|
84
84
|
className: `${blockClass}--content`
|
85
|
-
},
|
85
|
+
}, stepType === 'multi' ? /*#__PURE__*/React.createElement("div", {
|
86
86
|
className: `${blockClass}__carousel`
|
87
87
|
}, /*#__PURE__*/React.createElement(Carousel.Carousel, {
|
88
88
|
disableArrowScroll: true,
|
89
89
|
ref: scrollRef,
|
90
90
|
onScroll: onScrollHandler
|
91
|
-
}, bodyChildrenData)) : bodyChildrenData));
|
91
|
+
}, bodyChildrenData)) : stepType === 'single' ? bodyChildrenData : ''));
|
92
92
|
return isFullScreen ? renderBody() : /*#__PURE__*/React.createElement(react.ModalBody, {
|
93
93
|
className: bodyBlockClass
|
94
94
|
}, renderBody());
|
@@ -44,6 +44,13 @@ const InterstitialScreenFooter = /*#__PURE__*/React.forwardRef(props => {
|
|
44
44
|
const isMultiStep = !!stepCount;
|
45
45
|
const progStepFloor = 0;
|
46
46
|
const progStepCeil = stepCount - 1;
|
47
|
+
//this will focus the start button on last step when next button is hidden and start button is shown
|
48
|
+
React.useEffect(() => {
|
49
|
+
if (progStep + 1 === stepCount && startButtonRef.current) {
|
50
|
+
startButtonRef.current.focus();
|
51
|
+
}
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
53
|
+
}, [progStep]);
|
47
54
|
const handleAction = async actionType => {
|
48
55
|
setLoadingAction(actionType);
|
49
56
|
await onAction?.(actionType, {
|