@@ -7,18 +7,17 @@ import {IsaacQuestionProps} from "../../../IsaacAppTypes";
7
7
import { Immutable } from "immer" ;
8
8
import QuestionInputValidation from "../elements/inputs/QuestionInputValidation" ;
9
9
10
- // Custom input component for coordinates - a pair of inputs, one for x and one for y, formatted with brackets
11
- // and a comma in between.
10
+ // Custom input component for coordinates
12
11
interface CoordinateInputProps {
13
12
value : Immutable < CoordinateItemDTO > ;
14
- placeholderXValue ? : string ;
15
- placeholderYValue ?: string ;
13
+ placeholderValues : string [ ] ;
14
+ numberOfDimensions : number ;
16
15
onChange : ( value : Immutable < CoordinateItemDTO > ) => void ;
17
16
readonly ?: boolean ;
18
17
remove ?: ( ) => void ;
19
18
}
20
19
21
- export const coordinateInputValidator = ( input : string [ ] [ ] ) => {
20
+ export const coordinateInputValidator = ( input : ( readonly string [ ] ) [ ] ) => {
22
21
const errors : string [ ] = [ ] ;
23
22
const allBadChars : string [ ] = [ ] ;
24
23
let containsComma = false ;
@@ -51,32 +50,25 @@ export const coordinateInputValidator = (input: string[][]) => {
51
50
} ;
52
51
53
52
const CoordinateInput = ( props : CoordinateInputProps ) => {
54
- const { value, placeholderXValue, placeholderYValue, onChange, readonly, remove} = props ;
55
- return < span className = "coordinate-input" >
56
- (
57
- < Input
58
- type = "text"
59
- className = "force-print"
60
- placeholder = { placeholderXValue ?? "x" }
61
- value = { value . x ?? "" }
62
- onChange = { event => onChange ( { ...value , x : event . target . value === "" ? undefined : event . target . value } ) }
63
- readOnly = { readonly }
64
- />
65
- < span className = "coordinate-input-separator" > , </ span >
66
- < Input
67
- type = "text"
68
- className = "force-print"
69
- placeholder = { placeholderYValue ?? "y" }
70
- value = { value . y ?? "" }
71
- onChange = { event => onChange ( { ...value , y : event . target . value === "" ? undefined : event . target . value } ) }
72
- readOnly = { readonly }
73
- />
74
- )
75
- { remove && < Button className = "ms-3" size = "sm" onClick = { remove } > Delete</ Button > }
53
+ const { value, placeholderValues, numberOfDimensions, onChange, readonly, remove} = props ;
54
+ return < span className = "coordinate-input" > ({ [ ...Array ( numberOfDimensions ) ] . map ( ( _ , i ) =>
55
+ < span key = { i } >
56
+ < Input
57
+ type = "text"
58
+ className = "force-print"
59
+ placeholder = { placeholderValues [ i ] ?? "" }
60
+ value = { isDefined ( value . coordinates ?. [ i ] ) ? value . coordinates [ i ] : "" }
61
+ onChange = { event => onChange ( { ...value , coordinates : value . coordinates && value . coordinates . length ? value . coordinates . with ( i , event . target . value ) :
62
+ ( event . target . value === "" ? undefined : Array < string > ( numberOfDimensions ) . fill ( "" ) . with ( i , event . target . value ) ) } ) }
63
+ readOnly = { readonly }
64
+ />
65
+ { ( i < numberOfDimensions - 1 ) && < span className = "coordinate-input-separator" > , </ span > }
66
+ </ span > ) } )
67
+ { remove && < Button className = "ms-3" size = "sm" onClick = { remove } > Delete</ Button > }
76
68
</ span > ;
77
69
} ;
78
70
79
- const DEFAULT_COORDINATE_ITEM = { type : "coordinateItem" , x : undefined , y : undefined } ;
71
+ const DEFAULT_COORDINATE_ITEM = { type : "coordinateItem" , coordinates : [ ] } ;
80
72
81
73
const IsaacCoordinateQuestion = ( { doc, questionId, readonly} : IsaacQuestionProps < IsaacCoordinateQuestionDTO > ) => {
82
74
@@ -110,8 +102,8 @@ const IsaacCoordinateQuestion = ({doc, questionId, readonly}: IsaacQuestionProps
110
102
? Array . from ( { length : doc . numberOfCoordinates } ) . map ( ( _ , index ) =>
111
103
< CoordinateInput
112
104
key = { index }
113
- placeholderXValue = { doc . placeholderXValue }
114
- placeholderYValue = { doc . placeholderYValue }
105
+ placeholderValues = { doc . placeholderValues ?? [ ] }
106
+ numberOfDimensions = { doc . numberOfDimensions ?? 1 }
115
107
value = { currentAttempt ?. items ?. [ index ] ?? { ...DEFAULT_COORDINATE_ITEM } }
116
108
readonly = { readonly }
117
109
onChange = { value => updateItem ( index , value ) }
@@ -121,8 +113,8 @@ const IsaacCoordinateQuestion = ({doc, questionId, readonly}: IsaacQuestionProps
121
113
{ currentAttempt ?. items ?. map ( ( item , index ) =>
122
114
< CoordinateInput
123
115
key = { index }
124
- placeholderXValue = { doc . placeholderXValue }
125
- placeholderYValue = { doc . placeholderYValue }
116
+ placeholderValues = { doc . placeholderValues ?? [ ] }
117
+ numberOfDimensions = { doc . numberOfDimensions ?? 1 }
126
118
value = { item }
127
119
readonly = { readonly }
128
120
onChange = { value => updateItem ( index , value ) }
@@ -132,14 +124,14 @@ const IsaacCoordinateQuestion = ({doc, questionId, readonly}: IsaacQuestionProps
132
124
</ >
133
125
: < CoordinateInput
134
126
key = { 0 }
135
- placeholderXValue = { doc . placeholderXValue }
136
- placeholderYValue = { doc . placeholderYValue }
127
+ placeholderValues = { doc . placeholderValues ?? [ ] }
128
+ numberOfDimensions = { doc . numberOfDimensions ?? 1 }
137
129
value = { { ...DEFAULT_COORDINATE_ITEM } }
138
130
readonly = { readonly }
139
131
onChange = { value => updateItem ( 0 , value ) }
140
132
/>
141
133
}
142
- < QuestionInputValidation userInput = { currentAttempt ?. items ?. map ( answer => [ answer . x ?? "" , answer . y ?? "" ] ) ?? [ ] } validator = { coordinateInputValidator } />
134
+ < QuestionInputValidation userInput = { currentAttempt ?. items ?. map ( answer => answer . coordinates ?? [ ] ) ?? [ ] } validator = { coordinateInputValidator } />
143
135
{ ! doc . numberOfCoordinates && < Button color = "secondary" size = "sm" className = "mt-3" onClick = { ( ) => updateItem ( currentAttempt ?. items ?. length ?? 1 , { ...DEFAULT_COORDINATE_ITEM } ) } > Add coordinate</ Button > }
144
136
</ div > ;
145
137
} ;
0 commit comments