Skip to content

feat: support user defined component labels by istance - #1763

Open
fasenderos wants to merge 7 commits into
puckeditor:mainfrom
fasenderos:user-component-label
Open

feat: support user defined component labels by istance#1763
fasenderos wants to merge 7 commits into
puckeditor:mainfrom
fasenderos:user-component-label

Conversation

@fasenderos

@fasenderos fasenderos commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes #1752

Description

This PR adds per-instance custom labels for Puck components. Users can now rename individual component instances directly from the UI — the sidebar, the canvas action bar, and the outline panel — with the label persisting in the component data via a __puck.label field.

A new InlineLabelEdit component centralizes the label editing logic (read store, resolve label, dispatch updates), and a getComponentLabel utility provides a consistent resolution priority: __puck.label → config.components[type].label → type.toString().

Changes made

Core: label storage & resolution

  • Added __puck?: { label?: string } to BaseData in Data.tsx — per-instance metadata stored outside props so it never leaks to rendered output
  • Created lib/data/get-component-label.ts with getComponentLabel(item, config, fallback) — resolves label with priority __puck.label → component config label → type string — and getNodeLabel(node, config, fallback) for the store index node format
  • Implemented setComponentLabel reducer action — stores the custom label in __puck.label, and auto-strips it when the label matches the type default or is empty

New shared component: InlineLabelEdit

  • Reads component data from the Puck store via componentId prop and resolves the label internally with getComponentLabel
  • Double-click on it to start editing label
  • Dispatches setComponentLabel automatically on save
  • Optional render-prop children({ label }) for custom display; defaults to plain text when omitted
  • Styled with a minimal inline input (underline on focus)

UI integration

  • SidebarSection — when a component is selected, the breadcrumb heading title becomes editable via InlineLabelEdit
  • DraggableComponent (DefaultActionBar) — the action bar label uses InlineLabelEdit with a render-prop for ActionBar.Label
  • LayerTree/layer — the outline panel shows the editable label via InlineLabelEdit
  • Fields plugin — CurrentTitle now respects __puck.label

How to test

  1. Open any Puck editor with a component on the canvas
  2. Double-click the component's title in the right sidebar (or the action bar, or the outline) and type a custom label, then press Enter
  3. Confirm the custom label appears in:
  • The right sidebar breadcrumb
  • The canvas action bar
  • The outline panel
  1. Reset the label to the default value (the component type name) and confirm __puck is stripped from the data
  2. Verify __puck does not appear in the rendered output (SSR safety — it lives on ComponentData, not inside props)

Note

Tests and documentation will be added when you think the implementation is ready to be approved.

Summary by CodeRabbit

  • New Features
    • Added inline renaming for components, layers, and sidebar sections.
    • Double-click labels to edit them; press Enter or click away to save, or Escape to cancel.
    • Custom labels now appear consistently across breadcrumbs, sidebars, layer trees, and component titles.
    • Labels automatically fall back to configured names or component types when no custom label is set.

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@fasenderos is attempting to deploy a commit to the Puck Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
puck-demo Ready Ready Preview Aug 10, 2026 1:40am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 44a6d17c-9ba2-45a9-b700-54fc2c0ea976

📥 Commits

Reviewing files that changed from the base of the PR and between e1c40a8 and 57a1822.

📒 Files selected for processing (1)
  • packages/core/components/SidebarSection/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/components/SidebarSection/index.tsx

📝 Walkthrough

Walkthrough

The PR adds per-instance component labels. Users can edit labels in the outline, action bar, and sidebar. Labels are stored in __puck.label, resolved consistently, and removed before rendered component data is consumed.

Changes

Component label editing

Layer / File(s) Summary
Label metadata and resolution
packages/core/types/Data.tsx, packages/core/lib/data/get-component-label.ts, packages/core/lib/dictionary.ts
Adds __puck.label, shared label resolution helpers, and the label-rename dictionary entry.
Label action and state updates
packages/core/reducer/actions.tsx, packages/core/reducer/actions/set-component-label.ts, packages/core/reducer/index.ts, packages/core/components/DropZone/index.tsx
Adds label actions and reducer handling. Stores non-default labels and removes empty overrides. Preserves metadata during node expansion.
Inline label editor
packages/core/components/InlineLabelEdit/index.tsx, packages/core/components/InlineLabelEdit/styles.module.css
Adds double-click editing with save, cancel, focus, trimming, and event propagation handling.
Editor surface integration
packages/core/components/DraggableComponent/index.tsx, packages/core/components/LayerTree/..., packages/core/components/SidebarSection/index.tsx, packages/core/components/Puck/components/Layout/index.tsx, packages/core/lib/use-breadcrumbs.ts, packages/core/plugins/fields/index.tsx
Uses editable or shared label resolution across the action bar, outline, sidebar, breadcrumbs, and selected-component title.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant InlineLabelEdit
  participant PuckStore
  participant setComponentLabelAction
  participant ComponentData
  User->>InlineLabelEdit: Double-click label
  InlineLabelEdit->>PuckStore: Read node and current label
  User->>InlineLabelEdit: Enter trimmed label
  InlineLabelEdit->>PuckStore: Dispatch setComponentLabel
  PuckStore->>setComponentLabelAction: Apply label action
  setComponentLabelAction->>ComponentData: Store or remove __puck.label
  ComponentData-->>PuckStore: Updated component data
  PuckStore-->>InlineLabelEdit: Render updated label
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers per-instance label editing, precedence, storage, and UI integration required by issue [#1752], but does not show all required cleanup, theming, and dictionary behavior. Add or verify removal of __puck before Render, make all label UI strings dictionary-overridable, and ensure label editor colors use themeable values.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies support for user-defined per-instance component labels, despite a minor spelling error.
Description check ✅ Passed The description includes the required issue link, description, changes, and testing sections with relevant implementation and verification details.
Out of Scope Changes check ✅ Passed The changes remain focused on per-instance component labels and their shared UI, data, reducer, and label-resolution support for issue [#1752].
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/core/components/SidebarSection/index.tsx

Oops! Something went wrong! :(

ESLint: 9.39.4

YAMLException: Cannot read config file: /packages/eslint-config-custom/index.mjs
Error: end of the stream or a document separator is expected (10:21)

7 | ...
8 |
9 | const newReactHooksRules = {
10 | "react-hooks/refs": "off",
--------------------------^
11 | "react-hooks/error-boundaries": "off",
12 | "react-hooks/immutability": "off",
Referenced from: /.eslintrc.js
at generateError (/node_modules/js-yaml/lib/loader.js:196:10)
at throwError (/node_modules/js-yaml/lib/loader.js:200:9)
at readDocument (/node_modules/js-yaml/lib/loader.js:1720:5)
at loadDocuments (/node_modules/js-yaml/lib/loader.js:1759:5)
at Object.load (/node_modules/js-yaml/lib/loader.js:1783:21)
at loadLegacyConfigFile (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2666:21)
at loadConfigFile (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2782:20)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:42)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 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/InlineLabelEdit/index.tsx`:
- Around line 105-112: Update the label trigger in InlineLabelEdit’s rendered
span to be keyboard accessible: make it focusable, handle Enter and Space key
presses by calling startEditing, and retain the existing double-click behavior
and label rendering.

In `@packages/core/components/LayerTree/components/layer/index.tsx`:
- Around line 197-199: Update the layer row component around InlineLabelEdit to
provide a keyboard-focusable rename control that triggers editing without
relying solely on double-click, and restructure the JSX so the editing input
renders outside the row selection button. Preserve existing layer selection
behavior while avoiding nested interactive elements.

In `@packages/core/components/SidebarSection/index.tsx`:
- Around line 27-40: Update the heading content in SidebarSection around
selectedItem and InlineLabelEdit so it falls back to the title prop when
selectedItem is absent, represents the root, or lacks an indexed component node.
Preserve InlineLabelEdit for valid editable component selections, rendering
title whenever it returns no editable heading.

In `@packages/core/reducer/actions/set-component-label.ts`:
- Around line 17-20: Normalize action.label in the SetComponentLabel reducer
before comparison and storage: trim surrounding whitespace, convert an empty
result to undefined, and use that normalized value for the default-label check
and custom override. Keep non-empty labels’ normalized text as the stored value.
- Around line 15-17: Update setComponentLabelAction around the newLabel
calculation to normalize incoming labels consistently with getComponentLabel and
InlineLabelEdit: trim surrounding whitespace and treat empty or whitespace-only
values as undefined before storing __puck.label. Preserve the existing
configured-label fallback behavior.

In `@packages/core/types/Data.tsx`:
- Around line 10-14: Update both Render implementations to remove the __puck
metadata from rootProps before spreading those props into config.root.render;
preserve all other root props and keep component, slot, and drop-zone rendering
behavior unchanged.
🪄 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: 99f5390a-8277-45f9-b29a-2ced0ecac93e

📥 Commits

Reviewing files that changed from the base of the PR and between b4204f0 and fd948b2.

📒 Files selected for processing (16)
  • packages/core/components/DraggableComponent/index.tsx
  • packages/core/components/DropZone/index.tsx
  • packages/core/components/InlineLabelEdit/index.tsx
  • packages/core/components/InlineLabelEdit/styles.module.css
  • packages/core/components/LayerTree/components/layer/index.tsx
  • packages/core/components/LayerTree/lib/build-layer-tree.ts
  • packages/core/components/Puck/components/Layout/index.tsx
  • packages/core/components/SidebarSection/index.tsx
  • packages/core/lib/data/get-component-label.ts
  • packages/core/lib/dictionary.ts
  • packages/core/lib/use-breadcrumbs.ts
  • packages/core/plugins/fields/index.tsx
  • packages/core/reducer/actions.tsx
  • packages/core/reducer/actions/set-component-label.ts
  • packages/core/reducer/index.ts
  • packages/core/types/Data.tsx

Comment on lines +105 to +112
return (
<span
onDoubleClick={startEditing}
title={renameMsg}
className={getClassName("label")}
>
{typeof children === "function" ? children({ label }) : label}
</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add keyboard access to label editing.

Line 107 starts editing only from onDoubleClick. The span cannot receive keyboard focus and has no keyboard handler. Keyboard users cannot rename a component from this control. Use a keyboard-accessible trigger and support Enter and Space.

🤖 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/InlineLabelEdit/index.tsx` around lines 105 - 112,
Update the label trigger in InlineLabelEdit’s rendered span to be keyboard
accessible: make it focusable, handle Enter and Space key presses by calling
startEditing, and retain the existing double-click behavior and label rendering.

Comment on lines +197 to +199
<div className={getClassName("name")}>
<InlineLabelEdit componentId={node.itemId} />
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 10 '<button|InlineLabelEdit|<input|onDoubleClick' \
  packages/core/components/LayerTree/components/layer/index.tsx \
  packages/core/components/InlineLabelEdit/index.tsx

Repository: puckeditor/puck

Length of output: 12880


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Layer component ---'
sed -n '130,215p' packages/core/components/LayerTree/components/layer/index.tsx

printf '%s\n' '--- InlineLabelEdit component ---'
sed -n '29,125p' packages/core/components/InlineLabelEdit/index.tsx

printf '%s\n' '--- Related usages and tests ---'
rg -n -C 5 'InlineLabelEdit|LayerTree|double.?click|renameMsg' \
  packages/core --glob '*.{ts,tsx,js,jsx}' | head -n 500

printf '%s\n' '--- InlineLabelEdit files ---'
git ls-files packages/core/components/InlineLabelEdit

Repository: puckeditor/puck

Length of output: 39164


Make outline renaming keyboard-accessible and keep the editor outside the selection button.

InlineLabelEdit starts editing only on onDoubleClick, so keyboard-only users cannot rename layers. Its editing state renders an <input> inside the row <button>, which creates invalid interactive nesting. Add a keyboard-focusable rename control and render the input outside the selection button.

🤖 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/LayerTree/components/layer/index.tsx` around lines
197 - 199, Update the layer row component around InlineLabelEdit to provide a
keyboard-focusable rename control that triggers editing without relying solely
on double-click, and restructure the JSX so the editing input renders outside
the row selection button. Preserve existing layer selection behavior while
avoiding nested interactive elements.

Comment thread packages/core/components/SidebarSection/index.tsx Outdated
Comment thread packages/core/reducer/actions/set-component-label.ts Outdated
Comment thread packages/core/reducer/actions/set-component-label.ts Outdated
Comment on lines +10 to +14
/** Per-instance metadata. The __puck property is removed from all components in the tree when passing data down to the Render component, before the components are actually rendered. This avoids polluting data sent to user pages when doing SSR. */
__puck?: {
/** User-set custom label for this component instance. */
label?: string;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Expect: every render path removes __puck before invoking Render.
rg -n -C 8 '__puck|<Render\b|Render\(' packages/core --glob '*.{ts,tsx}'

Repository: puckeditor/puck

Length of output: 22894


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Render-related files ---'
git ls-files packages/core | rg '(^|/)(Render|ServerRender|DropZone|data|Internal|types)(/|\\.)' | head -200

printf '%s\n' '--- Render definitions and call sites ---'
rg -n -C 12 'export (function|const) Render|function Render|<Render\b|renderComponent|Component\.render|propsWithSlots|strip.*puck|__puck' packages/core \
  --glob '*.{ts,tsx}' \
  --glob '!**/__tests__/**'

Repository: puckeditor/puck

Length of output: 40932


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in $(git ls-files packages/core | rg 'ServerRender/index\.tsx$|components/Render|lib/data/.*(render|strip)|components/DropZone/index\.tsx$|types/Internal\.ts'); do
  echo "--- $f ---"
  wc -l "$f"
  ast-grep outline "$f" 2>/dev/null | head -120 || true
done

Repository: puckeditor/puck

Length of output: 3369


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- ServerRender implementation ---'
sed -n '1,240p' packages/core/components/ServerRender/index.tsx

echo '--- Render exports and references ---'
rg -n -C 15 'export .*Render|function Render|const Render|<Render\b|Render\(' packages/core \
  --glob '*.{ts,tsx}' \
  --glob '!**/__tests__/**'

Repository: puckeditor/puck

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- Data transformation helpers ---'
rg -n -C 20 'strip|remove|omit|expandNode|flattenNode|propsWithSlots|slots|content' packages/core/lib packages/core/components \
  --glob '*.{ts,tsx}' \
  --glob '!**/__tests__/**' | head -1200

echo '--- Relevant type definitions ---'
sed -n '1,220p' packages/core/types/Data.tsx
sed -n '1,220p' packages/core/types/Internal.ts

Repository: puckeditor/puck

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- package scripts and available test configuration ---'
if [ -f package.json ]; then
  node - <<'JS'
const p = require('./package.json');
console.log(JSON.stringify({scripts:p.scripts, workspaces:p.workspaces}, null, 2));
JS
fi
find packages/core -maxdepth 3 -type f \( -name 'package.json' -o -name 'jest.config.*' -o -name 'vitest.config.*' \) -print

Repository: puckeditor/puck

Length of output: 1315


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- client Render ---'
sed -n '1,115p' packages/core/components/Render/index.tsx

echo '--- client DropZone render path ---'
sed -n '540,635p' packages/core/components/DropZone/index.tsx

echo '--- server SlotRender ---'
sed -n '1,100p' packages/core/components/SlotRender/server.tsx

echo '--- useSlots ---'
fd -i 'use-slots' packages/core --type f --exec sh -c 'echo "--- $1 ---"; sed -n "1,240p" "$1"' sh {}

echo '--- data types ---'
sed -n '1,180p' packages/core/types/Data.tsx

Repository: puckeditor/puck

Length of output: 10632


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- all direct spreads of root and item data ---'
rg -n -C 8 '\.\.\.(rootProps|data\.root|item|props|nodeProps|defaultedNode|renderItem)' \
  packages/core/components packages/core/lib \
  --glob '*.{ts,tsx}' \
  --glob '!**/__tests__/**'

echo '--- exact __puck references outside editor metadata consumers ---'
rg -n -C 6 '__puck' packages/core --glob '*.{ts,tsx}' --glob '!**/__tests__/**'

Repository: puckeditor/puck

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

files = [
    Path("packages/core/components/Render/index.tsx"),
    Path("packages/core/components/ServerRender/index.tsx"),
    Path("packages/core/components/DropZone/index.tsx"),
    Path("packages/core/components/SlotRender/server.tsx"),
    Path("packages/core/lib/use-slots.ts"),
    Path("packages/core/types/Data.tsx"),
]

needles = ("__puck", "rootProps", "item.props", "propsWithSlots", "Component.render", "config.root.render")
for path in files:
    print(f"--- {path} ---")
    lines = path.read_text().splitlines()
    for i, line in enumerate(lines, 1):
        if any(n in line for n in needles):
            lo, hi = max(1, i - 3), min(len(lines), i + 5)
            for j in range(lo, hi + 1):
                print(f"{j:4}: {lines[j-1]}")
            print()
PY

Repository: puckeditor/puck

Length of output: 7638


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read-only structural verifier for the documented invariant:
# report every object that is assembled immediately before a user render
# and whether that assembly explicitly omits the top-level __puck key.
python3 - <<'PY'
from pathlib import Path
import re

targets = [
    Path("packages/core/components/Render/index.tsx"),
    Path("packages/core/components/ServerRender/index.tsx"),
    Path("packages/core/components/DropZone/index.tsx"),
    Path("packages/core/components/SlotRender/server.tsx"),
]
patterns = [
    r"<(?:config\.)?root\.render",
    r"<Component\.render",
    r"<Component\.render",
]
for path in targets:
    lines = path.read_text().splitlines()
    print(f"--- {path} ---")
    for i, line in enumerate(lines):
        if any(re.search(p, line) for p in patterns):
            start = max(0, i - 18)
            block = "\n".join(lines[start:i+3])
            print(f"render at line {i+1}")
            print(block)
            print("explicit __puck omission:", bool(re.search(r"\b__puck\b", block)))
PY

Repository: puckeditor/puck

Length of output: 3378


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- root migration and call sites ---'
sed -n '1,110p' packages/core/lib/migrate.ts
rg -n -C 10 'migrate\(|RootDataWithProps|RootDataWithoutProps|root:\s*\{\s*__puck|__puck.*root|root.*__puck' packages/core packages --glob '*.{ts,tsx}' --glob '!**/node_modules/**' --glob '!**/dist/**' | head -1200

echo '--- root data fixtures containing metadata ---'
rg -n -C 8 '__puck|root:\s*\{' packages/core/components/ServerRender packages/core/components/Render packages/core/types packages/core/lib/data --glob '*.{ts,tsx}' | head -1200

Repository: puckeditor/puck

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
# Read-only verifier for the two RootData representations used by Render.
# It models only the object spreads in the checked source paths.
def client_or_server_root_props(root):
    return root["props"] if "props" in root else root

def rendered_props(root):
    root_props = client_or_server_root_props(root)
    return {**root_props, "puck": {}, "title": "", "editMode": False, "id": "puck-root"}

cases = {
    "new root metadata sibling": {
        "props": {"title": "x"},
        "__puck": {"label": "root"},
    },
    "legacy root metadata sibling": {
        "title": "x",
        "__puck": {"label": "root"},
    },
    "component metadata outside props": {
        "type": "A",
        "props": {"id": "a", "title": "x"},
        "__puck": {"label": "A"},
    },
}
for name, value in cases.items():
    if "type" in value:
        actual = {**value["props"], "puck": {}}
    else:
        actual = rendered_props(value)
    print(name, "=> __puck passed:", "__puck" in actual, actual)
PY

Repository: puckeditor/puck

Length of output: 507


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- migrate implementation ---'
sed -n '1,130p' packages/core/lib/migrate.ts

echo '--- migrate references ---'
rg -n -C 8 '\bmigrate\b' packages/core --glob '*.{ts,tsx}' --glob '!**/__tests__/**'

echo '--- RootData representation references ---'
rg -n -C 6 'RootDataWithProps|RootDataWithoutProps|RootData<' packages/core --glob '*.{ts,tsx}' --glob '!**/__tests__/**'

Repository: puckeditor/puck

Length of output: 16426


Strip __puck from root props before rendering.

migrate copies legacy root fields, including __puck, into root.props. Both Render implementations then spread rootProps into config.root.render, so root metadata reaches user components and SSR. Component, slot, and drop-zone metadata does not cross their render boundaries.

🤖 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/types/Data.tsx` around lines 10 - 14, Update both Render
implementations to remove the __puck metadata from rootProps before spreading
those props into config.root.render; preserve all other root props and keep
component, slot, and drop-zone rendering behavior unchanged.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/SidebarSection/index.tsx`:
- Around line 35-40: Reorder the JSX around InlineLabelEdit so Heading remains
the outer element and renders the editable label inside it. Preserve the
existing rank="2" and size="xs" props, and keep InlineLabelEdit responsible only
for the label content and editing behavior.
🪄 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: 8e9fc99e-a8c2-4c2e-a587-cd9dc46d1d6c

📥 Commits

Reviewing files that changed from the base of the PR and between fd948b2 and e1c40a8.

📒 Files selected for processing (2)
  • packages/core/components/SidebarSection/index.tsx
  • packages/core/reducer/actions/set-component-label.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/reducer/actions/set-component-label.ts

Comment thread packages/core/components/SidebarSection/index.tsx Outdated
@fasenderos

Copy link
Copy Markdown
Contributor Author

@FedericoBonel @chrisvxd can you review this PR? Thanks

@FedericoBonel

Copy link
Copy Markdown
Collaborator

Hey @fasenderos! Thanks for the contribution, I actually had some thoughts on this PR and how it should be implemented but you got ahead of me!

I have some ideas on the UI, but I think that would be easier picked up on my side since it would take some iterations with the rest of the team to get it done.

I'll give it a review when I get a moment, thanks again.

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.

Support user defined component labels by instance

2 participants