@capyx/components-library 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -210
- package/dist/addons/AutocompleteInput.d.ts +40 -0
- package/dist/addons/AutocompleteInput.d.ts.map +1 -0
- package/dist/addons/AutocompleteInput.js +101 -0
- package/dist/addons/CharacterCountInput.d.ts +73 -0
- package/dist/addons/CharacterCountInput.d.ts.map +1 -0
- package/dist/addons/CharacterCountInput.js +130 -0
- package/dist/addons/index.d.ts +5 -0
- package/dist/addons/index.d.ts.map +1 -0
- package/dist/addons/index.js +2 -0
- package/dist/components/CheckInput.d.ts +49 -0
- package/dist/components/CheckInput.d.ts.map +1 -0
- package/dist/components/CheckInput.js +58 -0
- package/dist/components/DateInput.d.ts +63 -0
- package/dist/components/DateInput.d.ts.map +1 -0
- package/dist/components/DateInput.js +86 -0
- package/dist/components/FileInput.d.ts +102 -0
- package/dist/components/FileInput.d.ts.map +1 -0
- package/dist/components/FileInput.js +164 -0
- package/dist/components/RichTextInput.d.ts +34 -0
- package/dist/components/RichTextInput.d.ts.map +1 -0
- package/dist/components/RichTextInput.js +57 -0
- package/dist/components/SelectInput.d.ts +54 -0
- package/dist/components/SelectInput.d.ts.map +1 -0
- package/dist/components/SelectInput.js +64 -0
- package/dist/components/SwitchInput.d.ts +46 -0
- package/dist/components/SwitchInput.d.ts.map +1 -0
- package/dist/components/SwitchInput.js +53 -0
- package/dist/components/TagsInput.d.ts +35 -0
- package/dist/components/TagsInput.d.ts.map +1 -0
- package/dist/components/TagsInput.js +67 -0
- package/dist/components/TextAreaInput.d.ts +71 -0
- package/dist/components/TextAreaInput.d.ts.map +1 -0
- package/dist/components/TextAreaInput.js +113 -0
- package/dist/components/TextInput.d.ts +68 -0
- package/dist/components/TextInput.d.ts.map +1 -0
- package/dist/components/TextInput.js +77 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/index.cjs +18 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +87 -72
- package/.storybook/main.ts +0 -33
- package/.storybook/preview.ts +0 -36
- package/.storybook/vitest.setup.ts +0 -7
- package/biome.json +0 -37
- package/lib/addons/CharacterCountInput.tsx +0 -204
- package/lib/addons/index.ts +0 -2
- package/lib/components/CheckInput.tsx +0 -126
- package/lib/components/DateInput.tsx +0 -179
- package/lib/components/FileInput.tsx +0 -353
- package/lib/components/RichTextInput.tsx +0 -112
- package/lib/components/SelectInput.tsx +0 -144
- package/lib/components/SwitchInput.tsx +0 -116
- package/lib/components/TagsInput.tsx +0 -118
- package/lib/components/TextAreaInput.tsx +0 -211
- package/lib/components/TextInput.tsx +0 -381
- package/stories/CharacterCountInput.stories.tsx +0 -104
- package/stories/CheckInput.stories.tsx +0 -80
- package/stories/DateInput.stories.tsx +0 -137
- package/stories/FileInput.stories.tsx +0 -125
- package/stories/RichTextInput.stories.tsx +0 -77
- package/stories/SelectInput.stories.tsx +0 -131
- package/stories/SwitchInput.stories.tsx +0 -80
- package/stories/TagsInput.stories.tsx +0 -69
- package/stories/TextAreaInput.stories.tsx +0 -117
- package/stories/TextInput.stories.tsx +0 -167
- package/vitest.config.ts +0 -37
- package/vitest.shims.d.ts +0 -1
- /package/{lib/components/index.ts → dist/components/index.js} +0 -0
- /package/{lib/index.ts → dist/index.js} +0 -0
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import React, { type FC } from 'react';
|
|
2
|
-
import { Form } from 'react-bootstrap';
|
|
3
|
-
import { Controller, useFormContext } from 'react-hook-form';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Props for the SwitchInput component
|
|
7
|
-
*/
|
|
8
|
-
export type SwitchInputProps = {
|
|
9
|
-
/** The name of the switch input field */
|
|
10
|
-
name: string;
|
|
11
|
-
/** Label text displayed next to the switch */
|
|
12
|
-
label?: string;
|
|
13
|
-
/** Whether the switch is required */
|
|
14
|
-
required?: boolean;
|
|
15
|
-
/** Current on/off state (standalone mode) */
|
|
16
|
-
value?: boolean;
|
|
17
|
-
/** Callback function called when the switch state changes */
|
|
18
|
-
onChange?: (checked: boolean) => void;
|
|
19
|
-
/** Whether the switch is disabled */
|
|
20
|
-
disabled?: boolean;
|
|
21
|
-
/** Custom HTML id for the switch element */
|
|
22
|
-
id?: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* SwitchInput - A toggle switch component with react-hook-form integration
|
|
27
|
-
*
|
|
28
|
-
* Provides a toggle switch input that works both standalone and with react-hook-form.
|
|
29
|
-
* Automatically integrates with FormProvider when available, providing validation
|
|
30
|
-
* and error handling.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```tsx
|
|
34
|
-
* // With react-hook-form
|
|
35
|
-
* <SwitchInput
|
|
36
|
-
* name="notifications"
|
|
37
|
-
* label="Enable notifications"
|
|
38
|
-
* />
|
|
39
|
-
*
|
|
40
|
-
* // Standalone mode
|
|
41
|
-
* <SwitchInput
|
|
42
|
-
* name="darkMode"
|
|
43
|
-
* label="Dark mode"
|
|
44
|
-
* value={isDarkMode}
|
|
45
|
-
* onChange={setIsDarkMode}
|
|
46
|
-
* />
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export const SwitchInput: FC<SwitchInputProps> = ({
|
|
50
|
-
name,
|
|
51
|
-
label,
|
|
52
|
-
required = false,
|
|
53
|
-
value,
|
|
54
|
-
onChange,
|
|
55
|
-
disabled = false,
|
|
56
|
-
id,
|
|
57
|
-
}) => {
|
|
58
|
-
const formContext = useFormContext();
|
|
59
|
-
|
|
60
|
-
const getFieldError = (fieldName: string) => {
|
|
61
|
-
try {
|
|
62
|
-
const error = formContext?.formState?.errors?.[fieldName];
|
|
63
|
-
return error?.message as string | undefined;
|
|
64
|
-
} catch {
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const errorMessage = getFieldError(name);
|
|
70
|
-
const inputId = id || `switch-input-${name}`;
|
|
71
|
-
|
|
72
|
-
// Integrated with react-hook-form
|
|
73
|
-
if (formContext) {
|
|
74
|
-
return (
|
|
75
|
-
<Controller
|
|
76
|
-
name={name}
|
|
77
|
-
control={formContext.control}
|
|
78
|
-
rules={{
|
|
79
|
-
required: required ? `${label || 'This field'} is required` : false,
|
|
80
|
-
}}
|
|
81
|
-
render={({ field }) => (
|
|
82
|
-
<Form.Check
|
|
83
|
-
{...field}
|
|
84
|
-
id={inputId}
|
|
85
|
-
type="switch"
|
|
86
|
-
label={label}
|
|
87
|
-
checked={field.value ?? false}
|
|
88
|
-
onChange={(e) => {
|
|
89
|
-
const checked = e.target.checked;
|
|
90
|
-
field.onChange(checked);
|
|
91
|
-
onChange?.(checked);
|
|
92
|
-
}}
|
|
93
|
-
disabled={disabled}
|
|
94
|
-
required={required}
|
|
95
|
-
isInvalid={!!errorMessage}
|
|
96
|
-
feedback={errorMessage}
|
|
97
|
-
feedbackType="invalid"
|
|
98
|
-
/>
|
|
99
|
-
)}
|
|
100
|
-
/>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Standalone mode
|
|
105
|
-
return (
|
|
106
|
-
<Form.Check
|
|
107
|
-
id={inputId}
|
|
108
|
-
type="switch"
|
|
109
|
-
label={label}
|
|
110
|
-
checked={value ?? false}
|
|
111
|
-
onChange={(e) => onChange?.(e.target.checked)}
|
|
112
|
-
disabled={disabled}
|
|
113
|
-
required={required}
|
|
114
|
-
/>
|
|
115
|
-
);
|
|
116
|
-
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { Autocomplete, Chip, TextField } from '@mui/material';
|
|
2
|
-
import React, { type FC } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Props for the TagsInput component
|
|
6
|
-
*/
|
|
7
|
-
export type TagsInputProps = {
|
|
8
|
-
/** Array of current tag values */
|
|
9
|
-
value: string[];
|
|
10
|
-
/** Callback function called when tags change */
|
|
11
|
-
onChange: (value: string[]) => void;
|
|
12
|
-
/** Placeholder text shown when no tags are entered (default: "Add tags...") */
|
|
13
|
-
placeholder?: string;
|
|
14
|
-
/** Whether the input is disabled */
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
/** Name attribute for the input field */
|
|
17
|
-
name?: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* TagsInput - A multi-tag input component using Material-UI Autocomplete
|
|
22
|
-
*
|
|
23
|
-
* Provides a tag input interface where users can add/remove multiple tags.
|
|
24
|
-
* Automatically trims whitespace and filters empty values. Tags are displayed
|
|
25
|
-
* as chips with delete functionality.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```tsx
|
|
29
|
-
* <TagsInput
|
|
30
|
-
* name="skills"
|
|
31
|
-
* value={tags}
|
|
32
|
-
* onChange={setTags}
|
|
33
|
-
* placeholder="Add skills..."
|
|
34
|
-
* />
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
export const TagsInput: FC<TagsInputProps> = ({
|
|
38
|
-
value = [],
|
|
39
|
-
onChange,
|
|
40
|
-
placeholder = 'Add tags...',
|
|
41
|
-
disabled = false,
|
|
42
|
-
name,
|
|
43
|
-
}) => {
|
|
44
|
-
return (
|
|
45
|
-
<Autocomplete
|
|
46
|
-
multiple
|
|
47
|
-
freeSolo
|
|
48
|
-
options={[]}
|
|
49
|
-
value={value}
|
|
50
|
-
onChange={(_event, newValue) => {
|
|
51
|
-
// Filter out empty strings and trim whitespace
|
|
52
|
-
const cleanedValues = newValue
|
|
53
|
-
.map((v) => (typeof v === 'string' ? v.trim() : v))
|
|
54
|
-
.filter((v) => v.length > 0);
|
|
55
|
-
onChange(cleanedValues);
|
|
56
|
-
}}
|
|
57
|
-
disabled={disabled}
|
|
58
|
-
renderValue={(tagValue, getTagProps) =>
|
|
59
|
-
tagValue.map((option, index) => (
|
|
60
|
-
<Chip
|
|
61
|
-
{...getTagProps({ index })}
|
|
62
|
-
key={option}
|
|
63
|
-
label={option}
|
|
64
|
-
sx={{
|
|
65
|
-
backgroundColor: '#212529',
|
|
66
|
-
color: '#ffffff',
|
|
67
|
-
'& .MuiChip-deleteIcon': {
|
|
68
|
-
color: 'rgba(255, 255, 255, 0.7)',
|
|
69
|
-
userSelect: 'none',
|
|
70
|
-
WebkitUserSelect: 'none',
|
|
71
|
-
MozUserSelect: 'none',
|
|
72
|
-
msUserSelect: 'none',
|
|
73
|
-
pointerEvents: 'auto',
|
|
74
|
-
'&::selection': {
|
|
75
|
-
backgroundColor: 'transparent',
|
|
76
|
-
color: 'transparent',
|
|
77
|
-
},
|
|
78
|
-
'& svg': {
|
|
79
|
-
userSelect: 'none',
|
|
80
|
-
WebkitUserSelect: 'none',
|
|
81
|
-
pointerEvents: 'none',
|
|
82
|
-
},
|
|
83
|
-
'&:hover': {
|
|
84
|
-
color: '#dc3545',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
}}
|
|
88
|
-
/>
|
|
89
|
-
))
|
|
90
|
-
}
|
|
91
|
-
renderInput={(params) => (
|
|
92
|
-
<TextField
|
|
93
|
-
{...params}
|
|
94
|
-
name={name}
|
|
95
|
-
placeholder={value.length === 0 ? placeholder : undefined}
|
|
96
|
-
variant="outlined"
|
|
97
|
-
size="small"
|
|
98
|
-
sx={{
|
|
99
|
-
'& .MuiOutlinedInput-root': {
|
|
100
|
-
padding: '4px',
|
|
101
|
-
minHeight: '38px',
|
|
102
|
-
'& fieldset': {
|
|
103
|
-
borderColor: '#ced4da',
|
|
104
|
-
},
|
|
105
|
-
'&:hover fieldset': {
|
|
106
|
-
borderColor: '#86b7fe',
|
|
107
|
-
},
|
|
108
|
-
'&.Mui-focused fieldset': {
|
|
109
|
-
borderColor: '#86b7fe',
|
|
110
|
-
borderWidth: '1px',
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
}}
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
116
|
-
/>
|
|
117
|
-
);
|
|
118
|
-
};
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import debounce from 'lodash.debounce';
|
|
2
|
-
import React, {
|
|
3
|
-
type ChangeEvent,
|
|
4
|
-
type FC,
|
|
5
|
-
useEffect,
|
|
6
|
-
useLayoutEffect,
|
|
7
|
-
useRef,
|
|
8
|
-
useState,
|
|
9
|
-
} from 'react';
|
|
10
|
-
import { Form } from 'react-bootstrap';
|
|
11
|
-
import { Controller, useFormContext } from 'react-hook-form';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Props for the TextAreaInput component
|
|
15
|
-
*/
|
|
16
|
-
export type TextAreaInputProps = {
|
|
17
|
-
/** The name of the textarea field */
|
|
18
|
-
name: string;
|
|
19
|
-
/** Label text displayed for the textarea */
|
|
20
|
-
label?: string;
|
|
21
|
-
/** Whether the field is required */
|
|
22
|
-
required?: boolean;
|
|
23
|
-
/** Maximum number of characters allowed */
|
|
24
|
-
maxLength?: number;
|
|
25
|
-
/** Size variant of the textarea control */
|
|
26
|
-
controlSize?: 'sm' | 'lg';
|
|
27
|
-
/** Placeholder text shown when textarea is empty */
|
|
28
|
-
placeholder?: string;
|
|
29
|
-
/** Controlled value of the textarea */
|
|
30
|
-
value?: string;
|
|
31
|
-
/** Callback fired when the value changes */
|
|
32
|
-
onChange?: (value: string) => void;
|
|
33
|
-
/** Whether the textarea is disabled */
|
|
34
|
-
disabled?: boolean;
|
|
35
|
-
/** Whether the textarea is read-only */
|
|
36
|
-
isReadOnly?: boolean;
|
|
37
|
-
/** Whether to render as plain text */
|
|
38
|
-
isPlainText?: boolean;
|
|
39
|
-
/** Debounce delay in milliseconds for value changes */
|
|
40
|
-
debounceMs?: number;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const MIN_TEXTAREA_HEIGHT = 32;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* A flexible textarea input component with automatic height adjustment,
|
|
47
|
-
* react-hook-form integration, and optional debouncing.
|
|
48
|
-
*
|
|
49
|
-
* Features:
|
|
50
|
-
* - Auto-expands height based on content
|
|
51
|
-
* - Seamless integration with react-hook-form for validation
|
|
52
|
-
* - Debounced onChange callback to reduce update frequency
|
|
53
|
-
* - Built-in validation rules (required, maxLength)
|
|
54
|
-
* - Works in both controlled and standalone modes
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // Basic usage with react-hook-form
|
|
58
|
-
* <TextAreaInput
|
|
59
|
-
* name="description"
|
|
60
|
-
* label="Description"
|
|
61
|
-
* required
|
|
62
|
-
* maxLength={500}
|
|
63
|
-
* placeholder="Enter description..."
|
|
64
|
-
* />
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* // With custom onChange and debouncing
|
|
68
|
-
* <TextAreaInput
|
|
69
|
-
* name="notes"
|
|
70
|
-
* label="Notes"
|
|
71
|
-
* debounceMs={300}
|
|
72
|
-
* onChange={(value) => console.log(value)}
|
|
73
|
-
* />
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* // Standalone mode without form context
|
|
77
|
-
* <TextAreaInput
|
|
78
|
-
* name="comment"
|
|
79
|
-
* value={commentText}
|
|
80
|
-
* onChange={setCommentText}
|
|
81
|
-
* placeholder="Add your comment..."
|
|
82
|
-
* />
|
|
83
|
-
*/
|
|
84
|
-
export const TextAreaInput: FC<TextAreaInputProps> = ({
|
|
85
|
-
name,
|
|
86
|
-
label,
|
|
87
|
-
required = false,
|
|
88
|
-
maxLength,
|
|
89
|
-
controlSize,
|
|
90
|
-
placeholder,
|
|
91
|
-
value,
|
|
92
|
-
onChange,
|
|
93
|
-
disabled = false,
|
|
94
|
-
isReadOnly = false,
|
|
95
|
-
isPlainText = false,
|
|
96
|
-
debounceMs,
|
|
97
|
-
}) => {
|
|
98
|
-
const formContext = useFormContext();
|
|
99
|
-
|
|
100
|
-
// Create ref for debounced onChange to clean up on unmount
|
|
101
|
-
const debouncedOnChangeRef = useRef<ReturnType<typeof debounce> | null>(null);
|
|
102
|
-
|
|
103
|
-
// Create debounced version of onChange if debounceMs is provided
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
if (debounceMs && onChange) {
|
|
106
|
-
debouncedOnChangeRef.current = debounce(onChange, debounceMs);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Cleanup on unmount
|
|
110
|
-
return () => {
|
|
111
|
-
debouncedOnChangeRef.current?.cancel();
|
|
112
|
-
};
|
|
113
|
-
}, [debounceMs, onChange]);
|
|
114
|
-
|
|
115
|
-
// Helper to handle onChange with optional debouncing
|
|
116
|
-
const handleChange = (value: string) => {
|
|
117
|
-
if (debounceMs && debouncedOnChangeRef.current) {
|
|
118
|
-
debouncedOnChangeRef.current(value);
|
|
119
|
-
} else if (onChange) {
|
|
120
|
-
onChange(value);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const getFieldError = (fieldName: string) => {
|
|
125
|
-
try {
|
|
126
|
-
const error = formContext?.formState?.errors?.[fieldName];
|
|
127
|
-
return error?.message as string | undefined;
|
|
128
|
-
} catch {
|
|
129
|
-
return undefined;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const errorMessage = getFieldError(name);
|
|
134
|
-
const isInvalid = !!errorMessage;
|
|
135
|
-
|
|
136
|
-
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
137
|
-
const [_textAreaValue, setTextAreaValue] = useState('');
|
|
138
|
-
|
|
139
|
-
const _handleTextAreaChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
|
140
|
-
setTextAreaValue(event.target.value);
|
|
141
|
-
handleChange(event.target.value);
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
useLayoutEffect(() => {
|
|
145
|
-
if (textareaRef.current) {
|
|
146
|
-
textareaRef.current.style.height = 'inherit';
|
|
147
|
-
textareaRef.current.style.height = `${Math.max(
|
|
148
|
-
textareaRef.current.scrollHeight,
|
|
149
|
-
MIN_TEXTAREA_HEIGHT,
|
|
150
|
-
)}px`;
|
|
151
|
-
}
|
|
152
|
-
}, []);
|
|
153
|
-
|
|
154
|
-
// Integrated with react-hook-form
|
|
155
|
-
if (formContext) {
|
|
156
|
-
return (
|
|
157
|
-
<Controller
|
|
158
|
-
name={name}
|
|
159
|
-
control={formContext.control}
|
|
160
|
-
rules={{
|
|
161
|
-
required: required ? `${label || 'This field'} is required` : false,
|
|
162
|
-
maxLength: maxLength
|
|
163
|
-
? {
|
|
164
|
-
value: maxLength,
|
|
165
|
-
message: `Maximum ${maxLength} characters allowed`,
|
|
166
|
-
}
|
|
167
|
-
: undefined,
|
|
168
|
-
}}
|
|
169
|
-
render={({ field }) => (
|
|
170
|
-
<Form.Control
|
|
171
|
-
{...field}
|
|
172
|
-
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
173
|
-
field.onChange(e);
|
|
174
|
-
setTextAreaValue(e.target.value);
|
|
175
|
-
handleChange(e.target.value);
|
|
176
|
-
}}
|
|
177
|
-
ref={textareaRef}
|
|
178
|
-
style={{
|
|
179
|
-
minHeight: MIN_TEXTAREA_HEIGHT,
|
|
180
|
-
resize: 'none',
|
|
181
|
-
}}
|
|
182
|
-
as="textarea"
|
|
183
|
-
required={required}
|
|
184
|
-
maxLength={maxLength}
|
|
185
|
-
size={controlSize}
|
|
186
|
-
placeholder={placeholder}
|
|
187
|
-
disabled={disabled}
|
|
188
|
-
readOnly={isReadOnly}
|
|
189
|
-
plaintext={isPlainText}
|
|
190
|
-
isInvalid={isInvalid}
|
|
191
|
-
/>
|
|
192
|
-
)}
|
|
193
|
-
/>
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Standalone mode
|
|
198
|
-
return (
|
|
199
|
-
<Form.Control
|
|
200
|
-
as="textarea"
|
|
201
|
-
required={required}
|
|
202
|
-
maxLength={maxLength}
|
|
203
|
-
size={controlSize}
|
|
204
|
-
placeholder={placeholder}
|
|
205
|
-
value={value || ''}
|
|
206
|
-
disabled={disabled}
|
|
207
|
-
readOnly={isReadOnly}
|
|
208
|
-
plaintext={isPlainText}
|
|
209
|
-
/>
|
|
210
|
-
);
|
|
211
|
-
};
|