Skip to content

feat: Custom Slot - fragment-backed reusable content with instance-local fields#5677

Open
Yxnnxck wants to merge 1 commit intowebstudio-is:mainfrom
Yxnnxck:customSlot
Open

feat: Custom Slot - fragment-backed reusable content with instance-local fields#5677
Yxnnxck wants to merge 1 commit intowebstudio-is:mainfrom
Yxnnxck:customSlot

Conversation

@Yxnnxck
Copy link
Copy Markdown

@Yxnnxck Yxnnxck commented Apr 4, 2026

Description

This PR introduces a new core component: Custom Slot, enabling reusable synced content with per-instance field values.

It builds on top of:

The goal is to bridge the gap between current Slots and a full component system by introducing:

  • explicit structure (Fragment-backed root)
  • instance-local values
  • shared schema
  • scoped data injection

Summary

Custom Slot allows creating reusable content blocks that behave like real components:

  • shared structure
  • per-instance configurable fields
  • isolated scope
  • predictable rendering

Unlike current Slots, this removes implicit structure (e.g. "first child is special") and introduces a proper internal model.


Motivation

Current limitations:

  • Slots only support structure reuse, but not proper configuration
  • No clear component abstraction (Webstudio Components #2529)
  • No way to define per-instance fields
  • Reuse patterns are fragile or implicit

This PR moves Webstudio toward a real component model.


What changed

Implemented

1. New core component: ws:customSlot

  • Core metas + templates added
  • Insertable in project
  • SDK helpers introduced

2. Data model redesign

Invariant:

Custom Slot -> Fragment (internal)

  • Slot instance:
    • owns __customSlotValues
  • Fragment root:
    • owns __customSlotSchema
  • Derived component object

3. Rendering & traversal

  • Fragment used as hidden structural root
  • Navigator only reacts to visible children
  • Copy/paste + tree logic updated

4. Local fields system

  • Named fields defined in Settings panel
  • Shared schema, local values
  • UI supports:
    • inline editing
    • binding
    • rename/delete

5. Structured bindable values

  • Expression-based values (not just strings)
  • Evaluated in owner scope
  • Dynamic component object creation

6. Scope isolation

  • Slot owner → has outer scope access
  • Slot children → only:
    • global scope
    • injected component

7. UX cleanup

Internal variables hidden from:

  • settings scopes
  • page scopes
  • resource scopes
  • binding popovers

8. Not implemented


Why this approach

  • Introduces explicit content root
  • Keeps reusable structure stable
  • Enables component-like mental model
  • Avoids leaking internal implementation details

Steps for reproduction

  1. Insert Custom Slot
  2. Add multiple children inside
  3. Define fields in Settings panel
  4. Create multiple instances
  5. Change field values per instance

Expected:

  • structure stays synced
  • values differ per instance

Code Review

  • hi @kof, I need you to do
    • conceptual review (architecture, feature-correctness)
    • detailed review (read every line)
    • test it on preview

Before requesting a review

  • made a self-review
  • added inline comments where things may be not obvious
    (I didn't add Comments if needed I can do so but I hope Code is clear)

Before merging

  • tested locally and on preview environment (preview dev login: 0000)
  • updated test cases document
  • added tests
  • env variables updated (if needed)

@Yxnnxck Yxnnxck changed the title Custom Slot: fragment-backed reusable content with instance-local fields feat: Custom Slot: fragment-backed reusable content with instance-local fields Apr 4, 2026
@Yxnnxck Yxnnxck changed the title feat: Custom Slot: fragment-backed reusable content with instance-local fields feat: Custom Slot - fragment-backed reusable content with instance-local fields Apr 4, 2026
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.

1 participant