import { booleanAttribute, ChangeDetectionStrategy, Component, input, model, ViewEncapsulation, } from "@angular/core"; import { setupModelHook } from "../../core/setupModelHook"; @Component({ selector: "sd-switch", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [], host: { "[attr.data-sd-on]": "value()", "[attr.data-sd-disabled]": "disabled()", "[attr.data-sd-inline]": "inline()", "[attr.data-sd-inset]": "inset()", "[attr.data-sd-size]": "size()", "[attr.data-sd-theme]": "theme()", "[attr.tabindex]": "'0'", "(click)": "onClick($event)", "(keydown)": "onKeydown($event)", }, template: `
`, styles: [ /* language=SCSS */ ` @use "sass:map"; @use "../../../scss/commons/variables"; sd-switch { display: block; padding: var(--gap-sm) 0; border: 1px solid transparent; vertical-align: top; cursor: pointer; > div { height: var(--line-height); width: calc(var(--line-height) * 2 - var(--gap-xs)); padding: calc(var(--gap-xs) / 2); border-radius: calc(var(--line-height) / 2); text-align: left; background: var(--theme-gray-lighter); > div { display: inline-block; width: calc(var(--line-height) - var(--gap-xs)); height: calc(var(--line-height) - var(--gap-xs)); border-radius: 100%; background: var(--control-color); transition: transform var(--animation-duration); } } &[data-sd-on="true"] { > div { background: var(--theme-success-default); > div { transform: translateX(100%); } } } &[data-sd-inline="true"] { display: inline-block; padding: 0; border: none; } &[data-sd-inset="true"] { border: none; } &[data-sd-size="sm"] { padding: var(--gap-sm) 0; } &[data-sd-size="lg"] { padding: var(--gap-default) 0; } @each $key, $val in map.get(variables.$vars, theme) { &[data-sd-theme="#{$key}"] { &[data-sd-on="true"] { > div { background: var(--theme-#{$key}-default); } } } } &[data-sd-disabled="true"] { > div { opacity: 0.5; > div { background: var(--theme-gray-default); } } } } `, ], }) export class SdSwitch { value = model(false); canChangeFn = input<(item: boolean) => boolean | Promise>(() => true); disabled = input(false, { transform: booleanAttribute }); inline = input(false, { transform: booleanAttribute }); inset = input(false, { transform: booleanAttribute }); size = input<"sm" | "lg">(); theme = input< "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray" >(); constructor() { setupModelHook(this.value, this.canChangeFn); } onClick(event: Event) { event.preventDefault(); event.stopPropagation(); if (this.disabled()) return; this.value.update((v) => !v); } onKeydown(event: KeyboardEvent) { if (event.key === " ") { event.preventDefault(); event.stopPropagation(); if (this.disabled()) return; this.value.update((v) => !v); } } }