@cloud-ru/ds-fields 2.1.3 → 2.2.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 +6 -0
- package/README.md +5 -3
- package/dist/cjs/components/FieldSelect/types.d.ts +14 -3
- package/dist/cjs/components/FieldSelect/utils.d.ts +6 -6
- package/dist/cjs/components/FieldSelect/utils.js +3 -4
- package/dist/esm/components/FieldSelect/types.d.ts +14 -3
- package/dist/esm/components/FieldSelect/utils.d.ts +6 -6
- package/dist/esm/components/FieldSelect/utils.js +3 -4
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/components/FieldSelect/types.ts +12 -3
- package/src/components/FieldSelect/utils.ts +14 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-ru/ds-fields",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Поля ввода с единой обёрткой label/caption/hint/error и общими осями size/validationState — текст, пароль, число, ползунок, дата, время, выбор, цвет.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,20 +43,20 @@
|
|
|
43
43
|
"@cloud-ru/ds-bottom-sheet": "^1.1.1",
|
|
44
44
|
"@cloud-ru/ds-button": "^1.0.2",
|
|
45
45
|
"@cloud-ru/ds-calendar": "^1.0.13",
|
|
46
|
-
"@cloud-ru/ds-color-picker": "^1.0.
|
|
46
|
+
"@cloud-ru/ds-color-picker": "^1.0.6",
|
|
47
47
|
"@cloud-ru/ds-divider": "^1.0.1",
|
|
48
|
-
"@cloud-ru/ds-field-decorator": "^1.0.5",
|
|
49
48
|
"@cloud-ru/ds-dropdown": "^1.0.8",
|
|
50
|
-
"@cloud-ru/ds-
|
|
49
|
+
"@cloud-ru/ds-field-decorator": "^1.0.5",
|
|
51
50
|
"@cloud-ru/ds-input-private": "^1.0.4",
|
|
51
|
+
"@cloud-ru/ds-icons": "^1.1.0",
|
|
52
52
|
"@cloud-ru/ds-list": "^2.1.2",
|
|
53
53
|
"@cloud-ru/ds-loader": "^1.0.1",
|
|
54
54
|
"@cloud-ru/ds-materials": "^1.0.1",
|
|
55
55
|
"@cloud-ru/ds-scroll": "^1.0.2",
|
|
56
56
|
"@cloud-ru/ds-skeleton": "^1.0.1",
|
|
57
|
-
"@cloud-ru/ds-
|
|
57
|
+
"@cloud-ru/ds-slider": "^1.0.4",
|
|
58
|
+
"@cloud-ru/ds-tag": "^1.1.0",
|
|
58
59
|
"@cloud-ru/ds-tooltip": "^1.0.4",
|
|
59
|
-
"@cloud-ru/ds-utils": "^1.1.0"
|
|
60
|
-
"@cloud-ru/ds-slider": "^1.0.4"
|
|
60
|
+
"@cloud-ru/ds-utils": "^1.1.0"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FieldDecoratorProps, ValidationState } from '@cloud-ru/ds-field-decorator';
|
|
2
2
|
import { DroplistProps, ItemId, ItemProps } from '@cloud-ru/ds-list';
|
|
3
|
+
import { Appearance as TagAppearance } from '@cloud-ru/ds-tag';
|
|
3
4
|
import { ValueOf } from '@cloud-ru/ds-utils';
|
|
4
5
|
import { FocusEvent, KeyboardEvent, ReactNode } from 'react';
|
|
5
6
|
|
|
@@ -9,6 +10,14 @@ import { SELECTION_MODE } from './constants';
|
|
|
9
10
|
/** Режим выбора FieldSelect: одно значение или несколько. */
|
|
10
11
|
export type Selection = ValueOf<typeof SELECTION_MODE>;
|
|
11
12
|
|
|
13
|
+
// ItemProps — union с рекурсивными группами, поэтому раздаём поле по всем веткам.
|
|
14
|
+
type WithTagAppearance<T> = T extends { items: ItemProps[] }
|
|
15
|
+
? Omit<T, 'items'> & { appearance?: TagAppearance; items: WithTagAppearance<ItemProps>[] }
|
|
16
|
+
: T & { appearance?: TagAppearance };
|
|
17
|
+
|
|
18
|
+
/** Айтем дроплиста: айтем `@cloud-ru/ds-list` плюс `appearance` — цвет тега выбранного значения при `selection='multiple'`. */
|
|
19
|
+
export type FieldSelectItem = WithTagAppearance<ItemProps>;
|
|
20
|
+
|
|
12
21
|
type FieldSelectDecoratorProps = Omit<FieldDecoratorProps, 'children' | 'validationState' | 'size'>;
|
|
13
22
|
|
|
14
23
|
type DroplistPassthrough = Pick<
|
|
@@ -48,11 +57,11 @@ type CommonSelectProps = FieldSelectDecoratorProps &
|
|
|
48
57
|
/** CSS-класс оболочки поля */
|
|
49
58
|
fieldClassName?: string;
|
|
50
59
|
/** Список айтемов дроплиста (формат `@cloud-ru/ds-list`) */
|
|
51
|
-
items:
|
|
60
|
+
items: FieldSelectItem[];
|
|
52
61
|
/** Пресет-айтемы сверху (формат `@cloud-ru/ds-list`) */
|
|
53
|
-
pinTop?:
|
|
62
|
+
pinTop?: FieldSelectItem[];
|
|
54
63
|
/** Пресет-айтемы снизу (формат `@cloud-ru/ds-list`) */
|
|
55
|
-
pinBottom?:
|
|
64
|
+
pinBottom?: FieldSelectItem[];
|
|
56
65
|
/** Placeholder в триггере, когда нет выбранного значения */
|
|
57
66
|
placeholder?: string;
|
|
58
67
|
/** Иконка перед текстом */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Size } from '@cloud-ru/ds-field-decorator';
|
|
2
|
-
import { ItemId
|
|
2
|
+
import { ItemId } from '@cloud-ru/ds-list';
|
|
3
3
|
import { Appearance as TagAppearance, Size as TagSize } from '@cloud-ru/ds-tag';
|
|
4
4
|
|
|
5
5
|
import { SELECTION_MODE } from './constants';
|
|
6
|
-
import { FieldSelectMultipleProps, FieldSelectProps } from './types';
|
|
6
|
+
import { FieldSelectItem, FieldSelectMultipleProps, FieldSelectProps } from './types';
|
|
7
7
|
|
|
8
8
|
export const TAG_SIZE_MAP: Record<Size, TagSize> = { s: 'xs', m: 'xs', l: 's' };
|
|
9
9
|
|
|
10
|
-
export type WithIdContent = { id?: ItemId; content?: unknown; disabled?: boolean; appearance?:
|
|
10
|
+
export type WithIdContent = { id?: ItemId; content?: unknown; disabled?: boolean; appearance?: TagAppearance };
|
|
11
11
|
|
|
12
12
|
export function extractLabel(item: WithIdContent): string {
|
|
13
13
|
const { content, id } = item;
|
|
@@ -48,29 +48,27 @@ export function extractSearchText(item: WithIdContent): string {
|
|
|
48
48
|
return parts.join(' ');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// Цвет
|
|
52
|
-
//
|
|
51
|
+
// Цвет тега выбранного значения (multiple) — паритет с легаси `option.appearance`.
|
|
52
|
+
// Проверка типа нужна и при типизированном поле: items часто приходят из ответа бэкенда.
|
|
53
53
|
export function extractAppearance(item?: WithIdContent): TagAppearance | undefined {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return typeof a === 'string' ? (a as TagAppearance) : undefined;
|
|
54
|
+
return typeof item?.appearance === 'string' ? item.appearance : undefined;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
export function flatten(items:
|
|
57
|
+
export function flatten(items: FieldSelectItem[]): WithIdContent[] {
|
|
60
58
|
const out: WithIdContent[] = [];
|
|
61
59
|
|
|
62
60
|
for (const item of items) {
|
|
63
61
|
out.push(item as WithIdContent);
|
|
64
62
|
|
|
65
63
|
if ('items' in item && Array.isArray(item.items)) {
|
|
66
|
-
out.push(...flatten(item.items as
|
|
64
|
+
out.push(...flatten(item.items as FieldSelectItem[]));
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
return out;
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
export function findItem(items:
|
|
71
|
+
export function findItem(items: FieldSelectItem[], id: ItemId): WithIdContent | undefined {
|
|
74
72
|
for (const item of flatten(items)) {
|
|
75
73
|
if (item.id === id) {
|
|
76
74
|
return item;
|
|
@@ -102,25 +100,25 @@ export function isFuzzyMatch(haystack: string, needle: string): boolean {
|
|
|
102
100
|
return false;
|
|
103
101
|
}
|
|
104
102
|
|
|
105
|
-
export function filterItems(items:
|
|
103
|
+
export function filterItems(items: FieldSelectItem[], query: string, fuzzy: boolean): FieldSelectItem[] {
|
|
106
104
|
if (!query) {
|
|
107
105
|
return items;
|
|
108
106
|
}
|
|
109
107
|
|
|
110
108
|
const q = query.toLowerCase();
|
|
111
109
|
|
|
112
|
-
const matches = (item:
|
|
110
|
+
const matches = (item: FieldSelectItem): boolean => {
|
|
113
111
|
const text = extractSearchText(item as WithIdContent).toLowerCase();
|
|
114
112
|
|
|
115
113
|
return fuzzy ? isFuzzyMatch(text, q) : text.includes(q);
|
|
116
114
|
};
|
|
117
115
|
|
|
118
|
-
const walk = (list:
|
|
116
|
+
const walk = (list: FieldSelectItem[]): FieldSelectItem[] =>
|
|
119
117
|
list.flatMap(item => {
|
|
120
118
|
if ('items' in item && Array.isArray(item.items)) {
|
|
121
|
-
const filteredChildren = walk(item.items as
|
|
119
|
+
const filteredChildren = walk(item.items as FieldSelectItem[]);
|
|
122
120
|
|
|
123
|
-
return filteredChildren.length > 0 ? [{ ...item, items: filteredChildren } as
|
|
121
|
+
return filteredChildren.length > 0 ? [{ ...item, items: filteredChildren } as FieldSelectItem] : [];
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
return matches(item) ? [item] : [];
|