@atlaskit/navigation-system 11.3.3 → 11.4.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 (97) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +20 -0
  3. package/constellation/layout/code.mdx +1 -1
  4. package/constellation/layout/examples.mdx +4 -16
  5. package/constellation/layout/images/layout-anatomy-dark.png +0 -0
  6. package/constellation/layout/images/layout-anatomy-light.png +0 -0
  7. package/constellation/layout/images/layout-do-dark.png +0 -0
  8. package/constellation/layout/images/layout-do-light.png +0 -0
  9. package/constellation/layout/images/layout-dont-dark.png +0 -0
  10. package/constellation/layout/images/layout-dont-light.png +0 -0
  11. package/constellation/layout/images/layout-example-dark.png +0 -0
  12. package/constellation/layout/images/layout-example-light.png +0 -0
  13. package/constellation/layout/images/layout-example-sideNav-dark.png +0 -0
  14. package/constellation/layout/images/layout-example-sideNav-light.png +0 -0
  15. package/constellation/layout/images/layout-example-topNav-1-dark.png +0 -0
  16. package/constellation/layout/images/layout-example-topNav-1-light.png +0 -0
  17. package/constellation/layout/usage.mdx +1 -2
  18. package/constellation/top-nav-items/examples.mdx +7 -13
  19. package/dist/cjs/entry-points/layout/panel-layout.js +19 -0
  20. package/dist/cjs/ui/page-layout/calculate-layout-area-states.js +4 -4
  21. package/dist/cjs/ui/page-layout/chat-panel.js +1 -1
  22. package/dist/cjs/ui/page-layout/constants.js +15 -1
  23. package/dist/cjs/ui/page-layout/get-panel-layout-defaults.js +22 -0
  24. package/dist/cjs/ui/page-layout/layout-area-sizing-provider.js +2 -1
  25. package/dist/cjs/ui/page-layout/layout-area-sizing-runtime.js +5 -4
  26. package/dist/cjs/ui/page-layout/local-panel-surface.compiled.css +26 -0
  27. package/dist/cjs/ui/page-layout/local-panel-surface.js +206 -0
  28. package/dist/cjs/ui/page-layout/main/main.js +5 -2
  29. package/dist/cjs/ui/page-layout/main-min-width-context.js +10 -0
  30. package/dist/cjs/ui/page-layout/panel-layout-shell.compiled.css +27 -0
  31. package/dist/cjs/ui/page-layout/panel-layout-shell.js +67 -0
  32. package/dist/cjs/ui/page-layout/panel-layout.js +162 -0
  33. package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +12 -5
  34. package/dist/cjs/ui/page-layout/root.js +3 -1
  35. package/dist/cjs/ui/page-layout/side-nav/bind-open-layer-change.js +56 -0
  36. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +167 -57
  37. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +8 -1
  38. package/dist/cjs/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  39. package/dist/cjs/ui/page-layout/top-nav/top-nav-end.js +3 -2
  40. package/dist/cjs/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  41. package/dist/es2019/entry-points/layout/panel-layout.js +2 -0
  42. package/dist/es2019/ui/page-layout/calculate-layout-area-states.js +4 -4
  43. package/dist/es2019/ui/page-layout/chat-panel.js +2 -2
  44. package/dist/es2019/ui/page-layout/constants.js +14 -0
  45. package/dist/es2019/ui/page-layout/get-panel-layout-defaults.js +16 -0
  46. package/dist/es2019/ui/page-layout/layout-area-sizing-provider.js +2 -1
  47. package/dist/es2019/ui/page-layout/layout-area-sizing-runtime.js +4 -3
  48. package/dist/es2019/ui/page-layout/local-panel-surface.compiled.css +26 -0
  49. package/dist/es2019/ui/page-layout/local-panel-surface.js +193 -0
  50. package/dist/es2019/ui/page-layout/main/main.js +6 -3
  51. package/dist/es2019/ui/page-layout/main-min-width-context.js +5 -0
  52. package/dist/es2019/ui/page-layout/panel-layout-shell.compiled.css +27 -0
  53. package/dist/es2019/ui/page-layout/panel-layout-shell.js +74 -0
  54. package/dist/es2019/ui/page-layout/panel-layout.js +147 -0
  55. package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +12 -5
  56. package/dist/es2019/ui/page-layout/root.js +3 -1
  57. package/dist/es2019/ui/page-layout/side-nav/bind-open-layer-change.js +51 -0
  58. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +123 -10
  59. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +8 -1
  60. package/dist/es2019/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  61. package/dist/es2019/ui/page-layout/top-nav/top-nav-end.js +3 -2
  62. package/dist/es2019/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  63. package/dist/esm/entry-points/layout/panel-layout.js +2 -0
  64. package/dist/esm/ui/page-layout/calculate-layout-area-states.js +4 -4
  65. package/dist/esm/ui/page-layout/chat-panel.js +2 -2
  66. package/dist/esm/ui/page-layout/constants.js +14 -0
  67. package/dist/esm/ui/page-layout/get-panel-layout-defaults.js +16 -0
  68. package/dist/esm/ui/page-layout/layout-area-sizing-provider.js +2 -1
  69. package/dist/esm/ui/page-layout/layout-area-sizing-runtime.js +4 -3
  70. package/dist/esm/ui/page-layout/local-panel-surface.compiled.css +26 -0
  71. package/dist/esm/ui/page-layout/local-panel-surface.js +197 -0
  72. package/dist/esm/ui/page-layout/main/main.js +6 -3
  73. package/dist/esm/ui/page-layout/main-min-width-context.js +5 -0
  74. package/dist/esm/ui/page-layout/panel-layout-shell.compiled.css +27 -0
  75. package/dist/esm/ui/page-layout/panel-layout-shell.js +59 -0
  76. package/dist/esm/ui/page-layout/panel-layout.js +154 -0
  77. package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +12 -5
  78. package/dist/esm/ui/page-layout/root.js +3 -1
  79. package/dist/esm/ui/page-layout/side-nav/bind-open-layer-change.js +50 -0
  80. package/dist/esm/ui/page-layout/side-nav/side-nav.js +168 -58
  81. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +8 -1
  82. package/dist/esm/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  83. package/dist/esm/ui/page-layout/top-nav/top-nav-end.js +3 -2
  84. package/dist/esm/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  85. package/dist/types/entry-points/layout/panel-layout.d.ts +3 -0
  86. package/dist/types/ui/page-layout/constants.d.ts +12 -0
  87. package/dist/types/ui/page-layout/get-panel-layout-defaults.d.ts +10 -0
  88. package/dist/types/ui/page-layout/layout-area-sizing-context.d.ts +5 -1
  89. package/dist/types/ui/page-layout/local-panel-surface.d.ts +32 -0
  90. package/dist/types/ui/page-layout/main-min-width-context.d.ts +2 -0
  91. package/dist/types/ui/page-layout/panel-layout-shell.d.ts +47 -0
  92. package/dist/types/ui/page-layout/panel-layout.d.ts +74 -0
  93. package/dist/types/ui/page-layout/side-nav/bind-open-layer-change.d.ts +17 -0
  94. package/layout/panel-layout/package.json +10 -0
  95. package/package.json +6 -6
  96. package/constellation/layout/images/layout-example-topNav-2-dark.png +0 -0
  97. package/constellation/layout/images/layout-example-topNav-2-light.png +0 -0
@@ -0,0 +1,197 @@
1
+ /* local-panel-surface.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import "./local-panel-surface.compiled.css";
5
+ import * as React from 'react';
6
+ import { ax, ix } from "@compiled/react/runtime";
7
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
+ import { useCallback, useContext, useMemo, useRef } from 'react';
10
+ import mergeRefs from '@atlaskit/ds-lib/merge-refs';
11
+ import { useLayoutEffect } from '@atlaskit/ds-lib/use-layout-effect';
12
+ import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
13
+ import { useMotion } from '@atlaskit/motion/entering/use-motion';
14
+ import ExitingPersistence from '@atlaskit/motion/exiting-persistence';
15
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
16
+ import { localPanelWidthVar } from './constants';
17
+ import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
18
+ import { PanelSplitter } from './panel-splitter/panel-splitter';
19
+ import { PanelSplitterProvider } from './panel-splitter/provider';
20
+ var localPanelVar = '--p_lclPnlW';
21
+ var panelSplitterResizingVar = '--p_lclPnlRsz';
22
+ var localPanelSplitterId = Symbol('LocalPanel PanelSplitter');
23
+
24
+ // Compiled preserves the existing container-relative widths and discrete motion styles.
25
+ /* eslint-disable @compiled/shorthand-property-sorting -- Content motion overrides only the animation delay. */
26
+ var styles = {
27
+ panelWrapper: "_nd5l1gzg _kqsw1if8 _bfhk1bhr _vchhusvi _4t3ieqxy _152tidpf _10fph9n0 _1bsb13q4",
28
+ managedInline: "_nd5l1c6w _bfhkvuon _152tidpf _1bsb1c5w",
29
+ unmeasured: "_nd5l32aw _191wbqna _1bsb1cku _bfhk1g1j _16qs1dhr",
30
+ managedOverlay: "_nd5l1gzg _bfhk1bhr _1bsb1c5w",
31
+ panelScrollContainer: "_1reo1wug _18m91wug _4t3i1osq",
32
+ border: "_191wglyw _16qs130s",
33
+ managedInlineBorder: "_191wia51 _16qsglyw",
34
+ entering: "_k1af1nn1 _10t81ia4 _xrrp147i _1wsa1ign _1vrh1a5r _1kmh1n9t _105abamb",
35
+ exiting: "_k1af14vv _bq641n9t _105aeydr",
36
+ contentEntering: "_y44v1mph",
37
+ contentExiting: "_y44vf1qi",
38
+ contentChangeContainer: "_4t3i1osq"
39
+ };
40
+ var contentEnteringDelayStyles = {
41
+ root: "_ju25dn4k"
42
+ };
43
+ /* eslint-enable @compiled/shorthand-property-sorting */
44
+
45
+ var PanelContentMotion = function PanelContentMotion(_ref) {
46
+ var children = _ref.children;
47
+ var _useMotion = useMotion(),
48
+ state = _useMotion.state,
49
+ ref = _useMotion.ref;
50
+ return /*#__PURE__*/React.createElement("div", {
51
+ ref: ref,
52
+ className: ax([styles.contentChangeContainer, state === 'entering' && styles.contentEntering, state === 'exiting' && styles.contentExiting])
53
+ }, children);
54
+ };
55
+ /**
56
+ * Internal surface for PanelLayout. The host supplies content; navigation owns its geometry.
57
+ */
58
+ export function LocalPanelSurface(_ref2) {
59
+ var _managedSizing$mode, _managedSizing$width;
60
+ var children = _ref2.children,
61
+ contentKey = _ref2.contentKey,
62
+ label = _ref2.label,
63
+ resizeLabel = _ref2.resizeLabel,
64
+ defaultWidth = _ref2.defaultWidth,
65
+ minWidth = _ref2.minWidth,
66
+ maxWidth = _ref2.maxWidth,
67
+ testId = _ref2.testId,
68
+ layoutRef = _ref2.layoutRef,
69
+ managedSizing = _ref2.managedSizing,
70
+ getManagedResizeBounds = _ref2.getManagedResizeBounds,
71
+ prepareResize = _ref2.prepareResize,
72
+ onManagedResizeStart = _ref2.onManagedResizeStart,
73
+ onManagedResize = _ref2.onManagedResize,
74
+ onManagedResizeEnd = _ref2.onManagedResizeEnd,
75
+ onWidthChange = _ref2.onWidthChange,
76
+ onResizeEnd = _ref2.onResizeEnd;
77
+ var ref = useRef(null);
78
+ var dangerouslyHoistSlotSizes = useContext(DangerouslyHoistSlotSizes);
79
+ useLayoutEffect(function () {
80
+ var panel = ref.current;
81
+ if (!dangerouslyHoistSlotSizes || !panel) {
82
+ return;
83
+ }
84
+ // Container-relative CSS owns the initial width, before the sizing runtime loads.
85
+ // Publish geometry directly for external controls; never feed it into saved preferences.
86
+ var previousWidth;
87
+ var publishWidth = function publishWidth(width) {
88
+ if (width !== previousWidth) {
89
+ previousWidth = width;
90
+ panel.ownerDocument.documentElement.style.setProperty(localPanelWidthVar, "".concat(width, "px"));
91
+ }
92
+ };
93
+ publishWidth(panel.getBoundingClientRect().width);
94
+ var observer = new ResizeObserver(function (_ref3) {
95
+ var _entry$borderBoxSize$, _entry$borderBoxSize;
96
+ var _ref4 = _slicedToArray(_ref3, 1),
97
+ entry = _ref4[0];
98
+ publishWidth((_entry$borderBoxSize$ = (_entry$borderBoxSize = entry.borderBoxSize) === null || _entry$borderBoxSize === void 0 || (_entry$borderBoxSize = _entry$borderBoxSize[0]) === null || _entry$borderBoxSize === void 0 ? void 0 : _entry$borderBoxSize.inlineSize) !== null && _entry$borderBoxSize$ !== void 0 ? _entry$borderBoxSize$ : panel.getBoundingClientRect().width);
99
+ });
100
+ observer.observe(panel, {
101
+ box: 'border-box'
102
+ });
103
+ return function () {
104
+ observer.disconnect();
105
+ panel.ownerDocument.documentElement.style.removeProperty(localPanelWidthVar);
106
+ };
107
+ }, [dangerouslyHoistSlotSizes]);
108
+ var scrollRef = useRef(null);
109
+ useLayoutEffect(function () {
110
+ if (scrollRef.current) {
111
+ scrollRef.current.scrollTop = 0;
112
+ }
113
+ }, [contentKey]);
114
+ var _useMotion2 = useMotion(),
115
+ state = _useMotion2.state,
116
+ motionRef = _useMotion2.ref;
117
+ var isMotionUpliftEnabled = fg('platform-dst-motion-uplift-panel');
118
+ var isContentMotionEnabled = fg('platform-dst-motion-uplift-panel-content');
119
+ var mergedRef = useMemo(function () {
120
+ return isMotionUpliftEnabled ? mergeRefs([ref, motionRef]) : ref;
121
+ }, [isMotionUpliftEnabled, motionRef]);
122
+ var mode = (_managedSizing$mode = managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) !== null && _managedSizing$mode !== void 0 ? _managedSizing$mode : 'overlay';
123
+ var managedMode = useStableRef(managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode);
124
+ // Resize preparation can load the coordinator after the interaction starts.
125
+ // Read its latest mode instead of the pre-load callback's captured fallback.
126
+ var getMode = useCallback(function () {
127
+ if (managedMode.current) {
128
+ return managedMode.current;
129
+ }
130
+ return ref.current && getComputedStyle(ref.current).gridArea.split('/')[0].trim() === 'panel' ? 'inline' : 'overlay';
131
+ }, [managedMode]);
132
+ var dragMode = useRef('overlay');
133
+ var completedResizeModeRef = useRef(mode);
134
+ var renderedWidth = (_managedSizing$width = managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.width) !== null && _managedSizing$width !== void 0 ? _managedSizing$width : Math.max(minWidth, Math.min(defaultWidth, maxWidth !== null && maxWidth !== void 0 ? maxWidth : Infinity));
135
+ // Before the first measurement, CSS caps the surface to its containing region.
136
+ // Resize preparation waits for the coordinator to resolve the same bounds for both inputs.
137
+ var getResizeBounds = useCallback(function () {
138
+ var _getManagedResizeBoun;
139
+ return (_getManagedResizeBoun = getManagedResizeBounds()) !== null && _getManagedResizeBoun !== void 0 ? _getManagedResizeBoun : {
140
+ min: '0px',
141
+ max: '0px'
142
+ };
143
+ }, [getManagedResizeBounds]);
144
+ var onCompleteResize = useCallback(function (width) {
145
+ // Keyboard analytics are debounced; retain the mode that produced this width,
146
+ // rather than the layout mode when the delayed callback eventually runs.
147
+ var mode = getMode();
148
+ completedResizeModeRef.current = mode;
149
+ onManagedResizeEnd(mode, width);
150
+ onWidthChange(width);
151
+ }, [getMode, onManagedResizeEnd, onWidthChange]);
152
+ var onResizeStartInternal = useCallback(function () {
153
+ dragMode.current = getMode();
154
+ onManagedResizeStart(dragMode.current);
155
+ }, [getMode, onManagedResizeStart]);
156
+ var onResizeInternal = useCallback(function (width) {
157
+ return onManagedResize(dragMode.current, width);
158
+ }, [onManagedResize]);
159
+ var handleResizeEnd = useCallback(function (event) {
160
+ return onResizeEnd(_objectSpread(_objectSpread({}, event), {}, {
161
+ mode: completedResizeModeRef.current
162
+ }));
163
+ }, [onResizeEnd]);
164
+ return /*#__PURE__*/React.createElement("section", {
165
+ "aria-label": label,
166
+ "data-testid": testId,
167
+ "data-layout-with-panel-slot": "",
168
+ style: _defineProperty({}, localPanelVar, "".concat(renderedWidth, "px")),
169
+ ref: mergedRef,
170
+ className: ax([isMotionUpliftEnabled && state === 'entering' && styles.entering, isMotionUpliftEnabled && state === 'exiting' && styles.exiting, styles.panelWrapper, styles.border, !managedSizing && styles.unmeasured, (managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) === 'inline' && styles.managedInline, (managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) === 'overlay' && styles.managedOverlay, (managedSizing === null || managedSizing === void 0 ? void 0 : managedSizing.mode) === 'inline' && styles.managedInlineBorder])
171
+ }, /*#__PURE__*/React.createElement(PanelSplitterProvider, {
172
+ panelId: localPanelSplitterId,
173
+ panelRef: ref,
174
+ resizingElementRef: layoutRef,
175
+ panelWidth: renderedWidth,
176
+ onCompleteResize: onCompleteResize,
177
+ prepareResize: prepareResize,
178
+ onResizeStartInternal: onResizeStartInternal,
179
+ onResizeInternal: onResizeInternal,
180
+ getResizeBounds: getResizeBounds,
181
+ isEnabled: managedSizing !== undefined || prepareResize !== undefined,
182
+ resizingCssVar: panelSplitterResizingVar,
183
+ position: "start"
184
+ }, /*#__PURE__*/React.createElement("div", {
185
+ ref: scrollRef,
186
+ "data-testid": testId && "".concat(testId, "--scroll-container"),
187
+ className: ax([styles.panelScrollContainer, state === 'entering' && styles.contentEntering, isMotionUpliftEnabled && state === 'entering' && contentEnteringDelayStyles.root, state === 'exiting' && styles.contentExiting])
188
+ }, isContentMotionEnabled && contentKey !== undefined ? /*#__PURE__*/React.createElement(ExitingPersistence, {
189
+ exitThenEnter: true
190
+ }, /*#__PURE__*/React.createElement(PanelContentMotion, {
191
+ key: contentKey
192
+ }, children)) : children, /*#__PURE__*/React.createElement(PanelSplitter, {
193
+ label: resizeLabel,
194
+ testId: testId && "".concat(testId, "--splitter"),
195
+ onResizeEnd: handleResizeEnd
196
+ }))));
197
+ }
@@ -5,7 +5,8 @@ import { ax, ix } from "@compiled/react/runtime";
5
5
  import { Fragment } from 'react';
6
6
  import { fg } from '@atlaskit/platform-feature-flags/fg';
7
7
  import { useSkipLink } from '../../../context/skip-links/use-skip-link';
8
- import { mainMinimumWidthVar } from '../constants';
8
+ import { defaultMainMinWidth, mainMinimumWidthVar } from '../constants';
9
+ import { MainMinWidthContext } from '../main-min-width-context';
9
10
  import { gridRootFitId, gridRootId } from '../root';
10
11
  import { useLayoutId } from '../use-layout-id';
11
12
  import { useLayoutMainSizing } from '../use-layout-main-sizing';
@@ -26,7 +27,7 @@ export function Main(_ref) {
26
27
  testId = _ref.testId,
27
28
  providedId = _ref.id,
28
29
  _ref$minWidth = _ref.minWidth,
29
- minWidth = _ref$minWidth === void 0 ? 320 : _ref$minWidth;
30
+ minWidth = _ref$minWidth === void 0 ? defaultMainMinWidth : _ref$minWidth;
30
31
  var id = useLayoutId({
31
32
  providedId: providedId
32
33
  });
@@ -41,5 +42,7 @@ export function Main(_ref) {
41
42
  className: ax([mainElementStyles.root, xcss]),
42
43
  role: "main",
43
44
  "data-testid": testId
44
- }, children));
45
+ }, /*#__PURE__*/React.createElement(MainMinWidthContext.Provider, {
46
+ value: fg('platform-dst-chat-panel-layout') ? minWidth : defaultMainMinWidth
47
+ }, children)));
45
48
  }
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'react';
2
+ import { defaultMainMinWidth } from './constants';
3
+
4
+ // Available during SSR, before Main registers with the measured sizing coordinator.
5
+ export var MainMinWidthContext = /*#__PURE__*/createContext(defaultMainMinWidth);
@@ -0,0 +1,27 @@
1
+ ._nd5l1gzg{grid-area:main}._129o1uuk{--p_lclPnlSsrPreferredW:var(--p_lclPnlCompactW)}
2
+ ._18m915vq{overflow-y:hidden}
3
+ ._18m91wug{overflow-y:auto}
4
+ ._19121cl4{isolation:isolate}
5
+ ._1bsb1osq{width:100%}
6
+ ._1e0c11p5{display:grid}
7
+ ._1e0c1txw{display:flex}
8
+ ._1f38177r{container-name:local-panel-layout}
9
+ ._1l7c1wug._1l7c1wug{grid-template-rows:auto}
10
+ ._1l7chkll._1l7chkll{grid-template-rows:1fr}
11
+ ._1lmc1m6a{grid-template-areas:"main"}
12
+ ._1lmcc53r{grid-template-areas:var(--p_lclPnlSsrAreas,"main")}
13
+ ._1reo15vq{overflow-x:hidden}
14
+ ._1reo1wug{overflow-x:auto}
15
+ ._1uwq15vq._1uwq15vq{overflow-x:hidden}
16
+ ._2z05hkll{grid-template-rows:1fr}
17
+ ._4t3i1osq{height:100%}
18
+ ._7cca15wb{container-type:inline-size}
19
+ ._82e815vq._82e815vq{overflow-y:hidden}
20
+ ._evra4a59{--p_lclPnlSsrInlineAreas:"main panel"}
21
+ ._f8371m6a._f8371m6a{grid-template-areas:"main"}
22
+ ._f8374a59._f8374a59{grid-template-areas:"main panel"}
23
+ ._vleg1orf._vleg1orf{grid-template-columns:minmax(var(--n_mainMinW,20pc),1fr) clamp(var(--p_lclPnlMinW),var(--p_lclPnlRsz,var(--p_lclPnlTrackW)),calc(100% - var(--n_mainMinW, 20pc)))}
24
+ ._vlegi47z._vlegi47z{grid-template-columns:minmax(0,1fr)}
25
+ ._yv0eggl6{grid-template-columns:var(--p_lclPnlSsrColumns,minmax(0,1fr))}
26
+ ._yv0ei47z{grid-template-columns:minmax(0,1fr)}
27
+ @media (min-width:64rem){._peezi77x{--p_lclPnlSsrPreferredW:var(--p_lclPnlTrackW)}}
@@ -0,0 +1,59 @@
1
+ /* panel-layout-shell.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import "./panel-layout-shell.compiled.css";
4
+ import * as React from 'react';
5
+ import { ax, ix } from "@compiled/react/runtime";
6
+ import { useContext, useId } from 'react';
7
+ import { MainMinWidthContext } from './main-min-width-context';
8
+
9
+ // The grid uses runtime CSS variables and container sizing outside @atlaskit/css's bounded values.
10
+ var localPanelTrackWidthVar = '--p_lclPnlTrackW';
11
+ var localPanelResizingVar = '--p_lclPnlRsz';
12
+ var localPanelMinWidthVar = '--p_lclPnlMinW';
13
+ var styles = {
14
+ container: "_1f38177r _7cca15wb _4t3i1osq _1bsb1osq",
15
+ layout: "_1reo1wug _18m91wug _1e0c11p5 _7cca15wb _1lmc1m6a _yv0ei47z _2z05hkll _4t3i1osq _1bsb1osq",
16
+ mainContent: "_nd5l1gzg _1reo1wug _18m91wug _1e0c1txw _4t3i1osq _19121cl4",
17
+ panelUplift: "_1reo15vq _18m915vq",
18
+ unmeasured: "_evra4a59 _1lmcc53r _yv0eggl6 _129o1uuk _peezi77x",
19
+ managedInline: "_1uwq15vq _82e815vq _f8374a59 _1l7c1wug _vleg1orf",
20
+ managedOverlay: "_1uwq15vq _82e815vq _f8371m6a _vlegi47z _1l7chkll",
21
+ panelClosed: "_f8371m6a _vlegi47z _1l7chkll"
22
+ };
23
+ /**
24
+ * Grid and scrolling for Main and its local panel. Use inside navigation's Root and Main.
25
+ */
26
+ export function PanelLayoutShell(_ref) {
27
+ var children = _ref.children,
28
+ panel = _ref.panel,
29
+ isPanelOpen = _ref.isPanelOpen,
30
+ panelWidth = _ref.panelWidth,
31
+ compactPanelWidth = _ref.compactPanelWidth,
32
+ _ref$panelMinWidth = _ref.panelMinWidth,
33
+ panelMinWidth = _ref$panelMinWidth === void 0 ? 320 : _ref$panelMinWidth,
34
+ mode = _ref.mode,
35
+ layoutRef = _ref.layoutRef,
36
+ _ref$shouldClipOverfl = _ref.shouldClipOverflow,
37
+ shouldClipOverflow = _ref$shouldClipOverfl === void 0 ? false : _ref$shouldClipOverfl,
38
+ testId = _ref.testId;
39
+ var mainMinWidth = useContext(MainMinWidthContext);
40
+ var id = "local-panel-".concat(useId().replace(/[^a-zA-Z0-9_-]/g, '_'));
41
+ // CSS query conditions cannot read custom properties. Only the numeric minimums and
42
+ // instance selector are generated here; this rule is removed after the first measurement,
43
+ // so live resizing never rewrites stylesheet text. The named container is local to this shell.
44
+ var inlineQuery = "@container local-panel-layout (min-width: ".concat(mainMinWidth + panelMinWidth, "px)");
45
+ return /*#__PURE__*/React.createElement("div", {
46
+ className: ax([styles.container])
47
+ }, mode === undefined && isPanelOpen &&
48
+ /*#__PURE__*/
49
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles -- Instance-scoped SSR query supports caller-defined minimums; CSS variables are not allowed in query conditions.
50
+ React.createElement("style", null, "".concat(inlineQuery, " {\n\t\t\t\t\t#").concat(id, " {\n\t\t\t\t\t\t--p_lclPnlSsrAreas: var(--p_lclPnlSsrInlineAreas);\n\t\t\t\t\t\t--p_lclPnlSsrColumns: minmax(0, 1fr) min(var(--p_lclPnlSsrPreferredW), calc(100% - ").concat(mainMinWidth, "px));\n\t\t\t\t\t\t--p_lclPnlSsrArea: panel;\n\t\t\t\t\t\t--p_lclPnlSsrWidth: 100%;\n\t\t\t\t\t\t--p_lclPnlSsrBackground: ", "var(--ds-surface, #FFFFFF)", ";\n\t\t\t\t\t\t--p_lclPnlSsrShadow: none;\n\t\t\t\t\t\t--p_lclPnlSsrBorder: ", "var(--ds-border-width, 1px)", " solid ", "var(--ds-border, #0B120E24)", ";\n\t\t\t\t\t}\n\t\t\t\t}")), /*#__PURE__*/React.createElement("div", {
51
+ id: id,
52
+ "data-testid": testId,
53
+ ref: layoutRef,
54
+ style: _defineProperty(_defineProperty(_defineProperty({}, localPanelTrackWidthVar, "".concat(panelWidth, "px")), localPanelMinWidthVar, "".concat(panelMinWidth, "px")), '--p_lclPnlCompactW', "".concat(compactPanelWidth, "px")),
55
+ className: ax([styles.layout, mode === undefined && isPanelOpen && styles.unmeasured, shouldClipOverflow && styles.panelUplift, mode === 'inline' && styles.managedInline, mode === 'overlay' && styles.managedOverlay, !isPanelOpen && styles.panelClosed])
56
+ }, /*#__PURE__*/React.createElement("div", {
57
+ className: ax([styles.mainContent])
58
+ }, children), panel));
59
+ }
@@ -0,0 +1,154 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
3
+ import invariant from 'tiny-invariant';
4
+ import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
5
+ import ExitingPersistence from '@atlaskit/motion/exiting-persistence';
6
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
7
+ import { getPanelLayoutDefaults } from './get-panel-layout-defaults';
8
+ import { LayoutAreaSizingContext } from './layout-area-sizing-context';
9
+ import { LayoutAreaSizingProvider } from './layout-area-sizing-provider';
10
+ import { LocalPanelSurface } from './local-panel-surface';
11
+ import { PanelLayoutShell } from './panel-layout-shell';
12
+ import { useLayoutAreaSizing } from './use-layout-area-sizing';
13
+
14
+ // Development-only ownership checks are scoped to each coordinator, not the whole page.
15
+ var mountedPanelLayouts = new WeakSet();
16
+ function CoordinatedPanelLayout(_ref) {
17
+ var _ref2, _ref3, _ref4, _state$width;
18
+ var children = _ref.children,
19
+ panel = _ref.panel,
20
+ isPanelOpen = _ref.isPanelOpen,
21
+ panelKey = _ref.panelKey,
22
+ panelWidth = _ref.panelWidth,
23
+ defaultPanelWidth = _ref.defaultPanelWidth,
24
+ compactDefaultPanelWidth = _ref.compactDefaultPanelWidth,
25
+ suppliedMinWidth = _ref.panelMinWidth,
26
+ panelMaxWidth = _ref.panelMaxWidth,
27
+ onPanelWidthChange = _ref.onPanelWidthChange,
28
+ onResizeEnd = _ref.onResizeEnd,
29
+ _ref$panelLabel = _ref.panelLabel,
30
+ panelLabel = _ref$panelLabel === void 0 ? 'Panel' : _ref$panelLabel,
31
+ _ref$resizeLabel = _ref.resizeLabel,
32
+ resizeLabel = _ref$resizeLabel === void 0 ? 'Resize panel' : _ref$resizeLabel,
33
+ testId = _ref.testId,
34
+ layoutRef = _ref.layoutRef;
35
+ var _useState = useState(getPanelLayoutDefaults),
36
+ _useState2 = _slicedToArray(_useState, 1),
37
+ defaults = _useState2[0];
38
+ var panelMinWidth = suppliedMinWidth !== null && suppliedMinWidth !== void 0 ? suppliedMinWidth : defaults.panelMinWidth;
39
+ var coordinator = useContext(LayoutAreaSizingContext);
40
+ useEffect(function () {
41
+ if (process.env.NODE_ENV !== 'production' && coordinator) {
42
+ invariant(!mountedPanelLayouts.has(coordinator), 'Only one PanelLayout may be mounted per navigation Root/sizing coordinator, including closed hosts and LayoutWithPanel. Reuse the host to switch panel content.');
43
+ mountedPanelLayouts.add(coordinator);
44
+ return function () {
45
+ mountedPanelLayouts.delete(coordinator);
46
+ };
47
+ }
48
+ }, [coordinator]);
49
+ var _useState3 = useState((_ref2 = defaultPanelWidth !== null && defaultPanelWidth !== void 0 ? defaultPanelWidth : panelWidth) !== null && _ref2 !== void 0 ? _ref2 : defaults.panelWidth),
50
+ _useState4 = _slicedToArray(_useState3, 1),
51
+ defaultWidth = _useState4[0];
52
+ var _useState5 = useState((_ref3 = (_ref4 = compactDefaultPanelWidth !== null && compactDefaultPanelWidth !== void 0 ? compactDefaultPanelWidth : defaultPanelWidth) !== null && _ref4 !== void 0 ? _ref4 : panelWidth) !== null && _ref3 !== void 0 ? _ref3 : defaults.compactPanelWidth),
53
+ _useState6 = _slicedToArray(_useState5, 1),
54
+ compactWidth = _useState6[0];
55
+ // Use the controlled request before measurement too, without changing the mount-time default.
56
+ var fallbackWidth = Math.max(panelMinWidth, Math.min(panelWidth !== null && panelWidth !== void 0 ? panelWidth : defaultWidth, panelMaxWidth !== null && panelMaxWidth !== void 0 ? panelMaxWidth : Infinity));
57
+ var _useLayoutAreaSizing = useLayoutAreaSizing({
58
+ area: 'panel',
59
+ config: {
60
+ isOpen: isPanelOpen,
61
+ requestedWidth: panelWidth,
62
+ defaultWidth: defaultWidth,
63
+ compactDefaultWidth: compactWidth,
64
+ minWidth: panelMinWidth,
65
+ maxWidth: panelMaxWidth
66
+ }
67
+ }),
68
+ state = _useLayoutAreaSizing.state,
69
+ prepareResize = _useLayoutAreaSizing.prepareResize,
70
+ getResizeBounds = _useLayoutAreaSizing.getResizeBounds,
71
+ startResize = _useLayoutAreaSizing.startResize,
72
+ resize = _useLayoutAreaSizing.resize,
73
+ completeResize = _useLayoutAreaSizing.completeResize;
74
+ // Host callback identity is unrelated to sizing. Keep drag bindings stable while
75
+ // still delivering completions to the latest product-owned state and analytics.
76
+ var onWidthChangeRef = useStableRef(onPanelWidthChange);
77
+ var onResizeEndRef = useStableRef(onResizeEnd);
78
+ var handleWidthChange = useCallback(function (width) {
79
+ var _onWidthChangeRef$cur;
80
+ return (_onWidthChangeRef$cur = onWidthChangeRef.current) === null || _onWidthChangeRef$cur === void 0 ? void 0 : _onWidthChangeRef$cur.call(onWidthChangeRef, width);
81
+ }, [onWidthChangeRef]);
82
+ var handleResizeEnd = useCallback(function (event) {
83
+ var _onResizeEndRef$curre;
84
+ return (_onResizeEndRef$curre = onResizeEndRef.current) === null || _onResizeEndRef$curre === void 0 ? void 0 : _onResizeEndRef$curre.call(onResizeEndRef, event);
85
+ }, [onResizeEndRef]);
86
+ var isMotionEnabled = fg('platform-dst-motion-uplift-panel');
87
+ var surface = isPanelOpen && /*#__PURE__*/React.createElement(LocalPanelSurface, {
88
+ key: "local-panel",
89
+ contentKey: panelKey,
90
+ defaultWidth: fallbackWidth,
91
+ minWidth: panelMinWidth,
92
+ maxWidth: panelMaxWidth,
93
+ layoutRef: layoutRef,
94
+ managedSizing: state,
95
+ getManagedResizeBounds: getResizeBounds,
96
+ prepareResize: prepareResize,
97
+ onManagedResizeStart: startResize,
98
+ onManagedResize: resize,
99
+ onManagedResizeEnd: completeResize,
100
+ onWidthChange: handleWidthChange,
101
+ onResizeEnd: handleResizeEnd,
102
+ label: panelLabel,
103
+ resizeLabel: resizeLabel,
104
+ testId: testId && "".concat(testId, "--panel-slot")
105
+ }, panel);
106
+ return /*#__PURE__*/React.createElement(PanelLayoutShell, {
107
+ isPanelOpen: isPanelOpen,
108
+ panelWidth: (_state$width = state === null || state === void 0 ? void 0 : state.width) !== null && _state$width !== void 0 ? _state$width : fallbackWidth,
109
+ compactPanelWidth: Math.max(panelMinWidth, Math.min(panelWidth !== null && panelWidth !== void 0 ? panelWidth : compactWidth, panelMaxWidth !== null && panelMaxWidth !== void 0 ? panelMaxWidth : Infinity)),
110
+ panelMinWidth: panelMinWidth,
111
+ mode: state === null || state === void 0 ? void 0 : state.mode,
112
+ layoutRef: layoutRef,
113
+ shouldClipOverflow: isMotionEnabled,
114
+ testId: testId,
115
+ panel: isMotionEnabled ? /*#__PURE__*/React.createElement(ExitingPersistence, null, surface) : surface
116
+ }, children);
117
+ }
118
+
119
+ /**
120
+ * A coordinated local panel with caller-owned content and state. Keep this host mounted
121
+ * while closed to retain resized widths. Unmount it to reset its width preferences.
122
+ *
123
+ * Mount only one local-panel host per navigation Root/sizing coordinator, including
124
+ * closed hosts and panel-system's LayoutWithPanel. Switch content through the same host;
125
+ * separate Roots may each own a local panel.
126
+ *
127
+ * With chat layout enabled it shares Root's sizing coordinator. Otherwise it measures
128
+ * its own Main region, leaving existing navigation/chat behavior unchanged.
129
+ * Local-panel placement and resize constraints use this layout in both cases; disabling
130
+ * the chat-layout gate does not restore the previous panel-system layout engine.
131
+ */
132
+ export function PanelLayout(props) {
133
+ var parentSizing = useContext(LayoutAreaSizingContext);
134
+ var layoutRef = useRef(null);
135
+ var content = /*#__PURE__*/React.createElement(CoordinatedPanelLayout, {
136
+ layoutRef: layoutRef,
137
+ panel: props.panel,
138
+ isPanelOpen: props.isPanelOpen,
139
+ panelKey: props.panelKey,
140
+ panelWidth: props.panelWidth,
141
+ defaultPanelWidth: props.defaultPanelWidth,
142
+ compactDefaultPanelWidth: props.compactDefaultPanelWidth,
143
+ panelMinWidth: props.panelMinWidth,
144
+ panelMaxWidth: props.panelMaxWidth,
145
+ onPanelWidthChange: props.onPanelWidthChange,
146
+ onResizeEnd: props.onResizeEnd,
147
+ panelLabel: props.panelLabel,
148
+ resizeLabel: props.resizeLabel,
149
+ testId: props.testId
150
+ }, props.children);
151
+ return parentSizing ? content : /*#__PURE__*/React.createElement(LayoutAreaSizingProvider, {
152
+ layoutRef: layoutRef
153
+ }, content);
154
+ }
@@ -26,6 +26,7 @@ import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util
26
26
  import { preventUnhandled } from '@atlaskit/pragmatic-drag-and-drop/utils/prevent-unhandled';
27
27
  import Tooltip from '@atlaskit/tooltip/Tooltip';
28
28
  import TooltipContainer from '@atlaskit/tooltip/TooltipContainer';
29
+ import { requestClosePopovers } from '@atlaskit/top-layer/page-surface/request-close-popovers';
29
30
  import VisuallyHidden from '@atlaskit/visually-hidden/visually-hidden';
30
31
  import { contentInsetBlockStart } from '../constants';
31
32
  import { convertResizeBoundToPixels } from './convert-resize-bound-to-pixels';
@@ -168,7 +169,9 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
168
169
  _useState4 = _slicedToArray(_useState3, 2),
169
170
  rangeInputBounds = _useState4[0],
170
171
  setRangeInputBounds = _useState4[1];
171
- var openLayerObserver = useOpenLayerObserver();
172
+ var openLayerObserver = useOpenLayerObserver({
173
+ isEnabled: !fg('platform-dst-top-layer')
174
+ });
172
175
 
173
176
  /**
174
177
  * This is a temporary workaround to enable the `SideNavPanelSplitter` component
@@ -182,7 +185,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
182
185
  var initialClientXRef = useRef(null);
183
186
  // Live allocation changes panelWidth on every frame. Only the legacy path should
184
187
  // rebind the drag listeners when this value changes.
185
- var legacyPanelWidth = fg('platform-dst-chat-panel-layout') ? undefined : panelWidth;
188
+ var legacyPanelWidth = fg('platform-dst-chat-panel-layout') || onResizeInternal ? undefined : panelWidth;
186
189
  useEffect(function () {
187
190
  var splitter = splitterRef.current;
188
191
  invariant(splitter, 'Splitter ref must be set');
@@ -259,6 +262,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
259
262
  onResizeStart === null || onResizeStart === void 0 || onResizeStart(resizeStartData);
260
263
 
261
264
  // Close any open layers when the user starts resizing
265
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
266
+ requestClosePopovers();
262
267
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
263
268
  },
264
269
  onDrag: function onDrag(_ref6) {
@@ -289,7 +294,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
289
294
  position: position
290
295
  });
291
296
  var resizingWidth = "clamp(".concat(resizeBounds.min, ", ").concat(targetWidth, "px, ").concat(resizeBounds.max, ")");
292
- if (fg('platform-dst-chat-panel-layout') && onResizeInternal) {
297
+ if (onResizeInternal) {
293
298
  // The allocator needs below-minimum requests for the local-to-chat cascade.
294
299
  var currentBounds = getResizeBounds();
295
300
  var width = Math.max(0, Math.min(targetWidth, prepareResize ? window.innerWidth : convertResizeBoundToPixels(currentBounds.max)));
@@ -345,7 +350,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
345
350
  }
346
351
  finalWidth = getPixelWidth(panel); // Persist the final preferred width before removing the imperative drag
347
352
  // variable, so the rendered width is continuous across pointer release.
348
- if (fg('platform-dst-chat-panel-layout')) {
353
+ if (fg('platform-dst-chat-panel-layout') || onResizeInternal) {
349
354
  flushSync(function () {
350
355
  return onCompleteResize(finalWidth);
351
356
  });
@@ -374,6 +379,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
374
379
  onResizeStart: function onResizeStart() {
375
380
  var _onResizeStartStableR;
376
381
  // Close any open layers when the user starts resizing with keyboard
382
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
383
+ requestClosePopovers();
377
384
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
378
385
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
379
386
  args[_key] = arguments[_key];
@@ -400,7 +407,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
400
407
  return _regeneratorRuntime.wrap(function (_context2) {
401
408
  while (1) switch (_context2.prev = _context2.next) {
402
409
  case 0:
403
- isManagedResize = fg('platform-dst-chat-panel-layout') && onResizeInternal;
410
+ isManagedResize = onResizeInternal;
404
411
  sequence = focusSequence.current;
405
412
  value = isManagedResize ? parseFloat(event.currentTarget.value) : parseInt(event.currentTarget.value);
406
413
  if (!prepareResize) {
@@ -69,6 +69,8 @@ export function Root(_ref2) {
69
69
  var isChatPanelLayoutEnabled = fg('platform-dst-chat-panel-layout');
70
70
  var LayoutProvider = isChatPanelLayoutEnabled ? LayoutAreaSizingProvider : React.Fragment;
71
71
  var WidthContainer = isChatPanelLayoutEnabled ? LayoutFitContainers : React.Fragment;
72
+ // Top-layer surfaces are found through the DOM, so the observer is only needed when the gate is off.
73
+ var LayerObserverProvider = fg('platform-dst-top-layer') ? React.Fragment : OpenLayerObserver;
72
74
  useEffect(function () {
73
75
  if (process.env.NODE_ENV !== 'production') {
74
76
  var IGNORED_ELEMENTS = ['SCRIPT', 'STYLE'];
@@ -91,7 +93,7 @@ export function Root(_ref2) {
91
93
  isSideNavShortcutEnabled: isSideNavShortcutEnabled
92
94
  }, /*#__PURE__*/React.createElement(TopNavStartProvider, null, /*#__PURE__*/React.createElement(LayoutProvider, isChatPanelLayoutEnabled ? {
93
95
  layoutRef: ref
94
- } : {}, /*#__PURE__*/React.createElement(OpenLayerObserver, null, /*#__PURE__*/React.createElement(DangerouslyHoistSlotSizes.Provider, {
96
+ } : {}, /*#__PURE__*/React.createElement(LayerObserverProvider, null, /*#__PURE__*/React.createElement(DangerouslyHoistSlotSizes.Provider, {
95
97
  value: UNSAFE_dangerouslyHoistSlotSizes
96
98
  }, /*#__PURE__*/React.createElement(SkipLinksProvider, {
97
99
  label: skipLinksLabel,
@@ -0,0 +1,50 @@
1
+ import { bindAll } from 'bind-event-listener';
2
+ /**
3
+ * Calls `onChange` after any popover or dialog inside `within` opens or closes.
4
+ * Read the new state with `hasOpenDialogOrPopover`.
5
+ *
6
+ * `beforetoggle`, `toggle` and `close` do not bubble, so they are observed in the capture phase.
7
+ *
8
+ * `toggle` and `close` are queued tasks. When a surface closes because it unmounts,
9
+ * they fire after the element has left the DOM, so they never reach `within`.
10
+ * `beforetoggle` fires synchronously while the element is still inside `within`,
11
+ * so it also schedules `onChange` in a microtask, after the state has changed.
12
+ */
13
+ export function bindOpenLayerChange(_ref) {
14
+ var within = _ref.within,
15
+ onChange = _ref.onChange;
16
+ var isBound = true;
17
+ function listener() {
18
+ onChange();
19
+ }
20
+ function deferredListener() {
21
+ queueMicrotask(function () {
22
+ if (isBound) {
23
+ onChange();
24
+ }
25
+ });
26
+ }
27
+ var unbind = bindAll(within, [{
28
+ type: 'beforetoggle',
29
+ listener: deferredListener,
30
+ options: {
31
+ capture: true
32
+ }
33
+ }, {
34
+ type: 'toggle',
35
+ listener: listener,
36
+ options: {
37
+ capture: true
38
+ }
39
+ }, {
40
+ type: 'close',
41
+ listener: listener,
42
+ options: {
43
+ capture: true
44
+ }
45
+ }]);
46
+ return function cleanup() {
47
+ isBound = false;
48
+ unbind();
49
+ };
50
+ }