1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +00:00
Files
browser/libs/components/src/toggle-group/toggle.component.ts
Oscar Hinton ff7b625851 [CL-946] Migrate ToggleGroup to OnPush (#17718)
Migrates the ToggleGroup and Toggle components to use OnPush.
2025-12-05 13:06:03 +01:00

110 lines
2.9 KiB
TypeScript

import {
afterNextRender,
ChangeDetectionStrategy,
Component,
computed,
contentChild,
ElementRef,
inject,
input,
signal,
viewChild,
} from "@angular/core";
import { BadgeComponent } from "../badge";
import { ToggleGroupComponent } from "./toggle-group.component";
let nextId = 0;
@Component({
selector: "bit-toggle",
templateUrl: "./toggle.component.html",
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
tabindex: "-1",
"[class]": "hostClasses",
},
})
export class ToggleComponent<TValue> {
protected readonly id = "bit-toggle-" + nextId++;
private readonly groupComponent = inject(ToggleGroupComponent<TValue>);
readonly value = input.required<TValue>();
protected readonly labelContent = viewChild<ElementRef<HTMLSpanElement>>("labelContent");
protected readonly badgeElement = contentChild(BadgeComponent);
protected readonly hasBadge = computed(() => !!this.badgeElement());
protected readonly labelTitle = signal<string | null>(null);
constructor() {
// Set label title after view is initialized
afterNextRender(() => {
const labelText = this.labelContent()?.nativeElement.innerText;
if (labelText) {
this.labelTitle.set(labelText);
}
});
}
protected readonly name = this.groupComponent.name;
readonly selected = computed(() => this.groupComponent.selected() === this.value());
protected handleInputChange() {
this.groupComponent.onInputInteraction(this.value());
}
protected readonly hostClasses = ["tw-group/toggle", "tw-flex", "tw-min-w-16"];
protected readonly inputClasses = [
"tw-peer/toggle-input",
"tw-appearance-none",
"tw-outline-none",
];
protected readonly labelClasses = [
"tw-h-full",
"tw-w-full",
"tw-flex",
"tw-items-center",
"tw-justify-center",
"tw-gap-1.5",
"!tw-font-medium",
"tw-leading-5",
"tw-transition",
"tw-text-center",
"tw-text-sm",
"tw-border-primary-600",
"!tw-text-primary-600",
"tw-border-solid",
"tw-border-y",
"tw-border-r",
"tw-border-l-0",
"tw-cursor-pointer",
"hover:tw-bg-hover-default",
"group-first-of-type/toggle:tw-border-l",
"group-first-of-type/toggle:tw-rounded-s-full",
"group-last-of-type/toggle:tw-rounded-e-full",
"peer-focus-visible/toggle-input:tw-outline-none",
"peer-focus-visible/toggle-input:tw-ring",
"peer-focus-visible/toggle-input:tw-ring-offset-2",
"peer-focus-visible/toggle-input:tw-ring-primary-600",
"peer-focus-visible/toggle-input:tw-z-10",
"peer-focus-visible/toggle-input:tw-bg-primary-600",
"peer-focus-visible/toggle-input:tw-border-primary-600",
"peer-focus-visible/toggle-input:!tw-text-contrast",
"peer-checked/toggle-input:tw-bg-primary-600",
"peer-checked/toggle-input:tw-border-primary-600",
"peer-checked/toggle-input:!tw-text-contrast",
"tw-py-1.5",
"tw-px-3",
// Fix for bootstrap styles that add bottom margin
"!tw-mb-0",
];
}