Repository navigation
feat: port crosswinds-blocks grid + grid-item families (CW2) - #569
Conversation
Forks `crosswinds-blocks/basic-grid` and `basic-grid-item` into the
artisanpack/* namespace with the "basic-" prefix dropped from block
names, attributes, classes, and labels.
Grid family:
- artisanpack/grid (parent) carries a single `numColumns` attribute,
enrolled in artisanpackResponsive.attributes so the per-breakpoint
HOC routes overrides into `responsive.numColumns.{bp}`. Gap is
surfaced through the standard spacing.blockGap support with
horizontal/vertical sides.
- artisanpack/grid-item (child) carries `gridColumnSpan`, `gridRowSpan`,
and an `innerLayout` enum (normal/equal/center/bottom/last-bottom).
Spans are enrolled in artisanpackResponsive.attributes; the
column-span max is clamped to the grid's `numColumns` via block
context.
Renderers (Blade + React + Vue):
- Per-breakpoint values encode as static classes:
`ap-grid-has-N-{base|sm|md|lg|xl|2xl}-columns`
`ap-grid-item-span-N-{bp}-{columns|row}`
- grid.css ships the matching @media-keyed rules; mobile-first cascade
picks the active breakpoint's class at runtime. Class-driven (not
per-instance @media via the accumulator) so the front-end works
regardless of where `<x-ve-blocks-styles>` lands.
Editor canvas:
- canvas-styles.ts injects grid.css into the iframe so authors get an
accurate preview as they switch breakpoints.
Tests:
- Renderer-parity tests cover the family in all three renderers
(Unit) plus a Feature test that verifies the per-breakpoint class
emission survives through `<x-ve-blocks>`.
Closes #498
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughAdds ChangesGrid Block Implementation & Registry
sequenceDiagram
participant Editor as Gutenberg Editor
participant GridEdit as GridEdit Component
participant BlockTree as InnerBlock Tree
participant Renderer as Blade/React/Vue Renderer
participant CSS as Grid CSS
Editor->>GridEdit: setAttributes(numColumns=4)
GridEdit->>BlockTree: useInnerBlocksProps(artisanpack/grid-item)
BlockTree->>GridEdit: Nested grid-item blocks
GridEdit->>Renderer: Render block tree
Renderer->>CSS: apply ap-grid / ap-grid-item classes
CSS->>Renderer: grid-template-columns / grid-column/span rules
Editor->>GridEdit: update responsive.numColumns.md=3
Renderer->>CSS: apply ap-grid-has-3-md-columns
Estimated code review effort 🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@packages/visual-editor-renderer-blade/resources/assets/frontend/grid.css`:
- Around line 54-57: The .ap-grid-item.ap-grid-item-layout-bottom rule is using
flex-direction: column but incorrectly uses align-items: flex-end (which
controls cross-axis); change the rule to use justify-content: flex-end to push
children to the bottom when stacked vertically and remove or correct align-items
as needed (update the .ap-grid-item.ap-grid-item-layout-bottom selector to use
justify-content: flex-end and only keep align-items if you need horizontal
alignment).
In
`@packages/visual-editor-renderer-blade/resources/views/components/blocks-styles.blade.php`:
- Around line 5-9: The grid stylesheet is incorrectly gated by the
$emitInteractive conditional; ensure the link tag rendering $gridStyleHref with
data-ve-grid is moved outside (or duplicated outside) the `@if`( $emitInteractive
) block so the grid CSS always loads even when $emitInteractive is false; update
the block that contains the <link rel="stylesheet" href="{{ $gridStyleHref }}"
data-ve-grid> (referencing $gridStyleHref and data-ve-grid) to be rendered
unconditionally while keeping accordion/tabs and the interactivity script
controlled by $emitInteractive.
In `@packages/visual-editor-renderer-react/src/blocks/artisanpack/grid.tsx`:
- Around line 61-63: The code currently clamps raw responsive values with
clampInt before validating, causing non-numeric or malformed inputs to become 1
and emit classes like ap-grid-*-1-*. Update the loop in grid.tsx (where
clampInt(raw, 1, 12, 0) is used) to first validate raw is a parseable finite
integer (e.g., parseInt/Number check or Number.isFinite(Number(raw))) and
skip/continue for invalid values, then call clampInt on the validated numeric
value so only legitimate numbers produce ap-grid classes.
In `@resources/js/visual-editor/blocks/grid/grid.css`:
- Around line 54-57: The .ap-grid-item.ap-grid-item-layout-bottom rule is using
align-items: flex-end with flex-direction: column which moves items
horizontally; change it to use justify-content: flex-end (and remove or leave
align-items as needed) so vertical stacking actually aligns content to the
bottom while keeping flex-direction: column.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: acefc5b3-a9e8-4f50-b71f-e36f1453207c
📒 Files selected for processing (25)
packages/renderer-parity.jsonpackages/visual-editor-renderer-blade/resources/assets/frontend/grid.csspackages/visual-editor-renderer-blade/resources/views/blocks/artisanpack/grid-item.blade.phppackages/visual-editor-renderer-blade/resources/views/blocks/artisanpack/grid.blade.phppackages/visual-editor-renderer-blade/resources/views/components/blocks-styles.blade.phppackages/visual-editor-renderer-blade/src/View/Components/BlocksStylesComponent.phppackages/visual-editor-renderer-blade/tests/Feature/Responsive/GridResponsiveRenderTest.phppackages/visual-editor-renderer-blade/tests/Unit/BlockRendererTest.phppackages/visual-editor-renderer-react/src/blocks/artisanpack/grid.tsxpackages/visual-editor-renderer-react/src/blocks/registerCoreBlocks.tspackages/visual-editor-renderer-react/tests/BlockTree.test.tsxpackages/visual-editor-renderer-vue/src/blocks/artisanpack/grid.tspackages/visual-editor-renderer-vue/src/blocks/registerCoreBlocks.tspackages/visual-editor-renderer-vue/tests/BlockTree.test.tsresources/js/visual-editor/blocks/grid-item/block.jsonresources/js/visual-editor/blocks/grid-item/edit.tsxresources/js/visual-editor/blocks/grid-item/index.tsresources/js/visual-editor/blocks/grid-item/save.tsxresources/js/visual-editor/blocks/grid/block.jsonresources/js/visual-editor/blocks/grid/edit.tsxresources/js/visual-editor/blocks/grid/grid.cssresources/js/visual-editor/blocks/grid/index.tsresources/js/visual-editor/blocks/grid/save.tsxresources/js/visual-editor/editor/__tests__/canvas-styles.test.tsresources/js/visual-editor/editor/canvas-styles.ts
- Move grid CSS link outside `$emitInteractive` gate — grid is a pure
layout family with no companion interactivity script, so it must
ship even when hosts opt out of accordion/tabs interactivity.
- Fix `.ap-grid-item-layout-bottom`: with `flex-direction: column` the
main axis is vertical, so `justify-content: flex-end` (not
`align-items: flex-end`) is what pushes children to the bottom.
- Validate raw `responsive.*` overrides as finite numbers before
clamping in React + Vue renderers — previously non-numeric values
silently snapped to the clamp min (1) and emitted bogus
`ap-grid-*-1-{bp}-*` classes. Regression tests cover the fix.
1d91687
into
feature/495-port-crosswinds-blocks
Description
Forks
crosswinds-blocks/basic-gridandbasic-grid-iteminto theartisanpack/*namespace with the "basic-" prefix dropped from block names, attribute names, class names, and labels. Part of CW2 in the crosswinds-blocks port (umbrella #495).Closes: #498
Type of Change
Related Issue
Issue: #498
Motivation and Context
CW2 cluster of the crosswinds-blocks port. Brings the grid block family in under the artisanpack/* namespace, drops the legacy "basic-" prefix, and rewires the per-breakpoint responsive story onto the visual-editor's existing
artisanpackResponsiveHOC + breakpoint registry so the editor and front-end share one source of truth.Changes Made
artisanpack/grid(parent) — singlenumColumnsattribute enrolled inartisanpackResponsive.attributes; gap surfaced via core'sspacing.blockGapwith horizontal/vertical sides.artisanpack/grid-item(child) — singlegridColumnSpan+gridRowSpan(both enrolled inartisanpackResponsive.attributes) plus aninnerLayoutenum (normal/equal/center/bottom/last-bottom). Column-span max is clamped to the parent grid'snumColumnsvia block context.ap-grid-has-N-{base|sm|md|lg|xl|2xl}-columnsandap-grid-item-span-N-{bp}-{columns|row}— that the matching media-query rules ingrid.csspick up. Mobile-first cascade resolves at viewport time; no per-instance @media or accumulator drain required.grid.cssships from bothblocks/grid/(editor canvas via?inline) andpackages/visual-editor-renderer-blade/resources/assets/frontend/(front-end via<x-ve-blocks-styles>).BlocksStylesComponent+blocks-styles.blade.phpwire the front-end stylesheet alongside accordion/tabs under theemitInteractiveflag.canvas-styles.tsinjectsgrid.cssinto the editor iframe so authors get an accurate preview as they toggle the breakpoint switcher.renderer-parity.jsonextended withartisanpack/grid+artisanpack/grid-item; verify-renderer-parity passes 135/135 across all three renderers.How Has This Been Tested?
Testing Environment:
Tests Performed:
node scripts/verify-renderer-parity.mjs: 135/135 across Blade, React, Vue.responsive.numColumns: {sm:1, md:2, lg:4}) and the front-end re-flowed columns across 640 / 768 / 1024 px. Repeated for grid-item span attributes.Accessibility Tests Run
Details: No new interactive surfaces — grid + grid-item are pure-layout containers. The block-supports compiler still emits all standard a11y attributes (className, anchor, ariaLabel) on the wrappers.
Tests Added
Test details:
BlockRendererTest.php— base render, per-breakpoint class emission, clamp behavior, innerLayout fallback, blockGap with sides.GridResponsiveRenderTest.php(Feature) — per-breakpoint classes survive through<x-ve-blocks>and unknown breakpoints are dropped silently.BlockTree.test.tsx+ VueBlockTree.test.ts— matching coverage of base + responsive class emission + clamps.canvas-styles.test.ts— count bumped from 13 → 14 to include grid styles.Documentation
Documentation details: File headers + inline blocks explain the per-breakpoint cascade and the class-driven approach across each renderer.
Pre-Submission Checklist
Summary by CodeRabbit
New Features
Tests