All files / src/components/lib/InlineEditInputFactory InlineEditInputFactory.js

95% Statements 19/20
95.83% Branches 23/24
62.5% Functions 5/8
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                            187x 7x 7x 7x     187x   187x     4x   4x     187x 164x     187x                   187x                   187x 187x     1x       187x 78x                               109x              
import { Input } from 'antd';
import React from 'react';
import { InputSuffix } from '../InputSuffix/InputSuffix';
 
/**
 * Factory function to create an input / textarea component
 *
 * @param {String} component - 'input' or 'textarea'
 * @param {String} label - current value
 * @param {String} defaultLabel - default value
 * @param {Function} onSave - callback function to set value + close edit mode
 * @param {Function} setLabel - callback function to set value
 * @param {Function} onUndoClick - callback function to reset value to default
 * @param {Object} inputRef - ref to input
 * @param {Number} maxLength - max length of input
 * @param {Object} textAreaProps - props to override antd's Input.TextArea
 * @returns {ReactDOM}
 */
export function InlineEditInputFactory({
  component = 'input', // or 'textarea',
  label = '',
  // initialLabel,
  defaultLabel,
  onSave = () => {},
  setLabel = () => {},
  onUndoClick = () => {},
  inputRef,
  maxLength,
  textAreaProps = {},
}) {
  const onInputSave = (e, onPressEnterFn) => {
    const text = e.target.value;
    if (onPressEnterFn) { onPressEnterFn(e); }
    onSave(text || defaultLabel);
  };
 
  const isChanged = label !== defaultLabel;
 
  const onBlur = (e) => {
    // if undo button is clicked, don't blur immediately
    // isEditing will be false after undo button is clicked
    Iif (e.relatedTarget?.id === 'inline-edit__undo-button') { return; }
 
    onInputSave(e);
  };
 
  const onChangeFn = (e) => {
    setLabel(e.target.value);
  };
 
  const commonProps = {
    ref: inputRef,
    value: label,
    // onPressEnter: onInputSave,
    onBlur,
    onChange: onChangeFn,
    placeholder: defaultLabel,
    maxLength,
    // showCount
  };
  const inputProps = {
    className: `inline-edit__input input-component ${isChanged ? 'has-suffix' : ''}`,
    onPressEnter: onInputSave,
    suffix: <InputSuffix
      isChanged={isChanged}
      onUndoClick={onUndoClick}
      onSaveClick={onInputSave}
    />,
  };
 
  const { className, onPressEnter: textAreaOnPressEnter, ...restTextAreaProps } = textAreaProps;
  const parsedTextAreaProps = {
    className: `inline-edit__input textarea-component ${isChanged ? 'has-suffix' : ''} ${className || ''}`,
    autoSize: { minRows: 1, maxRows: 4 },
    onPressEnter: textAreaOnPressEnter ? (e) => onInputSave(e, textAreaOnPressEnter) : null,
    ...restTextAreaProps,
  };
 
  if (component === 'textarea') {
    return (
      <div className={`inline-edit__wrapper inline-edit__textarea-wrapper ${isChanged ? 'has-suffix' : ''}`}>
        <Input.TextArea
          {...commonProps}
          {...parsedTextAreaProps}
        />
        <InputSuffix
          component="textarea"
          isChanged={isChanged}
          onUndoClick={onUndoClick}
          onSaveClick={onInputSave}
        />
      </div>
    );
  }
 
  return (
    <Input
      {...commonProps}
      {...inputProps}
    />
  );
}