Skip to content

Commit 2c1c32c

Browse files
cpsievertschloerke
andauthored
Update @render.data_frame renderer to work properly with fill/fillable (#1126)
Co-authored-by: Barret Schloerke <[email protected]>
1 parent ce53433 commit 2c1c32c

File tree

7 files changed

+68
-17
lines changed

7 files changed

+68
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222

2323
### Other changes
2424

25+
* `@render.data_frame` now properly fills its container by default. (#1126)
26+
2527
* We improved the accessibility of the full screen toggle button in cards created with `ui.card(full_screen=True)`. Full-screen cards are now also supported on mobile devices. (#1129)
2628

2729
* When entering and exiting full-screen card mode, Shiny now emits a client-side custom `bslib.card` event that JavaScript-oriented users can use to react to the full screen state change. (#1129)

js/dataframe/index.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ interface ShinyDataGridProps<TIndex> {
5959
const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = (props) => {
6060
const { id, data, bgcolor } = props;
6161
const { columns, type_hints, data: rowData } = data;
62-
const { width, height, filters: withFilters } = data.options;
62+
const { width, height, fill, filters: withFilters } = data.options;
6363

6464
const containerRef = useRef<HTMLDivElement>(null);
6565
const theadRef = useRef<HTMLTableSectionElement>(null);
@@ -213,10 +213,13 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = (props) => {
213213

214214
const headerRowCount = table.getHeaderGroups().length;
215215

216-
const scrollingClass =
217-
containerRef.current?.scrollHeight > containerRef.current?.clientHeight
218-
? "scrolling"
219-
: "";
216+
// Assume we're scrolling until proven otherwise
217+
let scrollingClass = "scrolling";
218+
const scrollHeight = containerRef.current?.scrollHeight;
219+
const clientHeight = containerRef.current?.clientHeight;
220+
if (scrollHeight && clientHeight && scrollHeight <= clientHeight) {
221+
scrollingClass = "";
222+
}
220223

221224
const makeHeaderKeyDown =
222225
(column: Column<unknown[], unknown>) => (event: React.KeyboardEvent) => {
@@ -227,12 +230,17 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = (props) => {
227230

228231
const measureEl = useVirtualizerMeasureWorkaround(rowVirtualizer);
229232

233+
let className = `shiny-data-grid ${containerClass} ${scrollingClass}`;
234+
if (fill) {
235+
className += " html-fill-item";
236+
}
237+
230238
return (
231239
<>
232240
<div
233-
className={`shiny-data-grid ${containerClass} ${scrollingClass}`}
241+
className={className}
234242
ref={containerRef}
235-
style={{ width, maxHeight: height, overflow: "auto" }}
243+
style={{ width, height, overflow: "auto" }}
236244
>
237245
<table
238246
className={tableClass + (withFilters ? " filtering" : "")}

js/dataframe/styles.scss

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838

3939
.shiny-data-grid {
4040
max-width: 100%;
41+
height: 500px;
42+
&:not(.scrolling) {
43+
height: auto;
44+
}
4145

4246
> table {
4347
border-collapse: separate;
@@ -198,3 +202,20 @@
198202
}
199203
}
200204
}
205+
206+
/* Center the table when inside of a card */
207+
.card-body .shiny-data-grid {
208+
margin-left: auto;
209+
margin-right: auto;
210+
}
211+
212+
213+
/* When .shiny-data-grid is not scrolling, the containers shouldn't flex */
214+
shiny-data-frame {
215+
&:has(> div > .shiny-data-grid:not(.scrolling)) {
216+
flex: 0 0 auto;
217+
}
218+
> div:has(> .shiny-data-grid:not(.scrolling)) {
219+
flex: 0 0 auto;
220+
}
221+
}

js/dataframe/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface DataGridOptions {
1616
filters?: boolean;
1717
width?: string;
1818
height?: string;
19+
fill?: boolean;
1920
}
2021

2122
export interface PandasData<TIndex> {

shiny/render/_dataframe.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ class DataGrid(AbstractTabularData):
4242
A pandas `DataFrame` object, or any object that has a `.to_pandas()` method
4343
(e.g., a Polars data frame or Arrow table).
4444
width
45-
A _maximum_ amount of vertical space for the data grid to occupy, in CSS units
45+
A _maximum_ amount of horizontal space for the data grid to occupy, in CSS units
4646
(e.g. `"400px"`) or as a number, which will be interpreted as pixels. The
4747
default is `fit-content`, which sets the grid's width according to its contents.
4848
Set this to `100%` to use the maximum available horizontal space.
4949
height
5050
A _maximum_ amount of vertical space for the data grid to occupy, in CSS units
5151
(e.g. `"400px"`) or as a number, which will be interpreted as pixels. If there
5252
are more rows than can fit in this space, the grid will scroll. Set the height
53-
to `None` to allow the grid to grow to fit all of the rows (this is not
53+
to `"auto"` to allow the grid to grow to fit all of the rows (this is not
5454
recommended for large data sets, as it may crash the browser).
5555
summary
5656
If `True` (the default), shows a message like "Viewing rows 1 through 10 of 20"
@@ -83,7 +83,7 @@ def __init__(
8383
data: object,
8484
*,
8585
width: str | float | None = "fit-content",
86-
height: Union[str, float, None] = "500px",
86+
height: Union[str, float, None] = None,
8787
summary: Union[bool, str] = True,
8888
filters: bool = False,
8989
row_selection_mode: Literal["none", "single", "multiple"] = "none",
@@ -113,6 +113,7 @@ def to_payload(self) -> Jsonifiable:
113113
filters=self.filters,
114114
row_selection_mode=self.row_selection_mode,
115115
style="grid",
116+
fill=self.height is None,
116117
)
117118
return res
118119

shiny/www/shared/py-shiny/dataframe/dataframe.js

Lines changed: 22 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shiny/www/shared/py-shiny/dataframe/dataframe.js.map

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)