Skip to content

Dynamic height

"header" and "content" working together. Add a row while the sheet is open. The sheet measures itself again and springs to the new height instead of jumping.

tsx
import { useState } from "react";
import { Sheet } from "snap-bottom-sheet/react";

// `frame` is the box this demo runs in: it is passed to
// `Sheet.Portal container`, so the sheet stays inside the box instead of
// covering the page. Leave `container` out and the sheet portals to <body>.
function DynamicHeight({ frame }: { frame: HTMLElement }) {
  const [open, setOpen] = useState(false);
  const [rows, setRows] = useState(2);

  return (
    <div className="demo-page">
      <button
        type="button"
        className="demo-button"
        onClick={() => setOpen(true)}
      >
        Open the sheet
      </button>

      <Sheet
        open={open}
        onOpenChange={setOpen}
        snapPoints={["header", "content"]}
        defaultSnapIndex={1}
      >
        <Sheet.Portal container={frame}>
          <Sheet.Overlay className="demo-overlay" />
          <Sheet.Content className="demo-sheet">
            <Sheet.Handle className="demo-handle" />
            <Sheet.Header className="demo-header">
              <Sheet.Title className="demo-title">Measured live</Sheet.Title>
              <Sheet.Description className="demo-description">
                Snap 0 is the header, snap 1 is the whole content.
              </Sheet.Description>
            </Sheet.Header>
            <Sheet.Body className="demo-body">
              <button
                type="button"
                className="demo-button"
                onClick={() => setRows((n) => n + 1)}
              >
                Add a row
              </button>
              <ul className="demo-list">
                {Array.from({ length: rows }, (_, i) => i + 1).map((n) => (
                  <li key={n}>Row {n}</li>
                ))}
              </ul>
            </Sheet.Body>
          </Sheet.Content>
        </Sheet.Portal>
      </Sheet>
    </div>
  );
}

Released under the MIT License.