feat: add grid block with two-column layout to block editor#34789
feat: add grid block with two-column layout to block editor#34789
Conversation
…d virtual scroller initialization for improved user experience
…ze and minHeight properties for better layout control
…ture for content type management
…nce content type selection experience
…d user experience and enhance dropdown options management
…nsive scenarios including lazy loading, filtering, and pinned option functionality
… for improved consistency and functionality across the application
…nput bindings and adding output emission tests for improved coverage
…unnecessary disabled input binding and focusing on FormControl state
…g unused provideNoopAnimations and maintaining essential testing utilities
…t by refining input handling, enhancing output emissions, and ensuring proper state management during filtering and lazy loading
…elect options and improving event handling for better user interaction
…clarify synchronization with ControlValueAccessor and state fetching for content and site objects
…to clear debounce timeout for improved resource management
…t and site fetching logic, ensuring no duplicate API calls for already loaded items
…d improve state management by removing unnecessary logic and enhancing readability
…th improved API integration and unit tests
…lity, including lazy loading, filtering, and improved state management
…otThemeComponent for improved theme selection integration
…nt and its associated files to streamline theme selection process
…electorComponent with DotSiteComponent and enhance mock service for site retrieval
…d services and improving mock configurations
…ce and improving event handling for dot-site component
- Replace CSS custom properties and hardcoded values with Tailwind @apply - Move styles to :host selector, removing unnecessary top-level wrapper divs - Wrap naked ::ng-deep selectors in :host to prevent style leakage - Use @reference instead of @import for Tailwind in component CSS files to avoid bundle bloat - Apply same @reference fix to template-builder component CSS files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across different contexts, creating inconsistency and potential rendering issues:
This inconsistency means the same content will render differently in the editor vs. frontend vs. backend, breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
currentRatio = Math.min(11/12, Math.max(1/12, startRatio + deltaX / usableWidth));If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling. Should use 🟡 Potential Memory IssuesDOM Manipulation Without Cleanup ( const editorParent = view.dom.parentElement;
if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. 🟡 Design IssuesGeneric CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin name suggests it could be extensible. This creates misleading architecture. 🟡 Edge Case IssuesNavigation Logic Complexity ( Empty Grid Deletion ( Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping Recommendation: Address the CSS styling inconsistencies before merging as they break the WYSIWYG principle. The different rendering approaches need to be unified across all contexts. |
…ind utilities Replace dotCMS CSS custom properties with PrimeNG-mapped Tailwind utilities: - var(--gray-N) → surface-N (tailwindcss-primeui surface palette) - var(--color-palette-primary-N) → primary-N (PrimeNG primary palette) - var(--color-palette-primary-op-N) → color-mix() for opacity variants - All layout properties converted to @apply directives - Added @reference imports for tailwindcss and tailwindcss-primeui Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewReviewing the grid block implementation for security issues, edge cases, and design problems. Todo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across different contexts, creating inconsistency and potential rendering issues:
This inconsistency means the same content will render differently in the editor vs. frontend vs. backend, breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
currentRatio = Math.min(11/12, Math.max(1/12, startRatio + deltaX / usableWidth));If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling. Should use 🟡 Potential Memory IssuesDOM Manipulation Without Cleanup ( const editorParent = view.dom.parentElement;
if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. 🟡 Design IssuesGeneric CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin name suggests it could be extensible. This creates misleading architecture. 🟡 Edge Case IssuesNavigation Logic Complexity ( Empty Grid Deletion ( Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping Recommendation: Address the CSS styling inconsistencies before merging as they break the WYSIWYG principle. The different rendering approaches need to be unified across all contexts. |
… properties Replace dotCMS CSS variables with PrimeNG tokens in _tables.css and _prosemirror.css: - var(--gray-N) → var(--p-surface-N) - var(--color-palette-primary-N) → var(--p-primary-N) - var(--color-palette-primary-op-N) → color-mix() for opacity variants - Add comments explaining why @apply cannot be used in plain CSS partials Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across different contexts, creating inconsistency and potential rendering issues:
This inconsistency means the same content will render differently in the editor vs. frontend vs. backend, breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
currentRatio = Math.min(11/12, Math.max(1/12, startRatio + deltaX / usableWidth));If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling. Should use 🟡 Potential Memory IssuesDOM Manipulation Without Cleanup ( const editorParent = view.dom.parentElement;
if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. 🟡 Design IssuesGeneric CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin name suggests it could be extensible. This creates misleading architecture. 🟡 Edge Case IssuesNavigation Logic Complexity ( Empty Grid Deletion ( Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping Recommendation: Address the CSS styling inconsistencies before merging as they break the WYSIWYG principle. The different rendering approaches need to be unified across all contexts. |
Use :scope > .grid-block__column selectors instead of .grid-block__column to restrict column lookup to direct children only. Without :scope, querySelector would match columns belonging to nested inner grid blocks, causing the outer grid block resize handle to be positioned incorrectly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across contexts, creating inconsistency and breaking WYSIWYG principles:
This means the same content renders differently in editor vs. frontend vs. backend, fundamentally breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
const startRatio = firstCol.getBoundingClientRect().width / usableWidth;If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling and DOM bloat. Should use 🟡 Memory/DOM IssuesDOM Manipulation Without Cleanup ( if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. Generic CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like 🟡 Edge Cases & Design IssuesNavigation Logic Complexity ( Empty Grid Deletion Logic ( Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin architecture suggests extensibility. This creates misleading expectations. Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping in Velocity template Recommendation: Address the CSS styling inconsistencies before merging as they break the fundamental WYSIWYG principle. The different rendering approaches need to be unified across all contexts (editor, React SDK, Angular SDK, Velocity template). |
- Restrict gridColumn content schema to exclude gridBlock nodes - Guard insertGridBlock command to return false when cursor is inside a gridColumn - Clean up grid-resize plugin removing failed nested-grid position resolution attempts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across contexts, creating inconsistency and breaking WYSIWYG principles:
This means the same content renders differently in editor vs. frontend vs. backend, fundamentally breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
const startRatio = firstCol.getBoundingClientRect().width / usableWidth;If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling and DOM bloat. Should use 🟡 Memory/DOM IssuesDOM Manipulation Without Cleanup ( if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. Generic CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like 🟡 Edge Cases & Design IssuesNavigation Logic Complexity ( Empty Grid Deletion Logic ( Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin architecture suggests extensibility. This creates misleading expectations. Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping in Velocity template Recommendation: Address the CSS styling inconsistencies before merging as they break the fundamental WYSIWYG principle. The different rendering approaches need to be unified across all contexts (editor, React SDK, Angular SDK, Velocity template). |
Replace percentage-based gridTemplateColumns with repeat(12, 1fr) and grid-column: span N on each column, matching the VTL renderer approach. This ensures consistent rendering across editor, React SDK, Angular SDK, and the Velocity template. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across contexts, creating inconsistency and breaking WYSIWYG principles:
This means the same content renders differently in editor vs. frontend vs. backend, fundamentally breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
const startRatio = firstCol.getBoundingClientRect().width / usableWidth;If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling and DOM bloat. Should use 🟡 Memory/DOM IssuesDOM Manipulation Without Cleanup ( if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. Generic CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like 🟡 Edge Cases & Design IssuesNavigation Logic Complexity ( Empty Grid Deletion Logic ( Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin architecture suggests extensibility. This creates misleading expectations. Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping in Velocity template Recommendation: Address the CSS styling inconsistencies before merging as they break the fundamental WYSIWYG principle. The different rendering approaches need to be unified across all contexts (editor, React SDK, Angular SDK, Velocity template). |
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across contexts, creating inconsistency and breaking WYSIWYG principles:
This means the same content renders differently in editor vs. frontend vs. backend, fundamentally breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
const startRatio = firstCol.getBoundingClientRect().width / usableWidth;If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling and DOM bloat. Should use 🟡 Memory/DOM IssuesDOM Manipulation Without Cleanup ( if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. Generic CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like 🟡 Edge Cases & Design IssuesNavigation Logic Complexity ( Empty Grid Deletion Logic ( Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin architecture suggests extensibility. This creates misleading expectations. Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping in Velocity template Recommendation: Address the CSS styling inconsistencies before merging as they break the fundamental WYSIWYG principle. The different rendering approaches need to be unified across all contexts (editor, React SDK, Angular SDK, Velocity template). |
|
Claude finished @fmontes's task —— View job Grid Block PR ReviewTodo List:
Critical Issues Found🔴 CSS Styling InconsistenciesThe implementation uses three different CSS Grid approaches across different contexts, creating inconsistency and potential rendering issues:
This inconsistency means the same content will render differently in the editor vs. frontend vs. backend, breaking WYSIWYG expectations. 🟡 Input Validation IssuesDivision by Zero Risk ( const usableWidth = gridRect.width - gap;
const startRatio = firstCol.getBoundingClientRect().width / usableWidth;If Precision Issues ( const pct1 = (cols[0] / 12) * 100; // Can produce 33.333333333%
const pct2 = (cols[1] / 12) * 100;Long decimal percentages create inconsistent styling and DOM bloat. Should use 🟡 Memory/DOM IssuesDOM Manipulation Without Cleanup ( if (editorParent) {
editorParent.style.position = 'relative'; // Modifies parent styling permanently
}The plugin modifies parent element styling but never resets it, potentially affecting other components. Generic CSS Classes ( class: 'grid-block' // Too generic, could conflict with other grid implementationsShould use more specific prefixed classes like 🟡 Edge Cases & Design IssuesNavigation Logic Complexity ( Empty Grid Deletion Logic ( Hardcoded Column Limit ( content: 'gridColumn gridColumn', // Fixed to exactly 2 columnsThe content spec hardcodes 2 columns but the plugin architecture suggests extensibility. This creates misleading expectations. Minor Issues
Positive Aspects✅ Security: XSS vulnerability properly addressed with input validation and escaping in Velocity template Recommendation: Address the CSS styling inconsistencies before merging as they break the fundamental WYSIWYG principle. The different rendering approaches need to be unified across all contexts (editor, React SDK, Angular SDK, Velocity template). |
|
@claude please create a github issue based on the summary and the test plan of this PR. |
|
Claude finished @erickgonzalez's task —— View job Create GitHub Issue from PR Summary and Test PlanTodo List:
Issue Content PreparedI've prepared the complete GitHub issue content based on the PR summary and test plan, but I don't have permission to create issues via the GitHub CLI. Here's the issue content that should be created: Title: Body: ## Overview
This issue tracks the implementation of a new grid block feature with two-column layout for the block editor, as implemented in PR #34789.
## Summary
- Adds a new `gridBlock` TipTap node with two-column layout, following the same pure-node pattern as tables (no Angular components needed)
- Each column (`gridColumn`) supports independent nested blocks (paragraphs, headings, images, lists, etc.)
- Includes CSS Grid styling with dashed borders, focus highlighting, and drag support
- Integrates into the slash menu as "Grid (2 columns)" and supports Tab/Shift-Tab column navigation
## Test Plan
- [ ] Open block editor, type `/` and search for "Grid" — should see "Grid (2 columns)"
- [ ] Select it — should insert a two-column grid with dashed borders
- [ ] Type in each column independently — content should stay in its column
- [ ] Add headings, images, lists inside columns — should work normally
- [ ] Tab between columns — should navigate left→right, Shift-Tab right→left
- [ ] Drag the grid block — should move the entire grid
- [ ] Backspace in a column — should not delete the column itself
## Technical Implementation
- **Backend**: Velocity template (`gridBlock.vtl`) with XSS protection and input validation
- **Frontend SDKs**: React and Angular components with proper column validation
- **Editor Integration**: TipTap node with resize plugin for interactive column adjustment
- **Styling**: CSS Grid with responsive design and accessibility features
## Related
- Original PR: #34789
- Fixes: #33882
## Labels
`feature`, `block-editor`, `frontend`
---
Generated from PR #34789 via Claude CodeNext StepsYou can copy the above content and manually create the GitHub issue, or grant me additional permissions to create issues directly. The content is formatted and ready to be used as a GitHub issue. |
## Summary - Adds a new `gridBlock` TipTap node with two-column layout, following the same pure-node pattern as tables (no Angular components needed) - Each column (`gridColumn`) supports independent nested blocks (paragraphs, headings, images, lists, etc.) - Includes CSS Grid styling with dashed borders, focus highlighting, and drag support - Integrates into the slash menu as "Grid (2 columns)" and supports Tab/Shift-Tab column navigation ## Test plan - [ ] Open block editor, type `/` and search for "Grid" — should see "Grid (2 columns)" - [ ] Select it — should insert a two-column grid with dashed borders - [ ] Type in each column independently — content should stay in its column - [ ] Add headings, images, lists inside columns — should work normally - [ ] Tab between columns — should navigate left→right, Shift-Tab right→left - [ ] Drag the grid block — should move the entire grid - [ ] Backspace in a column — should not delete the column itself 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Rafael Velazco <rjvelazco21@gmail.com> Co-authored-by: Humberto Morera <humberto.morera@dotcms.com> Co-authored-by: Adrian Molina <adrian.molina@dotcms.com> Co-authored-by: Jalinson Diaz <zjaaaldev@gmail.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Humberto Morera <31667212+hmoreras@users.noreply.github.com> Co-authored-by: Kevin <kevin.davila@dotcms.com> Co-authored-by: Kevin Davila <144152756+KevinDavilaDotCMS@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Stephen Bolton <steve.bolton@dotcms.com> Co-authored-by: Arcadio Quintero <oidacra@gmail.com>
Summary
gridBlockTipTap node with two-column layout, following the same pure-node pattern as tables (no Angular components needed)gridColumn) supports independent nested blocks (paragraphs, headings, images, lists, etc.)Test plan
/and search for "Grid" — should see "Grid (2 columns)"🤖 Generated with Claude Code
This PR fixes: #33882