-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInputText.tsx
More file actions
122 lines (111 loc) · 3.81 KB
/
InputText.tsx
File metadata and controls
122 lines (111 loc) · 3.81 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
import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
import BaseInput from '@ids-internal/partials/BaseInput';
import ClearBtn from '../../ui/ClearBtn';
import { createCssClassNames } from '@ids-internal/shared/css.class.names';
import withStateValue from '@ids-internal/hoc/withStateValue';
import { ComponentEntryDataType } from '@ids-types/general';
import { InputTextProps } from './InputText.types';
const InputText = ({
name,
onBlur = () => undefined,
onChange = () => undefined,
onFocus = () => undefined,
onInput = () => undefined,
disabled = false,
error = false,
extraAria = {},
className = '',
id = undefined,
placeholder = '',
processActions = (actions): ComponentEntryDataType[] => actions,
readOnly = false,
required = false,
size = 'medium',
title = '',
type = 'text',
value = '',
}: InputTextProps) => {
const actionsRef = useRef<HTMLDivElement>(null);
const [sourcePadding, setSourcePadding] = useState(0);
const inputTextClassName = createCssClassNames({
'ids-input-text': true,
[className]: true,
});
const componentOnBlur = (event: React.FocusEvent<HTMLInputElement>) => {
onBlur(event);
};
const componentOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.value, event);
};
const componentOnFocus = (event: React.FocusEvent<HTMLInputElement>) => {
onFocus(event);
};
const componentOnInput = (event: React.ChangeEvent<HTMLInputElement>) => {
onInput(event.target.value, event);
};
const actions = useMemo((): ComponentEntryDataType[] => {
const baseActions: ComponentEntryDataType[] = [];
if (value) {
baseActions.push({
component: (
<ClearBtn
disabled={disabled}
onClick={() => {
onChange('');
}}
/>
),
id: 'clear',
});
}
return processActions(baseActions);
}, [disabled, onChange, processActions, value]);
const renderActions = () => {
if (actions.length === 0) {
return null;
}
return (
<div className="ids-input-text__actions" ref={actionsRef}>
{actions.map((action) => (
<div className="ids-input-text__action" key={action.id}>
{action.component}
</div>
))}
</div>
);
};
useLayoutEffect(() => {
const actionsWidth = actionsRef.current?.offsetWidth ?? 0;
setSourcePadding(actionsWidth);
}, [value]);
return (
<div className={inputTextClassName}>
<div className="ids-input-text__source">
<BaseInput
disabled={disabled}
error={error}
extraInputAttrs={{
onBlur: componentOnBlur,
onChange: componentOnChange,
onFocus: componentOnFocus,
onInput: componentOnInput,
placeholder,
readOnly,
style: { paddingRight: `${sourcePadding.toString()}px` },
...extraAria,
}}
id={id}
name={name}
required={required}
size={size}
title={title}
type={type}
value={value}
/>
</div>
{renderActions()}
</div>
);
};
export default InputText;
export const InputTextStateful = withStateValue<string | number>(InputText);