-
Notifications
You must be signed in to change notification settings - Fork 381
Expand file tree
/
Copy pathTextInputGroupMain.tsx
More file actions
151 lines (145 loc) · 4.99 KB
/
TextInputGroupMain.tsx
File metadata and controls
151 lines (145 loc) · 4.99 KB
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
import { forwardRef, useContext, useRef } from 'react';
import styles from '@patternfly/react-styles/css/components/TextInputGroup/text-input-group';
import { css } from '@patternfly/react-styles';
import { TextInputGroupContext } from './TextInputGroup';
import { TextInputGroupIcon } from './TextInputGroupIcon';
import { statusIcons } from '../../helpers';
export interface TextInputGroupMainProps extends Omit<React.HTMLProps<HTMLDivElement>, 'onChange'> {
/** Content rendered inside the text input group main div */
children?: React.ReactNode;
/** Additional classes applied to the text input group main container */
className?: string;
/** Icon to be shown on the left side of the text input group main container */
icon?: React.ReactNode;
/** Type that the input accepts. */
type?:
| 'text'
| 'date'
| 'datetime-local'
| 'email'
| 'month'
| 'number'
| 'password'
| 'search'
| 'tel'
| 'time'
| 'url';
/** Suggestion that will show up like a placeholder even with text in the input */
hint?: string;
/** Callback for when there is a change in the input field*/
onChange?: (event: React.FormEvent<HTMLInputElement>, value: string) => void;
/** Callback for when the input field is focused*/
onFocus?: (event?: any) => void;
/** Callback for when focus is lost on the input field*/
onBlur?: (event?: any) => void;
/** Accessibility label for the input */
'aria-label'?: string;
/** Value for the input */
value?: string | number;
/** Placeholder value for the input */
placeholder?: string;
/** @hide A reference object to attach to the input box */
innerRef?: React.RefObject<any>;
/** Name for the input */
name?: string;
/** The id of the active element. Required if role has a value of "combobox", and focus
* should remain on the input.
*/
'aria-activedescendant'?: string;
/** Determines the accessible role of the input. */
role?: string;
/** Flag for whether an associated element controlled by the input is visible. Required if
* role has a value of "combobox".
*/
isExpanded?: boolean;
/** The id of the element(s) controlled by the input. Required if role has a value of "combobox". */
'aria-controls'?: string;
/** The id of the input element */
inputId?: string;
/** Additional props to spread to the input element. */
inputProps?: any;
}
const TextInputGroupMainBase: React.FunctionComponent<TextInputGroupMainProps> = ({
children,
className,
icon,
type = 'text',
hint,
onChange = (): any => undefined,
onFocus,
onBlur,
'aria-label': ariaLabel = 'Type to filter',
value: inputValue,
placeholder: inputPlaceHolder,
innerRef,
name,
'aria-activedescendant': ariaActivedescendant,
role,
isExpanded,
'aria-controls': ariaControls,
inputId,
inputProps,
...props
}: TextInputGroupMainProps) => {
const { isDisabled, validated } = useContext(TextInputGroupContext);
const ref = useRef(null);
const textInputGroupInputInputRef = innerRef || ref;
const hasStatusIcon = ['success', 'error', 'warning'].includes(validated);
const StatusIcon = (() => {
if (!hasStatusIcon) {
return undefined;
}
if (validated === 'error') {
return statusIcons.danger;
}
if (validated === 'success') {
return statusIcons.success;
}
return statusIcons.warning;
})();
const handleChange = (event: React.FormEvent<HTMLInputElement>) => {
onChange(event, event.currentTarget.value);
};
return (
<div className={css(styles.textInputGroupMain, icon && styles.modifiers.icon, className)} {...props}>
{children}
<span className={css(styles.textInputGroupText)}>
{hint && (
<input
className={css(styles.textInputGroupTextInput, styles.modifiers.hint)}
type="text"
disabled
aria-hidden="true"
value={hint}
id={inputId}
/>
)}
{icon && <TextInputGroupIcon>{icon}</TextInputGroupIcon>}
<input
ref={textInputGroupInputInputRef}
type={type}
className={css(styles.textInputGroupTextInput)}
aria-label={ariaLabel}
disabled={isDisabled}
onChange={handleChange}
onFocus={onFocus}
onBlur={onBlur}
value={inputValue || ''}
placeholder={inputPlaceHolder}
name={name}
aria-activedescendant={ariaActivedescendant}
id={inputId}
{...(role && { role })}
{...(isExpanded !== undefined && { 'aria-expanded': isExpanded })}
{...(ariaControls && { 'aria-controls': ariaControls })}
{...inputProps}
/>
{hasStatusIcon && <TextInputGroupIcon isStatus>{<StatusIcon />}</TextInputGroupIcon>}
</span>
</div>
);
};
export const TextInputGroupMain = forwardRef((props: TextInputGroupMainProps, ref: React.Ref<HTMLInputElement>) => (
<TextInputGroupMainBase innerRef={ref as React.MutableRefObject<any>} {...props} />
));
TextInputGroupMain.displayName = 'TextInputGroupMain';