feat(table): column visibility dropdown in table top bar#9865
Merged
Conversation
Hidden columns could previously only be restored through the column explorer panel, which the VS Code embedding omits, leaving no way to unhide a column there. This adds a searchable dropdown that lists all user columns with per-column show/hide toggles and a "Show all" action. The list is driven by the shared useSelectList core with selection modeling the hidden set: pinSelected floats hidden columns to the top in an order frozen while the menu is open, so toggling a row does not reorder the list under the cursor; reopening re-sorts. Select, index, and nameless columns are excluded, and non-hideable columns render disabled without a toggle. The component is not yet rendered anywhere; wiring into the table top bar lands separately.
Render the column visibility dropdown in the table top bar so hidden columns can be managed without the column explorer panel, which the VS Code embedding does not have. TableTopBar becomes generic over the row type to accept the TanStack table instance the dropdown reads. Since the dropdown is always available, the bar no longer bails out when search, chart builder, explorer, and export are all disabled: minimal tables now always show the top bar.
The "(n hidden)" suffix in the table bottom bar opened the column explorer panel, which does not exist in the VS Code embedding. Hidden columns are now managed by the Columns dropdown in the top bar, so the suffix becomes a plain informational label and TableBottomBar no longer needs the togglePanel prop.
Highlight the eye-off icon with the primary color so hidden columns stand out. Prevent the trigger from stealing focus on mouse-down: focus leaving the search input fired Radix focus-outside dismiss before the trigger click toggled the popover back open, so clicking "Columns" while open flickered closed-then-open instead of closing.
While searching, the dropdown offers "Hide N matching" / "Show N matching" rows built from the select-core bulk actions, so a prefix query like "shipping" can toggle a whole column group at once.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
No issues found across 6 files
Architecture diagram
sequenceDiagram
participant DataTable as DataTableInternal
participant TopBar as TableTopBar
participant Dropdown as ColumnVisibilityDropdown
participant SelectCore as useSelectList
participant TableRoot as TanStack Table
participant BottomBar as TableBottomBar
Note over DataTable,BottomBar: PR introduces column visibility dropdown in top bar
DataTable->>TopBar: renders with { table, ...otherProps }
TopBar->>Dropdown: renders <ColumnVisibilityDropdown table={table} />
Note over Dropdown: NEW: always rendered (top bar no longer returns null)
User->>Dropdown: clicks "Columns" button
Dropdown->>SelectCore: useSelectList({ options, value, multiple, pinSelected, filterFn: smartMatchFilter })
Note over SelectCore: options built from user columns (excludes select/index/nameless)
SelectCore-->>Dropdown: list API (visibleOptions, searchQuery, toggle, isChecked, bulkActions)
Dropdown->>TableRoot: read column visibility state (getIsVisible, getCanHide)
TableRoot-->>Dropdown: column visibilities
Dropdown->>Dropdown: builds hiddenIds set
Note over Dropdown: pinSelected floats hidden columns to top and freezes order while open
alt User clicks column toggle
User->>Dropdown: clicks column item
Dropdown->>SelectCore: list.toggle(columnId)
SelectCore->>TableRoot: applyHidden(newSet)
TableRoot-->>Dropdown: column visibility updated
else User searches
User->>Dropdown: types in search input
Dropdown->>SelectCore: list.setSearchQuery(query)
SelectCore->>SelectCore: filters via smartMatchFilter
SelectCore-->>Dropdown: matching bulk actions (select-matching / deselect-matching)
alt User clicks bulk action
User->>Dropdown: clicks "Hide N matching" or "Show N matching"
Dropdown->>SelectCore: action.run()
SelectCore->>TableRoot: applyHidden(updatedSet)
else No matches
Dropdown-->>User: "No results."
end
else User clicks "Show all"
User->>Dropdown: clicks "Show all"
Dropdown->>SelectCore: applyHidden([])
SelectCore-->>TableRoot: shows all columns
end
Note over BottomBar: CHANGED: "(n hidden)" now renders as inert text
DataTable->>BottomBar: renders without togglePanel prop
BottomBar->>BottomBar: renders hiddenSuffix as plain <span> instead of clickable <button>
Note over Dropdown: Reopen re-sorts according to current pinned state
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a first-class column visibility recovery affordance to the data table UI (especially important for the VS Code embed, where the column explorer panel is not available), by introducing a searchable “Columns” dropdown in the top bar and making the bottom-bar hidden-count suffix non-interactive.
Changes:
- Add
ColumnVisibilityDropdownto the table top bar to show/hide columns (including smartMatch search + bulk hide/show matching + “Show all”). - Remove the clickable “(n hidden)” bottom-bar button behavior and drop
togglePanelfromTableBottomBar’s API. - Add comprehensive tests for the new dropdown and update bottom-bar tests accordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/components/data-table/TableTopBar.tsx | Always renders the top bar and adds the new column visibility dropdown (requires table prop). |
| frontend/src/components/data-table/TableBottomBar.tsx | Makes “(n hidden)” inert text and removes the togglePanel prop dependency. |
| frontend/src/components/data-table/data-table.tsx | Wires table into TableTopBar and removes togglePanel from TableBottomBar usage. |
| frontend/src/components/data-table/column-visibility-dropdown.tsx | Implements the searchable column visibility dropdown using useSelectList with pinned/frozen ordering. |
| frontend/src/components/data-table/tests/TableBottomBar.test.tsx | Updates expectations to verify hidden suffix is rendered as inert text. |
| frontend/src/components/data-table/tests/column-visibility-dropdown.test.tsx | Adds coverage for filtering/exclusions, ordering/freeze behavior, bulk actions, show-all, and non-hideable columns. |
mscolnick
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Hidden table columns could only be restored through the column explorer panel. The VS Code embedding omits that panel, so once a column was hidden there it could not be brought back from the table UI. The "(n hidden)" button in the bottom bar also opened that panel, making it a dead end in VS Code.
Solution
Adds a searchable "Columns" dropdown to the table top bar:
The list is driven by the shared
useSelectListcore fromui/select-core, with selection modeling the hidden set:pinSelectedprovides the hidden-first frozen ordering andselect-matching/deselect-matchingprovide the bulk actions. Search usessmartMatch, consistent with the column explorer.The "(n hidden)" suffix in the bottom bar becomes plain text since the dropdown replaces it as the recovery affordance, and
TableBottomBarno longer takestogglePanel.Behavior note
TableTopBarpreviously returnednullwhen search, chart builder, table explorer, and export were all disabled. The dropdown is always available, so that gate is removed: minimal tables now always render the top bar.Testing
column-visibility-dropdown.test.tsx(11 tests): column filtering/exclusion, hidden-first ordering, frozen order while open + re-sort on reopen, smartMatch search, "Show all", bulk hide/show matching, non-hideable columns.TableBottomBar.test.tsx: "(n hidden)" renders as inert text.src/components/data-table/suite passes;make fe-checkclean.Screen.Recording.2026-06-11.at.12.43.16.PM.mov
Closes MO-6448
Closes #9419