PluginProbe
Extendify / trunk
Extendify vtrunk
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
← All changes | src/Agent/components/layouts/SidebarLayout.jsx +24 -25 3.1.5 → trunk View file →
@@ -1,9 +1,9 @@
1 1 import {
2 2 CANVAS_PANE_WIDTH,
3 3 CanvasPane,
4 4 DOT_GRID,
5 - useCanvasOpen,
5 + useCanvasSeat,
6 6 } from '@agent/components/Canvas';
7 7 import { usePortal } from '@agent/hooks/usePortal';
8 8 import { DESKTOP_MIN_WIDTH, useGlobalStore } from '@agent/state/global';
9 9 import { createPortal, useEffect, useRef } from '@wordpress/element';
@@ -20,9 +20,10 @@
20 20 export const SidebarLayout = ({ children }) => {
21 21 const mountNode = usePortal('extendify-agent-sidebar-mount');
22 22 const frameNode = usePortal('extendify-agent-border-frame-mount');
23 23 const { open, setOpen } = useGlobalStore();
24 - const canvasOpen = useCanvasOpen();
24 + const seat = useCanvasSeat();
25 + const beside = seat === 'beside';
25 26 useLayoutShift(open);
26 27
27 28 const closeAgent = () => {
28 29 setOpen(false);
@@ -55,11 +56,12 @@
55 56 borderRadius: 0,
56 57 },
57 58 };
58 59
60 + // Unclipped, the 9999px shadow covers the notification bar.
59 61 const frameBar = frameNode
60 62 ? createPortal(
61 - <div className="fixed inset-0 pointer-events-none z-high">
63 + <div className="fixed top-0 left-0 right-0 bottom-(--extendify-notification-bar-height,0px) overflow-hidden pointer-events-none z-high">
62 64 <motion.div
63 65 className="absolute overflow-hidden"
64 66 initial={false}
65 67 animate={open ? 'open' : 'closed'}
@@ -89,21 +91,26 @@
89 91 // app/Agent/Skeleton.php mirrors this markup for the deferred mount; edit both.
90 92 const sidebar = mountNode
91 93 ? createPortal(
92 94 <motion.div
93 - className=" fixed top-0 bottom-0 left-0 z-higher border-transparent border-8"
95 + className={`fixed top-0 bottom-[var(--extendify-notification-bar-height,0px)] left-0 border-transparent border-8 ${
96 + // An emptied panel belongs under the scrim with the rest of the page.
97 + seat === 'modal' ? 'z-high' : 'z-higher'
98 + }`}
94 99 id="extendify-agent-sidebar"
100 + data-extendify-agent-panel
101 + data-extendify-agent-emptied={seat === 'modal' ? '' : undefined}
95 102 initial={false}
96 103 inert={open ? undefined : ''}
97 104 animate={{
98 105 x: open ? 0 : -SIDEBAR_WIDTH,
99 - width: canvasOpen ? CANVAS_WIDTH : SIDEBAR_WIDTH,
106 + width: beside ? CANVAS_WIDTH : SIDEBAR_WIDTH,
100 107 }}
101 108 transition={{ duration: ANIMATE_TIME / 1000, ease: 'easeInOut' }}
102 109 >
103 110 <div
104 - className={`h-full flex shadow-lg rounded-2xl overflow-hidden ${canvasOpen ? 'bg-gray-50' : 'bg-white'}`}
105 - style={canvasOpen ? DOT_GRID : undefined}
111 + className={`relative h-full flex shadow-lg rounded-2xl overflow-hidden ${beside ? 'bg-gray-50' : 'bg-white'}`}
112 + style={beside ? DOT_GRID : undefined}
106 113 >
107 114 <div
108 115 className="relative z-10 h-full flex shrink-0 flex-col rounded-2xl overflow-hidden bg-white shadow-lg"
109 116 style={{ width: SIDEBAR_WIDTH - FRAME_WIDTH * 2 }}
@@ -118,9 +125,9 @@
118 125 />
119 126 </div>
120 127 </div>
121 128 <div className="flex gap-1 h-full items-center p-2">
122 - {canvasOpen ? null : (
129 + {seat ? null : (
123 130 <>
124 131 <OptionsPopover />
125 132 <button
126 133 type="button"
@@ -141,9 +148,9 @@
141 148 </div>
142 149 </div>
143 150 {open ? children : null}
144 151 </div>
145 - <CanvasPane />
152 + <CanvasPane seat="beside" />
146 153 </div>
147 154 </motion.div>,
148 155 mountNode,
149 156 )
@@ -230,13 +237,17 @@
230 237 const scale = (viewportWidth - SIDEBAR_WIDTH) / viewportWidth;
231 238
232 239 // Subtract 40 because translateY(40px) below pushes the element down.
233 240 const scaledHeight = (window.innerHeight - 40) / scale;
241 + // Divided by the scale because this height is in pre-scale units.
242 + const height =
243 + `calc(${scaledHeight}px - ` +
244 + `var(--extendify-notification-bar-height, 0px) / ${scale})`;
234 245
235 246 Object.assign(siteBlocks.style, {
236 247 transformOrigin: 'top left',
237 248 transform: `translateX(${SIDEBAR_WIDTH}px) translateY(40px) scale(${scale})`,
238 - height: `${scaledHeight}px`,
249 + height,
239 250 overflowY: 'auto',
240 251 // `auto` so the scrollTop below is instant; `smooth` would animate from 0.
241 252 scrollBehavior: 'auto',
242 253 });
@@ -301,11 +312,8 @@
301 312 firstRun.current = false;
302 313 }
303 314
304 315 const raf = requestAnimationFrame(() => {
305 - const fw = open ? `${FRAME_WIDTH}px` : '0px';
306 - const ml = open ? `${SIDEBAR_WIDTH}px` : '0px';
307 -
308 316 applyScaling();
309 317
310 318 // External contract: no in-repo listener by design — lets host-page
311 319 // consumers react to the agent reflowing the viewport.
@@ -314,20 +322,11 @@
314 322 detail: { open },
315 323 }),
316 324 );
317 325
318 - if (wpadminbar) {
319 - Object.assign(wpadminbar.style, {
320 - marginTop: fw,
321 - marginRight: fw,
322 - marginBottom: '0px',
323 - marginLeft: ml,
324 - borderRadius: open ? '8px 8px 0 0' : '0',
325 - maxWidth: open
326 - ? `calc(100% - ${SIDEBAR_WIDTH + FRAME_WIDTH}px)`
327 - : '100%',
328 - });
329 - }
326 + // agent.css carries the bar offsets, so they drop with the
327 + // breakpoint rather than with this component.
328 + document.documentElement.classList.toggle('extendify-agent-docked', open);
330 329 });
331 330
332 331 window.addEventListener('resize', applyScaling);
333 332