import { html, unsafeCSS } from "lit"; import { property } from "lit/decorators.js"; import { FRoot } from "../../mixins/components/f-root/f-root"; import { FDiv } from "../f-div/f-div"; import { FText } from "../f-text/f-text"; import eleStyle from "./f-form-group.scss?inline"; import globalStyle from "./f-form-group-global.scss?inline"; import { flowElement } from "./../../utils"; import { injectCss } from "@cldcvr/flow-core-config"; injectCss("f-form-group", globalStyle); export type FGroupLabel = { title: string; description?: string; iconTooltip?: string; }; /** * @summary Text component includes Headings, titles, body texts and links. */ @flowElement("f-form-group") export class FFormGroup extends FRoot { /** * css loaded from scss file */ static styles = [unsafeCSS(eleStyle), unsafeCSS(globalStyle), ...FDiv.styles, ...FText.styles]; /** * @attribute Label for showing group label */ @property({ type: Object, reflect: true }) label?: FGroupLabel; /** * @attribute Variant decides whether the input elements in a group have some gap or not when they are aligned horizontally. */ @property({ type: String, reflect: true }) variant?: "normal" | "compact" = "normal"; /** * @attribute Decides the direction of the input elements within the group. */ @property({ type: String, reflect: true }) direction?: "vertical" | "horizontal" = "vertical"; /** * @attribute decides the gap between elements of a group */ @property({ type: String, reflect: true }) gap?: "large" | "medium" | "small" | "x-small" = "small"; /** * @attribute Defines whether the group will be collapsed as an accordion or as text. */ @property({ type: String, reflect: true }) collapse?: "none" | "accordion" | "text" = "none"; /** * @attribute Defines whether the group will be collapsed as an accordion or as text. */ @property({ type: Boolean, reflect: true, attribute: "is-collapsed" }) isCollapsed?: boolean = false; /** * @attribute Allows the group to be duplicated by clicking on the plus button */ @property({ type: Boolean, reflect: true, attribute: "can-duplicate" }) canDuplicate?: boolean = false; /** * apply styles */ applyStyles() { if (this.collapse !== "none") { if (!this.isCollapsed) return `max-height:800px; transition: max-height var(--transition-time-rapid) ease-in 0s; );`; else return `max-height:0px; transition: max-height var(--transition-time-rapid) ease-in 0s; );`; } else return ``; } /** * apply cursor styles */ applyCursorStyles() { if (this.collapse !== "none") { return `cursor:pointer`; } else return ``; } /* * emit duplication event */ duplicationClick(e: MouseEvent) { e.stopPropagation(); const event = new CustomEvent("duplicate-group", { detail: { message: "Duplicate Group clicked!", duplicate: true }, bubbles: true, composed: true }); this.dispatchEvent(event); } render() { /** * Final html to render */ return html` ${this.label && Object.keys(this.label)?.length > 0 && Object.values(this.label)?.every(item => item !== undefined) ? html` { if (this.collapse !== "none") this.isCollapsed = !this.isCollapsed; }} .style="${this.applyCursorStyles()}" > ${this.collapse === "text" ? html` { e.preventDefault(); if (this.collapse === "text") { this.isCollapsed = !this.isCollapsed; } }} >${this.label.title}` : html`${this.label.title}`} ${this.label?.iconTooltip ? html` ` : ""} ${this.label?.description ? html` ${this.label.description} ` : ""} ${this.canDuplicate ? html` ` : ""} ${this.collapse === "accordion" ? html` ` : ""} ` : ""} ${!this.isCollapsed || this.collapse === "none" ? html` ` : ""} `; } } /** * Required for typescript */ declare global { interface HTMLElementTagNameMap { "f-form-group": FFormGroup; } }