Visual Editor - v1.0.0
Visual Editor Changelog
All notable changes to this project are documented in this file. The format is based on Keep a Changelog; this project adheres to Semantic Versioning.
[Unreleased]
[1.0.0] — 2026-06-08
First stable release of the V1 surface. Promotes 1.0.0-beta1 to GA
with the additions and fixes listed below. The post editor, site
editor, artisanpack/* block fork, and first-class
artisanpack-ui/cms-framework pairing — all introduced across
1.0.0-alpha.1 and 1.0.0-beta1 — are now considered stable. See the
README and the docs/ directory for the full V1
surface.
Added
- Laravel 13 support.
illuminate/supportconstraint updated to^11.0|^12.0|^13.0(Laravel 5.3–10 are no longer supported — the previous>=5.3floor was effectively dead code, sinceorchestra/ testbenchalready pinned us to Laravel 11+). Laravel 13 requires PHP 8.3+, which is enforced transitively through L13's ownphpconstraint; the package PHP floor (^8.2) is unchanged for users staying on Laravel 11/12.
Fixed
- Paragraph block-gap spacing. Paragraph blocks now correctly
inherit
is-layout-flowblock-gap spacing in the rendered output (#540). artisanpack/post-titleeditable inline. The post-title block now edits the live entity directly instead of getting stuck on its initial value (#546).- FontSizePicker duplicate-key warnings. Font-size presets are
now deduplicated before being handed to
FontSizePicker, silencing the React duplicate-key warning that surfaced under certain theme.json configurations (#547). tsc --noEmiterrors in the core-data shim. Resolved the TypeScript errors surfaced bytsc --noEmitin the core-data shim and its tests (#542).
[1.0.0-beta1] — V1 beta release
First public beta of the V1 surface. Ships the post editor, the site
editor, the block fork to the artisanpack/* namespace, and first-class
pairing with artisanpack-ui/cms-framework. See the README
and the docs/ directory for the full V1 surface.
Added
- Site editor (Phase H). Mounted at
/visual-editor/site. Templates, template parts, theme.json-backed global styles, navigation menus, and patterns — all editable through a custom shell built on@wordpress/block-editor. Backed by cms-framework'sTemplate/TemplatePart/GlobalStyles/Menu/Patternmodels when cms-framework is installed; fail-closedSiteEditorAccessGatedefaults to deny until the host binds a permissive gate (or installs cms-framework, which auto-bindsCmsFrameworkInstallGate). - Documentation set. Fifteen new / refreshed docs covering install,
content model, Blade component reference, post-editor surface, custom
blocks, renderers, site-editor surface, templates, global styles,
navigation, patterns, Livewire and Inertia embedding recipes,
theming, troubleshooting, and migration. Entry point:
docs/getting-started.md. - V1 expansion plan retained as historical record:
docs/plans/11-v1-expansion.md.
Changed
- README rewritten to reflect final V1 scope: post editor + site editor
- patterns + Livewire/Inertia embedding.
[1.0.0-alpha.1] — Gutenberg adoption marker
Added
- Block fork (Phase I) —
core/*→artisanpack/*. All 42 forked blocks plus the pre-existingartisanpack/calloutandartisanpack/formnow register under theartisanpack/*namespace. Clusters landed in order: I0 paragraph pilot (#408), I1 content (#409), I2 media (#410), I3 layout incl. grid/grid-item split (#411), I4 widgets (#412), I5 entity (#413), I6 loop/feed (#414), I7 cutover (#415). The editor bootstraps ineditor-app.tsxandsite-editor-app.tsxcallregisterArtisanPackBlocks()instead ofregisterCoreBlocks();@wordpress/block-libraryis demoted todevDependenciesand consumed only byscripts/upstream-diff.mjs. Per-blockupstream-state.jsonfiles keep the drift trail.from:core/*transforms ship on every fork so pasted upstream markup still converts. Full plan:docs/plans/13-block-fork.md. - Block fork completion gate (Phase I8, #416). Confirms the cutover
is complete and hands release-notes inputs to #325. Adds
docs/release-notes-inputs-1.0.0.mdwith the pinned@wordpress/*table and the visual-editor ↔ cms-framework version pair (v1.0.x↔^1.1). Wires the per-block upstream-diff CLI into CI so the first post-fork Renovate cycle triages drift before merging. - cms-framework integration (Phase G). First-class pairing with
artisanpack-ui/cms-framework. When both packages are installed, the visual editor can edit cms-framework'sPostandPagecontent end-to-end;core/site-*blocks read from cms-framework's settings store viaapGetSetting('site.*');core/post-*,core/archives,core/categories,core/tag-cloud,core/query, andcore/query-loopcome off the V1 deny-list and resolve against cms-framework's models and term endpoints. Loose coupling preserved — both packages remain usable standalone; cms-framework's editor wiring is guarded byclass_exists(\ArtisanPackUI\VisualEditor\VisualEditor::class). Pair-versioning matrix lives in the README; thedocs/g6-smoke-flow.mdflow runs against the version pair before every release tag. Full integration contract:docs/plans/12-cms-framework-integration.md. - "Using with cms-framework" README section. Covers install, migrations, the merged resource map under
ap.visual-editor.resources, and the version-pair contract. visual_editor.*permissions schema seeded into cms-framework's RBAC when both packages are installed (G5). Policies still use the "any authenticated user" baseline in V1.0; delegation lands in V1.1 behindartisanpack.visual-editor.authorization.delegate_to_cms_framework.artisanpack/formblock. Dynamic block that lets authors pick a form from the artisanpack-ui/forms package via the InspectorControls sidebar, and renders a<div data-keystone-form="…" data-form-id="…">mount-point on the public site. The host application supplies a JS island that hydrates the mount-point with the forms package's ReactFormRenderer. Registration is gated onclass_exists(ArtisanPackUI\Forms\Models\Form::class)so visual-editor still boots when forms is absent.- Stale-selection guard in the form block's editor preview. When the persisted
formIdno longer matches any form returned by/api/v1/forms, the canvas renders a distinct<Placeholder>with a "Reset selection" button that clears the attribute back to0. Replaces the previous silent fall-through to the 404 "inactive" message, which mis-coded deleted forms as merely deactivated.
Changed
FormBlock::validateAttrs()now parsesformIdwithFILTER_VALIDATE_INTvia anormalizeFormId()helper. Rejects float strings ("12.9") and scientific notation ("1e2") thatis_numeric+(int)previously truncated into unrelated form ids; non-positive values fall through to the "select a form" placeholder.- Form block editor preview's 404 error message updated from "This form is inactive…" to "This form is unavailable — it may have been deleted or deactivated." — neutral wording that fits both branches of
FormBlock::render's server-side check. - All
block.jsontextdomainvalues aligned with the editor runtime'sTEXT_DOMAINconstant (artisanpack-visual-editor). Translations for block titles/descriptions/keywords now resolve under the same domain as the rest of the editor strings.