feat(17-02): repeater field and dependent dropdown states

- RepeaterField: rows with drag handle, index, titleFrom title, error chip,
  move up/down (buttons, ArrowUp/ArrowDown on the handle, native drag and
  drop), expand/collapse, remove (asks only for a row holding a value),
  add with nested defaults, maxItems counter, empty state, collapse all;
  every change edits form state only
- 422 row paths (content.3.answer) open the row, mark it and focus the
  nested control; the banner no longer repeats row messages
- DropdownField dependsOn: waiting, loading, not used, empty, loaded with
  depth indent, failed with retry; cached per sibling value, last request
  wins, a stale value is cleared after a sibling change and announced
- FormView provides form feedback (errors and notices by row path, the
  polite live region, its confirm dialog) and the options cache; FormGrid
  provides the sibling scope for repeater rows
- repeater.* and form.dependent_* phrase keys (en, pl), smoke specs, docs
This commit is contained in:
2026-10-12 16:08:23 +02:00
parent 4a5e896429
commit d3bf5d8f86
17 changed files with 1432 additions and 60 deletions

View File

@@ -68,6 +68,12 @@ export type FieldTypeAssets = Schemas['cabana.FieldTypeAssets']
export type FieldUploadResponse = Schemas['cabana.FieldUploadResponse']
/** One save notice of a plugin field type: field, content locale and message. */
export type FieldNotice = Schemas['cabana.FieldNotice']
/** A dependent dropdown's options for one sibling value (D-08): applies false takes no value. */
export type AdminDependentOptionsResult = Schemas['cabana.AdminDependentOptionsResult']
/** One dependent option; depth indents a choice taken from a tree. */
export type AdminDependentOption = Schemas['cabana.AdminDependentOption']
/** A repeater's row form: the nested fields of one row (D-07). */
export type RepeaterForm = Schemas['cabana.RepeaterForm']
/** A registered toolbar action the admin may run, with its localized label. */
export type ToolbarAction = Schemas['cabana.ToolbarAction']
/** One node of a rendered partial: an allowlisted element or a text node. */