import { html, PropertyValueMap, unsafeCSS } from "lit";
import { property, query, queryAssignedElements } from "lit/decorators.js";
import eleStyle from "./f-switch.scss?inline";
import globalStyle from "./f-switch-global.scss?inline";
import { FRoot } from "../../mixins/components/f-root/f-root";
import { FDiv } from "../f-div/f-div";
import { flowElement } from "./../../utils";
import { injectCss } from "@cldcvr/flow-core-config";
injectCss("f-switch", globalStyle);
export type FSwitchState = "primary" | "default" | "success" | "warning" | "danger";
export type FSwitchCustomEvent = {
value: boolean;
};
@flowElement("f-switch")
export class FSwitch extends FRoot {
/**
* css loaded from scss file
*/
static styles = [unsafeCSS(eleStyle), unsafeCSS(globalStyle), ...FDiv.styles];
/**
* @attribute Value of a switch defines if it is on or off.
*/
@property({ reflect: true, type: String })
value?: boolean = false;
/**
* @attribute States are used to communicate purpose and connotations.
*/
@property({ reflect: true, type: String })
state?: FSwitchState = "default";
/**
* @attribute f-switch can have 2 sizes.
*/
@property({ reflect: true, type: String })
size?: "small" | "medium";
/**
* @attribute f-switch can have 2 sizes.
*/
@property({ reflect: true, type: Boolean })
disabled?: boolean = false;
@query(".switch-slots")
switchSlots!: FDiv;
/**
* @attribute assigned elements inside slot label
*/
@queryAssignedElements({ slot: "label" })
_labelNodes!: NodeListOf;
/**
* @attribute assigned elements inside slot description
*/
@queryAssignedElements({ slot: "subtitle" })
_subtitleNodes!: NodeListOf;
/**
* @attribute assigned elements inside slot help
*/
@queryAssignedElements({ slot: "icon-tooltip" })
_iconTooltipNodes!: NodeListOf;
/**
* has label slot
*/
get hasLabel() {
return this._labelNodes.length > 0;
}
/**
* has subtitle slot
*/
get hasSubtitle() {
return this._subtitleNodes.length > 0;
}
/**
* has icon-tooltip slot
*/
get hasIconTooltip() {
return this._iconTooltipNodes.length > 0;
}
/**
* emit event.
*/
handleInput(e: InputEvent) {
e.stopPropagation();
this.value = !this.value;
const event = new CustomEvent("input", {
detail: {
value: this.value
},
bubbles: true,
composed: true
});
this.dispatchEvent(event);
}
render() {
if (!this.value) {
this.value = false;
}
/**
* Final html to render
*/
return html`
`;
}
protected updated(changedProperties: PropertyValueMap | Map) {
super.updated(changedProperties);
if (!this.hasLabel && !this.hasIconTooltip && !this.hasSubtitle) {
this.switchSlots.style.display = "none";
}
}
}
/**
* Required for typescript
*/
declare global {
interface HTMLElementTagNameMap {
"f-switch": FSwitch;
}
}