Skip to content

Feature: Tabs 9.1 (ID-frei, modern/vertikal) + Form Builder + Repeater-Demos - #424

Merged
skerbis merged 13 commits into
mainfrom
feature/tabs-9.1.0-demos
May 21, 2026
Merged

Feature: Tabs 9.1 (ID-frei, modern/vertikal) + Form Builder + Repeater-Demos#424
skerbis merged 13 commits into
mainfrom
feature/tabs-9.1.0-demos

Conversation

@skerbis

@skerbis skerbis commented May 21, 2026

Copy link
Copy Markdown
Member

Zusammenfassung

Dieses PR bringt die 9.1-Tab-Erweiterungen inklusive Demos und Form-Builder-Support:

  • ID-freie Tab-Logik in verschachtelten Kontexten
  • optionale Tab-Features: tab-icon, tab-style=modern, tab-layout=vertical
  • Form Builder um Tab-Optionen erweitert
  • zwei neue Demo-Module für die neuen Features
  • Repeater-Tab-Fix inkl. verschachtelter Tab-Navigation
  • Doku aktualisiert (What's New, Repeater, API)

Enthaltene Änderungen

  • Tab-Rendering/Handling (PHP + JS) auf wrapper-gescopte, ID-freie Steuerung
  • Dark-Mode-kompatible Styles für moderne/vertikale Tabs
  • Form Builder Properties/Code-Emission für Tab-Icon, Style, Layout
  • Neue Demos:
    • wrapper/tabs_modern_vertical
    • repeater/tabs_repeater_tabs (inkl. TinyMCE-Profil full im Block-Text)
  • Repeater-Fix: Klicks in verschachtelten Tabs steuern nur den lokalen Tab-Container
  • Repeater-Renderer: Auto-Grouping für addTabElement()-Tabs im Repeater, falls keine explizite Tab-Gruppe definiert ist
  • Dokumentation aktualisiert

Tests

  • node --check assets/js/formbuilder.js
  • node --check assets/mform.js
  • node --check assets/repeater.js
  • rexstan:analyze redaxo/src/addons/mform -> OK

Hinweise

  • main wurde zuvor per Revert bereinigt; diese Änderungen liegen bewusst nur auf der Feature-Branch.

Summary by CodeRabbit

  • New Features

    • Tab-Optionen: modern-Stil, vertikales Layout mit Mobile-Fallback, Tab-Icons und ID-freies Tab-Rendering
    • Visual Form Builder: neue Tab-Eigenschaften, ColorSwatch-, ToggleCheckbox- und Alert-Elemente; Palette-Suche ergänzt
    • Demo-Templates für Tabs/Repeater und vertical-modern Wrapper
  • Bug Fixes

    • Wiederherstellung der Vorbefüllung beim Hinzufügen neuer Slices; Parser-Problem bei Tab-active-Klasse behoben
  • Documentation

    • Changelog auf 9.1.0, erweiterte Doku- und API-Beschreibungen zu Tabs, Repeatern und Builder

Review Change Stack

Nachträge

  1. Form Builder: neue Feldtypen aus [9.2][Builder] Fehlende API-Methoden in Palette ergänzen (Rest) #403 (ColorSwatch, ToggleCheckbox, Modal, Alerts)
  2. ColorSwatch-Hilfe inkl. Beispiel-Palette und Syntax mit Preview
  3. Palette-Suche (Live-Filter + / Shortcut)
  4. max. Höhe + Scroll in der linken Palette
  5. A11y-Review-Fixes für Tabs (aria-selected/controls/labelledby)

Copilot AI review requested due to automatic review settings May 21, 2026 20:28
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@skerbis has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 55 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4425b69c-664d-4446-889f-aeeb43669c1b

📥 Commits

Reviewing files that changed from the base of the PR and between 569d758 and 9852d0e.

📒 Files selected for processing (3)
  • assets/css/flex-repeater.css
  • assets/css/formbuilder.css
  • assets/css/list-widget.css

Walkthrough

Moin — Release 9.1.0: Tabs auf ID‑freies Rendering umgestellt (data‑Attribute), neue Tab‑Attribute (icon/style/layout) und Layout‑Varianten (modern, vertical) hinzugefügt; Form‑Builder erweitert (Model, UI, Codegen, Palette‑Suche), JS‑Tab‑Logik ersetzt Bootstrap, Demos, Lokalisierung und Docs aktualisiert.

Changes

Tab-System-Refactoring und Form‑Builder Erweiterungen

Layer / File(s) Summary
CSS Custom Properties und Theme‑Variablen für Tab‑Layouts
assets/css/mform.css
Neue CSS‑Variablen für .mform-tabs mit Support für moderne (horizontal) und vertikale Layouts, Hover/Active‑States, Dark‑Theme‑Overrides und Media‑Query‑Responsive-Regeln.
PHP FlexRepeater‑Rendering: ID‑freie Tabs und Auto‑Grouping
lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php
Umstellung von __MFRTAB__‑ID‑Patterns auf datenbasierte data-*‑Attribute; renderTemplate prüft needsTabAutoGrouping() und erweitert Items via MFormGroupExtensionHelper::addTabGroupExtensionItems(...).
Tab‑Attribut‑Normalisierung & Wrapper‑Markup
lib/MForm/MFormElements.php, lib/MForm/Parser/MFormParser.php, fragments/mform/mform_wrapper.php
tab-style/tab-layout werden zu data-group-* normalisiert; Parser hängt mform-tabs--modern/--vertical Klassen an; Wrapper gibt data-mform-tabs, data-mform-tab-toggle, data-tab-item und ARIA‑Attribute statt ID/href‑Bindung aus.
JS Tab‑Initialisierung: Ablösung des Bootstrap‑Tab‑Plugin
assets/mform.js, assets/repeater.js
Eigene activateTab/initTabElements ersetzen $(...).tab('show'); ensureAriaLinking() sorgt für IDs/ARIA; Event‑Delegation über data-mform-tab-toggle und konsistente active/aria‑Synchronisation.
Form‑Builder Model, Codegen & Output
assets/js/formbuilder.js
TYPES erweitert (togglecheckbox, alert*, colorswatch), Tab‑Props (tabIcon, tabStyle, tabLayout) hinzugefügt; Tab‑Nesting‑Restriktionen gelockert; Codegen übergibt optionale Tab‑Attribute an addTabElement(...); flattenStructuralChildren und modal‑Handling im Output ergänzt.
Form‑Builder UI & Palette
pages/formbuilder.php, assets/css/formbuilder.css
Palette‑Suche, ColorSwatch‑Palette‑Item, Modal‑Wrapper in Palette; neue Property‑Controls (tabIcon, tabStyle, tabLayout, modalBtnClass, modalAlign) und Hilfestellungen/AlertText im Properties‑Panel; Styles für Palette/Colorswatch‑Hilfe.
Demo‑Module und Lokalisierung
pages/module/wrapper/tabs_modern_vertical/*, pages/module/repeater/tabs_repeater_tabs/*, lang/de_de.lang, lang/en_gb.lang
Neue Demo‑Input/Output‑Templates für vertikale/verschachtelte Tabs; Ausgabe‑Template mit JSON‑Parsing; neue Sprachschlüssel (DE/EN) für Demos.
Dokumentation, Roadmap & Changelog
docs/*, CHANGELOG.md, package.yml
Docs erweitert (What's New, API‑Ref für addTabElement, Wrapper & Repeater Guides); Roadmap‑Liste neu gegliedert; package.yml auf 9.1.0 gesetzt; CHANGELOG um 9.1.0 und 9.0.1‑Fix ergänzt.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

Possibly related PRs

  • FriendsOfREDAXO/mform#400: Frühere Form‑Builder/JS‑Änderungen; thematisch verbunden mit den Builder‑Erweiterungen in diesem PR.

Suggested reviewers

  • joachimdoerr
  • eaCe
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel beschreibt präzise die Hauptänderungen: ID-freie Tab-Logik für Version 9.1, neue optionale Tab-Varianten (modern/vertikal), Form-Builder-Integration und neue Repeater-Demo-Module.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/tabs-9.1.0-demos

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Dieses PR erweitert MForm auf Version 9.1 mit einer ID-freien Tab-Implementierung, optionalen Tab-Varianten (modern/vertikal + Icons), Form-Builder-Support sowie neuen Demo-Modulen und aktualisierter Dokumentation.

Changes:

  • Tabs: ID-freies Rendering + JS-Handling (scoped pro .mform-tabs), inkl. Fixes für verschachtelte/Repeater-Kontexte.
  • Neue Tab-Optionen: tab-icon, tab-style=modern, tab-layout=vertical (PHP-Parsing + Styles + Form Builder).
  • Demos & Doku: neue Demo-Module, Changelog/What’s New/Wrapper-/Repeater-/API-Doku ergänzt.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pages/module/wrapper/tabs_modern_vertical/input.inc Neues Demo-Input für moderne/vertikale Tabs inkl. Icons
pages/module/wrapper/tabs_modern_vertical/output.inc Neues Demo-Output für Tabs modern/vertikal
pages/module/repeater/tabs_repeater_tabs/input.inc Neues Demo-Input für verschachtelte Tabs + Repeater + Tabs
pages/module/repeater/tabs_repeater_tabs/output.inc Neues Demo-Output (Debug-Ausgabe) für verschachtelte Tabs/Reapeater
pages/formbuilder.php UI im Visual Form Builder um Tab-Icon/Style/Layout erweitert
package.yml Versionsbump auf 9.1.0
lib/MForm/Parser/MFormParser.php Tab-Wrapper: Klassen für modern/vertikal aus data-group-* ableiten; Attribute bereinigen
lib/MForm/MFormElements.php addTabElement() mappt tab-style/tab-layout auf data-group-tab-*
lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php ID-freies Tab-Markup im Repeater + Auto-Grouping für addTabElement()
lang/en_gb.lang Neue Demo-Labels (EN)
lang/de_de.lang Neue Demo-Labels (DE)
fragments/mform/mform_wrapper.php Tab-Markup auf ID-frei umgestellt + Wrapper-Klassen ausgegeben
docs/13_api_reference.md API-Referenz um Tab-Optionen/Builder-Hinweis ergänzt
docs/07_repeater.md Repeater-Doku für ID-freie Tabs + Auto-Grouping ergänzt
docs/05_wrapper.md Wrapper-Doku um modern/vertical Tabs ergänzt
docs/00_whats_new.md “Update 9.1” Abschnitt ergänzt
CHANGELOG.md Changelog-Eintrag für 9.1.0 ergänzt
assets/repeater.js Repeater-Tab-Handling auf ID-freie Tabs umgestellt (scoped)
assets/mform.js Globales Tab-Handling auf ID-freie Tabs umgestellt (scoped)
assets/js/formbuilder.js Form Builder: Tab-Props erweitert + Code-Emission für Tab-Optionen + Tabs nesting erlaubt
assets/css/mform.css Styles für mform-tabs--modern und mform-tabs--vertical inkl. Dark-Mode-Variablen

Comment thread lib/MForm/Parser/MFormParser.php
Comment thread fragments/mform/mform_wrapper.php
Comment thread lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php Outdated
Comment thread docs/07_repeater.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php (1)

216-224: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Moin: aria-selected wird für aktive Tabs nicht korrekt gesetzt.

Bei einem voraktivierten Tab bleibt in Line 223 aria-selected trotzdem false. Das liefert Screenreadern einen falschen Zustand.

Diff-Vorschlag
                 foreach ($tabsMeta as $idx => $meta) {
                     $tabIcon = isset($meta['attrs']['tab-icon']) ? '<i class="rex-icon ' . htmlspecialchars((string) $meta['attrs']['tab-icon'], ENT_QUOTES) . '"></i> ' : '';
+                    $isActive = isset($meta['attrs']['data-group-open-tab']) && true === $meta['attrs']['data-group-open-tab'];
                     $navClass = trim(
                         ((isset($meta['attrs']['nav-class'])) ? (string) $meta['attrs']['nav-class'] . ' ' : '')
                         . ((isset($meta['attrs']['pull-right']) && true === $meta['attrs']['pull-right']) ? 'pull-right ' : '')
-                        . ((isset($meta['attrs']['data-group-open-tab']) && true === $meta['attrs']['data-group-open-tab']) ? 'active' : ''),
+                        . ($isActive ? 'active' : ''),
                     );
                     $navHtml .= sprintf(
-                        '<li role="presentation" class="%s" data-tab-nav-item="%d"><a href="#" role="tab" aria-selected="false" data-mform-tab-toggle="1" data-tab-item="%d">%s%s</a></li>',
+                        '<li role="presentation" class="%s" data-tab-nav-item="%d"><a href="#" role="tab" aria-selected="%s" data-mform-tab-toggle="1" data-tab-item="%d">%s%s</a></li>',
                         htmlspecialchars($navClass, ENT_QUOTES),
                         $idx,
+                        $isActive ? 'true' : 'false',
                         $idx,
                         $tabIcon,
                         $meta['label'], // Label ist Entwickler-HTML
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php` around lines 216 - 224,
The aria-selected attribute is always hardcoded to "false" in the sprintf that
renders the tab link; change it to reflect the active state by computing a
boolean (based on meta['attrs']['data-group-open-tab'] or the $navClass 'active'
presence) and pass "true" when the tab is active and "false" otherwise so the
sprintf call that uses $navClass, $tabIcon and data-tab-item also receives the
correct aria-selected value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/05_wrapper.md`:
- Around line 229-233: The example call to addCheckboxField is using the label
in the wrong parameter (it treats ['label' => 'Aktiv'] as the options argument);
update the example so the second argument is the options array (empty or
containing checkbox-specific options) and the third argument is the attributes
array containing the label — i.e. adjust the addCheckboxField invocation to pass
options and attributes separately so the label ends up in the attributes
parameter rather than the options parameter.

In `@docs/07_repeater.md`:
- Around line 302-304: The documentation example uses the wrong method name:
change the call on the MForm::factory() chain from addTextareaField('text', ...)
to the correct addTextAreaField('text', ...) so the example matches the real
API; verify the surrounding addTabElement('Meta', MForm::factory()... ) snippet
and update only the method name to addTextAreaField to avoid copy/paste errors.

In `@fragments/mform/mform_wrapper.php`:
- Line 45: The aria-selected attribute is hardcoded to "false" in the tab
markup; update the rendering in mform_wrapper.php to compute aria-selected
dynamically (e.g. inspect $this->getVar('class') for an "active" token or use an
existing active flag) and output aria-selected="true" when the tab is active and
"false" otherwise; locate the echo that uses $this->getVar('class'),
$this->getVar('value') and $this->getVar('label') and replace the static
aria-selected with the computed value so the anchor reflects the actual active
state.

---

Outside diff comments:
In `@lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php`:
- Around line 216-224: The aria-selected attribute is always hardcoded to
"false" in the sprintf that renders the tab link; change it to reflect the
active state by computing a boolean (based on
meta['attrs']['data-group-open-tab'] or the $navClass 'active' presence) and
pass "true" when the tab is active and "false" otherwise so the sprintf call
that uses $navClass, $tabIcon and data-tab-item also receives the correct
aria-selected value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9b1381a3-e1a0-4d1e-ada8-6d4c2531e114

📥 Commits

Reviewing files that changed from the base of the PR and between ebc5856 and 6dd4097.

📒 Files selected for processing (21)
  • CHANGELOG.md
  • assets/css/mform.css
  • assets/js/formbuilder.js
  • assets/mform.js
  • assets/repeater.js
  • docs/00_whats_new.md
  • docs/05_wrapper.md
  • docs/07_repeater.md
  • docs/13_api_reference.md
  • fragments/mform/mform_wrapper.php
  • lang/de_de.lang
  • lang/en_gb.lang
  • lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php
  • lib/MForm/MFormElements.php
  • lib/MForm/Parser/MFormParser.php
  • package.yml
  • pages/formbuilder.php
  • pages/module/repeater/tabs_repeater_tabs/input.inc
  • pages/module/repeater/tabs_repeater_tabs/output.inc
  • pages/module/wrapper/tabs_modern_vertical/input.inc
  • pages/module/wrapper/tabs_modern_vertical/output.inc

Comment thread docs/05_wrapper.md
Comment thread docs/07_repeater.md
Comment thread fragments/mform/mform_wrapper.php Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@assets/css/formbuilder.css`:
- Line 520: Remove the deprecated CSS property word-break: break-word from the
.mform-fb__colorswatch-help and .mform-fb__colorswatch-help code rules and
replace it with the already supported overflow-wrap: anywhere (or ensure
overflow-wrap: anywhere is present) to maintain the same wrapping behavior; also
scan and update the other occurrences noted (.list-widget.css at the selector
around line ~140 and .flex-repeater.css around line ~551) to keep the project
lint-clean.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e3e135cc-4179-4198-bc77-6ad598d6e6a8

📥 Commits

Reviewing files that changed from the base of the PR and between e7ab390 and 569d758.

📒 Files selected for processing (11)
  • CHANGELOG.md
  • assets/css/formbuilder.css
  • assets/js/formbuilder.js
  • assets/mform.js
  • assets/repeater.js
  • docs/05_wrapper.md
  • docs/07_repeater.md
  • fragments/mform/mform_wrapper.php
  • lib/MForm/FlexRepeater/MFormFlexRepeaterRenderer.php
  • lib/MForm/Parser/MFormParser.php
  • pages/formbuilder.php
✅ Files skipped from review due to trivial changes (3)
  • CHANGELOG.md
  • docs/05_wrapper.md
  • docs/07_repeater.md

Comment thread assets/css/formbuilder.css Outdated
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@skerbis
skerbis merged commit af9d1a9 into main May 21, 2026
7 checks passed
@skerbis
skerbis deleted the feature/tabs-9.1.0-demos branch May 21, 2026 21:14
@coderabbitai coderabbitai Bot mentioned this pull request May 22, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Jul 6, 2026
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.

2 participants