Add width and height configuration to st.table#13850
Conversation
Implement configurable width and height for arrow tables with proper overflow handling and scrolling behavior. Includes styled-components updates, frontend component changes, and backend protobuf field additions with corresponding tests.
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
width and height configuration to st.table
There was a problem hiding this comment.
Pull request overview
Adds width/height sizing support for st.table across the Python API and frontend rendering so tables can be constrained (pixel, stretch, content) and support scrolling with sticky headers/index.
Changes:
- Backend: add
width/heightparameters tost.table, validate them, and serialize viaLayoutConfig. - Frontend: update
ArrowTablestyling/logic for scroll containers, sticky header/index behavior, and cell wrapping/truncation. - Tests: add Python unit tests for layout config serialization + frontend unit tests for truncation/sticky offsets.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| table-width-height.md | Adds an implementation plan document for the feature. |
| table-sizing.md | Adds implementation notes/learned behavior for CSS sizing + sticky/scroll details. |
| lib/streamlit/elements/arrow.py | Extends st.table API with width/height, validates inputs, and enqueues with LayoutConfig. |
| lib/tests/streamlit/elements/arrow_table_test.py | Adds backend tests for width/height validation + layout config serialization. |
| frontend/lib/src/components/elements/ArrowTable/ArrowTable.tsx | Adds width/height config props + sticky/scroll logic. |
| frontend/lib/src/components/elements/ArrowTable/styled-components.ts | Implements scroll container changes, sticky cell styles, and wrapping/truncation rules. |
| frontend/lib/src/components/elements/ArrowTable/ArrowTable.test.tsx | Adds frontend tests for truncation defaults and sticky offset behavior. |
| frontend/lib/src/components/core/Block/StyledElementContainerLayoutWrapper.tsx | Adds table to stretch sizing behavior and documents overflow handling intent. |
Remove unnecessary useMemo wrappers for simple boolean coercions and replace nested ternary with clearer getStickyType helper function.
width and height configuration to st.tablewidth and height configuration to st.table
Delete table-sizing.md and table-width-height.md files that are no longer needed.
Resolved conflict in StyledElementContainerLayoutWrapper.tsx by adopting the new ElementContainerConfig pattern from develop. Updated the table case in ElementNodeRenderer.tsx to use ElementContainerConfig.LARGE_ELEMENT to preserve the large stretch behavior for st._arrow_table.
✅ PR preview is ready!
|
- Add E2E tests for fixed height, width, and combined scrolling behavior - Add test for multi-index tables with sticky index columns - Document fallback offset constants in ArrowTable.tsx explaining their purpose
Add dedicated tableColumnMaxWidth constant to avoid affecting the status widget which shares appStatusMaxWidth.
Sticky index columns now have a min-width matching the fallback offset (120px), ensuring consistent column widths and preventing gaps or overlaps between sticky columns.
Update the height parameter documentation to accurately describe that sticky index columns only work when horizontal scrolling is enabled via a fixed pixel width, not just with vertical scrolling.
Update snapshots to reflect the increased table column max width (20rem -> 25rem) and multi-index sticky column fixes.
There was a problem hiding this comment.
As a follow-up, it probably makes sense to clean this up so that it doesn't depend on indices.
- Consolidate 4 separate width/height tests into 2 focused tests:
1. Fixed dimensions with multi-index (tests scrolling in both directions
with sticky headers and index columns)
2. Content width sizing (tests width="content")
- Remove redundant snapshots for height-only and width-only tests
- CI will regenerate Linux snapshots for the new tests
There was a problem hiding this comment.
The PR adds a max column width that will trigger the column to wrap to new line
Add snapshots for: - st_table-35/36: Numbered snapshots for the two new test tables - st_table-fixed_dimensions_scrolled: Multi-index table scrolled in both directions - st_table-content_width: Table with width="content" sizing
The fit-content styling on markdown containers was preventing code blocks from expanding to fill the available cell width. Add a specific CSS rule for pre elements to use 100% width while keeping the fit-content behavior for regular text content.
📈 Frontend coverage change detectedThe frontend unit test (vitest) coverage has increased by 0.0400%
✅ Coverage change is within normal range. |
|
@cursor review |
5da8676 to
d3a6f76
Compare
The content_width table is already covered by test_table_rendering which iterates through all table indices including index 36.
Replace data-testid selector with direct Emotion component selector for better type safety and maintainability.
1a608fc to
a3a39a0
Compare
- Add overflow-y: hidden to markdown CSS in ArrowTable to prevent vertical overflow affecting layout - Add width constraints and overflow: clip to StyledTableContainer - Add brief markdown test row to st_table.py with key features - Add code block to st_markdown.py test
Convert hardcoded pixel fallbacks to rem-based values so they scale properly with user font size changes. The header row offset (2rem) is now derived from theme tokens, and the index column offset (7.5rem) scales proportionally instead of being fixed at 120px.
Add verticalAlign: top to markdown elements in table cells to prevent the baseline shift caused by overflowY: hidden on inline-block elements.
width and height configuration to st.tablewidth and height configuration to st.table
SummaryThis PR adds configurable
Code QualityThe code is well-structured and follows existing Streamlit patterns:
Test CoverageTest coverage is thorough and appropriate:
One minor observation: the e2e Backwards CompatibilityThe changes maintain backwards compatibility:
Security & RiskNo security concerns identified:
Accessibility
Recommendations
VerdictAPPROVED: Well-implemented feature with good test coverage, proper validation, backwards-compatible defaults, and clean code that follows established Streamlit patterns. The minor optimization and accessibility suggestions are non-blocking. This is an automated AI review by |
Precompute fallbackIndexColumnWidthPx once via useMemo to avoid redundant DOM-based rem-to-px conversions per cell. Add tabindex, role, and aria-label to scrollable table wrapper for keyboard navigation accessibility.
- Remove redundant conditional in getStickyOffset function - Replace if-else chain with STICKY_Z_INDEX lookup map - Remove unnecessary toBeTruthy assertions in frontend tests - Consolidate repetitive Python tests with parameterized.expand
| // Index column: approximate width for typical index values | ||
| const FALLBACK_INDEX_COLUMN_OFFSET_REM = "7.5rem" |
There was a problem hiding this comment.
question: Is this really a fallback? It seems like we are not actually measuring anything on screen, and instead, we're just using this value everywhere.
In general, I think columns are going to be a bit more variable in terms of their content, so having a static value here makes me wonder about visual edge cases that may come up. Is there a better way to measure actual column widths at runtime?
There was a problem hiding this comment.
Calculating this at runtime would be a bit complex/hacky since column width only handled by CSS. But taking a step back, this is only for multi-index cases - which are rare - and for st.table we anyways plan to auto-hide the index in many cases... so its less important to have this sticky compared to `st.dataframe.
I pushed a change to clean this up and only apply stickyness for single index columns.
Sticky index columns now only work for single-index DataFrames. This simplifies the code by removing the fallback width approximation that was needed for positioning multiple sticky index columns.
8283b2d to
9839a9a
Compare
## Describe your changes Implement configurable width and height support for `st.table` with proper scrolling behavior and sticky headers/index columns. The table element now accepts: - `width`: `"content"` | `"stretch"` | `int` (pixels) - `height`: `"content"` | `"stretch"` | `int` (pixels) When a fixed pixel dimension is specified, the table enables scrolling with sticky headers (top) and index columns (left) for easy navigation through large datasets. ## Github Issues - Closes #10775 - Closes #10820 - Related #13185 ## Testing Plan - Frontend unit tests validate width/height configuration, sticky header/index positioning, and content truncation behavior - Backend unit tests verify parameter validation and LayoutConfig serialization - Default behavior (`width="stretch"`, `height="content"`) maintains backward compatibility --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
Describe your changes
Implement configurable width and height support for
st.tablewith proper scrolling behavior and sticky headers/index columns. The table element now accepts:width:"content"|"stretch"|int(pixels)height:"content"|"stretch"|int(pixels)When a fixed pixel dimension is specified, the table enables scrolling with sticky headers (top) and index columns (left) for easy navigation through large datasets.
Github Issues
width="content"inst.table()#10775width&heightsupport tost.table#10820Testing Plan
width="stretch",height="content") maintains backward compatibilityContribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.