Skip to content

Image block: style fields, float alignment, coupling, and linking - #167

Merged
sneridagh merged 7 commits into
mainfrom
styledFieldsImageBlock
Sep 16, 2026
Merged

sneridagh merged 7 commits into
mainfrom
styledFieldsImageBlock

Conversation

@sneridagh

@sneridagh sneridagh commented Sep 11, 2026 •

Copy link
Copy Markdown
Member

Summary

Standardizes the image block's size and alignment on Aurora's schema-driven style fields, and completes the block's styling and interaction story on top of the concepts explored in #147 (this is a clean take rather than a continuation of that branch).

Key points:

  • Alignment and size are now styleFields resolved from config.blocks.alignments / config.blocks.sizes, consistent with blockWidth.
  • The block's CSS ships as a CSS module (ImageBlock.module.css) — no global side-effect import './ImageBlock.css', matching the slots pattern.
  • Left/right alignment floats the image so surrounding blocks wrap around it — at any size, including large (the floated width is capped so it always leaves room to wrap).
  • Alignment, size and block width are independent controls.
  • The image renders through the shared Image component in both edit and view, and is wrapped in a link when the block has an href.

What changed

Style fields for size & alignment

  • align and size marked styleField: true; config.blocks.alignments / config.blocks.sizes provide the definitions and utilities (packages/blocks/index.ts).
  • New alignments? / sizes? in BlocksConfig types.

CSS module (no side-effect import)

  • ImageBlock.module.css replaces the global ImageBlock.css. Because Tailwind's preflight/utilities and the editor selection outline live in a stronger cascade layer (cmsui), the block's own layout rules are intentionally unlayered so they win (documented inline).

Float-based alignment + wrapping

  • left/right inject --block-float + --block-margin; the module consumes them so following content (text and list markers) wraps with a proper gap.
  • Floated images are capped with max-width: var(--block-float-max-size, 66%), so even the large size floats with room for content to wrap. Centered images are unaffected (large stays full width).
  • Editor selectability: a floated image collapses its block wrapper to zero height, so the next block used to paint over it and steal clicks. The floated image is raised (position: relative; z-index) and the stray collapsed selection outline / spacing are suppressed — scoped to floated states via the data-style-align attribute.
  • List markers: lists following a floated image use list-style-position: inside so outside markers don't hang onto the image (a marker gutter can't fix this given Plate's per-item <ol> structure — see the inline note).

Independent controls (no coupling)

  • Alignment, size and block width do not constrain each other: floating an image leaves its width editable and every size available.
  • A generic onChangeSideEffects(value, nextData) tap point is available in BlockSettingsForm for blocks that do want cross-field reactions in the future; the image block no longer uses it. Documented in the new how-to with an illustrative example.

Rendering + linking

  • ImageBlockEdit/ImageBlockView share getImageBlockItem / getImageBlockSrc (responsive scales when available, legacy @@images / external URL fallback otherwise).
  • ImageBlockView wraps the image in Link (@plone/components) when href is set, honoring openLinkInNewTab (target/rel). Aurora has no UniversalLink; Link is the pattern used by Teaser and the slots.

Image widget fix

  • The image widget now forwards image_field and image_scales from the object-browser selection (previously only title), so picked images render responsive scales.

Testing

  • Unit (packages/blocks): schema style-field marks, alignment/size definitions, and that the fields stay independent (no coupling).
  • Acceptance (packages/cmsui/acceptance/tests/image-block-style-fields.test.ts, 8 tests):
    • centered large is full width with no float and all controls;
    • floating left/right leaves width and size untouched and floats the large size (capped, so it wraps);
    • block width stays editable and independent while floated;
    • floated sizes scale S < M < L with large capped (verified in the published view);
    • a single sequential walkthrough of every alignment/size combination;
    • a render-on-save round trip (set a combination in the editor, Save, then assert the published view renders it);
    • a linked image wraps in an <a target="_blank" rel="noopener…">.
  • Updated block-width.test.ts locator (.image.align.block → .block-image) after the class refactor, and added testIgnore for .codex/** / node_modules in playwright.config.ts so ephemeral git worktrees aren't collected.

Docs

New how-to guide Couple block schema fields documenting onChangeSideEffects with an illustrative example (no shipped block enables the coupling today).

* main:
  Release @plone/plate 1.0.0-alpha.15
  Fix release @plone/plate (#166)
Migrate the image block's alignment and size to schema-driven style fields
and finish the block's styling story:

- Deliver the block CSS as a CSS module (no global side-effect import),
  following the slots pattern.
- Float left/right aligned images so surrounding content wraps around them,
  keep the gap for wrapping text and list markers, and keep floated images
  selectable in the editor (raise them, drop the collapsed selection outline).
- Couple alignment with size and block width via a new, generic
  `onChangeSideEffects` tap point in the block settings form: floated images
  fix the width to default and drop the large size; centering restores both.
- Render the image through the shared Image component in both edit and view,
  and wrap it in a link when the block has an href.

Add unit and acceptance coverage and a how-to guide for onChangeSideEffects.
@sneridagh
sneridagh requested a review from pnicolli September 11, 2026 22:11
Following review feedback, remove the alignment↔size/width coupling from the
image block so left/right, size and block width are independent controls again:

- Left/right alignment floats the image at any size; the floated width is
  capped (`--block-float-max-size`, default 66%) so even the large size floats
  with room for content to wrap.
- The block width control stays editable while floated, and every image size
  stays available.
- The generic `onChangeSideEffects` tap point remains in the block settings
  form for future use; the how-to guide now presents it with an illustrative
  example instead of the (removed) image block coupling.

Expand the acceptance suite to cover the combinations end to end: the size
scale while floated, block width independence, a single sequential walkthrough
of every alignment/size combination, and a render-on-save round trip.
The sequential walkthrough flaked in CI: changing a style field re-renders and
deselects the block asynchronously, and the previous `ensureSelected` helper
could observe the still-open sidebar during that transition, skip re-selecting,
then fail when the next radio had disappeared.

Replace it with a retrying `selectBlock` (open the sidebar, retried) and
`setRadio` (select-then-click as one retried unit), so a pending deselect no
longer races the next interaction.
@sneridagh
sneridagh merged commit 9550625 into main Sep 16, 2026
32 of 33 checks passed
@sneridagh
sneridagh deleted the styledFieldsImageBlock branch September 16, 2026 07:56
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