Make the settings card behave like the other plugin cards

It rendered as a flat, always-open block with no header. The framework's card
chrome is a disclosure: the tab renders every card into a <ul>, each card's root
is an <li>, its header is its own <button> that discloses the controls in place,
it starts collapsed, the header marks it when it holds unsaved edits, and a save
that lands folds it back up.

Three things were wrong and only one of them was cosmetic:

  * the root was a <div> inside the tab's <ul>, so the list and card styling
    never reached it
  * there was no header button, so no disclosure and no aria-expanded
  * nothing marked unsaved edits, and nothing collapsed after a save

`PluginCard` is not importable — it lives in that package's client bundle, and
the client purity gate forbids cross-plugin value imports — so the behaviour is
reproduced rather than borrowed, with inline styles for the same reason.

The collapse-on-save originally lived in an effect watching a `saving` flag, which
is how the shipped card does it because its form state comes from a controller.
This card awaits its own writes, so it already knows the save landed; collapsing
directly in the success path is simpler and is what the tests can actually reach.
A failed save still keeps the card open with its drafts.

Tests cover the disclosure itself: the root element, collapsed-by-default, the
header's aria-expanded and label, that staged edits survive collapsing, and that
a landed save folds the card up.
This commit is contained in:
dsh-slopo agent committed 2026-09-22 13:26:29 +01:00
1 parent 6b9d91b436
commit 2d7a7d1e73
3 files changed
+209 -88

No files matched your search

+5
View File
@@ -46,6 +46,11 @@ keyed on the `dsh-slopo` settings namespace the Host registers. Every setting in
the table below is editable there, overridden fields are marked, and Reset
returns a field to the deployment default rather than to empty.
The card behaves the way the other plugin cards do: it starts collapsed, its
header is a button that discloses the controls in place, the header marks it when
it holds unsaved edits — visible even while collapsed, since staged edits outlive
being folded away — and a save that lands collapses it again.
The card is the bundle's second half — the browser half. It needs no build step
and ships as plain ESM in the module-loader wrapper, but the platform snapshots
client bundles at activation, so **a client half only appears after the profile