@atlaskit/navigation-system 11.3.0 → 11.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/ui/page-layout/calculate-layout-area-states.js +76 -37
- package/dist/cjs/ui/page-layout/chat-panel.js +6 -3
- package/dist/cjs/ui/page-layout/layout-area-sizing-context.js +2 -2
- package/dist/cjs/ui/page-layout/layout-area-sizing-provider.js +243 -247
- package/dist/cjs/ui/page-layout/layout-area-sizing-runtime.js +468 -0
- package/dist/cjs/ui/page-layout/main/main.js +1 -1
- package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +239 -99
- package/dist/cjs/ui/page-layout/panel-splitter/provider.js +3 -1
- package/dist/cjs/ui/page-layout/root.compiled.css +14 -3
- package/dist/cjs/ui/page-layout/root.js +43 -17
- package/dist/cjs/ui/page-layout/side-nav/side-nav.js +14 -3
- package/dist/cjs/ui/page-layout/use-css-layout-area-states.js +117 -0
- package/dist/cjs/ui/page-layout/use-layout-area-sizing.js +3 -1
- package/dist/es2019/ui/page-layout/calculate-layout-area-states.js +51 -17
- package/dist/es2019/ui/page-layout/chat-panel.js +29 -5
- package/dist/es2019/ui/page-layout/layout-area-sizing-context.js +2 -2
- package/dist/es2019/ui/page-layout/layout-area-sizing-provider.js +171 -241
- package/dist/es2019/ui/page-layout/layout-area-sizing-runtime.js +419 -0
- package/dist/es2019/ui/page-layout/main/main.js +2 -2
- package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +60 -10
- package/dist/es2019/ui/page-layout/panel-splitter/provider.js +3 -1
- package/dist/es2019/ui/page-layout/root.compiled.css +14 -3
- package/dist/es2019/ui/page-layout/root.js +30 -3
- package/dist/es2019/ui/page-layout/side-nav/side-nav.js +23 -3
- package/dist/es2019/ui/page-layout/use-css-layout-area-states.js +73 -0
- package/dist/es2019/ui/page-layout/use-layout-area-sizing.js +3 -1
- package/dist/esm/ui/page-layout/calculate-layout-area-states.js +75 -37
- package/dist/esm/ui/page-layout/chat-panel.js +7 -4
- package/dist/esm/ui/page-layout/layout-area-sizing-context.js +2 -2
- package/dist/esm/ui/page-layout/layout-area-sizing-provider.js +243 -248
- package/dist/esm/ui/page-layout/layout-area-sizing-runtime.js +459 -0
- package/dist/esm/ui/page-layout/main/main.js +2 -2
- package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +238 -98
- package/dist/esm/ui/page-layout/panel-splitter/provider.js +3 -1
- package/dist/esm/ui/page-layout/root.compiled.css +14 -3
- package/dist/esm/ui/page-layout/root.js +42 -16
- package/dist/esm/ui/page-layout/side-nav/side-nav.js +14 -3
- package/dist/esm/ui/page-layout/use-css-layout-area-states.js +110 -0
- package/dist/esm/ui/page-layout/use-layout-area-sizing.js +3 -1
- package/dist/types/ui/page-layout/calculate-layout-area-states.d.ts +7 -2
- package/dist/types/ui/page-layout/layout-area-sizing-context.d.ts +10 -3
- package/dist/types/ui/page-layout/layout-area-sizing-provider.d.ts +6 -0
- package/dist/types/ui/page-layout/layout-area-sizing-runtime.d.ts +8 -0
- package/dist/types/ui/page-layout/panel-splitter/panel-splitter-context.d.ts +4 -0
- package/dist/types/ui/page-layout/panel-splitter/provider.d.ts +1 -1
- package/dist/types/ui/page-layout/root.d.ts +2 -0
- package/dist/types/ui/page-layout/use-css-layout-area-states.d.ts +8 -0
- package/dist/types/ui/page-layout/use-layout-area-sizing.d.ts +2 -0
- package/package.json +12 -6
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { bind } from 'bind-event-listener';
|
|
3
|
+
import { calculateLayoutAreaStates } from './calculate-layout-area-states';
|
|
4
|
+
import { LayoutAreaSizingContext } from './layout-area-sizing-context';
|
|
5
|
+
import { layoutAreaStateContexts } from './layout-area-state-contexts';
|
|
6
|
+
import { resolveLayoutWidth } from './resolve-layout-width';
|
|
7
|
+
import { useOccupiedLayoutWidth } from './use-occupied-layout-width';
|
|
8
|
+
const defaultMainMinWidth = 320;
|
|
9
|
+
function useStableAreaState(state) {
|
|
10
|
+
const {
|
|
11
|
+
mode,
|
|
12
|
+
width,
|
|
13
|
+
minWidth
|
|
14
|
+
} = state !== null && state !== void 0 ? state : {};
|
|
15
|
+
return useMemo(() => mode !== undefined && width !== undefined && minWidth !== undefined ? {
|
|
16
|
+
mode,
|
|
17
|
+
width,
|
|
18
|
+
minWidth
|
|
19
|
+
} : undefined, [mode, width, minWidth]);
|
|
20
|
+
}
|
|
21
|
+
export function LayoutAreaSizingRuntime({
|
|
22
|
+
children,
|
|
23
|
+
layoutRef,
|
|
24
|
+
onReady,
|
|
25
|
+
onUpdate
|
|
26
|
+
}) {
|
|
27
|
+
const occupiedWidth = useOccupiedLayoutWidth(layoutRef);
|
|
28
|
+
const [dimensions, setDimensions] = useState(null);
|
|
29
|
+
const [mainMinWidth, setMainMinWidth] = useState(defaultMainMinWidth);
|
|
30
|
+
const [areas, setAreas] = useState({});
|
|
31
|
+
const [resizeSession, setResizeSession] = useState(null);
|
|
32
|
+
const areaStatesRef = React.useRef({});
|
|
33
|
+
const configsRef = React.useRef({});
|
|
34
|
+
const [hasInteraction, setHasInteraction] = useState(false);
|
|
35
|
+
const adoptedConstraints = React.useRef(null);
|
|
36
|
+
// Preserve the CSS handoff only while its available space is unchanged.
|
|
37
|
+
const isPreservingInitialLayout = !hasInteraction && (!adoptedConstraints.current || adoptedConstraints.current.occupiedWidth === occupiedWidth && adoptedConstraints.current.mainMinWidth === mainMinWidth);
|
|
38
|
+
const [initialStates, setInitialStates] = useState({});
|
|
39
|
+
const inputsRef = React.useRef({
|
|
40
|
+
dimensions,
|
|
41
|
+
occupiedWidth,
|
|
42
|
+
mainMinWidth,
|
|
43
|
+
areas,
|
|
44
|
+
resizeSession
|
|
45
|
+
});
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
inputsRef.current = {
|
|
48
|
+
dimensions,
|
|
49
|
+
occupiedWidth,
|
|
50
|
+
mainMinWidth,
|
|
51
|
+
areas,
|
|
52
|
+
resizeSession
|
|
53
|
+
};
|
|
54
|
+
}, [dimensions, occupiedWidth, mainMinWidth, areas, resizeSession]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (adoptedConstraints.current && (adoptedConstraints.current.occupiedWidth !== occupiedWidth || adoptedConstraints.current.mainMinWidth !== mainMinWidth)) {
|
|
57
|
+
setHasInteraction(true);
|
|
58
|
+
}
|
|
59
|
+
setResizeSession(null);
|
|
60
|
+
}, [mainMinWidth, occupiedWidth]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const root = layoutRef === null || layoutRef === void 0 ? void 0 : layoutRef.current;
|
|
63
|
+
let previous = null;
|
|
64
|
+
// Match the actual rem-based grid breakpoint, including browser font settings.
|
|
65
|
+
const inlineChatQuery = window.matchMedia('(min-width: 40rem)');
|
|
66
|
+
const inlineSideNavQuery = window.matchMedia('(min-width: 64rem)');
|
|
67
|
+
const updateDimensions = contentWidth => {
|
|
68
|
+
var _style$width, _style$paddingLeft, _style$paddingRight, _style$borderLeftWidt, _style$borderRightWid, _previous;
|
|
69
|
+
const style = root && contentWidth === undefined ? getComputedStyle(root) : null;
|
|
70
|
+
const computedWidth = Number.parseFloat((_style$width = style === null || style === void 0 ? void 0 : style.width) !== null && _style$width !== void 0 ? _style$width : '');
|
|
71
|
+
const padding = (parseFloat((_style$paddingLeft = style === null || style === void 0 ? void 0 : style.paddingLeft) !== null && _style$paddingLeft !== void 0 ? _style$paddingLeft : '') || 0) + (parseFloat((_style$paddingRight = style === null || style === void 0 ? void 0 : style.paddingRight) !== null && _style$paddingRight !== void 0 ? _style$paddingRight : '') || 0);
|
|
72
|
+
const border = (parseFloat((_style$borderLeftWidt = style === null || style === void 0 ? void 0 : style.borderLeftWidth) !== null && _style$borderLeftWidt !== void 0 ? _style$borderLeftWidt : '') || 0) + (parseFloat((_style$borderRightWid = style === null || style === void 0 ? void 0 : style.borderRightWidth) !== null && _style$borderRightWid !== void 0 ? _style$borderRightWid : '') || 0);
|
|
73
|
+
const layoutWidth = contentWidth !== null && contentWidth !== void 0 ? contentWidth : root ?
|
|
74
|
+
// Keep fractional CSS pixels, just as ResizeObserver does. Otherwise
|
|
75
|
+
// its initial delivery could be mistaken for a viewport resize.
|
|
76
|
+
Math.max(0, Number.isFinite(computedWidth) ? computedWidth - ((style === null || style === void 0 ? void 0 : style.boxSizing) === 'border-box' ? padding + border : 0) : root.clientWidth - padding) : window.innerWidth;
|
|
77
|
+
const next = {
|
|
78
|
+
viewportWidth: window.innerWidth,
|
|
79
|
+
layoutWidth,
|
|
80
|
+
isChatPanelOverlay: !inlineChatQuery.matches,
|
|
81
|
+
isSideNavOverlay: !inlineSideNavQuery.matches
|
|
82
|
+
};
|
|
83
|
+
if (((_previous = previous) === null || _previous === void 0 ? void 0 : _previous.viewportWidth) === next.viewportWidth && previous.layoutWidth === next.layoutWidth && previous.isChatPanelOverlay === next.isChatPanelOverlay && previous.isSideNavOverlay === next.isSideNavOverlay) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (previous) {
|
|
87
|
+
setHasInteraction(true);
|
|
88
|
+
}
|
|
89
|
+
previous = next;
|
|
90
|
+
setDimensions(next);
|
|
91
|
+
setResizeSession(null);
|
|
92
|
+
};
|
|
93
|
+
updateDimensions();
|
|
94
|
+
const observer = new ResizeObserver(entries => {
|
|
95
|
+
const entry = entries.find(entry => entry.target === root);
|
|
96
|
+
if (entry) {
|
|
97
|
+
updateDimensions(entry.contentRect.width);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (root) {
|
|
101
|
+
observer.observe(root);
|
|
102
|
+
}
|
|
103
|
+
const unbindResize = bind(window, {
|
|
104
|
+
type: 'resize',
|
|
105
|
+
listener: () => updateDimensions()
|
|
106
|
+
});
|
|
107
|
+
const unbindQuery = bind(inlineChatQuery, {
|
|
108
|
+
type: 'change',
|
|
109
|
+
listener: () => updateDimensions()
|
|
110
|
+
});
|
|
111
|
+
const unbindSideNavQuery = bind(inlineSideNavQuery, {
|
|
112
|
+
type: 'change',
|
|
113
|
+
listener: () => updateDimensions()
|
|
114
|
+
});
|
|
115
|
+
return () => {
|
|
116
|
+
observer.disconnect();
|
|
117
|
+
unbindResize();
|
|
118
|
+
unbindQuery();
|
|
119
|
+
unbindSideNavQuery();
|
|
120
|
+
};
|
|
121
|
+
}, [layoutRef]);
|
|
122
|
+
const registerArea = useCallback((area, config) => {
|
|
123
|
+
const previous = configsRef.current[area];
|
|
124
|
+
if (adoptedConstraints.current && (!previous || previous.isOpen !== config.isOpen || previous.requestedWidth !== config.requestedWidth || previous.minWidth !== config.minWidth || previous.maxWidth !== config.maxWidth || previous.defaultWidth !== config.defaultWidth || previous.compactDefaultWidth !== config.compactDefaultWidth)) {
|
|
125
|
+
setHasInteraction(true);
|
|
126
|
+
}
|
|
127
|
+
configsRef.current[area] = config;
|
|
128
|
+
setResizeSession(current => {
|
|
129
|
+
// A changed layout/configuration needs a fresh allocation. A controlled
|
|
130
|
+
// acknowledgement for the resized area keeps its siblings fixed.
|
|
131
|
+
return previous && (previous.isOpen === config.isOpen || area === 'side-nav' && !config.isOpen && (current === null || current === void 0 ? void 0 : current.area) !== 'side-nav') && previous.minWidth === config.minWidth && previous.maxWidth === config.maxWidth && previous.defaultWidth === config.defaultWidth && previous.compactDefaultWidth === config.compactDefaultWidth && (previous.requestedWidth === config.requestedWidth || (current === null || current === void 0 ? void 0 : current.area) === area && current.completedWidth === config.requestedWidth || area === 'side-nav' && !config.isOpen && (current === null || current === void 0 ? void 0 : current.area) !== 'side-nav') ? current : null;
|
|
132
|
+
});
|
|
133
|
+
setAreas(current => {
|
|
134
|
+
const existing = current[area];
|
|
135
|
+
return {
|
|
136
|
+
...current,
|
|
137
|
+
[area]: {
|
|
138
|
+
...existing,
|
|
139
|
+
...config,
|
|
140
|
+
liveResize: config.isOpen ? existing === null || existing === void 0 ? void 0 : existing.liveResize : undefined
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
}, []);
|
|
145
|
+
const unregisterArea = useCallback(area => {
|
|
146
|
+
if (adoptedConstraints.current) {
|
|
147
|
+
setHasInteraction(true);
|
|
148
|
+
}
|
|
149
|
+
delete configsRef.current[area];
|
|
150
|
+
setResizeSession(null);
|
|
151
|
+
setAreas(current => {
|
|
152
|
+
if (!current[area]) {
|
|
153
|
+
return current;
|
|
154
|
+
}
|
|
155
|
+
// Closing uses isOpen: false and retains preferences. Unregistering means
|
|
156
|
+
// the owning component unmounted; a replacement must start with its own defaults.
|
|
157
|
+
const next = {
|
|
158
|
+
...current
|
|
159
|
+
};
|
|
160
|
+
delete next[area];
|
|
161
|
+
return next;
|
|
162
|
+
});
|
|
163
|
+
}, []);
|
|
164
|
+
const captureSiblingWidths = useCallback((area, mode = 'inline') => {
|
|
165
|
+
const baselineWidths = {};
|
|
166
|
+
const overlayModes = {};
|
|
167
|
+
for (const areaName of ['side-nav', 'panel', 'chat-panel']) {
|
|
168
|
+
const state = areaStatesRef.current[areaName];
|
|
169
|
+
if (state) {
|
|
170
|
+
overlayModes[areaName] = state.mode;
|
|
171
|
+
}
|
|
172
|
+
if ((state === null || state === void 0 ? void 0 : state.mode) === 'inline') {
|
|
173
|
+
baselineWidths[areaName] = state.width;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
area,
|
|
178
|
+
baselineWidths,
|
|
179
|
+
overlayModes: mode === 'overlay' ? overlayModes : undefined
|
|
180
|
+
};
|
|
181
|
+
}, []);
|
|
182
|
+
const startResize = useCallback((area, mode) => {
|
|
183
|
+
setHasInteraction(true);
|
|
184
|
+
setResizeSession(captureSiblingWidths(area, mode));
|
|
185
|
+
|
|
186
|
+
// Start from the effective width, which may already be compressed below the preferred width.
|
|
187
|
+
// Reapplying the preferred width here would move the splitter away from the pointer.
|
|
188
|
+
const renderedState = areaStatesRef.current[area];
|
|
189
|
+
if ((renderedState === null || renderedState === void 0 ? void 0 : renderedState.mode) === mode) {
|
|
190
|
+
setAreas(current => {
|
|
191
|
+
const existing = current[area];
|
|
192
|
+
return existing ? {
|
|
193
|
+
...current,
|
|
194
|
+
[area]: {
|
|
195
|
+
...existing,
|
|
196
|
+
liveResize: {
|
|
197
|
+
mode,
|
|
198
|
+
width: renderedState.width
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
} : current;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}, [captureSiblingWidths]);
|
|
205
|
+
const resize = useCallback((area, mode, width) => {
|
|
206
|
+
setAreas(current => {
|
|
207
|
+
var _existing$liveResize;
|
|
208
|
+
const existing = current[area];
|
|
209
|
+
if ((existing === null || existing === void 0 ? void 0 : (_existing$liveResize = existing.liveResize) === null || _existing$liveResize === void 0 ? void 0 : _existing$liveResize.mode) === mode && existing.liveResize.width === width) {
|
|
210
|
+
return current;
|
|
211
|
+
}
|
|
212
|
+
return existing ? {
|
|
213
|
+
...current,
|
|
214
|
+
[area]: {
|
|
215
|
+
...existing,
|
|
216
|
+
liveResize: {
|
|
217
|
+
mode,
|
|
218
|
+
width
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} : current;
|
|
222
|
+
});
|
|
223
|
+
}, []);
|
|
224
|
+
const completeResize = useCallback((area, mode, width) => {
|
|
225
|
+
setHasInteraction(true);
|
|
226
|
+
if (mode === 'overlay') {
|
|
227
|
+
const session = inputsRef.current.resizeSession;
|
|
228
|
+
setResizeSession({
|
|
229
|
+
...((session === null || session === void 0 ? void 0 : session.area) === area && session.overlayModes ? session : captureSiblingWidths(area, mode)),
|
|
230
|
+
completedWidth: width
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (mode === 'inline') {
|
|
234
|
+
var _inputs$resizeSession, _inputs$areas$area;
|
|
235
|
+
const inputs = inputsRef.current;
|
|
236
|
+
const session = ((_inputs$resizeSession = inputs.resizeSession) === null || _inputs$resizeSession === void 0 ? void 0 : _inputs$resizeSession.area) === area && (_inputs$areas$area = inputs.areas[area]) !== null && _inputs$areas$area !== void 0 && _inputs$areas$area.liveResize ? inputs.resizeSession : captureSiblingWidths(area);
|
|
237
|
+
const existing = inputs.areas[area];
|
|
238
|
+
if (inputs.dimensions && existing) {
|
|
239
|
+
// Keyboard completion has no preview; calculate it using the accepted
|
|
240
|
+
// request, not the parent's previous controlled width. Pointer completion
|
|
241
|
+
// keeps below-minimum cascade results even though its payload is clamped.
|
|
242
|
+
const completed = existing.liveResize ? areaStatesRef.current : calculateLayoutAreaStates({
|
|
243
|
+
...inputs.dimensions,
|
|
244
|
+
occupiedWidth: inputs.occupiedWidth,
|
|
245
|
+
mainMinWidth: inputs.mainMinWidth,
|
|
246
|
+
areas: {
|
|
247
|
+
...inputs.areas,
|
|
248
|
+
[area]: {
|
|
249
|
+
...existing,
|
|
250
|
+
liveResize: {
|
|
251
|
+
mode,
|
|
252
|
+
width
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
resizeSession: session
|
|
257
|
+
});
|
|
258
|
+
const completedWidths = {};
|
|
259
|
+
for (const name of ['side-nav', 'panel', 'chat-panel']) {
|
|
260
|
+
var _completed$name;
|
|
261
|
+
if (((_completed$name = completed[name]) === null || _completed$name === void 0 ? void 0 : _completed$name.mode) === 'inline') {
|
|
262
|
+
completedWidths[name] = completed[name].width;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
setResizeSession({
|
|
266
|
+
...session,
|
|
267
|
+
completedWidth: width,
|
|
268
|
+
completedWidths
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
setAreas(current => {
|
|
273
|
+
const existing = current[area];
|
|
274
|
+
if (!existing) {
|
|
275
|
+
return current;
|
|
276
|
+
}
|
|
277
|
+
if (mode === 'overlay') {
|
|
278
|
+
return {
|
|
279
|
+
...current,
|
|
280
|
+
[area]: {
|
|
281
|
+
...existing,
|
|
282
|
+
liveResize: undefined,
|
|
283
|
+
preferredOverlayWidth: width
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
...current,
|
|
289
|
+
[area]: {
|
|
290
|
+
...existing,
|
|
291
|
+
liveResize: undefined,
|
|
292
|
+
preferredInlineWidth: width
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
}, [captureSiblingWidths]);
|
|
297
|
+
useEffect(() => {
|
|
298
|
+
// Loading the interaction engine is not a layout event. Adopt the CSS layout
|
|
299
|
+
// without changing widths or modes; subsequent changes to configuration or
|
|
300
|
+
// available space may redistribute it. Content stays mounted during the handoff.
|
|
301
|
+
const root = layoutRef === null || layoutRef === void 0 ? void 0 : layoutRef.current;
|
|
302
|
+
if (onUpdate && root && dimensions && isPreservingInitialLayout) {
|
|
303
|
+
const measured = {};
|
|
304
|
+
const selectors = {
|
|
305
|
+
'side-nav': ':scope > nav[data-layout-slot]',
|
|
306
|
+
panel: '[data-layout-with-panel-slot]',
|
|
307
|
+
'chat-panel': ':scope > [data-layout-chat-panel]'
|
|
308
|
+
};
|
|
309
|
+
for (const name of ['side-nav', 'panel', 'chat-panel']) {
|
|
310
|
+
const element = root.querySelector(selectors[name]);
|
|
311
|
+
const config = areas[name];
|
|
312
|
+
if (!element || !(config !== null && config !== void 0 && config.isOpen)) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const style = getComputedStyle(element);
|
|
316
|
+
const mode = style.gridArea.split('/')[0].trim() === name ? 'inline' : 'overlay';
|
|
317
|
+
measured[name] = {
|
|
318
|
+
mode,
|
|
319
|
+
width: element.getBoundingClientRect().width,
|
|
320
|
+
minWidth: resolveLayoutWidth(config.minWidth, dimensions.viewportWidth)
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
setInitialStates(measured);
|
|
324
|
+
}
|
|
325
|
+
}, [areas, dimensions, isPreservingInitialLayout, layoutRef, onUpdate]);
|
|
326
|
+
const areaStates = useMemo(() => {
|
|
327
|
+
var _initialStates$sideN, _initialStates$panel, _initialStates$chatP;
|
|
328
|
+
if (!dimensions) {
|
|
329
|
+
return {};
|
|
330
|
+
}
|
|
331
|
+
const allocated = calculateLayoutAreaStates({
|
|
332
|
+
...dimensions,
|
|
333
|
+
occupiedWidth,
|
|
334
|
+
mainMinWidth,
|
|
335
|
+
areas,
|
|
336
|
+
resizeSession,
|
|
337
|
+
initialModes: onUpdate && layoutRef !== null && layoutRef !== void 0 && layoutRef.current && isPreservingInitialLayout ? {
|
|
338
|
+
'side-nav': (_initialStates$sideN = initialStates['side-nav']) === null || _initialStates$sideN === void 0 ? void 0 : _initialStates$sideN.mode,
|
|
339
|
+
panel: (_initialStates$panel = initialStates.panel) === null || _initialStates$panel === void 0 ? void 0 : _initialStates$panel.mode,
|
|
340
|
+
'chat-panel': (_initialStates$chatP = initialStates['chat-panel']) === null || _initialStates$chatP === void 0 ? void 0 : _initialStates$chatP.mode
|
|
341
|
+
} : undefined
|
|
342
|
+
});
|
|
343
|
+
if (onUpdate && layoutRef !== null && layoutRef !== void 0 && layoutRef.current && isPreservingInitialLayout) {
|
|
344
|
+
for (const name of ['side-nav', 'panel', 'chat-panel']) {
|
|
345
|
+
if (initialStates[name] && allocated[name]) {
|
|
346
|
+
allocated[name] = {
|
|
347
|
+
...allocated[name],
|
|
348
|
+
...initialStates[name]
|
|
349
|
+
};
|
|
350
|
+
} else {
|
|
351
|
+
delete allocated[name];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return allocated;
|
|
356
|
+
}, [areas, mainMinWidth, resizeSession, dimensions, occupiedWidth, isPreservingInitialLayout, initialStates, layoutRef, onUpdate]);
|
|
357
|
+
useEffect(() => {
|
|
358
|
+
var _areas$sideNav;
|
|
359
|
+
if (hasInteraction && (resizeSession === null || resizeSession === void 0 ? void 0 : resizeSession.area) !== 'side-nav' && (_areas$sideNav = areas['side-nav']) !== null && _areas$sideNav !== void 0 && _areas$sideNav.isOpen && !areaStates['side-nav'] && dimensions) {
|
|
360
|
+
var _areas$sideNav$onReq, _areas$sideNav2;
|
|
361
|
+
(_areas$sideNav$onReq = (_areas$sideNav2 = areas['side-nav']).onRequestClose) === null || _areas$sideNav$onReq === void 0 ? void 0 : _areas$sideNav$onReq.call(_areas$sideNav2);
|
|
362
|
+
}
|
|
363
|
+
}, [areaStates, areas, dimensions, hasInteraction, resizeSession]);
|
|
364
|
+
useEffect(() => {
|
|
365
|
+
areaStatesRef.current = areaStates;
|
|
366
|
+
}, [areaStates]);
|
|
367
|
+
|
|
368
|
+
// Read bounds lazily: changing a sibling's capacity must not publish new render
|
|
369
|
+
// state or recreate drag listeners for a region whose own width did not change.
|
|
370
|
+
const getResizeBounds = useCallback(area => {
|
|
371
|
+
var _areaStatesRef$curren;
|
|
372
|
+
const bounds = (_areaStatesRef$curren = areaStatesRef.current[area]) === null || _areaStatesRef$curren === void 0 ? void 0 : _areaStatesRef$curren.resizeBounds;
|
|
373
|
+
return bounds ? {
|
|
374
|
+
min: `${bounds.min}px`,
|
|
375
|
+
max: `${bounds.max}px`
|
|
376
|
+
} : undefined;
|
|
377
|
+
}, []);
|
|
378
|
+
const value = useMemo(() => ({
|
|
379
|
+
getResizeBounds,
|
|
380
|
+
registerArea,
|
|
381
|
+
unregisterArea,
|
|
382
|
+
startResize,
|
|
383
|
+
resize,
|
|
384
|
+
completeResize,
|
|
385
|
+
setMainMinWidth
|
|
386
|
+
}), [completeResize, getResizeBounds, registerArea, resize, startResize, unregisterArea]);
|
|
387
|
+
const sideNavState = useStableAreaState(areaStates['side-nav']);
|
|
388
|
+
const panelState = useStableAreaState(areaStates.panel);
|
|
389
|
+
const chatPanelState = useStableAreaState(areaStates['chat-panel']);
|
|
390
|
+
const SideNavStateProvider = layoutAreaStateContexts['side-nav'].Provider;
|
|
391
|
+
const PanelStateProvider = layoutAreaStateContexts.panel.Provider;
|
|
392
|
+
const ChatPanelStateProvider = layoutAreaStateContexts['chat-panel'].Provider;
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
onReady === null || onReady === void 0 ? void 0 : onReady(value);
|
|
395
|
+
return () => onReady === null || onReady === void 0 ? void 0 : onReady(null);
|
|
396
|
+
}, [onReady, value]);
|
|
397
|
+
useEffect(() => {
|
|
398
|
+
if (!adoptedConstraints.current && (sideNavState || panelState || chatPanelState)) {
|
|
399
|
+
adoptedConstraints.current = {
|
|
400
|
+
occupiedWidth,
|
|
401
|
+
mainMinWidth
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate({
|
|
405
|
+
'side-nav': sideNavState,
|
|
406
|
+
panel: panelState,
|
|
407
|
+
'chat-panel': chatPanelState
|
|
408
|
+
});
|
|
409
|
+
}, [onUpdate, sideNavState, panelState, chatPanelState, occupiedWidth, mainMinWidth]);
|
|
410
|
+
return /*#__PURE__*/React.createElement(LayoutAreaSizingContext.Provider, {
|
|
411
|
+
value: value
|
|
412
|
+
}, /*#__PURE__*/React.createElement(SideNavStateProvider, {
|
|
413
|
+
value: sideNavState
|
|
414
|
+
}, /*#__PURE__*/React.createElement(PanelStateProvider, {
|
|
415
|
+
value: panelState
|
|
416
|
+
}, /*#__PURE__*/React.createElement(ChatPanelStateProvider, {
|
|
417
|
+
value: chatPanelState
|
|
418
|
+
}, children))));
|
|
419
|
+
}
|
|
@@ -6,7 +6,7 @@ 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
8
|
import { mainMinimumWidthVar } from '../constants';
|
|
9
|
-
import { gridRootId } from '../root';
|
|
9
|
+
import { gridRootFitId, gridRootId } from '../root';
|
|
10
10
|
import { useLayoutId } from '../use-layout-id';
|
|
11
11
|
import { useLayoutMainSizing } from '../use-layout-main-sizing';
|
|
12
12
|
const contentInsetBlockStartStatic = `calc(var(--n_bnrM, 0px) + var(--n_tNvM, 0px))`;
|
|
@@ -34,7 +34,7 @@ export function Main({
|
|
|
34
34
|
return /*#__PURE__*/React.createElement(Fragment, null, fg('platform-dst-chat-panel-layout') &&
|
|
35
35
|
/*#__PURE__*/
|
|
36
36
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles
|
|
37
|
-
React.createElement("style", null, `#${gridRootId} { ${mainMinimumWidthVar}: ${minWidth}px; }`), /*#__PURE__*/React.createElement("div", {
|
|
37
|
+
React.createElement("style", null, `#${gridRootId}, #${gridRootFitId} { ${mainMinimumWidthVar}: ${minWidth}px; }`), /*#__PURE__*/React.createElement("div", {
|
|
38
38
|
id: id,
|
|
39
39
|
"data-layout-slot": true,
|
|
40
40
|
className: ax([mainElementStyles.root, xcss]),
|
|
@@ -134,6 +134,7 @@ const PortaledPanelSplitter = ({
|
|
|
134
134
|
onCompleteResize,
|
|
135
135
|
onResizeStartInternal,
|
|
136
136
|
onResizeInternal,
|
|
137
|
+
prepareResize,
|
|
137
138
|
getResizeBounds,
|
|
138
139
|
panel,
|
|
139
140
|
portal,
|
|
@@ -282,8 +283,9 @@ const PortaledPanelSplitter = ({
|
|
|
282
283
|
});
|
|
283
284
|
const resizingWidth = `clamp(${resizeBounds.min}, ${targetWidth}px, ${resizeBounds.max})`;
|
|
284
285
|
if (fg('platform-dst-chat-panel-layout') && onResizeInternal) {
|
|
285
|
-
//
|
|
286
|
-
const
|
|
286
|
+
// The allocator needs below-minimum requests for the local-to-chat cascade.
|
|
287
|
+
const currentBounds = getResizeBounds();
|
|
288
|
+
const width = Math.max(0, Math.min(targetWidth, prepareResize ? window.innerWidth : convertResizeBoundToPixels(currentBounds.max)));
|
|
287
289
|
if (width !== lastManagedResizeWidth) {
|
|
288
290
|
lastManagedResizeWidth = width;
|
|
289
291
|
onResizeInternal(width);
|
|
@@ -295,12 +297,17 @@ const PortaledPanelSplitter = ({
|
|
|
295
297
|
}
|
|
296
298
|
source.data.resizingWidth = resizingWidth;
|
|
297
299
|
},
|
|
298
|
-
onDrop({
|
|
300
|
+
async onDrop({
|
|
299
301
|
source
|
|
300
302
|
}) {
|
|
301
303
|
var _resizingElementRef$c2;
|
|
302
304
|
invariant(isPanelSplitterDragData(source.data));
|
|
303
305
|
preventUnhandled.stop();
|
|
306
|
+
if (prepareResize) {
|
|
307
|
+
if (!(await prepareResize()) || !panel.isConnected) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
304
311
|
|
|
305
312
|
// PDD may deliver its final throttled drag update immediately before drop.
|
|
306
313
|
// Commit that update once before measuring; do not persist a previous frame.
|
|
@@ -325,7 +332,7 @@ const PortaledPanelSplitter = ({
|
|
|
325
332
|
resizingElementRef === null || resizingElementRef === void 0 ? void 0 : (_resizingElementRef$c2 = resizingElementRef.current) === null || _resizingElementRef$c2 === void 0 ? void 0 : _resizingElementRef$c2.style.removeProperty(resizingCssVar);
|
|
326
333
|
}
|
|
327
334
|
}));
|
|
328
|
-
}, [onCompleteResize, onResizeStartInternal, onResizeInternal, onResizeStart, onResizeEnd, panel, resizingCssVar, resizingElementRef, legacyPanelWidth, position, openLayerObserver, panelId, getResizeBounds]);
|
|
335
|
+
}, [onCompleteResize, onResizeStartInternal, onResizeInternal, prepareResize, onResizeStart, onResizeEnd, panel, resizingCssVar, resizingElementRef, legacyPanelWidth, position, openLayerObserver, panelId, getResizeBounds]);
|
|
329
336
|
const onResizeStartStableRef = useStableRef(onResizeStart);
|
|
330
337
|
const onResizeEndStableRef = useStableRef(onResizeEnd);
|
|
331
338
|
const [keyboardResizeManager] = useState(() => createKeyboardResizeManager({
|
|
@@ -340,21 +347,41 @@ const PortaledPanelSplitter = ({
|
|
|
340
347
|
return (_onResizeEndStableRef = onResizeEndStableRef.current) === null || _onResizeEndStableRef === void 0 ? void 0 : _onResizeEndStableRef.call(onResizeEndStableRef, ...args);
|
|
341
348
|
}
|
|
342
349
|
}));
|
|
343
|
-
const
|
|
350
|
+
const focusSequence = useRef(0);
|
|
351
|
+
const keyboardBoundsReady = useRef(false);
|
|
352
|
+
const pendingKeyboardWidth = useRef(null);
|
|
353
|
+
const handleSliderInputChange = useCallback(async (event, pendingKey) => {
|
|
344
354
|
const isManagedResize = fg('platform-dst-chat-panel-layout') && onResizeInternal;
|
|
345
|
-
|
|
355
|
+
const sequence = focusSequence.current;
|
|
356
|
+
let value = isManagedResize ? parseFloat(event.currentTarget.value) : parseInt(event.currentTarget.value);
|
|
357
|
+
if (prepareResize) {
|
|
358
|
+
if (!(await prepareResize()) || !panel.isConnected || sequence !== focusSequence.current) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
346
362
|
if (isManagedResize) {
|
|
347
363
|
// The available region may have changed since focus, including without a
|
|
348
364
|
// window resize. Use the allocator's current bounds for the public payload.
|
|
349
365
|
const bounds = getResizeBounds();
|
|
350
366
|
const min = convertResizeBoundToPixels(bounds.min);
|
|
351
367
|
const max = convertResizeBoundToPixels(bounds.max);
|
|
368
|
+
if (pendingKey) {
|
|
369
|
+
var _pendingKeyboardWidth;
|
|
370
|
+
// Native range inputs would apply these keys to the placeholder bounds.
|
|
371
|
+
// Preserve the intent until the chunk provides the real bounds instead.
|
|
372
|
+
const current = (_pendingKeyboardWidth = pendingKeyboardWidth.current) !== null && _pendingKeyboardWidth !== void 0 ? _pendingKeyboardWidth : getPixelWidth(panel);
|
|
373
|
+
const isRtl = getTextDirection(panel) === 'rtl';
|
|
374
|
+
const increase = pendingKey === 'ArrowUp' || pendingKey === (isRtl ? 'ArrowLeft' : 'ArrowRight') || pendingKey === 'PageUp';
|
|
375
|
+
const step = pendingKey.startsWith('Page') ? Math.max(20, (max - min) / 10) : 20;
|
|
376
|
+
value = pendingKey === 'End' ? max : pendingKey === 'Home' ? min : current + (increase ? step : -step);
|
|
377
|
+
}
|
|
352
378
|
value = Math.max(min, Math.min(value, max));
|
|
353
379
|
setRangeInputBounds({
|
|
354
380
|
min,
|
|
355
381
|
max
|
|
356
382
|
});
|
|
357
383
|
}
|
|
384
|
+
pendingKeyboardWidth.current = value;
|
|
358
385
|
setRangeInputValue(value);
|
|
359
386
|
|
|
360
387
|
/**
|
|
@@ -366,10 +393,24 @@ const PortaledPanelSplitter = ({
|
|
|
366
393
|
initialWidth: panelWidth,
|
|
367
394
|
finalWidth: value
|
|
368
395
|
});
|
|
369
|
-
}, [getResizeBounds, onCompleteResize, onResizeInternal, panelWidth, keyboardResizeManager]);
|
|
396
|
+
}, [getResizeBounds, onCompleteResize, onResizeInternal, panelWidth, keyboardResizeManager, panel, prepareResize]);
|
|
397
|
+
const handleSliderKeyDown = useCallback(event => {
|
|
398
|
+
if (prepareResize && !keyboardBoundsReady.current && ['Home', 'End', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageUp', 'PageDown'].includes(event.key)) {
|
|
399
|
+
event.preventDefault();
|
|
400
|
+
void handleSliderInputChange(event, event.key);
|
|
401
|
+
}
|
|
402
|
+
}, [handleSliderInputChange, prepareResize]);
|
|
370
403
|
const resizeEventListenerCleanupFn = useRef(null);
|
|
371
|
-
const handleSliderFocus = useCallback(() => {
|
|
404
|
+
const handleSliderFocus = useCallback(async () => {
|
|
372
405
|
var _resizeEventListenerC;
|
|
406
|
+
const sequence = ++focusSequence.current;
|
|
407
|
+
keyboardBoundsReady.current = false;
|
|
408
|
+
pendingKeyboardWidth.current = null;
|
|
409
|
+
if (prepareResize) {
|
|
410
|
+
if (!(await prepareResize()) || !panel.isConnected || sequence !== focusSequence.current) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
373
414
|
/**
|
|
374
415
|
* We are only updating the range input's properties when the element is focused, as a performance optimisation.
|
|
375
416
|
* It isn't necessary to recalculate these values until the element is going to be used.
|
|
@@ -379,7 +420,9 @@ const PortaledPanelSplitter = ({
|
|
|
379
420
|
(_resizeEventListenerC = resizeEventListenerCleanupFn.current) === null || _resizeEventListenerC === void 0 ? void 0 : _resizeEventListenerC.call(resizeEventListenerCleanupFn);
|
|
380
421
|
|
|
381
422
|
// Update the range input value to match the current panel width.
|
|
382
|
-
|
|
423
|
+
const width = prepareResize ? getPixelWidth(panel) : panelWidth;
|
|
424
|
+
pendingKeyboardWidth.current = width;
|
|
425
|
+
setRangeInputValue(width);
|
|
383
426
|
const resizeBounds = getResizeBounds();
|
|
384
427
|
|
|
385
428
|
// Update the range input bounds to ensure they are accurate (in case the viewport was previously resized)
|
|
@@ -387,6 +430,7 @@ const PortaledPanelSplitter = ({
|
|
|
387
430
|
min: convertResizeBoundToPixels(resizeBounds.min),
|
|
388
431
|
max: convertResizeBoundToPixels(resizeBounds.max)
|
|
389
432
|
});
|
|
433
|
+
keyboardBoundsReady.current = true;
|
|
390
434
|
|
|
391
435
|
/**
|
|
392
436
|
* _While the slider element is focused_, add a window resize event listener to update the range input bounds
|
|
@@ -405,9 +449,11 @@ const PortaledPanelSplitter = ({
|
|
|
405
449
|
});
|
|
406
450
|
}
|
|
407
451
|
});
|
|
408
|
-
}, [panelWidth, getResizeBounds]);
|
|
452
|
+
}, [panelWidth, getResizeBounds, panel, prepareResize]);
|
|
409
453
|
const handleSliderBlur = useCallback(() => {
|
|
410
454
|
var _resizeEventListenerC2;
|
|
455
|
+
focusSequence.current++;
|
|
456
|
+
keyboardBoundsReady.current = false;
|
|
411
457
|
// Remove the resize event listener when the range input is blurred.
|
|
412
458
|
(_resizeEventListenerC2 = resizeEventListenerCleanupFn.current) === null || _resizeEventListenerC2 === void 0 ? void 0 : _resizeEventListenerC2.call(resizeEventListenerCleanupFn);
|
|
413
459
|
}, []);
|
|
@@ -432,6 +478,7 @@ const PortaledPanelSplitter = ({
|
|
|
432
478
|
}, /*#__PURE__*/React.createElement("div", {
|
|
433
479
|
ref: splitterRef,
|
|
434
480
|
"data-testid": testId,
|
|
481
|
+
"data-panel-splitter": prepareResize ? '' : undefined,
|
|
435
482
|
onDoubleClick: onDoubleClick,
|
|
436
483
|
className: ax([grabAreaStyles.root, fg('platform-dst-tokens-finesse') && grabAreaStyles.rootFinesse])
|
|
437
484
|
}, /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement("input", {
|
|
@@ -443,6 +490,7 @@ const PortaledPanelSplitter = ({
|
|
|
443
490
|
"aria-valuetext": ariaValueText,
|
|
444
491
|
"aria-labelledby": labelId,
|
|
445
492
|
onChange: handleSliderInputChange,
|
|
493
|
+
onKeyDown: prepareResize ? handleSliderKeyDown : undefined,
|
|
446
494
|
onFocus: handleSliderFocus,
|
|
447
495
|
onBlur: handleSliderBlur
|
|
448
496
|
}), /*#__PURE__*/React.createElement("span", {
|
|
@@ -488,6 +536,7 @@ export const PanelSplitter = ({
|
|
|
488
536
|
onResizeStartInternal,
|
|
489
537
|
onResizeInternal,
|
|
490
538
|
getResizeBounds,
|
|
539
|
+
prepareResize,
|
|
491
540
|
resizingCssVar,
|
|
492
541
|
resizingElementRef,
|
|
493
542
|
position,
|
|
@@ -587,6 +636,7 @@ export const PanelSplitter = ({
|
|
|
587
636
|
onCompleteResize: onCompleteResize,
|
|
588
637
|
onResizeStartInternal: onResizeStartInternal,
|
|
589
638
|
onResizeInternal: onResizeInternal,
|
|
639
|
+
prepareResize: prepareResize,
|
|
590
640
|
getResizeBounds: getResizeBounds,
|
|
591
641
|
resizingCssVar: resizingCssVar,
|
|
592
642
|
resizingElementRef: resizingElementRef,
|
|
@@ -11,6 +11,7 @@ export const PanelSplitterProvider = ({
|
|
|
11
11
|
onCompleteResize,
|
|
12
12
|
onResizeStartInternal,
|
|
13
13
|
onResizeInternal,
|
|
14
|
+
prepareResize,
|
|
14
15
|
getResizeBounds,
|
|
15
16
|
resizingCssVar,
|
|
16
17
|
panelRef,
|
|
@@ -28,6 +29,7 @@ export const PanelSplitterProvider = ({
|
|
|
28
29
|
onCompleteResize,
|
|
29
30
|
onResizeStartInternal,
|
|
30
31
|
onResizeInternal,
|
|
32
|
+
prepareResize,
|
|
31
33
|
getResizeBounds,
|
|
32
34
|
resizingCssVar,
|
|
33
35
|
position,
|
|
@@ -36,7 +38,7 @@ export const PanelSplitterProvider = ({
|
|
|
36
38
|
isEnabled,
|
|
37
39
|
portalRef: typeof providedPortalRef !== 'undefined' ? providedPortalRef : portalRef,
|
|
38
40
|
shortcut
|
|
39
|
-
}), [panelId, panelWidth, onCompleteResize, onResizeStartInternal, onResizeInternal, getResizeBounds, resizingCssVar, position, panelRef, resizingElementRef, isEnabled, providedPortalRef, shortcut]);
|
|
41
|
+
}), [panelId, panelWidth, onCompleteResize, onResizeStartInternal, onResizeInternal, prepareResize, getResizeBounds, resizingCssVar, position, panelRef, resizingElementRef, isEnabled, providedPortalRef, shortcut]);
|
|
40
42
|
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(PanelSplitterContext.Provider, {
|
|
41
43
|
value: context
|
|
42
44
|
}, children), typeof providedPortalRef !== 'undefined' ? null : /*#__PURE__*/React.createElement("div", {
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
._18m9zryt{overflow-y:clip}
|
|
2
|
+
._1bsb1osq{width:100%}
|
|
3
|
+
._1bsb1raa{width:max(0px,calc(var(--n_layoutW) - var(--n_mainMinW) - var(--n_fitAside, 0px) - var(--n_fitRibbon, 0px) - var(--n_fitPanel, 0px)))}
|
|
4
|
+
._1bsb4nr3{width:var(--n_layoutW)}
|
|
5
|
+
._1bsbjwgu{width:max(0px,calc(100% - var(--n_fitNav)))}
|
|
2
6
|
._1ciragmp >:not([data-layout-slot]){display:none!important}
|
|
3
7
|
._1cwmtye8{--n_mainMinW:20rem}
|
|
4
8
|
._1e0c11p5{display:grid}
|
|
9
|
+
._1f381mry{container-name:navigation-chat-space}
|
|
10
|
+
._1f38hwoh{container-name:navigation-main-space}
|
|
11
|
+
._1f38hx13{container-name:navigation-layout-width}
|
|
5
12
|
._1lmcq9em{grid-template-areas:"banner" "top-bar" "main" "aside"}
|
|
6
13
|
._1reozryt{overflow-x:clip}
|
|
7
14
|
._1tke1kxc{min-height:100vh}
|
|
8
15
|
._1tvnagmp >:not([data-layout-slot]):not(dialog):not([popover]){display:none!important}
|
|
9
16
|
._2z0516ab{grid-template-rows:auto auto 1fr auto}
|
|
17
|
+
._5to3grho{--n_fitNav:0px}
|
|
18
|
+
._7cca15wb{container-type:inline-size}
|
|
19
|
+
._82d6okmw{--n_layoutW:100cqw}
|
|
20
|
+
._vchh1ntv{box-sizing:content-box}
|
|
10
21
|
._yv0ei47z{grid-template-columns:minmax(0,1fr)}
|
|
11
|
-
@media (min-width:40rem){._12ag50j2{grid-template-areas:"banner banner" "top-bar chat-panel" "main chat-panel" "aside chat-panel"}.
|
|
12
|
-
@media (min-width:64rem){._12fk1aio{grid-template-areas:"banner banner banner banner" "ribbon top-bar top-bar top-bar" "ribbon side-nav main aside"}._12qzrxre{grid-template-rows:auto auto 3fr}._1rqteala{grid-template-columns:auto auto minmax(0,1fr) auto}._12fkqmyk{grid-template-areas:"banner banner banner banner banner" "ribbon top-bar top-bar top-bar chat-panel" "ribbon side-nav main aside chat-panel"}.
|
|
13
|
-
@media (min-width:90rem){._xkmggc7l{grid-template-areas:"banner banner banner banner banner banner" "ribbon top-bar top-bar top-bar top-bar chat-panel" "ribbon side-nav main aside panel chat-panel"}.
|
|
22
|
+
@media (min-width:40rem){._12ag50j2{grid-template-areas:"banner banner" "top-bar chat-panel" "main chat-panel" "aside chat-panel"}._71dl19sb{grid-template-columns:minmax(var(--n_mainMinW),1fr) var(--n_chatTrack,0)}}
|
|
23
|
+
@media (min-width:64rem){._12fk1aio{grid-template-areas:"banner banner banner banner" "ribbon top-bar top-bar top-bar" "ribbon side-nav main aside"}._12qzrxre{grid-template-rows:auto auto 3fr}._1rqteala{grid-template-columns:auto auto minmax(0,1fr) auto}._12fkqmyk{grid-template-areas:"banner banner banner banner banner" "ribbon top-bar top-bar top-bar chat-panel" "ribbon side-nav main aside chat-panel"}._1rqttswr{grid-template-columns:auto auto minmax(var(--n_mainMinW),1fr) auto var(--n_chatTrack,0)}}
|
|
24
|
+
@media (min-width:90rem){._xkmggc7l{grid-template-areas:"banner banner banner banner banner banner" "ribbon top-bar top-bar top-bar top-bar chat-panel" "ribbon side-nav main aside panel chat-panel"}._tyve87m4{grid-template-columns:auto auto minmax(var(--n_mainMinW),1fr) auto auto var(--n_chatTrack,0)}._xkmgks3h{grid-template-areas:"banner banner banner banner banner" "ribbon top-bar top-bar top-bar top-bar" "ribbon side-nav main aside panel"}._jbc7rxre{grid-template-rows:auto auto 3fr}._tyve1nco{grid-template-columns:auto auto minmax(0,1fr) auto auto}}
|