All files / molecule/field/src index.js

100% Statements 9/9
75% Branches 21/28
100% Functions 2/2
100% Lines 9/9

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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165                                          1x                                         13x               13x     10x         13x                 13x               13x                                                 1x   1x                                                                                                                            
import {Children, cloneElement} from 'react'
 
import cx from 'classnames'
import PropTypes from 'prop-types'
 
import AtomHelpText from '@s-ui/react-atom-help-text'
import AtomValidationText, {AtomValidationTextTypes} from '@s-ui/react-atom-validation-text'
 
import {
  BASE_CLASS,
  CLASS_AUTO_HIDE,
  CLASS_FULLWIDTH,
  CLASS_INLINE,
  CLASS_INLINE_REVERSE,
  CLASS_INPUT_CONTAINER,
  CLASS_LABEL_CONTAINER
} from './config.js'
import MoleculeLabel from './Label.js'
import useStatusValidationText from './useStatusValidationText.js'
import useTypeValidationLabel from './useTypeValidationLabel.js'
 
const MoleculeField = ({
  disabled,
  inline,
  reverse,
  errorText,
  successText,
  alertText,
  label,
  nodeLabel,
  fullWidth,
  useContrastLabel,
  helpText,
  name,
  status,
  statusText,
  onClickLabel,
  onChange: onChangeFromProps,
  children,
  autoHideHelpText,
  isAligned
}) => {
  const className = cx(
    BASE_CLASS,
    inline && CLASS_INLINE,
    inline && reverse && CLASS_INLINE_REVERSE,
    autoHideHelpText && CLASS_AUTO_HIDE,
    fullWidth && CLASS_FULLWIDTH
  )
 
  const extendedChildren = Children.toArray(children)
    .filter(Boolean)
    .map((child, index) => {
      return cloneElement(child, {
        onChange: onChangeFromProps
      })
    })
 
  const typeValidationLabel = useTypeValidationLabel({
    useContrastLabel,
    errorText,
    successText,
    alertText,
    disabled,
    status
  })
 
  const {text: validationTextValue, status: validationTextStatus} = useStatusValidationText({
    successText,
    errorText,
    alertText,
    status,
    statusText
  })
 
  return (
    <div
      className={className}
      {...(validationTextStatus &&
        Object.values(AtomValidationTextTypes).includes(validationTextStatus) && {'data-status': validationTextStatus})}
    >
      {(label || nodeLabel) && (
        <div className={CLASS_LABEL_CONTAINER}>
          {inline && extendedChildren}
          <MoleculeLabel type={typeValidationLabel} name={name} onClick={onClickLabel}>
            {label || nodeLabel}
          </MoleculeLabel>
        </div>
      )}
      <div className={cx(CLASS_INPUT_CONTAINER, isAligned && `${CLASS_INPUT_CONTAINER}--aligned`)}>
        {!inline && extendedChildren}
        {!disabled && validationTextValue && (
          <AtomValidationText type={validationTextStatus} text={validationTextValue} />
        )}
        {helpText && <AtomHelpText text={helpText} />}
      </div>
    </div>
  )
}
 
MoleculeField.displayName = 'MoleculeField'
 
MoleculeField.propTypes = {
  /** children */
  children: PropTypes.any,
 
  /** Text to be displayed as label of the textarea */
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
 
  /** React node to be displayed as label of the textarea if there is not a given label value */
  nodeLabel: PropTypes.element, // deprecated (use label)
 
  /** Makes nodeLabelContainer full width */
  fullWidth: PropTypes.bool,
 
  /** If true it will set the label type to 'CONTRAST' */
  useContrastLabel: PropTypes.bool,
 
  /** Text to be displayed as label of the textarea */
  onChange: PropTypes.func,
 
  /** used as for attribute. Must be the same as the input element id */
  name: PropTypes.string.isRequired,
 
  /** Success message to display when success state  */
  successText: PropTypes.oneOfType([PropTypes.element, PropTypes.bool, PropTypes.node]),
 
  /** Error message to display when error state  */
  errorText: PropTypes.oneOfType([PropTypes.element, PropTypes.bool, PropTypes.node]),
 
  /** Error message to display when alert state  */
  alertText: PropTypes.oneOfType([PropTypes.element, PropTypes.bool, PropTypes.node]),
 
  /** Help Text to display */
  helpText: PropTypes.oneOfType([PropTypes.element, PropTypes.bool, PropTypes.node]),
 
  /** Boolean to decide if elements should be set inline */
  inline: PropTypes.bool,
 
  /** Boolean to decide if the field should appear as disabled */
  disabled: PropTypes.bool,
 
  /** Boolean to decide if elements should be set inline but input first */
  reverse: PropTypes.bool,
 
  /** Function triggered when field's label is clicked */
  onClickLabel: PropTypes.func,
 
  /** Boolean to decide if helptext should be auto hide */
  autoHideHelpText: PropTypes.bool,
 
  /** Boolean to indicate if there is a checkbox or radiobutton & it has to be aligned  */
  isAligned: PropTypes.bool,
 
  /** set the field status (ERROR, SUCCESS, ALERT) */
  status: PropTypes.oneOf(Object.values(AtomValidationTextTypes)),
 
  /** status field text **/
  statusText: PropTypes.string
}
 
export default MoleculeField
 
export {AtomValidationTextTypes as moleculeFieldStatus}