Skip to content

Conversation

@stravo1
Copy link
Member

@stravo1 stravo1 commented Oct 20, 2025

This PR introduces block-level props and block-specific JavaScript scripts.

Each block now has two new properties: Block Script and Props.

  • Block Script:
    These are JavaScript code snippets associated with an individual block, unlike Client Scripts which apply to an entire page.
    Block Scripts make it easier to manage reactivity by eliminating the need for multiple Client Scripts and by localizing logic to the block itself.

    Within a Block Script, two special keywords are available:

    • this: Refers directly to the DOM node corresponding to the block.
      Example:

      this.addEventListener('click', ...)

      attaches an event listener to the block itself.

    • props: Provides access to the properties passed to the block. Props are discussed below.

  • Props:
    Props work similarly to those found in component-based JavaScript frameworks such as Vue or React. They serve as an interface between the “outside world” and the block script.

    There are three types of props:

    • static - Constant literal values.
    • dynamic - Derived from Data Scripts.
    • inherited - Passed down from parent blocks.

As mentioned earlier, props can be accessed within the Block Script using the props keyword.
They can also be used as "Dynamic values" along side data from Data Scripts. In a component, Repeaters/Collections can use array/object std. props (discussed below), and in such cases all children of repeater/collection block receive default props named "item" in case of array or "key" and "value in case of objects. These default props behave as any other prop and thus can also in turn be used as Dynamic value.

Screen.Recording.2025-11-26.at.11.17.27.PM.mp4

This addition brings some of the benefits of component-based frameworks into the builder.
By associating scripts and props directly with blocks (and therefore components), it becomes easier to create reusable components and component libraries.

Standard Props for Components:

Based on block props and block scripts, this PR also introduces "Standard Props for Components". Root block of each component can have special block props called "Standard Props". These props act as an interface between the component and the user. These props can be of various types (unlike normal block props which are always of type string) such as string, number, boolean, select, array and object. When a component with std. props is used in a page, the user gets a form where he/she can fill out the value for those std. props.
For eg:

  • "Profile Card" component can have std. props like Name, Description, Image URL, etc. When this component is used in a page, the user simply fills those inputs and the Profile Card is ready.
Screenshot 2025-11-26 at 11 05 25 PM
Screen.Recording.2025-11-26.at.11.06.33.PM.mp4
  • "Navbar" component can have a std. prop named Links in which user puts a list of title and urls.
Screen.Recording.2025-11-26.at.11.08.47.PM.mp4
  • "Weather Card" can take just the location and show details automatically
Screen.Recording.2025-11-27.at.12.11.44.PM.mp4
@codecov
Copy link

codecov bot commented Oct 20, 2025

Codecov Report

❌ Patch coverage is 37.03704% with 102 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.08%. Comparing base (dd91305) to head (393c83d).

Files with missing lines Patch % Lines
...ilder/builder/doctype/builder_page/builder_page.py 37.03% 102 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #423      +/-   ##
===========================================
- Coverage    49.19%   48.08%   -1.12%     
===========================================
  Files           28       28              
  Lines         2179     2325     +146     
===========================================
+ Hits          1072     1118      +46     
- Misses        1107     1207     +100     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
used the rawStylesSection as a template to create the props section to maintain consistency but forgot to update the name
@surajshetty3416 surajshetty3416 marked this pull request as draft October 27, 2025 05:33
previously, block props relied on blockIds to manage inheritance. This caused issues when using components - each component instance generated new blockIds for its blocks, breaking prop references that still pointed to the original component blockIds. maintaining and updating these blockId dependencies became increasingly complex and error-prone.

this commit removes the dependency on blockIds entirely.
Props are now identified by their names, and a stack-based approach is used to resolve inherited values. the system now behaves similarly to variable scoping in programming languages - where inherited props take the value of the nearest ancestor with the same prop name in the faimly tree (block scoping in programming)
green shows that inherited prop is valid, i.e., there is an ancestor who has that prop and can be inherited while red shows that the inherited prop is invalid and no ancestor was found having that prop
have NOT intentionally put all script content in one script tag as if here is an error in one of the blockScripts then the remaining/following blockScripts also fail to execute
@stravo1
Copy link
Member Author

stravo1 commented Nov 9, 2025

Remaining features:

  • Standard props in Component Root Block
  • Reuse Block Scripts for Components instead of creating extra <script> tags (next iter)
  • Autocomplete in Block Script for "this" and "props" (next iter)
@stravo1 stravo1 marked this pull request as ready for review December 7, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants