@carbon/ibm-products 2.83.0 → 2.84.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/carbon.css +4 -0
- package/css/carbon.css.map +1 -1
- package/css/index-full-carbon.css +99 -33
- 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 +95 -33
- 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 +95 -33
- 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 +95 -33
- 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/AddSelect/AddSelectBody.js +1 -1
- package/es/components/Coachmark/next/Coachmark/CoachmarkBeacon/CoachmarkBeacon.js +6 -6
- package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +1 -1
- package/es/components/PageHeader/PageHeader.js +4 -12
- package/es/components/PageHeader/next/PageHeader.js +29 -12
- package/es/components/PageHeader/next/context.d.ts +3 -0
- package/es/components/PageHeader/next/utils.js +8 -0
- package/es/components/SidePanel/SidePanel.js +11 -3
- package/es/components/Tearsheet/TearsheetPresence.d.ts +37 -0
- package/es/components/Tearsheet/TearsheetPresence.js +56 -0
- package/es/components/Tearsheet/TearsheetShell.js +76 -17
- package/es/components/Tearsheet/index.d.ts +2 -0
- package/es/components/Tearsheet/usePresence.d.ts +17 -0
- package/es/components/Tearsheet/usePresence.js +69 -0
- package/es/components/Tearsheet/usePresenceContext.d.ts +25 -0
- package/es/components/Tearsheet/usePresenceContext.js +50 -0
- package/es/global/js/hooks/useMergedRefs.d.ts +1 -0
- package/es/global/js/hooks/useMergedRefs.js +32 -0
- package/es/global/js/hooks/useOverflowString.js +1 -16
- package/es/index.js +1 -0
- package/lib/components/AddSelect/AddSelectBody.js +1 -1
- package/lib/components/Coachmark/next/Coachmark/CoachmarkBeacon/CoachmarkBeacon.js +6 -6
- package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +1 -1
- package/lib/components/PageHeader/PageHeader.js +3 -11
- package/lib/components/PageHeader/next/PageHeader.js +29 -12
- package/lib/components/PageHeader/next/context.d.ts +3 -0
- package/lib/components/PageHeader/next/utils.js +8 -0
- package/lib/components/SidePanel/SidePanel.js +10 -2
- package/lib/components/Tearsheet/TearsheetPresence.d.ts +37 -0
- package/lib/components/Tearsheet/TearsheetPresence.js +61 -0
- package/lib/components/Tearsheet/TearsheetShell.js +74 -15
- package/lib/components/Tearsheet/index.d.ts +2 -0
- package/lib/components/Tearsheet/usePresence.d.ts +17 -0
- package/lib/components/Tearsheet/usePresence.js +71 -0
- package/lib/components/Tearsheet/usePresenceContext.d.ts +25 -0
- package/lib/components/Tearsheet/usePresenceContext.js +52 -0
- package/lib/global/js/hooks/useMergedRefs.d.ts +1 -0
- package/lib/global/js/hooks/useMergedRefs.js +34 -0
- package/lib/global/js/hooks/useOverflowString.js +0 -16
- package/lib/index.js +3 -0
- package/package.json +22 -21
- package/scss/components/APIKeyModal/_api-key-modal.scss +6 -4
- package/scss/components/AboutModal/_about-modal.scss +5 -5
- package/scss/components/ActionBar/_action-bar.scss +2 -0
- package/scss/components/ActionSet/_action-set.scss +12 -11
- package/scss/components/AddSelect/_add-select.scss +28 -29
- package/scss/components/BreadcrumbWithOverflow/_breadcrumb-with-overflow.scss +10 -8
- package/scss/components/ButtonMenu/_button-menu.scss +11 -9
- package/scss/components/Card/_card.scss +12 -10
- package/scss/components/Checklist/_checklist.scss +8 -6
- package/scss/components/Coachmark/_coachmark-overlay.scss +11 -9
- package/scss/components/Coachmark/_coachmark.scss +1 -1
- package/scss/components/CoachmarkStack/_coachmark-stack.scss +6 -4
- package/scss/components/ComboButton/_combo-button.scss +11 -9
- package/scss/components/CreateFullPage/_create-full-page.scss +9 -9
- package/scss/components/CreateModal/_create-modal.scss +9 -7
- package/scss/components/CreateSidePanel/_create-side-panel.scss +6 -4
- package/scss/components/CreateTearsheet/_create-tearsheet.scss +9 -9
- package/scss/components/CreateTearsheetNarrow/_create-tearsheet-narrow.scss +5 -3
- package/scss/components/Datagrid/_datagrid.scss +9 -7
- package/scss/components/Datagrid/styles/_datagrid.scss +86 -86
- package/scss/components/Datagrid/styles/_useExpandedRow.scss +11 -9
- package/scss/components/Datagrid/styles/_useInlineEdit.scss +48 -46
- package/scss/components/Datagrid/styles/_useNestedRows.scss +16 -16
- package/scss/components/Datagrid/styles/_useNestedTable.scss +5 -3
- package/scss/components/Datagrid/styles/_useSelectAllToggle.scss +4 -2
- package/scss/components/Datagrid/styles/_useSortableColumns.scss +21 -19
- package/scss/components/Datagrid/styles/addons/_CustomizeColumnsTearsheet.scss +5 -4
- package/scss/components/Datagrid/styles/addons/_FilterFlyout.scss +5 -5
- package/scss/components/Datagrid/styles/addons/_FilterPanel.scss +11 -8
- package/scss/components/Datagrid/styles/addons/_RowSizeDropdown.scss +18 -16
- package/scss/components/Datagrid/styles/addons/_animations.scss +4 -4
- package/scss/components/DescriptionList/_description-list.scss +6 -4
- package/scss/components/EditInPlace/_edit-in-place.scss +5 -9
- package/scss/components/EditSidePanel/_edit-side-panel.scss +6 -4
- package/scss/components/EditTearsheet/_edit-tearsheet.scss +8 -9
- package/scss/components/ExportModal/_export-modal.scss +7 -5
- package/scss/components/FilterPanel/_filter-panel-accordion-item.scss +6 -5
- package/scss/components/FilterPanel/_filter-panel-checkbox-with-overflow.scss +6 -5
- package/scss/components/FilterPanel/_filter-panel-checkbox.scss +6 -5
- package/scss/components/FilterPanel/_filter-panel.scss +6 -5
- package/scss/components/FilterSummary/_filter-summary.scss +5 -9
- package/scss/components/Guidebanner/_guidebanner.scss +5 -3
- package/scss/components/ImportModal/_import-modal.scss +16 -16
- package/scss/components/InterstitialScreen/_interstitial-screen.scss +6 -4
- package/scss/components/NotificationsPanel/_notifications-panel.scss +13 -8
- package/scss/components/OptionsTile/_options-tile.scss +8 -6
- package/scss/components/PageHeader/_page-header.scss +25 -21
- package/scss/components/RemoveModal/_remove-modal.scss +5 -4
- package/scss/components/Saving/_saving.scss +5 -3
- package/scss/components/SearchBar/_search-bar.scss +5 -4
- package/scss/components/SidePanel/_animations.scss +4 -4
- package/scss/components/SidePanel/_side-panel.scss +31 -12
- package/scss/components/SimpleHeader/_simple-header.scss +5 -4
- package/scss/components/StatusIcon/_status-icon.scss +5 -3
- package/scss/components/StatusIndicator/_status-indicator.scss +3 -2
- package/scss/components/StringFormatter/_string-formatter.scss +5 -4
- package/scss/components/TagOverflow/_tag-overflow.scss +7 -6
- package/scss/components/TagSet/_tag-set.scss +20 -18
- package/scss/components/Tearsheet/_tearsheet.scss +121 -30
- package/scss/components/Toolbar/_toolbar.scss +4 -2
- package/scss/components/TruncatedList/_truncated-list.scss +4 -3
- package/scss/components/TruncatedText/_truncated-text.scss +2 -2
- package/scss/components/UserAvatar/_user-avatar.scss +5 -4
- package/scss/components/UserProfileImage/_user-profile-image.scss +11 -7
- package/scss/components/WebTerminal/_web-terminal.scss +4 -2
- package/telemetry.yml +3 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2025
|
|
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 { type RefObject } from 'react';
|
|
8
|
+
export interface PresenceContext {
|
|
9
|
+
/**
|
|
10
|
+
* The ref object the presence mode is mounted with
|
|
11
|
+
*/
|
|
12
|
+
presenceRef: RefObject<HTMLDivElement | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Indicates whether the ref object is currently exiting
|
|
15
|
+
*/
|
|
16
|
+
isExiting: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Returns if the caller is exclusive to this presence context
|
|
19
|
+
*/
|
|
20
|
+
isPresenceExclusive: (id: string) => boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns if the presence node is present and the context value to be used by a presence context, e.g. ModalPresence.
|
|
24
|
+
*/
|
|
25
|
+
export declare const usePresenceContext: (open: boolean, initialPresenceId?: string) => readonly [boolean, PresenceContext];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2020, 2026
|
|
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
|
+
|
|
8
|
+
import { useRef, useCallback, useMemo } from 'react';
|
|
9
|
+
import { usePresence } from './usePresence.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns if the presence node is present and the context value to be used by a presence context, e.g. ModalPresence.
|
|
13
|
+
*/
|
|
14
|
+
const usePresenceContext = (open, initialPresenceId) => {
|
|
15
|
+
const presenceIdRef = useRef(initialPresenceId);
|
|
16
|
+
const presenceRef = useRef(null);
|
|
17
|
+
const prevPresenceRef = useRef(null);
|
|
18
|
+
|
|
19
|
+
// clean up the presence id, if not predefined and if the presence node was unmounted
|
|
20
|
+
if (!initialPresenceId && prevPresenceRef.current && !presenceRef.current) {
|
|
21
|
+
presenceIdRef.current = null;
|
|
22
|
+
}
|
|
23
|
+
prevPresenceRef.current = presenceRef.current;
|
|
24
|
+
const {
|
|
25
|
+
isPresent,
|
|
26
|
+
isExiting
|
|
27
|
+
} = usePresence(presenceRef, open);
|
|
28
|
+
const isPresenceExclusive = useCallback(id => {
|
|
29
|
+
if (!id) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// return false if the presence context is occupied
|
|
34
|
+
if (presenceIdRef.current && presenceIdRef.current !== id) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// otherwise occupy presence context and return true
|
|
39
|
+
presenceIdRef.current = id;
|
|
40
|
+
return true;
|
|
41
|
+
}, []);
|
|
42
|
+
const contextValue = useMemo(() => ({
|
|
43
|
+
presenceRef,
|
|
44
|
+
isPresenceExclusive,
|
|
45
|
+
isExiting
|
|
46
|
+
}), [presenceRef, isPresenceExclusive, isExiting]);
|
|
47
|
+
return [isPresent, contextValue];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { usePresenceContext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function useMergedRefs(refs: any): (node: any) => void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2020, 2026
|
|
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
|
+
|
|
8
|
+
import { useMemo, useCallback } from 'react';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Merges multiple refs into a single callback ref.
|
|
12
|
+
*
|
|
13
|
+
* This hook is useful when you need to attach multiple refs (for example, a ref
|
|
14
|
+
* passed from `forwardRef` and a local ref from `useRef`) to the same node. It
|
|
15
|
+
* accepts an array of refs and returns a callback ref that, when attached to a
|
|
16
|
+
* node, assigns that node to every ref in the array.
|
|
17
|
+
*/
|
|
18
|
+
const useMergedRefs = refs => {
|
|
19
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20
|
+
const memoizedRefs = useMemo(() => refs, refs);
|
|
21
|
+
return useCallback(node => {
|
|
22
|
+
memoizedRefs.forEach(ref => {
|
|
23
|
+
if (typeof ref === 'function') {
|
|
24
|
+
ref(node);
|
|
25
|
+
} else if (ref) {
|
|
26
|
+
ref.current = node;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}, [memoizedRefs]);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { useMergedRefs };
|
|
@@ -22,20 +22,5 @@ function useOverflowStringWidth(elementRef) {
|
|
|
22
22
|
}, [checkWidthOverflow, elementRef, innerText]);
|
|
23
23
|
return isOverflowing;
|
|
24
24
|
}
|
|
25
|
-
const useOverflowStringHeight = elementRef => {
|
|
26
|
-
const innerText = elementRef?.current?.innerText;
|
|
27
|
-
const [isOverflowing, setIsOverflowing] = useState();
|
|
28
|
-
const checkHeightOverflow = useCallback(() => {
|
|
29
|
-
const offsetHeight = elementRef?.current?.offsetHeight;
|
|
30
|
-
const scrollHeight = elementRef?.current?.scrollHeight;
|
|
31
|
-
if (offsetHeight && scrollHeight) {
|
|
32
|
-
setIsOverflowing(offsetHeight < scrollHeight);
|
|
33
|
-
}
|
|
34
|
-
}, [elementRef]);
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
checkHeightOverflow();
|
|
37
|
-
}, [checkHeightOverflow, elementRef, innerText]);
|
|
38
|
-
return isOverflowing;
|
|
39
|
-
};
|
|
40
25
|
|
|
41
|
-
export {
|
|
26
|
+
export { useOverflowStringWidth };
|
package/es/index.js
CHANGED
|
@@ -49,6 +49,7 @@ export { TagOverflow } from './components/TagOverflow/TagOverflow.js';
|
|
|
49
49
|
export { TagSet } from './components/TagSet/TagSet.js';
|
|
50
50
|
export { Tearsheet } from './components/Tearsheet/Tearsheet.js';
|
|
51
51
|
export { TearsheetNarrow } from './components/Tearsheet/TearsheetNarrow.js';
|
|
52
|
+
export { TearsheetPresence, withTearsheetPresence } from './components/Tearsheet/TearsheetPresence.js';
|
|
52
53
|
export { WebTerminal } from './components/WebTerminal/WebTerminal.js';
|
|
53
54
|
export { WebTerminalContentWrapper } from './components/WebTerminal/WebTerminalContentWrapper.js';
|
|
54
55
|
export { WebTerminalProvider, useWebTerminal } from './components/WebTerminal/hooks/index.js';
|
|
@@ -14,6 +14,7 @@ var cx = require('classnames');
|
|
|
14
14
|
var react = require('@carbon/react');
|
|
15
15
|
var Tearsheet = require('../Tearsheet/Tearsheet.js');
|
|
16
16
|
var TearsheetNarrow = require('../Tearsheet/TearsheetNarrow.js');
|
|
17
|
+
var settings = require('../../settings.js');
|
|
17
18
|
require('../EmptyStates/EmptyState.js');
|
|
18
19
|
require('../EmptyStates/EmptyStateV2.deprecated.js');
|
|
19
20
|
require('../EmptyStates/ErrorEmptyState/ErrorEmptyState.js');
|
|
@@ -32,7 +33,6 @@ var addSelectUtils = require('./add-select-utils.js');
|
|
|
32
33
|
var useItemSort = require('./hooks/useItemSort.js');
|
|
33
34
|
var useParentSelect = require('./hooks/useParentSelect.js');
|
|
34
35
|
var usePath = require('./hooks/usePath.js');
|
|
35
|
-
var settings = require('../../settings.js');
|
|
36
36
|
|
|
37
37
|
const blockClass = `${settings.pkg.prefix}--add-select`;
|
|
38
38
|
const componentName = 'AddSelectBody';
|
|
@@ -33,18 +33,18 @@ const CoachmarkBeacon = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
33
33
|
} = props;
|
|
34
34
|
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
|
|
35
35
|
className: cx(blockClass, `${blockClass}-${kind}`, className)
|
|
36
|
-
}, devtools.getDevtoolsProps(componentName), {
|
|
37
|
-
role: "tooltip"
|
|
38
|
-
}, rest, {
|
|
36
|
+
}, devtools.getDevtoolsProps(componentName), rest, {
|
|
39
37
|
ref: ref
|
|
40
38
|
}), /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({
|
|
41
39
|
type: "button"
|
|
42
40
|
}, buttonProps, {
|
|
43
|
-
className: `${blockClass}__target
|
|
41
|
+
className: `${blockClass}__target`,
|
|
42
|
+
"aria-label": label
|
|
44
43
|
}), /*#__PURE__*/React.createElement("svg", {
|
|
45
44
|
className: `${blockClass}__center`,
|
|
46
|
-
"aria-
|
|
47
|
-
|
|
45
|
+
"aria-hidden": "true",
|
|
46
|
+
focusable: "false"
|
|
47
|
+
}, _circle || (_circle = /*#__PURE__*/React.createElement("circle", {
|
|
48
48
|
r: 1,
|
|
49
49
|
cx: 38,
|
|
50
50
|
cy: 38
|
package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js
CHANGED
|
@@ -13,9 +13,9 @@ var React = require('react');
|
|
|
13
13
|
var index = require('../../../../../_virtual/index.js');
|
|
14
14
|
require('../../../../Tearsheet/Tearsheet.js');
|
|
15
15
|
var TearsheetNarrow = require('../../../../Tearsheet/TearsheetNarrow.js');
|
|
16
|
+
var settings = require('../../../../../settings.js');
|
|
16
17
|
var Columns = require('./Columns.js');
|
|
17
18
|
var Actions = require('./Actions.js');
|
|
18
|
-
var settings = require('../../../../../settings.js');
|
|
19
19
|
|
|
20
20
|
const blockClass = `${settings.pkg.prefix}--datagrid`;
|
|
21
21
|
const CustomizeColumnsTearsheet = _ref => {
|
|
@@ -21,7 +21,6 @@ var cx = require('classnames');
|
|
|
21
21
|
var devtools = require('../../global/js/utils/devtools.js');
|
|
22
22
|
var settings = require('../../settings.js');
|
|
23
23
|
var useResizeObserver = require('../../global/js/hooks/useResizeObserver.js');
|
|
24
|
-
var useOverflowString = require('../../global/js/hooks/useOverflowString.js');
|
|
25
24
|
var useWindowScroll = require('../../global/js/hooks/useWindowScroll.js');
|
|
26
25
|
var useWindowResize = require('../../global/js/hooks/useWindowResize.js');
|
|
27
26
|
var useIsomorphicEffect = require('../../global/js/hooks/useIsomorphicEffect.js');
|
|
@@ -357,12 +356,6 @@ const PageHeader = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
357
356
|
}
|
|
358
357
|
});
|
|
359
358
|
}, [headerRef, pageHeaderStyles]);
|
|
360
|
-
const subtitleRef = React.useRef(null);
|
|
361
|
-
const isOverflowing = useOverflowString.useOverflowStringHeight(subtitleRef);
|
|
362
|
-
const subtitleContent = /*#__PURE__*/React.createElement("span", {
|
|
363
|
-
ref: subtitleRef,
|
|
364
|
-
className: `${PageHeaderUtils.blockClass}__subtitle-text`
|
|
365
|
-
}, subtitle);
|
|
366
359
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
367
360
|
className: `${PageHeaderUtils.blockClass}--offset-top-measuring-element`,
|
|
368
361
|
ref: offsetTopMeasuringRef
|
|
@@ -439,10 +432,9 @@ const PageHeader = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
439
432
|
className: `${PageHeaderUtils.blockClass}__subtitle-row`
|
|
440
433
|
}, /*#__PURE__*/React.createElement(react.Column, {
|
|
441
434
|
className: `${PageHeaderUtils.blockClass}__subtitle`
|
|
442
|
-
},
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}, subtitleContent) : subtitleContent)), children ? /*#__PURE__*/React.createElement(react.Row, {
|
|
435
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
436
|
+
className: `${PageHeaderUtils.blockClass}__subtitle-text`
|
|
437
|
+
}, subtitle))), children ? /*#__PURE__*/React.createElement(react.Row, {
|
|
446
438
|
className: `${PageHeaderUtils.blockClass}__available-row`
|
|
447
439
|
}, /*#__PURE__*/React.createElement(react.Column, {
|
|
448
440
|
className: `${PageHeaderUtils.blockClass}__available-column`
|
|
@@ -59,6 +59,7 @@ const PageHeader = /*#__PURE__*/React.forwardRef(function PageHeader(_ref, ref)
|
|
|
59
59
|
const [fullyCollapsed, setFullyCollapsed] = React.useState(false);
|
|
60
60
|
const [titleClipped, setTitleClipped] = React.useState(false);
|
|
61
61
|
const [contentActionsClipped, setContentActionsClipped] = React.useState(false);
|
|
62
|
+
const [breadcrumbActionsClipped, setBreadcrumbActionsClipped] = React.useState(false);
|
|
62
63
|
|
|
63
64
|
// Intersection Observer setup, tracks if the PageHeaderContent is visible on page.
|
|
64
65
|
// If it is not visible, we should set fully collapsed to true so that the
|
|
@@ -103,6 +104,7 @@ const PageHeader = /*#__PURE__*/React.forwardRef(function PageHeader(_ref, ref)
|
|
|
103
104
|
entries.forEach(entry => {
|
|
104
105
|
if (entry.target === refs?.contentActions.current) {
|
|
105
106
|
setContentActionsClipped(!entry.isIntersecting);
|
|
107
|
+
setBreadcrumbActionsClipped(entry.isIntersecting);
|
|
106
108
|
}
|
|
107
109
|
});
|
|
108
110
|
}, {
|
|
@@ -142,7 +144,8 @@ const PageHeader = /*#__PURE__*/React.forwardRef(function PageHeader(_ref, ref)
|
|
|
142
144
|
pageActionsInstance,
|
|
143
145
|
setPageActionsInstance,
|
|
144
146
|
titleClipped,
|
|
145
|
-
contentActionsClipped
|
|
147
|
+
contentActionsClipped,
|
|
148
|
+
breadcrumbActionsClipped
|
|
146
149
|
}
|
|
147
150
|
}, /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
|
|
148
151
|
className: classNames,
|
|
@@ -169,10 +172,11 @@ const PageHeaderBreadcrumbBar = /*#__PURE__*/React.forwardRef(function PageHeade
|
|
|
169
172
|
pageActionsFlush,
|
|
170
173
|
...other
|
|
171
174
|
} = _ref2;
|
|
175
|
+
const context$1 = context.usePageHeader();
|
|
172
176
|
const {
|
|
173
177
|
pageActionsInstance: globalActions,
|
|
174
178
|
contentActionsClipped
|
|
175
|
-
} = context
|
|
179
|
+
} = context$1;
|
|
176
180
|
const classNames = cx({
|
|
177
181
|
[`${PageHeaderUtils.blockClass}__breadcrumb-bar`]: true,
|
|
178
182
|
[`${PageHeaderUtils.blockClass}__breadcrumb-bar-border`]: border,
|
|
@@ -183,7 +187,12 @@ const PageHeaderBreadcrumbBar = /*#__PURE__*/React.forwardRef(function PageHeade
|
|
|
183
187
|
[`${PageHeaderUtils.blockClass}__breadcrumb__content-actions-with-global-actions`]: !!globalActions,
|
|
184
188
|
[`${PageHeaderUtils.blockClass}__breadcrumb__content-actions-with-global-actions--show`]: contentActionsClipped
|
|
185
189
|
});
|
|
186
|
-
return /*#__PURE__*/React.createElement(
|
|
190
|
+
return /*#__PURE__*/React.createElement(context.PageHeaderContext.Provider, {
|
|
191
|
+
value: {
|
|
192
|
+
...context$1,
|
|
193
|
+
isContentActionsInBreadcrumbBar: true
|
|
194
|
+
}
|
|
195
|
+
}, /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
|
|
187
196
|
className: classNames,
|
|
188
197
|
ref: ref
|
|
189
198
|
}, other), /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement(react.Column, {
|
|
@@ -200,7 +209,7 @@ const PageHeaderBreadcrumbBar = /*#__PURE__*/React.forwardRef(function PageHeade
|
|
|
200
209
|
className: `${PageHeaderUtils.blockClass}__breadcrumb__actions`
|
|
201
210
|
}, /*#__PURE__*/React.createElement("div", {
|
|
202
211
|
className: contentActionsClasses
|
|
203
|
-
}, contentActions), pageActions)))));
|
|
212
|
+
}, contentActions), pageActions))))));
|
|
204
213
|
});
|
|
205
214
|
PageHeaderBreadcrumbBar.displayName = 'PageHeaderBreadcrumbBar';
|
|
206
215
|
|
|
@@ -332,12 +341,14 @@ const PageHeaderContentPageActions = _ref4 => {
|
|
|
332
341
|
} = _ref4;
|
|
333
342
|
const {
|
|
334
343
|
setRefs,
|
|
335
|
-
contentActionsClipped
|
|
344
|
+
contentActionsClipped,
|
|
345
|
+
breadcrumbActionsClipped,
|
|
346
|
+
isContentActionsInBreadcrumbBar: isInBreadcrumbBar
|
|
336
347
|
} = context.usePageHeader();
|
|
337
348
|
const classNames = cx(`${PageHeaderUtils.blockClass}__content__page-actions`, {
|
|
338
349
|
// Revisit this:
|
|
339
350
|
// May want to only add this class if there are content actions in the breadcrumb bar as well
|
|
340
|
-
[`${PageHeaderUtils.blockClass}__content__page-actions--clipped`]: contentActionsClipped
|
|
351
|
+
[`${PageHeaderUtils.blockClass}__content__page-actions--clipped`]: isInBreadcrumbBar ? breadcrumbActionsClipped : contentActionsClipped
|
|
341
352
|
}, className);
|
|
342
353
|
const containerRef = React.useRef(null);
|
|
343
354
|
const offsetRef = React.useRef(null);
|
|
@@ -353,12 +364,18 @@ const PageHeaderContentPageActions = _ref4 => {
|
|
|
353
364
|
}
|
|
354
365
|
}, [menuButtonVisibility]);
|
|
355
366
|
React.useEffect(() => {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
367
|
+
if (isInBreadcrumbBar) {
|
|
368
|
+
setRefs(prev => ({
|
|
369
|
+
...prev,
|
|
370
|
+
breadcrumbActions: containerRef
|
|
371
|
+
}));
|
|
372
|
+
} else {
|
|
373
|
+
setRefs(prev => ({
|
|
374
|
+
...prev,
|
|
375
|
+
contentActions: containerRef
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
}, [isInBreadcrumbBar, setRefs]);
|
|
362
379
|
React.useEffect(() => {
|
|
363
380
|
if (!containerRef.current || !Array.isArray(actions)) {
|
|
364
381
|
return;
|
|
@@ -14,6 +14,7 @@ export type PageHeaderRefs = {
|
|
|
14
14
|
contentRef?: RefObject<HTMLDivElement | null>;
|
|
15
15
|
titleRef?: RefObject<HTMLHeadingElement | null>;
|
|
16
16
|
contentActions?: RefObject<HTMLDivElement | null>;
|
|
17
|
+
breadcrumbActions?: RefObject<HTMLDivElement | null>;
|
|
17
18
|
};
|
|
18
19
|
type PageHeaderContextType = {
|
|
19
20
|
refs?: PageHeaderRefs;
|
|
@@ -23,6 +24,8 @@ type PageHeaderContextType = {
|
|
|
23
24
|
fullyCollapsed?: boolean;
|
|
24
25
|
titleClipped?: boolean;
|
|
25
26
|
contentActionsClipped?: boolean;
|
|
27
|
+
breadcrumbActionsClipped?: boolean;
|
|
28
|
+
isContentActionsInBreadcrumbBar?: boolean;
|
|
26
29
|
};
|
|
27
30
|
export declare const PageHeaderContext: import("react").Context<PageHeaderContextType | undefined>;
|
|
28
31
|
export declare function usePageHeader(): PageHeaderContextType;
|
|
@@ -41,6 +41,14 @@ const windowExists = typeof window !== `undefined`;
|
|
|
41
41
|
*/
|
|
42
42
|
const scrollable = target => {
|
|
43
43
|
const style = window.getComputedStyle(target);
|
|
44
|
+
const tagName = target.tagName.toLowerCase();
|
|
45
|
+
|
|
46
|
+
// Exclude body/html from hidden check (modals set overflow:hidden on body)
|
|
47
|
+
if (tagName === 'body' || tagName === 'html') {
|
|
48
|
+
return /(auto|scroll)/.test(style.overflow);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// For other elements, include hidden as it may be intentional scroll container
|
|
44
52
|
return /(auto|scroll|hidden)/.test(style.overflow);
|
|
45
53
|
};
|
|
46
54
|
|
|
@@ -115,11 +115,19 @@ const SidePanel = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
115
115
|
|
|
116
116
|
// Title animation on scroll related state
|
|
117
117
|
const [labelTextHeight, setLabelTextHeight] = React.useState(0);
|
|
118
|
-
const handleEscapeKey = event => {
|
|
118
|
+
const handleEscapeKey = React.useCallback(event => {
|
|
119
119
|
if (event.key === 'Escape' && open) {
|
|
120
120
|
onRequestClose?.();
|
|
121
121
|
}
|
|
122
|
-
};
|
|
122
|
+
}, [onRequestClose, open]);
|
|
123
|
+
React.useEffect(() => {
|
|
124
|
+
if (open && !slideIn) {
|
|
125
|
+
window.addEventListener('keydown', handleEscapeKey);
|
|
126
|
+
return () => {
|
|
127
|
+
window.removeEventListener('keydown', handleEscapeKey);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}, [handleEscapeKey, open, slideIn]);
|
|
123
131
|
React.useEffect(() => {
|
|
124
132
|
if (!enableResizer) {
|
|
125
133
|
return;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2025
|
|
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, { type ComponentType, type FC, type PropsWithChildren } from 'react';
|
|
8
|
+
import { type PresenceContext } from './usePresenceContext';
|
|
9
|
+
export interface TearsheetPresenceProps {
|
|
10
|
+
/**
|
|
11
|
+
* Specify whether the Modal is currently open
|
|
12
|
+
*/
|
|
13
|
+
open: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Internal property for backwards compatibility. Specify whether the Modal should opt in to presence mode.
|
|
16
|
+
*/
|
|
17
|
+
_autoEnablePresence?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Internal property to predefine the presence context's id for exclusivity.
|
|
20
|
+
*/
|
|
21
|
+
_presenceId?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const TearsheetPresence: ({ open, _presenceId: presenceId, _autoEnablePresence: autoEnablePresence, children, }: PropsWithChildren<TearsheetPresenceProps>) => React.JSX.Element | null;
|
|
24
|
+
interface ModalPresenceContextProps extends PresenceContext {
|
|
25
|
+
autoEnablePresence: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const TearsheetPresenceContext: React.Context<ModalPresenceContextProps | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* Handles occurrences where only a single modal must consume a context.
|
|
30
|
+
*/
|
|
31
|
+
export declare const useExclusiveTearsheetPresenceContext: (id: string) => ModalPresenceContextProps | undefined;
|
|
32
|
+
type WithModalPresenceProps = Pick<TearsheetPresenceProps, 'open'>;
|
|
33
|
+
/**
|
|
34
|
+
* Higher-order function that wraps a component with ModalPresence
|
|
35
|
+
*/
|
|
36
|
+
export declare const withTearsheetPresence: <TProps extends object>(Component: ComponentType<TProps>) => FC<TProps & WithModalPresenceProps>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2020, 2026
|
|
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
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
var React = require('react');
|
|
11
|
+
var usePresenceContext = require('./usePresenceContext.js');
|
|
12
|
+
|
|
13
|
+
const TearsheetPresence = _ref => {
|
|
14
|
+
let {
|
|
15
|
+
open,
|
|
16
|
+
_presenceId: presenceId,
|
|
17
|
+
_autoEnablePresence: autoEnablePresence = true,
|
|
18
|
+
children
|
|
19
|
+
} = _ref;
|
|
20
|
+
const [isPresent, context] = usePresenceContext.usePresenceContext(open, presenceId);
|
|
21
|
+
const contextValue = React.useMemo(() => ({
|
|
22
|
+
autoEnablePresence,
|
|
23
|
+
...context
|
|
24
|
+
}), [autoEnablePresence, context]);
|
|
25
|
+
if (!isPresent) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return /*#__PURE__*/React.createElement(TearsheetPresenceContext.Provider, {
|
|
29
|
+
value: contextValue
|
|
30
|
+
}, children);
|
|
31
|
+
};
|
|
32
|
+
const TearsheetPresenceContext = /*#__PURE__*/React.createContext(undefined);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Handles occurrences where only a single modal must consume a context.
|
|
36
|
+
*/
|
|
37
|
+
const useExclusiveTearsheetPresenceContext = id => {
|
|
38
|
+
const ctx = React.useContext(TearsheetPresenceContext);
|
|
39
|
+
return ctx?.isPresenceExclusive(id) ? ctx : undefined;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Higher-order function that wraps a component with ModalPresence
|
|
43
|
+
*/
|
|
44
|
+
const withTearsheetPresence = Component => {
|
|
45
|
+
const WithModalPresence = props => {
|
|
46
|
+
const {
|
|
47
|
+
open,
|
|
48
|
+
...componentProps
|
|
49
|
+
} = props;
|
|
50
|
+
return /*#__PURE__*/React.createElement(TearsheetPresence, {
|
|
51
|
+
open: open
|
|
52
|
+
}, /*#__PURE__*/React.createElement(Component, componentProps));
|
|
53
|
+
};
|
|
54
|
+
WithModalPresence.displayName = `withModalPresence(${Component.displayName || Component.name || 'Component'})`;
|
|
55
|
+
return WithModalPresence;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
exports.TearsheetPresence = TearsheetPresence;
|
|
59
|
+
exports.TearsheetPresenceContext = TearsheetPresenceContext;
|
|
60
|
+
exports.useExclusiveTearsheetPresenceContext = useExclusiveTearsheetPresenceContext;
|
|
61
|
+
exports.withTearsheetPresence = withTearsheetPresence;
|