Et2Textbox: Also accept RegExp as validator

Previously only accepted string
This commit is contained in:
nathan 2024-08-06 08:41:11 -06:00
parent 26fd4311a6
commit 1cc0a9e33b

View File

@ -9,12 +9,16 @@
*/
import {css, PropertyValues} from "lit";
import {css, html, nothing, PropertyValues} from "lit";
import {customElement} from "lit/decorators/custom-element.js";
import {property} from "lit/decorators/property.js";
import {Regex} from "../Validators/Regex";
import {SlInput} from "@shoelace-style/shoelace";
import shoelace from "../Styles/shoelace";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
import IMask, {InputMask} from "imask";
import {SlInput} from "@shoelace-style/shoelace";
@customElement("et2-textbox")
export class Et2Textbox extends Et2InputWidget(SlInput)
{
@ -42,19 +46,37 @@ export class Et2Textbox extends Et2InputWidget(SlInput)
];
}
static get properties()
{
return {
...super.properties,
/**
* Perl regular expression eg. '/^[0-9][a-f]{4}$/i'
*
* Not to be confused with this.validators, which is a list of validators for this widget
*/
validator: String,
onkeypress: Function,
}
}
@property()
value = "";
/**
* Placeholder text to show as a hint when the input is empty.
*/
@property()
placeholder;
/**
* Mask the input to enforce format. The mask is enforced as the user types, preventing invalid input.
*/
@property()
mask;
/**
* Disables the input. It is still visible.
* @type {boolean}
*/
@property({type: Boolean})
disabled = false;
@property({type: Function})
onkeypress;
private __validator : any;
private _mask : InputMask;
protected _value : string = "";
inputMode = "text";
static get translate()
{
@ -73,6 +95,20 @@ export class Et2Textbox extends Et2InputWidget(SlInput)
super.connectedCallback();
}
disconnectedCallback()
{
super.disconnectedCallback();
this.removeEventListener("focus", this.handleFocus);
}
firstUpdated()
{
if(this.maskOptions.mask)
{
this.updateMask();
}
}
/** @param changedProperties */
updated(changedProperties : PropertyValues)
{
@ -83,8 +119,13 @@ export class Et2Textbox extends Et2InputWidget(SlInput)
this.validators = (this.validators || []).filter((validator) => !(validator instanceof Regex))
this.validators.push(new Regex(this.validator));
}
if(changedProperties.has('mask'))
{
this.updateMask();
}
}
@property()
get validator()
{
return this.__validator;
@ -112,7 +153,114 @@ export class Et2Textbox extends Et2InputWidget(SlInput)
this.requestUpdate("validator");
}
}
}
// @ts-ignore TypeScript is not recognizing that Et2Textbox is a LitElement
customElements.define("et2-textbox", Et2Textbox);
/**
* Get the options for masking.
* Can be overridden by subclass for additional options.
*
* @see https://imask.js.org/guide.html#masked
*/
protected get maskOptions()
{
return {
mask: this.mask,
lazy: this.placeholder ? true : false,
autofix: true,
eager: "append",
overwrite: "shift"
}
}
protected updateMask()
{
const input = this.shadowRoot.querySelector("input")
if(!this._mask)
{
this._mask = IMask(input, this.maskOptions);
this.addEventListener("focus", this.handleFocus)
window.setTimeout(() =>
{
this._mask.updateControl();
}, 1);
}
else
{
this._mask.updateOptions(this.maskOptions);
}
if(this._mask)
{
this.updateMaskValue();
}
}
protected updateMaskValue()
{
this._mask.unmaskedValue = "" + this.value;
this._mask.updateValue();
this.updateComplete.then(() =>
{
this._mask.updateControl();
});
}
protected handleFocus(event)
{
if(this._mask)
{
// this._mask.updateValue();
}
}
protected _inputTemplate()
{
return html`
<sl-input
part="input"
placeholder=${this.placeholder || nothing}
inputmode="${this.inputMode}"
?disabled=${this.disabled}
?readonly=${this.readonly}
?required=${this.required}
.value=${this.value}
@input=${(e) =>
{
if(this.__mask)
{
this.__mask.updateCursor(this.__mask.cursorPos)
}
}}
>
<slot name="prefix" slot="prefix"></slot>
<slot name="suffix" slot="suffix"></slot>
</sl-input>
`;
}
/*
render()
{
const labelTemplate = this._labelTemplate();
const helpTemplate = this._helpTextTemplate();
return html`
<div
part="form-control"
class=${classMap({
'form-control': true,
'form-control--medium': true,
'form-control--has-label': labelTemplate !== nothing,
'form-control--has-help-text': helpTemplate !== nothing
})}
>
${labelTemplate}
<div part="form-control-input" class="form-control-input">
${this._inputTemplate()}
</div>
${helpTemplate}
</div>
`;
}
*/
}