UNPKG

13.8 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.SignatureField = exports.IncrementButtonField = exports.TextareaField = exports.DecimalInputField = exports.InputField = exports.SelectButtons = exports.Label = void 0;
7
8var _preact = require("preact");
9
10var _classnames = _interopRequireDefault(require("classnames"));
11
12var _plusMinus = require("./plus-minus");
13
14var _signature = _interopRequireDefault(require("./signature"));
15
16var _signatureBox = _interopRequireDefault(require("./signature-box"));
17
18var _ = require(".");
19
20var _suggestionsBox = _interopRequireDefault(require("./suggestions-box"));
21
22var _env = require("./utils/env");
23
24var _decimals = require("./utils/decimals");
25
26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
28function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
29
30function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
31
32function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
33
34function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
35
36function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
37
38function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
39
40const noOp = () => {};
41
42const Label = ({
43 item,
44 updateValue,
45 removeSuggestion
46}) => {
47 const isRequired = item.required !== false;
48 return (0, _preact.h)("label", {
49 className: "db fw6 lh-copy f5 mb1",
50 htmlFor: item.name
51 }, (0, _preact.h)("div", {
52 className: "flex-shrink-0"
53 }, (0, _preact.h)("div", {
54 className: "flex items-center"
55 }, item.label, isRequired && item.isComplete && (0, _preact.h)(_.Icon, {
56 className: "ml2 light-blue",
57 icon: "check",
58 size: "18"
59 }), isRequired && !item.isComplete && (0, _preact.h)("span", {
60 className: "fw3 red ml2"
61 }, "(required)"), !isRequired && item.explicitOptional && (0, _preact.h)("span", {
62 className: "fw3 gray ml2"
63 }, "(optional)")), item.subLabel && (0, _preact.h)("div", {
64 className: (0, _classnames.default)('fw3 f6', {
65 orange: item.subLabelWarning,
66 red: item.subLabelError
67 })
68 }, item.subLabel instanceof Function ? item.subLabel(item) : item.subLabel)), item.buttons && (0, _preact.h)("div", null, item.buttons.map(val => (0, _preact.h)(_.Button, {
69 key: val,
70 type: "button",
71 "data-e2e": "".concat(item.name, "InputButton:").concat(val),
72 className: "mr2 ml0 mt2",
73 pressed: item.value === val,
74 onClick: e => {
75 e.preventDefault();
76 updateValue(val);
77 }
78 }, val))), item.suggestions && (0, _preact.h)(_suggestionsBox.default, {
79 removeSuggestion: removeSuggestion,
80 name: item.name,
81 value: item.value,
82 autoSuggestType: item.autoSuggestType,
83 updateValue: updateValue,
84 suggestions: item.suggestions,
85 suggestionsDeleting: item.suggestionsDeleting
86 }));
87};
88
89exports.Label = Label;
90const separator = ', ';
91
92const stringToArray = str => str ? str.toString().split(separator) : [];
93
94const arrayToString = arr => arr.filter(Boolean).join(separator);
95
96class SelectButtons extends _preact.Component {
97 constructor(props) {
98 super(props);
99 this.state = {
100 open: false
101 };
102 this.handleButtonPress = this.handleButtonPress.bind(this);
103 this.handleOtherPress = this.handleOtherPress.bind(this);
104
105 this.open = () => {
106 if (!this.state.open) {
107 this.setState({
108 open: true
109 });
110 }
111
112 setTimeout(() => {
113 this.base.querySelector('input').focus();
114 }, 200);
115 };
116
117 this.close = () => this.setState({
118 open: false
119 });
120
121 this.choiceValues = props.item.choices.reduce((res, choice) => {
122 res[choice.val] = true;
123 return res;
124 }, {});
125 }
126
127 handleButtonPress(val, isPressed) {
128 const {
129 item,
130 allowDeselect,
131 updateValue
132 } = this.props;
133 const isMultiButton = item.type === 'multiButton';
134 const {
135 value
136 } = item;
137
138 if (!isMultiButton) {
139 this.close();
140
141 if (isPressed && allowDeselect === false) {
142 return;
143 }
144
145 updateValue(isPressed ? null : val);
146 } else {
147 const values = stringToArray(value);
148 const index = values.indexOf(val);
149
150 if (index === -1) {
151 values.push(val);
152 } else {
153 values.splice(index, 1);
154 }
155
156 this.UpdateValue(arrayToString(values));
157 }
158 }
159
160 handleOtherPress(isPressed) {
161 const {
162 item,
163 updateValue
164 } = this.props;
165 const isMultiButton = item.type === 'multiButton';
166
167 if (!isMultiButton) {
168 if (isPressed) {
169 this.close();
170 updateValue(null);
171 } else {
172 this.open();
173 updateValue('');
174 }
175 } else {
176 const values = stringToArray(this.props.item.value);
177
178 if (isPressed) {
179 this.close();
180 const unknownRemoved = values.reduce((res, val) => {
181 if (this.choiceValues[val]) {
182 res.push(val);
183 }
184
185 return res;
186 }, []);
187 updateValue(arrayToString(unknownRemoved));
188 } else {
189 values.push('');
190 updateValue(arrayToString(values));
191 this.open();
192 }
193 }
194 }
195
196 getPressed(val) {
197 const {
198 value,
199 type
200 } = this.props.item;
201 const isMultiButton = type === 'multiButton'; // if there are no unusual circumstances, we just want an exact match
202
203 if (!isMultiButton) {
204 return value === val;
205 }
206
207 return value != null && value.toString().includes(val);
208 }
209
210 getOtherInputVisible() {
211 return (// either its explicitly open
212 this.state.open || // or it contains something outside of known options
213 // this is important for first load (since we may not have state yet)
214 !stringToArray(this.props.item.value).every(val => this.choiceValues[val])
215 );
216 }
217
218 render(_ref) {
219 let {
220 item,
221 updateValue
222 } = _ref,
223 rest = _objectWithoutProperties(_ref, ["item", "updateValue"]);
224
225 const showOtherInput = this.getOtherInputVisible();
226 const {
227 value
228 } = item;
229 return (0, _preact.h)("div", rest, item.label && (0, _preact.h)(Label, {
230 item: item,
231 updateValue: updateValue
232 }), (0, _preact.h)("div", {
233 "data-e2e": "".concat(item.name, "InputButtons")
234 }, item.choices.map(choice => {
235 let {
236 name,
237 val
238 } = choice;
239 const pressed = this.getPressed(val);
240 return (0, _preact.h)(_.Button, {
241 key: val,
242 pressed: pressed,
243 className: "mr2 mv1 items-base",
244 "data-e2e": "".concat(item.name, "InputButton:").concat(val),
245 "data-state": pressed ? 'pressed' : 'unpressed',
246 type: "button",
247 onClick: () => this.handleButtonPress(val, pressed)
248 }, name);
249 }), item.showOther && (0, _preact.h)(_.Button, {
250 key: "other",
251 pressed: showOtherInput,
252 "data-state": showOtherInput ? 'pressed' : 'unpressed',
253 className: "mr2 mv1 items-base",
254 type: "button",
255 onClick: () => this.handleOtherPress(showOtherInput),
256 "data-e2e": "".concat(item.name, "InputButton:other")
257 }, "Other"), item.showOther && showOtherInput && (0, _preact.h)(_.Input, {
258 className: "mv1 w-100 border-box",
259 name: "".concat(item.name, "Other"),
260 value: value,
261 onInput: e => updateValue(e.target.value)
262 })));
263 }
264
265}
266
267exports.SelectButtons = SelectButtons;
268
269const identity = res => res;
270
271const autoCompleteFallback = _env.IS_CHROME ? 'new-password' : 'none';
272
273const InputField = (_ref2) => {
274 let {
275 item,
276 updateValue,
277 autocomplete = autoCompleteFallback,
278 autofocus,
279 className = '',
280 inputClassName = 'w-100',
281 removeSuggestion
282 } = _ref2,
283 rest = _objectWithoutProperties(_ref2, ["item", "updateValue", "autocomplete", "autofocus", "className", "inputClassName", "removeSuggestion"]);
284
285 const type = item.type || 'text';
286 let clean = item.clean;
287 const {
288 value,
289 cleanRe
290 } = item;
291
292 if (!clean && cleanRe) {
293 clean = val => val.replace(cleanRe, '');
294 }
295
296 if (!clean) {
297 clean = identity;
298 }
299
300 const update = e => updateValue(clean(e.target.value));
301
302 const hasError = !!item.errorMessage;
303 return (0, _preact.h)("div", _extends({
304 className: "w-100 ".concat(className)
305 }, rest), item.label && (0, _preact.h)(Label, {
306 item: item,
307 updateValue: updateValue,
308 removeSuggestion: removeSuggestion
309 }), (0, _preact.h)(_.Input, {
310 className: (0, _classnames.default)('mv1', {
311 'bg-washed-red': hasError
312 }, inputClassName),
313 name: item.name,
314 onChange: item.onInput ? noOp : update,
315 onInput: item.onInput ? update : noOp,
316 id: item.name,
317 placeholder: item.placeholder,
318 type,
319 value,
320 autocomplete,
321 autofocus,
322 inputmode: item.inputmode || null,
323 'data-e2e': "".concat(item.name, "Input"),
324 'data-has-error': hasError ? true : null,
325 style: item.inputWidth ? {
326 width: item.inputWidth
327 } : null
328 }));
329};
330
331exports.InputField = InputField;
332
333const DecimalInputField = (_ref3) => {
334 let {
335 item,
336 updateValue
337 } = _ref3,
338 rest = _objectWithoutProperties(_ref3, ["item", "updateValue"]);
339
340 const modifiedItem = _objectSpread({
341 type: 'number',
342 onInput: true,
343 inputmode: 'decimal',
344 clean: _decimals.cleanDecimalInput,
345 required: false
346 }, item);
347
348 return (0, _preact.h)(InputField, _extends({
349 updateValue: updateValue,
350 item: modifiedItem
351 }, rest));
352};
353
354exports.DecimalInputField = DecimalInputField;
355
356const TextareaField = ({
357 item,
358 updateValue,
359 removeSuggestion
360}) => (0, _preact.h)("div", {
361 className: "mb2"
362}, (0, _preact.h)(Label, {
363 item: item,
364 updateValue: updateValue,
365 removeSuggestion: removeSuggestion
366}), (0, _preact.h)(_.Textarea, {
367 className: (0, _classnames.default)('w-100', item.size === 'large' ? 'h5' : 'h4'),
368 name: item.name,
369 onChange: item.onInput ? noOp : e => updateValue(e.target.value),
370 onInput: item.onInput ? e => updateValue(e.target.value) : noOp,
371 value: item.value,
372 id: item.name,
373 'data-e2e': "".concat(item.name, "Input")
374}));
375
376exports.TextareaField = TextareaField;
377
378const IncrementButtonField = ({
379 item,
380 displayValue,
381 updateValue,
382 step = 1,
383 max = Infinity,
384 min = 0,
385 width,
386 unit = '',
387 showStep = true,
388 formatter,
389 className
390}) => {
391 const {
392 name,
393 value,
394 fieldSpecificProps
395 } = item;
396
397 const passOn = _objectSpread({
398 formatter,
399 width,
400 updateValue,
401 displayValue,
402 step,
403 showStep,
404 max,
405 min,
406 unit,
407 name,
408 value: value != null ? value : fieldSpecificProps.startingValue
409 }, fieldSpecificProps || {});
410
411 return (0, _preact.h)("div", {
412 className: (0, _classnames.default)(className)
413 }, (0, _preact.h)(Label, {
414 item: item
415 }), (0, _preact.h)("div", null, (0, _preact.h)(_plusMinus.IncrementorButtons, passOn)));
416};
417
418exports.IncrementButtonField = IncrementButtonField;
419
420class SignatureField extends _preact.Component {
421 constructor(props) {
422 super(props);
423 this.state = {
424 editing: false
425 };
426 }
427
428 render({
429 item,
430 updateValue
431 }, {
432 editing
433 }) {
434 const {
435 value
436 } = item;
437 return (0, _preact.h)("div", null, item.label && (0, _preact.h)(Label, {
438 item: item
439 }), (0, _preact.h)("div", null, !editing && value && (0, _preact.h)(_signature.default, {
440 width: "200",
441 path: value,
442 className: _.inputClasses
443 }), !editing && (0, _preact.h)(_.Button, {
444 type: "button",
445 className: "db mv2",
446 onClick: () => this.setState({
447 editing: true
448 })
449 }, value ? 'Change' : 'Add Signature'), editing && (0, _preact.h)(_signatureBox.default, {
450 name: item.signatureLineName,
451 close: () => this.setState({
452 editing: false
453 }),
454 updateValue: val => {
455 updateValue(val);
456 this.setState({
457 editing: false
458 });
459 }
460 })));
461 }
462
463}
464
465exports.SignatureField = SignatureField;
\No newline at end of file