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;
}
}