Meowland docs
Workbench

Component reference

LayoutItem

A wrapper that sets how one child of a Stack or Inline grows, shrinks and aligns.

Preview

Text baseline and fixed actions

Related text sits close along the baseline; the body can shrink while actions keep their natural width; wrap line spacing is independent of group spacing.

packages/meowtail/stories/layout.stories.tsxline 28tsx
render: () => (
  <Measure width="content">
    <Stack gap="relaxed">
      <Inline as="header" gap="compact" align="baseline" data-layout-summary>
        <small>Default connection</small>
        <Inline gap="compact" align="baseline">
          <strong>Codex</strong>
          <small>gpt-6-luna</small>
        </Inline>
      </Inline>
      <Inline wrap={false} align="center" data-layout-fixed>
        <LayoutItem grow>
          <Stack gap="compact">
            <strong>Default model connection shared by the team</strong>
            <span style={{ overflowWrap: "anywhere" }}>
              organization/research-model-with-a-very-long-unbroken-identifier-2026
            </span>
          </Stack>
        </LayoutItem>
        <LayoutItem shrink={false}>
          <Button variant="outline">Edit connection</Button>
        </LayoutItem>
      </Inline>
      <Inline as="footer" gap="compact" rowGap="normal" data-layout-actions>
        <Button>Save current configuration</Button>
        <Button variant="outline">Restore default configuration</Button>
        <Button variant="quiet">Check connection availability</Button>
      </Inline>
      <Grid columns={2} gap="relaxed" rowGap="compact" data-layout-grid-gaps>
        <span>Connection name</span>
        <span>Current model</span>
        <strong>Codex</strong>
        <span>gpt-6-luna</span>
      </Grid>
    </Stack>
  </Measure>
)

Installation

bun add meowtail

Usage

Taken from the examples on this page.

usage.tsxtsx
import { LayoutItem } from "meowtail";

<LayoutItem grow>
  <Stack gap="compact">
    <strong>Default model connection shared by the team</strong>
    <span style={{ overflowWrap: "anywhere" }}>
      organization/research-model-with-a-very-long-unbroken-identifier-2026
    </span>
  </Stack>
</LayoutItem>

Examples

The other stories that show this component.

Fixed header and footer with local scrolling

The layout allocates the limited height and the reading area scrolls independently; fixed actions, the draft, and natural content flow keep their identity.

packages/meowtail/stories/layout.stories.tsxline 256tsx
render: () => {
  const count = signal(24);
  return (
    <Measure width="wide">
      <Stack
        gap="compact"
        style={{ height: "clamp(240px, calc(100dvh - 170px), 540px)" }}
        data-nested-layout
      >
        <LayoutItem shrink={false} data-nested-fixed="header">
          <Inline gap="compact" justify="between">
            <strong>Check dynamic content and available space</strong>
            <Button size="small" variant="outline" onClick={() => (count.value += 12)}>
              Append content
            </Button>
          </Inline>
        </LayoutItem>
        <LayoutItem grow basis={0} style={{ display: "flex" }} data-nested-body>
          <Inline wrap={false} align="stretch" gap="compact" style={{ flex: 1 }}>
            <LayoutItem basis={120} shrink={false} style="color:inherit" data-numeric-basis>
              <Stack gap="compact">
                <strong>Current scope</strong>
                <span>Layout basis</span>
                <Badge>Local check</Badge>
              </Stack>
            </LayoutItem>
            <LayoutItem grow basis="0%" style={{ display: "flex" }} data-percent-basis>
              <Stack gap="compact" style={{ flex: 1 }}>
                <LayoutItem shrink={false}>
                  <Field label="Review draft" htmlFor="nested-layout-draft">
                    <Input
                      id="nested-layout-draft"
                      placeholder="Keep editing after the window changes"
                    />
                  </Field>
                </LayoutItem>
                <LayoutItem grow basis={0} style={{ display: "flex" }}>
                  <Grid columns={1} gap="none" style={{ flex: 1 }}>
                    <Stack
                      gap="compact"
                      role="region"
                      aria-label="Nested layout reading area"
                      tabIndex={0}
                      style={{ overflow: "auto", overscrollBehavior: "contain" }}
                      data-nested-scroll
                    >
                      {mapSignal(count, (value) =>
                        Array.from({ length: value }, (_, index) => (
                          <p style={{ margin: 0, overflowWrap: "anywhere" }}>
                            Record {index + 1}: Long content flows continuously inside the reading
                            area while the input and bottom actions stay reachable.
                            organization/research-model-with-a-very-long-unbroken-identifier-2026
                          </p>
                        )),
                      )}
                    </Stack>
                  </Grid>
                </LayoutItem>
              </Stack>
            </LayoutItem>
          </Inline>
        </LayoutItem>
        <LayoutItem shrink={false} data-nested-fixed="footer">
          <Inline gap="compact">
            <Button>Finish check</Button>
            <span>Fixed actions do not scroll with the reading area.</span>
          </Inline>
        </LayoutItem>
      </Stack>
    </Measure>
  );
}

API reference

Props

PropTypeDefault
as
LayoutElement"div"
grow
booleanfalse
shrink
booleantrue
basis
string | number"auto"
alignSelf
LayoutAlign | "auto""auto"

Also takes className, children and the attributes and events of its root element.

DOM parts

root

Registry

The component is registered as layout-item in the meowtail component registry.