@cloud-ru/ds-fields 1.0.2-preview-cd0cd6fb.0 → 1.0.2
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 +6 -0
- package/dist/cjs/components/FieldSelect/FieldSelect.js +14 -4
- package/dist/cjs/components/FieldTextArea/FieldTextArea.js +0 -5
- package/dist/esm/components/FieldSelect/FieldSelect.js +15 -5
- package/dist/esm/components/FieldTextArea/FieldTextArea.js +1 -6
- 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 +27 -5
- package/src/components/FieldTextArea/FieldTextArea.tsx +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-ru/ds-fields",
|
|
3
|
-
"version": "1.0.2
|
|
3
|
+
"version": "1.0.2",
|
|
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-
|
|
43
|
-
"@cloud-ru/ds-
|
|
44
|
-
"@cloud-ru/ds-bottom-sheet": "1.0.0",
|
|
45
|
-
"@cloud-ru/ds-calendar": "1.0.
|
|
46
|
-
"@cloud-ru/ds-color-picker": "1.0.0",
|
|
47
|
-
"@cloud-ru/ds-divider": "1.0.0",
|
|
48
|
-
"@cloud-ru/ds-dropdown": "1.0.0",
|
|
49
|
-
"@cloud-ru/ds-field-decorator": "1.0.0",
|
|
50
|
-
"@cloud-ru/ds-
|
|
51
|
-
"@cloud-ru/ds-list": "1.1.
|
|
52
|
-
"@cloud-ru/ds-
|
|
53
|
-
"@cloud-ru/ds-loader": "1.0.0",
|
|
54
|
-
"@cloud-ru/ds-materials": "1.0.0",
|
|
55
|
-
"@cloud-ru/ds-scroll": "1.0.0",
|
|
56
|
-
"@cloud-ru/ds-
|
|
57
|
-
"@cloud-ru/ds-
|
|
58
|
-
"@cloud-ru/ds-tooltip": "1.0.0",
|
|
59
|
-
"@cloud-ru/ds-tag": "1.0.
|
|
60
|
-
"@cloud-ru/ds-utils": "1.0.0"
|
|
42
|
+
"@cloud-ru/ds-adaptive": "^1.0.0",
|
|
43
|
+
"@cloud-ru/ds-button": "^1.0.0",
|
|
44
|
+
"@cloud-ru/ds-bottom-sheet": "^1.0.0",
|
|
45
|
+
"@cloud-ru/ds-calendar": "^1.0.1",
|
|
46
|
+
"@cloud-ru/ds-color-picker": "^1.0.0",
|
|
47
|
+
"@cloud-ru/ds-divider": "^1.0.0",
|
|
48
|
+
"@cloud-ru/ds-dropdown": "^1.0.0",
|
|
49
|
+
"@cloud-ru/ds-field-decorator": "^1.0.0",
|
|
50
|
+
"@cloud-ru/ds-icons": "^1.0.0",
|
|
51
|
+
"@cloud-ru/ds-list": "^1.1.0",
|
|
52
|
+
"@cloud-ru/ds-input-private": "^1.0.0",
|
|
53
|
+
"@cloud-ru/ds-loader": "^1.0.0",
|
|
54
|
+
"@cloud-ru/ds-materials": "^1.0.0",
|
|
55
|
+
"@cloud-ru/ds-scroll": "^1.0.0",
|
|
56
|
+
"@cloud-ru/ds-skeleton": "^1.0.0",
|
|
57
|
+
"@cloud-ru/ds-slider": "^1.0.0",
|
|
58
|
+
"@cloud-ru/ds-tooltip": "^1.0.0",
|
|
59
|
+
"@cloud-ru/ds-tag": "^1.0.1",
|
|
60
|
+
"@cloud-ru/ds-utils": "^1.0.0"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -37,7 +37,16 @@ import {
|
|
|
37
37
|
import fieldStyles from '../shared/styles.module.scss';
|
|
38
38
|
import styles from './styles.module.scss';
|
|
39
39
|
import { FieldSelectProps } from './types';
|
|
40
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
extractAppearance,
|
|
42
|
+
extractLabel,
|
|
43
|
+
filterItems,
|
|
44
|
+
findItem,
|
|
45
|
+
flatten,
|
|
46
|
+
isMultiple,
|
|
47
|
+
TAG_SIZE_MAP,
|
|
48
|
+
WithIdContent,
|
|
49
|
+
} from './utils';
|
|
41
50
|
|
|
42
51
|
export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(function FieldSelect(props, ref) {
|
|
43
52
|
const {
|
|
@@ -150,6 +159,19 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
150
159
|
|
|
151
160
|
const allItems = useMemo(() => [...(pinTop ?? []), ...items, ...(pinBottom ?? [])], [items, pinTop, pinBottom]);
|
|
152
161
|
|
|
162
|
+
// Выбранное значение переживает смену `items` (серверный поиск, ленивая подгрузка).
|
|
163
|
+
const seenItems = useRef(new Map<ItemId, WithIdContent>());
|
|
164
|
+
|
|
165
|
+
const resolveItem = useMemo(() => {
|
|
166
|
+
for (const item of flatten(allItems)) {
|
|
167
|
+
if (item.id !== undefined) {
|
|
168
|
+
seenItems.current.set(item.id, item);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return (id: ItemId) => findItem(allItems, id) ?? seenItems.current.get(id);
|
|
173
|
+
}, [allItems]);
|
|
174
|
+
|
|
153
175
|
const selectedPairs = useMemo(() => {
|
|
154
176
|
if (!multiple || multipleValue.length === 0) {
|
|
155
177
|
return [];
|
|
@@ -157,7 +179,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
157
179
|
|
|
158
180
|
// Неизвестное значение (ещё не загружены опции) показываем по его id, не теряем (паритет с легаси).
|
|
159
181
|
return multipleValue.map(id => {
|
|
160
|
-
const item =
|
|
182
|
+
const item = resolveItem(id);
|
|
161
183
|
|
|
162
184
|
return {
|
|
163
185
|
id,
|
|
@@ -166,7 +188,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
166
188
|
appearance: extractAppearance(item),
|
|
167
189
|
};
|
|
168
190
|
});
|
|
169
|
-
}, [
|
|
191
|
+
}, [multiple, multipleValue, resolveItem]);
|
|
170
192
|
|
|
171
193
|
const formatPair = useCallback(
|
|
172
194
|
(pair: { id: ItemId; label: string }) => (selectedOptionFormatter ? selectedOptionFormatter(pair) : pair.label),
|
|
@@ -179,7 +201,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
179
201
|
return '';
|
|
180
202
|
}
|
|
181
203
|
|
|
182
|
-
const item =
|
|
204
|
+
const item = resolveItem(singleValue);
|
|
183
205
|
const label = item ? extractLabel(item) : String(singleValue);
|
|
184
206
|
|
|
185
207
|
return formatPair({ id: singleValue, label });
|
|
@@ -194,7 +216,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
|
|
|
194
216
|
}
|
|
195
217
|
|
|
196
218
|
return selectedPairs.map(formatPair).join(', ');
|
|
197
|
-
}, [
|
|
219
|
+
}, [multiple, singleValue, selectedPairs, chips, props, formatPair, resolveItem]);
|
|
198
220
|
|
|
199
221
|
// Строка поиска: controlled через `search.value`, иначе локальный state. Auto-sync к выбранному
|
|
200
222
|
// значению делаем через СТАБИЛЬНЫЙ setLocalInput, а не через setInputValue в deps эффекта —
|
|
@@ -14,9 +14,7 @@ import {
|
|
|
14
14
|
MouseEvent,
|
|
15
15
|
ReactNode,
|
|
16
16
|
useCallback,
|
|
17
|
-
useEffect,
|
|
18
17
|
useMemo,
|
|
19
|
-
useReducer,
|
|
20
18
|
useRef,
|
|
21
19
|
useState,
|
|
22
20
|
} from 'react';
|
|
@@ -172,12 +170,6 @@ export const FieldTextArea = forwardRef<HTMLTextAreaElement, FieldTextAreaProps>
|
|
|
172
170
|
const [focusVisible, setFocusVisible] = useState(false);
|
|
173
171
|
const [hover, setHover] = useState(false);
|
|
174
172
|
|
|
175
|
-
// autosize меряет высоту до того, как ThemeScope навесит классы темы — пересчитываем после mount.
|
|
176
|
-
const [, remeasure] = useReducer((tick: number) => tick + 1, 0);
|
|
177
|
-
useEffect(() => {
|
|
178
|
-
remeasure();
|
|
179
|
-
}, []);
|
|
180
|
-
|
|
181
173
|
const resolvedAutoFocus = useAdaptiveAutoFocus(autoFocus, layoutPresets);
|
|
182
174
|
|
|
183
175
|
// controlled/uncontrolled: useValueControl держит внутреннее состояние при отсутствии `value`,
|