diff --git a/content/docs/learn/playground/filter-by-value.mdx b/content/docs/learn/playground/filter-by-value.mdx new file mode 100644 index 0000000..291e664 --- /dev/null +++ b/content/docs/learn/playground/filter-by-value.mdx @@ -0,0 +1,142 @@ +--- +title: "Filter a range by value (daily-driver slice)" +description: "Data ▸ Create a filter (or a header's funnel button) opens a panel listing the selected range's columns; unchecking a value for a column hides every row whose raw value in that column is unchecked, and re-checking it (or removing the filter) restores those rows. The header row is never hidden. Two columns' criteria on the SAME filter combine as AND. Creating a filter, changing its criteria, and removing it are each one undoable command." +--- + +{/* GENERATED — do not edit by hand */} + +## What it does + +**Data ▸ Create a filter** opens a panel over the currently-selected range: one tab per column, and — for whichever column is selected — a checkbox list of every distinct value in it. Unchecking a value hides every row whose value in that column matches; checking it back (or clicking **Remove filter**) restores those rows. The range's own first row is the filter's header and is never hidden. + +Two things worth knowing: + +1. **A filtered-out row takes up no space at all** — it isn't dimmed or struck through, it collapses to zero height, exactly like the rows above and below it closed the gap. Row numbers keep their ORIGINAL value (so hiding row 3 shows `1, 2, 4, 5`, not a renumbered `1, 2, 3, 4`) — the header is a reference/formula anchor, and renumbering would misrepresent which sheet row it addresses. +2. **Two columns on the same filter combine as AND.** Narrowing column A and column B both apply — a row has to pass both to stay visible. + +Creating a filter, narrowing a column's criteria, and removing the filter are each **one undoable command**, so a single Ctrl+Z reverses whichever of those you just did. + +A cell counted as **blank** (nothing typed into it) is its own distinct entry in the checklist, labeled `(Blanks)`, separate from any typed value. + +## Try it + + + +## What this slice deliberately does not do + +The live oracle session that would have verified this feature's actual hide/show mechanics against Google Sheets failed on browser tooling before it could drive anything past the filter's creation chrome (see the oracle brief's "Session method (transparency)" section for the full account) — so everything below the creation chrome is a **Studio decision**, built to be the least-invented reading of a checkbox-value filter, not a claim of Sheets parity: + +- **The panel's exact contents and layout were never seen.** Sheets' own dropdown, its "Select all"/search box, and its exact hide-affordance were never driven live. Studio's docked, tabbed panel is its own design, not a reproduction. +- **No click-to-unhide affordance on the row-header gutter.** Sheets is believed to show a small expand control between two header numbers that straddle a hidden run; this was never observed, so it isn't built. Re-opening the panel and re-checking a value is the only way to unhide here. +- **No filter-by-condition, no filter views, no slicers.** Full parity stays out of scope; this slice is value-only, one filter per sheet. +- **Multi-column AND-stacking is inferred, not observed.** Oracle observation 13 shows one filter puts a dropdown in every covered column's header (one filter, several columns) — that several-column shape is real; that unrelated columns' criteria combine as AND is the standard reading of that shape, not something the live session actually exercised. + +Every one of these is called out, with the reasoning, in the oracle brief's "Studio decisions (not Sheets-observed)" section — a future session with working browser tooling should revisit each. + +## Verified behavior + +_Matches Google Sheets:_ Google Sheets' Data ▸ Create a filter is a single menu item (no submenu) that, over a selected range, changes the sheet's chrome without touching any data: a funnel-glyph dropdown button appears in each cell of the range's first row, that row renders bold, the column headers it covers are tinted green, a green outline is drawn around the range, and the toolbar's filter icon becomes active — live-verified, with nothing hidden yet (all rows stay visible). That is the full extent of what this session could verify live: a fresh attempt to drive the filter's actual value-hiding behaviour (what the dropdown lists, what unchecking a value does, how hidden rows affect row-header numbering, whether it survives reload, whether undo is one step, whether two columns' criteria stack) failed on browser tooling six separate times over roughly 45 minutes, not on Sheets itself — see the oracle brief's "Session method (transparency)" section for the full account. Everything this slice ships beyond the verified creation chrome is therefore a documented STUDIO DECISION (the oracle's "Studio decisions (not Sheets-observed)" section), not a fresh Sheets citation: the mechanically obvious, lowest-invention reading of a checkbox-list value filter (hide a row iff its checked-value set excludes that row's value in the column), built to be corrected by a future session with working tooling rather than left unshipped a second time. + +#### Data ▸ Create a filter opens the panel with nothing hidden yet + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A3** = `alpha` +- **A4** = `delta` + +**When** I select **A1:A4**, then click menu item **data.createFilter** + +**Then** +- `[data-testid="filter-panel"]` is visible + +#### Unchecking a value hides every row holding it; the header row never hides + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A3** = `alpha` +- **A4** = `delta` + +**When** I select **A1:A4**, then click menu item **data.createFilter**, then click **filter-panel-value-delta**, then click **filter-panel-done** + +**Then** +- row **2** is exactly 0px tall +- row **4** is exactly 0px tall + +#### Re-checking a value before Done leaves it visible + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A3** = `alpha` + +**When** I select **A1:A3**, then click menu item **data.createFilter**, then click **filter-panel-value-delta**, then click **filter-panel-value-delta**, then click **filter-panel-done** + +**Then** + +#### A blank cell can be filtered out via the (Blanks) entry + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A4** = `alpha` + +**When** I select **A1:A4**, then click menu item **data.createFilter**, then click **filter-panel-value-blank**, then click **filter-panel-done** + +**Then** +- row **3** is exactly 0px tall + +#### Two columns' criteria on the same filter stack as AND + +**Given** +- **A1** = `Name` +- **B1** = `Dept` +- **A2** = `delta` +- **B2** = `eng` +- **A3** = `alpha` +- **B3** = `sales` +- **A4** = `delta` +- **B4** = `sales` + +**When** I select **A1:B4**, then click menu item **data.createFilter**, then click **filter-panel-column-1**, then click **filter-panel-value-sales**, then click **filter-panel-done** + +**Then** +- row **3** is exactly 0px tall +- row **4** is exactly 0px tall + +#### The panel's own Remove filter button removes it and restores every row + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A3** = `alpha` + +**When** I select **A1:A3**, then click menu item **data.createFilter**, then click **filter-panel-remove** + +**Then** +- `[data-testid="filter-panel"]` is hidden + +#### ONE undo after narrowing a filter restores every row + +**Given** +- **A1** = `Name` +- **A2** = `delta` +- **A3** = `alpha` + +**When** I select **A1:A3**, then click menu item **data.createFilter**, then click **filter-panel-value-delta**, then click **filter-panel-done**, then click **A1**, then undo + +**Then** + +#### Creating a filter refuses a single-row selection — nothing to filter + +**Given** +- **A1** = `Name` +- **B1** = `Dept` + +**When** I select **A1:B1**, then click menu item **data.createFilter** + +**Then** +- **A1** shows `Name` +- **B1** shows `Dept` +- `[data-testid="filter-panel"]` is hidden diff --git a/content/docs/learn/playground/meta.json b/content/docs/learn/playground/meta.json index 0eaf70c..7055f6a 100644 --- a/content/docs/learn/playground/meta.json +++ b/content/docs/learn/playground/meta.json @@ -55,6 +55,7 @@ "sort-range", "structure-insert-delete", "views", - "chart-axis-labels" + "chart-axis-labels", + "filter-by-value" ] } diff --git a/content/docs/learn/playground/navigate-range-select.mdx b/content/docs/learn/playground/navigate-range-select.mdx index 1607861..28aebf2 100644 --- a/content/docs/learn/playground/navigate-range-select.mdx +++ b/content/docs/learn/playground/navigate-range-select.mdx @@ -52,7 +52,7 @@ _Matches Google Sheets:_ In Google Sheets, clicking a cell selects it alone; shi **Then** - the active cell is **B2** -#### Tab moves the active cell one column right +#### Tab moves the active cell one column right without extending the selection **Given** @@ -60,8 +60,10 @@ _Matches Google Sheets:_ In Google Sheets, clicking a cell selects it alone; shi **Then** - the active cell is **B1** +- the selection is just **B1** — it did not extend +- keyboard focus is on the **grid** -#### Shift+Tab moves the active cell one column left +#### Shift+Tab moves the active cell one column left without extending the selection **Given** @@ -69,8 +71,10 @@ _Matches Google Sheets:_ In Google Sheets, clicking a cell selects it alone; shi **Then** - the active cell is **B1** +- the selection is just **B1** — it did not extend +- keyboard focus is on the **grid** -#### Tab from an open editor commits the edit and moves one column right +#### Tab from an open editor commits the edit, moves one column right, and keeps focus on the grid **Given** @@ -79,8 +83,10 @@ _Matches Google Sheets:_ In Google Sheets, clicking a cell selects it alone; shi **Then** - **B2** shows `9` - the active cell is **C2** +- the selection is just **C2** — it did not extend +- keyboard focus is on the **grid** -#### Shift+Tab from an open editor commits the edit and moves one column left +#### Shift+Tab from an open editor commits the edit, moves one column left, and keeps focus on the grid **Given** @@ -89,6 +95,8 @@ _Matches Google Sheets:_ In Google Sheets, clicking a cell selects it alone; shi **Then** - **C2** shows `9` - the active cell is **B2** +- the selection is just **B2** — it did not extend +- keyboard focus is on the **grid** #### Committing an edit with Enter moves the active cell down diff --git a/content/docs/learn/playground/sort-range.mdx b/content/docs/learn/playground/sort-range.mdx index 4bfcb2c..f6f7840 100644 --- a/content/docs/learn/playground/sort-range.mdx +++ b/content/docs/learn/playground/sort-range.mdx @@ -33,7 +33,7 @@ Sorting is destructive, so anything the live oracle session did not actually dem - **No ordering is claimed within the boolean group or within the error group**, and no tie-break between two equal keys: the sort is _stable_, so equal keys keep their original relative order. - **A range overlapping a merged cell, or a spilled dynamic array, is refused** rather than sorted. Neither was ever put inside a sorted range in the oracle session, and both have a concrete way to lose data if guessed at: permuting content under a merge hides it (the merge stays put, so whatever lands in a covered cell vanishes from the grid while still sitting in the model), and moving a spill anchor re-spills from a new origin, hard-materialises the echoes it left behind, and cannot be undone in one step. The menu row is a no-op on such a selection; the API command throws with the reason. - **A relative reference with nowhere to go becomes `#REF!`.** `=A1` moving up out of row 1 has no cell to point at. Sort hands the text to the same `adjustFormula` translate that fill and copy/paste already use, so it behaves identically to them — but Sheets was never asked what _it_ does, so this is recorded as unobserved rather than claimed as parity. -- **No filter.** `Data ▸ Create a filter` stays "coming soon". The oracle captured a filter's creation chrome (green column headers, per-header dropdown buttons, a bold header row) but none of the behaviour that matters — what the dropdown contains, how hidden rows renumber, whether it survives reload, whether undo removes it in one step — and Studio has no row-hiding mechanism at all today. It is filed separately; the wider parity scope stays open. +- **Filter by value is a separate manifest.** `Data ▸ Create a filter` now ships alongside sort in this same daily-driver slice — see the `filter-by-value` manifest for its own scope and ground truth. Every one of these is recorded, with the reason, in the oracle brief's **"NOT OBSERVED — do not guess these"** section. @@ -280,12 +280,3 @@ _Matches Google Sheets:_ Google Sheets' Data ▸ Sort range is a submenu offerin - **A1** shows `delta` - **A2** shows `alpha` - **B2** shows `keep-me` - -#### Data ▸ Create a filter is still disabled — this slice ships sort only - -**Given** - -**When** I click menu item **data.createFilter** - -**Then** -- `[data-menu-item="data.createFilter"]` is visible