Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ test('should make every Dock tool reachable on mobile', async ({ website }) => {
['Site Settings', 'Site Settings pane'],
['Database', 'Database pane'],
['Files', 'Files pane'],
['Logs', 'Logs pane'],
['Logs', 'PHP error log pane'],
['Export', 'Export pane'],
] as const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('Dock positioning', () => {
dockCenter: null,
viewportSize: { width: 1200, height: 800 },
isEditorSection: false,
isWideSection: false,
isFixedHeightSection: false,
isPlaygroundsSection: false,
})
Expand All @@ -34,6 +35,7 @@ describe('Dock positioning', () => {
toastHeight: 62,
paneOpen: false,
isEditorSection: false,
isWideSection: false,
})
).toBeUndefined();
});
Expand All @@ -48,6 +50,7 @@ describe('Dock positioning', () => {
dockCenter: null,
viewportSize: { width: 1200, height: 100 },
isEditorSection: false,
isWideSection: false,
isFixedHeightSection: false,
isPlaygroundsSection: false,
})
Expand All @@ -64,6 +67,7 @@ describe('Dock positioning', () => {
dockCenter: null,
viewportSize: { width: 390, height: 844 },
isEditorSection: false,
isWideSection: false,
isFixedHeightSection: false,
isPlaygroundsSection: false,
})
Expand All @@ -80,6 +84,7 @@ describe('Dock positioning', () => {
dockCenter: 100,
viewportSize: { width: 1200, height: 800 },
isEditorSection: false,
isWideSection: false,
isFixedHeightSection: true,
isPlaygroundsSection: true,
})
Expand All @@ -102,6 +107,7 @@ describe('Dock positioning', () => {
dockCenter: null,
viewportSize: { width: 1200, height: 800 },
isEditorSection: false,
isWideSection: false,
isFixedHeightSection: false,
isPlaygroundsSection: false,
})
Expand All @@ -124,6 +130,7 @@ describe('Dock positioning', () => {
toastHeight: 62,
paneOpen: true,
isEditorSection: false,
isWideSection: false,
})
).toEqual({ bottom: '504px', left: '308px' });
});
Expand All @@ -141,6 +148,7 @@ describe('Dock positioning', () => {
toastHeight: 62,
paneOpen: false,
isEditorSection: false,
isWideSection: false,
})
).toEqual({
bottom: `${80 + DOCK_PANE_GAP}px`,
Expand All @@ -161,6 +169,7 @@ describe('Dock positioning', () => {
toastHeight: 62,
paneOpen: false,
isEditorSection: false,
isWideSection: false,
})
).toEqual({ bottom: '92px', left: '5px' });
});
Expand All @@ -171,14 +180,35 @@ describe('Dock positioning', () => {
dockCenter: 0,
viewportWidth: 1200,
isEditorSection: false,
isWideSection: false,
})
).toBe(308);
expect(
getDockPaneCenter({
dockCenter: 1200,
viewportWidth: 1200,
isEditorSection: false,
isWideSection: false,
})
).toBe(892);
});

it('clamps wide pane centers by their own half width', () => {
expect(
getDockPaneCenter({
dockCenter: 0,
viewportWidth: 1200,
isEditorSection: false,
isWideSection: true,
})
).toBe(438);
expect(
getDockPaneCenter({
dockCenter: 1200,
viewportWidth: 1200,
isEditorSection: false,
isWideSection: true,
})
).toBe(762);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function getDockPaneStyle({
dockCenter,
viewportSize,
isEditorSection,
isWideSection,
isFixedHeightSection,
isPlaygroundsSection,
}: {
Expand All @@ -29,6 +30,7 @@ export function getDockPaneStyle({
dockCenter: number | null;
viewportSize: Size;
isEditorSection: boolean;
isWideSection: boolean;
isFixedHeightSection: boolean;
isPlaygroundsSection: boolean;
}): CSSProperties | undefined {
Expand All @@ -52,6 +54,7 @@ export function getDockPaneStyle({
dockCenter,
viewportWidth: viewportSize.width,
isEditorSection,
isWideSection,
});
const availableHeight = Math.max(
DOCK_PANE_MIN_HEIGHT,
Expand Down Expand Up @@ -81,6 +84,7 @@ export function getDockOperationToastStyle({
toastHeight,
paneOpen,
isEditorSection,
isWideSection,
}: {
isMobile: boolean;
dockSize: Size;
Expand All @@ -92,6 +96,7 @@ export function getDockOperationToastStyle({
toastHeight: number;
paneOpen: boolean;
isEditorSection: boolean;
isWideSection: boolean;
}): CSSProperties | undefined {
if (!dockSize.height) {
return undefined;
Expand Down Expand Up @@ -124,6 +129,7 @@ export function getDockOperationToastStyle({
dockCenter,
viewportWidth: viewportSize.width,
isEditorSection,
isWideSection,
});
const minCenter = halfToastWidth + DOCK_PANE_GAP;
const maxCenter = viewportSize.width - halfToastWidth - DOCK_PANE_GAP;
Expand All @@ -143,14 +149,17 @@ export function getDockPaneCenter({
dockCenter,
viewportWidth,
isEditorSection,
isWideSection,
}: {
dockCenter: number | null;
viewportWidth: number;
isEditorSection: boolean;
isWideSection: boolean;
}) {
const desiredCenter = dockCenter ?? viewportWidth / 2;
// Half of the .pane / .pane-wide / .pane-editor widths in style.module.css.
const halfPaneWidth = Math.min(
isEditorSection ? 560 : 300,
isEditorSection ? 560 : isWideSection ? 430 : 300,
(viewportWidth - 2 * DOCK_DRAG_EDGE) / 2
);
return Math.min(
Expand Down
9 changes: 7 additions & 2 deletions packages/playground/website/src/components/dock/dock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ const PANE_COPY: Record<
description: 'Browse and edit the active Playground filesystem.',
},
logs: {
title: 'Logs',
description: 'PHP, WordPress, and Playground runtime messages.',
title: 'PHP error log',
description: 'Errors, warnings, and notices from your site.',
},
Comment thread
adamziel marked this conversation as resolved.
share: {
title: 'Export',
Expand Down Expand Up @@ -206,6 +206,8 @@ export function Dock({
const paneTitle = paneCopy.title;
const isMobile = useIsMobileDock();
const isEditorSection = section === 'blueprint' || section === 'files';
// Logs hold long monospace records, so they get a wider pane.
const isWideSection = section === 'logs';
const isFixedHeightSection =
section === 'new' || (section === 'share' && shareExportOpen);
const showSharedHeader = !isEditorSection;
Expand Down Expand Up @@ -988,6 +990,7 @@ export function Dock({
dockCenter,
viewportSize,
isEditorSection,
isWideSection,
isFixedHeightSection,
isPlaygroundsSection: section === 'playgrounds',
});
Expand All @@ -1002,6 +1005,7 @@ export function Dock({
toastHeight: operationToastHeight,
paneOpen: dockPaneIsOpen,
isEditorSection,
isWideSection,
});

return (
Expand Down Expand Up @@ -1118,6 +1122,7 @@ export function Dock({
[css.hostPaneHidden]:
!dockPaneIsOpen && paneExitComplete,
[css.paneSave]: section === 'save',
[css.paneWide]: isWideSection,
})}
style={paneStyle}
isEditor={isEditorSection}
Expand Down
31 changes: 31 additions & 0 deletions packages/playground/website/src/components/dock/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,36 @@
width: min(440px, calc(100vw - 40px));
}

/* Logs hold long monospace records, so they get a wider pane. Same compound
selector trick as .pane-compact so the mobile override below still wins.
Half of this width is mirrored in dock-positioning.ts.

The pane also pins its header and scrolls the tool body internally
(inside .tab-contents) instead of scrolling as one piece. The Logs
search/filter toolbar is sticky, and every ancestor between it and the
pane creates its own overflow context — the tool body is the only
scrollport the toolbar can reliably stick to. */
.pane.pane-wide {
display: flex;
flex-direction: column;
overflow: hidden;
width: min(860px, calc(100vw - 40px));
}

.pane.pane-wide .pane-body {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
overflow: hidden;
}

/* Let the tool chain shrink so the innermost overflow: auto box scrolls. */
.pane.pane-wide .pane-body :global(.components-flex),
.pane.pane-wide .pane-body :global(.components-flex-item) {
min-height: 0;
}

/* Start states. CSSTransition keeps the base (`-enter`/`-exit`) class on the
node alongside the `-active` class for the whole transition, so the `-active`
rules MUST come later in source order to win — otherwise the end state never
Expand Down Expand Up @@ -747,6 +777,7 @@
inline so the panel always clears the (collapsible) bar. */
.pane,
.pane.pane-compact,
.pane.pane-wide,
.pane-editor,
.pane-fixed-height {
border-radius: 0;
Expand Down
Loading
Loading