@khanacademy/perseus 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/es/index.css +17 -8
- package/dist/es/index.js +258 -223
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +17 -8
- package/dist/index.js +261 -225
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/__stories__/input-with-examples.stories.jsx +1 -0
- package/src/components/input-with-examples.jsx +41 -24
- package/src/components/number-input.jsx +2 -2
- package/src/components/simple-keypad-input.jsx +18 -21
- package/src/components/text-input.jsx +5 -3
- package/src/index.js +1 -1
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +356 -65
- package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
- package/src/perseus-types.js +18 -7
- package/src/styles/perseus-renderer.less +8 -2
- package/src/styles/widgets/matrix.less +2 -0
- package/src/styles/widgets/passage.less +9 -5
- package/src/util/answer-types.js +2 -3
- package/src/util/math.js +3 -10
- package/src/widgets/__stories__/numeric-input.stories.jsx +94 -7
- package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +4 -4
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +15 -6
- package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +5 -2
- package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +4 -1
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +228 -67
- package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +24 -24
- package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +4 -4
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +2581 -679
- package/src/widgets/__tests__/group_test.jsx +4 -4
- package/src/widgets/__tests__/numeric-input_test.jsx +12 -8
- package/src/widgets/__tests__/passage_test.jsx +81 -0
- package/src/widgets/__tests__/radio/base-radio_test.jsx +55 -7
- package/src/widgets/__tests__/radio/choice_test.jsx +164 -63
- package/src/widgets/__tests__/radio_test.jsx +39 -15
- package/src/widgets/definition.jsx +1 -1
- package/src/widgets/graded-group.jsx +5 -1
- package/src/widgets/group.jsx +84 -102
- package/src/widgets/input-number.jsx +6 -1
- package/src/widgets/matrix.jsx +17 -1
- package/src/widgets/numeric-input.jsx +99 -86
- package/src/widgets/radio/base-radio.jsx +3 -1
- package/src/widgets/radio/choice-a11y-text.js +62 -0
- package/src/widgets/radio/choice-icon/choice-icon.jsx +0 -68
- package/src/widgets/radio/choice-icon/library-choice-icon.jsx +5 -10
- package/src/widgets/radio/choice-icon/sat-choice-icon.jsx +3 -12
- package/src/widgets/radio/choice.jsx +46 -3
|
@@ -25,7 +25,7 @@ import type {
|
|
|
25
25
|
import type {APIOptions} from "../../types.js";
|
|
26
26
|
|
|
27
27
|
const selectOption = (index: number) => {
|
|
28
|
-
const options = screen.getAllByRole("
|
|
28
|
+
const options = screen.getAllByRole("radio");
|
|
29
29
|
|
|
30
30
|
// element that is null/undefined (ie. if the index is invalid) so we
|
|
31
31
|
// manually check and throw here to protect future me, and others :)
|
|
@@ -101,8 +101,7 @@ describe("single-choice question", () => {
|
|
|
101
101
|
it("should accept the right answer (touch)", () => {
|
|
102
102
|
// Arrange
|
|
103
103
|
const {renderer} = renderQuestion(question, apiOptions);
|
|
104
|
-
const correctRadio =
|
|
105
|
-
screen.getAllByRole("checkbox")[correct];
|
|
104
|
+
const correctRadio = screen.getAllByRole("radio")[correct];
|
|
106
105
|
|
|
107
106
|
// Act
|
|
108
107
|
fireEvent.touchStart(correctRadio);
|
|
@@ -157,7 +156,7 @@ describe("single-choice question", () => {
|
|
|
157
156
|
renderer.deselectIncorrectSelectedChoices();
|
|
158
157
|
|
|
159
158
|
// Assert
|
|
160
|
-
screen.getAllByRole("
|
|
159
|
+
screen.getAllByRole("radio").forEach((r) => {
|
|
161
160
|
expect(r).not.toBeChecked();
|
|
162
161
|
});
|
|
163
162
|
});
|
|
@@ -181,9 +180,14 @@ describe("single-choice question", () => {
|
|
|
181
180
|
|
|
182
181
|
// Assert
|
|
183
182
|
// Everything's read-only so no selections made
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
// Note(TB): The visual buttons are hidden from screen readers
|
|
184
|
+
// so they need to be identified as hidden
|
|
185
|
+
// The visual button has the aria attributes
|
|
186
|
+
screen
|
|
187
|
+
.getAllByRole("button", {hidden: true})
|
|
188
|
+
.forEach((r) => {
|
|
189
|
+
expect(r).toHaveAttribute("aria-disabled", "true");
|
|
190
|
+
});
|
|
187
191
|
});
|
|
188
192
|
},
|
|
189
193
|
);
|
|
@@ -194,11 +198,18 @@ describe("single-choice question", () => {
|
|
|
194
198
|
|
|
195
199
|
// Act
|
|
196
200
|
userEvent.tab();
|
|
197
|
-
|
|
201
|
+
// Note(TB): The visual buttons are hidden from screen readers
|
|
202
|
+
// so they need to be identified as hidden;
|
|
203
|
+
// cannot access screen reader buttons via tabbing
|
|
204
|
+
expect(
|
|
205
|
+
screen.getAllByRole("button", {hidden: true})[0],
|
|
206
|
+
).toHaveFocus();
|
|
198
207
|
userEvent.tab();
|
|
199
208
|
|
|
200
209
|
// Assert
|
|
201
|
-
expect(
|
|
210
|
+
expect(
|
|
211
|
+
screen.getAllByRole("button", {hidden: true})[1],
|
|
212
|
+
).toHaveFocus();
|
|
202
213
|
});
|
|
203
214
|
|
|
204
215
|
it("should be able to navigate up by keyboard", () => {
|
|
@@ -207,13 +218,23 @@ describe("single-choice question", () => {
|
|
|
207
218
|
|
|
208
219
|
// Act
|
|
209
220
|
userEvent.tab();
|
|
210
|
-
|
|
221
|
+
// Note(TB): The visual buttons are hidden from screen readers
|
|
222
|
+
// so they need to be identified as hidden
|
|
223
|
+
expect(
|
|
224
|
+
screen.getAllByRole("button", {hidden: true})[0],
|
|
225
|
+
).toHaveFocus();
|
|
226
|
+
|
|
211
227
|
userEvent.tab();
|
|
212
|
-
expect(
|
|
228
|
+
expect(
|
|
229
|
+
screen.getAllByRole("button", {hidden: true})[1],
|
|
230
|
+
).toHaveFocus();
|
|
231
|
+
|
|
213
232
|
userEvent.tab({shift: true});
|
|
214
233
|
|
|
215
234
|
// Assert
|
|
216
|
-
expect(
|
|
235
|
+
expect(
|
|
236
|
+
screen.getAllByRole("button", {hidden: true})[0],
|
|
237
|
+
).toHaveFocus();
|
|
217
238
|
});
|
|
218
239
|
|
|
219
240
|
it("should be able to navigate through 'None of the above' choice by keyboard", () => {
|
|
@@ -229,7 +250,11 @@ describe("single-choice question", () => {
|
|
|
229
250
|
userEvent.tab();
|
|
230
251
|
|
|
231
252
|
// Assert
|
|
232
|
-
|
|
253
|
+
// Note(TB): The visual buttons are hidden from screen readers
|
|
254
|
+
// so they need to be identified as hidden
|
|
255
|
+
expect(
|
|
256
|
+
screen.getAllByRole("button", {hidden: true})[2],
|
|
257
|
+
).toHaveFocus();
|
|
233
258
|
});
|
|
234
259
|
|
|
235
260
|
it.each([
|
|
@@ -251,7 +276,7 @@ describe("single-choice question", () => {
|
|
|
251
276
|
// We click on the first item, which was the second (index == 1)
|
|
252
277
|
// item in the original choices. But because of enforced ordering,
|
|
253
278
|
// it is now at the top of the list (and thus our correct answer).
|
|
254
|
-
userEvent.click(screen.getAllByRole("
|
|
279
|
+
userEvent.click(screen.getAllByRole("radio")[0]);
|
|
255
280
|
|
|
256
281
|
// Assert
|
|
257
282
|
const items = screen.getAllByRole("listitem");
|
|
@@ -393,7 +418,6 @@ describe("single-choice question", () => {
|
|
|
393
418
|
|
|
394
419
|
it("should cross-out selection and dismiss button when clicked", async () => {
|
|
395
420
|
// Arrange
|
|
396
|
-
|
|
397
421
|
renderQuestion(question, crossOutApiOptions);
|
|
398
422
|
userEvent.click(
|
|
399
423
|
screen.getByRole("button", {
|
|
@@ -294,7 +294,11 @@ class GradedGroup extends React.Component<Props, State> {
|
|
|
294
294
|
{gradeStatus}
|
|
295
295
|
</div>
|
|
296
296
|
)}
|
|
297
|
-
{!apiOptions.isMobile &&
|
|
297
|
+
{!apiOptions.isMobile && (
|
|
298
|
+
<p role="status" aria-live="polite">
|
|
299
|
+
{this.state.message}
|
|
300
|
+
</p>
|
|
301
|
+
)}
|
|
298
302
|
{!apiOptions.isMobile && (
|
|
299
303
|
<Button
|
|
300
304
|
kind="secondary"
|
package/src/widgets/group.jsx
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
/* eslint-disable react/sort-comp */
|
|
2
1
|
// @flow
|
|
3
2
|
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
4
3
|
import classNames from "classnames";
|
|
5
4
|
import * as React from "react";
|
|
6
|
-
import _ from "underscore";
|
|
7
5
|
|
|
8
6
|
import * as Changeable from "../mixins/changeable.jsx";
|
|
9
7
|
import {ApiOptions} from "../perseus-api.jsx";
|
|
10
8
|
import Renderer from "../renderer.jsx";
|
|
11
9
|
|
|
12
10
|
import type {PerseusGroupWidgetOptions} from "../perseus-types.js";
|
|
11
|
+
import type {Widget} from "../renderer.jsx";
|
|
13
12
|
import type {
|
|
13
|
+
APIOptions,
|
|
14
|
+
ChangeFn,
|
|
14
15
|
FocusPath,
|
|
15
16
|
PerseusScore,
|
|
16
17
|
WidgetExports,
|
|
@@ -28,6 +29,8 @@ type DefaultProps = {|
|
|
|
28
29
|
|};
|
|
29
30
|
|
|
30
31
|
class Group extends React.Component<Props> {
|
|
32
|
+
rendererRef: ?Renderer;
|
|
33
|
+
|
|
31
34
|
static defaultProps: DefaultProps = {
|
|
32
35
|
content: "",
|
|
33
36
|
widgets: {},
|
|
@@ -42,24 +45,76 @@ class Group extends React.Component<Props> {
|
|
|
42
45
|
this.forceUpdate();
|
|
43
46
|
}
|
|
44
47
|
|
|
48
|
+
change: ChangeFn = (...args) => {
|
|
49
|
+
return Changeable.change.apply(this, args);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
getUserInput: () => $FlowFixMe = () => {
|
|
53
|
+
return this.rendererRef?.getUserInput();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
getSerializedState: () => $FlowFixMe = () => {
|
|
57
|
+
return this.rendererRef?.getSerializedState();
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
restoreSerializedState: ($FlowFixMe, $FlowFixMe) => null = (
|
|
61
|
+
state,
|
|
62
|
+
callback,
|
|
63
|
+
) => {
|
|
64
|
+
this.rendererRef?.restoreSerializedState(state, callback);
|
|
65
|
+
// Tell our renderer that we have no props to change
|
|
66
|
+
// (all our changes were in state):
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
simpleValidate: (Rubric) => ?PerseusScore = (rubric) => {
|
|
71
|
+
return this.rendererRef?.score();
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Mobile API:
|
|
75
|
+
getInputPaths: () => ?$ReadOnlyArray<FocusPath> = () => {
|
|
76
|
+
return this.rendererRef?.getInputPaths();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
setInputValue: (FocusPath, string, () => mixed) => void = (
|
|
80
|
+
path,
|
|
81
|
+
newValue,
|
|
82
|
+
callback,
|
|
83
|
+
) => {
|
|
84
|
+
return this.rendererRef?.setInputValue(path, newValue, callback);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
focus: () => ?boolean = () => {
|
|
88
|
+
return this.rendererRef?.focus();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
focusInputPath: (FocusPath) => void = (path) => {
|
|
92
|
+
this.rendererRef?.focusPath(path);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
blurInputPath: (FocusPath) => void = (path) => {
|
|
96
|
+
this.rendererRef?.blurPath(path);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
showRationalesForCurrentlySelectedChoices: () => void = () => {
|
|
100
|
+
this.rendererRef?.showRationalesForCurrentlySelectedChoices();
|
|
101
|
+
};
|
|
102
|
+
|
|
45
103
|
render(): React.Node {
|
|
46
|
-
const apiOptions =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this.props.onFocus(newFocus);
|
|
59
|
-
}
|
|
60
|
-
},
|
|
104
|
+
const apiOptions: APIOptions = {
|
|
105
|
+
...ApiOptions.defaults,
|
|
106
|
+
...this.props.apiOptions,
|
|
107
|
+
// Api Rewriting to support correct onFocus/onBlur
|
|
108
|
+
// events for the mobile API
|
|
109
|
+
onFocusChange: (newFocus, oldFocus) => {
|
|
110
|
+
if (oldFocus) {
|
|
111
|
+
this.props.onBlur(oldFocus);
|
|
112
|
+
}
|
|
113
|
+
if (newFocus) {
|
|
114
|
+
this.props.onFocus(newFocus);
|
|
115
|
+
}
|
|
61
116
|
},
|
|
62
|
-
|
|
117
|
+
};
|
|
63
118
|
|
|
64
119
|
// Allow a problem number annotation to be added.
|
|
65
120
|
// This is cyclical and should probably be reconsidered. In order to
|
|
@@ -69,7 +124,9 @@ class Group extends React.Component<Props> {
|
|
|
69
124
|
// give ourselves number -1. To combat this, we forceUpdate in
|
|
70
125
|
// componentDidMount so that we can number ourselves properly. But,
|
|
71
126
|
// really we should have a more unidirectional flow. TODO(marcia): fix.
|
|
72
|
-
const
|
|
127
|
+
const groupWidgets: $ReadOnlyArray<Widget> =
|
|
128
|
+
this.props.findWidgets("group");
|
|
129
|
+
const number: number = groupWidgets.indexOf(this);
|
|
73
130
|
const problemNumComponent = this.props.apiOptions.groupAnnotator(
|
|
74
131
|
number,
|
|
75
132
|
this.props.widgetId,
|
|
@@ -81,15 +138,12 @@ class Group extends React.Component<Props> {
|
|
|
81
138
|
// alert our renderer (our parent) of the fact that some interaction
|
|
82
139
|
// has occurred.
|
|
83
140
|
const onInteractWithWidget = (id) => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// eslint-disable-next-line react/no-string-refs
|
|
87
|
-
this.change("widgets", this.refs.renderer.props.widgets);
|
|
141
|
+
if (this.rendererRef) {
|
|
142
|
+
this.change("widgets", this.rendererRef.props.widgets);
|
|
88
143
|
}
|
|
89
144
|
};
|
|
90
145
|
|
|
91
|
-
|
|
92
|
-
const score = this.refs.renderer && this.refs.renderer.score();
|
|
146
|
+
const score = this.rendererRef?.score();
|
|
93
147
|
const isValid = score && score.type !== "invalid";
|
|
94
148
|
const isInvalid = score && score.type === "invalid";
|
|
95
149
|
|
|
@@ -104,18 +158,11 @@ class Group extends React.Component<Props> {
|
|
|
104
158
|
})}
|
|
105
159
|
>
|
|
106
160
|
{problemNumComponent}
|
|
107
|
-
{/**
|
|
108
|
-
* We're passing a bunch of extra props to Renderer here that it
|
|
109
|
-
* doesn't need. We should replace {...this.props} with the individual
|
|
110
|
-
* props that are needed.
|
|
111
|
-
* TODO(FEI-4034): Only pass what the Renderer expects.
|
|
112
|
-
*/}
|
|
113
|
-
{/* $FlowFixMe[prop-missing] */}
|
|
114
|
-
{/* $FlowFixMe[incompatible-type] */}
|
|
115
161
|
<Renderer
|
|
116
|
-
{
|
|
117
|
-
|
|
118
|
-
|
|
162
|
+
content={this.props.content}
|
|
163
|
+
widgets={this.props.widgets}
|
|
164
|
+
images={this.props.images}
|
|
165
|
+
ref={(ref) => (this.rendererRef = ref)}
|
|
119
166
|
apiOptions={apiOptions}
|
|
120
167
|
findExternalWidgets={this.props.findWidgets}
|
|
121
168
|
reviewMode={!!this.props.reviewModeRubric}
|
|
@@ -129,78 +176,13 @@ class Group extends React.Component<Props> {
|
|
|
129
176
|
</div>
|
|
130
177
|
);
|
|
131
178
|
}
|
|
132
|
-
|
|
133
|
-
change: ($FlowFixMe, $FlowFixMe, $FlowFixMe) => $FlowFixMe = (...args) => {
|
|
134
|
-
return Changeable.change.apply(this, args);
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
getUserInput: () => $FlowFixMe = () => {
|
|
138
|
-
// eslint-disable-next-line react/no-string-refs
|
|
139
|
-
return this.refs.renderer.getUserInput();
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
getSerializedState: () => $FlowFixMe = () => {
|
|
143
|
-
// eslint-disable-next-line react/no-string-refs
|
|
144
|
-
return this.refs.renderer.getSerializedState();
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
restoreSerializedState: ($FlowFixMe, $FlowFixMe) => $FlowFixMe = (
|
|
148
|
-
state,
|
|
149
|
-
callback,
|
|
150
|
-
) => {
|
|
151
|
-
// eslint-disable-next-line react/no-string-refs
|
|
152
|
-
this.refs.renderer.restoreSerializedState(state, callback);
|
|
153
|
-
// Tell our renderer that we have no props to change
|
|
154
|
-
// (all our changes were in state):
|
|
155
|
-
return null;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
simpleValidate: (Rubric) => PerseusScore = (rubric) => {
|
|
159
|
-
// eslint-disable-next-line react/no-string-refs
|
|
160
|
-
return this.refs.renderer.score();
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// Mobile API:
|
|
164
|
-
getInputPaths: () => $ReadOnlyArray<FocusPath> = () => {
|
|
165
|
-
// eslint-disable-next-line react/no-string-refs
|
|
166
|
-
return this.refs.renderer.getInputPaths();
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
setInputValue: (FocusPath, string, $FlowFixMe) => void = (
|
|
170
|
-
path,
|
|
171
|
-
newValue,
|
|
172
|
-
cb,
|
|
173
|
-
) => {
|
|
174
|
-
// eslint-disable-next-line react/no-string-refs
|
|
175
|
-
return this.refs.renderer.setInputValue(path, newValue, cb);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
focus: () => ?boolean = () => {
|
|
179
|
-
// eslint-disable-next-line react/no-string-refs
|
|
180
|
-
return this.refs.renderer.focus();
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
focusInputPath: (FocusPath) => void = (path) => {
|
|
184
|
-
// eslint-disable-next-line react/no-string-refs
|
|
185
|
-
this.refs.renderer.focusPath(path);
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
blurInputPath: (FocusPath) => void = (path) => {
|
|
189
|
-
// eslint-disable-next-line react/no-string-refs
|
|
190
|
-
this.refs.renderer.blurPath(path);
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
showRationalesForCurrentlySelectedChoices: () => void = () => {
|
|
194
|
-
// eslint-disable-next-line react/no-string-refs
|
|
195
|
-
this.refs.renderer.showRationalesForCurrentlySelectedChoices();
|
|
196
|
-
};
|
|
197
179
|
}
|
|
198
180
|
|
|
199
181
|
const traverseChildWidgets = function (
|
|
200
182
|
props: $FlowFixMe,
|
|
201
183
|
traverseRenderer: $FlowFixMe,
|
|
202
184
|
): $FlowFixMe {
|
|
203
|
-
return
|
|
185
|
+
return {...props, ...traverseRenderer(props)};
|
|
204
186
|
};
|
|
205
187
|
|
|
206
188
|
export default ({
|
|
@@ -332,8 +332,13 @@ class InputNumber extends React.Component<Props> {
|
|
|
332
332
|
if (rubric.answerType == null) {
|
|
333
333
|
rubric.answerType = "number";
|
|
334
334
|
}
|
|
335
|
+
|
|
336
|
+
// note(matthewc): this will get immediately parsed again by
|
|
337
|
+
// `KhanAnswerTypes.number.convertToPredicate`, but a string is
|
|
338
|
+
// expected here
|
|
339
|
+
const stringValue = `${rubric.value}`;
|
|
335
340
|
const val = KhanAnswerTypes.number.createValidatorFunctional(
|
|
336
|
-
|
|
341
|
+
stringValue,
|
|
337
342
|
{
|
|
338
343
|
simplify: rubric.simplify,
|
|
339
344
|
inexact: rubric.inexact || undefined,
|
package/src/widgets/matrix.jsx
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// @flow
|
|
4
4
|
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
5
5
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
6
|
+
import {StyleSheet} from "aphrodite";
|
|
6
7
|
import classNames from "classnames";
|
|
7
8
|
import * as React from "react";
|
|
8
9
|
import ReactDOM from "react-dom";
|
|
@@ -324,8 +325,23 @@ class Matrix extends React.Component<Props, State> {
|
|
|
324
325
|
<NumberInput {...inputProps} />
|
|
325
326
|
);
|
|
326
327
|
} else {
|
|
328
|
+
const updatedProps = {
|
|
329
|
+
...inputProps,
|
|
330
|
+
style: StyleSheet.create({
|
|
331
|
+
// eslint-disable-next-line react-native/no-unused-styles
|
|
332
|
+
input: {
|
|
333
|
+
...inputProps.style,
|
|
334
|
+
display: "inline-block",
|
|
335
|
+
padding: 0,
|
|
336
|
+
backgroundColor: outside
|
|
337
|
+
? "#f3f3f3"
|
|
338
|
+
: "#fff",
|
|
339
|
+
},
|
|
340
|
+
}).input,
|
|
341
|
+
};
|
|
342
|
+
|
|
327
343
|
MatrixInput = (
|
|
328
|
-
<TextInput {...
|
|
344
|
+
<TextInput {...updatedProps} />
|
|
329
345
|
);
|
|
330
346
|
}
|
|
331
347
|
return (
|