forms(qml): SlotRegistry.byKind -- one host control per kind of control (fixes #812) - #816
Merged
Merged
Conversation
…ol (fixes #812) `byType` keys on the JSON type, which does not name a control: a Quantity and a nested object are both "object", a Choice is "integer", an enum and a Timestamp are "string". A host whose every control comes from its own kit therefore had to register byField per action and field, or byUnit per unit. Every field descriptor now carries `kind` -- the control DynamicForm would draw, decided in the order fieldJsonLiteral picks its encoder: objectArray, array, enum, choice, datetime, date, quantity, integer, boolean, number, object, string. `SlotRegistry.byKind(kind, component)` registers for it, and `resolve()` takes `kind` as an optional sixth argument, consulted after unit and before type, so the five-argument call resolves exactly as before and a field / x-widget / unit registration still wins. tst_SlotRegistryByKind.qml builds one member of every kind in the shape schemaJson<A>() emits, with a byType slot registered for each JSON type in play, and asserts the byKind slot is the one loaded. Removing the tier from resolve() reddens 4 of its 5 cases. forms_qml_logic: 324 passed on MSVC 14.51 / Qt 6.11.1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Yaraslaut
added a commit
that referenced
this pull request
Sep 25, 2026
….byChrome, and the registry reaches the forms they embed (fixes #813) (#819) #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>
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>
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.
Fixes #812.
byTypekeys on the JSON type, which does not name a control (Quantityand nested object are both"object",Choiceis"integer", enum andTimestampare"string"), so a host supplying all controls from its own kit had to register per field.kind, chosen in the orderfieldJsonLiteralpicks its encoder:objectArray,array,enum,choice,datetime,date,quantity,integer,boolean,number,object,string.SlotRegistry.byKind(kind, component);resolve(action, field, xWidget, unitAscii, jsonType, kind)—kindoptional, order field → x-widget → unit → kind → type. Five-argument callers unchanged.docs/spec/forms/forms.md"Theming / component-override registry" (kind table).Tests (MSVC 14.51, Qt 6.11.1): new
tst_SlotRegistryByKind.qml— one member of every kind inschemaJsonshape, with competingbyTypeslots registered; removing the tier reddens 4 of 5 cases.forms_qml_logic324 passed.Touches the same
resolve(...)call as #809 (slotClaims); resolved on the combined branch.🤖 Generated with Claude Code