@cloud-ru/ds-fields 1.0.8-preview-04507fc5.0 → 2.0.0
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/CHANGELOG.md +12 -0
- package/README.md +4 -3
- package/dist/cjs/components/FieldSelect/FieldSelect.js +24 -3
- package/dist/cjs/components/FieldSelect/types.d.ts +2 -2
- package/dist/cjs/components/FieldTextArea/FieldTextArea.d.ts +7 -1
- package/dist/cjs/components/FieldTextArea/FieldTextArea.js +4 -4
- package/dist/esm/components/FieldSelect/FieldSelect.js +24 -3
- package/dist/esm/components/FieldSelect/types.d.ts +2 -2
- package/dist/esm/components/FieldTextArea/FieldTextArea.d.ts +7 -1
- package/dist/esm/components/FieldTextArea/FieldTextArea.js +4 -4
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +20 -20
- package/src/components/FieldSelect/FieldSelect.tsx +33 -6
- package/src/components/FieldSelect/types.ts +2 -2
- package/src/components/FieldTextArea/FieldTextArea.tsx +11 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-ru/ds-fields",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Поля ввода с единой обёрткой label/caption/hint/error и общими осями size/validationState — текст, пароль, число, ползунок, дата, время, выбор, цвет.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,24 +39,24 @@
|
|
|
39
39
|
"classnames": "^2.5.1",
|
|
40
40
|
"merge-refs": "^2.0.0",
|
|
41
41
|
"react-textarea-autosize": "^8.5.9",
|
|
42
|
-
"@cloud-ru/ds-adaptive": "1.0.1",
|
|
43
|
-
"@cloud-ru/ds-bottom-sheet": "1.0.
|
|
44
|
-
"@cloud-ru/ds-
|
|
45
|
-
"@cloud-ru/ds-
|
|
46
|
-
"@cloud-ru/ds-
|
|
47
|
-
"@cloud-ru/ds-
|
|
48
|
-
"@cloud-ru/ds-
|
|
49
|
-
"@cloud-ru/ds-
|
|
50
|
-
"@cloud-ru/ds-
|
|
51
|
-
"@cloud-ru/ds-input-private": "1.0.
|
|
52
|
-
"@cloud-ru/ds-list": "2.0.1
|
|
53
|
-
"@cloud-ru/ds-
|
|
54
|
-
"@cloud-ru/ds-
|
|
55
|
-
"@cloud-ru/ds-
|
|
56
|
-
"@cloud-ru/ds-
|
|
57
|
-
"@cloud-ru/ds-
|
|
58
|
-
"@cloud-ru/ds-tag": "1.0.4
|
|
59
|
-
"@cloud-ru/ds-tooltip": "1.0.
|
|
60
|
-
"@cloud-ru/ds-
|
|
42
|
+
"@cloud-ru/ds-adaptive": "^1.0.1",
|
|
43
|
+
"@cloud-ru/ds-bottom-sheet": "^1.0.3",
|
|
44
|
+
"@cloud-ru/ds-color-picker": "^1.0.3",
|
|
45
|
+
"@cloud-ru/ds-dropdown": "^1.0.3",
|
|
46
|
+
"@cloud-ru/ds-divider": "^1.0.1",
|
|
47
|
+
"@cloud-ru/ds-button": "^1.0.1",
|
|
48
|
+
"@cloud-ru/ds-icons": "^1.0.2",
|
|
49
|
+
"@cloud-ru/ds-calendar": "^1.0.7",
|
|
50
|
+
"@cloud-ru/ds-loader": "^1.0.1",
|
|
51
|
+
"@cloud-ru/ds-input-private": "^1.0.2",
|
|
52
|
+
"@cloud-ru/ds-list": "^2.0.1",
|
|
53
|
+
"@cloud-ru/ds-materials": "^1.0.1",
|
|
54
|
+
"@cloud-ru/ds-skeleton": "^1.0.1",
|
|
55
|
+
"@cloud-ru/ds-slider": "^1.0.3",
|
|
56
|
+
"@cloud-ru/ds-scroll": "^1.0.2",
|
|
57
|
+
"@cloud-ru/ds-utils": "^1.1.0",
|
|
58
|
+
"@cloud-ru/ds-tag": "^1.0.4",
|
|
59
|
+
"@cloud-ru/ds-tooltip": "^1.0.3",
|
|
60
|
+
"@cloud-ru/ds-field-decorator": "^1.0.3"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -141,15 +141,42 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
141
141
|
// строкой при переключении selection) не должен ронять компонент на `.map` строки.
|
|
142
142
|
multiple && Array.isArray(props.defaultValue) ? (props.defaultValue as ItemId[]) : [],
|
|
143
143
|
);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
|
|
145
|
+
// Controlled-режим «залипает»: как только потребитель прислал `value`, локальный стейт больше
|
|
146
|
+
// не читается. Иначе очистка (потребитель ставит `undefined`) откатывалась бы на устаревший
|
|
147
|
+
// локальный выбор и воскрешала прошлое значение.
|
|
148
|
+
const singleControlled = useRef(false);
|
|
149
|
+
const multipleControlled = useRef(false);
|
|
150
|
+
|
|
151
|
+
if (!multiple && props.value !== undefined) {
|
|
152
|
+
singleControlled.current = true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (multiple && Array.isArray(props.value)) {
|
|
156
|
+
multipleControlled.current = true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const singleValue = useMemo<ItemId | undefined>(() => {
|
|
160
|
+
if (multiple) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const raw = singleControlled.current ? (props.value as ItemId | undefined) : singleLocal;
|
|
165
|
+
|
|
166
|
+
// `''` = «значение не выбрано»: формы отдают пустое значение строкой.
|
|
167
|
+
return raw === '' ? undefined : raw;
|
|
168
|
+
}, [multiple, props.value, singleLocal]);
|
|
169
|
+
|
|
148
170
|
const multipleValue = useMemo<ItemId[]>(() => {
|
|
149
171
|
if (!multiple) {
|
|
150
172
|
return [];
|
|
151
173
|
}
|
|
152
|
-
|
|
174
|
+
|
|
175
|
+
if (multipleControlled.current) {
|
|
176
|
+
return Array.isArray(props.value) ? (props.value as ItemId[]) : [];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return multipleLocal;
|
|
153
180
|
}, [multiple, props.value, multipleLocal]);
|
|
154
181
|
|
|
155
182
|
const effectiveValidationState = useMemo(
|
|
@@ -547,7 +574,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
547
574
|
className={cn(fieldStyles.fieldInput, !searchable && styles.readonlyCursor)}
|
|
548
575
|
value={inputValue}
|
|
549
576
|
onChange={searchable ? handleInputChange : undefined}
|
|
550
|
-
placeholder={selectedLabel ? '' : placeholder}
|
|
577
|
+
placeholder={selectedLabel || hasChips ? '' : placeholder}
|
|
551
578
|
disabled={disabled}
|
|
552
579
|
readonly={!searchable || readOnly}
|
|
553
580
|
id={id}
|
|
@@ -163,9 +163,9 @@ type CommonSelectProps = FieldSelectDecoratorProps &
|
|
|
163
163
|
export type FieldSelectSingleProps = CommonSelectProps & {
|
|
164
164
|
/** Режим выбора. По умолчанию `'single'`. */
|
|
165
165
|
selection?: typeof SELECTION_MODE.Single;
|
|
166
|
-
/** Управляемое
|
|
166
|
+
/** Управляемое значение. Пустая строка трактуется как «значение не выбрано». */
|
|
167
167
|
value?: ItemId;
|
|
168
|
-
/** Неуправляемое значение по
|
|
168
|
+
/** Неуправляемое значение по умолчанию. Пустая строка трактуется как «значение не выбрано». */
|
|
169
169
|
defaultValue?: ItemId;
|
|
170
170
|
/** Колбек смены значения */
|
|
171
171
|
onChange?(value: ItemId | undefined): void;
|
|
@@ -105,10 +105,16 @@ type FieldTextAreaOwnProps = {
|
|
|
105
105
|
*/
|
|
106
106
|
showClearButton?: boolean;
|
|
107
107
|
/**
|
|
108
|
-
* Кнопка копирования (видна при value
|
|
108
|
+
* Кнопка копирования (видна при непустом value в режиме readonly, как у остальных полей)
|
|
109
109
|
* @default true
|
|
110
110
|
*/
|
|
111
111
|
showCopyButton?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Показывать кнопку копирования и в обычном (не readonly) режиме — рядом с кнопкой очистки.
|
|
114
|
+
* Опция только для textarea: в многострочном поле копирование значения осмысленно и при вводе.
|
|
115
|
+
* @default false
|
|
116
|
+
*/
|
|
117
|
+
showCopyButtonInEditMode?: boolean;
|
|
112
118
|
/** Колбек после копирования */
|
|
113
119
|
onCopyButtonClick?(): void;
|
|
114
120
|
/** Колбек фокуса */
|
|
@@ -157,6 +163,7 @@ export const FieldTextArea = forwardRef<HTMLTextAreaElement, FieldTextAreaProps>
|
|
|
157
163
|
footer,
|
|
158
164
|
showClearButton: showClearButtonProp = true,
|
|
159
165
|
showCopyButton: showCopyButtonProp = true,
|
|
166
|
+
showCopyButtonInEditMode = false,
|
|
160
167
|
onCopyButtonClick,
|
|
161
168
|
onFocus: onFocusProp,
|
|
162
169
|
onBlur: onBlurProp,
|
|
@@ -192,9 +199,9 @@ export const FieldTextArea = forwardRef<HTMLTextAreaElement, FieldTextAreaProps>
|
|
|
192
199
|
const stringValue = String(value ?? '');
|
|
193
200
|
const isResizable = resizable && !disabled && !readOnly;
|
|
194
201
|
const showClearUi = Boolean(showClearButtonProp && stringValue && !readOnly && !disabled);
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled);
|
|
202
|
+
// По умолчанию copy — только в readonly, как у остальных полей. В editable-режиме кнопка
|
|
203
|
+
// появляется лишь по явному `showCopyButtonInEditMode`; тогда видны обе (clear + copy).
|
|
204
|
+
const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled && (readOnly || showCopyButtonInEditMode));
|
|
198
205
|
|
|
199
206
|
const onClear = useCallback(() => {
|
|
200
207
|
setValue('');
|