Skip to content

Commit 4a5b1ef

Browse files
committed
UI polish - duplicate expand/collapse
1 parent e63a2fe commit 4a5b1ef

6 files changed

Lines changed: 283 additions & 69 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ uv pip install -e '.[with-streamlit]' --force-reinstall
571571
uv run streamlit run streamlit_app.py
572572
```
573573

574-
The example app (`streamlit_app.py`) contains 13 sections demonstrating every feature with interactive examples and inline documentation.
574+
The example app (`streamlit_app.py`) contains 13 sections covering the major features and usage patterns with interactive examples and inline documentation.
575575

576576
### Building the frontend
577577

SKILL.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ Returns a `PivotTableResult` dict containing the current `config` state.
6666
| `columns` | `list[str] \| None` | `None` | Column names to use as column dimensions. |
6767
| `values` | `list[str] \| None` | `None` | Column names to aggregate as measures. |
6868
| `synthetic_measures` | `list[dict] \| None` | `None` | Derived measures computed from source-field sums (e.g., ratio of sums). See [Synthetic Measures](#synthetic-measures). |
69-
| `aggregation` | `str` | `"sum"` | Aggregation function. See [Aggregation Functions](#aggregation-functions). |
70-
| `interactive` | `bool` | `True` | Enable toolbar controls for reconfiguring the pivot. |
69+
| `aggregation` | `str \| dict[str, str]` | `"sum"` | Aggregation setting for raw value fields. A single string applies to every raw measure; a dict enables per-measure aggregation. See [Aggregation Functions](#aggregation-functions). |
70+
| `interactive` | `bool` | `True` | Enable end-user config controls. When `False`, the toolbar is hidden and header-menu sort/filter/show-values-as actions are disabled. |
7171

7272
#### Totals and Subtotals
7373

@@ -109,9 +109,9 @@ Returns a `PivotTableResult` dict containing the current `config` state.
109109
| Parameter | Type | Default | Description |
110110
|-----------|------|---------|-------------|
111111
| `on_cell_click` | `Callable[[], None] \| None` | `None` | Called when a user clicks a data cell. Read the payload from `st.session_state[key]`. See [Cell Click Payload](#cell-click-payload). |
112-
| `on_config_change` | `Callable[[], None] \| None` | `None` | Called when the user changes the pivot config via the toolbar. |
112+
| `on_config_change` | `Callable[[], None] \| None` | `None` | Called when the user changes the pivot config interactively, including toolbar and header-menu actions. |
113113
| `enable_drilldown` | `bool` | `True` | Show an inline drill-down panel with source records when a cell is clicked. |
114-
| `locked` | `bool` | `False` | Viewer mode with exploration enabled. Toolbar config controls are read-only, while data export, group expand/collapse, and header-menu sorting/filtering/show-values-as remain available. |
114+
| `locked` | `bool` | `False` | Viewer mode with exploration enabled. Toolbar config controls are read-only, viewer-safe actions like data export and group expand/collapse remain available, and header-menu sorting/filtering/`Show Values As` plus drill-down still work. |
115115
| `export_filename` | `str \| None` | `None` | Base filename (without extension) for exported files. Date and extension are appended automatically. Defaults to `"pivot-table"`. |
116116

117117
#### Data Control
@@ -415,7 +415,7 @@ Hover over a parent column header to reveal the collapse toggle.
415415

416416
### Data Export
417417

418-
Export the pivot table as CSV, TSV, or copy to clipboard. Available via the toolbar utility menu (download icon) when `interactive=True`.
418+
Export the pivot table as CSV, TSV, or copy to clipboard. Available via the toolbar utility menu (download icon) whenever the interactive toolbar is shown, including locked viewer mode.
419419

420420
- **Format**: CSV, TSV, or Clipboard (tab-separated for pasting into spreadsheets)
421421
- **Content**: Formatted (display values with currency, percentages, etc.) or Raw (unformatted numbers)
@@ -445,7 +445,7 @@ result = st_pivot_table(
445445

446446
### Locked Mode
447447

448-
Freeze toolbar config controls so end-users cannot change rows, columns, values, aggregation, or display settings. The entire utility menu (reset, swap, config import/export, data export, settings) is hidden. Sorting and filtering via header menus remain available.
448+
Use `locked=True` for a viewer-mode experience with exploration enabled. Toolbar config controls stay locked so end-users cannot change rows, columns, values, per-measure aggregation, or settings toggles. Reset, Swap, and config import/export are hidden, while data export remains available and the Settings gear stays visible for read-only display status plus Expand/Collapse All group controls. Header-menu sorting, filtering, and `Show Values As` remain available, and drill-down still works.
449449

450450
```python
451451
st_pivot_table(
@@ -471,7 +471,11 @@ When `interactive=True`, hovering over the top-right of the toolbar reveals util
471471
| **Export Data** | Open the export popover (CSV / TSV / Clipboard). Use `export_filename` to customize the download filename. |
472472
| **Settings** (gear icon) | Opens a popover with display toggles: Row Totals, Column Totals, Subtotals, Repeat Labels, Sticky Headers, and Expand/Collapse All group controls |
473473

474-
In **locked mode**, Reset, Swap, and config import/export are hidden while data export remains available. The Settings gear remains visible, its popover shows read-only view status plus group expand/collapse actions, and sorting/filtering/show-values-as remain available via header menus.
474+
In **locked mode**, Reset, Swap, and config import/export are hidden. `Export Data` remains available as a viewer action. The Settings gear remains visible, its popover shows read-only display status plus group expand/collapse actions, and header-menu sorting, filtering, and `Show Values As` stay enabled.
475+
476+
### Non-Interactive Mode
477+
478+
Set `interactive=False` to render a read-only pivot view. This hides the toolbar and disables header-menu config actions (sorting, filtering, and `Show Values As`). Cell clicks and drill-down remain available.
475479

476480
---
477481

@@ -520,7 +524,7 @@ For total cells, `rowKey` or `colKey` will be `["Total"]` and the corresponding
520524

521525
### Config State
522526

523-
The returned `config` dict contains the full current configuration including any changes the user made via the toolbar. Use this to persist user customizations or synchronize multiple components.
527+
The returned `config` dict contains the current supported configuration state, including interactive changes such as rows, columns, values, aggregation, totals, sorting, filtering, and display options. Use this to persist user customizations or synchronize multiple components.
524528

525529
---
526530

e2e_playwright/pivot_table_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ def test_subtotal_group_collapse(page_at_app: Page):
740740
rows_before = container.get_by_test_id("pivot-data-row").count()
741741

742742
toggle = container.locator(
743-
"button[data-testid^='pivot-group-toggle-']"
743+
"[data-testid^='pivot-group-toggle-']"
744744
":not([data-testid$='-expand-all'])"
745745
":not([data-testid$='-collapse-all'])"
746746
).first

streamlit_app.py

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
**Try it:**
5353
- Use the **Rows / Columns / Values** dropdowns in the toolbar to add or remove fields.
5454
- Change the **Aggregation** (e.g. Sum → Average) in the toolbar.
55+
- Omit `rows`, `columns`, and `values` entirely to let the component auto-detect dimensions and measures.
5556
- Click any data cell — the cell coordinates will appear below the table.
5657
- Hover over the top-right of the toolbar to reveal the **utility menu**:
5758
- **Reset** (↺) — resets the config to the original Python-supplied values
@@ -96,8 +97,22 @@
9697
language="python",
9798
)
9899

99-
if result_basic.get("cell_click"):
100-
st.info(f"Last cell click: {result_basic['cell_click']}")
100+
basic_cell_click = st.session_state.get("basic", {}).get("cell_click")
101+
if basic_cell_click:
102+
st.info(f"Last cell click: {basic_cell_click}")
103+
104+
st.markdown("#### Auto-Detect Layout")
105+
st.markdown(
106+
"""
107+
If you omit `rows`, `columns`, and `values`, the component auto-detects dimensions
108+
and measures from the input data. This is useful for quick exploration when you
109+
want a sensible starting layout without pre-configuring the pivot.
110+
"""
111+
)
112+
st_pivot_table(
113+
df,
114+
key="basic_auto_detect",
115+
)
101116

102117

103118
# ---------------------------------------------------------------------------
@@ -156,10 +171,10 @@
156171

157172

158173
# ---------------------------------------------------------------------------
159-
# Section 3: Filtering and Locked Mode
174+
# Section 3: Filtering, Locked Mode, and Non-Interactive Mode
160175
# ---------------------------------------------------------------------------
161176
st.divider()
162-
st.subheader("3. Filtering and Locked Mode")
177+
st.subheader("3. Filtering, Locked Mode, and Non-Interactive Mode")
163178

164179
st.markdown(
165180
"""
@@ -169,20 +184,27 @@
169184
menus still work, **Show Values As** remains available on value headers, and
170185
export still stays available as a viewer action. **Custom sorters** enforce a specific dimension order.
171186
187+
**Non-interactive mode** (`interactive=False`) is the true read-only mode:
188+
the toolbar is hidden, header-menu config actions are disabled, but cell clicks
189+
and drill-down still work.
190+
172191
**Try it (left table):**
173192
- Click the **⋮** menu icon on the "Region" header → uncheck regions to filter them out.
174193
- Use the search box to find specific values quickly.
175194
176-
**Right table** is **locked** — authoring actions like reset, swap, and config import/export
195+
**Middle table** is **locked** — authoring actions like reset, swap, and config import/export
177196
are hidden, but **Export Data** remains available, the **Settings** gear shows
178-
read-only view status, and you can still sort, filter, and change **Show Values As**
179-
from the header menus.
197+
read-only view status plus **Expand/Collapse All** group controls, and you can
198+
still sort, filter, and change **Show Values As** from the header menus.
180199
181-
**API parameters used:** `hidden_from_aggregators`, `sorters`, `locked`
200+
**Right table** is **non-interactive** — there is no toolbar and no header-menu
201+
config UI, but cell clicks still work and drill-down remains enabled.
202+
203+
**API parameters used:** `hidden_from_aggregators`, `sorters`, `locked`, `interactive`
182204
"""
183205
)
184206

185-
col_left, col_right = st.columns(2)
207+
col_left, col_middle, col_right = st.columns(3)
186208

187209
with col_left:
188210
st.caption("Interactive (with custom sorters)")
@@ -196,16 +218,29 @@
196218
null_handling="zero",
197219
)
198220

199-
with col_right:
221+
with col_middle:
200222
st.caption("Locked mode")
201223
st_pivot_table(
202224
df,
203225
key="locked",
204-
rows=["Region"],
226+
rows=["Region", "Category"],
205227
columns=["Year"],
206-
values=["Revenue"],
228+
values=["Revenue", "Profit"],
207229
locked=True,
208230
hidden_from_aggregators=["Year", "Region"],
231+
show_subtotals=True,
232+
)
233+
234+
with col_right:
235+
st.caption("Non-interactive mode")
236+
result_noninteractive = st_pivot_table(
237+
df,
238+
key="noninteractive",
239+
rows=["Region"],
240+
columns=["Year"],
241+
values=["Revenue"],
242+
interactive=False,
243+
on_cell_click=lambda: None,
209244
)
210245

211246
with st.expander("View Code"):
@@ -226,16 +261,32 @@
226261
st_pivot_table(
227262
df,
228263
key="locked",
229-
rows=["Region"],
264+
rows=["Region", "Category"],
230265
columns=["Year"],
231-
values=["Revenue"],
266+
values=["Revenue", "Profit"],
232267
locked=True,
233268
hidden_from_aggregators=["Year", "Region"],
269+
show_subtotals=True,
270+
)
271+
272+
# Non-interactive — no toolbar or header-menu config actions
273+
st_pivot_table(
274+
df,
275+
key="noninteractive",
276+
rows=["Region"],
277+
columns=["Year"],
278+
values=["Revenue"],
279+
interactive=False,
280+
on_cell_click=lambda: None,
234281
)
235282
""",
236283
language="python",
237284
)
238285

286+
noninteractive_cell_click = st.session_state.get("noninteractive", {}).get("cell_click")
287+
if noninteractive_cell_click:
288+
st.info(f"Non-interactive cell click: {noninteractive_cell_click}")
289+
239290

240291
# ---------------------------------------------------------------------------
241292
# Section 4: Subtotals and Grouping
@@ -778,6 +829,8 @@
778829
- Use ``export_filename`` to customize the downloaded file name. The date
779830
(``YYYY-MM-DD``) and file extension are appended automatically.
780831
Defaults to ``"pivot-table"`` (e.g. ``pivot-table_2026-03-09.csv``).
832+
- This demo sets `export_filename="sales-export-demo"` so you can see the custom
833+
filename behavior in the downloaded file.
781834
"""
782835
)
783836

@@ -791,6 +844,7 @@
791844
number_format={"Revenue": "$,.0f", "Profit": "$,.0f"},
792845
show_totals=True,
793846
interactive=True,
847+
export_filename="sales-export-demo",
794848
)
795849

796850
with st.expander("View Code"):
@@ -804,6 +858,7 @@
804858
values=["Revenue", "Profit"],
805859
number_format={"Revenue": "$,.0f", "Profit": "$,.0f"},
806860
show_totals=True,
861+
export_filename="sales-export-demo",
807862
)
808863
# Then use the Download icon in the toolbar utility menu.
809864
""",

0 commit comments

Comments
 (0)