@carbon/ibm-products 2.71.1 → 2.72.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.
Files changed (226) hide show
  1. package/css/carbon.css +50 -0
  2. package/css/carbon.css.map +1 -1
  3. package/css/index-full-carbon.css +560 -185
  4. package/css/index-full-carbon.css.map +1 -1
  5. package/css/index-full-carbon.min.css +1 -1
  6. package/css/index-full-carbon.min.css.map +1 -1
  7. package/css/index-without-carbon-released-only.css +132 -1
  8. package/css/index-without-carbon-released-only.css.map +1 -1
  9. package/css/index-without-carbon-released-only.min.css +1 -1
  10. package/css/index-without-carbon-released-only.min.css.map +1 -1
  11. package/css/index-without-carbon.css +570 -245
  12. package/css/index-without-carbon.css.map +1 -1
  13. package/css/index-without-carbon.min.css +1 -1
  14. package/css/index-without-carbon.min.css.map +1 -1
  15. package/css/index.css +358 -33
  16. package/css/index.css.map +1 -1
  17. package/css/index.min.css +1 -1
  18. package/css/index.min.css.map +1 -1
  19. package/es/components/{BigNumbers/BigNumbers.d.ts → BigNumber/BigNumber.d.ts} +5 -5
  20. package/es/components/{BigNumbers/BigNumbers.js → BigNumber/BigNumber.js} +12 -12
  21. package/es/components/BigNumber/BigNumberSkeleton.d.ts +17 -0
  22. package/es/components/{BigNumbers/BigNumbersSkeleton.js → BigNumber/BigNumberSkeleton.js} +16 -16
  23. package/es/components/{BigNumbers → BigNumber}/constants.d.ts +3 -3
  24. package/es/components/{BigNumbers → BigNumber}/constants.js +6 -6
  25. package/es/components/{BigNumbers → BigNumber}/index.d.ts +2 -2
  26. package/es/components/Coachmark/next/Coachmark/Coachmark.d.ts +72 -0
  27. package/es/components/Coachmark/next/Coachmark/Coachmark.js +185 -0
  28. package/es/components/Coachmark/next/Coachmark/CoachmarkBeacon/CoachmarkBeacon.d.ts +44 -0
  29. package/es/components/Coachmark/next/Coachmark/CoachmarkBeacon/index.d.ts +8 -0
  30. package/es/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubble.d.ts +38 -0
  31. package/es/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubble.js +125 -0
  32. package/es/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubbleHeader.d.ts +24 -0
  33. package/es/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubbleHeader.js +25 -0
  34. package/es/components/Coachmark/next/Coachmark/CoachmarkBubble/index.d.ts +10 -0
  35. package/es/components/Coachmark/next/Coachmark/CoachmarkContent.d.ts +34 -0
  36. package/es/components/Coachmark/next/Coachmark/CoachmarkContent.js +118 -0
  37. package/es/components/Coachmark/next/Coachmark/ContentBody.d.ts +23 -0
  38. package/es/components/Coachmark/next/Coachmark/ContentBody.js +37 -0
  39. package/es/components/Coachmark/next/Coachmark/ContentHeader.d.ts +21 -0
  40. package/es/components/Coachmark/next/Coachmark/ContentHeader.js +89 -0
  41. package/{lib/components/BigNumbers → es/components/Coachmark/next/Coachmark}/index.d.ts +2 -2
  42. package/es/components/CoachmarkBeacon/CoachmarkBeacon.js +0 -1
  43. package/es/components/ConditionBuilder/ConditionBuilderContent/ConditionBuilderContent.js +2 -1
  44. package/es/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItem.js +30 -5
  45. package/es/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemDate/ConditionBuilderItemDate.js +1 -1
  46. package/es/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemNumber/ConditionBuilderItemNumber.js +11 -4
  47. package/es/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemOption/ItemOption.js +2 -2
  48. package/es/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemOption/ItemOptionForValueField.js +1 -1
  49. package/es/components/ConditionBuilder/ConditionGroupBuilder/ConditionGroupBuilder.js +42 -3
  50. package/es/components/ConditionBuilder/ConditionPreview/ConditionPreview.d.ts +3 -1
  51. package/es/components/ConditionBuilder/ConditionPreview/ConditionPreview.js +5 -3
  52. package/es/components/ConditionBuilder/utils/useEvent.d.ts +8 -0
  53. package/es/components/ConditionBuilder/utils/useEvent.js +32 -0
  54. package/es/components/ConditionBuilder/utils/useTranslations.js +1 -1
  55. package/es/components/EditInPlace/EditInPlace.js +0 -3
  56. package/es/components/EmptyStates/EmptyState.d.ts +2 -2
  57. package/es/components/EmptyStates/EmptyState.js +2 -8
  58. package/es/components/FilterPanel/FilterPanelGroup/index.d.ts +1 -0
  59. package/es/components/InterstitialScreen/InterstitialScreen.d.ts +1 -25
  60. package/es/components/InterstitialScreen/InterstitialScreen.js +3 -19
  61. package/es/components/InterstitialScreen/InterstitialScreenBody.d.ts +1 -1
  62. package/es/components/InterstitialScreen/InterstitialScreenBody.js +1 -1
  63. package/es/components/InterstitialScreen/InterstitialScreenFooter.d.ts +1 -1
  64. package/es/components/InterstitialScreen/InterstitialScreenFooter.js +1 -1
  65. package/es/components/InterstitialScreen/InterstitialScreenHeader.d.ts +6 -0
  66. package/es/components/InterstitialScreen/InterstitialScreenHeader.js +1 -1
  67. package/es/components/InterstitialScreen/_story-assets/InterstitialScreenViewModule/InterstitialScreenViewModule.d.ts +1 -1
  68. package/es/components/InterstitialScreen/context.d.ts +31 -0
  69. package/es/components/InterstitialScreen/context.js +18 -0
  70. package/es/components/InterstitialScreen/index.d.ts +3 -2
  71. package/es/components/NotificationsPanel/NotificationsPanel.js +36 -13
  72. package/es/components/PageHeader/PageHeader.d.ts +2 -1
  73. package/es/components/PageHeader/PageHeader.js +2 -1
  74. package/es/components/PageHeader/next/PageHeader.d.ts +18 -3
  75. package/es/components/PageHeader/next/PageHeader.js +260 -12
  76. package/es/components/PageHeader/next/context.d.ts +25 -0
  77. package/es/components/PageHeader/next/context.js +30 -0
  78. package/es/components/PageHeader/next/index.d.ts +3 -3
  79. package/es/components/PageHeader/next/overflowHandler.d.ts +95 -0
  80. package/es/components/PageHeader/next/overflowHandler.js +162 -0
  81. package/es/components/PageHeader/next/utils.d.ts +19 -0
  82. package/es/components/PageHeader/next/utils.js +68 -0
  83. package/es/components/ProductiveCard/ProductiveCard.js +2 -1
  84. package/es/components/ScrollGradient/ScrollGradient.js +1 -2
  85. package/es/components/SidePanel/SidePanel.d.ts +4 -0
  86. package/es/components/SidePanel/SidePanel.js +8 -2
  87. package/es/components/Tearsheet/TearsheetShell.js +8 -5
  88. package/es/components/TruncatedText/TruncatedText.d.ts +48 -0
  89. package/es/components/TruncatedText/TruncatedText.js +86 -0
  90. package/es/components/TruncatedText/index.d.ts +7 -0
  91. package/es/components/TruncatedText/useTruncatedText.d.ts +16 -0
  92. package/es/components/TruncatedText/useTruncatedText.js +41 -0
  93. package/es/components/index.d.ts +3 -1
  94. package/es/global/js/hooks/useOverflowString.d.ts +2 -2
  95. package/es/global/js/hooks/useResizeObserver.d.ts +1 -1
  96. package/es/global/js/package-settings.d.ts +2 -1
  97. package/es/global/js/package-settings.js +3 -2
  98. package/es/global/js/utils/checkForOverflow.js +21 -0
  99. package/es/global/js/utils/makeDraggable/index.d.ts +1 -0
  100. package/es/global/js/utils/makeDraggable/makeDraggable.d.ts +19 -0
  101. package/es/global/js/utils/makeDraggable/makeDraggable.js +91 -0
  102. package/es/global/js/utils/makeDraggable/makeDraggable.stories.d.ts +22 -0
  103. package/es/index.js +3 -1
  104. package/es/node_modules/@floating-ui/core/dist/floating-ui.core.js +592 -0
  105. package/es/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +713 -0
  106. package/es/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js +95 -0
  107. package/es/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +161 -0
  108. package/es/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +142 -0
  109. package/es/settings.d.ts +2 -1
  110. package/lib/components/{BigNumbers/BigNumbers.d.ts → BigNumber/BigNumber.d.ts} +5 -5
  111. package/lib/components/{BigNumbers/BigNumbers.js → BigNumber/BigNumber.js} +11 -11
  112. package/lib/components/BigNumber/BigNumberSkeleton.d.ts +17 -0
  113. package/lib/components/{BigNumbers/BigNumbersSkeleton.js → BigNumber/BigNumberSkeleton.js} +15 -15
  114. package/lib/components/{BigNumbers → BigNumber}/constants.d.ts +3 -3
  115. package/lib/components/{BigNumbers → BigNumber}/constants.js +6 -6
  116. package/lib/components/BigNumber/index.d.ts +7 -0
  117. package/lib/components/Coachmark/Coachmark.js +2 -2
  118. package/lib/components/Coachmark/next/Coachmark/Coachmark.d.ts +72 -0
  119. package/lib/components/Coachmark/next/Coachmark/Coachmark.js +189 -0
  120. package/lib/components/Coachmark/next/Coachmark/CoachmarkBeacon/CoachmarkBeacon.d.ts +44 -0
  121. package/lib/components/Coachmark/next/Coachmark/CoachmarkBeacon/index.d.ts +8 -0
  122. package/lib/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubble.d.ts +38 -0
  123. package/lib/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubble.js +127 -0
  124. package/lib/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubbleHeader.d.ts +24 -0
  125. package/lib/components/Coachmark/next/Coachmark/CoachmarkBubble/CoachmarkBubbleHeader.js +27 -0
  126. package/lib/components/Coachmark/next/Coachmark/CoachmarkBubble/index.d.ts +10 -0
  127. package/lib/components/Coachmark/next/Coachmark/CoachmarkContent.d.ts +34 -0
  128. package/lib/components/Coachmark/next/Coachmark/CoachmarkContent.js +122 -0
  129. package/lib/components/Coachmark/next/Coachmark/ContentBody.d.ts +23 -0
  130. package/lib/components/Coachmark/next/Coachmark/ContentBody.js +41 -0
  131. package/lib/components/Coachmark/next/Coachmark/ContentHeader.d.ts +21 -0
  132. package/lib/components/Coachmark/next/Coachmark/ContentHeader.js +93 -0
  133. package/lib/components/Coachmark/next/Coachmark/index.d.ts +7 -0
  134. package/lib/components/CoachmarkBeacon/CoachmarkBeacon.js +0 -1
  135. package/lib/components/CoachmarkFixed/CoachmarkFixed.js +2 -2
  136. package/lib/components/CoachmarkStack/CoachmarkStack.js +2 -2
  137. package/lib/components/CoachmarkStack/CoachmarkStackHome.js +2 -2
  138. package/lib/components/ConditionBuilder/ConditionBuilderContent/ConditionBuilderContent.js +2 -1
  139. package/lib/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItem.js +30 -5
  140. package/lib/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemDate/ConditionBuilderItemDate.js +1 -1
  141. package/lib/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemNumber/ConditionBuilderItemNumber.js +11 -4
  142. package/lib/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemOption/ItemOption.js +2 -2
  143. package/lib/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemOption/ItemOptionForValueField.js +1 -1
  144. package/lib/components/ConditionBuilder/ConditionGroupBuilder/ConditionGroupBuilder.js +41 -2
  145. package/lib/components/ConditionBuilder/ConditionPreview/ConditionPreview.d.ts +3 -1
  146. package/lib/components/ConditionBuilder/ConditionPreview/ConditionPreview.js +5 -3
  147. package/lib/components/ConditionBuilder/utils/useEvent.d.ts +8 -0
  148. package/lib/components/ConditionBuilder/utils/useEvent.js +34 -0
  149. package/lib/components/ConditionBuilder/utils/useTranslations.js +1 -1
  150. package/lib/components/EditInPlace/EditInPlace.js +0 -3
  151. package/lib/components/EmptyStates/EmptyState.d.ts +2 -2
  152. package/lib/components/EmptyStates/EmptyState.js +2 -8
  153. package/lib/components/FilterPanel/FilterPanelGroup/index.d.ts +1 -0
  154. package/lib/components/InterstitialScreen/InterstitialScreen.d.ts +1 -25
  155. package/lib/components/InterstitialScreen/InterstitialScreen.js +6 -25
  156. package/lib/components/InterstitialScreen/InterstitialScreenBody.d.ts +1 -1
  157. package/lib/components/InterstitialScreen/InterstitialScreenBody.js +6 -6
  158. package/lib/components/InterstitialScreen/InterstitialScreenFooter.d.ts +1 -1
  159. package/lib/components/InterstitialScreen/InterstitialScreenFooter.js +9 -9
  160. package/lib/components/InterstitialScreen/InterstitialScreenHeader.d.ts +6 -0
  161. package/lib/components/InterstitialScreen/InterstitialScreenHeader.js +5 -5
  162. package/lib/components/InterstitialScreen/_story-assets/InterstitialScreenViewModule/InterstitialScreenViewModule.d.ts +1 -1
  163. package/lib/components/InterstitialScreen/context.d.ts +31 -0
  164. package/lib/components/InterstitialScreen/context.js +21 -0
  165. package/lib/components/InterstitialScreen/index.d.ts +3 -2
  166. package/lib/components/NotificationsPanel/NotificationsPanel.js +36 -13
  167. package/lib/components/PageHeader/PageHeader.d.ts +2 -1
  168. package/lib/components/PageHeader/PageHeader.js +2 -1
  169. package/lib/components/PageHeader/next/PageHeader.d.ts +18 -3
  170. package/lib/components/PageHeader/next/PageHeader.js +261 -7
  171. package/lib/components/PageHeader/next/context.d.ts +25 -0
  172. package/lib/components/PageHeader/next/context.js +33 -0
  173. package/lib/components/PageHeader/next/index.d.ts +3 -3
  174. package/lib/components/PageHeader/next/overflowHandler.d.ts +95 -0
  175. package/lib/components/PageHeader/next/overflowHandler.js +166 -0
  176. package/lib/components/PageHeader/next/utils.d.ts +19 -0
  177. package/lib/components/PageHeader/next/utils.js +71 -0
  178. package/lib/components/ProductiveCard/ProductiveCard.js +2 -1
  179. package/lib/components/ScrollGradient/ScrollGradient.js +1 -2
  180. package/lib/components/SidePanel/SidePanel.d.ts +4 -0
  181. package/lib/components/SidePanel/SidePanel.js +8 -2
  182. package/lib/components/Tearsheet/TearsheetShell.js +8 -5
  183. package/lib/components/TruncatedText/TruncatedText.d.ts +48 -0
  184. package/lib/components/TruncatedText/TruncatedText.js +86 -0
  185. package/lib/components/TruncatedText/index.d.ts +7 -0
  186. package/lib/components/TruncatedText/useTruncatedText.d.ts +16 -0
  187. package/lib/components/TruncatedText/useTruncatedText.js +45 -0
  188. package/lib/components/index.d.ts +3 -1
  189. package/lib/global/js/hooks/useOverflowString.d.ts +2 -2
  190. package/lib/global/js/hooks/usePortalTarget.js +2 -2
  191. package/lib/global/js/hooks/useResizeObserver.d.ts +1 -1
  192. package/lib/global/js/package-settings.d.ts +2 -1
  193. package/lib/global/js/package-settings.js +3 -2
  194. package/lib/global/js/utils/checkForOverflow.js +23 -0
  195. package/lib/global/js/utils/makeDraggable/index.d.ts +1 -0
  196. package/lib/global/js/utils/makeDraggable/makeDraggable.d.ts +19 -0
  197. package/lib/global/js/utils/makeDraggable/makeDraggable.js +93 -0
  198. package/lib/global/js/utils/makeDraggable/makeDraggable.stories.d.ts +22 -0
  199. package/lib/index.js +10 -3
  200. package/lib/node_modules/@floating-ui/core/dist/floating-ui.core.js +600 -0
  201. package/lib/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +722 -0
  202. package/lib/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js +102 -0
  203. package/lib/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +182 -0
  204. package/lib/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +164 -0
  205. package/lib/settings.d.ts +2 -1
  206. package/package.json +9 -10
  207. package/scss/components/{BigNumbers/_big-numbers.scss → BigNumber/_big-number.scss} +5 -5
  208. package/scss/components/{BigNumbers → BigNumber}/_carbon-imports.scss +3 -3
  209. package/scss/components/{BigNumbers → BigNumber}/_index-with-carbon.scss +2 -2
  210. package/scss/components/{BigNumbers → BigNumber}/_index.scss +2 -2
  211. package/scss/components/Card/_card.scss +2 -0
  212. package/scss/components/Coachmark/_bubble.scss +62 -0
  213. package/scss/components/Coachmark/_coachmark-beacon.scss +164 -0
  214. package/scss/components/Coachmark/_coachmark.scss +15 -0
  215. package/scss/components/ConditionBuilder/_condition-builder.scss +8 -0
  216. package/scss/components/PageHeader/_page-header.scss +144 -1
  217. package/scss/components/Tearsheet/_tearsheet.scss +6 -0
  218. package/scss/components/TruncatedText/_carbon-imports.scss +6 -0
  219. package/scss/components/TruncatedText/_index-with-carbon.scss +9 -0
  220. package/scss/components/TruncatedText/_index.scss +8 -0
  221. package/scss/components/TruncatedText/_truncated-text.scss +26 -0
  222. package/scss/components/_index-with-carbon.scss +3 -2
  223. package/scss/components/_index.scss +3 -2
  224. package/telemetry.yml +24 -5
  225. package/es/components/BigNumbers/BigNumbersSkeleton.d.ts +0 -17
  226. package/lib/components/BigNumbers/BigNumbersSkeleton.d.ts +0 -17
@@ -6,15 +6,21 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useRef, useState, useLayoutEffect, useMemo, useEffect, useCallback } from 'react';
9
+ import React__default, { forwardRef, useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from 'react';
10
10
  import PropTypes from '../../../_virtual/index.js';
11
11
  import cx from 'classnames';
12
- import { Grid, Column, DefinitionTooltip, unstable_Text, Tag, Popover, OperationalTag, PopoverContent, MenuButton, MenuItem, AspectRatio } from '@carbon/react';
12
+ import { Grid, Column, DefinitionTooltip, unstable_Text, IconButton, BreadcrumbItem, usePrefix, Breadcrumb, Tag, Popover, OperationalTag, PopoverContent, MenuButton, MenuItem, AspectRatio } from '@carbon/react';
13
13
  import { breakpoints } from '@carbon/layout';
14
14
  import { blockClass } from '../PageHeaderUtils.js';
15
- import { createOverflowHandler } from '@carbon/utilities';
15
+ import { createOverflowHandler } from './overflowHandler.js';
16
+ import { createOverflowHandler as createOverflowHandler$1 } from '@carbon/utilities';
16
17
  import { useOverflowItems } from '../../../global/js/hooks/useOverflowItems/useOverflowItems.js';
17
18
  import { useId } from '../../../global/js/utils/useId.js';
19
+ import { ChevronUp } from '@carbon/react/icons';
20
+ import { PageHeaderContext, usePageHeader } from './context.js';
21
+ import { getHeaderOffset, scrollableAncestor } from './utils.js';
22
+ import { pkg } from '../../../settings.js';
23
+ import { useResizeObserver } from '../../../global/js/hooks/useResizeObserver.js';
18
24
 
19
25
  /**
20
26
  * ----------
@@ -28,14 +34,91 @@ const PageHeader = /*#__PURE__*/React__default.forwardRef(function PageHeader(_r
28
34
  children,
29
35
  ...other
30
36
  } = _ref;
37
+ const [refs, setRefs] = useState({});
38
+ const tempRef = useRef(null);
39
+ const componentRef = ref ?? tempRef;
31
40
  const classNames = cx({
32
41
  [`${blockClass}`]: true,
33
42
  [`${blockClass}__next`]: true
34
43
  }, className);
35
- return /*#__PURE__*/React__default.createElement("div", _extends({
44
+
45
+ // Used to set CSS custom property with PageHeaderContent height to be used
46
+ // for sticky positioning
47
+ useResizeObserver(componentRef, () => {
48
+ if (componentRef?.current && refs?.contentRef?.current) {
49
+ const pageHeaderContentHeight = refs?.contentRef?.current?.offsetHeight;
50
+ const totalHeaderOffset = getHeaderOffset(componentRef?.current);
51
+ componentRef?.current.style.setProperty(`--${pkg.prefix}-page-header-header-top`, `${(Math.round(pageHeaderContentHeight) - totalHeaderOffset) * -1}px`);
52
+ componentRef?.current.style.setProperty(`--${pkg.prefix}-page-header-breadcrumb-top`, `${totalHeaderOffset}px`);
53
+ }
54
+ });
55
+ const [fullyCollapsed, setFullyCollapsed] = useState(false);
56
+ const [titleClipped, setTitleClipped] = useState(false);
57
+
58
+ // Intersection Observer setup, tracks if the PageHeaderContent is visible on page.
59
+ // If it is not visible, we should set fully collapsed to true so that the
60
+ // scroller button will know if it is clicked to expand rather than
61
+ // collapse the header.
62
+ useEffect(() => {
63
+ if (!refs?.contentRef || !componentRef?.current) {
64
+ return;
65
+ }
66
+ const totalHeaderOffset = getHeaderOffset(componentRef?.current);
67
+ const predefinedContentPadding = 24;
68
+ const contentObserver = new IntersectionObserver(entries => {
69
+ entries.forEach(entry => {
70
+ if (entry.target === refs?.contentRef.current) {
71
+ setFullyCollapsed(!entry.isIntersecting);
72
+ }
73
+ });
74
+ }, {
75
+ root: null,
76
+ rootMargin: `${(predefinedContentPadding + totalHeaderOffset + 40) * -1}px 0px 0px 0px`,
77
+ threshold: 0.1
78
+ });
79
+ if (!refs?.titleRef?.current) {
80
+ return;
81
+ }
82
+ const totalTitleHeight = refs?.titleRef.current.offsetHeight;
83
+ const titleObserver = new IntersectionObserver(entries => {
84
+ entries.forEach(entry => {
85
+ if (entry.target === refs?.titleRef.current) {
86
+ setTitleClipped(!entry.isIntersecting);
87
+ }
88
+ });
89
+ }, {
90
+ root: null,
91
+ rootMargin: `${(predefinedContentPadding + totalTitleHeight + totalHeaderOffset + 24) * -1}px 0px 0px 0px`,
92
+ threshold: 0.1
93
+ });
94
+ if (refs?.contentRef.current) {
95
+ contentObserver.observe(refs?.contentRef.current);
96
+ }
97
+ if (refs?.titleRef.current) {
98
+ titleObserver.observe(refs?.titleRef.current);
99
+ }
100
+ return () => {
101
+ if (!refs?.contentRef?.current) {
102
+ return;
103
+ }
104
+ contentObserver.unobserve(refs?.contentRef.current);
105
+ if (!refs?.titleRef?.current) {
106
+ return;
107
+ }
108
+ contentObserver.unobserve(refs?.titleRef.current);
109
+ };
110
+ }, [refs, componentRef]);
111
+ return /*#__PURE__*/React__default.createElement(PageHeaderContext.Provider, {
112
+ value: {
113
+ refs,
114
+ setRefs,
115
+ fullyCollapsed,
116
+ titleClipped
117
+ }
118
+ }, /*#__PURE__*/React__default.createElement("div", _extends({
36
119
  className: classNames,
37
- ref: ref
38
- }, other), children);
120
+ ref: componentRef
121
+ }, other), children));
39
122
  });
40
123
  PageHeader.displayName = 'PageHeader';
41
124
 
@@ -102,10 +185,25 @@ const PageHeaderContent = /*#__PURE__*/React__default.forwardRef(function PageHe
102
185
  pageActions,
103
186
  ...other
104
187
  } = _ref3;
188
+ const contentRef = useRef(null);
189
+ const componentRef = ref ?? contentRef;
190
+ const {
191
+ setRefs
192
+ } = usePageHeader();
105
193
  const classNames = cx({
106
194
  [`${blockClass}__content`]: true
107
195
  }, className);
108
196
  const titleRef = useRef(null);
197
+ useEffect(() => {
198
+ if (componentRef?.current) {
199
+ setRefs(prev => ({
200
+ ...prev,
201
+ contentRef: componentRef,
202
+ titleRef
203
+ }));
204
+ }
205
+ // eslint-disable-next-line react-hooks/exhaustive-deps
206
+ }, []);
109
207
  const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
110
208
  const isEllipsisActive = element => {
111
209
  setIsEllipsisApplied(element.offsetHeight < element.scrollHeight);
@@ -116,7 +214,7 @@ const PageHeaderContent = /*#__PURE__*/React__default.forwardRef(function PageHe
116
214
  }, [title]);
117
215
  return /*#__PURE__*/React__default.createElement("div", _extends({
118
216
  className: classNames,
119
- ref: ref
217
+ ref: componentRef
120
218
  }, other), /*#__PURE__*/React__default.createElement(Grid, null, /*#__PURE__*/React__default.createElement(Column, {
121
219
  lg: 16,
122
220
  md: 8,
@@ -209,7 +307,7 @@ const PageHeaderContentPageActions = _ref4 => {
209
307
  if (!containerRef.current || !Array.isArray(actions)) {
210
308
  return;
211
309
  }
212
- createOverflowHandler({
310
+ createOverflowHandler$1({
213
311
  container: containerRef.current,
214
312
  // exclude the hidden menu button from children
215
313
  maxVisibleItems: containerRef.current.children.length - 1,
@@ -358,11 +456,16 @@ const PageHeaderTabBar = /*#__PURE__*/React__default.forwardRef(function PageHea
358
456
  className,
359
457
  children,
360
458
  tags = [],
459
+ scroller,
361
460
  ...other
362
461
  } = _ref7;
363
462
  const classNames = cx({
364
463
  [`${blockClass}__tab-bar`]: true
365
464
  }, className);
465
+ const renderScroller = () => scroller && /*#__PURE__*/React__default.createElement("div", {
466
+ className: `${pkg.prefix}--page-header--scroller-button-container`
467
+ }, scroller);
468
+
366
469
  // Early return if no tags are provided
367
470
  if (!tags.length) {
368
471
  return /*#__PURE__*/React__default.createElement("div", _extends({
@@ -372,7 +475,7 @@ const PageHeaderTabBar = /*#__PURE__*/React__default.forwardRef(function PageHea
372
475
  lg: 16,
373
476
  md: 8,
374
477
  sm: 4
375
- }, children)));
478
+ }, children, renderScroller())));
376
479
  }
377
480
  const [openPopover, setOpenPopover] = useState(false);
378
481
  const tagSize = tags[0]?.size || 'md';
@@ -447,10 +550,149 @@ const PageHeaderTabBar = /*#__PURE__*/React__default.forwardRef(function PageHea
447
550
  md: 8,
448
551
  sm: 4
449
552
  }, /*#__PURE__*/React__default.createElement("div", {
450
- className: `${blockClass}__tab-bar--tablist`
451
- }, children, tags.length > 0 && renderTags()))));
553
+ className: cx(`${blockClass}__tab-bar--tablist`, {
554
+ [`${pkg.prefix}--page-header__tab-bar--with-scroller`]: !!scroller
555
+ })
556
+ }, children, tags.length > 0 && renderTags(), renderScroller()))));
452
557
  });
453
558
  PageHeaderTabBar.displayName = 'PageHeaderTabBar';
559
+ const PageHeaderScrollButton = /*#__PURE__*/React__default.forwardRef(function PageHeaderExpander(_ref8, ref) {
560
+ let {
561
+ className,
562
+ children,
563
+ label,
564
+ onClick,
565
+ collapseText = 'Collapse',
566
+ expandText = 'Expand',
567
+ ...other
568
+ } = _ref8;
569
+ const {
570
+ refs,
571
+ fullyCollapsed
572
+ } = usePageHeader();
573
+ const handleScroller = isFullyCollapsed => {
574
+ if (!refs?.contentRef?.current) {
575
+ return;
576
+ }
577
+ const scrollableTarget = scrollableAncestor(refs?.contentRef.current);
578
+
579
+ // Page header content is not fully collapsed
580
+ if (!isFullyCollapsed) {
581
+ const pageHeaderContentHeight = refs?.contentRef.current.offsetHeight;
582
+ scrollableTarget?.scrollTo({
583
+ top: pageHeaderContentHeight,
584
+ // headerTopValue, check if breadcrumb bar is included
585
+ behavior: 'smooth'
586
+ });
587
+ } else {
588
+ // Page header content is fully collapsed
589
+ scrollableTarget?.scrollTo({
590
+ top: 0,
591
+ behavior: 'smooth'
592
+ });
593
+ }
594
+ };
595
+ return /*#__PURE__*/React__default.createElement(IconButton, _extends({
596
+ ref: ref,
597
+ label: fullyCollapsed ? expandText : collapseText,
598
+ size: "md",
599
+ kind: "ghost",
600
+ autoAlign: true
601
+ }, other, {
602
+ onClick: event => {
603
+ onClick?.(event);
604
+ handleScroller(!!fullyCollapsed);
605
+ },
606
+ className: cx(className, `${pkg.prefix}--page-header--scroller-button`)
607
+ }), /*#__PURE__*/React__default.createElement(ChevronUp, {
608
+ className: cx(`${pkg.prefix}--page-header--scroller-button-icon`, {
609
+ [`${pkg.prefix}--page-header--scroller-button-icon-collapsed`]: fullyCollapsed
610
+ })
611
+ }));
612
+ });
613
+ const PageHeaderTitleBreadcrumb = /*#__PURE__*/forwardRef((_ref9, ref) => {
614
+ let {
615
+ className,
616
+ children,
617
+ ...other
618
+ } = _ref9;
619
+ const {
620
+ titleClipped,
621
+ refs
622
+ } = usePageHeader();
623
+ return /*#__PURE__*/React__default.createElement(BreadcrumbItem, _extends({
624
+ ref: ref,
625
+ isCurrentPage: true
626
+ }, other, {
627
+ className: cx(className, `${pkg.prefix}--page-header-title-breadcrumb`, {
628
+ [`${pkg.prefix}--page-header-title-breadcrumb-show`]: titleClipped && refs?.titleRef
629
+ })
630
+ }), children);
631
+ });
632
+ // This component is a wrapper for the Breadcrumb, and renders breadcrumb items as children
633
+ // including the overflow breadcrumb item. The overflowHandler determines what elements
634
+ // are visible and hidden and passes the hidden elements back to the render prop used
635
+ // to display the overflow breadcrumb
636
+ const PageHeaderBreadcrumbOverflow = /*#__PURE__*/forwardRef((_ref10, ref) => {
637
+ let {
638
+ renderOverflowBreadcrumb,
639
+ className,
640
+ children,
641
+ ...other
642
+ } = _ref10;
643
+ const [hiddenBreadcrumbs, setHiddenBreadcrumbs] = React__default.useState([]);
644
+ const fallbackRef = useRef(null);
645
+ const componentRef = ref ?? fallbackRef;
646
+
647
+ // Initialize overflow resize handler
648
+ const carbonPrefix = usePrefix();
649
+ useEffect(() => {
650
+ if (!componentRef) {
651
+ return;
652
+ }
653
+ const breadcrumbList = componentRef?.current.querySelector(`.${carbonPrefix}--breadcrumb`);
654
+ createOverflowHandler({
655
+ container: breadcrumbList,
656
+ onChange: (_, hidden) => {
657
+ setHiddenBreadcrumbs(hidden);
658
+ }
659
+ });
660
+ // Don't want ref or carbon prefix in dependency array
661
+ // eslint-disable-next-line react-hooks/exhaustive-deps
662
+ }, []);
663
+ const renderChildren = () => {
664
+ // Only BreadcrumbItems and TitleBreadcrumbs are valid children
665
+ const filteredBreadcrumbs = React__default.Children.toArray(children).filter(child => {
666
+ if (/*#__PURE__*/React__default.isValidElement(child)) {
667
+ return child.type === BreadcrumbItem || PageHeaderTitleBreadcrumb;
668
+ }
669
+ });
670
+ // We need to clone the renderProp for the overflow breadcrumb item
671
+ // to place it before the title breadcrumb according to the design
672
+ if (filteredBreadcrumbs) {
673
+ const overflowBreadcrumb = renderOverflowBreadcrumb?.(hiddenBreadcrumbs);
674
+ // If no overflow breadcrumb provided, return here with the rest of the children
675
+ if (!overflowBreadcrumb) {
676
+ return children;
677
+ }
678
+ const clonedTitleBreadcrumb = /*#__PURE__*/React__default.cloneElement(overflowBreadcrumb, {
679
+ key: 'cloned overflow breadcrumb item',
680
+ 'data-fixed': true,
681
+ className: cx(`${pkg.prefix}--page-header-breadcrumb-overflow-item`, {
682
+ [`${pkg.prefix}--page-header-overflow-breadcrumb-item-with-items`]: hiddenBreadcrumbs.length
683
+ })
684
+ });
685
+ const clonedChildren = [...filteredBreadcrumbs];
686
+ clonedChildren.splice(filteredBreadcrumbs.length - 1, 0, clonedTitleBreadcrumb); // second to last position
687
+ return clonedChildren;
688
+ }
689
+ return children;
690
+ };
691
+ return /*#__PURE__*/React__default.createElement(Breadcrumb, _extends({
692
+ className: cx(className, `${pkg.prefix}--page-header-breadcrumb-overflow`),
693
+ ref: componentRef
694
+ }, other), renderChildren());
695
+ });
454
696
 
455
697
  /**
456
698
  * -------
@@ -471,5 +713,11 @@ const HeroImage = PageHeaderHeroImage;
471
713
  HeroImage.displayName = 'PageHeaderHeroImage';
472
714
  const TabBar = PageHeaderTabBar;
473
715
  TabBar.displayName = 'PageHeaderTabBar';
716
+ const ScrollButton = PageHeaderScrollButton;
717
+ ScrollButton.displayName = 'PageHeaderScrollButton';
718
+ const TitleBreadcrumb = PageHeaderTitleBreadcrumb;
719
+ TitleBreadcrumb.displayName = 'PageHeaderTitleBreadcrumb';
720
+ const BreadcrumbOverflow = PageHeaderBreadcrumbOverflow;
721
+ BreadcrumbOverflow.displayName = 'PageHeaderBreadcrumbOverflow';
474
722
 
475
- export { BreadcrumbBar, Content, ContentPageActions, ContentText, HeroImage, PageHeader, PageHeaderBreadcrumbBar, PageHeaderContent, PageHeaderContentPageActions, PageHeaderContentText, PageHeaderHeroImage, PageHeaderTabBar, Root, TabBar };
723
+ export { BreadcrumbBar, BreadcrumbOverflow, Content, ContentPageActions, ContentText, HeroImage, PageHeader, PageHeaderBreadcrumbBar, PageHeaderBreadcrumbOverflow, PageHeaderContent, PageHeaderContentPageActions, PageHeaderContentText, PageHeaderHeroImage, PageHeaderScrollButton, PageHeaderTabBar, PageHeaderTitleBreadcrumb, Root, ScrollButton, TabBar, TitleBreadcrumb };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025, 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 { RefObject } from 'react';
8
+ /**
9
+ * -------------
10
+ * Context setup
11
+ * -------------
12
+ */
13
+ export type PageHeaderRefs = {
14
+ contentRef?: RefObject<HTMLDivElement | null>;
15
+ titleRef?: RefObject<HTMLHeadingElement | null>;
16
+ };
17
+ type PageHeaderContextType = {
18
+ refs?: PageHeaderRefs;
19
+ setRefs: React.Dispatch<React.SetStateAction<PageHeaderRefs>>;
20
+ fullyCollapsed?: boolean;
21
+ titleClipped?: boolean;
22
+ };
23
+ export declare const PageHeaderContext: import("react").Context<PageHeaderContextType | undefined>;
24
+ export declare function usePageHeader(): PageHeaderContextType;
25
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright IBM Corp. 2020, 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
+
8
+ import { createContext, useContext } from 'react';
9
+
10
+ /**
11
+ * -------------
12
+ * Context setup
13
+ * -------------
14
+ */
15
+
16
+ const PageHeaderContext = /*#__PURE__*/createContext({
17
+ fullyCollapsed: false,
18
+ setRefs: () => {},
19
+ refs: {},
20
+ titleClipped: false
21
+ });
22
+ function usePageHeader() {
23
+ const context = useContext(PageHeaderContext);
24
+ if (!context) {
25
+ throw new Error('Page header context was not provided or hook was used outside of the Page header component.');
26
+ }
27
+ return context;
28
+ }
29
+
30
+ export { PageHeaderContext, usePageHeader };
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Copyright IBM Corp. 2025
2
+ * Copyright IBM Corp. 2025, 2025
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- export { PageHeader, PageHeaderBreadcrumbBar, PageHeaderContent, PageHeaderContentPageActions, PageHeaderContentText, PageHeaderTabBar, PageHeaderHeroImage, Root, BreadcrumbBar, Content, ContentPageActions, ContentText, TabBar, HeroImage, } from './PageHeader';
8
- export type { PageHeaderProps, PageHeaderBreadcrumbBarProps, PageHeaderContentProps, PageHeaderContentPageActionsProps, PageHeaderContentTextProps, PageHeaderTabBarProps, PageHeaderHeroImageProps, } from './PageHeader';
7
+ export { PageHeader, PageHeaderBreadcrumbBar, PageHeaderContent, PageHeaderContentPageActions, PageHeaderContentText, PageHeaderTabBar, PageHeaderHeroImage, PageHeaderScrollButton, PageHeaderTitleBreadcrumb, PageHeaderBreadcrumbOverflow, Root, BreadcrumbBar, Content, ContentPageActions, ContentText, TabBar, HeroImage, ScrollButton, TitleBreadcrumb, BreadcrumbOverflow, } from './PageHeader';
8
+ export type { PageHeaderProps, PageHeaderBreadcrumbBarProps, PageHeaderContentProps, PageHeaderContentPageActionsProps, PageHeaderContentTextProps, PageHeaderTabBarProps, PageHeaderHeroImageProps, PageHeaderScrollButtonProps, } from './PageHeader';
@@ -0,0 +1,95 @@
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
+ /**
8
+ * Calculates the size (width or height) of a given HTML element.
9
+ *
10
+ * This function performs an expensive calculation by temporarily changing the
11
+ * display style of the element if it is not currently visible. It then uses
12
+ * `getBoundingClientRect` to retrieve the size of the element.
13
+ *
14
+ * @param el - The HTML element whose size is to be calculated.
15
+ * @param dimension - The dimension to measure ('width' or 'height').
16
+ * @returns The size of the element in pixels. Returns 0 if the element is not provided.
17
+ */
18
+ export declare function getSize(el: HTMLElement, dimension: 'width' | 'height'): number;
19
+ /**
20
+ * Options for updating the overflow handler.
21
+ * Determines which items should be visible and which should be hidden
22
+ * based on the container size, item sizes, and other constraints.
23
+ */
24
+ export interface UpdateOverflowHandlerOptions {
25
+ /** The container element that holds the items. */
26
+ container: HTMLElement;
27
+ /** An array of item elements to be managed for overflow. */
28
+ items: HTMLElement[];
29
+ /** An element that represents the offset, which can be shown or hidden based on overflow. Identified by `data-offset` attribute. */
30
+ offset: HTMLElement;
31
+ /** An array of sizes corresponding to each item in the `items` array. */
32
+ sizes: number[];
33
+ /** An array of sizes corresponding to each item in the fixed items array. */
34
+ fixedSizes: number[];
35
+ /** The size of the offset element. */
36
+ offsetSize: number;
37
+ /** The maximum number of items that can be visible at once. If undefined, all items can be visible. */
38
+ maxVisibleItems?: number;
39
+ /** The dimension to consider for overflow, either 'width' or 'height'. */
40
+ dimension: 'width' | 'height';
41
+ /** A callback function that is called when the visible or hidden items change. */
42
+ onChange: (visibleItems: HTMLElement[], hiddenItems: HTMLElement[]) => void;
43
+ /** An array of previously hidden items to compare against the new hidden items. */
44
+ previousHiddenItems?: HTMLElement[];
45
+ }
46
+ /**
47
+ * Updates the overflow handler by determining which items should be visible and which should be hidden.
48
+ *
49
+ * @param options - Configuration options for updating the overflow handler.
50
+ * @param options.container - Container for overflowing
51
+ * @param options.items - Child elements within container
52
+ * @param options.offset - Children with data-offset attribute
53
+ * @param options.sizes - Sizes of child elements
54
+ * @param options.fixedSizes - Fixed sizes of child elements with data-fixed attribute
55
+ * @param options.offsetSize - Total offset size
56
+ * @param options.maxVisibleItems - Max visible items
57
+ * @param options.dimension - width | height used to measure overflow
58
+ * @param options.onChange - onChange callback
59
+ * @param options.previousHiddenItems - Array of previously hidden items
60
+ * @returns An array of hidden items after the update.
61
+ */
62
+ export declare function updateOverflowHandler({ container, items, offset, sizes, fixedSizes, offsetSize, maxVisibleItems, dimension, onChange, previousHiddenItems, }: UpdateOverflowHandlerOptions): HTMLElement[];
63
+ /**
64
+ * Options for initializing an overflow handler.
65
+ */
66
+ export interface OverflowHandlerOptions {
67
+ /**
68
+ * The container element that holds the items. along with offset item
69
+ */
70
+ container: HTMLElement;
71
+ /**
72
+ * Maximum number of visible items. If provided, only this number of items will be shown.
73
+ */
74
+ maxVisibleItems?: number;
75
+ /**
76
+ * Callback function invoked when the visible and hidden items change.
77
+ * @param visibleItems - The array of items that are currently visible.
78
+ * @param hiddenItems - The array of items that are currently hidden.
79
+ */
80
+ onChange: (visibleItems: HTMLElement[], hiddenItems: HTMLElement[]) => void;
81
+ /**
82
+ * The dimension to consider for overflow calculations. Defaults to 'width'.
83
+ */
84
+ dimension?: 'width' | 'height';
85
+ }
86
+ /**
87
+ * Represents an instance of an overflow handler.
88
+ */
89
+ export interface OverflowHandler {
90
+ /**
91
+ * Disconnects the overflow handler, cleaning up any event listeners or resources.
92
+ */
93
+ disconnect: () => void;
94
+ }
95
+ export declare function createOverflowHandler({ container, maxVisibleItems, onChange, dimension, }: OverflowHandlerOptions): OverflowHandler;
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Copyright IBM Corp. 2020, 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
+
8
+ /**
9
+ * Calculates the size (width or height) of a given HTML element.
10
+ *
11
+ * This function performs an expensive calculation by temporarily changing the
12
+ * display style of the element if it is not currently visible. It then uses
13
+ * `getBoundingClientRect` to retrieve the size of the element.
14
+ *
15
+ * @param el - The HTML element whose size is to be calculated.
16
+ * @param dimension - The dimension to measure ('width' or 'height').
17
+ * @returns The size of the element in pixels. Returns 0 if the element is not provided.
18
+ */
19
+ function getSize(el, dimension) {
20
+ if (!el) {
21
+ return 0;
22
+ }
23
+ const originalDisplay = el.style.display;
24
+ if (!el.offsetParent && getComputedStyle(el).display === 'none') {
25
+ el.style.display = 'inline-block';
26
+ }
27
+ let size = el.getBoundingClientRect()[dimension];
28
+ el.style.display = originalDisplay;
29
+ const computedStyles = getComputedStyle(el);
30
+ size = dimension === 'width' ? size + parseInt(computedStyles.paddingLeft) + parseInt(computedStyles.paddingRight) + parseInt(computedStyles.marginLeft) + parseInt(computedStyles.marginRight) : size + parseInt(computedStyles.paddingTop) + parseInt(computedStyles.paddingBottom) + parseInt(computedStyles.marginTop) + parseInt(computedStyles.marginBottom);
31
+ return size;
32
+ }
33
+
34
+ /**
35
+ * Options for updating the overflow handler.
36
+ * Determines which items should be visible and which should be hidden
37
+ * based on the container size, item sizes, and other constraints.
38
+ */
39
+
40
+ /**
41
+ * Updates the overflow handler by determining which items should be visible and which should be hidden.
42
+ *
43
+ * @param options - Configuration options for updating the overflow handler.
44
+ * @param options.container - Container for overflowing
45
+ * @param options.items - Child elements within container
46
+ * @param options.offset - Children with data-offset attribute
47
+ * @param options.sizes - Sizes of child elements
48
+ * @param options.fixedSizes - Fixed sizes of child elements with data-fixed attribute
49
+ * @param options.offsetSize - Total offset size
50
+ * @param options.maxVisibleItems - Max visible items
51
+ * @param options.dimension - width | height used to measure overflow
52
+ * @param options.onChange - onChange callback
53
+ * @param options.previousHiddenItems - Array of previously hidden items
54
+ * @returns An array of hidden items after the update.
55
+ */
56
+ function updateOverflowHandler(_ref) {
57
+ let {
58
+ container,
59
+ items,
60
+ offset,
61
+ sizes,
62
+ fixedSizes,
63
+ offsetSize,
64
+ maxVisibleItems,
65
+ dimension,
66
+ onChange,
67
+ previousHiddenItems = []
68
+ } = _ref;
69
+ const containerSize = dimension === 'width' ? container.clientWidth : container.clientHeight;
70
+ let visibleItems = [];
71
+ let hiddenItems = [];
72
+ const totalSize = sizes.reduce((sum, size) => sum + size, 0);
73
+ const totalFixedSize = fixedSizes.reduce((sum, size) => sum + size, 0);
74
+ if (totalSize + totalFixedSize <= containerSize) {
75
+ visibleItems = maxVisibleItems ? items.slice(0, maxVisibleItems) : [...items];
76
+ hiddenItems = maxVisibleItems ? items.slice(maxVisibleItems) : [];
77
+ } else {
78
+ const available = containerSize - offsetSize;
79
+ let accumulated = 0;
80
+ for (let i = 0; i < items.length; i++) {
81
+ const size = sizes[i];
82
+ if (accumulated + size + totalFixedSize <= available && (!maxVisibleItems || visibleItems.length < maxVisibleItems)) {
83
+ visibleItems.push(items[i]);
84
+ accumulated += size;
85
+ } else {
86
+ hiddenItems.push(items[i]);
87
+ }
88
+ }
89
+ }
90
+ if (previousHiddenItems.length === hiddenItems.length && previousHiddenItems.every((item, index) => item === hiddenItems[index])) {
91
+ return previousHiddenItems;
92
+ }
93
+ visibleItems.forEach(item => item.removeAttribute('data-hidden'));
94
+ hiddenItems.forEach(item => item.setAttribute('data-hidden', ''));
95
+ if (offset) {
96
+ offset.toggleAttribute('data-hidden', hiddenItems.length === 0);
97
+ }
98
+ onChange(visibleItems, hiddenItems);
99
+ return hiddenItems;
100
+ }
101
+
102
+ /**
103
+ * Options for initializing an overflow handler.
104
+ */
105
+
106
+ /**
107
+ * Represents an instance of an overflow handler.
108
+ */
109
+
110
+ function createOverflowHandler(_ref2) {
111
+ let {
112
+ container,
113
+ maxVisibleItems,
114
+ onChange,
115
+ dimension = 'width'
116
+ } = _ref2;
117
+ // Error handling
118
+ if (!(container instanceof HTMLElement)) {
119
+ throw new Error('container must be an HTMLElement');
120
+ }
121
+ if (typeof onChange !== 'function') {
122
+ throw new Error('onChange must be a function');
123
+ }
124
+ if (maxVisibleItems !== undefined && (!Number.isInteger(maxVisibleItems) || maxVisibleItems <= 0)) {
125
+ throw new Error('maxVisibleItems must be a positive integer');
126
+ }
127
+ const children = Array.from(container.children);
128
+ const offset = children.find(item => item.hasAttribute('data-offset'));
129
+ const fixedItems = children.filter(item => item.hasAttribute('data-fixed'));
130
+ const items = children.filter(item => item !== offset && !fixedItems.includes(item));
131
+ const fixedSizes = fixedItems.map(item => getSize(item, dimension));
132
+ const sizes = items.map(item => getSize(item, dimension));
133
+ const offsetSize = getSize(offset, dimension);
134
+ let previousHiddenItems = [];
135
+ function update() {
136
+ previousHiddenItems = updateOverflowHandler({
137
+ container,
138
+ items,
139
+ offset,
140
+ sizes,
141
+ fixedSizes,
142
+ offsetSize,
143
+ maxVisibleItems,
144
+ dimension,
145
+ onChange,
146
+ previousHiddenItems
147
+ });
148
+ }
149
+ const resizeObserver = new ResizeObserver(() => {
150
+ requestAnimationFrame(update);
151
+ });
152
+ resizeObserver.observe(container);
153
+ requestAnimationFrame(update); // Initial update
154
+
155
+ return {
156
+ disconnect() {
157
+ resizeObserver.disconnect();
158
+ }
159
+ };
160
+ }
161
+
162
+ export { createOverflowHandler, getSize, updateOverflowHandler };