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:

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

@stravo1
Copy link
Member Author

stravo1 commented Oct 20, 2025

WIP

@codecov
Copy link

codecov bot commented Oct 20, 2025

Codecov Report

❌ Patch coverage is 20.93023% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.22%. Comparing base (bdecddd) to head (fec31f3).
⚠️ Report is 24 commits behind head on develop.

Files with missing lines Patch % Lines
...ilder/builder/doctype/builder_page/builder_page.py 20.93% 34 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #423      +/-   ##
===========================================
- Coverage    47.88%   47.22%   -0.67%     
===========================================
  Files           26       26              
  Lines         1629     1673      +44     
===========================================
+ Hits           780      790      +10     
- Misses         849      883      +34     

☔ 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
  • Autocomplete in Block Script for "this" and "props"

- getPropValue and getValueForInheritedProp now returns default values for std. props in specific conditions
- defaultValue in StringOptions updates properly
- No dynamic values message shown in required conditions
- removing defaultValue from standardOptions and moving it to standardOptions.options
this trades off  slightly more perfomance and memory overhead for cleaner and more stable code and also better readability
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