dce-reactkit 1.0.20 → 2.0.2
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/.eslintrc.js +95 -0
- package/lib/components/LoadingSpinner.d.ts +6 -0
- package/lib/components/LoadingSpinner.js +41 -0
- package/lib/components/LoadingSpinner.js.map +1 -0
- package/lib/components/Modal.d.ts +69 -0
- package/lib/components/Modal.js +315 -0
- package/lib/components/Modal.js.map +1 -0
- package/lib/errors/ErrorWithCode.d.ts +9 -0
- package/lib/errors/ErrorWithCode.js +33 -0
- package/lib/errors/ErrorWithCode.js.map +1 -0
- package/lib/helpers/abbreviate.d.ts +9 -0
- package/lib/helpers/abbreviate.js +21 -0
- package/lib/helpers/abbreviate.js.map +1 -0
- package/lib/helpers/avg.d.ts +8 -0
- package/lib/helpers/avg.js +24 -0
- package/lib/helpers/avg.js.map +1 -0
- package/lib/helpers/ceilToNumDecimals.d.ts +9 -0
- package/lib/helpers/ceilToNumDecimals.js +15 -0
- package/lib/helpers/ceilToNumDecimals.js.map +1 -0
- package/lib/helpers/floorToNumDecimals.d.ts +9 -0
- package/lib/helpers/floorToNumDecimals.js +15 -0
- package/lib/helpers/floorToNumDecimals.js.map +1 -0
- package/lib/helpers/forceNumIntoBounds.d.ts +10 -0
- package/lib/helpers/forceNumIntoBounds.js +15 -0
- package/lib/helpers/forceNumIntoBounds.js.map +1 -0
- package/lib/helpers/padDecimalZeros.d.ts +10 -0
- package/lib/helpers/padDecimalZeros.js +30 -0
- package/lib/helpers/padDecimalZeros.js.map +1 -0
- package/lib/helpers/padZerosLeft.d.ts +9 -0
- package/lib/helpers/padZerosLeft.js +21 -0
- package/lib/helpers/padZerosLeft.js.map +1 -0
- package/lib/helpers/roundToNumDecimals.d.ts +9 -0
- package/lib/helpers/roundToNumDecimals.js +15 -0
- package/lib/helpers/roundToNumDecimals.js.map +1 -0
- package/lib/helpers/sum.d.ts +8 -0
- package/lib/helpers/sum.js +15 -0
- package/lib/helpers/sum.js.map +1 -0
- package/lib/helpers/visitServerEndpoint.d.ts +17 -0
- package/lib/helpers/visitServerEndpoint.js +84 -0
- package/lib/helpers/visitServerEndpoint.js.map +1 -0
- package/lib/helpers/waitMs.d.ts +7 -0
- package/lib/helpers/waitMs.js +55 -0
- package/lib/helpers/waitMs.js.map +1 -0
- package/lib/types/ReactKitErrorCode.d.ts +9 -0
- package/lib/types/ReactKitErrorCode.js +14 -0
- package/lib/types/ReactKitErrorCode.js.map +1 -0
- package/lib/types/Variant.d.ts +15 -0
- package/lib/types/Variant.js +19 -0
- package/lib/types/Variant.js.map +1 -0
- package/package.json +22 -40
- package/src/components/LoadingSpinner.tsx +105 -0
- package/src/components/Modal.tsx +447 -0
- package/src/errors/ErrorWithCode.tsx +15 -0
- package/src/helpers/abbreviate.tsx +23 -0
- package/src/helpers/avg.tsx +22 -0
- package/src/helpers/ceilToNumDecimals.tsx +13 -0
- package/src/helpers/floorToNumDecimals.tsx +13 -0
- package/src/helpers/forceNumIntoBounds.tsx +19 -0
- package/src/helpers/padDecimalZeros.tsx +32 -0
- package/src/helpers/padZerosLeft.tsx +21 -0
- package/src/helpers/roundToNumDecimals.tsx +13 -0
- package/src/helpers/sum.tsx +16 -0
- package/src/helpers/visitServerEndpoint.tsx +59 -0
- package/src/helpers/waitMs.tsx +12 -0
- package/src/types/ReactKitErrorCode.tsx +12 -0
- package/src/types/Variant.tsx +16 -0
- package/tsconfig.json +24 -0
- package/index.js +0 -1
- package/lib/Bar.js +0 -169
- package/lib/Donut.js +0 -145
- package/lib/DownloadButton.js +0 -81
- package/lib/Histogram.js +0 -193
- package/lib/Scatter.js +0 -162
- package/lib/StackedBar.js +0 -243
- package/lib/common/chart/Holder/index.js +0 -182
- package/lib/common/chart/Holder/style.css +0 -41
- package/lib/common/chart/colors.js +0 -12
- package/lib/common/csvToString.js +0 -23
- package/lib/common/isFloat.js +0 -14
- package/lib/common/isInteger.js +0 -24
- package/lib/common/math.js +0 -21
- package/lib/common/validators.js +0 -18
- package/lib/glyph/Adjust.js +0 -13
- package/lib/glyph/Angle.js +0 -44
- package/lib/glyph/Archive.js +0 -13
- package/lib/glyph/Arrow.js +0 -49
- package/lib/glyph/ArrowsHorizontal.js +0 -13
- package/lib/glyph/ArrowsVertical.js +0 -13
- package/lib/glyph/Award.js +0 -13
- package/lib/glyph/Ban.js +0 -13
- package/lib/glyph/Barcode.js +0 -13
- package/lib/glyph/Bed.js +0 -13
- package/lib/glyph/Bell.js +0 -35
- package/lib/glyph/Bolt.js +0 -13
- package/lib/glyph/Bookmark.js +0 -37
- package/lib/glyph/Bug.js +0 -13
- package/lib/glyph/Calendar.js +0 -13
- package/lib/glyph/Check.js +0 -36
- package/lib/glyph/Checkbox.js +0 -40
- package/lib/glyph/Chevron.js +0 -63
- package/lib/glyph/Circle.js +0 -15
- package/lib/glyph/Cog.js +0 -13
- package/lib/glyph/DoubleAngle.js +0 -45
- package/lib/glyph/Download.js +0 -13
- package/lib/glyph/Ellipsis.js +0 -36
- package/lib/glyph/Envelope.js +0 -13
- package/lib/glyph/File.js +0 -37
- package/lib/glyph/IdCard.js +0 -13
- package/lib/glyph/Menu.js +0 -13
- package/lib/glyph/Minus.js +0 -13
- package/lib/glyph/Move.js +0 -13
- package/lib/glyph/Plus.js +0 -13
- package/lib/glyph/Square.js +0 -47
- package/lib/glyph/Teacher.js +0 -13
- package/lib/glyph/TextAlign.js +0 -53
- package/lib/glyph/Times.js +0 -36
- package/lib/glyph/WarningTriangle.js +0 -13
- package/lib/index.js +0 -1
- package/src-old/common/csvToString.js +0 -5
- package/src-old/common/isFloat.js +0 -3
- package/src-old/common/isInteger.js +0 -14
- package/src-old/common/math.js +0 -16
- package/src-old/common/validators.js +0 -14
- package/src-old/components/Alert.js +0 -79
- package/src-old/components/Button.js +0 -64
- package/src-old/components/CSV/autoMatch.js +0 -174
- package/src-old/components/CSV/getNumCols.js +0 -15
- package/src-old/components/CSV/index.js +0 -743
- package/src-old/components/Card.js +0 -64
- package/src-old/components/Chart/Bar.js +0 -169
- package/src-old/components/Chart/Donut.js +0 -160
- package/src-old/components/Chart/Histogram.js +0 -189
- package/src-old/components/Chart/Scatter.js +0 -162
- package/src-old/components/Chart/colors.js +0 -20
- package/src-old/components/Checkbox/index.js +0 -106
- package/src-old/components/Checkbox/style.css +0 -11
- package/src-old/components/DatePicker.js +0 -59
- package/src-old/components/DownloadButton.js +0 -72
- package/src-old/components/Dropdown.js +0 -120
- package/src-old/components/Layout/LeftAddon.js +0 -63
- package/src-old/components/Layout/RightAddon.js +0 -64
- package/src-old/components/Layout/TwoCol.js +0 -67
- package/src-old/components/Modal.js +0 -161
- package/src-old/components/PhotoRoster.js +0 -152
- package/src-old/components/Pills.js +0 -117
- package/src-old/components/Radio.js +0 -94
- package/src-old/components/Splash/Error.js +0 -62
- package/src-old/components/Splash/Load/index.js +0 -32
- package/src-old/components/Splash/Load/style.css +0 -51
- package/src-old/components/Stat/General.js +0 -252
- package/src-old/components/Stat/helpers/calcAverage.js +0 -20
- package/src-old/components/Stat/helpers/calcExtremes.js +0 -27
- package/src-old/components/Stat/helpers/calcMedian.js +0 -32
- package/src-old/components/Stat/helpers/calcStdDev.js +0 -30
- package/src-old/components/Stat/helpers/calcSum.js +0 -8
- package/src-old/components/UserProfile/index.js +0 -151
- package/src-old/components/UserProfile/style.css +0 -33
- package/src-old/components/Well.js +0 -28
- package/src-old/components/Wizard/Question/CSV.js +0 -307
- package/src-old/components/Wizard/Question/Chooser/Assignment.js +0 -108
- package/src-old/components/Wizard/Question/Chooser/Course.js +0 -214
- package/src-old/components/Wizard/Question/Chooser/helpers/divideIntoSections.js +0 -16
- package/src-old/components/Wizard/Question/Chooser/helpers/genGetItemsPromise.js +0 -20
- package/src-old/components/Wizard/Question/Chooser/helpers/preprocessSections.js +0 -36
- package/src-old/components/Wizard/Question/Chooser/index.js +0 -306
- package/src-old/components/Wizard/Question/Form/Field/CheckableItem.js +0 -155
- package/src-old/components/Wizard/Question/Form/Field/Input.js +0 -149
- package/src-old/components/Wizard/Question/Form/Field/NumberItem.js +0 -374
- package/src-old/components/Wizard/Question/Form/Field/index.js +0 -34
- package/src-old/components/Wizard/Question/Form/Field/readme.md +0 -7
- package/src-old/components/Wizard/Question/Form/index.js +0 -175
- package/src-old/components/Wizard/Question/Form/style.css +0 -3
- package/src-old/components/Wizard/Question/OneButton.js +0 -80
- package/src-old/components/Wizard/Question/index.js +0 -46
- package/src-old/components/Wizard/Question/readme.md +0 -10
- package/src-old/components/Wizard/QuestionGroup/AnswerAll.js +0 -126
- package/src-old/components/Wizard/QuestionGroup/AnswerAny.js +0 -60
- package/src-old/components/Wizard/index.js +0 -233
- package/src-old/components/Wizard/style.css +0 -21
- package/src-old/glyphs/Adjust.js +0 -13
- package/src-old/glyphs/Angle.js +0 -57
- package/src-old/glyphs/Archive.js +0 -13
- package/src-old/glyphs/Arrow.js +0 -85
- package/src-old/glyphs/ArrowsHorizontal.js +0 -13
- package/src-old/glyphs/ArrowsVertical.js +0 -13
- package/src-old/glyphs/Award.js +0 -13
- package/src-old/glyphs/Ban.js +0 -13
- package/src-old/glyphs/Barcode.js +0 -13
- package/src-old/glyphs/Bed.js +0 -13
- package/src-old/glyphs/Bell.js +0 -34
- package/src-old/glyphs/Bolt.js +0 -13
- package/src-old/glyphs/Bookmark.js +0 -36
- package/src-old/glyphs/Bug.js +0 -13
- package/src-old/glyphs/Calendar.js +0 -13
- package/src-old/glyphs/Check.js +0 -34
- package/src-old/glyphs/Checkbox.js +0 -42
- package/src-old/glyphs/Chevron.js +0 -88
- package/src-old/glyphs/Circle.js +0 -16
- package/src-old/glyphs/Cog.js +0 -13
- package/src-old/glyphs/DoubleAngle.js +0 -58
- package/src-old/glyphs/Download.js +0 -13
- package/src-old/glyphs/Ellipsis.js +0 -35
- package/src-old/glyphs/Envelope.js +0 -13
- package/src-old/glyphs/File.js +0 -40
- package/src-old/glyphs/IdCard.js +0 -13
- package/src-old/glyphs/Menu.js +0 -13
- package/src-old/glyphs/Minus.js +0 -13
- package/src-old/glyphs/Move.js +0 -13
- package/src-old/glyphs/Plus.js +0 -13
- package/src-old/glyphs/Square.js +0 -48
- package/src-old/glyphs/Teacher.js +0 -13
- package/src-old/glyphs/TextAlign.js +0 -58
- package/src-old/glyphs/Times.js +0 -34
- package/src-old/glyphs/WarningTriangle.js +0 -13
- package/src-old/index.js +0 -1
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import genUUID from 'uuid/v1';
|
|
4
|
-
|
|
5
|
-
// Import bootstrap componenets
|
|
6
|
-
import {
|
|
7
|
-
Input as BootstrapInput,
|
|
8
|
-
FormFeedback,
|
|
9
|
-
InputGroup,
|
|
10
|
-
InputGroupAddon,
|
|
11
|
-
} from 'reactstrap';
|
|
12
|
-
// Import bootstrap stylesheet
|
|
13
|
-
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
14
|
-
|
|
15
|
-
// Import other components
|
|
16
|
-
import Field from '.';
|
|
17
|
-
import Well from '../../../../Well';
|
|
18
|
-
import Button from '../../../../Button';
|
|
19
|
-
import RightAddonLayout from '../../../../Layout/RightAddon';
|
|
20
|
-
|
|
21
|
-
// Import glyphs
|
|
22
|
-
import Minus from '../../../../../glyphs/Minus';
|
|
23
|
-
import Plus from '../../../../../glyphs/Plus';
|
|
24
|
-
|
|
25
|
-
// Import helpers
|
|
26
|
-
import isFloat from '../../../../../common/isFloat';
|
|
27
|
-
import isInteger from '../../../../../common/isInteger';
|
|
28
|
-
import math from '../../../../../common/math';
|
|
29
|
-
|
|
30
|
-
class NumberItem extends Component {
|
|
31
|
-
constructor(props) {
|
|
32
|
-
super(props);
|
|
33
|
-
|
|
34
|
-
this.key = genUUID();
|
|
35
|
-
|
|
36
|
-
// Deconstruct props
|
|
37
|
-
const {
|
|
38
|
-
min,
|
|
39
|
-
max,
|
|
40
|
-
integer,
|
|
41
|
-
step,
|
|
42
|
-
onChange,
|
|
43
|
-
defaultNumber,
|
|
44
|
-
} = this.props;
|
|
45
|
-
|
|
46
|
-
// Determine step
|
|
47
|
-
this.step = step;
|
|
48
|
-
if (step === null) {
|
|
49
|
-
this.step = (
|
|
50
|
-
integer
|
|
51
|
-
? 1
|
|
52
|
-
: 0.1
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Determine defaultNumber
|
|
57
|
-
this.defaultNumber = defaultNumber;
|
|
58
|
-
if (defaultNumber === null) {
|
|
59
|
-
this.defaultNumber = (
|
|
60
|
-
min !== null
|
|
61
|
-
? min
|
|
62
|
-
: 0
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Create initial state
|
|
67
|
-
let value = defaultNumber;
|
|
68
|
-
|
|
69
|
-
// Apply min and max right away
|
|
70
|
-
if (min !== null && value < min) {
|
|
71
|
-
value = min;
|
|
72
|
-
}
|
|
73
|
-
if (max !== null && value > max) {
|
|
74
|
-
value = max;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const haltSubmit = false;
|
|
78
|
-
this.state = {
|
|
79
|
-
number: value,
|
|
80
|
-
string: String(value),
|
|
81
|
-
haltSubmit,
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Bind functions
|
|
85
|
-
this.onInputBlurred = this.onInputBlurred.bind(this);
|
|
86
|
-
|
|
87
|
-
// Update parent
|
|
88
|
-
onChange(value, haltSubmit);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
onInputBlurred() {
|
|
92
|
-
// Deconstruct props
|
|
93
|
-
const {
|
|
94
|
-
min,
|
|
95
|
-
max,
|
|
96
|
-
integer,
|
|
97
|
-
numDecimals,
|
|
98
|
-
onChange,
|
|
99
|
-
} = this.props;
|
|
100
|
-
|
|
101
|
-
// Deconstruct state
|
|
102
|
-
let { string } = this.state;
|
|
103
|
-
|
|
104
|
-
let number = null;
|
|
105
|
-
let err = null;
|
|
106
|
-
|
|
107
|
-
// Check for empty field
|
|
108
|
-
if (!string || string.trim().length === 0) {
|
|
109
|
-
// Use the default number
|
|
110
|
-
number = this.defaultNumber;
|
|
111
|
-
// Validate number
|
|
112
|
-
} else if (integer) {
|
|
113
|
-
if (!isFloat(string)) {
|
|
114
|
-
err = 'This needs to be a valid number';
|
|
115
|
-
} else if (!isInteger(string)) {
|
|
116
|
-
err = 'This item only accepts whole numbers (integers)';
|
|
117
|
-
} else {
|
|
118
|
-
// Valid int! Parse it
|
|
119
|
-
number = parseInt(string);
|
|
120
|
-
}
|
|
121
|
-
} else if (!isFloat(string)) {
|
|
122
|
-
err = 'This needs to be a valid number';
|
|
123
|
-
} else {
|
|
124
|
-
// Valid float! Save it
|
|
125
|
-
number = parseFloat(string);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Check min/max
|
|
129
|
-
if (number !== null) {
|
|
130
|
-
if (min !== null && number < min) {
|
|
131
|
-
err = `This number is smaller than the minimum (must be ${min} or larger)`;
|
|
132
|
-
}
|
|
133
|
-
if (max !== null && number > max) {
|
|
134
|
-
err = `This number is larger than the maximum (must be no greater than ${max})`;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Number should be null if there's an error
|
|
139
|
-
if (err) {
|
|
140
|
-
number = null;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Create string from number with appropriate number of decimals
|
|
144
|
-
if (number !== null) {
|
|
145
|
-
if (numDecimals !== null) {
|
|
146
|
-
string = String(number.toFixed(numDecimals));
|
|
147
|
-
number = parseFloat(string);
|
|
148
|
-
} else {
|
|
149
|
-
string = String(number);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Update state
|
|
154
|
-
const haltSubmit = !!err;
|
|
155
|
-
this.setState({
|
|
156
|
-
number,
|
|
157
|
-
err,
|
|
158
|
-
haltSubmit,
|
|
159
|
-
string,
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Update handler
|
|
163
|
-
onChange(number, haltSubmit);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
onButtonClicked(isAdder) {
|
|
167
|
-
// Deconstruct props
|
|
168
|
-
const { onChange } = this.props;
|
|
169
|
-
|
|
170
|
-
// Get current number
|
|
171
|
-
const { number } = this.state;
|
|
172
|
-
const newNumber = (
|
|
173
|
-
isAdder
|
|
174
|
-
? math.add(number, this.step)
|
|
175
|
-
: math.sub(number, this.step)
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
// Update state
|
|
179
|
-
const haltSubmit = false;
|
|
180
|
-
this.setState({
|
|
181
|
-
haltSubmit,
|
|
182
|
-
err: null,
|
|
183
|
-
number: newNumber,
|
|
184
|
-
string: newNumber,
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
onChange(newNumber, haltSubmit);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
render() {
|
|
191
|
-
// Deconstruct props
|
|
192
|
-
const {
|
|
193
|
-
title,
|
|
194
|
-
name,
|
|
195
|
-
subtitle,
|
|
196
|
-
min,
|
|
197
|
-
max,
|
|
198
|
-
integer,
|
|
199
|
-
numDecimals,
|
|
200
|
-
children,
|
|
201
|
-
} = this.props;
|
|
202
|
-
|
|
203
|
-
// Deconstruct state
|
|
204
|
-
const {
|
|
205
|
-
number,
|
|
206
|
-
string,
|
|
207
|
-
haltSubmit,
|
|
208
|
-
err,
|
|
209
|
-
} = this.state;
|
|
210
|
-
|
|
211
|
-
// Determine the step size
|
|
212
|
-
let { step } = this.props;
|
|
213
|
-
if (step === null) {
|
|
214
|
-
step = (
|
|
215
|
-
integer
|
|
216
|
-
? 1
|
|
217
|
-
: 0.1
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Disable adder and subtracter
|
|
222
|
-
let adderDisabled;
|
|
223
|
-
let subberDisabled;
|
|
224
|
-
if (number === null) {
|
|
225
|
-
adderDisabled = true;
|
|
226
|
-
subberDisabled = true;
|
|
227
|
-
} else {
|
|
228
|
-
adderDisabled = (
|
|
229
|
-
max !== null
|
|
230
|
-
? number + step > max
|
|
231
|
-
: false
|
|
232
|
-
);
|
|
233
|
-
subberDisabled = (
|
|
234
|
-
min !== null
|
|
235
|
-
? number - step < min
|
|
236
|
-
: false
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Create content
|
|
241
|
-
let content = children;
|
|
242
|
-
if (!content) {
|
|
243
|
-
if (title || subtitle) {
|
|
244
|
-
content = (
|
|
245
|
-
<div>
|
|
246
|
-
<h5
|
|
247
|
-
className="mb-0"
|
|
248
|
-
>
|
|
249
|
-
{title}
|
|
250
|
-
</h5>
|
|
251
|
-
{subtitle && (
|
|
252
|
-
<p className="mb-0 mt-2">{subtitle}</p>
|
|
253
|
-
)}
|
|
254
|
-
</div>
|
|
255
|
-
);
|
|
256
|
-
} else {
|
|
257
|
-
content = (
|
|
258
|
-
<h5>
|
|
259
|
-
Unnamed Item
|
|
260
|
-
</h5>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Render the field
|
|
266
|
-
return (
|
|
267
|
-
<Field
|
|
268
|
-
name={name}
|
|
269
|
-
>
|
|
270
|
-
<Well
|
|
271
|
-
className={`p-2 border mb-0${haltSubmit ? ' border-danger' : ' border-secondary'}`}
|
|
272
|
-
>
|
|
273
|
-
<RightAddonLayout centerVertically>
|
|
274
|
-
{content}
|
|
275
|
-
<div className="text-nowrap">
|
|
276
|
-
<InputGroup>
|
|
277
|
-
<InputGroupAddon addonType="prepend">
|
|
278
|
-
<Button
|
|
279
|
-
color="info"
|
|
280
|
-
disabled={subberDisabled}
|
|
281
|
-
onClick={() => {
|
|
282
|
-
this.onButtonClicked(false);
|
|
283
|
-
}}
|
|
284
|
-
>
|
|
285
|
-
<Minus />
|
|
286
|
-
</Button>
|
|
287
|
-
</InputGroupAddon>
|
|
288
|
-
<BootstrapInput
|
|
289
|
-
value={string}
|
|
290
|
-
className="border-info"
|
|
291
|
-
placeholder={this.defaultNumber}
|
|
292
|
-
bsSize="lg"
|
|
293
|
-
style={{
|
|
294
|
-
width: '5em',
|
|
295
|
-
}}
|
|
296
|
-
min={min}
|
|
297
|
-
max={max}
|
|
298
|
-
decimals={numDecimals}
|
|
299
|
-
step={step}
|
|
300
|
-
onChange={(event) => {
|
|
301
|
-
// Update string in state
|
|
302
|
-
this.setState({
|
|
303
|
-
string: event.target.value,
|
|
304
|
-
});
|
|
305
|
-
}}
|
|
306
|
-
onBlur={this.onInputBlurred}
|
|
307
|
-
/>
|
|
308
|
-
<InputGroupAddon addonType="append">
|
|
309
|
-
<Button
|
|
310
|
-
color="info"
|
|
311
|
-
disabled={adderDisabled}
|
|
312
|
-
onClick={() => {
|
|
313
|
-
this.onButtonClicked(true);
|
|
314
|
-
}}
|
|
315
|
-
>
|
|
316
|
-
<Plus />
|
|
317
|
-
</Button>
|
|
318
|
-
</InputGroupAddon>
|
|
319
|
-
</InputGroup>
|
|
320
|
-
</div>
|
|
321
|
-
</RightAddonLayout>
|
|
322
|
-
</Well>
|
|
323
|
-
<FormFeedback
|
|
324
|
-
className={haltSubmit ? 'd-block' : null}
|
|
325
|
-
>
|
|
326
|
-
{err}
|
|
327
|
-
</FormFeedback>
|
|
328
|
-
</Field>
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
NumberItem.propTypes = {
|
|
334
|
-
/* Title of the number item (replaced by children if children are included) */
|
|
335
|
-
title: PropTypes.string,
|
|
336
|
-
/* The field name (to be used as a key in the form) */
|
|
337
|
-
name: PropTypes.string.isRequired,
|
|
338
|
-
/* Subtitle of the item (replaced by children if children are included) */
|
|
339
|
-
subtitle: PropTypes.string,
|
|
340
|
-
/* Minimum allowed number */
|
|
341
|
-
min: PropTypes.number,
|
|
342
|
-
/* Maximum allowed number */
|
|
343
|
-
max: PropTypes.number,
|
|
344
|
-
/* Increment step (for when + or - are clicked) */
|
|
345
|
-
step: PropTypes.number,
|
|
346
|
-
/* Handler to call when number is changed */
|
|
347
|
-
onChange: PropTypes.func,
|
|
348
|
-
/* Default value of the number field (reverts to this if field is emptied) */
|
|
349
|
-
defaultNumber: PropTypes.number,
|
|
350
|
-
/* If true, only integers are allowed */
|
|
351
|
-
integer: PropTypes.bool,
|
|
352
|
-
/* The number of decimals to display and round to */
|
|
353
|
-
numDecimals: PropTypes.number,
|
|
354
|
-
/* The children of this component (displayed as content) */
|
|
355
|
-
children: PropTypes.oneOfType([
|
|
356
|
-
PropTypes.arrayOf(PropTypes.node),
|
|
357
|
-
PropTypes.node,
|
|
358
|
-
]),
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
NumberItem.defaultProps = {
|
|
362
|
-
title: null,
|
|
363
|
-
subtitle: null,
|
|
364
|
-
min: null,
|
|
365
|
-
max: null,
|
|
366
|
-
step: null,
|
|
367
|
-
onChange: () => {},
|
|
368
|
-
defaultNumber: null,
|
|
369
|
-
integer: false,
|
|
370
|
-
numDecimals: null,
|
|
371
|
-
children: null,
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
export default NumberItem;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
class Field extends Component {
|
|
5
|
-
render() {
|
|
6
|
-
// Deconstruct props
|
|
7
|
-
const {
|
|
8
|
-
name,
|
|
9
|
-
children,
|
|
10
|
-
} = this.props;
|
|
11
|
-
|
|
12
|
-
// Render a chooser
|
|
13
|
-
return (
|
|
14
|
-
<div
|
|
15
|
-
key={name}
|
|
16
|
-
className="mb-2"
|
|
17
|
-
>
|
|
18
|
-
{children}
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
Field.propTypes = {
|
|
25
|
-
/* The field name (to be used as a key in the form) */
|
|
26
|
-
name: PropTypes.string.isRequired,
|
|
27
|
-
/* The children of this component */
|
|
28
|
-
children: PropTypes.oneOfType([
|
|
29
|
-
PropTypes.arrayOf(PropTypes.node),
|
|
30
|
-
PropTypes.node,
|
|
31
|
-
]).isRequired,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default Field;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Also, every Field component must have a property called `name`.
|
|
2
|
-
|
|
3
|
-
Each field must call its own `props.onChange(answer, haltSubmit)` function when its value is changed
|
|
4
|
-
|
|
5
|
-
- haltSubmit = true if the submit button should be disabled (this field is not valid)
|
|
6
|
-
|
|
7
|
-
Upon creation, send an onChange update!
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
// Import custom styles
|
|
5
|
-
import './style.css';
|
|
6
|
-
|
|
7
|
-
// Import other components
|
|
8
|
-
import Question from '..';
|
|
9
|
-
import Button from '../../../Button';
|
|
10
|
-
|
|
11
|
-
const SUBMIT_ERROR_TIMEOUT = 2000; // ms to show submit button error
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* onAnswered is called with the following:
|
|
15
|
-
* {
|
|
16
|
-
* <form field name>: <form field value>,
|
|
17
|
-
* ...
|
|
18
|
-
* }
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
class Form extends Component {
|
|
22
|
-
constructor(props) {
|
|
23
|
-
super(props);
|
|
24
|
-
|
|
25
|
-
// Initialize state
|
|
26
|
-
this.state = {
|
|
27
|
-
answerMap: {}, // field name => answer of field
|
|
28
|
-
haltSubmitMap: {}, // field name => true/false (field is halting submit)
|
|
29
|
-
submitButtonError: false,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Bind functions
|
|
33
|
-
this.onSubmitClicked = this.onSubmitClicked.bind(this);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
onSubmitClicked() {
|
|
37
|
-
// Deconstruct props
|
|
38
|
-
const { onAnswered } = this.props;
|
|
39
|
-
|
|
40
|
-
// Deconstruct state
|
|
41
|
-
const {
|
|
42
|
-
answerMap,
|
|
43
|
-
haltSubmitMap,
|
|
44
|
-
} = this.state;
|
|
45
|
-
|
|
46
|
-
// Halt submission
|
|
47
|
-
const haltSubmit = Object.values(haltSubmitMap).some((x) => { return x; });
|
|
48
|
-
if (haltSubmit) {
|
|
49
|
-
// Turn the submit button red for some time
|
|
50
|
-
this.setState({
|
|
51
|
-
submitButtonError: true,
|
|
52
|
-
});
|
|
53
|
-
setTimeout(() => {
|
|
54
|
-
this.setState({
|
|
55
|
-
submitButtonError: false,
|
|
56
|
-
});
|
|
57
|
-
}, SUBMIT_ERROR_TIMEOUT);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
this.setState({
|
|
61
|
-
submitButtonError: false,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Call handler
|
|
65
|
-
onAnswered(answerMap);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
render() {
|
|
69
|
-
// Deconstruct props
|
|
70
|
-
const {
|
|
71
|
-
title,
|
|
72
|
-
subtitle,
|
|
73
|
-
submitColor,
|
|
74
|
-
submitTitle,
|
|
75
|
-
} = this.props;
|
|
76
|
-
|
|
77
|
-
// Turn children into an array if it isn't already
|
|
78
|
-
let { children } = this.props;
|
|
79
|
-
if (!Array.isArray(children)) {
|
|
80
|
-
children = [children];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Deconstruct state
|
|
84
|
-
const {
|
|
85
|
-
submitButtonError,
|
|
86
|
-
} = this.state;
|
|
87
|
-
|
|
88
|
-
// Wrap form fields
|
|
89
|
-
const wrappedChildren = children.map((child) => {
|
|
90
|
-
if (!child.props) {
|
|
91
|
-
return child;
|
|
92
|
-
}
|
|
93
|
-
const childOnChange = child.props.onChange;
|
|
94
|
-
return React.cloneElement(child, {
|
|
95
|
-
onChange: (answer, haltSubmit) => {
|
|
96
|
-
// Call child's onChange handler
|
|
97
|
-
if (childOnChange) {
|
|
98
|
-
childOnChange(answer, haltSubmit);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Update form results
|
|
102
|
-
const {
|
|
103
|
-
answerMap,
|
|
104
|
-
haltSubmitMap,
|
|
105
|
-
} = this.state;
|
|
106
|
-
answerMap[child.props.name] = answer;
|
|
107
|
-
haltSubmitMap[child.props.name] = haltSubmit;
|
|
108
|
-
this.setState({
|
|
109
|
-
answerMap,
|
|
110
|
-
haltSubmitMap,
|
|
111
|
-
});
|
|
112
|
-
},
|
|
113
|
-
key: child.props.name,
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Create submit button
|
|
118
|
-
const submitButton = (
|
|
119
|
-
<Button
|
|
120
|
-
text={(
|
|
121
|
-
submitButtonError
|
|
122
|
-
? 'Fix Issues Above First'
|
|
123
|
-
: submitTitle
|
|
124
|
-
)}
|
|
125
|
-
disabled={submitButtonError}
|
|
126
|
-
color={(
|
|
127
|
-
submitButtonError
|
|
128
|
-
? 'danger'
|
|
129
|
-
: submitColor
|
|
130
|
-
)}
|
|
131
|
-
onClick={this.onSubmitClicked}
|
|
132
|
-
block
|
|
133
|
-
/>
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// Render a chooser
|
|
137
|
-
return (
|
|
138
|
-
<Question
|
|
139
|
-
title={title}
|
|
140
|
-
subtitle={subtitle}
|
|
141
|
-
>
|
|
142
|
-
{wrappedChildren}
|
|
143
|
-
{submitButton}
|
|
144
|
-
</Question>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
Form.propTypes = {
|
|
150
|
-
/* The title of the form */
|
|
151
|
-
title: PropTypes.string,
|
|
152
|
-
/* The subtitle of the form */
|
|
153
|
-
subtitle: PropTypes.string,
|
|
154
|
-
/* The title of the submit button */
|
|
155
|
-
submitTitle: PropTypes.string,
|
|
156
|
-
/* The color of the submit button */
|
|
157
|
-
submitColor: PropTypes.string,
|
|
158
|
-
/* Handler to call when the form is submitted */
|
|
159
|
-
onAnswered: PropTypes.func,
|
|
160
|
-
/* The children of this component */
|
|
161
|
-
children: PropTypes.oneOfType([
|
|
162
|
-
PropTypes.arrayOf(PropTypes.node),
|
|
163
|
-
PropTypes.node,
|
|
164
|
-
]).isRequired,
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
Form.defaultProps = {
|
|
168
|
-
title: 'Please Complete this Form:',
|
|
169
|
-
subtitle: null,
|
|
170
|
-
submitTitle: 'Continue',
|
|
171
|
-
submitColor: 'info',
|
|
172
|
-
onAnswered: () => {},
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export default Form;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
// Import other components
|
|
5
|
-
import Question from '.';
|
|
6
|
-
import Button from '../../Button';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* onAnswered is called with the following:
|
|
10
|
-
* {
|
|
11
|
-
* true
|
|
12
|
-
* }
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
class OneButton extends Component {
|
|
16
|
-
constructor(props) {
|
|
17
|
-
super(props);
|
|
18
|
-
|
|
19
|
-
this.onAddClicked = this.onAddClicked.bind(this);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
onAddClicked() {
|
|
23
|
-
// Deconstruct props
|
|
24
|
-
const { onAnswered } = this.props;
|
|
25
|
-
|
|
26
|
-
if (onAnswered) {
|
|
27
|
-
onAnswered(true);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
render() {
|
|
32
|
-
// Deconstruct props
|
|
33
|
-
const {
|
|
34
|
-
title,
|
|
35
|
-
subtitle,
|
|
36
|
-
buttonTitle,
|
|
37
|
-
buttonColor,
|
|
38
|
-
} = this.props;
|
|
39
|
-
|
|
40
|
-
// Render a chooser
|
|
41
|
-
return (
|
|
42
|
-
<Question
|
|
43
|
-
title={title}
|
|
44
|
-
subtitle={subtitle}
|
|
45
|
-
>
|
|
46
|
-
<Button
|
|
47
|
-
text={buttonTitle}
|
|
48
|
-
color={buttonColor}
|
|
49
|
-
size="lg"
|
|
50
|
-
block
|
|
51
|
-
onClick={() => {
|
|
52
|
-
this.onAddClicked();
|
|
53
|
-
}}
|
|
54
|
-
/>
|
|
55
|
-
</Question>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
OneButton.propTypes = {
|
|
61
|
-
/* The title of the question */
|
|
62
|
-
title: PropTypes.string,
|
|
63
|
-
/* The subtitle of the question */
|
|
64
|
-
subtitle: PropTypes.string,
|
|
65
|
-
/* The title of the button to click */
|
|
66
|
-
buttonTitle: PropTypes.string,
|
|
67
|
-
/* The color of the button to click */
|
|
68
|
-
buttonColor: PropTypes.string,
|
|
69
|
-
/* Function to call when button is clicked */
|
|
70
|
-
onAnswered: PropTypes.func.isRequired,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
OneButton.defaultProps = {
|
|
74
|
-
title: 'Click to continue:',
|
|
75
|
-
subtitle: null,
|
|
76
|
-
buttonTitle: 'Click Here',
|
|
77
|
-
buttonColor: 'info',
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export default OneButton;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
// Import other components
|
|
5
|
-
import Card from '../../Card';
|
|
6
|
-
|
|
7
|
-
class Question extends Component {
|
|
8
|
-
render() {
|
|
9
|
-
// Deconstruct props
|
|
10
|
-
const {
|
|
11
|
-
title,
|
|
12
|
-
subtitle,
|
|
13
|
-
children,
|
|
14
|
-
} = this.props;
|
|
15
|
-
|
|
16
|
-
// Render a chooser
|
|
17
|
-
return (
|
|
18
|
-
<Card
|
|
19
|
-
title={title}
|
|
20
|
-
subtitle={subtitle}
|
|
21
|
-
className="mb-2"
|
|
22
|
-
>
|
|
23
|
-
{children}
|
|
24
|
-
</Card>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
Question.propTypes = {
|
|
30
|
-
/* The question title */
|
|
31
|
-
title: PropTypes.string,
|
|
32
|
-
/* The subtitle of the question */
|
|
33
|
-
subtitle: PropTypes.string,
|
|
34
|
-
/* The children of this question (displayed in the body) */
|
|
35
|
-
children: PropTypes.oneOfType([
|
|
36
|
-
PropTypes.arrayOf(PropTypes.node),
|
|
37
|
-
PropTypes.node,
|
|
38
|
-
]).isRequired,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
Question.defaultProps = {
|
|
42
|
-
title: 'Please complete the following to continue',
|
|
43
|
-
subtitle: null,
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default Question;
|