Atomic Angular — Doc interne

Checkbox

A native checkbox wrapped in an accessible label, with an indeterminate visual state and Signal Forms integration.

Checkbox wraps a native <input type="checkbox"> inside an accessible <label>, with built-in support for a secondary hint line and an indeterminate ("mixed") visual state.

Minimal example

Two-way bound checked state
sample.component.ts
import { Component, signal } from "@angular/core";
import { CheckboxComponent } from "@sinequa/galactik";

@Component({
  selector: "sample-component",
  imports: [CheckboxComponent],
  template: `<checkbox [(checked)]="acceptTerms">Accept terms and conditions</checkbox>`,
})
export class SampleComponent {
  acceptTerms = signal(false);
}

Recipes

Indeterminate state, driven from a "select all" parent

indeterminate is purely visual/AT-facing — it never changes checked, and clicking still toggles checked from whatever value it currently holds.

A parent checkbox summarizing a list's selection
select-all.component.ts
import { Component, computed, signal } from "@angular/core";
import { CheckboxComponent } from "@sinequa/galactik";

interface Item {
  id: string;
  label: string;
  selected: boolean;
}

@Component({
  selector: "select-all-list",
  imports: [CheckboxComponent],
  template: `
    <checkbox
      [checked]="allSelected()"
      [indeterminate]="someSelected() && !allSelected()"
      (checkedChange)="toggleAll($event)">
      Select all
    </checkbox>
    <div class="flex flex-col gap-2 pl-4">
      @for (item of items(); track item.id) {
        <checkbox [checked]="item.selected" (checkedChange)="toggle(item.id, $event)">
          {{ item.label }}
        </checkbox>
      }
    </div>
  `,
})
export class SelectAllListComponent {
  items = signal<Item[]>([
    { id: "1", label: "Document A", selected: false },
    { id: "2", label: "Document B", selected: true },
    { id: "3", label: "Document C", selected: false },
  ]);

  allSelected = computed(() => this.items().every((i) => i.selected));
  someSelected = computed(() => this.items().some((i) => i.selected));

  toggle(id: string, selected: boolean) {
    this.items.update((items) => items.map((i) => (i.id === id ? { ...i, selected } : i)));
  }

  toggleAll(selected: boolean) {
    this.items.update((items) => items.map((i) => ({ ...i, selected })));
  }
}

Options

Prop

Type

Pitfalls

What's next

On this page