Components
Components in PulsePoint allow you to split your UI into independent, reusable pieces. Each component has its own isolated scope, state, and logic.
Basic Structure
A component is defined by the pp-component attribute. Any state declared inside this element is scoped to it and will not leak to the global scope or other components.
<div pp-component="counter">
<h3>Counter Component</h3>
<p>Count: {count}</p>
<button onclick="setCount(count + 1)">+</button>
<button onclick="setCount(count - 1)">-</button>
<script>
const [count, setCount] = pp.state(0);
</script>
</div>
Backend Integration
PulsePoint is designed to work with HTML generated by backends like PHP, Node, or Python. When using component abstraction layers (like custom JSX parsers or Blade components), you must follow specific rules to ensure scope and props are handled correctly.
1. Scope Definition
When your backend renders a component that relies on variables from a Parent, you must hint to PulsePoint where the parent scope begins using comments.
<!-- pp-scope:app -->
<div pp-component="card" title="{parentTitle}">
...
</div>
<!-- /pp-scope -->
2. Compiler Rule: Attribute Casing
If you are building a JSX-like compiler or backend helper, you must transform camelCase props into kebab-case attributes.
Browsers force all HTML attributes to lowercase. If you render userName="...", the browser sees username. PulsePoint expects kebab-case in the HTML to correctly map back to camelCase variables in JavaScript.
<div pp-component="User" userName="{name}">
<div pp-component="User" user-name="{name}">
Props & Data Flow
Data flows down. Parents pass data to children via HTML attributes (in kebab-case). The child accesses these attributes as variables (in camelCase) within its own scope.
<div pp-component="app">
<!-- pp-scope:app -->
<div
pp-component="user-card"
user-name="{selectedUser.name}"
user-role="{selectedUser.role}"
>
<!-- Inside user-card: Access variables as camelCase -->
<div class="card">
<h3>{userName}</h3>
<span>{userRole}</span>
</div>
</div>
<!-- /pp-scope -->
<script>
const [selectedUser] = pp.state({ name: 'Alice', role: 'Admin' });
</script>
</div>
Passing Children
PulsePoint fully supports the "Children" pattern found in frameworks like React. You can nest content inside a component tag, and that content will be rendered by the component, preserving the parent's data structure where necessary.
<div pp-component="Card">
<!-- pp-scope:app -->
<div class="card-content">
<!-- This content is projected from the parent -->
<h3>{dynamicTitle}</h3>
<p>This content was projected into the component.</p>
</div>
<!-- /pp-scope -->
</div>