import { FRoot } from "../../mixins/components/f-root/f-root";
import { property, state } from "lit/decorators.js";
export type FInputState = "primary" | "default" | "success" | "warning" | "danger";
export type FInputCustomEvent = {
value?: string | number;
type: "clear" | "input";
};
export type FInputSuffixWhen = (value?: string | number) => boolean;
export class FInputBase extends FRoot {
/**
* @attribute local state for password to text toggling and vice versa.
*/
@state({})
showPassword = false;
/**
* @attribute Variants are various visual representations of an input field.
*/
@property({ reflect: true, type: String })
variant?: "curved" | "round" | "block" = "curved";
/**
* @attribute Categories are various visual representations of an input field.
*/
@property({ reflect: true, type: String })
category?: "fill" | "outline" | "transparent" = "fill";
/**
* @attribute States are used to communicate purpose and connotations.
*/
@property({ reflect: true, type: String })
state?: FInputState = "default";
/**
* @attribute f-input can have 2 sizes. By default size is inherited by the parent f-field.
*/
@property({ reflect: true, type: String })
size?: "medium" | "small" = "medium";
/**
* @attribute The type attribute specifies the type of element to display.
*/
@property({ reflect: true, type: String })
type?: "text" | "number" | "email" | "password" | "url" | "tel" = "text";
/**
* @attribute Defines the value of an f-input. Validation rules are applied on the value depending on the type property of the f-text-input.
*/
@property({ reflect: true, type: String })
value?: string | number;
/**
* @attribute Defines the placeholder text for f-input and f-input-light
*/
@property({ reflect: true, type: String })
placeholder?: string;
/**
* @attribute The icon-left property allows the placement of an icon to the left of the input value
*/
@property({ reflect: true, type: String, attribute: "icon-left" })
iconLeft?: string;
/**
* @attribute The icon-right property allows the placement of an icon to the right of the input value
*/
@property({ reflect: true, type: String, attribute: "icon-right" })
iconRight?: string;
/**
* @attribute The prefix property facilitates the addition of a string on the left side of the input box.
*/
@property({ reflect: true, type: String })
prefix: string | null = null;
/**
* @attribute The suffix property facilitates the addition of a string on the right side of the input box.
*/
@property({ reflect: true, type: String })
suffix?: string;
/**
* @attribute The maxLength property of an input box specifies the maximum number of characters that a user can input into the field.
*/
@property({ reflect: true, type: [Number, undefined], attribute: "max-length" })
maxLength?: number;
/**
* @attribute The loading property, when enabled, facilitates the display of a loading icon on the right side of the input box.
*/
@property({ reflect: true, type: Boolean })
loading?: boolean = false;
/**
* @attribute Shows disabled state of input element
*/
@property({ reflect: true, type: Boolean })
disabled?: boolean = false;
/**
* @attribute Displays a close icon-button on the right side of the input that allows the user to clear the input value
*/
@property({ reflect: true, type: Boolean })
clear?: boolean = true;
/**
* @attribute When true the user can not select the input element.
*/
@property({ reflect: true, type: Boolean, attribute: "read-only" })
readOnly?: boolean = false;
@property({ reflect: false, type: Function })
suffixWhen?: FInputSuffixWhen;
/**
* emit input custom event
*/
handleInput(e: InputEvent) {
e.stopPropagation();
const val = (e.target as HTMLInputElement)?.value;
this.value = this.type === "number" ? Number(val) : val;
this.dispatchInputEvent(this.value, "input");
}
/**
* clear input value on clear icon clicked
*/
clearInputValue() {
this.value = undefined;
this.dispatchInputEvent(undefined, "clear");
}
dispatchInputEvent(value: string | number | undefined, type: "clear" | "input") {
const event = new CustomEvent("input", {
detail: {
value: value,
type: type
},
bubbles: true,
composed: true
});
this.dispatchEvent(event);
}
/**
* icon size
*/
get iconSize() {
if (this.size === "medium") return "small";
else if (this.size === "small") return "x-small";
else return undefined;
}
/**
* Toggle Password view
*/
togglePasswordView() {
if (this.type === "text") {
this.type = "password";
} else {
this.type = "text";
}
this.showPassword = !this.showPassword;
}
}