• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

react-ui-org / react-ui / 16140343605

08 Jul 2025 10:10AM UTC coverage: 91.76%. Remained the same
16140343605

Pull #656

github

web-flow
Merge aa9b22fc9 into 3c7e5b4c2
Pull Request #656: Add custom properties for the border of disabled cards

762 of 836 branches covered (91.15%)

Branch coverage included in aggregate %.

719 of 778 relevant lines covered (92.42%)

77.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.3
/src/components/InputGroup/InputGroup.jsx
1
import PropTypes from 'prop-types';
2
import React, {
3
  useContext,
4
  useMemo,
5
} from 'react';
6
import { withGlobalProps } from '../../providers/globalProps';
7
import { classNames } from '../../helpers/classNames/classNames';
8
import { transferProps } from '../../helpers/transferProps';
9
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
10
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
11
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
12
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
13
import { FormLayoutContext } from '../FormLayout';
14
import { Text } from '../Text';
15
import { InputGroupContext } from './InputGroupContext';
16
import styles from './InputGroup.module.scss';
17

18
export const InputGroup = ({
8✔
19
  children,
20
  disabled,
21
  id,
22
  isLabelVisible,
23
  label,
24
  layout,
25
  required,
26
  size,
27
  validationTexts,
28
  ...restProps
29
}) => {
30
  const formLayoutContext = useContext(FormLayoutContext);
36✔
31
  const inputGroupContextValue = useMemo(() => ({
36✔
32
    disabled,
33
    layout,
34
    size,
35
  }), [disabled, layout, size]);
36

37
  if (isChildrenEmpty(children)) {
36✔
38
    return null;
8✔
39
  }
40

41
  const validationState = children.reduce(
28✔
42
    (state, child) => {
43
      if (state === 'invalid' || (state === 'warning' && child.props.validationState === 'valid')) {
82!
44
        return state;
×
45
      }
46
      return child.props.validationState ?? state;
82✔
47
    },
48
    null,
49
  );
50

51
  return (
28✔
52
    <fieldset
53
      {...transferProps(restProps)}
54
      className={classNames(
55
        styles.root,
56
        formLayoutContext && styles.isRootInFormLayout,
15✔
57
        resolveContextOrProp(formLayoutContext && formLayoutContext.layout, layout) === 'horizontal'
29✔
58
          ? styles.isRootLayoutHorizontal
59
          : styles.isRootLayoutVertical,
60
        disabled && styles.isRootDisabled,
15✔
61
        required && styles.isRootRequired,
15✔
62
        getRootSizeClassName(size, styles),
63
        getRootValidationStateClassName(validationState, styles),
64
      )}
65
      disabled={disabled}
66
      id={id}
67
    >
68
      <legend
69
        className={styles.legend}
70
        id={id && `${id}__label`}
19✔
71
      >
72
        {label}
73
      </legend>
74
      {isLabelVisible && (
27✔
75
        <div
76
          aria-hidden
77
          className={styles.label}
78
          id={id && `${id}__displayLabel`}
17✔
79
        >
80
          {label}
81
        </div>
82
      )}
83
      <div className={styles.field}>
84
        <div
85
          className={styles.inputGroup}
86
          id={id && `${id}__group`}
19✔
87
        >
88
          <InputGroupContext.Provider value={inputGroupContextValue}>
89
            {children}
90
          </InputGroupContext.Provider>
91
        </div>
92
        {validationTexts && (
15✔
93
          <ul
94
            className={styles.validationText}
95
            id={id && `${id}__validationTexts`}
1!
96
          >
97
            {validationTexts.map((validationText) => (
98
              <li key={validationText}>
4✔
99
                <Text blockLevel>
100
                  {validationText}
101
                </Text>
102
              </li>
103
            ))}
104
          </ul>
105
        )}
106
      </div>
107
    </fieldset>
108
  );
109
};
110

111
InputGroup.defaultProps = {
8✔
112
  children: null,
113
  disabled: false,
114
  id: undefined,
115
  isLabelVisible: true,
116
  layout: 'vertical',
117
  required: false,
118
  size: 'medium',
119
  validationTexts: null,
120
};
121

122
InputGroup.propTypes = {
8✔
123
  /**
124
   * Supported elements to be grouped:
125
   * * `Button`
126
   * * `SelectField`
127
   * * `TextField`
128
   *
129
   * If none are provided nothing is rendered.
130
   */
131
  children: PropTypes.node,
132
  /**
133
   * If `true`, the whole input group with all nested inputs and buttons will be disabled.
134
   */
135
  disabled: PropTypes.bool,
136
  /**
137
   * ID of the root HTML element.
138
   *
139
   * Also serves as base for ids of nested elements:
140
   * * `<ID>__label`
141
   * * `<ID>__displayLabel`
142
   * * `<ID>__group`
143
   * * `<ID>__validationTexts`
144
   */
145
  id: PropTypes.string,
146
  /**
147
   * If `false`, the label will be visually hidden (but remains accessible by assistive
148
   * technologies).
149
   */
150
  isLabelVisible: PropTypes.bool,
151
  /**
152
   * Input group label.
153
   */
154
  label: PropTypes.node.isRequired,
155
  /**
156
   * Layout of the group.
157
   *
158
   * Ignored if the component is rendered within `FormLayout` component
159
   * as the value is inherited in such case.
160
   */
161
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
162
  /**
163
   * If `true`, the `InputGroup`'s label appears as required. Underlying `<fieldset>`
164
   * element does not take `required` attribute so there is no functional effect.
165
   */
166
  required: PropTypes.bool,
167
  /**
168
   * Size of the `children` elements.
169
   */
170
  size: PropTypes.oneOf(['small', 'medium', 'large']),
171
  /**
172
   * An array of validation messages to be displayed.
173
   */
174
  validationTexts: PropTypes.node,
175
};
176

177
export const InputGroupWithGlobalProps = withGlobalProps(InputGroup, 'InputGroup');
8✔
178

179
export default InputGroupWithGlobalProps;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc