sercrod

@focus

Summary

@focus attaches a handler to the native focus event on an element. The expression on @focus is evaluated when that element receives focus. Typical uses include highlighting a field while it is active, resetting error messages when the user returns to a control, or tracking which part of a form is currently focused.

@focus is part of the general event handler family (for example @click, @input, @blur) and follows the same evaluation rules as other event directives that use the Sercrod event prefix.

Basic example

Tracking whether an input is currently focused:

<serc-rod id="app" data='{
  "profile": { "name": "" },
  "focus":   { "name": false }
}'>
  <label>
    Name:
    <input type="text"
           :value="profile.name"
           @focus="focus.name = true"
           @blur="focus.name = false">
  </label>

  <p *if="focus.name">
    This field is currently focused.
  </p>
</serc-rod>

Behavior:

Behavior

Core rules:

Evaluation timing

@focus participates in Sercrod’s normal event lifecycle:

The actual focus event still fires according to browser rules; Sercrod only attaches its handler to that event and evaluates your expression when it occurs.

Execution model

Conceptually, the runtime behaves as follows for @focus:

  1. During rendering, Sercrod encounters an attribute whose name starts with the configured events.prefix and whose event name portion is focus.

  2. It splits the attribute name into:

    • The event name focus.
    • A set of modifiers (for example prevent, stop, once, capture, passive, update, noupdate).
  3. Sercrod reads the attribute value as an expression string.

  4. Sercrod constructs listener options:

    • capture is true if the name includes the capture modifier.
    • passive is true if the name includes the passive modifier.
    • once is true if the name includes the once modifier.
  5. Sercrod creates a handler function that:

    • Applies generic modifiers:

      • If the name includes prevent, it calls event.preventDefault() before anything else.
      • If the name includes stop, it calls event.stopPropagation().
    • Constructs a proxy scope in which:

      • $event and $e refer to the native focus event.
      • el and $el refer to the focused element.
      • Other reads first consult the Sercrod scope; if a name is not found there, the proxy falls back to the global window.
    • Evaluates the expression with this proxy scope using the event evaluator.

    • Catches and logs any errors so that one failing handler does not break other updates.

  6. After the expression runs, Sercrod decides how to update the host:

    • It consults the configured set events.non_mutating to see whether the event should cause a re-render by default.
    • The update modifier forces a re-render even if the event is configured as non mutating.
    • The noupdate modifier suppresses updates even if the event is normally treated as mutating.
    • For focus, this means you can opt into or out of re-rendering per handler by using these modifiers.
  7. Sercrod either triggers a lightweight children update or a host level update according to its update strategy and then returns control to the browser.

Finally, Sercrod records the handler in an internal map so that subsequent re-renders can remove or replace it cleanly.

Use with form fields and UI state

@focus is most commonly used with form controls and interactive UI components:

Use with conditionals and loops

Because @focus is an event directive on the element itself, it composes naturally with structural directives:

Sercrod-specific notes and restrictions

Best practices

Additional examples

Highlighting the currently focused row in a table:

<serc-rod id="app" data='{
  "rows": [
    { "id": 1, "name": "Alpha" },
    { "id": 2, "name": "Beta" }
  ],
  "focused_id": null
}'>
  <table>
    <tbody>
      <tr *for="row of rows"
          :class="row.id === focused_id ? 'is-focused-row' : ''">
        <td>
          <input type="text"
                 :value="row.name"
                 @focus="focused_id = row.id"
                 @blur="focused_id = null">
        </td>
      </tr>
    </tbody>
  </table>
</serc-rod>

Showing contextual helper text only while a field has focus:

<serc-rod id="app" data='{
  "focus": { "password": false }
}'>
  <label>
    Password:
    <input type="password"
           @focus="focus.password = true"
           @blur="focus.password = false">
  </label>

  <p *if="focus.password">
    Use at least 12 characters, mixing letters, numbers, and symbols.
  </p>
</serc-rod>

Notes