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
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 94 out of 95 changed files in this pull request and generated 10 comments.
Comments suppressed due to low confidence (1)
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.html:14
- Same issue here:
[class]overwrites the element’s entire class list, so the static classes (grid items-center w-full ...) can be lost. Use[ngClass]to add these grid-cols values without overriding other classes.
.../sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/GridBlock.tsx
Show resolved
Hide resolved
...ortlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.html
Outdated
Show resolved
Hide resolved
...-types-edit/components/dot-convert-to-block-info/dot-convert-to-block-info.component.spec.ts
Outdated
Show resolved
Hide resolved
core-web/libs/block-editor/src/lib/components/dot-block-editor/styles/_grid.css
Outdated
Show resolved
Hide resolved
.../sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/GridBlock.tsx
Show resolved
Hide resolved
.../sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/BlockEditorBlock.tsx
Show resolved
Hide resolved
...s/sdk/angular/src/lib/components/dotcms-block-editor-renderer/blocks/grid-block.component.ts
Outdated
Show resolved
Hide resolved
...rtlets/dot-content-drive/ui/src/lib/dot-folder-list-view/dot-folder-list-view.component.html
Show resolved
Hide resolved
...rtlets/dot-content-drive/ui/src/lib/dot-folder-list-view/dot-folder-list-view.component.html
Outdated
Show resolved
Hide resolved
dotCMS/src/main/webapp/WEB-INF/velocity/static/storyblock/gridBlock.vtl
Outdated
Show resolved
Hide resolved
Reverts changes to dot-analytics and dot-content-drive portlets that were not part of the grid block feature work. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Claude finished @fmontes's task —— View job Grid Block PR Security & Design Review🔴 Critical Security IssueXSS Vulnerability in Velocity Template ( The Velocity template properly validates and escapes the ## Validate span is a number between 1 and 12 to prevent XSS injection
#if($rawSpan && $rawSpan.toString().matches("^[0-9]+$") && $rawSpan >= 1 && $rawSpan <= 12)
#set($span = $rawSpan)
#else
#set($span = 6)
#end✅ This XSS concern has been properly addressed. The template validates that span values are numeric (1-12) and falls back to safe defaults, preventing injection attacks. Frontend Validation AnalysisThe frontend implementations also properly validate column arrays: React SDK ( const cols = rawCols.length === 2 &&
rawCols.every((v: unknown) => typeof v === 'number' && Number.isFinite(v))
? rawCols : [6, 6];Angular SDK ( const cols = rawCols.length === 2 &&
rawCols.every((v: unknown) => typeof v === 'number' && Number.isFinite(v))
? rawCols : [6, 6];Both implementations validate that columns are exactly 2 finite numbers and fall back to Design & Implementation Issues
Minor Issues
SummaryThe implementation is secure and well-designed. The critical XSS vulnerability flagged by Copilot has been properly addressed with input validation and sanitization. The grid resizing, navigation, and rendering logic is robust with good error handling and fallbacks. |
...libs/block-editor/src/lib/components/dot-editor-count-bar/dot-editor-count-bar.component.css
Outdated
Show resolved
Hide resolved
...s/dot-bubble-menu/components/dot-image-editor-popover/dot-image-editor-popover.component.css
Show resolved
Hide resolved
...nts/dot-bubble-menu/components/dot-link-editor-popover/dot-link-editor-popover.component.css
Show resolved
Hide resolved
core-web/libs/block-editor/src/lib/elements/dot-bubble-menu/dot-bubble-menu.component.css
Show resolved
Hide resolved
core-web/libs/block-editor/src/lib/elements/dot-context-menu/dot-context-menu.component.css
Show resolved
Hide resolved
core-web/libs/block-editor/src/lib/shared/components/empty-message/empty-message.component.css
Show resolved
Hide resolved
...ponents/suggestion-list/components/suggestions-list-item/suggestions-list-item.component.css
Show resolved
Hide resolved
...itor/src/lib/shared/components/suggestion-loading-list/suggestion-loading-list.component.css
Show resolved
Hide resolved
core-web/libs/block-editor/src/lib/shared/components/suggestions/suggestions.component.css
Show resolved
Hide resolved
.../sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/GridBlock.tsx
Outdated
Show resolved
Hide resolved
- 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). |
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