I am currently working on an Angular input component in StorybookJS. The problem that I am facing is that when I type a value
(e.g., hello) in the control panel in storybook js and click disabled
to true, the input text gets disabled displaying the text "hello" and the text remains disabled as expected and returns to normal when disabled
is false. And this is the correct behavior.
But, when I am actually typing in the input itself (e.g., hello11) and repeat the similar steps, when I click disabled
to true, the value in the input will be changed and seen as "hello" instead of "hello11". So there is some inconsistency in the output of value when actually typing a value in the text input itself and disabling it.
Here is what I have:
In input-test.component.html:
<input
type="text"
[(ngModel)]="value"
[disabled]="disabled"
(input)="updateValue($event)"
/>
In input-test.component.ts:
import { Component, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-input-test',
templateUrl: './input-test.component.html',
styleUrls: ['./input-test.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputTestComponent),
multi: true,
},
],
})
export class InputTestComponent implements ControlValueAccessor {
@Input() value: string = '';
@Input() disabled: boolean = false;
/**
* @ignore
*/
onChange: any = () => {};
/**
* @ignore
*/
onTouch: any = () => {};
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
updateValue(event: Event): void {
const newValue = (event.target as HTMLInputElement).value;
this.value = newValue;
this.onChange(this.value);
this.onTouch(this.value);
}
}
In InputTest.stories.ts:
import { FormsModule, ReactiveFormsModule, FormBuilder } from '@angular/forms';
import { InputTestComponent } from 'src/app/input-test/input-test.component';
import { Meta, StoryObj } from '@storybook/angular';
import { moduleMetadata } from '@storybook/angular';
const meta: Meta<InputTestComponent> = {
component: InputTestComponent,
title: 'Basic Components/InputTestComponent',
tags: ['autodocs'],
decorators: [
moduleMetadata({
declarations: [InputTestComponent],
imports: [FormsModule, ReactiveFormsModule],
}),
],
args: {},
render: (args: InputTestComponent) => ({
props: {
...args,
},
}),
argTypes: {},
};
export default meta;
type Story = StoryObj<InputTestComponent>;
const createFormGroup = (value: string, disabled: boolean) => {
const fb = new FormBuilder();
return fb.group({
name: [{value: value, disabled: disabled}],
});
};
export const Default: Story = {
args: {
value: 'default',
disabled: false,
},
render: (args) => ({
props: {
...args,
form: createFormGroup(args.value, args.disabled),
},
template: `
<form [formGroup]="form">
<app-input-test formControlName="name" [(ngModel)]="value" [disabled]="disabled"></app-input-test>
</form>
<div>Name: {{ form.get('name').value }}</div>
`,
}),
};
Can someone help me with this? Thank you!
value
is NOT an@Input
else a simple variable.this.value
in your functionupdateValue
disabled
is NOT an@Input
[setDisabledState]