Skip to content

Commit

Permalink
feat: add form ElementInternals to pin input
Browse files Browse the repository at this point in the history
  • Loading branch information
hossein-nas committed Aug 19, 2024
1 parent 9e95ce6 commit a3a96a8
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 8 deletions.
21 changes: 21 additions & 0 deletions src/pin-input/pin-input.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,24 @@ const Template: Story<ArgTypes> = (/*{}: ArgTypes*/) => html`
export const PinInput = Template.bind({});

PinInput.args = {};
const TemplateWithForm: Story<ArgTypes> = (/*{}: ArgTypes*/) => html`
<form
@submit=${(e, b) => {
console.log({ e, b });
e.preventDefault();
}}
@formdata=${(e, b) => {
console.log({ e, b });
e.preventDefault();
}}
>
<tap-pin-input
title="عنوان"
description="توضیحات"
@input-filled=${(e: Error) => console.log(e)}
></tap-pin-input>
<button type="submit">Submit</button>
</form>
`;

export const PinInputWithForm = TemplateWithForm.bind({});
87 changes: 79 additions & 8 deletions src/pin-input/pin-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,31 @@ import {
import { PinInputFilled } from './events';

export class PinInput extends LitElement {
private internals_: ElementInternals;
static formAssociated = true;

constructor() {
super();
this.internals_ = this.attachInternals();
}

@queryAll('.pin-input-cell') _cells!: PinInputCell[];

@property({ type: Boolean, reflect: true }) disabled: boolean = false;

@property({ type: Boolean, reflect: true, attribute: 'has-error' })
hasError = false;

@property({ type: Boolean, attribute: 'auto-focus-first-cell' })
autoFocusFirstCell: boolean = true;
@property({ type: Boolean, attribute: 'auto-focus' })
autoFocus: boolean = true;

@property({ reflect: true, type: Number }) value = null;
@property({ reflect: true, type: String }) _value = '';

@property() label = '';

@property({ reflect: true }) title = '';
@property() title = '';

@property({ reflect: true }) description = '';
@property() description = '';

@property({ reflect: true, type: Number }) count = 5;

Expand All @@ -41,7 +49,7 @@ export class PinInput extends LitElement {
}

isFirstCellShouldAutoFocus(index: number) {
return this.autoFocusFirstCell && index === 0;
return this.autoFocus && index === 0;
}

private handleCellFilled(event: PinInputCellFilled) {
Expand Down Expand Up @@ -118,28 +126,91 @@ export class PinInput extends LitElement {
}

private emitPinInputFilled() {
const value = this.inputValue!;
const event = new PinInputFilled('PinInput Filled.', {
value: this.inputValue!,
value: value,
cellCount: this.count,
displayValue: this.inputValue!,
displayValue: value,
});

this.dispatchEvent(event);
}

private handleFormValidity(value: string) {
if (typeof value === 'string' && value.length < this.count) {
this.internals_.setValidity(
{ customError: true },
'Value is less than required',
);
} else {
this.internals_.setValidity({});
}
}

get cellValues() {
return [...this._cells].map((_cell) => _cell.value);
}

get inputValue() {
const result = this.cellValues.join('');
this.internals_.setFormValue(result);
this._value = result;
this.handleFormValidity(result);

if (result.length === this.count) {
return result;
}

return null;
}

set value(value: string) {
if (value) {
void this.fillCells(value);
}
}

async formResetCallback() {
await this.fillCells('');
void this.emitPinInputFilled();
}

formStateRestoreCallback(state: string) {
this.internals_.setFormValue(state);
}

get value() {
return this._value;
}

get form() {
return this.internals_.form;
}

get type() {
return 'pin-input';
}

get validity() {
return this.internals_.validity;
}

get validationMessage() {
return this.internals_.validationMessage;
}

get willValidate() {
return this.internals_.willValidate;
}

checkValidity() {
return this.internals_.checkValidity();
}

reportValidity() {
return this.internals_.reportValidity();
}

private focusNextElementByIndex(current: number) {
const nextIndex = current + 1;
if (this.checkIndexIsInRange(current) && !this.checkIndexIsLast(current)) {
Expand Down

0 comments on commit a3a96a8

Please sign in to comment.