Spread Attributes

Apply multiple attributes dynamically using the pp-spread directive. This is essential for building reusable components.

Basic Usage

Instead of writing attributes inline, you can define them in a state object and "spread" them onto an element.

ui-button.html
<div class="flex gap-4">
  <!-- Apply all attributes from the object -->
  <button pp-spread="{...primaryBtn}">
    Primary Action
  </button>

  <button pp-spread="{...secondaryBtn}">
    Secondary Action
  </button>
</div>

<script type="text/pp">
  const [primaryBtn] = pp.state({
    type: "submit",
    class: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700",
    "aria-label": "Submit Form"
  });

  const [secondaryBtn] = pp.state({
    type: "button",
    class: "px-4 py-2 border bg-transparent rounded hover:bg-gray-100",
    disabled: true
  });
</script>

Overriding & Merging

PulsePoint uses standard JavaScript object syntax. You can spread a base configuration and override specific properties inline.

Order Matters: Properties are applied from left to right. If you spread `...defaults` before a specific key, the specific key takes precedence (overrides).
custom-input.html
<form>
  <!-- 1. Spread default props -->
  <!-- 2. Override 'placeholder' and add specific ID -->
  <input 
    pp-spread="{ ...defaultInput, placeholder: 'Enter username', id: 'user-field' }" 
  />

  <!-- Different placeholder, same base styles -->
  <input 
    pp-spread="{ ...defaultInput, placeholder: 'Enter password', type: 'password' }" 
  />
</form>

<script type="text/pp">
  const [defaultInput] = pp.state({
    type: "text",
    class: "w-full border p-2 mb-2 rounded focus:ring-2 ring-blue-500",
    autocomplete: "off"
  });
</script>

Dynamic Updates

To update spread attributes reactively, simply update the state object.

toggle-state.html
<div>
  <input pp-spread="{config}" />
  
  <div class="mt-4 space-x-2">
    <button onclick="toggleDisabled()">Toggle Disabled</button>
    <button onclick="toggleError()">Toggle Error</button>
  </div>
  
  <p class="text-xs mt-2 text-muted-foreground">Config: {JSON.stringify(config)}</p>
</div>

<script type="text/pp">
  const [config, setConfig] = pp.state({
    type: "text",
    placeholder: "Dynamic input...",
    disabled: false,
    class: "border p-2 rounded"
  });

  function toggleDisabled() {
    // Spread existing config, flip disabled boolean
    setConfig({ ...config, disabled: !config.disabled });
  }

  function toggleError() {
    // Conditionally change the class
    const isError = !config.class.includes("border-red-500");
    setConfig({
      ...config,
      class: isError ? "border p-2 rounded border-red-500 bg-red-50" : "border p-2 rounded"
    });
  }
</script>
Loop Next: Text Interpolation