import { html, PropertyValueMap, unsafeCSS } from "lit"; import { property, query } from "lit/decorators.js"; import eleStyle from "./f-radio.scss?inline"; import globalStyle from "./f-radio-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-radio", globalStyle); export type FRadioState = "primary" | "default" | "success" | "warning" | "danger"; export type FRadioCustomEvent = { value: string; }; @flowElement("f-radio") export class FRadio extends FRoot { /** * css loaded from scss file */ static styles = [unsafeCSS(eleStyle), unsafeCSS(globalStyle), ...FDiv.styles]; /** * @attribute Value of a radio defines if it is selected or not */ @property({ reflect: true, type: String }) value?: "selected" | "unselected" = "unselected"; /** * @attribute States are used to communicate purpose and connotations. */ @property({ reflect: true, type: String }) state?: FRadioState = "default"; /** * @attribute f-radio can have 2 sizes. */ @property({ reflect: true, type: String }) size?: "small" | "medium"; /** * @attribute */ @property({ reflect: true, type: Boolean }) disabled?: boolean = false; @query(".slot-wrapper") slotWrapper!: FDiv; /** * emit event on click */ handleClick(e: MouseEvent) { if (this.value === "unselected") { e.stopPropagation(); const event = new CustomEvent("input", { detail: { value: "selected" }, bubbles: true, composed: true }); this.value = "selected"; this.dispatchEvent(event); } } render() { /** * Final html to render */ return html` `; } protected updated(changedProperties: PropertyValueMap | Map): void { super.updated(changedProperties); this.checkSlots(); } checkSlots() { const labelSlots = this.shadowRoot?.querySelectorAll( "slot[name='label'],slot[name='icon-tooltip'],slot[name='subtitle']" ); let displaySlotWrapper = false; labelSlots?.forEach(slot => { if (slot.assignedNodes().length > 0) { displaySlotWrapper = true; } }); if (!displaySlotWrapper) { this.slotWrapper.style.display = "none"; } } } /** * Required for typescript */ declare global { interface HTMLElementTagNameMap { "f-radio": FRadio; } }