Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ test.describe('playground layout persistence (desktop)', () => {
await expect(playground.bottomPanel).toBeVisible();
});

test('a collapsed bottom sheet reopens expanded after a reload', async ({ page, playground }) => {
test('a collapsed bottom sheet stays collapsed after a reload', async ({ page, playground }) => {
await playground.open('bottom');
await expect(playground.bottomPanel).toBeVisible();
const expanded = await playground.bottomPanelHeight();

await playground.grabBottomResizer();
await playground.movePointerToY(890);
Expand All @@ -92,6 +91,48 @@ test.describe('playground layout persistence (desktop)', () => {

await page.reload();
await expect(playground.bottomPanel).toBeVisible();
expect(Math.abs((await playground.bottomPanelHeight()) - expanded)).toBeLessThan(5);
expect(await playground.bottomPanelHeight()).toBeLessThan(100);
});

test('expanding after a collapsed reload restores the pre-collapse height', async ({ page, playground }) => {
await playground.open('bottom');
await expect(playground.bottomPanel).toBeVisible();

await playground.grabBottomResizer();
await playground.movePointerToY(300);
await playground.releasePointer();
const resized = await playground.bottomPanelHeight();
expect(resized).toBeGreaterThan(560);

await playground.grabBottomResizer();
await playground.movePointerToY(890);
await playground.releasePointer();
expect(await playground.bottomPanelHeight()).toBeLessThan(100);

await page.reload();
await expect(playground.bottomPanel).toBeVisible();
expect(await playground.bottomPanelHeight()).toBeLessThan(100);

await playground.toggleCollapse();
expect(Math.abs((await playground.bottomPanelHeight()) - resized)).toBeLessThan(5);
});

test('Try it after collapsing expands to the persisted height', async ({ requestPage, playground }) => {
await requestPage.open(REQUEST_PATH);
await requestPage.urlBar.tryButton.click();
await expect(playground.bottomPanel).toBeVisible();

await playground.grabBottomResizer();
await playground.movePointerToY(200);
await playground.releasePointer();
const resized = await playground.bottomPanelHeight();
expect(resized).toBeGreaterThan(650);

await playground.toggleCollapse();
expect(await playground.bottomPanelHeight()).toBeLessThan(100);

await requestPage.urlBar.tryButton.click();
await expect(playground.content).toBeVisible();
expect(Math.abs((await playground.bottomPanelHeight()) - resized)).toBeLessThan(5);
});
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React, { useEffect, useMemo, useRef } from 'react';
import PlaygroundHeader from '../../PlaygroundHeader/PlaygroundHeader';
import { useDockResize } from '@/hooks/useDockResize';
import { areaFor, readStoredNumber, writeStored } from '@/hooks/useStorage';
import { areaFor, readStored, readStoredNumber, writeStored } from '@/hooks/useStorage';
import type { DockMode } from '@/utils/playgroundDock';
import { StyledWrapper } from './StyledWrapper';

const HEADER_HEIGHT = 52;
const COLLAPSE_EPSILON = 8;
const getDefaultHeight = () => Math.round(window.innerHeight * 0.6);
const HEIGHT_STORAGE_KEY = 'oc-docs:playgroundBottomHeight';
const COLLAPSED_STORAGE_KEY = 'oc-docs:playgroundBottomCollapsed';

const readStoredHeight = () => readStoredNumber(areaFor('session'), HEIGHT_STORAGE_KEY, getDefaultHeight());

interface BottomSheetDockProps {
dock: DockMode;
Expand All @@ -29,44 +32,35 @@ const BottomSheetDock: React.FC<BottomSheetDockProps> = ({
openNonce,
children
}) => {
const defaultHeight = getDefaultHeight();
const initialHeight = useMemo(
() => readStoredNumber(areaFor('session'), HEIGHT_STORAGE_KEY, getDefaultHeight()),
[]
);
const initialHeight = useMemo(() => {
const storedCollapsed = readStored<unknown>(areaFor('session'), COLLAPSED_STORAGE_KEY, false) === true;
return storedCollapsed ? HEADER_HEIGHT : readStoredHeight();
}, []);
const { size, dragging, startDrag, setSize } = useDockResize({
axis: 'y',
initial: initialHeight,
min: HEADER_HEIGHT,
max: () => window.innerHeight
});

const lastExpanded = useRef<number>(initialHeight);
const collapsed = size <= HEADER_HEIGHT + COLLAPSE_EPSILON;

const sizeRef = useRef(size);
sizeRef.current = size;
const defaultHeightRef = useRef(defaultHeight);
defaultHeightRef.current = defaultHeight;

useEffect(() => {
if (openNonce === undefined) return;
if (sizeRef.current <= HEADER_HEIGHT + COLLAPSE_EPSILON) setSize(defaultHeightRef.current);
if (!openNonce) return;
if (sizeRef.current <= HEADER_HEIGHT + COLLAPSE_EPSILON) setSize(readStoredHeight());
}, [openNonce, setSize]);

useEffect(() => {
if (!dragging && size > HEADER_HEIGHT + COLLAPSE_EPSILON) {
writeStored(areaFor('session'), HEIGHT_STORAGE_KEY, size);
}
}, [dragging, size]);
if (dragging) return;
writeStored(areaFor('session'), COLLAPSED_STORAGE_KEY, collapsed);
if (!collapsed) writeStored(areaFor('session'), HEIGHT_STORAGE_KEY, size);
}, [dragging, size, collapsed]);

const toggleCollapse = () => {
if (collapsed) {
setSize(lastExpanded.current > HEADER_HEIGHT + COLLAPSE_EPSILON ? lastExpanded.current : defaultHeight);
} else {
lastExpanded.current = size;
setSize(HEADER_HEIGHT);
}
setSize(collapsed ? readStoredHeight() : HEADER_HEIGHT);
};

return (
Expand Down
Loading