|
1 | 1 | import { TinyEmitter, Callback } from "../helpers/emitter";
|
2 |
| -import produce from "immer"; |
| 2 | +import { produce } from "immer"; |
3 | 3 |
|
4 | 4 | export const SEPARATOR = ".";
|
5 | 5 |
|
6 | 6 | interface Field {
|
7 | 7 | id: string;
|
8 | 8 | name: string;
|
| 9 | + |
9 | 10 | defaultValue?: string;
|
10 | 11 | initialValue?: string;
|
11 | 12 | currentValue: string;
|
| 13 | + |
| 14 | + isFocused: boolean; |
| 15 | + isTouched: boolean; |
12 | 16 | }
|
13 | 17 |
|
14 | 18 | type Fields = {
|
@@ -47,7 +51,9 @@ export class GroupStoreMutable extends TinyEmitter<Callback> {
|
47 | 51 | name: name,
|
48 | 52 | defaultValue: defaultValue,
|
49 | 53 | initialValue: initialValue,
|
50 |
| - currentValue: initialValue || defaultValue |
| 54 | + currentValue: initialValue || defaultValue, |
| 55 | + isFocused: false, |
| 56 | + isTouched: false |
51 | 57 | };
|
52 | 58 |
|
53 | 59 | this.fields = produce(this.fields, fields => {
|
@@ -84,6 +90,37 @@ export class GroupStoreMutable extends TinyEmitter<Callback> {
|
84 | 90 | this.emit();
|
85 | 91 | }
|
86 | 92 |
|
| 93 | + public focus(fieldId: string): void { |
| 94 | + this.setFocused(fieldId, true); |
| 95 | + this.emit(); |
| 96 | + } |
| 97 | + |
| 98 | + public blur(fieldId: string): void { |
| 99 | + this.setFocused(fieldId, false); |
| 100 | + this.emit(); |
| 101 | + } |
| 102 | + |
| 103 | + private setFocused(fieldId: string, isFocused: boolean): void { |
| 104 | + console.log(`Setting focus for field '${fieldId}' to ${isFocused}`); |
| 105 | + if (this.fields[fieldId] == null) { |
| 106 | + throw new Error( |
| 107 | + `Cannot update non-existent field value. (field id '${fieldId}').` |
| 108 | + ); |
| 109 | + } |
| 110 | + this.fields = produce(this.fields, fields => { |
| 111 | + const field = fields[fieldId]; |
| 112 | + if (field == null) { |
| 113 | + return; |
| 114 | + } |
| 115 | + field.isFocused = isFocused; |
| 116 | + |
| 117 | + // If the field is not touched yet and got focused, make it touched. |
| 118 | + if (!field.isTouched && isFocused) { |
| 119 | + field.isTouched = true; |
| 120 | + } |
| 121 | + }); |
| 122 | + } |
| 123 | + |
87 | 124 | public toObject(): unknown {
|
88 | 125 | const result: { [key: string]: unknown } = {};
|
89 | 126 | for (const key in this.fields) {
|
|
0 commit comments