|
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