Settings/NLDD: what was evaluated and not made, and when it expires #208
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
While putting Settings on NLDD's form system (#201), a set of further changes
was evaluated and deliberately not made. This records what was already tried
and why, so the same proposals do not get re-investigated from scratch.
Every claim below is pinned to a version. The original list was checked
against
@nldd/design-system0.8.70. NLDD changes behaviour inside patchreleases, so a rejection here is only as good as its date - and four of them
had already expired by 0.8.79. Re-verify before treating any of this as
settled.
Last verified against 0.8.79, 2026-08-09.
Done
Landed in #272 (merged):
See "Corrected" below.
nldd-form-field+nldd-password-field, with the decryption failure routed onto it.MattermostServerFields.vueextracted. Only the base-URL and label fields:they are byte-identical between the two forms, while the token field differs
in label, placeholder and its onboarding hint.
nldd-title :sizedrift between the two modals. It was a symptom, not adesign question: both dialogs sat outside the shared shell. Settled by shape
rather than by consistency - the delete confirm carries a form and moved to
Modal.vue; the disconnect confirm is a question with buttons and stays onNLDD's own
nldd-modal-dialog, wrapped asConfirmDialog.vueso itregisters with the overlay stack. Without that registration the single-key
shortcuts stayed live behind it, because its
<dialog>sits in a shadow rootthat
document.querySelectorcannot reach.nldd-segmented-control:nldd-radio-button-group, which the same panel already used for thebrowser/desktop choice. Sync-interval also lost its 10- and 30-minute steps,
so both groups are three options. The retention fields keep dropdowns - more
options, longer labels.
Corrected
Routing 422 to the Token field was wrong. The endpoint answered 422 for
three unrelated causes: Pydantic validation (token shape, and the SSRF guard
on
base_url), an invalid token, and an unreachable server. Pastinghttp://10.0.0.5/chatreported "Token is ongeldig" on a token that was fine,and attaching that to the Token field would have made it worse. #272 splits the
statuses first (unreachable is now 502) and routes on the validation body's
loc.The objection to the original
formErrorMessagestill stands and is why thereplacement returns a target rather than a message: an error with no status
is panel-level, never nothing.
Expired - do not trust these without re-checking
"Clicking an
nldd-form-fieldlabel focuses nothing." Fixed fornldd-text-fieldandnldd-password-field, which now delegate focus. Stilltrue for
nldd-dropdown,nldd-radio-button-groupandnldd-checkbox-field, which implement neitherfocus()nordelegatesFocus. Measured on 0.8.79, with a positive control:"
nldd-form-actionsoutside annldd-formcontributes only a label-columnspacer." Never accurate. The spacer is conditional on
label-alignmentanda container of at least 641px; outside a form it contributes nothing.
"
nldd-checkbox-fieldhas a hard 44px row." It is a token-drivenmin-height(--semantics-controls-md-min-size), overridable, and it growswith a wrapping label.
"
nldd-banneris for persistent, page-level feedback." The doc commentstill says so, but 0.8.78 added
size="sm", documented for "a notice that hasto sit inside a pane or above a toolbar". The rejection for the per-server
warning row is weaker than it was. Not acted on.
Still rejected on mechanism, verified at 0.8.79
nldd-formanywhere. Export, Preferences, Import and the delete dialoghave no submit. It also auto-migrates direct children into an inner
<form>via a
MutationObserver(there is an opt-out: supply your own<form>).--semantics-forms-gap-tightstill exists and still buys the rhythm.nldd-form-section. Still renders its title as a<legend>: a grouplabel that heading navigation skips.
nldd-titlestays the home for panelheadings.
SettingsAlert.vuewould re-implementnldd-banner, which setsrole and
aria-atomicitself. Note the split is critical versus everythingelse, not warning versus critical:
warninggetsrole="status"alongsideneutral, accent and success.
nldd-checkbox-fieldon the diff-table row. Its label is still a plainstring with no slot and no parts, so it would duplicate or destroy the visible
label in the neighbouring
<td>._findInput()still returns the first non-helperchild, so it would treat the
<label>wrapper as the input and put the id,the
aria-labeland thearia-describedbyon it. 0.8.79 still ships nofile-upload component.
nldd-dropdownstill has noinputId, sonldd-form-fieldwritesaria-describedbyonto the role-lesshost and it never reaches the slotted
<select>. This is also why thearia-labelon that<select>is load-bearing.nldd-form-fieldaround AccountDeletePanel's two consent checkboxes.Only the first would be treated as "the input", and a plain
<label>isweaker than the
<fieldset>plus visually-hidden<legend>already there.nldd-switch-fieldfor the browser/desktop-app choice - two nameddestinations, not an on/off state. It is a single boolean
checked.Settled by measurement
nldd-tablefor the diff table. Now evaluated. It fits mechanically -nldd-celltakes arbitrary content, and the design system itself suggests acheckbox column - but the family contains no
<table>,<th scope>or<caption>anywhere: it is a CSS grid withrole="table",role="columnheader"androle="cell". The current markup is a native tablewith real
<th scope="col">, so this would trade semantics for roles.Rejected.
The
<output aria-label="Herstelcode, 44 karakters">in RecoveryKeyModal.Did not need a screen reader after all - Chromium's accessibility tree answers
it:
The label becomes the accessible name; the key stays exposed as a text child.
The feared substitution does not happen. No change.
nldd-pageinsidenldd-windowfor the modal title bar.nldd-window'sown docs say it has no header and point consumers at
nldd-pagewith asticky header, so
Modal.vue's hand-written header looks like a deviation.Tried on 2026-08-09; it costs two things. Measured with a dialog open, the
flattened tree carries two visible main landmarks:
That is the
landmark-one-mainviolationtests/e2e/landmarks.spec.tsguards app-wide. The scroll region also moves into
nldd-page's shadow root,so
Modal.vue'sscroll-padding-blockstops applying and nothing in the appcan reach it -
long-message-thread-scroll.spec.tsfails on exactly that.The guidance is written for a window used as a window, not for a dialog
layered over a route that already has a
<main>. Rejected, with thereasoning in
Modal.vue's docblock.Still open
Nothing. The last item - a retry after a failed Voorkeuren save - is handled in
#275, which gives both auto-saving panels an "Opnieuw proberen" button.
Automatisch opruimen turned out to show no failure at all, which was not in this
list; it gets the same notice there.
Upstream
Reported as MinBZK/storybook#188. Wider than this list had it: on
0.8.79 the label click does nothing for ten components, not three -
dropdown, checkbox, checkbox-field, radio-button, radio-button-field,
radio-button-group, segmented-control, stepper, toggle-button and
toggle-button-group.
_focusInputcalls.focus()on the slotted host, whichonly lands where the component has
delegatesFocusor its ownfocus().The argument that carries it is the asymmetry inside the design system:
nldd-switch-fieldhas afocus()override and works, whilenldd-checkbox-fieldandnldd-radio-button-field- the same kind of control -do not.
Verified in a blank page loading only the package, with real mouse clicks and a
per-component control. Worth knowing for us: the components' own labels do work,
so a user loses only the field-level label click.
Revisit when
The NLDD minor or patch version changes. Everything above is a claim about
component internals, and this list has already been wrong once for exactly that
reason.
frontend/node_modules/@nldd/design-system/dist/components/is thesource of truth; the skill's changelog says what moved.
Settings/NLDD: 22 changes evaluated and deliberately not madeto Settings/NLDD: what was evaluated and not made, and when it expiresClosing: every item is resolved, rejected with a verified reason, or filed elsewhere.
The body stays as the record it was meant to be: what was tried, what was rejected and why, and which four claims had already expired between 0.8.70 and 0.8.79. That last part is the lesson - a rejection is only as good as the version it was measured against, so re-verify before treating any of it as settled.
The reasoning that is expensive to rediscover also sits next to the code: Modal.vue`s docblock carries why nldd-page is not used for the dialog title bar, with the landmark measurement.