ElementFocus

Reactive tracking of focus state on an element. Detects when an element gains or loses focus.

Loading demo...

Usage

angular-ts
import { Component, viewChild, ElementRef } from '@angular/core';
import { elementFocus } from '@signality/core';

@Component({
  template: `
    <input #input [class.focused]="focused()" />
    <p>{{ focused() ? 'Input is focused' : 'Input is not focused' }}</p>
  `,
})
export class FocusDemo {
  readonly input = viewChild<ElementRef>('input');
  readonly focused = elementFocus(this.input); 
}

Parameters

ParameterTypeDescription
targetMaybeElementSignal<HTMLElement>Target element to track
optionsElementFocusOptionsOptional configuration (see Options below)

Options

The ElementFocusOptions extends CreateSignalOptions<boolean> and WithInjector:

OptionTypeDefaultDescription
equalValueEqualityFn<boolean>-Custom equality function (see more)
debugNamestring-Debug name for the signal (development only)
focusVisiblebooleanfalseTrack focus using the :focus-visible pseudo-class. The browser uses heuristics to determine when focus should be visually indicated (e.g., keyboard navigation, programmatic focus). See MDN: :focus-visible for details.
injectorInjector-Optional injector for DI context

Return Value

Returns a Signal<boolean> containing true when the element has focus, false otherwise.

Examples

Focus ring

angular-ts
import { Component, viewChild, ElementRef } from '@angular/core';
import { elementFocus } from '@signality/core';

@Component({
  template: `
    <button #btn [class.focus-ring]="focused()">
      Click or Tab to me
    </button>
  `,
})
export class FocusRing {
  readonly btn = viewChild<ElementRef>('btn');
  readonly focused = elementFocus(this.btn, { focusVisible: true });
}

Form field with label animation

angular-ts
import { Component, viewChild, ElementRef, signal, computed } from '@angular/core';
import { elementFocus } from '@signality/core';

@Component({
  template: `
    <div class="form-field" [class.active]="isActive()">
      <label [class.floating]="isActive()">Email</label>
      <input #input [(ngModel)]="value" />
    </div>
  `,
})
export class FloatingLabel {
  readonly input = viewChild('input', { read: ElementRef });
  readonly isFocused = elementFocus(this.input);
  readonly value = signal('');
  
  readonly isActive = computed(() => 
    this.isFocused() || this.value().length > 0
  );
}

SSR Compatibility

On the server, the signal initializes with false.

Type Definitions

typescript
type ElementFocusOptions = CreateSignalOptions<boolean> &
  WithInjector & {
  readonly focusVisible?: boolean;
};

function elementFocus(
  target: MaybeElementSignal<HTMLElement>,
  options?: ElementFocusOptions
): Signal<boolean>;
Edit this page on GitHub Last updated: Mar 19, 2026, 23:28:23