feat: add visibility toggle for components with outline and action bar controls - #1760
feat: add visibility toggle for components with outline and action bar controls#1760fasenderos wants to merge 4 commits into
Conversation
|
@fasenderos is attempting to deploy a commit to the Puck Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR adds persisted component visibility state, reducer support, outline and editor show/hide controls, hidden-layer styling, and suppression of hidden components during server rendering. ChangesComponent visibility controls
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Editor
participant Outline
participant Reducer
participant PageData
participant RenderedSlot
Editor->>Outline: display component hidden state
Outline->>Reducer: dispatch setVisibility
Reducer->>PageData: update component.hidden
PageData->>Editor: synchronize component display
PageData->>RenderedSlot: provide hidden item state
RenderedSlot->>RenderedSlot: apply display:none
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/core/components/DraggableComponent/index.tsxOops! Something went wrong! :( ESLint: 9.39.4 YAMLException: Cannot read config file: /packages/eslint-config-custom/index.mjs 7 | ... packages/core/components/LayerTree/components/layer-actions/index.tsxOops! Something went wrong! :( ESLint: 9.39.4 YAMLException: Cannot read config file: /packages/eslint-config-custom/index.mjs 7 | ... packages/core/components/LayerTree/components/layer/index.tsxOops! Something went wrong! :( ESLint: 9.39.4 YAMLException: Cannot read config file: /packages/eslint-config-custom/index.mjs 7 | ...
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/core/components/DraggableComponent/index.tsx`:
- Around line 520-526: Update the visibility effect in the DraggableComponent
around ref and isHidden so unhiding restores the element’s original display
behavior instead of assigning "block". Preserve the pre-hide inline display
value before setting it to "none", then restore it when isHidden becomes false,
or use a hidden attribute/class that avoids changing display styles.
In `@packages/core/components/SlotRender/server.tsx`:
- Around line 42-51: Update the rendering logic around Component.render so
visible items return Component.render directly without an inline span. Preserve
the existing props, richtextProps, and puck metadata, and only apply a hiding
wrapper when item.hidden is true.
🪄 Autofix
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0f3885f3-9146-4d30-b533-9bc78275362a
📒 Files selected for processing (13)
packages/core/components/DraggableComponent/index.tsxpackages/core/components/LayerTree/components/layer-actions/index.tsxpackages/core/components/LayerTree/components/layer/index.tsxpackages/core/components/LayerTree/components/layer/styles.module.csspackages/core/components/LayerTree/lib/build-layer-tree.tspackages/core/components/LayerTree/types.tspackages/core/components/RichTextEditor/index.tspackages/core/components/SlotRender/server.tsxpackages/core/lib/dictionary.tspackages/core/reducer/actions.tsxpackages/core/reducer/actions/set-visibility.tspackages/core/reducer/index.tspackages/core/types/Data.tsx
| useEffect(() => { | ||
| if (!ref.current) return; | ||
|
|
||
| const el = ref.current as HTMLElement; | ||
|
|
||
| el.style.display = isHidden ? "none" : "block"; | ||
| }, [ref.current, isHidden]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Restore the original display value when the component becomes visible.
Line 525 forces every restored component to display: block. This changes layout for components that use inline, flex, grid, or an explicit inline display style.
Preserve the pre-hide inline display value, or toggle a dedicated hidden attribute or class instead of assigning "block".
🤖 Prompt for 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.
In `@packages/core/components/DraggableComponent/index.tsx` around lines 520 -
526, Update the visibility effect in the DraggableComponent around ref and
isHidden so unhiding restores the element’s original display behavior instead of
assigning "block". Preserve the pre-hide inline display value before setting it
to "none", then restore it when isHidden becomes false, or use a hidden
attribute/class that avoids changing display styles.
| <span style={item.hidden ? { display: "none" } : undefined}> | ||
| <Component.render | ||
| {...props} | ||
| {...richtextProps} | ||
| puck={{ | ||
| ...props.puck, | ||
| metadata: metadata || {}, | ||
| }} | ||
| /> | ||
| </span> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Do not wrap visible component output in an inline span.
Line 42 adds a span around every component, including visible components. This changes flex and grid item layout and breaks selectors that expect the component output as the direct child.
Return Component.render directly when item.hidden is false. Apply a hiding wrapper only for hidden items.
🤖 Prompt for 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.
In `@packages/core/components/SlotRender/server.tsx` around lines 42 - 51, Update
the rendering logic around Component.render so visible items return
Component.render directly without an inline span. Preserve the existing props,
richtextProps, and puck metadata, and only apply a hiding wrapper when
item.hidden is true.
Closes #1750
Description
This PR adds a visibility toggle (Hide/Show) for components in Puck, allowing users to hide components from both the editor canvas and public render while keeping them in the DOM.
Hidden components persist through save/load via the hidden field on
BaseDataand are undoable through the reducer history.Changes made
hidden?: booleantoBaseDataintypes/Data.tsxso visibility state persists in page data automatically.SetVisibilityActiontype toPuckActionunion andsetVisibilityreducer action with history recording for undo support.outline-item-show/outline-item-hidemessages to the dictionary.hiddenfield toLayerNodetype and wired it throughbuild-layer-tree.Eye/EyeOfftoggle button inLayerActionsandAction Barwith permission gating (permissions.edit).DraggableComponentreadsisHiddenfrom store and appliesdisplay: nonevia a dedicateduseEffect, keeping the component in the DOM.<span style={{ display: "none" }}>wrapper instead of being removed from the DOM entirely.Note
Tests and documentation will be added when you think the implementation is ready to be approved.
Note 2
The decision to keep hidden components in the DOM (via
display: none) rather than removing them entirely, follows the same approach used by GrapesJS. However, this choice is open for discussion — removing hidden components from the DOM entirely (return null) would be a valid alternative if preferred.Summary by CodeRabbit
New Features
Bug Fixes