@snack-uikit/fields 0.18.3 → 0.19.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +0 -204
  3. package/dist/components/FieldDate/FieldDate.js +1 -1
  4. package/dist/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
  5. package/dist/components/FieldSelect/FieldSelectMultiple.js +9 -2
  6. package/dist/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
  7. package/dist/components/FieldSelect/FieldSelectSingle.js +16 -4
  8. package/dist/components/FieldSelect/hooks.js +8 -2
  9. package/dist/components/FieldSelect/legacy/components/Items/hooks.d.ts +12 -0
  10. package/dist/components/FieldSelect/legacy/components/Items/hooks.js +33 -0
  11. package/dist/components/FieldSelect/legacy/components/index.d.ts +1 -0
  12. package/dist/components/FieldSelect/legacy/components/index.js +1 -0
  13. package/dist/components/FieldSelect/legacy/hooks.d.ts +5 -0
  14. package/dist/components/FieldSelect/legacy/hooks.js +19 -0
  15. package/dist/components/FieldSelect/legacy/index.d.ts +3 -0
  16. package/dist/components/FieldSelect/legacy/index.js +3 -0
  17. package/dist/components/FieldSelect/legacy/utils.d.ts +29 -0
  18. package/dist/components/FieldSelect/legacy/utils.js +107 -0
  19. package/dist/components/FieldSelect/types.d.ts +6 -3
  20. package/dist/components/FieldSelect/utils/extractListProps.d.ts +1 -1
  21. package/dist/components/FieldSelect/utils/extractListProps.js +1 -3
  22. package/dist/components/FieldSelect/utils/options.js +1 -1
  23. package/dist/components/FieldSelect/utils/typeGuards.js +1 -1
  24. package/dist/components/FieldSelect/utils/updateItems.d.ts +6 -6
  25. package/dist/components/FieldSelect/utils/updateItems.js +12 -3
  26. package/dist/helperComponents/FieldContainerPrivate/styles.module.css +1 -1
  27. package/package.json +15 -13
  28. package/src/components/FieldDate/FieldDate.tsx +1 -1
  29. package/src/components/FieldSelect/FieldSelectMultiple.tsx +10 -2
  30. package/src/components/FieldSelect/FieldSelectSingle.tsx +14 -3
  31. package/src/components/FieldSelect/hooks.ts +11 -2
  32. package/src/components/FieldSelect/legacy/components/Items/hooks.tsx +53 -0
  33. package/src/components/FieldSelect/legacy/components/index.ts +1 -0
  34. package/src/components/FieldSelect/legacy/hooks.ts +32 -0
  35. package/src/components/FieldSelect/legacy/index.ts +3 -0
  36. package/src/components/FieldSelect/legacy/utils.ts +166 -0
  37. package/src/components/FieldSelect/types.ts +29 -12
  38. package/src/components/FieldSelect/utils/extractListProps.ts +0 -4
  39. package/src/components/FieldSelect/utils/options.ts +2 -1
  40. package/src/components/FieldSelect/utils/typeGuards.ts +1 -1
  41. package/src/components/FieldSelect/utils/updateItems.ts +14 -4
@@ -0,0 +1,166 @@
1
+ import { RefObject } from 'react';
2
+
3
+ import {
4
+ AccordionItemProps,
5
+ BaseItemProps,
6
+ isAccordionItemProps,
7
+ isBaseItemProps,
8
+ isGroupItemProps,
9
+ isNextListItemProps,
10
+ ItemProps,
11
+ NextListItemProps,
12
+ } from '@snack-uikit/list';
13
+
14
+ type WithCollapsedItemsProps = {
15
+ items: ItemProps[];
16
+ openCollapsedItems: Array<number | string>;
17
+ };
18
+
19
+ export function withCollapsedItems({ items, openCollapsedItems }: WithCollapsedItemsProps) {
20
+ let itemRefs: RefObject<HTMLElement>[] = [];
21
+ let newItems: ItemProps[] = [];
22
+ let ids: Array<string | number> = [];
23
+ let expandedIds: Array<string | number> = [];
24
+
25
+ items.forEach(item => {
26
+ if (
27
+ ((isBaseItemProps(item) && !item.inactive) || isNextListItemProps(item) || isAccordionItemProps(item)) &&
28
+ !item.disabled
29
+ ) {
30
+ newItems = newItems.concat([item]);
31
+ ids = ids.concat([item.id ?? '']);
32
+
33
+ if (item.itemRef) {
34
+ itemRefs = itemRefs.concat([item.itemRef]);
35
+ }
36
+ }
37
+
38
+ if (isNextListItemProps(item) && item.id && !item.disabled) {
39
+ expandedIds = expandedIds.concat(item.id);
40
+ }
41
+
42
+ if (isGroupItemProps(item)) {
43
+ const { itemRefs: nestedItemsRefs, ids: nestedIds } = withCollapsedItems({
44
+ items: item.items,
45
+ openCollapsedItems,
46
+ });
47
+
48
+ ids = ids.concat(nestedIds);
49
+
50
+ itemRefs = itemRefs.concat(nestedItemsRefs);
51
+ }
52
+
53
+ if (isAccordionItemProps(item) && item.id && openCollapsedItems.includes(item.id)) {
54
+ const {
55
+ itemRefs: nestedItemsRefs,
56
+ ids: nestedIds,
57
+ items: nestedItems,
58
+ expandedIds: nestedExpandedIds,
59
+ } = withCollapsedItems({
60
+ items: item.items,
61
+ openCollapsedItems,
62
+ });
63
+
64
+ ids = ids.concat(nestedIds);
65
+ newItems = newItems.concat(nestedItems);
66
+ itemRefs = itemRefs.concat(nestedItemsRefs);
67
+ expandedIds = expandedIds.concat(nestedExpandedIds);
68
+ }
69
+ });
70
+
71
+ return { items, itemRefs, ids, expandedIds };
72
+ }
73
+
74
+ /**
75
+ * Функция возвращает массив id дочерних items
76
+ * @function extractItemIds
77
+ */
78
+
79
+ export function extractItemIds(items: ItemProps[]): Array<string | number> {
80
+ return items.reduce(
81
+ (prev: Array<string | number>, item: ItemProps) => {
82
+ if (isGroupItemProps(item)) {
83
+ return prev.concat(extractItemIds(item.items));
84
+ }
85
+ return item.id ? prev.concat([item.id]) : prev;
86
+ },
87
+ [] as Array<string | number>,
88
+ );
89
+ }
90
+
91
+ export function extractChildIds({ items }: { items: ItemProps[] }): Array<string | number> {
92
+ return items
93
+ .filter(
94
+ item =>
95
+ isAccordionItemProps(item) ||
96
+ isNextListItemProps(item) ||
97
+ isGroupItemProps(item) ||
98
+ (isBaseItemProps(item) && !item.disabled && !item.inactive),
99
+ )
100
+ .reduce(
101
+ (prev: Array<string | number>, item: ItemProps) => {
102
+ if (isAccordionItemProps(item) || isNextListItemProps(item)) {
103
+ return prev.concat([item.id ?? '']).concat(extractChildIds({ items: item.items }));
104
+ }
105
+
106
+ if (isGroupItemProps(item)) {
107
+ return prev.concat(extractChildIds({ items: item.items }));
108
+ }
109
+
110
+ return item.id && !isGroupItemProps(item) ? prev.concat([item.id]) : prev;
111
+ },
112
+ [] as Array<string | number>,
113
+ );
114
+ }
115
+
116
+ export function extractAllChildIds({ items }: { items: ItemProps[] }): Array<string | number> {
117
+ return items
118
+ .filter(
119
+ item =>
120
+ isAccordionItemProps(item) ||
121
+ isNextListItemProps(item) ||
122
+ isGroupItemProps(item) ||
123
+ (isBaseItemProps(item) && !item.inactive),
124
+ )
125
+ .reduce(
126
+ (prev: Array<string | number>, item: ItemProps) => {
127
+ if (isAccordionItemProps(item) || isNextListItemProps(item)) {
128
+ return prev.concat([item.id ?? '']).concat(extractAllChildIds({ items: item.items }));
129
+ }
130
+
131
+ if (isGroupItemProps(item)) {
132
+ return prev.concat(extractAllChildIds({ items: item.items }));
133
+ }
134
+
135
+ return item.id && !isGroupItemProps(item) ? prev.concat([item.id]) : prev;
136
+ },
137
+ [] as Array<string | number>,
138
+ );
139
+ }
140
+
141
+ /**
142
+ *  Функция разворачивает массив айтемов в плоский список
143
+ * @function flattenItems
144
+ */
145
+
146
+ export function flattenItems(items: ItemProps[]): (BaseItemProps | AccordionItemProps | NextListItemProps)[] {
147
+ const flattenItems: (BaseItemProps | AccordionItemProps | NextListItemProps)[] = [];
148
+
149
+ function flatten(item: ItemProps) {
150
+ if (!isGroupItemProps(item)) {
151
+ flattenItems.push(item);
152
+ }
153
+
154
+ if ('items' in item) {
155
+ for (const nestedItem of item.items) {
156
+ flatten(nestedItem);
157
+ }
158
+ }
159
+ }
160
+
161
+ for (const item of items) {
162
+ flatten(item);
163
+ }
164
+
165
+ return flattenItems;
166
+ }
@@ -6,6 +6,7 @@ import {
6
6
  BaseItemProps,
7
7
  DroplistProps,
8
8
  GroupItemProps,
9
+ ItemContentProps,
9
10
  NextListItemProps,
10
11
  SelectionMultipleState,
11
12
  SelectionSingleState,
@@ -15,17 +16,33 @@ import { WithSupportProps } from '@snack-uikit/utils';
15
16
 
16
17
  import { FieldDecoratorProps } from '../FieldDecorator';
17
18
 
18
- // eslint-disable-next-line no-use-before-define
19
- export type OptionProps = BaseOptionProps | AccordionOptionProps | GroupOptionProps | NestListOptionProps;
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ export type AnyType = any;
21
+
22
+ export type OptionProps =
23
+ // eslint-disable-next-line no-use-before-define
24
+ | BaseOptionProps
25
+ // eslint-disable-next-line no-use-before-define
26
+ | AccordionOptionProps
27
+ // eslint-disable-next-line no-use-before-define
28
+ | GroupOptionProps
29
+ // eslint-disable-next-line no-use-before-define
30
+ | NestListOptionProps;
20
31
 
21
32
  // eslint-disable-next-line no-use-before-define
22
33
  export type OptionWithoutGroup = BaseOptionProps | AccordionOptionProps | NestListOptionProps;
23
34
 
24
35
  export type BaseOptionProps = Pick<BaseItemProps, 'beforeContent' | 'afterContent' | 'disabled'> &
25
- BaseItemProps['content'] & { value: string | number } & Pick<TagProps, 'appearance'>;
36
+ Pick<ItemContentProps, 'option' | 'caption' | 'description'> & { value: string | number } & Pick<
37
+ TagProps,
38
+ 'appearance'
39
+ >;
26
40
 
27
41
  export type AccordionOptionProps = Pick<AccordionItemProps, 'type'> & BaseOptionProps & { options: OptionProps[] };
28
- export type GroupOptionProps = Omit<GroupItemProps, 'items' | 'id'> & { options: OptionProps[] };
42
+
43
+ export type GroupOptionProps = Omit<GroupItemProps, 'items' | 'id'> & {
44
+ options: OptionProps[];
45
+ };
29
46
  export type NestListOptionProps = Pick<NextListItemProps, 'type' | 'onSublistOpenChanged' | 'id'> &
30
47
  BaseOptionProps & { options: OptionProps[] };
31
48
 
@@ -65,6 +82,10 @@ export type FieldSelectPrivateProps = InputProps & WrapperProps & { options: Opt
65
82
 
66
83
  type FiledSelectCommonProps = WithSupportProps<{
67
84
  options: OptionProps[];
85
+
86
+ pinTop: OptionProps[];
87
+ pinBottom: OptionProps[];
88
+
68
89
  searchable?: boolean;
69
90
  /** Отображение кнопки Копировать для поля (актуально только для `readonly = true`) */
70
91
  showCopyButton?: boolean;
@@ -98,20 +119,16 @@ type FiledSelectCommonProps = WithSupportProps<{
98
119
 
99
120
  selectedOptionFormatter?: SelectedOptionFormatter;
100
121
  }> &
101
- Pick<
102
- DroplistProps,
103
- 'dataError' | 'noDataState' | 'noResultsState' | 'errorDataState' | 'pinTop' | 'pinBottom' | 'dataFiltered'
104
- >;
122
+ Pick<DroplistProps, 'dataError' | 'noDataState' | 'noResultsState' | 'errorDataState' | 'dataFiltered'>;
105
123
 
106
124
  export type FieldSelectSingleProps = FieldSelectPrivateProps &
107
125
  Omit<SelectionSingleState, 'mode'> &
108
126
  WrapperProps &
109
127
  FiledSelectCommonProps;
110
128
 
111
- export type FieldSelectMultipleProps = FieldSelectPrivateProps & { removeByBackspace?: boolean } & Omit<
112
- SelectionMultipleState,
113
- 'mode'
114
- > &
129
+ export type FieldSelectMultipleProps = FieldSelectPrivateProps & {
130
+ removeByBackspace?: boolean;
131
+ } & Omit<SelectionMultipleState, 'mode'> &
115
132
  Omit<FiledSelectCommonProps, 'showCopyButton'>;
116
133
 
117
134
  export type FieldSelectProps =
@@ -7,8 +7,6 @@ export function extractListProps({
7
7
  noDataState,
8
8
  noResultsState,
9
9
  errorDataState,
10
- pinTop,
11
- pinBottom,
12
10
  dataFiltered,
13
11
  loading,
14
12
  footer,
@@ -19,8 +17,6 @@ export function extractListProps({
19
17
  noDataState,
20
18
  noResultsState,
21
19
  errorDataState,
22
- pinTop,
23
- pinBottom,
24
20
  dataFiltered,
25
21
  loading,
26
22
  footer,
@@ -1,6 +1,7 @@
1
- import { flattenItems, ItemProps, SelectionSingleValueType } from '@snack-uikit/list';
1
+ import { ItemProps, SelectionSingleValueType } from '@snack-uikit/list';
2
2
  import { TagProps } from '@snack-uikit/tag';
3
3
 
4
+ import { flattenItems } from '../legacy';
4
5
  import { BaseOptionProps, ItemWithId, OptionProps } from '../types';
5
6
  import { isAccordionOptionProps, isGroupOptionProps, isNextListOptionProps } from './typeGuards';
6
7
 
@@ -24,7 +24,7 @@ export function isNextListOptionProps(option: any): option is NestListOptionProp
24
24
 
25
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
26
  export function isGroupOptionProps(option: any): option is GroupOptionProps {
27
- return 'options' in option && option['type'] === undefined;
27
+ return 'options' in option && option['type'] === 'group';
28
28
  }
29
29
 
30
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1,5 +1,6 @@
1
- import { flattenItems, ItemProps, SelectionSingleValueType } from '@snack-uikit/list';
1
+ import { ItemId, ItemProps, SelectionSingleValueType } from '@snack-uikit/list';
2
2
 
3
+ import { flattenItems } from '../legacy';
3
4
  import { ItemWithId, OptionProps } from '../types';
4
5
  import { transformOptionsToItems } from './options';
5
6
 
@@ -13,7 +14,7 @@ export function updateItems({
13
14
  selectedItem,
14
15
  }: {
15
16
  options: OptionProps[];
16
- value: SelectionSingleValueType;
17
+ value?: ItemId;
17
18
  selectedItem?: ItemWithId;
18
19
  currentItems?: ItemProps[];
19
20
  }) {
@@ -67,14 +68,23 @@ export function updateMultipleItems({
67
68
  };
68
69
  }
69
70
 
71
+ const foundedValue: (number | string)[] = [];
72
+
70
73
  let newItems: ItemProps[] = originalItems;
71
74
  let newSelectedItems = selectedItems;
72
75
 
73
76
  const flattenOriginalItems = flattenItems(originalItems);
74
77
 
75
- const foundItems: ItemWithId[] = flattenOriginalItems.filter(item => value.includes(item.id));
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ const foundItems: ItemWithId[] = flattenOriginalItems.filter((item: any) => {
80
+ if (value.includes(item.id) && !foundedValue.includes(item.id)) {
81
+ foundedValue.push(item.id);
82
+ return true;
83
+ }
84
+ });
76
85
  const nonFoundValues: SelectionSingleValueType[] = value.filter(
77
- value => !flattenOriginalItems.find(item => item.id === value),
86
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
+ value => !flattenOriginalItems.find((item: any) => item.id === value),
78
88
  );
79
89
 
80
90
  if (nonFoundValues.length) {