XDSSection/XDSHStack: no overflow or flex grow/shrink props — multi-pane layouts need custom CSS
- Dominant language
- TypeScript
- Stars
- 13k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 690
Description
## Problem
`XDSSection` and `XDSStack`/`XDSHStack` expose sizing props (`width`, `height`, `maxWidth`, `minHeight`) but **no** props for:
- **overflow** (`overflow-x` / `overflow-y` / scroll)
- **flex item sizing** (`flex-grow` / `flex-shrink` / `flex-basis`)
This forces any multi-pane / scrollable layout built from these primitives to drop to raw `stylex` for layout plumbing, which costs Custom-CSS points on the [template grading rubric](https://github.com/facebookexperimental/xds/wiki/Contributing-Templates#3-custom-css-15-pts) even though there's no idiomatic alternative.
## Concrete case: the `file-explorer` page template
A macOS-Finder-style Miller-column browser (`packages/cli/templates/pages/file-explorer/page.tsx`) is otherwise pure XDS (zero raw HTML, zero raw SVG, complete doc) but is capped at **A (90/100)** purely by Custom CSS, because it needs:
| Custom style | Property | What XDS prop would replace it |
|---|---|---|
| `page` | `height: 100dvh` | A way for `XDSLayout height="fill"` to fill the host when the host `/` aren't `height:100%` (or a documented "fill the viewport" escape) |
| `columnRow` | `overflowX: auto`, `overflowY: hidden` | `overflow` / `scroll` prop on `XDSHStack` (horizontal scroll of the column strip on small viewports) |
| `scrollable` | `overflowY: auto` | `isScrollable` / `overflow` prop on `XDSSection` (per-column vertical scroll) |
| `fixedColumn` | `flexShrink: 0` | `shrink={false}` / flex-item prop on `XDSSection` |
| `detailColumn` | `flexGrow: 1`, `flexShrink: 0`, `flexBasis: 320` | `grow` / `shrink` / `basis` props on `XDSSection` |
`XDSLayoutPanel` already supports `isScrollable` + `width` + `hasDivider` natively, but it only works in `XDSLayout`'s fixed `start`/`content`/`end` slots — it can't host a **dynamic, runtime-variable number** of columns (Finder columns grow/shrink as you navigate), and nested layouts **squeeze** fixed-width panels on narrow viewports instead of scrolling horizontally. So the data-driven `.map()` + `XDSHStack` + `XDSSection` approach is the right structure, and it has no prop-based way to express overflow/flex sizing.
## Proposed
Add to `XDSSection` (and ideally `XDSStack`/`XDSHStack`/`XDSVStack`):
- `isScrollable?: boolean` or `overflow?: 'visible' | 'auto' | 'clip' | 'hidden'` (and/or per-axis)
- flex-item props: `grow?: boolean | number`, `shrink?: boolean | number`, `basis?: SizeValue`
This would let scrollable multi-pane layouts (file browsers, kanban boards, horizontal card strips) be expressed prop-only and score full Custom-CSS marks.
Contributor guide
Assessment
This issue has not been assessed yet.