DOM References (Refs)

Access DOM elements directly using pp.ref and the pp-ref attribute. Useful for managing focus, media playback, or integrating third-party libraries.

Basic Ref Object

Create a reference object with pp.ref(). PulsePoint assigns the DOM element to the .current property when the component mounts.

Just like React: pp.ref() returns a mutable object { current: null }. Changing .current does not trigger a re-render.
focus-input.html
<div>
  <input pp-ref="{inputRef}" type="text" placeholder="I will be focused..." />
  
  <div class="mt-2">
    <button onclick="focusInput()">Click to Focus</button>
  </div>
</div>

<script type="text/pp">
  // 1. Create the ref container
  const inputRef = pp.ref(null);

  function focusInput() {
    // 2. Access the DOM element via .current
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }
</script>

Callback Refs (Dynamic Lists)

For lists or dynamic content, pass a function to pp-ref. The function receives the DOM element when mounted and null when unmounted.

dynamic-focus.html
<ul class="space-y-2">
  <template pp-for="item in items">
    <li key="{item.id}" class="flex gap-2">
      <span>{item.name}</span>
      
      <!-- Register specific inputs into a Map using a callback -->
      <input 
        pp-ref="{registerRef(item.id)}"
        type="text" 
        hidden="{editingId !== item.id}"
        value="{item.name}"
      />
      
      <button onclick="setEditingId(item.id)">Edit</button>
    </li>
  </template>
</ul>

<script type="text/pp">
  const [items, setItems] = pp.state([
    { id: 1, name: "Task A" },
    { id: 2, name: "Task B" }
  ]);
  const [editingId, setEditingId] = pp.state(null);

  // Store refs: Map<ID, HTMLElement>
  const itemRefs = new Map();

  // Curried function: ID -> (Element) -> Void
  const registerRef = (id) => (el) => {
    if (el) itemRefs.set(id, el);
    else itemRefs.delete(id); // Cleanup on unmount
  };

  // Effect: Auto-focus when entering edit mode
  pp.effect(() => {
    if (editingId && itemRefs.has(editingId)) {
      itemRefs.get(editingId).focus();
    }
  }, [editingId]);
</script>
Effect Next: Loop