Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f9c8e84
Stub out support for polars in data grid
machow Jun 6, 2024
90f8d01
Stub out more grid support
machow Jun 20, 2024
63101b7
flesh out tbl_data module and test
machow Jun 21, 2024
7af8424
Merge branch 'main' into feat-data-grid-polars
schloerke Jun 21, 2024
6f2403b
fix: wrong variable in error messages
machow Jun 21, 2024
f6827d5
fix: serialize pandas datetimes as ISO8601
machow Jun 24, 2024
9f753a3
chore: remove unused import
machow Jun 24, 2024
8160692
fix: to_json by default converts objects to strings
machow Jun 27, 2024
4239590
tests: add playwright polars data_frame app (untested)
machow Jun 27, 2024
31daefe
fix: add more _tbl_data tests, fixes and more typing
machow Jun 27, 2024
7bd2f14
Merge branch 'main' into machow-feat-data-grid-polars
schloerke Jul 2, 2024
c31737d
Fix typing for df. Add `render._types` file. Expose `shiny.types.Json…
schloerke Jul 2, 2024
22d32a8
Update types for testing file
schloerke Jul 2, 2024
7de1130
More robust tests from #1475; Test and fix class support in StyleInfo
schloerke Jul 3, 2024
4fe7cf2
First pass at integration. Still more work to do
schloerke Jul 3, 2024
a99948d
Merge branch 'main' into machow-feat-data-grid-polars
schloerke Jul 5, 2024
9686cc0
Update _controls.py
schloerke Jul 5, 2024
aa1b9c6
Expose `render.DataFrameLike`
schloerke Jul 5, 2024
1ae281e
lints
schloerke Jul 5, 2024
2a81f5e
Use more tbl methods
schloerke Jul 5, 2024
54f37dc
More tbl integrations; Add note for future integrations currently out…
schloerke Jul 5, 2024
61b1a3f
Fix styles app
schloerke Jul 8, 2024
af6894b
Fix styles class app / test
schloerke Jul 8, 2024
0406c65
lints
schloerke Jul 8, 2024
534bd82
Cleanups
schloerke Jul 8, 2024
89e0aa8
bug: Fix polars serialized `data` into an array of arrays by row, not…
schloerke Jul 8, 2024
ea4be98
polars Html support updated tests
schloerke Jul 8, 2024
1a6128f
More testing with polars data frame apps
schloerke Jul 8, 2024
b2047ba
Use more generic base type for `is_data_frame_like()`
schloerke Jul 8, 2024
dd2f867
Test `PandasCompatible` object for `@render.data_frame`
schloerke Jul 8, 2024
9cfc3ec
Merge branch 'main' into machow-feat-data-grid-polars
schloerke Jul 8, 2024
8683bf9
Update _tbl_data.py
schloerke Jul 8, 2024
fcf7d76
lints
schloerke Jul 8, 2024
28f3a14
Update _datagridtable.py
schloerke Jul 8, 2024
57bc292
lints
schloerke Jul 9, 2024
1b8ce68
splode more single dispatch registrations
schloerke Jul 9, 2024
c9d36e3
Update _tbl_data.py
schloerke Jul 9, 2024
5369ad2
Update _tbl_data.py
schloerke Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions js/data-frame/cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ type CellHtmlValue = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isShinyHtml = (x: any): x is CellHtmlValue => {
return (
x !== null &&
typeof x !== "string" &&
x !== null && // Note: x === null has `typeof x === "object"`
typeof x === "object" &&
Object.prototype.hasOwnProperty.call(x, "isShinyHtml") &&
x.isShinyHtml === true
);
Expand Down Expand Up @@ -83,6 +83,7 @@ interface TableBodyCellProps {
setData: (fn: (draft: unknown[][]) => void) => void;
cellEditInfo: CellEdit | undefined;
cellStyle: CellStyle | undefined;
cellClassName: string | undefined;
setCellEditMapAtLoc: SetCellEditMapAtLoc;
selection: SelectionSet<string, HTMLTableRowElement>;
}
Expand All @@ -100,6 +101,7 @@ export const TableBodyCell: FC<TableBodyCellProps> = ({
getSortedRowModel,
cellEditInfo,
cellStyle,
cellClassName,
setData,
setCellEditMapAtLoc,
selection,
Expand Down Expand Up @@ -402,7 +404,7 @@ export const TableBodyCell: FC<TableBodyCellProps> = ({
let content: ReactElement | ReturnType<typeof flexRender> | undefined =
undefined;
const cellTitle = errorTitle;
let tableCellClass: string | undefined = undefined;
let tableCellClass: string | undefined = cellClassName;
const addToTableCellClass = (x: string | undefined) => {
if (!x) return;
if (tableCellClass) {
Expand Down
23 changes: 17 additions & 6 deletions js/data-frame/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,27 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = ({
columns,
typeHints,
data: tableDataProp,
options: payloadOptions,
options: payloadOptions = {
width: undefined,
height: undefined,
fill: false,
styles: [],
},
} = payload;
const { width, height, fill, filters: withFilters } = payloadOptions;
const {
width,
height,
fill,
filters: withFilters,
styles: initStyleInfos,
} = payloadOptions;

const containerRef = useRef<HTMLDivElement>(null);
const theadRef = useRef<HTMLTableSectionElement>(null);
const tbodyRef = useRef<HTMLTableSectionElement>(null);

const _useStyleInfo = useStyleInfoMap({
initStyleInfos: payloadOptions["styles"],
initStyleInfos: initStyleInfos ?? [],
nrow: tableDataProp.length,
ncol: columns.length,
});
Expand Down Expand Up @@ -486,7 +497,6 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = ({
useEffect(() => {
const handleStyles = (event: CustomEvent<{ styles: StyleInfo[] }>) => {
const styles = event.detail.styles;
resetStyleInfos();
setStyleInfos(styles);
};

Expand All @@ -503,7 +513,7 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = ({
handleStyles as EventListener
);
};
}, [setStyleInfos]);
}, [id, setStyleInfos]);

useEffect(() => {
if (!id) return;
Expand Down Expand Up @@ -765,7 +775,7 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = ({
rowIndex,
columnIndex
);
const cellStyle = getCellStyle(
const { cellStyle, cellClassName } = getCellStyle(
styleInfoMap,
"body",
rowIndex,
Expand All @@ -787,6 +797,7 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = ({
getSortedRowModel={table.getSortedRowModel}
cellEditInfo={cellEditInfo}
cellStyle={cellStyle}
cellClassName={cellClassName}
setData={setTableData}
setCellEditMapAtLoc={setCellEditMapAtLoc}
selection={selection}
Expand Down
36 changes: 30 additions & 6 deletions js/data-frame/style-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,30 @@ export const useStyleInfoMap = ({
rowIndex,
columnIndex,
});
const prevObj = draft.get(key) ?? { style: {}, class: undefined };
let newClass: string | undefined = undefined;
if (prevObj.class) {
if (styleInfo.class) {
newClass = `${prevObj.class} ${styleInfo.class}`;
} else {
newClass = prevObj.class;
}
} else {
if (styleInfo.class) {
newClass = styleInfo.class;
} else {
newClass = undefined;
}
}
draft.set(key, {
location: styleInfo.location,
location,
rowIndex,
columnIndex,
style: styleInfo.style,
class: styleInfo.class,
style: {
...prevObj.style,
...styleInfo.style,
},
class: newClass,
});
}
}
Expand All @@ -105,11 +123,13 @@ export const useStyleInfoMap = ({

const setStyleInfos = useCallback(
(styleInfos: StyleInfo[]) => {
// When settings styleInfos, reset all style infos
resetStyleInfos();
for (const styleInfo of styleInfos) {
setStyleInfo(styleInfo);
}
},
[setStyleInfo]
[setStyleInfo, resetStyleInfos]
);

// Init all style infos
Expand Down Expand Up @@ -138,9 +158,13 @@ export const getCellStyle = (
location: StyleLocation,
rowIndex: number,
columnIndex: number
): CellStyle | undefined => {
): { cellStyle: CellStyle | undefined; cellClassName: string | undefined } => {
const key = makeStyleInfoMapKey({ location, rowIndex, columnIndex });
return x.get(key)?.style;
const obj = x.get(key);
return {
cellStyle: obj?.style,
cellClassName: obj?.class,
};
};

// Use a DOM element to convert CSS string to object
Expand Down
2 changes: 1 addition & 1 deletion js/data-frame/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface DataGridOptions {
width?: string;
height?: string;
fill?: boolean;
styles: StyleInfo[];
}

export interface PandasData<TIndex> {
Expand All @@ -33,7 +34,6 @@ export interface PandasData<TIndex> {
options: DataGridOptions;
typeHints?: ReadonlyArray<TypeHint>;
editable?: boolean;
styles: StyleInfo[];
}

export interface PatchInfo {
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ dev =
matplotlib
pandas
pandas-stubs
polars
numpy
shinyswatch>=0.2.4
# Chat() provider types
Expand Down
17 changes: 9 additions & 8 deletions shiny/playwright/controller/_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6255,10 +6255,12 @@ def set_sort(
----------
sort
The sorting configuration to apply. Can be one of the following:
int: Index of the column to sort by (ascending order by default).
ColumnSort: A dictionary specifying a single column sort with 'col' and 'desc' keys.
list[ColumnSort]: A list of dictionaries for multi-column sorting.
None: No sorting applied (not implemented in the current code).
* `int`: Index of the column to sort by (ascending order by default).
* `ColumnSort`: A dictionary specifying a single column sort with 'col' and 'desc' keys.
* `list[int | ColumnSort]`: A list of ints or dictionaries for multi-column sorting.
* `None`: No sorting applied (not implemented in the current code).

If a `desc` values is provided within your `ColumnSort` shaped dictionary, then the direction will be set to that value. If no `desc` value is provided, the column will be sorted in the default sorting order.
timeout
The maximum time to wait for the action to complete. Defaults to `None`.
"""
Expand Down Expand Up @@ -6348,10 +6350,9 @@ def set_filter(
----------
filter
The filter to apply. Can be one of the following:
None: Resets all filters.
str: A string filter (deprecated, use ColumnFilterStr instead).
ColumnFilterStr: A dictionary specifying a string filter with 'col' and 'value' keys.
ColumnFilterNumber: A dictionary specifying a numeric range filter with 'col' and 'value' keys.
* `None`: Resets all filters.
* `ColumnFilterStr`: A dictionary specifying a string filter with 'col' and 'value' keys.
* `ColumnFilterNumber`: A dictionary specifying a numeric range filter with 'col' and 'value' keys.
timeout
The maximum time to wait for the action to complete. Defaults to `None`.
"""
Expand Down
3 changes: 3 additions & 0 deletions shiny/playwright/expect/_expect.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def expect_attribute_to_have_value(
def expect_to_have_class(
loc: Locator,
cls: str,
*,
timeout: Timeout = None,
) -> None:
"""Expect a locator to contain a class value"""
Expand All @@ -56,6 +57,7 @@ def expect_to_have_class(
def expect_not_to_have_class(
loc: Locator,
cls: str,
*,
timeout: Timeout = None,
) -> None:
"""Expect a locator not to contain a class value"""
Expand All @@ -69,6 +71,7 @@ def expect_to_have_style(
css_key: str,
# Str representation for value. Will be put in a regex with `css_key`
css_value: StyleValue,
*,
timeout: Timeout = None,
) -> None:
"""Expect the `style` attribute to have a value. If `value` is `None`, then the style attribute should not exist."""
Expand Down
4 changes: 3 additions & 1 deletion shiny/render/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
DataTable,
data_frame,
)
from ._data_frame_utils import CellSelection, StyleInfo
from ._data_frame_utils import CellSelection
from ._data_frame_utils._types import DataFrameLike, StyleInfo
from ._deprecated import ( # noqa: F401
RenderFunction, # pyright: ignore[reportUnusedImport]
RenderFunctionAsync, # pyright: ignore[reportUnusedImport]
Expand Down Expand Up @@ -47,4 +48,5 @@
"CellValue",
"CellSelection",
"StyleInfo",
"DataFrameLike",
)
Loading