@startlibs/form 1.0.2 → 1.0.4

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.
Files changed (2) hide show
  1. package/lib/index.js +113 -99
  2. package/package.json +2 -1
package/lib/index.js CHANGED
@@ -36,7 +36,10 @@ import _createClass from '@babel/runtime/helpers/createClass';
36
36
  import _possibleConstructorReturn from '@babel/runtime/helpers/possibleConstructorReturn';
37
37
  import _getPrototypeOf from '@babel/runtime/helpers/getPrototypeOf';
38
38
  import _inherits from '@babel/runtime/helpers/inherits';
39
- import _map from 'lodash/fp/map';
39
+ import _concat from 'lodash/fp/concat';
40
+ import _without from 'lodash/fp/without';
41
+ import _isEqual from 'lodash/fp/isEqual';
42
+ import ContentEditable from 'react-contenteditable';
40
43
  import _isObject from 'lodash/fp/isObject';
41
44
  import _unionBy from 'lodash/fp/unionBy';
42
45
  import _uniq from 'lodash/fp/uniq';
@@ -53,6 +56,7 @@ import _flatten from 'lodash/fp/flatten';
53
56
  import _fromPairs from 'lodash/fp/fromPairs';
54
57
  import _pick from 'lodash/fp/pick';
55
58
  import _toPairs from 'lodash/fp/toPairs';
59
+ import _map from 'lodash/fp/map';
56
60
  import _entries from 'lodash/fp/entries';
57
61
 
58
62
  var getFormResponse = function getFormResponse(setter) {
@@ -2914,7 +2918,7 @@ var AutoCompletePlaceholder = styled.span.withConfig({
2914
2918
  displayName: "AutoComplete__AutoCompletePlaceholder",
2915
2919
  componentId: "g0526o-2"
2916
2920
  })(["position:absolute;top:50%;transform:translateY(-50%);pointer-events:none;color:rgba(0,0,0,0.3);left:0.7rem;right:0.7rem;", ""], media.mobile(_templateObject3$2()));
2917
- var AutoCompleteTextboxDiv = styled.div.withConfig({
2921
+ var AutoCompleteTextboxDiv = styled(ContentEditable).withConfig({
2918
2922
  displayName: "AutoComplete__AutoCompleteTextboxDiv",
2919
2923
  componentId: "g0526o-3"
2920
2924
  })(["display:inline-block;outline:0;outline:none;padding:0 1px;line-height:130%;"]);
@@ -2975,7 +2979,7 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
2975
2979
  title: label
2976
2980
  }, label, React.createElement(RemoveIcon, {
2977
2981
  icon: "x",
2978
- onClick: remove
2982
+ onMouseUp: constrainEvent(remove)
2979
2983
  }));
2980
2984
  } : _ref$CompletedBox,
2981
2985
  _ref$EditableInput = _ref.EditableInput,
@@ -3037,6 +3041,8 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3037
3041
  var hoverIndex = useToggle();
3038
3042
  var isLoading = useToggle();
3039
3043
 
3044
+ var _cancelEditable = useRef();
3045
+
3040
3046
  var _useInput = useInput$1({
3041
3047
  path: path,
3042
3048
  transform: transform,
@@ -3045,9 +3051,22 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3045
3051
  }, raw),
3046
3052
  _useInput2 = _slicedToArray(_useInput, 3),
3047
3053
  formValue = _useInput2[0],
3048
- setFormValue = _useInput2[1],
3054
+ _setFormValue = _useInput2[1],
3049
3055
  hasErrors = _useInput2[2].hasErrors;
3050
3056
 
3057
+ var _useState = useState(Date.now()),
3058
+ _useState2 = _slicedToArray(_useState, 2),
3059
+ localFormValue = _useState2[0],
3060
+ setLocalFormValue = _useState2[1];
3061
+
3062
+ var setFormValue = function setFormValue(updater) {
3063
+ _setFormValue(updater);
3064
+
3065
+ setLocalFormValue(updater);
3066
+ };
3067
+
3068
+ var lastIsEditable = _isEqual(localFormValue, formValue);
3069
+
3051
3070
  var _useProvideErrors = useProvideErrors$1(),
3052
3071
  _useProvideErrors2 = _slicedToArray(_useProvideErrors, 2),
3053
3072
  ErrorProvider = _useProvideErrors2[0],
@@ -3056,16 +3075,14 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3056
3075
  var hooksRef = useEnsureRef(outerRef);
3057
3076
  var ref = useRef();
3058
3077
  var queries = useRefState([]);
3059
- var editables = useRefState([(formValue || []).length]);
3060
- var listSize = useRefState(editables.get()[0]);
3061
3078
  var suggestionsFetchCache = useRefState({});
3062
3079
  var suggestionsLabelMapCache = useRefState({});
3063
3080
  var lastSuggestionQuery = useRefState('');
3064
3081
 
3065
- var _useState = useState([]),
3066
- _useState2 = _slicedToArray(_useState, 2),
3067
- autoCompleteList = _useState2[0],
3068
- setAutoCompleteList = _useState2[1];
3082
+ var _useState3 = useState([]),
3083
+ _useState4 = _slicedToArray(_useState3, 2),
3084
+ autoCompleteList = _useState4[0],
3085
+ setAutoCompleteList = _useState4[1];
3069
3086
 
3070
3087
  var getValue = function getValue() {
3071
3088
  return formValue || [];
@@ -3092,12 +3109,8 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3092
3109
  });
3093
3110
  }, [shouldFocusInput.isOpen]);
3094
3111
 
3095
- var lastIsEditable = function lastIsEditable() {
3096
- return Math.max.apply(0, editables.get()) === (formValue || ['']).length - 1;
3097
- };
3098
-
3099
3112
  var editableIsEmpty = function editableIsEmpty() {
3100
- return !lastIsEditable() || lastIsEditable() && !formValue[formValue.length - 1];
3113
+ return !lastIsEditable || lastIsEditable && !formValue[formValue.length - 1];
3101
3114
  };
3102
3115
 
3103
3116
  var ignoreCaseIfNeeded = function ignoreCaseIfNeeded(s) {
@@ -3113,7 +3126,7 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3113
3126
  queries.set([value]);
3114
3127
 
3115
3128
  var removeEditable = function removeEditable(list) {
3116
- return lastIsEditable() ? list.slice(0, -1) : list;
3129
+ return lastIsEditable ? list.slice(0, -1) : list;
3117
3130
  };
3118
3131
 
3119
3132
  return isLoading.wait(Promise.resolve(fetchSuggestions(ignoreCaseIfNeeded(value))).then(function (list) {
@@ -3182,23 +3195,13 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3182
3195
  };
3183
3196
 
3184
3197
  useEffect(function () {
3185
- var newValue = formValue || [];
3186
-
3187
- if (newValue.length !== listSize.get()) {
3188
- editables.set(_flow(_map(function (i) {
3189
- return newValue.indexOf(getValue()[i]);
3190
- }), _filter(function (_) {
3191
- return _ >= 0;
3192
- })));
3193
-
3194
- if (!editables.get().length) {
3195
- editables.set([newValue.length]);
3196
- }
3197
-
3198
- focusInput();
3198
+ if (!lastIsEditable) {
3199
+ setFormValue(_without([_cancelEditable.current], formValue).concat(""));
3200
+ _cancelEditable.current = null;
3199
3201
  }
3200
-
3201
- refreshSuggestions(lastIsEditable() ? getValue().slice(-1)[0] : '');
3202
+ }, [lastIsEditable]);
3203
+ useEffect(function () {
3204
+ refreshSuggestions(lastIsEditable ? getValue().slice(-1)[0] : '');
3202
3205
 
3203
3206
  if (recentlyAdded.get()) {
3204
3207
  recentlyAdded.set(false);
@@ -3251,20 +3254,12 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3251
3254
 
3252
3255
  var onChange = function onChange(index, value) {
3253
3256
  errorUtils.clearErrors();
3254
-
3255
- var newValue = _s.set([index], value, getValue());
3256
-
3257
- listSize.set(newValue.length);
3258
- setFormValue(newValue);
3257
+ setFormValue(_s.set([index], value));
3259
3258
  };
3260
3259
 
3261
3260
  var addValue = function addValue(value, fromBlur) {
3262
- var index = Math.max(lastIsEditable() ? getValue().length - 1 : getValue().length, 0);
3263
- editables.set(_flow(_filter(function (_) {
3264
- return _ !== index;
3265
- }), _s.concat([index + 1])));
3266
- setFormValue(_s.set(index, value, getValue()));
3267
- listSize.set(index);
3261
+ var index = Math.max(lastIsEditable ? getValue().length - 1 : getValue().length, 0);
3262
+ setFormValue(_flow(_set([index], value), _concat(_concat.placeholder, "")));
3268
3263
  recentlyAdded.set(true);
3269
3264
 
3270
3265
  if (!fromBlur) {
@@ -3272,17 +3267,10 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3272
3267
  }
3273
3268
  };
3274
3269
 
3275
- var _remove = function remove(index) {
3276
- editables.set(_map(function (_) {
3277
- return _ >= index ? _ - 1 : 1;
3278
- }));
3279
-
3280
- var newList = _s.unset(index, getValue()).filter(function (_) {
3270
+ var remove = function remove(index) {
3271
+ setFormValue(_flow(_s.unset(index), _filter(function (_) {
3281
3272
  return _ !== undefined;
3282
- });
3283
-
3284
- listSize.set(newList.length);
3285
- setFormValue(newList);
3273
+ })));
3286
3274
  focusInput();
3287
3275
  };
3288
3276
 
@@ -3290,7 +3278,7 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3290
3278
  autoCompleteBox.close();
3291
3279
  var v = getValue().slice(-1)[0];
3292
3280
 
3293
- if (lastIsEditable()) {
3281
+ if (lastIsEditable) {
3294
3282
  var _validation2 = validation(v),
3295
3283
  errors = _validation2.errors;
3296
3284
 
@@ -3314,7 +3302,7 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3314
3302
  return {
3315
3303
  addValue: addValue,
3316
3304
  confirm: confirm,
3317
- remove: _remove
3305
+ remove: remove
3318
3306
  };
3319
3307
  }, [formValue]);
3320
3308
  var validValue = formValue || [''];
@@ -3328,17 +3316,14 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3328
3316
  var label = getLabel(value);
3329
3317
  var uid = uniqueKeyLabel[label] = (uniqueKeyLabel[label] || 0) + 1;
3330
3318
  return label + uid;
3331
- }; // console.log(formValue)
3332
-
3333
-
3334
- var valueWithEditable = lastIsEditable() ? validValue : validValue.concat('');
3319
+ };
3335
3320
 
3336
3321
  var tryOpenSuggestions = function tryOpenSuggestions(e) {
3337
3322
  if (autoCompleteBox.get()) {
3338
3323
  stopPropagation(onBlur)(e);
3339
3324
  } else {
3340
3325
  errorUtils.clearErrors();
3341
- refreshSuggestions(lastIsEditable() ? getValue().slice(-1)[0] : '', false, true);
3326
+ refreshSuggestions(lastIsEditable ? getValue().slice(-1)[0] : '', false, true);
3342
3327
  focusInput();
3343
3328
  }
3344
3329
  };
@@ -3358,28 +3343,27 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3358
3343
  },
3359
3344
  focused: autoCompleteBox.isOpen,
3360
3345
  withDropdown: withDropdown
3361
- }, React.createElement("span", null, "\u200B"), valueWithEditable.map(function (v, i) {
3362
- return editables.get().indexOf(i) >= 0 ? React.createElement(AutoCompleteTextbox, {
3346
+ }, React.createElement("span", null, "\u200B"), validValue.map(function (v, i) {
3347
+ return React.createElement(ValueItem, {
3363
3348
  value: v,
3364
3349
  index: i,
3350
+ cancelEditable: function cancelEditable(v) {
3351
+ _cancelEditable.current = v;
3352
+ },
3353
+ isEditable: lastIsEditable && validValue.length === i + 1,
3365
3354
  confirmKeys: confirmKeys,
3366
3355
  confirmIfValueKeys: confirmIfValueKeys,
3367
3356
  deleteOnBackspace: deleteOnBackspace,
3368
3357
  EditableInput: EditableInput,
3369
- key: '$$editable$$' + i,
3358
+ key: lastIsEditable && validValue.length === i + 1 ? '$$editable$$' : _getUniqueKey(v),
3370
3359
  onChange: onChange,
3371
- remove: _remove,
3360
+ remove: remove,
3372
3361
  confirm: confirm,
3362
+ getLabel: getLabel,
3373
3363
  tabIndex: tabIndex,
3374
3364
  confirmIfNew: confirmIfNew,
3375
- confirmIfNewKeys: confirmIfNewKeys
3376
- }) : React.createElement(CompletedBox, {
3377
- key: _getUniqueKey(v),
3378
- label: getLabel(v),
3379
- value: v,
3380
- remove: function remove() {
3381
- return _remove(i);
3382
- }
3365
+ confirmIfNewKeys: confirmIfNewKeys,
3366
+ CompletedBox: CompletedBox
3383
3367
  });
3384
3368
  }), React.createElement("span", null, "\u200B"), (!formValue || !formValue.join('')) && placeholder && React.createElement(AutoCompletePlaceholder, {
3385
3369
  onClick: function onClick(e) {
@@ -3389,12 +3373,10 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3389
3373
  onClick: tryOpenSuggestions
3390
3374
  }, React.createElement(Icon, {
3391
3375
  icon: "arrow-down"
3392
- })), autoCompleteBox.isOpen !== false && !errorUtils.errors.length && autoCompleteList.length > 0 && React.createElement(AutoCompleteMenu, {
3376
+ }))), autoCompleteBox.isOpen !== false && !errorUtils.errors.length && autoCompleteList.length > 0 && React.createElement(AutoCompleteMenu, {
3393
3377
  hoverIndex: hoverIndex.isOpen,
3394
3378
  autoHover: autoSelect,
3395
- onClick: function onClick(e) {
3396
- return e.preventDefault();
3397
- },
3379
+ onClick: constrainEvent(),
3398
3380
  onHover: hoverIndex.openWith,
3399
3381
  my: "top left",
3400
3382
  at: "bottom left",
@@ -3411,7 +3393,7 @@ var AutoComplete = React.forwardRef(function (_ref, outerRef) {
3411
3393
  return addValue(value);
3412
3394
  }
3413
3395
  });
3414
- }))), React.createElement(ErrorProvider, {
3396
+ })), React.createElement(ErrorProvider, {
3415
3397
  value: errorUtils
3416
3398
  }, React.createElement(AutoCompleteError, null)));
3417
3399
  return withoutField ? input : React.createElement(Field$1, {
@@ -3437,6 +3419,39 @@ var cleanText = function cleanText(text) {
3437
3419
  return clean.trim() ? clean : '';
3438
3420
  };
3439
3421
 
3422
+ var ValueItem = function ValueItem(_ref3) {
3423
+ var CompletedBox = _ref3.CompletedBox,
3424
+ isEditable = _ref3.isEditable,
3425
+ getLabel = _ref3.getLabel,
3426
+ cancelEditable = _ref3.cancelEditable,
3427
+ value = _ref3.value,
3428
+ _remove = _ref3.remove,
3429
+ index = _ref3.index,
3430
+ props = _objectWithoutProperties(_ref3, ["CompletedBox", "isEditable", "getLabel", "cancelEditable", "value", "remove", "index"]);
3431
+
3432
+ var isEditing = useToggle(isEditable);
3433
+ var valueRef = useRef(value);
3434
+ valueRef.current = value;
3435
+ useEffect(function () {
3436
+ return function () {
3437
+ if (isEditing.isOpen) {
3438
+ cancelEditable(valueRef.current);
3439
+ }
3440
+ };
3441
+ }, []);
3442
+ return isEditing.isOpen ? React.createElement(AutoCompleteTextbox, _extends({}, props, {
3443
+ value: value,
3444
+ index: index,
3445
+ remove: _remove
3446
+ })) : React.createElement(CompletedBox, {
3447
+ label: getLabel(value),
3448
+ value: value,
3449
+ remove: function remove() {
3450
+ return _remove(index);
3451
+ }
3452
+ });
3453
+ };
3454
+
3440
3455
  var AutoCompleteTextbox =
3441
3456
  /*#__PURE__*/
3442
3457
  function (_React$Component) {
@@ -3483,7 +3498,17 @@ function (_React$Component) {
3483
3498
 
3484
3499
  _this.props.confirm(_this.props.index, _this.props.value);
3485
3500
  }
3486
- } else if (e.key === 'Backspace' && _this.props.deleteOnBackspace && (range.collapsed && range.startOffset === 0 || e.target.textContent === "\u200B")) {
3501
+ } else if (e.key === 'Backspace' && _this.props.deleteOnBackspace) {
3502
+ if (e.target.textContent !== "\u200B" || !range.collapsed) {
3503
+ if (range.startContainer.previousSibling) {
3504
+ if (range.startContainer.previousSibling.textContent.length) {
3505
+ return;
3506
+ }
3507
+ } else if (range.startOffset > 0) {
3508
+ return;
3509
+ }
3510
+ }
3511
+
3487
3512
  e.preventDefault();
3488
3513
 
3489
3514
  _this.deletePrev();
@@ -3491,7 +3516,7 @@ function (_React$Component) {
3491
3516
  };
3492
3517
 
3493
3518
  _this.onChange = function (evt) {
3494
- _this.props.onChange(_this.props.index, cleanText(evt.target.innerText));
3519
+ _this.props.onChange(_this.props.index, cleanText(evt.target.value));
3495
3520
  };
3496
3521
 
3497
3522
  _this.onPaste = function (ev) {
@@ -3512,9 +3537,10 @@ function (_React$Component) {
3512
3537
  setTimeout(function () {
3513
3538
  return window.dispatchEvent(event);
3514
3539
  }, 1);
3540
+ console.log(this.el, this.el.innerHTML);
3515
3541
 
3516
3542
  if (this.el.innerHTML === '<br>' || !this.el.innerHTML) {
3517
- this.el.innerHTML = "\u200B";
3543
+ this.props.onChange(this.props.index, '');
3518
3544
  }
3519
3545
 
3520
3546
  return nextProps.value !== cleanText(this.el.innerText) || !!Object.keys(nextProps).find(function (k) {
@@ -3533,16 +3559,6 @@ function (_React$Component) {
3533
3559
  setSelectionRange(this.el.firstChild || this.el, this.el.textContent.length + 1);
3534
3560
  }
3535
3561
  }
3536
- }, {
3537
- key: "componentDidMount",
3538
- value: function componentDidMount() {
3539
- this.el.addEventListener("textinput", this.onChange);
3540
- }
3541
- }, {
3542
- key: "componentWillUnmount",
3543
- value: function componentWillUnmount() {
3544
- this.el.removeEventListener("textinput", this.onChange);
3545
- }
3546
3562
  }, {
3547
3563
  key: "render",
3548
3564
  value: function render() {
@@ -3561,22 +3577,20 @@ function (_React$Component) {
3561
3577
 
3562
3578
  var valueOrBlank =
3563
3579
  /*android fix, not needed? value || */
3564
- "\u200B";
3580
+ _isString(value) && value ? value : "\u200B";
3565
3581
 
3566
3582
  var props = _objectSpread({
3567
- ref: function ref(_ref3) {
3568
- return _this3.el = _ref3;
3583
+ innerRef: function innerRef(ref) {
3584
+ return _this3.el = ref;
3569
3585
  },
3570
- contentEditable: true,
3571
- onInput: this.onChange,
3572
3586
  onKeyDown: this.onKeyDown,
3573
3587
  onPaste: this.onPaste,
3574
3588
  value: value,
3575
3589
  index: index,
3576
- dangerouslySetInnerHTML: {
3577
- __html: valueOrBlank.replace(/\s/, '&nbsp;')
3578
- }
3579
- }, rest);
3590
+ html: valueOrBlank.replace(/\s/, '&nbsp;')
3591
+ }, rest, {
3592
+ onChange: this.onChange
3593
+ });
3580
3594
 
3581
3595
  return typeof EditableInput === 'function' ? EditableInput(props) : React.createElement(EditableInput, props);
3582
3596
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startlibs/form",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Startlibs Form",
5
5
  "main": "lib/index.js",
6
6
  "sideEffects": false,
@@ -12,6 +12,7 @@
12
12
  "lodash": "*",
13
13
  "polished": "^1.1.3",
14
14
  "react": "*",
15
+ "react-contenteditable": "3.3.7",
15
16
  "react-dom": "*",
16
17
  "react-window": "*",
17
18
  "styled-components": "^5.2.0"