@atlaskit/navigation-system 11.0.0 → 11.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/entry-points/layout/chat-panel.js +12 -0
  3. package/dist/cjs/entry-points/layout/layout-sizing.js +44 -0
  4. package/dist/cjs/ui/page-layout/calculate-layout-area-states.js +179 -0
  5. package/dist/cjs/ui/page-layout/chat-panel.compiled.css +27 -0
  6. package/dist/cjs/ui/page-layout/chat-panel.js +216 -0
  7. package/dist/cjs/ui/page-layout/constants.js +6 -1
  8. package/dist/cjs/ui/page-layout/layout-area-sizing-context.js +13 -0
  9. package/dist/cjs/ui/page-layout/layout-area-sizing-provider.js +304 -0
  10. package/dist/cjs/ui/page-layout/layout-area-state-contexts.js +13 -0
  11. package/dist/cjs/ui/page-layout/main/main.js +11 -2
  12. package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +73 -7
  13. package/dist/cjs/ui/page-layout/panel-splitter/provider.js +7 -1
  14. package/dist/cjs/ui/page-layout/resolve-layout-width.js +13 -0
  15. package/dist/cjs/ui/page-layout/ribbon.js +1 -0
  16. package/dist/cjs/ui/page-layout/root.compiled.css +4 -2
  17. package/dist/cjs/ui/page-layout/root.js +10 -4
  18. package/dist/cjs/ui/page-layout/side-nav/side-nav.compiled.css +2 -1
  19. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +152 -14
  20. package/dist/cjs/ui/page-layout/use-layout-area-sizing.js +73 -0
  21. package/dist/cjs/ui/page-layout/use-layout-main-sizing.js +15 -0
  22. package/dist/cjs/ui/page-layout/use-occupied-layout-width.js +111 -0
  23. package/dist/es2019/entry-points/layout/chat-panel.js +1 -0
  24. package/dist/es2019/entry-points/layout/layout-sizing.js +3 -0
  25. package/dist/es2019/ui/page-layout/calculate-layout-area-states.js +128 -0
  26. package/dist/es2019/ui/page-layout/chat-panel.compiled.css +27 -0
  27. package/dist/es2019/ui/page-layout/chat-panel.js +199 -0
  28. package/dist/es2019/ui/page-layout/constants.js +5 -0
  29. package/dist/es2019/ui/page-layout/layout-area-sizing-context.js +8 -0
  30. package/dist/es2019/ui/page-layout/layout-area-sizing-provider.js +279 -0
  31. package/dist/es2019/ui/page-layout/layout-area-state-contexts.js +7 -0
  32. package/dist/es2019/ui/page-layout/main/main.js +10 -2
  33. package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +68 -8
  34. package/dist/es2019/ui/page-layout/panel-splitter/provider.js +7 -1
  35. package/dist/es2019/ui/page-layout/resolve-layout-width.js +7 -0
  36. package/dist/es2019/ui/page-layout/ribbon.js +1 -0
  37. package/dist/es2019/ui/page-layout/root.compiled.css +4 -2
  38. package/dist/es2019/ui/page-layout/root.js +10 -4
  39. package/dist/es2019/ui/page-layout/side-nav/side-nav.compiled.css +2 -1
  40. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +142 -14
  41. package/dist/es2019/ui/page-layout/use-layout-area-sizing.js +58 -0
  42. package/dist/es2019/ui/page-layout/use-layout-main-sizing.js +7 -0
  43. package/dist/es2019/ui/page-layout/use-occupied-layout-width.js +67 -0
  44. package/dist/esm/entry-points/layout/chat-panel.js +1 -0
  45. package/dist/esm/entry-points/layout/layout-sizing.js +3 -0
  46. package/dist/esm/ui/page-layout/calculate-layout-area-states.js +173 -0
  47. package/dist/esm/ui/page-layout/chat-panel.compiled.css +27 -0
  48. package/dist/esm/ui/page-layout/chat-panel.js +207 -0
  49. package/dist/esm/ui/page-layout/constants.js +5 -0
  50. package/dist/esm/ui/page-layout/layout-area-sizing-context.js +8 -0
  51. package/dist/esm/ui/page-layout/layout-area-sizing-provider.js +295 -0
  52. package/dist/esm/ui/page-layout/layout-area-state-contexts.js +7 -0
  53. package/dist/esm/ui/page-layout/main/main.js +11 -2
  54. package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +74 -8
  55. package/dist/esm/ui/page-layout/panel-splitter/provider.js +7 -1
  56. package/dist/esm/ui/page-layout/resolve-layout-width.js +7 -0
  57. package/dist/esm/ui/page-layout/ribbon.js +1 -0
  58. package/dist/esm/ui/page-layout/root.compiled.css +4 -2
  59. package/dist/esm/ui/page-layout/root.js +10 -4
  60. package/dist/esm/ui/page-layout/side-nav/side-nav.compiled.css +2 -1
  61. package/dist/esm/ui/page-layout/side-nav/side-nav.js +153 -15
  62. package/dist/esm/ui/page-layout/use-layout-area-sizing.js +67 -0
  63. package/dist/esm/ui/page-layout/use-layout-main-sizing.js +9 -0
  64. package/dist/esm/ui/page-layout/use-occupied-layout-width.js +105 -0
  65. package/dist/types/entry-points/layout/chat-panel.d.ts +1 -0
  66. package/dist/types/entry-points/layout/layout-sizing.d.ts +4 -0
  67. package/dist/types/ui/page-layout/calculate-layout-area-states.d.ts +20 -0
  68. package/dist/types/ui/page-layout/chat-panel.d.ts +48 -0
  69. package/dist/types/ui/page-layout/constants.d.ts +4 -0
  70. package/dist/types/ui/page-layout/layout-area-sizing-context.d.ts +55 -0
  71. package/dist/types/ui/page-layout/layout-area-sizing-provider.d.ts +5 -0
  72. package/dist/types/ui/page-layout/layout-area-state-contexts.d.ts +3 -0
  73. package/dist/types/ui/page-layout/main/main.d.ts +5 -1
  74. package/dist/types/ui/page-layout/panel-splitter/panel-splitter-context.d.ts +15 -1
  75. package/dist/types/ui/page-layout/panel-splitter/provider.d.ts +1 -1
  76. package/dist/types/ui/page-layout/resolve-layout-width.d.ts +2 -0
  77. package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +11 -2
  78. package/dist/types/ui/page-layout/use-layout-area-sizing.d.ts +12 -0
  79. package/dist/types/ui/page-layout/use-layout-main-sizing.d.ts +2 -0
  80. package/dist/types/ui/page-layout/use-occupied-layout-width.d.ts +8 -0
  81. package/layout/chat-panel/package.json +10 -0
  82. package/layout/layout-sizing/package.json +10 -0
  83. package/package.json +11 -3
@@ -21,10 +21,13 @@ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/el
21
21
  import { useSkipLinkInternal } from '../../../context/skip-links/use-skip-link-internal';
22
22
  import { TopNavStartElement } from '../../../context/top-nav-start/top-nav-start-element';
23
23
  import { useIsFhsEnabled } from '../../fhs-rollout/use-is-fhs-enabled';
24
- import { UNSAFE_sideNavLayoutVar, openLayerObserverSideNavNamespace, openLayerObserverTopNavStartNamespace, sideNavLiveWidthVar, sideNavPanelSplitterId, sideNavVar } from '../constants';
24
+ import { UNSAFE_sideNavLayoutVar, mainMinimumWidthVar, openLayerObserverSideNavNamespace, openLayerObserverTopNavStartNamespace, sideNavLiveWidthVar, sideNavPanelSplitterId, sideNavVar } from '../constants';
25
25
  import { DangerouslyHoistCssVarToDocumentRoot } from '../dangerously-hoist-css-var-to-document-root';
26
26
  import { DangerouslyHoistSlotSizes } from '../hoist-slot-sizes-context';
27
+ import { convertResizeBoundToPixels } from '../panel-splitter/convert-resize-bound-to-pixels';
27
28
  import { PanelSplitterProvider } from '../panel-splitter/provider';
29
+ import { resolveLayoutWidth } from '../resolve-layout-width';
30
+ import { useLayoutAreaSizing } from '../use-layout-area-sizing';
28
31
  import { useLayoutId } from '../use-layout-id';
29
32
  import { useResizingWidthCssVarOnRootElement } from '../use-resizing-width-css-var-on-root-element';
30
33
  import { useSafeDefaultWidth } from '../use-safe-default-width';
@@ -44,12 +47,11 @@ var panelSplitterResizingVar = '--n_snvRsz';
44
47
  // Used to share the side nav width with the panel splitter, which is rendered outside the side nav element
45
48
  // but positioned to stay at its right edge.
46
49
  var sideNavClampedWidthVar = '--n_snvW';
47
- var widthResizeBounds = {
48
- min: '240px',
49
- max: '50vw'
50
- };
51
- function getResizeBounds() {
52
- return widthResizeBounds;
50
+ var fallbackMinWidth = '240px';
51
+ function getPixelCustomProperty(element, propertyName, fallback) {
52
+ var raw = getComputedStyle(element).getPropertyValue(propertyName).trim();
53
+ var value = Number.parseFloat(raw);
54
+ return Number.isFinite(value) ? resolveLayoutWidth(raw.endsWith('vw') ? "".concat(value, "vw") : value, window.innerWidth) : fallback;
53
55
  }
54
56
 
55
57
  /**
@@ -63,6 +65,8 @@ var panelSplitterPortalTargetStyles = {
63
65
  };
64
66
  var styles = {
65
67
  root: "_191wglyw _t51zglyw _bfhk1bhr _16qs130s _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5clia51 _4ap3vuon _scbpglyw _89fi1b6c",
68
+ chatPanelSizing: "_1bsbhc79",
69
+ managedOverlay: "_cpcf1gzg _6kttglyw _w8v11bhr _1jug130s",
66
70
  flyoutOpen: "_qiln1gzg _p5clglyw _4ap31bhr _scbp130s _139f8iot _1tpvfnf5 _sylc1a5r _oyeijq3t",
67
71
  flyoutAnimateClosed: "_1e0cglyw _qiln1gzg _139f8iot _1tpvfnf5 _sylc1a5r _1uwsjq3t",
68
72
  animationRTLSupport: "_15yekb7n _65m41mrw",
@@ -112,11 +116,14 @@ export var onPeekStartDelayMs = 500;
112
116
  * context value.
113
117
  */
114
118
  function SideNavInternal(_ref) {
115
- var _sideNavState$lastTri;
119
+ var _managedSizing$mode, _managedSizing$width, _sideNavState$lastTri;
116
120
  var children = _ref.children,
117
121
  defaultCollapsed = _ref.defaultCollapsed,
118
122
  _ref$defaultWidth = _ref.defaultWidth,
119
123
  defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
124
+ _ref$minWidth = _ref.minWidth,
125
+ minWidth = _ref$minWidth === void 0 ? fallbackMinWidth : _ref$minWidth,
126
+ maxWidth = _ref.maxWidth,
120
127
  testId = _ref.testId,
121
128
  _ref$label = _ref.label,
122
129
  label = _ref$label === void 0 ? 'Sidebar' : _ref$label,
@@ -128,6 +135,7 @@ function SideNavInternal(_ref) {
128
135
  onPeekEnd = _ref.onPeekEnd,
129
136
  providedId = _ref.id,
130
137
  canToggleWithShortcut = _ref.canToggleWithShortcut;
138
+ var isChatPanelLayoutEnabled = fg('platform-dst-chat-panel-layout');
131
139
  var isFhsEnabled = useIsFhsEnabled();
132
140
  var id = useLayoutId({
133
141
  providedId: providedId
@@ -213,18 +221,142 @@ function SideNavInternal(_ref) {
213
221
  });
214
222
  var _useState5 = useState(defaultWidth),
215
223
  _useState6 = _slicedToArray(_useState5, 2),
216
- width = _useState6[0],
217
- setWidth = _useState6[1];
218
- var clampedWidth = "clamp(".concat(widthResizeBounds.min, ", ").concat(width, "px, ").concat(widthResizeBounds.max, ")");
224
+ inlineWidth = _useState6[0],
225
+ setInlineWidth = _useState6[1];
226
+ var _useState7 = useState(defaultWidth),
227
+ _useState8 = _slicedToArray(_useState7, 2),
228
+ overlayWidth = _useState8[0],
229
+ setOverlayWidth = _useState8[1];
230
+ var _useState9 = useState(false),
231
+ _useState0 = _slicedToArray(_useState9, 2),
232
+ isInline = _useState0[0],
233
+ setIsInline = _useState0[1];
234
+ useEffect(function () {
235
+ if (!isChatPanelLayoutEnabled) {
236
+ return;
237
+ }
238
+ var mediaQuery = window.matchMedia('(min-width: 64rem)');
239
+ setIsInline(mediaQuery.matches);
240
+ var onChange = function onChange(event) {
241
+ return setIsInline(event.matches);
242
+ };
243
+ return bind(mediaQuery, {
244
+ type: 'change',
245
+ listener: onChange
246
+ });
247
+ }, [isChatPanelLayoutEnabled]);
248
+ var toggleVisibilityForChatPanel = useToggleSideNav({
249
+ trigger: 'programmatic'
250
+ });
251
+ var closeOverlayForChatPanel = useCallback(function () {
252
+ // Allocation can overlay an expanded desktop nav when other slots consume
253
+ // its space. Dismiss the visibility state selected by the viewport, not the mode.
254
+ var isDesktop = window.matchMedia('(min-width: 64rem)').matches;
255
+ if (isDesktop ? isExpandedOnDesktop : isExpandedOnMobile) {
256
+ toggleVisibilityForChatPanel();
257
+ }
258
+ }, [isExpandedOnDesktop, isExpandedOnMobile, toggleVisibilityForChatPanel]);
259
+ var _useLayoutAreaSizing = useLayoutAreaSizing({
260
+ area: 'side-nav',
261
+ config: {
262
+ defaultWidth: defaultWidth,
263
+ minWidth: minWidth,
264
+ maxWidth: maxWidth,
265
+ isOpen: isInline ? isExpandedOnDesktop : isExpandedOnMobile,
266
+ onRequestClose: closeOverlayForChatPanel
267
+ }
268
+ }),
269
+ managedSizing = _useLayoutAreaSizing.state,
270
+ getManagedResizeBounds = _useLayoutAreaSizing.getResizeBounds,
271
+ startResize = _useLayoutAreaSizing.startResize,
272
+ resize = _useLayoutAreaSizing.resize,
273
+ completeResize = _useLayoutAreaSizing.completeResize;
274
+ var mode = (_managedSizing$mode = managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) !== null && _managedSizing$mode !== void 0 ? _managedSizing$mode : isInline ? 'inline' : 'overlay';
275
+ var renderedWidth = isChatPanelLayoutEnabled ? (_managedSizing$width = managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.width) !== null && _managedSizing$width !== void 0 ? _managedSizing$width : mode === 'inline' ? inlineWidth : overlayWidth : inlineWidth;
276
+ var configuredMaxWidth = maxWidth !== null && maxWidth !== void 0 ? maxWidth : '100vw';
277
+ var clampedWidth = !isChatPanelLayoutEnabled ? "clamp(240px, ".concat(inlineWidth, "px, 50vw)") : managedSizing ? "".concat(renderedWidth, "px") : "clamp(".concat(minWidth, ", ").concat(renderedWidth, "px, ").concat(configuredMaxWidth, ")");
219
278
  var dangerouslyHoistSlotSizes = useContext(DangerouslyHoistSlotSizes);
220
279
  var navRef = useRef(null);
221
280
  var panelSplitterPortalTargetRef = useRef(null);
281
+ var getResizeBounds = useCallback(function () {
282
+ if (!isChatPanelLayoutEnabled) {
283
+ return {
284
+ min: '240px',
285
+ max: '50vw'
286
+ };
287
+ }
288
+ var managedBounds = getManagedResizeBounds();
289
+ if (managedBounds) {
290
+ return managedBounds;
291
+ }
292
+ var sideNav = navRef.current;
293
+ var layoutRoot = sideNav === null || sideNav === void 0 ? void 0 : sideNav.parentElement;
294
+ var main = layoutRoot === null || layoutRoot === void 0 ? void 0 : layoutRoot.querySelector(':scope > [data-layout-slot][role="main"]');
295
+ var fallbackMaxWidth = maxWidth !== null && maxWidth !== void 0 ? maxWidth : mode === 'inline' ? '100vw' : '90vw';
296
+ if (!sideNav || mode === 'overlay') {
297
+ var chatPanel = layoutRoot === null || layoutRoot === void 0 ? void 0 : layoutRoot.querySelector(':scope > [data-layout-chat-panel]');
298
+ var inlineChatPanelWidth = chatPanel && getComputedStyle(chatPanel).gridArea === 'chat-panel' ? chatPanel.getBoundingClientRect().width : 0;
299
+ var overlayMaxWidth = Math.floor((window.innerWidth - inlineChatPanelWidth) * 0.9);
300
+ var _constrainedMaxWidth = maxWidth ? Math.min(convertResizeBoundToPixels(maxWidth), overlayMaxWidth) : overlayMaxWidth;
301
+ return {
302
+ min: minWidth,
303
+ max: "".concat(Math.max(convertResizeBoundToPixels(minWidth), _constrainedMaxWidth), "px")
304
+ };
305
+ }
306
+ if (!main) {
307
+ return {
308
+ min: minWidth,
309
+ max: fallbackMaxWidth
310
+ };
311
+ }
312
+ var sideNavWidth = sideNav.getBoundingClientRect().width;
313
+ var mainWidth = main.getBoundingClientRect().width;
314
+
315
+ // JSDOM does not perform layout, so retain the static fallback in unit tests and other
316
+ // environments where used widths cannot be measured.
317
+ if (sideNavWidth === 0 || mainWidth === 0) {
318
+ return {
319
+ min: minWidth,
320
+ max: fallbackMaxWidth
321
+ };
322
+ }
323
+ var localPanel = main.querySelector('[data-layout-with-panel-slot]');
324
+ var isLocalPanelInline = localPanel && getComputedStyle(localPanel).gridArea === 'panel';
325
+ var localPanelWidth = isLocalPanelInline ? localPanel.getBoundingClientRect().width : 0;
326
+ var mainContentWidth = mainWidth - localPanelWidth;
327
+ var mainMinimumWidth = getPixelCustomProperty(main, mainMinimumWidthVar, 320);
328
+ var availableWidth = Math.max(0, mainContentWidth - mainMinimumWidth);
329
+ var availableInlineWidth = Math.floor(sideNavWidth + availableWidth);
330
+ var constrainedMaxWidth = maxWidth ? Math.min(convertResizeBoundToPixels(maxWidth), availableInlineWidth) : availableInlineWidth;
331
+ return {
332
+ min: minWidth,
333
+ max: "".concat(Math.max(convertResizeBoundToPixels(minWidth), constrainedMaxWidth), "px")
334
+ };
335
+ }, [getManagedResizeBounds, isChatPanelLayoutEnabled, maxWidth, minWidth, mode]);
222
336
  /**
223
337
  * Used to share the side nav element with the `Panel`,
224
338
  * which observes the side nav to determine its maximum width.
225
339
  */
226
340
  var sharedRef = useSideNavRef();
227
341
  var mergedRef = mergeRefs([navRef, sharedRef]);
342
+ var onCompleteResize = useCallback(function (finalWidth) {
343
+ if (!isChatPanelLayoutEnabled) {
344
+ setInlineWidth(finalWidth);
345
+ return;
346
+ }
347
+ if (mode === 'inline') {
348
+ setInlineWidth(finalWidth);
349
+ } else {
350
+ setOverlayWidth(finalWidth);
351
+ }
352
+ completeResize(mode, finalWidth);
353
+ }, [completeResize, isChatPanelLayoutEnabled, mode]);
354
+ var onResizeStartInternal = useCallback(function () {
355
+ startResize(mode);
356
+ }, [mode, startResize]);
357
+ var onResizeInternal = useCallback(function (width) {
358
+ return resize(mode, width);
359
+ }, [mode, resize]);
228
360
  var toggleButtonElement = useContext(SideNavToggleButtonElement);
229
361
  var topNavStartElement = useContext(TopNavStartElement);
230
362
  var devTimeOnlyAttributes = {};
@@ -716,7 +848,7 @@ function SideNavInternal(_ref) {
716
848
  // Used to conditionally display the keyboard shortcut in the SideNavPanelSplitter tooltip.
717
849
  var isShortcutEnabled = useIsSideNavShortcutEnabled();
718
850
  useResizingWidthCssVarOnRootElement({
719
- isEnabled: true,
851
+ isEnabled: !isChatPanelLayoutEnabled || !managedSizing,
720
852
  cssVar: panelSplitterResizingVar,
721
853
  panelId: sideNavPanelSplitterId
722
854
  });
@@ -778,7 +910,7 @@ function SideNavInternal(_ref) {
778
910
  style: _defineProperty({}, sideNavVar, clampedWidth),
779
911
  ref: mergedRef,
780
912
  "data-testid": testId,
781
- className: ax([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, isMotionUpliftEnabled && motionUpliftStyles.animationRTLSupport, !isMotionUpliftEnabled && isFhsEnabled && styles.animationRTLSupport, shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.animationBaseStyles, shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.expandAnimationMobile, isExpandedOnMobile && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.collapseAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.expandAnimationDesktop, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.collapseAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutAnimateClosed, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && isFhsEnabled && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutAnimateClosedFullHeightSidebar])
913
+ className: ax([styles.root, isChatPanelLayoutEnabled && styles.chatPanelSizing, isChatPanelLayoutEnabled && (managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) === 'overlay' && styles.managedOverlay, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, isMotionUpliftEnabled && motionUpliftStyles.animationRTLSupport, !isMotionUpliftEnabled && isFhsEnabled && styles.animationRTLSupport, shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.animationBaseStyles, shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.expandAnimationMobile, isExpandedOnMobile && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.collapseAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.expandAnimationDesktop, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && isMotionUpliftEnabled && motionUpliftStyles.collapseAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && !isMotionUpliftEnabled && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutAnimateClosed, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && isFhsEnabled && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && isFhsEnabled && isMotionUpliftEnabled && motionUpliftStyles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && isFhsEnabled && !isMotionUpliftEnabled && styles.flyoutAnimateClosedFullHeightSidebar])
782
914
  }), /*#__PURE__*/React.createElement(DangerouslyHoistCssVarToDocumentRoot, {
783
915
  variableName: sideNavLiveWidthVar,
784
916
  value: "0px",
@@ -798,8 +930,10 @@ function SideNavInternal(_ref) {
798
930
  panelId: sideNavPanelSplitterId,
799
931
  panelRef: navRef,
800
932
  portalRef: isFhsEnabled ? panelSplitterPortalTargetRef : undefined,
801
- panelWidth: width,
802
- onCompleteResize: setWidth,
933
+ panelWidth: renderedWidth,
934
+ onCompleteResize: onCompleteResize,
935
+ onResizeStartInternal: isChatPanelLayoutEnabled && managedSizing ? onResizeStartInternal : undefined,
936
+ onResizeInternal: isChatPanelLayoutEnabled && managedSizing ? onResizeInternal : undefined,
803
937
  getResizeBounds: getResizeBounds,
804
938
  resizingCssVar: panelSplitterResizingVar
805
939
  // Not resizable when in peek (flyout) mode.
@@ -829,6 +963,8 @@ export function SideNav(_ref9) {
829
963
  defaultCollapsed = _ref9.defaultCollapsed,
830
964
  _ref9$defaultWidth = _ref9.defaultWidth,
831
965
  defaultWidth = _ref9$defaultWidth === void 0 ? 320 : _ref9$defaultWidth,
966
+ minWidth = _ref9.minWidth,
967
+ maxWidth = _ref9.maxWidth,
832
968
  testId = _ref9.testId,
833
969
  label = _ref9.label,
834
970
  _ref9$skipLinkLabel = _ref9.skipLinkLabel,
@@ -844,6 +980,8 @@ export function SideNav(_ref9) {
844
980
  }, /*#__PURE__*/React.createElement(SideNavInternal, {
845
981
  defaultCollapsed: defaultCollapsed,
846
982
  defaultWidth: defaultWidth,
983
+ minWidth: minWidth,
984
+ maxWidth: maxWidth,
847
985
  testId: testId,
848
986
  label: label,
849
987
  skipLinkLabel: skipLinkLabel,
@@ -0,0 +1,67 @@
1
+ import { useCallback, useContext, useEffect, useRef } from 'react';
2
+ import { LayoutAreaSizingContext } from './layout-area-sizing-context';
3
+ import { layoutAreaStateContexts } from './layout-area-state-contexts';
4
+ export function useLayoutAreaSizing(_ref) {
5
+ var area = _ref.area,
6
+ config = _ref.config;
7
+ var context = useContext(LayoutAreaSizingContext);
8
+ var requestedWidth = config.requestedWidth,
9
+ defaultWidth = config.defaultWidth,
10
+ compactDefaultWidth = config.compactDefaultWidth,
11
+ minWidth = config.minWidth,
12
+ maxWidth = config.maxWidth,
13
+ isOpen = config.isOpen,
14
+ onRequestClose = config.onRequestClose;
15
+ var registerArea = context === null || context === void 0 ? void 0 : context.registerArea;
16
+ var unregisterArea = context === null || context === void 0 ? void 0 : context.unregisterArea;
17
+ var startAreaResize = context === null || context === void 0 ? void 0 : context.startResize;
18
+ var resizeArea = context === null || context === void 0 ? void 0 : context.resize;
19
+ var completeAreaResize = context === null || context === void 0 ? void 0 : context.completeResize;
20
+ var getAreaResizeBounds = context === null || context === void 0 ? void 0 : context.getResizeBounds;
21
+ var state = useContext(layoutAreaStateContexts[area]);
22
+ // Dismissal is not a sizing input. Register a stable delegate while keeping
23
+ // the consumer's latest committed callback outside allocation state.
24
+ var onRequestCloseRef = useRef(onRequestClose);
25
+ useEffect(function () {
26
+ onRequestCloseRef.current = onRequestClose;
27
+ }, [onRequestClose]);
28
+ var requestClose = useCallback(function () {
29
+ var _onRequestCloseRef$cu;
30
+ return (_onRequestCloseRef$cu = onRequestCloseRef.current) === null || _onRequestCloseRef$cu === void 0 ? void 0 : _onRequestCloseRef$cu.call(onRequestCloseRef);
31
+ }, []);
32
+ useEffect(function () {
33
+ registerArea === null || registerArea === void 0 || registerArea(area, {
34
+ requestedWidth: requestedWidth,
35
+ defaultWidth: defaultWidth,
36
+ compactDefaultWidth: compactDefaultWidth,
37
+ minWidth: minWidth,
38
+ maxWidth: maxWidth,
39
+ isOpen: isOpen,
40
+ onRequestClose: requestClose
41
+ });
42
+ }, [area, compactDefaultWidth, defaultWidth, isOpen, maxWidth, minWidth, registerArea, requestClose, requestedWidth]);
43
+ useEffect(function () {
44
+ return function () {
45
+ return unregisterArea === null || unregisterArea === void 0 ? void 0 : unregisterArea(area);
46
+ };
47
+ }, [area, unregisterArea]);
48
+ var startResize = useCallback(function (mode) {
49
+ return startAreaResize === null || startAreaResize === void 0 ? void 0 : startAreaResize(area, mode);
50
+ }, [area, startAreaResize]);
51
+ var resize = useCallback(function (mode, width) {
52
+ return resizeArea === null || resizeArea === void 0 ? void 0 : resizeArea(area, mode, width);
53
+ }, [area, resizeArea]);
54
+ var completeResize = useCallback(function (mode, width) {
55
+ return completeAreaResize === null || completeAreaResize === void 0 ? void 0 : completeAreaResize(area, mode, width);
56
+ }, [area, completeAreaResize]);
57
+ var getResizeBounds = useCallback(function () {
58
+ return getAreaResizeBounds === null || getAreaResizeBounds === void 0 ? void 0 : getAreaResizeBounds(area);
59
+ }, [area, getAreaResizeBounds]);
60
+ return {
61
+ state: state,
62
+ startResize: startResize,
63
+ resize: resize,
64
+ completeResize: completeResize,
65
+ getResizeBounds: getResizeBounds
66
+ };
67
+ }
@@ -0,0 +1,9 @@
1
+ import { useContext, useEffect } from 'react';
2
+ import { LayoutAreaSizingContext } from './layout-area-sizing-context';
3
+ export function useLayoutMainSizing(minWidth) {
4
+ var context = useContext(LayoutAreaSizingContext);
5
+ var setMainMinWidth = context === null || context === void 0 ? void 0 : context.setMainMinWidth;
6
+ useEffect(function () {
7
+ return setMainMinWidth === null || setMainMinWidth === void 0 ? void 0 : setMainMinWidth(minWidth);
8
+ }, [minWidth, setMainMinWidth]);
9
+ }
@@ -0,0 +1,105 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ import { useEffect, useState } from 'react';
6
+ import { bind } from 'bind-event-listener';
7
+
8
+ /**
9
+ * Measures the existing Root slots that are not managed by the chat-layout allocator.
10
+ * Only count separate inline columns: Aside stacks below Main on mobile, and the
11
+ * legacy Panel spans other areas while overlaying. Read the grid rather than duplicating
12
+ * its responsive breakpoints. Border boxes include slot borders and live splitter widths.
13
+ */
14
+ export function useOccupiedLayoutWidth(layoutRef) {
15
+ var _useState = useState(0),
16
+ _useState2 = _slicedToArray(_useState, 2),
17
+ width = _useState2[0],
18
+ setWidth = _useState2[1];
19
+ useEffect(function () {
20
+ var root = layoutRef === null || layoutRef === void 0 ? void 0 : layoutRef.current;
21
+ if (!root) {
22
+ return;
23
+ }
24
+ var occupiedSlots = [];
25
+ var measure = function measure() {
26
+ var _getComputedStyle$gri, _rows$map$find;
27
+ if (occupiedSlots.length === 0) {
28
+ setWidth(0);
29
+ return;
30
+ }
31
+ var rows = (_getComputedStyle$gri = getComputedStyle(root).gridTemplateAreas.match(/"[^"]+"/g)) !== null && _getComputedStyle$gri !== void 0 ? _getComputedStyle$gri : [];
32
+ var mainRow = (_rows$map$find = rows.map(function (row) {
33
+ return row.replace(/"/g, '').split(/\s+/);
34
+ }).find(function (row) {
35
+ return row.includes('main');
36
+ })) !== null && _rows$map$find !== void 0 ? _rows$map$find : [];
37
+ var occupiedWidth = 0;
38
+ var _iterator = _createForOfIteratorHelper(occupiedSlots),
39
+ _step;
40
+ try {
41
+ var _loop = function _loop() {
42
+ var child = _step.value;
43
+ var style = getComputedStyle(child);
44
+ var area = style.gridArea.split('/').map(function (part) {
45
+ return part.trim();
46
+ });
47
+ var slot = area[0];
48
+ if (['ribbon', 'aside', 'panel'].includes(slot) && area.every(function (part) {
49
+ return part === slot;
50
+ }) && mainRow.includes(slot) && style.display !== 'none' && style.position !== 'absolute' && style.position !== 'fixed') {
51
+ occupiedWidth += child.getBoundingClientRect().width;
52
+ }
53
+ };
54
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
55
+ _loop();
56
+ }
57
+ } catch (err) {
58
+ _iterator.e(err);
59
+ } finally {
60
+ _iterator.f();
61
+ }
62
+ setWidth(occupiedWidth);
63
+ };
64
+ var resizeObserver = new ResizeObserver(measure);
65
+ var observeSlots = function observeSlots() {
66
+ resizeObserver.disconnect();
67
+ resizeObserver.observe(root);
68
+ // Managed regions resize on every drag frame but cannot consume extra tracks.
69
+ // Keep them out of both the observer and the measurement loop. Slot identity,
70
+ // unlike gridArea, remains stable when a region switches to overlay mode.
71
+ // TopNav and Banner also span columns rather than consuming independent tracks.
72
+ occupiedSlots = Array.from(root.children).filter(function (child) {
73
+ return child instanceof HTMLElement && child.hasAttribute('data-layout-slot') && !child.matches('nav, header, [role="main"], [data-layout-chat-panel]') && getComputedStyle(child).gridArea.split('/')[0].trim() !== 'banner';
74
+ });
75
+ var _iterator2 = _createForOfIteratorHelper(occupiedSlots),
76
+ _step2;
77
+ try {
78
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
79
+ var child = _step2.value;
80
+ resizeObserver.observe(child);
81
+ }
82
+ } catch (err) {
83
+ _iterator2.e(err);
84
+ } finally {
85
+ _iterator2.f();
86
+ }
87
+ measure();
88
+ };
89
+ var mutationObserver = new MutationObserver(observeSlots);
90
+ mutationObserver.observe(root, {
91
+ childList: true
92
+ });
93
+ observeSlots();
94
+ var unbind = bind(window, {
95
+ type: 'resize',
96
+ listener: measure
97
+ });
98
+ return function () {
99
+ unbind();
100
+ resizeObserver.disconnect();
101
+ mutationObserver.disconnect();
102
+ };
103
+ }, [layoutRef]);
104
+ return width;
105
+ }
@@ -0,0 +1 @@
1
+ export { ChatPanel } from '../../ui/page-layout/chat-panel';
@@ -0,0 +1,4 @@
1
+ export { contentHeightWhenFixed, contentInsetBlockStart, mainMinimumWidthVar, sideNavLiveWidthVar, } from '../../ui/page-layout/constants';
2
+ export { useLayoutAreaSizing as UNSAFE_useLayoutAreaSizing } from '../../ui/page-layout/use-layout-area-sizing';
3
+ export { resolveLayoutWidth as UNSAFE_resolveLayoutWidth } from '../../ui/page-layout/resolve-layout-width';
4
+ export type { LayoutAreaMode as UNSAFE_LayoutAreaMode, LayoutAreaState as UNSAFE_LayoutAreaState, } from '../../ui/page-layout/layout-area-sizing-context';
@@ -0,0 +1,20 @@
1
+ import type { LayoutArea, LayoutAreaAllocation, LayoutWidthBound, ResizeSession, StoredLayoutArea } from './layout-area-sizing-context';
2
+ export declare function calculateLayoutAreaStates({ viewportWidth, layoutWidth, isChatPanelOverlay, isSideNavOverlay, occupiedWidth, mainMinWidth: mainMinWidthBound, areas, resizeSession, }: {
3
+ viewportWidth: number;
4
+ /**
5
+ * Root's content width, excluding scrollbars, borders and padding.
6
+ */
7
+ layoutWidth?: number;
8
+ /**
9
+ * Whether the viewport is below Root's 40rem inline-chat breakpoint.
10
+ */
11
+ isChatPanelOverlay: boolean;
12
+ /**
13
+ * Whether the viewport is below Root and SideNav's 64rem desktop breakpoint.
14
+ */
15
+ isSideNavOverlay: boolean;
16
+ occupiedWidth?: number;
17
+ mainMinWidth: LayoutWidthBound;
18
+ areas: Partial<Record<LayoutArea, StoredLayoutArea>>;
19
+ resizeSession?: ResizeSession | null;
20
+ }): Partial<Record<LayoutArea, LayoutAreaAllocation>>;
@@ -0,0 +1,48 @@
1
+ import type { StrictXCSSProp } from '@atlaskit/css';
2
+ import type { ResizeBound } from './panel-splitter/types';
3
+ import type { CommonSlotProps } from './types';
4
+ /**
5
+ * The ChatPanel layout area is rendered below the banner and to the right (inline end) of the app.
6
+ *
7
+ * Below 40rem it overlays the app. At 40rem and above it is rendered as the final
8
+ * full-height column in the page layout grid.
9
+ *
10
+ * You can optionally render a `PanelSplitter` as a child to make the chat panel resizable.
11
+ */
12
+ export declare function ChatPanel({ children, defaultWidth: defaultWidthProp, minWidth, maxWidth, label, skipLinkLabel, testId, id: providedId, xcss, hasBorder, onClose, }: CommonSlotProps & {
13
+ /**
14
+ * The content of the layout area.
15
+ */
16
+ children: React.ReactNode;
17
+ /**
18
+ * The accessible name of the slot, announced by screen readers.
19
+ */
20
+ label?: string;
21
+ /**
22
+ * The default width of the layout area in pixels.
23
+ */
24
+ defaultWidth?: number;
25
+ /**
26
+ * The minimum width the chat panel can be resized to.
27
+ */
28
+ minWidth?: ResizeBound;
29
+ /**
30
+ * The maximum width the chat panel can be resized to.
31
+ */
32
+ maxWidth?: ResizeBound;
33
+ /**
34
+ * Bounded style overrides.
35
+ */
36
+ xcss?: StrictXCSSProp<'backgroundColor', never>;
37
+ /**
38
+ * Whether the slot has a border when inline, or a shadow when overlaying the app.
39
+ *
40
+ * @default true
41
+ */
42
+ hasBorder?: boolean;
43
+ /**
44
+ * Required for controlled dismissal. Unmount ChatPanel when called, including
45
+ * when opening SideNav replaces the chat overlay. Remount it to open it again.
46
+ */
47
+ onClose: () => void;
48
+ }): JSX.Element;
@@ -6,6 +6,9 @@
6
6
  export declare const sideNavVar = "--n_sNvw";
7
7
  export declare const asideVar = "--n_asDw";
8
8
  export declare const panelVar = "--n_pnlW";
9
+ export declare const chatPanelVar = "--n_cPnlW";
10
+ export declare const chatPanelLiveWidthVar = "--n_cPnlLw";
11
+ export declare const mainMinimumWidthVar = "--n_mainMinW";
9
12
  export declare const bannerMountedVar = "--n_bnrM";
10
13
  export declare const topNavMountedVar = "--n_tNvM";
11
14
  export declare const ribbonVar = "--n_rbnW";
@@ -35,6 +38,7 @@ export declare const UNSAFE_MAIN_INLINE_END_FOR_LEGACY_PAGES_ONLY: 'calc(var(--r
35
38
  * rely on accessing them through global means.
36
39
  */
37
40
  export declare const localSlotLayers: {
41
+ chatPanelOverlay: number;
38
42
  ribbon: number;
39
43
  sideNavPanelSplitterFHS: number;
40
44
  topBar: number;
@@ -0,0 +1,55 @@
1
+ import { type Context } from 'react';
2
+ import type { ResizeBounds } from './panel-splitter/types';
3
+ export type LayoutArea = 'side-nav' | 'panel' | 'chat-panel';
4
+ export type LayoutAreaMode = 'inline' | 'overlay';
5
+ export type LayoutWidthBound = number | `${number}px` | `${number}vw`;
6
+ export type LayoutAreaConfig = {
7
+ /**
8
+ * Controlled requested width. Allocation may constrain it without changing the request.
9
+ */
10
+ requestedWidth?: number;
11
+ defaultWidth: number;
12
+ compactDefaultWidth?: number;
13
+ minWidth: LayoutWidthBound;
14
+ maxWidth?: LayoutWidthBound;
15
+ isOpen: boolean;
16
+ onRequestClose?: () => void;
17
+ };
18
+ export type StoredLayoutArea = LayoutAreaConfig & {
19
+ preferredInlineWidth?: number;
20
+ preferredOverlayWidth?: number;
21
+ liveResize?: {
22
+ mode: LayoutAreaMode;
23
+ width: number;
24
+ };
25
+ openedAt?: number;
26
+ };
27
+ /**
28
+ * Effective sibling widths held fixed during and after a user resize, until the
29
+ * layout dimensions or configuration change. This is not a resize history.
30
+ */
31
+ export type ResizeSession = {
32
+ area: LayoutArea;
33
+ baselineWidths: Partial<Record<LayoutArea, number>>;
34
+ };
35
+ export type LayoutAreaState = {
36
+ mode: LayoutAreaMode;
37
+ width: number;
38
+ minWidth: number;
39
+ };
40
+ export type LayoutAreaAllocation = LayoutAreaState & {
41
+ resizeBounds: {
42
+ min: number;
43
+ max: number;
44
+ };
45
+ };
46
+ export type LayoutAreaSizingContextValue = {
47
+ getResizeBounds: (area: LayoutArea) => ResizeBounds | undefined;
48
+ registerArea: (area: LayoutArea, config: LayoutAreaConfig) => void;
49
+ unregisterArea: (area: LayoutArea) => void;
50
+ startResize: (area: LayoutArea, mode: LayoutAreaMode) => void;
51
+ resize: (area: LayoutArea, mode: LayoutAreaMode, width: number) => void;
52
+ completeResize: (area: LayoutArea, mode: LayoutAreaMode, width: number) => void;
53
+ setMainMinWidth: (minWidth: LayoutWidthBound) => void;
54
+ };
55
+ export declare const LayoutAreaSizingContext: Context<LayoutAreaSizingContextValue | null>;
@@ -0,0 +1,5 @@
1
+ import React, { type ReactNode } from 'react';
2
+ export declare function LayoutAreaSizingProvider({ children, layoutRef, }: {
3
+ children: ReactNode;
4
+ layoutRef?: React.RefObject<HTMLDivElement | null>;
5
+ }): JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { type Context } from 'react';
2
+ import type { LayoutArea, LayoutAreaState } from './layout-area-sizing-context';
3
+ export declare const layoutAreaStateContexts: Record<LayoutArea, Context<LayoutAreaState | undefined>>;
@@ -3,7 +3,7 @@ import type { CommonSlotProps } from '../types';
3
3
  /**
4
4
  * Use the Main area for the main page content. It has a fluid width and will expand to fill available space.
5
5
  */
6
- export declare function Main({ children, xcss, skipLinkLabel, testId, id: providedId, }: CommonSlotProps & {
6
+ export declare function Main({ children, xcss, skipLinkLabel, testId, id: providedId, minWidth, }: CommonSlotProps & {
7
7
  /**
8
8
  * The content of the layout area.
9
9
  * This is where you should put the main content of your page.
@@ -13,4 +13,8 @@ export declare function Main({ children, xcss, skipLinkLabel, testId, id: provid
13
13
  * Bounded style overrides.
14
14
  */
15
15
  xcss?: StrictXCSSProp<'backgroundColor', never>;
16
+ /**
17
+ * Minimum width used by the layout allocation system.
18
+ */
19
+ minWidth?: number;
16
20
  }): JSX.Element;