Skip to content

Conversation

@stravo1
Copy link
Member

@stravo1 stravo1 commented Jan 6, 2026

This PR introduces block props and block client scripts (JS) and block data scripts (Py).

Each block now has three new properties: Block Props and Block Client Scripts and Block Data Scripts.

  • 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 scripts (both client and data scripts).

    There are two types of props:

    • static - Constant literal values.
    • dynamic - Derived from Data Scripts (both Page Data and Block Data).

    Props are not passed down to child blocks by default. However, users can explicitly choose which props should be propagated. Any prop that is marked to be passed down becomes accessible to all descendant blocks of the block that declares it. These props can also be used as dynamic values wherever dynamic values are supported, such as in Text blocks.

    Standard Block Props

    These are special type of block props which can be used in Components. Std. Block props can be declared on the root block of a component. They can be of various types such as string, number, boolean, arrays (string[]) and objects (Map<string, string>), unlike non-std. props which are always of type string. They differ from from non-std. props in two primary ways:

    • When a component is used in a Page, the std. props appear as user inputs on the Right Panel (provided the root block of the component is selected). Different types of std. props will show up as different inputs. This way different instances of a component can take different inputs and produce different results. Std. Props can also have default values which are used if the user does not provide any input to the component using std. prop inputs. Non-std. props are like variables which are declared and defined at the same time, while std. props are like parameters of a function (here the function is a component) which can take different values but can also fallback on default values if not provided.
    • Std. props are passed down by default.

    Std. props of type array and object can also be used as keys for Repeaters/Collections to loop over their values. In such cases, for std. prop of type object, all blocks - which are repeated - are assigned two default props named key and value which hold the value of the key-value pairs of the object being looped over. Same goes for std. prop of type array, and in such case there is only one default prop named item.

Adding block props:

Screenshot 2026-01-06 at 11 01 11 AM

Adding std. props to root of component:

Screenshot 2026-01-06 at 10 41 29 AM

Different types of std. props:

Screenshot 2026-01-06 at 10 41 40 AM

Some std. props with default values (here Name and Type are same, that is for demonstration purpose) :

Screenshot 2026-01-06 at 10 39 53 AM

How they appear when used in a page:

Screenshot 2026-01-06 at 10 54 41 AM
  • Block Data Script:
    These are Python code snippets associated with an individual block, unlike Data Script which applies to the entire page. Block data scripts can be used like Page Data scripts to get dynamic values during SSR.

    Within Block Data Script, two special keywords are available:

    • block: Similar to data in page data scripts, we have block in block data scripts. It can be used to assign dynamic values which can be used in the block. Also all block data are passed down, so once a block assigns a dynamic value, it is accessible to all its successors. A successor block can re-assign a dynamic value in it's own block data script in which case the nearest assignment of the value is used, similar to how block scoping/variable shadowing works.

      block.sample_dynamic_value = "Hello world!"
    • props: Provides access to the properties passed to the block.

Assigning block data script:

Screenshot 2026-01-06 at 10 58 31 AM Screenshot 2026-01-06 at 10 58 37 AM Screenshot 2026-01-06 at 10 58 49 AM

Using the cumulative toggle to view all the block data being passed to the current block.

Screenshot 2026-01-06 at 10 59 01 AM
  • Block Client 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.

Some examples:

  • "Item Card" takes only the item name and prepares the entire item card (SSR):
Screen.Recording.2026-01-06.at.11.14.35.AM.mov
  • "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.
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

used the rawStylesSection as a template to create the props section to maintain consistency but forgot to update the name
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
blocks which are children of such repeater get some default props to access the looping items
this is because props which are dynamic and depend on loop variables as in for eg {{ key_item.val }} go out of the loop block {% for item in arr %} ... {% endfor %} when all scripts are added in one place
- 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
@codecov
Copy link

codecov bot commented Jan 6, 2026

Codecov Report

❌ Patch coverage is 46.09053% with 131 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.64%. Comparing base (ab746fc) to head (52fb4f0).

Files with missing lines Patch % Lines
...ilder/builder/doctype/builder_page/builder_page.py 42.60% 128 Missing ⚠️
builder/utils.py 84.21% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #459      +/-   ##
===========================================
- Coverage    49.26%   48.64%   -0.63%     
===========================================
  Files           28       28              
  Lines         2176     2393     +217     
===========================================
+ Hits          1072     1164      +92     
- Misses        1104     1229     +125     

☔ 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.

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.

2 participants