Skip to content

forms(qml): CollectionView and WizardView chrome through SlotRegistry.byChrome, and the registry reaches the forms they embed (fixes #813) - #819

Merged
Yaraslaut merged 1 commit into
feature/forms-chrome-slotsfrom
feature/forms-view-chrome
Sep 25, 2026
Merged

Yaraslaut merged 1 commit into
feature/forms-chrome-slotsfrom
feature/forms-view-chrome

Conversation

@Yaraslaut

Copy link
Copy Markdown
Member

Fixes #813. ⚠️ Stacked on #810 (base feature/forms-chrome-slots, which adds byChrome). Retarget to master once #810 merges.

The views hard-coded their chrome and never passed a slotRegistry to the DynamicForms they embed, so a host's field slots and form chrome stopped at the view's edge.

View Role Members
CollectionView collectionHeader title, columns, actions, fire(action)
collectionRow row, columns, cells, rowKey, actions, canOpen, open(), fire(action)
confirmDialog message, action, row, accept(), reject() (loaded only while an action waits)
editorDialog title, open, close(), contentItem (editor form reparented into it)
WizardView wizardHeader title, stepIndex, stepCount, stepTitle
wizardNav canBack, canNext, lastStep, back(), next() (same ok-reply gate)

Tests (MSVC 14.51, Qt 6.11.1): new tst_ViewChrome.qml (9 cases incl. a fully chromed collection with the editor open and no visible built-in Label/Button). Dropping the registry hand-off and the row swap reddens 3. forms_qml_logic 341 passed.

🤖 Generated with Claude Code

….byChrome, and the registry reaches the forms they embed (fixes #813)

#810 made DynamicForm's chrome replaceable. The two composing views still
hard-coded theirs -- title, column headers, row cells, Open / row-action /
collection-action buttons, the "Are you sure?" and editor Dialogs, Back / Next
and the step counter -- and, more to the point, never gave the DynamicForms
they embed a slotRegistry at all: a host's field slots and form chrome stopped
at the view's edge, so even a fully registered kit drew built-in editors.

  - `slotRegistry` on both views, handed to modalForm / detailForm and to every
    wizard step.
  - CollectionView roles: collectionHeader (title, columns, actions, fire),
    collectionRow (row, columns, cells, rowKey, actions, canOpen, open, fire),
    confirmDialog (message, action, row, accept, reject -- loaded only while an
    action waits) and editorDialog (title, open, close, and a contentItem the
    editor form is reparented into).
  - WizardView roles: wizardHeader (title, stepIndex, stepCount, stepTitle)
    and wizardNav (canBack, canNext, lastStep, back, next). next() keeps the
    built-in gate: the step's action must have replied ok.
  - DateTimePicker gets no chrome: a host replaces the whole picker with a
    field slot, byKind("datetime") from #816.

Nothing registered, nothing changes: tst_collectionview.qml and
tst_wizardview.qml are untouched and green. tst_ViewChrome.qml (9 cases) pins
each role, the embedded forms receiving the registry, and a fully chromed
collection screen with the editor open showing no visible built-in Label or
Button. Dropping the registry hand-off and the row-chrome swap reddens 3 of
them. forms_qml_logic: 341 passed on MSVC 14.51 / Qt 6.11.1.

Stacked on #810 (byChrome / resolveChrome).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Yaraslaut
Yaraslaut merged commit e34375a into feature/forms-chrome-slots Sep 25, 2026
59 of 60 checks passed
Yaraslaut added a commit that referenced this pull request Sep 25, 2026
….byChrome, and the registry reaches the forms they embed (fixes #813) (#819)

hard-coded theirs -- title, column headers, row cells, Open / row-action /
collection-action buttons, the "Are you sure?" and editor Dialogs, Back / Next
and the step counter -- and, more to the point, never gave the DynamicForms
they embed a slotRegistry at all: a host's field slots and form chrome stopped
at the view's edge, so even a fully registered kit drew built-in editors.

  - `slotRegistry` on both views, handed to modalForm / detailForm and to every
    wizard step.
  - CollectionView roles: collectionHeader (title, columns, actions, fire),
    collectionRow (row, columns, cells, rowKey, actions, canOpen, open, fire),
    confirmDialog (message, action, row, accept, reject -- loaded only while an
    action waits) and editorDialog (title, open, close, and a contentItem the
    editor form is reparented into).
  - WizardView roles: wizardHeader (title, stepIndex, stepCount, stepTitle)
    and wizardNav (canBack, canNext, lastStep, back, next). next() keeps the
    built-in gate: the step's action must have replied ok.
  - DateTimePicker gets no chrome: a host replaces the whole picker with a
    field slot, byKind("datetime") from #816.

Nothing registered, nothing changes: tst_collectionview.qml and
tst_wizardview.qml are untouched and green. tst_ViewChrome.qml (9 cases) pins
each role, the embedded forms receiving the registry, and a fully chromed
collection screen with the editor open showing no visible built-in Label or
Button. Dropping the registry hand-off and the row-chrome swap reddens 3 of
them. forms_qml_logic: 341 passed on MSVC 14.51 / Qt 6.11.1.

Stacked on #810 (byChrome / resolveChrome).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yaraslaut added a commit that referenced this pull request Sep 25, 2026
….byChrome, and the registry reaches the forms they embed (fixes #813) (#819)

hard-coded theirs -- title, column headers, row cells, Open / row-action /
collection-action buttons, the "Are you sure?" and editor Dialogs, Back / Next
and the step counter -- and, more to the point, never gave the DynamicForms
they embed a slotRegistry at all: a host's field slots and form chrome stopped
at the view's edge, so even a fully registered kit drew built-in editors.

  - `slotRegistry` on both views, handed to modalForm / detailForm and to every
    wizard step.
  - CollectionView roles: collectionHeader (title, columns, actions, fire),
    collectionRow (row, columns, cells, rowKey, actions, canOpen, open, fire),
    confirmDialog (message, action, row, accept, reject -- loaded only while an
    action waits) and editorDialog (title, open, close, and a contentItem the
    editor form is reparented into).
  - WizardView roles: wizardHeader (title, stepIndex, stepCount, stepTitle)
    and wizardNav (canBack, canNext, lastStep, back, next). next() keeps the
    built-in gate: the step's action must have replied ok.
  - DateTimePicker gets no chrome: a host replaces the whole picker with a
    field slot, byKind("datetime") from #816.

Nothing registered, nothing changes: tst_collectionview.qml and
tst_wizardview.qml are untouched and green. tst_ViewChrome.qml (9 cases) pins
each role, the embedded forms receiving the registry, and a fully chromed
collection screen with the editor open showing no visible built-in Label or
Button. Dropping the registry hand-off and the row-chrome swap reddens 3 of
them. forms_qml_logic: 341 passed on MSVC 14.51 / Qt 6.11.1.

Stacked on #810 (byChrome / resolveChrome).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yaraslaut added a commit that referenced this pull request Sep 25, 2026
…tainers and buttons, not only its controls (#810)

* forms(qml): chrome slots -- a host replaces DynamicForm's labels, containers and buttons, not only its controls

SlotRegistry lets a host swap a field's *control*, but everything around the
controls stayed built-in: the bold caption and red `*`, the help line, the
section heading and accordion toggle, the TabBar, the action-type heading, the
status line, the Submit button, the monospace JSON preview and the reply line.
A host whose look comes from one UI kit therefore could not get a form that
looked like the rest of the app, whatever slots it registered.

`SlotRegistry.byChrome(role, component)` / `resolveChrome(role)` register one
Component per role -- fieldLabel, fieldHelp, section, accordion (falls back to
section), tabset, header, status, submitButton, preview, result -- and
DynamicForm loads it in place of the built-in, which is hidden rather than
drawn beside it. Each chrome item is handed only the members it declares
(`bindChrome`), as bindings where the value changes: a label gets `required`
(including requiredWhen) and `invalid` (typed text that does not encode, via
the new `fieldInvalid(name)`); the status line's text moved into
`DynamicForm.statusText` so the built-in and a chrome read one source.

Container chrome (section / accordion / tabset) declares a `contentItem`, and
the form creates its field grid inside it. The built-in grid's Repeater is
emptied under a chrome, so each field exists once and its `field_<name>`
objectName stays unique -- prefill, resetFields() and name-based lookups keep
working. A tabset chrome owns `currentIndex`; the form rebuilds the selected
tab's fields on a switch exactly as the built-in tab bar does. A chrome
submit button goes through `submit()`, so the `ready` guard still holds.

Nothing registered, nothing changes: the existing 317 QML cases are untouched
and green. The new tst_DynamicFormChrome.qml (13 cases) pins each role, and a
form with every role registered showing no visible built-in Label, Button or
TabBar. Restoring the section Repeater under a chrome reddens the
fields-created-once case. forms_qml_logic: 330 passed on MSVC 14.51 / Qt
6.11.1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* forms(qml): CollectionView and WizardView chrome through SlotRegistry.byChrome, and the registry reaches the forms they embed (fixes #813) (#819)

hard-coded theirs -- title, column headers, row cells, Open / row-action /
collection-action buttons, the "Are you sure?" and editor Dialogs, Back / Next
and the step counter -- and, more to the point, never gave the DynamicForms
they embed a slotRegistry at all: a host's field slots and form chrome stopped
at the view's edge, so even a fully registered kit drew built-in editors.

  - `slotRegistry` on both views, handed to modalForm / detailForm and to every
    wizard step.
  - CollectionView roles: collectionHeader (title, columns, actions, fire),
    collectionRow (row, columns, cells, rowKey, actions, canOpen, open, fire),
    confirmDialog (message, action, row, accept, reject -- loaded only while an
    action waits) and editorDialog (title, open, close, and a contentItem the
    editor form is reparented into).
  - WizardView roles: wizardHeader (title, stepIndex, stepCount, stepTitle)
    and wizardNav (canBack, canNext, lastStep, back, next). next() keeps the
    built-in gate: the step's action must have replied ok.
  - DateTimePicker gets no chrome: a host replaces the whole picker with a
    field slot, byKind("datetime") from #816.

Nothing registered, nothing changes: tst_collectionview.qml and
tst_wizardview.qml are untouched and green. tst_ViewChrome.qml (9 cases) pins
each role, the embedded forms receiving the registry, and a fully chromed
collection screen with the editor open showing no visible built-in Label or
Button. Dropping the registry hand-off and the row-chrome swap reddens 3 of
them. forms_qml_logic: 341 passed on MSVC 14.51 / Qt 6.11.1.

Stacked on #810 (byChrome / resolveChrome).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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