"Fossies" - the Fresh Open Source Software Archive 
Member "jitsi-meet-7542/react/features/base/ui/components/web/Input.tsx" (21 Sep 2023, 8754 Bytes) of package /linux/misc/jitsi-meet-7542.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TSX (TypeScript with React) source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "Input.tsx":
jitsi-meet_8719_vs_jitsi-meet_8922.
1 import React, { useCallback } from 'react';
2 import TextareaAutosize from 'react-textarea-autosize';
3 import { makeStyles } from 'tss-react/mui';
4
5 import { isMobileBrowser } from '../../../environment/utils';
6 import Icon from '../../../icons/components/Icon';
7 import { IconCloseCircle } from '../../../icons/svg';
8 import { withPixelLineHeight } from '../../../styles/functions.web';
9 import { IInputProps } from '../types';
10
11 interface IProps extends IInputProps {
12 accessibilityLabel?: string;
13 autoComplete?: string;
14 autoFocus?: boolean;
15 bottomLabel?: string;
16 className?: string;
17 iconClick?: () => void;
18
19 /**
20 * The id to set on the input element.
21 * This is required because we need it internally to tie the input to its
22 * info (label, error) so that screen reader users don't get lost.
23 */
24 id: string;
25 maxLength?: number;
26 maxRows?: number;
27 maxValue?: number;
28 minRows?: number;
29 minValue?: number;
30 mode?: 'text' | 'none' | 'decimal' | 'numeric' | 'tel' | 'search' | ' email' | 'url';
31 name?: string;
32 onBlur?: (e: any) => void;
33 onFocus?: (event: React.FocusEvent) => void;
34 onKeyPress?: (e: React.KeyboardEvent) => void;
35 readOnly?: boolean;
36 required?: boolean;
37 testId?: string;
38 textarea?: boolean;
39 type?: 'text' | 'email' | 'number' | 'password';
40 }
41
42 const useStyles = makeStyles()(theme => {
43 return {
44 inputContainer: {
45 display: 'flex',
46 flexDirection: 'column'
47 },
48
49 label: {
50 color: theme.palette.text01,
51 ...withPixelLineHeight(theme.typography.bodyShortRegular),
52 marginBottom: theme.spacing(2),
53
54 '&.is-mobile': {
55 ...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
56 }
57 },
58
59 fieldContainer: {
60 position: 'relative',
61 display: 'flex'
62 },
63
64 input: {
65 backgroundColor: theme.palette.ui03,
66 background: theme.palette.ui03,
67 color: theme.palette.text01,
68 ...withPixelLineHeight(theme.typography.bodyShortRegular),
69 padding: '10px 16px',
70 borderRadius: theme.shape.borderRadius,
71 border: 0,
72 height: '40px',
73 boxSizing: 'border-box',
74 width: '100%',
75
76 '&::placeholder': {
77 color: theme.palette.text02
78 },
79
80 '&:focus': {
81 outline: 0,
82 boxShadow: `0px 0px 0px 2px ${theme.palette.focus01}`
83 },
84
85 '&:disabled': {
86 color: theme.palette.text03
87 },
88
89 '&.is-mobile': {
90 height: '48px',
91 padding: '13px 16px',
92 ...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
93 },
94
95 '&.icon-input': {
96 paddingLeft: '46px'
97 },
98
99 '&.error': {
100 boxShadow: `0px 0px 0px 2px ${theme.palette.textError}`
101 }
102 },
103
104 'input::-webkit-outer-spin-button, input::-webkit-inner-spin-button': {
105 '-webkit-appearance': 'none',
106 margin: 0
107 },
108
109 'input[type=number]': {
110 '-moz-appearance': 'textfield'
111 },
112
113 icon: {
114 position: 'absolute',
115 top: '50%',
116 transform: 'translateY(-50%)',
117 left: '16px'
118 },
119
120 iconClickable: {
121 cursor: 'pointer'
122 },
123
124 clearableInput: {
125 paddingRight: '46px'
126 },
127
128 clearButton: {
129 position: 'absolute',
130 right: '16px',
131 top: '10px',
132 cursor: 'pointer',
133 backgroundColor: theme.palette.action03,
134 border: 0,
135 padding: 0
136 },
137
138 bottomLabel: {
139 marginTop: theme.spacing(2),
140 ...withPixelLineHeight(theme.typography.labelRegular),
141 color: theme.palette.text02,
142
143 '&.is-mobile': {
144 ...withPixelLineHeight(theme.typography.bodyShortRegular)
145 },
146
147 '&.error': {
148 color: theme.palette.textError
149 }
150 }
151 };
152 });
153
154 const Input = React.forwardRef<any, IProps>(({
155 accessibilityLabel,
156 autoComplete,
157 autoFocus,
158 bottomLabel,
159 className,
160 clearable = false,
161 disabled,
162 error,
163 icon,
164 iconClick,
165 id,
166 label,
167 maxValue,
168 maxLength,
169 maxRows,
170 minValue,
171 minRows,
172 mode,
173 name,
174 onBlur,
175 onChange,
176 onFocus,
177 onKeyPress,
178 placeholder,
179 readOnly = false,
180 required,
181 testId,
182 textarea = false,
183 type = 'text',
184 value
185 }: IProps, ref) => {
186 const { classes: styles, cx } = useStyles();
187 const isMobile = isMobileBrowser();
188
189 const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
190 onChange?.(e.target.value), []);
191
192 const clearInput = useCallback(() => onChange?.(''), []);
193
194 return (
195 <div className = { cx(styles.inputContainer, className) }>
196 {label && <label
197 className = { cx(styles.label, isMobile && 'is-mobile') }
198 htmlFor = { id } >
199 {label}
200 </label>}
201 <div className = { styles.fieldContainer }>
202 {icon && <Icon
203 { ...(iconClick ? { tabIndex: 0 } : {}) }
204 className = { cx(styles.icon, iconClick && styles.iconClickable) }
205 onClick = { iconClick }
206 size = { 20 }
207 src = { icon } />}
208 {textarea ? (
209 <TextareaAutosize
210 aria-label = { accessibilityLabel }
211 autoComplete = { autoComplete }
212 autoFocus = { autoFocus }
213 className = { cx(styles.input, isMobile && 'is-mobile',
214 error && 'error', clearable && styles.clearableInput, icon && 'icon-input') }
215 disabled = { disabled }
216 id = { id }
217 maxLength = { maxLength }
218 maxRows = { maxRows }
219 minRows = { minRows }
220 name = { name }
221 onChange = { handleChange }
222 onKeyPress = { onKeyPress }
223 placeholder = { placeholder }
224 readOnly = { readOnly }
225 ref = { ref }
226 required = { required }
227 value = { value } />
228 ) : (
229 <input
230 aria-describedby = { bottomLabel ? `${id}-description` : undefined }
231 aria-label = { accessibilityLabel }
232 autoComplete = { autoComplete }
233 autoFocus = { autoFocus }
234 className = { cx(styles.input, isMobile && 'is-mobile',
235 error && 'error', clearable && styles.clearableInput, icon && 'icon-input') }
236 data-testid = { testId }
237 disabled = { disabled }
238 id = { id }
239 { ...(mode ? { inputmode: mode } : {}) }
240 { ...(type === 'number' ? { max: maxValue } : {}) }
241 maxLength = { maxLength }
242 { ...(type === 'number' ? { min: minValue } : {}) }
243 name = { name }
244 onBlur = { onBlur }
245 onChange = { handleChange }
246 onFocus = { onFocus }
247 onKeyPress = { onKeyPress }
248 placeholder = { placeholder }
249 readOnly = { readOnly }
250 ref = { ref }
251 required = { required }
252 type = { type }
253 value = { value } />
254 )}
255 {clearable && !disabled && value !== '' && <button className = { styles.clearButton }>
256 <Icon
257 onClick = { clearInput }
258 size = { 20 }
259 src = { IconCloseCircle } />
260 </button>}
261 </div>
262 {bottomLabel && (
263 <span
264 className = { cx(styles.bottomLabel, isMobile && 'is-mobile', error && 'error') }
265 id = { `${id}-description` }>
266 {bottomLabel}
267 </span>
268 )}
269 </div>
270 );
271 });
272
273 export default Input;