Skip to content

fix(dashboard-library): cards keep their state across a refetch, and filters show the value their $variable holds - #1624

Draft
Aditya-thesys wants to merge 7 commits into
mainfrom
ap/dashboard-library-fixes
Draft

Aditya-thesys wants to merge 7 commits into
mainfrom
ap/dashboard-library-fixes

Conversation

@Aditya-thesys

Copy link
Copy Markdown
Contributor

What

Five fixes to @openuidev/dashboard-library 1.0.0, found by rendering each component's documented behaviour and comparing it with what the description promises, plus four corrections to the prompt text. One commit per fix.

Fixes

Before After
A filter change remounted every card's content. StateFrame rendered a fragment normally and a wrapper <div> while refreshing, so React replaced the children. A table went back to page 1 and lost its sort; a leaderboard's sort, a heatmap's Show switch, a funnel's basis and a map's view all reset on every refetch. The shimmer and loader are siblings of the content in one fragment. The same nodes stay mounted and keep their state.
CompareToggle with options fell back to its first option for any value that was not "off". With the $variable not declared, the button read "Compare: Previous 30 days" while nothing was overlaid. With options, the control shows the variable's own value; anything that is not an option, unset included, is None. defaultOn applies only without options, and the description says so.
Filters with no value fell back to a default of their own. DateRangeFilter showed "Last 30 days" while the Query received null; PeriodPicker, ChipFilter and SelectFilter highlighted their first option the same way. MultiSelectFilter showed "All" for a stored value that was not an option, while that value still filtered. Chips and period show nothing selected, with the first one reachable by Tab. Dropdowns show their label alone. MultiSelectFilter names the stored value. Nothing is written to the variable on mount.
TimeSeries with stacked: "percent" and only lines The axis became 0 to 1 while the lines kept raw values, so they were drawn off the plot. stacked is ignored when every series is a line; the description says so. Area and bar stacking is unchanged.
What None hides (wording only) The description suggested the toggle controls change figures. The description and the previous-values note say what the code does: the toggle controls chart overlays; change figures show whenever previous is given. With data keyed by the choice, an "off" entry keeps figures under None.

Prompt text and two small behaviours

  • The rule about a second FilterBar said it is never drawn; both are drawn. It now says so and still asks for one.
  • Table: totals only does something together with a Column total; the description says that.
  • Table groupBy matches a column's label trimmed and without regard to case.
  • Section renders its description when the title is empty.

Checked

  • Each fix was reproduced with a jsdom probe first and re-run after the change: the remount (same nodes, page and view switches kept, loaders shown during the refetch and gone after), CompareToggle (12 of 12 cases), filters with no value (13 of 25 cases failed before, 25 of 25 pass after), the line chart's y-coordinates (off the plot before, identical to a plain line chart after).
  • Typecheck, lint, prettier and build are clean. 17 example programs parse and render.
  • Not run in a real browser: the refreshing shimmer's CSS selectors changed with the wrapper's removal and should be looked at once on screen.

To know

  • Server-rendered HTML shows filters with nothing selected until hydration, because $variable values are set after mount. Before, it showed each filter's own default, which could differ from the declared value.
  • A series with mark: "line" inside a percent-stacked bar chart is still drawn off the plot, as before.
  • The per-card data-state="refreshing" and aria-busy are gone with the wrapper; the dashboard root keeps aria-busy, and each card's loader keeps its role="status".

🤖 Generated with Claude Code

A card's content was a fragment normally and sat inside a wrapper element
while its data refetched, so React remounted it each time a filter reloaded a
Query: a Table lost its sort and page, a Leaderboard its sort, a Heatmap,
Funnel or GeoMap its view. The refresh shimmer and loader are now siblings of
the content inside one fragment, so the content keeps its place in every
state that shows data. Both still anchor to the card.
…'s value

With options, the button named the first choice whenever the $variable held
anything but "off": undeclared, it read "Compare: Previous 30 days" while the
program's prev[$compare] lookup was empty and nothing was overlaid. The
control now shows the variable's own value, and anything that is not one of
the options, unset included, reads as None. Nothing is written to the variable
on mount.

defaultOn applies to the form without options, as before. With options the
starting choice is the one the program declares ($compare = "prev"), and the
description now says so.
The toggle only shows or hides the previous-period overlays on charts. Change
figures on Kpi, Stat and Leaderboard are drawn whenever previous is given,
whatever the toggle says. With options the program keys its previous data by
the variable, so under None ("off") the lookup was empty and the figures
went away with the overlays. The CompareToggle description and the
previous-values note now state the split, and that data keyed by the choice
needs an "off" entry to keep the figures under None.
…ult of their own

A filter bound to a $variable with no value drew its first option as chosen
(DateRangeFilter its second, "Last 30 days") while the Queries received
nothing. Each control now shows what the variable holds and writes nothing on
mount:

- ChipFilter and PeriodPicker select no option. The first one takes the Tab
  stop whenever none is selected, so the group stays reachable by keyboard;
  before, a value that matched no option left every chip at tabIndex -1.
- SelectFilter and DateRangeFilter show their label alone ("Date range" when
  a DateRangeFilter has none) with nothing ticked in the menu.
- MultiSelectFilter counts stored values that are not among its options: they
  still filter the data, so the button names them instead of reading "All".
… lines

With type "line" and stacked "percent" the axis became 0 to 100% while the
lines kept their raw values, so they were drawn far above the plot. Lines
don't stack, so a chart whose series are all lines now ignores stacked and
draws as a plain line chart. Charts with bars or areas stack as before. The
description says stacked is ignored for "line".
…e and Section

- A rule said only the first FilterBar is drawn. Every FilterBar is drawn, so
  the rule now asks for one and says a second shows as a second bar.
- Table: totals draws a row only when a Column also sets total; the
  description says it takes both.
- Table: groupBy names a column by its label, and now matches it whatever its
  case or outer spaces. "plan" used to miss a column labelled "Plan" and the
  rows were left ungrouped.
- Section: a description was dropped when the title was "". It now shows on
  its own.
@vercel

vercel Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
openui-docs Ready Ready Preview Nov 12, 2026 2:09pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — 8be082fb Deployed Nov 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant