@snack-uikit/list 0.3.5 → 0.4.1-preview-2484f987.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 (60) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +28 -10
  3. package/dist/components/Items/AccordionItem/AccordionItem.js +3 -6
  4. package/dist/components/Items/BaseItem/BaseItem.js +1 -1
  5. package/dist/components/Items/BaseItem/styles.module.css +7 -11
  6. package/dist/components/Items/hooks.js +10 -10
  7. package/dist/components/Items/styles.module.css +5 -5
  8. package/dist/components/Items/types.d.ts +1 -0
  9. package/dist/components/Items/utils.js +5 -4
  10. package/dist/components/Lists/Droplist/DropList.js +8 -11
  11. package/dist/components/Lists/List/List.d.ts +3 -5
  12. package/dist/components/Lists/List/List.js +1 -6
  13. package/dist/components/Lists/ListPrivate/ListPrivate.d.ts +3 -5
  14. package/dist/components/Lists/ListPrivate/ListPrivate.js +10 -10
  15. package/dist/components/Lists/contexts/SelectionProvider.d.ts +3 -3
  16. package/dist/components/Lists/contexts/SelectionProvider.js +14 -11
  17. package/dist/components/Lists/index.d.ts +1 -1
  18. package/dist/components/Lists/styles.module.css +0 -14
  19. package/dist/components/Lists/types.d.ts +23 -10
  20. package/dist/components/index.d.ts +1 -0
  21. package/dist/components/index.js +1 -0
  22. package/dist/helperComponents/ListEmptyState/ListEmptyState.d.ts +14 -0
  23. package/dist/helperComponents/ListEmptyState/ListEmptyState.js +9 -0
  24. package/dist/helperComponents/ListEmptyState/hooks.d.ts +10 -0
  25. package/dist/helperComponents/ListEmptyState/hooks.js +16 -0
  26. package/dist/helperComponents/ListEmptyState/index.d.ts +2 -0
  27. package/dist/helperComponents/ListEmptyState/index.js +2 -0
  28. package/dist/helperComponents/ListEmptyState/styles.module.css +8 -0
  29. package/dist/helperComponents/index.d.ts +1 -0
  30. package/dist/helperComponents/index.js +1 -0
  31. package/dist/hooks.d.ts +2 -0
  32. package/dist/hooks.js +29 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/index.js +2 -0
  35. package/dist/utils.d.ts +3 -0
  36. package/dist/utils.js +17 -0
  37. package/package.json +12 -3
  38. package/src/components/Items/AccordionItem/AccordionItem.tsx +4 -7
  39. package/src/components/Items/BaseItem/BaseItem.tsx +1 -0
  40. package/src/components/Items/BaseItem/styles.module.scss +3 -6
  41. package/src/components/Items/hooks.tsx +13 -10
  42. package/src/components/Items/styles.module.scss +2 -2
  43. package/src/components/Items/types.ts +2 -0
  44. package/src/components/Items/utils.ts +5 -3
  45. package/src/components/Lists/Droplist/DropList.tsx +13 -12
  46. package/src/components/Lists/List/List.tsx +1 -5
  47. package/src/components/Lists/ListPrivate/ListPrivate.tsx +50 -48
  48. package/src/components/Lists/contexts/SelectionProvider.tsx +11 -8
  49. package/src/components/Lists/index.ts +3 -0
  50. package/src/components/Lists/styles.module.scss +0 -12
  51. package/src/components/Lists/types.ts +27 -10
  52. package/src/components/index.ts +2 -0
  53. package/src/helperComponents/ListEmptyState/ListEmptyState.tsx +35 -0
  54. package/src/helperComponents/ListEmptyState/hooks.ts +42 -0
  55. package/src/helperComponents/ListEmptyState/index.ts +2 -0
  56. package/src/helperComponents/ListEmptyState/styles.module.scss +11 -0
  57. package/src/helperComponents/index.ts +1 -0
  58. package/src/hooks.ts +45 -0
  59. package/src/index.ts +3 -0
  60. package/src/utils.ts +25 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 0.4.0 (2024-02-23)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **FF-4221:** fix keygen for items ([1d542c0](https://github.com/cloud-ru-tech/snack-uikit/commit/1d542c055c3a8a89b875bdb1e3cb4c1fcacd0a5a))
12
+ * **FF-4221:** fix selection/clean with disabled items; remove useless toggle-group ([d630d3c](https://github.com/cloud-ru-tech/snack-uikit/commit/d630d3c01c818c74eb30d6ec92c577476e847cb2))
13
+ * **FF-4221:** fix some select bugs; add some type exports ([e5435f1](https://github.com/cloud-ru-tech/snack-uikit/commit/e5435f18fb766456ae74452d529e797e9df36f20))
14
+
15
+
16
+ ### Features
17
+
18
+ * **FF-4221:** add ListEmptyState with translations ([83b3758](https://github.com/cloud-ru-tech/snack-uikit/commit/83b375876ff9a9b0ac294a67199a8b4d4ccbe799))
19
+
20
+
21
+ ### BREAKING CHANGES
22
+
23
+
24
+ * **FF-4221:** remove noData/noResults props; instead added: noDataState,noResultsState,errorDataState, dataError, dataFiltered; replace local "info-block" ([5b18ea2](https://github.com/cloud-ru-tech/snack-uikit/commit/5b18ea209ca33b7773f356e52c3ab3d95da1cfe1))
25
+
26
+
27
+
28
+
6
29
  ## 0.3.5 (2024-02-22)
7
30
 
8
31
  ### Only dependencies have been changed
package/README.md CHANGED
@@ -8,6 +8,18 @@
8
8
 
9
9
  [//]: DOCUMENTATION_SECTION_START
10
10
  [//]: THIS_SECTION_IS_AUTOGENERATED_PLEASE_DONT_EDIT_IT
11
+ ## extractChildIds
12
+ ### Props
13
+ | name | type | default value | description |
14
+ |------|------|---------------|-------------|
15
+ | items* | `ItemProps[]` | - | |
16
+ ## useGroupItemSelection
17
+ ### Props
18
+ | name | type | default value | description |
19
+ |------|------|---------------|-------------|
20
+ | items* | `ItemProps[]` | - | |
21
+ | id | `string \| number` | - | |
22
+ | disabled | `boolean` | - | |
11
23
  ## isSelectionSingleProps
12
24
  ### Props
13
25
  | name | type | default value | description |
@@ -21,29 +33,32 @@
21
33
  | name | type | default value | description |
22
34
  |------|------|---------------|-------------|
23
35
  | items* | `ItemProps[]` | - | Основные элементы списка |
36
+ | children* | `ReactNode \| ({onKeyDown}) => ReactNode * Рендер функция принимает аргументы `onKeyDown` - хендлер ввода, для поддержки управления с клавиатуры` | - | Триггер для дроплиста |
24
37
  | triggerElemRef | `RefObject<HTMLElement>` | - | Ссылка на элемент-триггер для дроплиста |
25
- | children | `ReactNode` | - | Триггер для дроплиста |
26
38
  | open | `boolean` | - | Управляет состоянием показан/не показан. |
27
39
  | onOpenChange | `(isOpen: boolean) => void` | - | Колбек отображения компонента. Срабатывает при изменении состояния open. |
28
40
  | widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | auto | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
29
41
  | trigger | enum Trigger: `"click"`, `"hover"`, `"focusVisible"`, `"focus"`, `"hoverAndFocusVisible"`, `"hoverAndFocus"`, `"clickAndFocusVisible"` | - | Условие отображения поповера: <br> - `click` - открывать по клику <br> - `hover` - открывать по ховеру <br> - `focusVisible` - открывать по focus-visible <br> - `focus` - открывать по фокусу <br> - `hoverAndFocusVisible` - открывать по ховеру и focus-visible <br> - `hoverAndFocus` - открывать по ховеру и фокусу <br> - `clickAndFocusVisible` - открывать по клику и focus-visible |
30
42
  | placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Положение поповера относительно своего триггера (children). |
31
43
  | className | `string` | - | CSS-класс |
44
+ | size | "s" \| "m" \| "l" | - | Размер списка |
32
45
  | pinTop | `ItemProps[]` | - | Элементы списка, закрепленные сверху |
33
46
  | pinBottom | `ItemProps[]` | - | Элементы списка, закрепленные снизу |
34
- | footer | `ReactElement` | - | Кастомизируемый элемент в конце списка |
47
+ | footer | `ReactNode ;` | - | Кастомизируемый элемент в конце списка |
35
48
  | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | Список ссылок на кастомные элементы, помещенные в специальную секцию внизу списка |
36
49
  | search | `SearchState` | - | Настройки поисковой строки |
37
- | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
38
- | noData | `string` | - | Текст для состояния "Отсутсвие данных" |
39
- | noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске |
40
50
  | collapse | `CollapseState` | {} | Настройки раскрытия элементов |
51
+ | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
41
52
  | selection | `SelectionSingleState \| SelectionMultipleState` | - | |
42
- | size | "s" \| "m" \| "l" | - | Размер списка |
43
53
  | marker | `boolean` | - | Отображать ли маркер у выбранного жлемента списка |
44
54
  | scroll | `boolean` | - | Включить ли скролл для основной части списка |
45
55
  | scrollRef | `RefObject<HTMLElement>` | - | Ссылка на элемент, обозначающий самый конец прокручиваемого списка |
46
56
  | scrollContainerRef | `RefObject<HTMLElement>` | - | Ссылка на контейнер, который скроллится |
57
+ | dataFiltered | `boolean` | - | |
58
+ | dataError | `boolean` | - | |
59
+ | noDataState | `EmptyStateProps` | - | Экран при отстутствии данных |
60
+ | noResultsState | `EmptyStateProps` | - | Экран при отстутствии результатов поиска или фильтров |
61
+ | errorDataState | `EmptyStateProps` | - | Экран при ошибке запроса |
47
62
  ## List
48
63
  ### Props
49
64
  | name | type | default value | description |
@@ -51,22 +66,25 @@
51
66
  | items* | `ItemProps[]` | - | Основные элементы списка |
52
67
  | pinTop | `ItemProps[]` | - | Элементы списка, закрепленные сверху |
53
68
  | pinBottom | `ItemProps[]` | - | Элементы списка, закрепленные снизу |
54
- | footer | `ReactElement` | - | Кастомизируемый элемент в конце списка |
69
+ | footer | `ReactNode ;` | - | Кастомизируемый элемент в конце списка |
55
70
  | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | Список ссылок на кастомные элементы, помещенные в специальную секцию внизу списка |
56
71
  | search | `SearchState` | - | Настройки поисковой строки |
57
- | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
58
- | noData | `string` | - | Текст для состояния "Отсутсвие данных" |
59
- | noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске |
60
72
  | tabIndex | `number` | - | Tab Index |
61
73
  | collapse | `CollapseState` | {} | Настройки раскрытия элементов |
62
74
  | className | `string` | - | CSS-класс |
63
75
  | onKeyDown | `(e: KeyboardEvent<HTMLElement>) => void` | - | |
76
+ | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
64
77
  | selection | `SelectionSingleState \| SelectionMultipleState` | - | |
65
78
  | size | "s" \| "m" \| "l" | - | Размер списка |
66
79
  | marker | `boolean` | - | Отображать ли маркер у выбранного жлемента списка |
67
80
  | scroll | `boolean` | - | Включить ли скролл для основной части списка |
68
81
  | scrollRef | `RefObject<HTMLElement>` | - | Ссылка на элемент, обозначающий самый конец прокручиваемого списка |
69
82
  | scrollContainerRef | `RefObject<HTMLElement>` | - | Ссылка на контейнер, который скроллится |
83
+ | dataFiltered | `boolean` | - | |
84
+ | dataError | `boolean` | - | |
85
+ | noDataState | `EmptyStateProps` | - | Экран при отстутствии данных |
86
+ | noResultsState | `EmptyStateProps` | - | Экран при отстутствии результатов поиска или фильтров |
87
+ | errorDataState | `EmptyStateProps` | - | Экран при ошибке запроса |
70
88
  | ref | `Ref<HTMLElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom |
71
89
  | key | `Key` | - | |
72
90
 
@@ -11,7 +11,6 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { ChevronDownSVG, ChevronUpSVG } from '@snack-uikit/icons';
14
- import { useToggleGroup } from '@snack-uikit/toggles';
15
14
  import { CollapseBlockPrivate } from '../../../helperComponents';
16
15
  import { CollapseContext, useCollapseContext, useParentListContext } from '../../Lists/contexts';
17
16
  import { BaseItem } from '../BaseItem';
@@ -19,12 +18,11 @@ import { useGroupItemSelection, useRenderItems } from '../hooks';
19
18
  export function AccordionItem(_a) {
20
19
  var { items: itemsProp, id, disabled } = _a, option = __rest(_a, ["items", "id", "disabled"]);
21
20
  const { level = 1 } = useCollapseContext();
22
- const { toggleOpenCollapsedItems } = useParentListContext();
21
+ const { toggleOpenCollapsedItems, openCollapsedItems } = useParentListContext();
23
22
  const { isIndeterminate, checked, handleOnSelect } = useGroupItemSelection({ items: itemsProp, id, disabled });
24
- const { isChecked: open, handleClick: handleChange } = useToggleGroup({ value: String(id) });
23
+ const isOpen = Boolean(openCollapsedItems === null || openCollapsedItems === void 0 ? void 0 : openCollapsedItems.includes(id !== null && id !== void 0 ? id : ''));
25
24
  const handleKeyDown = (e) => {
26
25
  if (e.key === 'ArrowRight') {
27
- handleChange();
28
26
  toggleOpenCollapsedItems === null || toggleOpenCollapsedItems === void 0 ? void 0 : toggleOpenCollapsedItems(id !== null && id !== void 0 ? id : '');
29
27
  e.preventDefault();
30
28
  e.stopPropagation();
@@ -33,9 +31,8 @@ export function AccordionItem(_a) {
33
31
  const itemsJSX = useRenderItems(itemsProp);
34
32
  const handleItemClick = (e) => {
35
33
  var _a;
36
- handleChange();
37
34
  toggleOpenCollapsedItems === null || toggleOpenCollapsedItems === void 0 ? void 0 : toggleOpenCollapsedItems(id !== null && id !== void 0 ? id : '');
38
35
  (_a = option.onClick) === null || _a === void 0 ? void 0 : _a.call(option, e);
39
36
  };
40
- return (_jsx(CollapseBlockPrivate, { header: _jsx(BaseItem, Object.assign({}, option, { id: id, disabled: disabled, expandIcon: open ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), onClick: handleItemClick, isParentNode: true, onKeyDown: handleKeyDown, indeterminate: isIndeterminate && !checked, onSelect: !disabled ? handleOnSelect : undefined })), expanded: open, "data-test-id": `list__accordion-item-${id}`, children: _jsx(CollapseContext.Provider, { value: { level: level + 1 }, children: itemsJSX }) }));
37
+ return (_jsx(CollapseBlockPrivate, { header: _jsx(BaseItem, Object.assign({}, option, { id: id, disabled: disabled, expandIcon: isOpen ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), onClick: handleItemClick, isParentNode: true, onKeyDown: handleKeyDown, indeterminate: isIndeterminate && !checked, onSelect: !disabled ? handleOnSelect : undefined })), expanded: isOpen, "data-test-id": `list__accordion-item-${id}`, children: _jsx(CollapseContext.Provider, { value: { level: level + 1 }, children: itemsJSX }) }));
41
38
  }
@@ -70,7 +70,7 @@ export function BaseItem(_a) {
70
70
  e.stopPropagation();
71
71
  };
72
72
  const props = extractSupportProps(rest);
73
- const item = (_jsxs("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem, className), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-non-pointer": inactive && !onClick, "data-inactive": inactive || undefined, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": mode || undefined, "data-open": open || undefined, "aria-disabled": disabled || undefined, "data-parent": parent || 'list', onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && interactive && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && interactive && (_jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' })), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }));
73
+ const item = (_jsxs("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem, className), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-non-pointer": inactive && !onClick, "data-inactive": inactive || undefined, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": mode || undefined, "data-open": open || undefined, "data-disabled": disabled || undefined, "aria-disabled": disabled || undefined, "data-parent": parent || 'list', onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && interactive && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && interactive && (_jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' })), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }));
74
74
  if (!itemWrapRender) {
75
75
  return item;
76
76
  }
@@ -184,13 +184,13 @@
184
184
  .droplistItem[aria-disabled] .option,
185
185
  .droplistItem[aria-disabled] .description,
186
186
  .droplistItem[aria-disabled] .caption,
187
- .droplistItem[aria-disabled] .expandableIcon, .droplistItem:disabled .option,
188
- .droplistItem:disabled .description,
189
- .droplistItem:disabled .caption,
190
- .droplistItem:disabled .expandableIcon{
187
+ .droplistItem[aria-disabled] .expandableIcon, .droplistItem[data-disabled] .option,
188
+ .droplistItem[data-disabled] .description,
189
+ .droplistItem[data-disabled] .caption,
190
+ .droplistItem[data-disabled] .expandableIcon{
191
191
  color:var(--sys-neutral-text-disabled, #b3b6bf);
192
192
  }
193
- .droplistItem[aria-disabled] .beforeContent, .droplistItem:disabled .beforeContent{
193
+ .droplistItem[aria-disabled] .beforeContent, .droplistItem[data-disabled] .beforeContent{
194
194
  opacity:var(--opacity-a064, 0.64);
195
195
  }
196
196
  .droplistItem[data-has-checked][data-variant=single]::after, .droplistItem[data-checked][data-variant=single]::after{
@@ -205,15 +205,11 @@
205
205
  background-color:var(--sys-primary-accent-default, #794ed3);
206
206
  }
207
207
  .droplistItem[data-has-checked]:focus-visible[data-variant=single], .droplistItem[data-checked]:focus-visible[data-variant=single]{
208
- background-color:var(--sys-primary-background, #f6effe);
209
208
  outline-color:var(--sys-primary-accent-default, #794ed3);
210
209
  }
211
- .droplistItem[data-has-checked]:disabled[data-variant=single], .droplistItem[data-checked]:disabled[data-variant=single]{
212
- background-color:var(--sys-neutral-background1-level, #fafafc);
213
- }
214
- .droplistItem[data-has-checked]:disabled[data-variant=single]::before, .droplistItem[data-checked]:disabled[data-variant=single]::before{
210
+ .droplistItem[data-has-checked][data-disabled][data-variant=single]::before, .droplistItem[data-checked][data-disabled][data-variant=single]::before{
215
211
  display:none;
216
212
  }
217
- .droplistItem[data-has-checked]:disabled .markerContainer:before, .droplistItem[data-checked]:disabled .markerContainer:before{
213
+ .droplistItem[data-has-checked][data-disabled] .markerContainer:before, .droplistItem[data-checked][data-disabled] .markerContainer:before{
218
214
  background-color:var(--sys-neutral-text-disabled, #b3b6bf);
219
215
  }
@@ -1,6 +1,6 @@
1
1
  import { createElement as _createElement } from "react";
2
2
  import { createRef, useEffect, useMemo } from 'react';
3
- import { extractChildIds } from '../../utils';
3
+ import { extractAllChildIds, extractChildIds } from '../../utils';
4
4
  import { useSelectionContext } from '../Lists/contexts';
5
5
  import { AccordionItem } from './AccordionItem';
6
6
  import { BaseItem } from './BaseItem';
@@ -8,17 +8,17 @@ import { GroupItem } from './GroupItem';
8
8
  import { NextListItem } from './NextListItem';
9
9
  import { addItemsIds, isAccordionItemProps, isGroupItemProps, isNextListItemProps } from './utils';
10
10
  export function useRenderItems(items) {
11
- return useMemo(() => items.map((item, idx) => {
11
+ return useMemo(() => items.map(item => {
12
12
  if (isGroupItemProps(item)) {
13
- return _createElement(GroupItem, Object.assign({}, item, { key: item.id }));
13
+ return _createElement(GroupItem, Object.assign({}, item, { key: item.label }));
14
14
  }
15
15
  if (isAccordionItemProps(item)) {
16
- return _createElement(AccordionItem, Object.assign({}, item, { key: idx }));
16
+ return _createElement(AccordionItem, Object.assign({}, item, { key: item.key }));
17
17
  }
18
18
  if (isNextListItemProps(item)) {
19
- return _createElement(NextListItem, Object.assign({}, item, { key: item.id }));
19
+ return _createElement(NextListItem, Object.assign({}, item, { key: item.key }));
20
20
  }
21
- return _createElement(BaseItem, Object.assign({}, item, { key: item.id }));
21
+ return _createElement(BaseItem, Object.assign({}, item, { key: item.key }));
22
22
  }), [items]);
23
23
  }
24
24
  export function useItemsWithIds({ search, footerActiveElementsRefs }) {
@@ -31,11 +31,11 @@ export function useItemsWithIds({ search, footerActiveElementsRefs }) {
31
31
  }
32
32
  export function useGroupItemSelection({ id, items, disabled }) {
33
33
  const { value, setValue, isSelectionMultiple } = useSelectionContext();
34
- const childIds = useMemo(() => extractChildIds({ items }), [items]);
34
+ const { childIds, allChildIds } = useMemo(() => ({ childIds: extractChildIds({ items }), allChildIds: extractAllChildIds({ items }) }), [items]);
35
35
  const isIndeterminate = isSelectionMultiple
36
- ? childIds.some(childId => value === null || value === void 0 ? void 0 : value.includes(childId))
37
- : childIds.includes(value !== null && value !== void 0 ? value : '');
38
- const checked = isSelectionMultiple ? childIds.every(childId => value === null || value === void 0 ? void 0 : value.includes(childId)) : undefined;
36
+ ? allChildIds.some(childId => value === null || value === void 0 ? void 0 : value.includes(childId))
37
+ : allChildIds.includes(value !== null && value !== void 0 ? value : '');
38
+ const checked = isSelectionMultiple ? allChildIds.every(childId => value === null || value === void 0 ? void 0 : value.includes(childId)) : undefined;
39
39
  useEffect(() => {
40
40
  if (isSelectionMultiple) {
41
41
  if (checked && !(value === null || value === void 0 ? void 0 : value.includes(id))) {
@@ -50,23 +50,23 @@
50
50
  height:100%;
51
51
  background-color:transparent;
52
52
  }
53
- .listItem:disabled{
53
+ .listItem[data-disabled], .listItem:disabled{
54
54
  cursor:not-allowed;
55
55
  background-color:transparent;
56
56
  outline:none;
57
57
  }
58
- .listItem:disabled::before{
58
+ .listItem[data-disabled]::before, .listItem:disabled::before{
59
59
  display:none;
60
60
  }
61
- .listItem:disabled::after{
61
+ .listItem[data-disabled]::after, .listItem:disabled::after{
62
62
  cursor:not-allowed;
63
63
  background-color:transparent;
64
64
  }
65
- .listItem:not([data-inactive])[data-open]::after, .listItem:not([data-inactive])[data-focused]::after, .listItem:not([data-inactive]):hover::after, .listItem:not([data-inactive]):focus-visible::after{
65
+ .listItem:not([data-inactive], [data-disabled])[data-open]::after, .listItem:not([data-inactive], [data-disabled])[data-focused]::after, .listItem:not([data-inactive], [data-disabled]):hover::after, .listItem:not([data-inactive], [data-disabled]):focus-visible::after{
66
66
  opacity:var(--opacity-a008, 0.08);
67
67
  background-color:var(--sys-neutral-accent-default, #6f717c);
68
68
  }
69
- .listItem:not([data-inactive])[data-focused], .listItem:not([data-inactive]):focus-visible{
69
+ .listItem:not([data-inactive], [data-disabled])[data-focused], .listItem:not([data-inactive], [data-disabled]):focus-visible{
70
70
  outline-width:var(--border-state-focus-s-border-width, 2px);
71
71
  outline-style:var(--border-state-focus-s-border-style, solid);
72
72
  outline-color:var(--border-state-focus-s-border-color, );
@@ -48,6 +48,7 @@ export type BaseItemProps = WithSupportProps<{
48
48
  * Флаг отображения состояния выбранного элемента через switch
49
49
  */
50
50
  switch?: boolean;
51
+ key?: string | number;
51
52
  itemWrapRender?(item: ReactNode): ReactNode;
52
53
  }>;
53
54
  type BaseItemsWithoutNonGroupProps = Omit<BaseItemProps, 'switch' | 'inactive'>;
@@ -30,13 +30,14 @@ export function getSlicedItems({ items, hasSearch, pinTop, pinBottom, footerRefs
30
30
  export function addItemsIds(itemsProp, prefix) {
31
31
  return itemsProp.map((item, idx) => {
32
32
  var _a;
33
- const itemId = (_a = item.id) !== null && _a !== void 0 ? _a : (prefix !== undefined ? [prefix, idx].join('-') : String(idx));
33
+ const autoId = prefix !== undefined ? [prefix, idx].join('-') : String(idx);
34
+ const itemId = (_a = item.id) !== null && _a !== void 0 ? _a : autoId;
34
35
  if (isGroupItemProps(item)) {
35
- return Object.assign(Object.assign({}, item), { id: itemId, items: addItemsIds(item.items, itemId) });
36
+ return Object.assign(Object.assign({ key: autoId }, item), { id: itemId, items: addItemsIds(item.items, itemId) });
36
37
  }
37
38
  if (isAccordionItemProps(item) || isNextListItemProps(item)) {
38
- return Object.assign(Object.assign({}, item), { id: itemId, items: addItemsIds(item.items, itemId), itemRef: item.itemRef || createRef() });
39
+ return Object.assign(Object.assign({ key: autoId }, item), { id: itemId, items: addItemsIds(item.items, itemId), itemRef: item.itemRef || createRef() });
39
40
  }
40
- return Object.assign(Object.assign({}, item), { id: itemId, itemRef: item.itemRef || createRef() });
41
+ return Object.assign(Object.assign({ key: autoId }, item), { id: itemId, itemRef: item.itemRef || createRef() });
41
42
  });
42
43
  }
@@ -23,12 +23,7 @@ export function Droplist(_a) {
23
23
  var { items: itemsProp, search, pinBottom, pinTop, footerActiveElementsRefs, children, trigger, placement, widthStrategy, triggerElemRef: triggerElemRefProp, open: openProp, onOpenChange, collapse = {} } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs", "children", "trigger", "placement", "widthStrategy", "triggerElemRef", "open", "onOpenChange", "collapse"]);
24
24
  const hasSearch = useMemo(() => Boolean(search), [search]);
25
25
  const memorizedItems = useMemo(() => addItemsIds((pinBottom !== null && pinBottom !== void 0 ? pinBottom : []).concat(itemsProp).concat(pinTop !== null && pinTop !== void 0 ? pinTop : [])), [itemsProp, pinBottom, pinTop]);
26
- const [openCollapsedItems, setOpenCollapsedItems] = useUncontrolledProp(collapse.value, (_b = collapse.defaultValue) !== null && _b !== void 0 ? _b : [], collapse.onChange
27
- ? cb => {
28
- var _a;
29
- (_a = collapse.onChange) === null || _a === void 0 ? void 0 : _a.call(collapse, cb(collapse.value));
30
- }
31
- : undefined);
26
+ const [openCollapsedItems, setOpenCollapsedItems] = useUncontrolledProp(collapse.value, (_b = collapse.defaultValue) !== null && _b !== void 0 ? _b : [], collapse.onChange);
32
27
  const { search: searchItem, footerRefs } = useItemsWithIds({
33
28
  search: hasSearch,
34
29
  footerActiveElementsRefs,
@@ -52,11 +47,9 @@ export function Droplist(_a) {
52
47
  const { activeFocusIndex, setActiveFocusIndex, openNestedIndex, handleListKeyDown, resetNestedIndex, resetActiveFocusIndex, } = useKeyboardNavigation({ ids, expandedIds, parentRef: triggerElemRefProp !== null && triggerElemRefProp !== void 0 ? triggerElemRefProp : triggerElemRef, itemRefs });
53
48
  const [open, setOpen] = useUncontrolledProp(openProp, false, onOpenChange);
54
49
  const handleOpenChange = (open) => {
55
- if (!open) {
56
- resetNestedIndex();
57
- resetActiveFocusIndex();
58
- setOpenCollapsedItems([]);
59
- }
50
+ resetNestedIndex();
51
+ resetActiveFocusIndex();
52
+ setOpenCollapsedItems([]);
60
53
  setOpen(open);
61
54
  };
62
55
  const onKeyDown = useCallback((e, cb) => {
@@ -79,6 +72,9 @@ export function Droplist(_a) {
79
72
  onKeyDown(e, (_a = children.props) === null || _a === void 0 ? void 0 : _a.onKeyDown);
80
73
  } }));
81
74
  }
75
+ if (typeof children === 'function') {
76
+ return children({ onKeyDown });
77
+ }
82
78
  return children;
83
79
  }, [onKeyDown, children]);
84
80
  return (
@@ -94,6 +90,7 @@ export function Droplist(_a) {
94
90
  parentRef: listRef,
95
91
  parentResetNestedIndex: resetNestedIndex,
96
92
  parentResetActiveFocusIndex: resetActiveFocusIndex,
93
+ openCollapsedItems,
97
94
  toggleOpenCollapsedItems: id => setOpenCollapsedItems((items = []) => items.includes(id) ? items.filter(item => item !== id) : items === null || items === void 0 ? void 0 : items.concat([id])),
98
95
  }, children: _jsx(Dropdown, Object.assign({ content: _jsx(ListPrivate, Object.assign({}, slicedItems, props, { onKeyDown: handleListKeyDown, tabIndex: 0, ref: listRef, search: search, limitedScrollHeight: true, parent: 'droplist' })), trigger: trigger, placement: placement, widthStrategy: widthStrategy }, (triggerElemRefProp
99
96
  ? {}
@@ -7,10 +7,7 @@ export declare const List: import("react").ForwardRefExoticComponent<{
7
7
  pinBottom?: import("../../Items").ItemProps[] | undefined;
8
8
  footer?: import("react").ReactNode;
9
9
  footerActiveElementsRefs?: import("react").RefObject<HTMLElement>[] | undefined;
10
- search?: import("../../../types").SearchState | undefined;
11
- loading?: boolean | undefined;
12
- noData?: string | undefined;
13
- noResults?: string | undefined;
10
+ search?: import("../../..").SearchState | undefined;
14
11
  tabIndex?: number | undefined;
15
12
  collapse?: {
16
13
  value?: (string | number)[] | undefined;
@@ -19,4 +16,5 @@ export declare const List: import("react").ForwardRefExoticComponent<{
19
16
  } | undefined;
20
17
  className?: string | undefined;
21
18
  onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
22
- } & import("../contexts").SelectionState & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("react").RefAttributes<HTMLElement>>;
19
+ loading?: boolean | undefined;
20
+ } & import("../contexts").SelectionState & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("../types").EmptyState & import("react").RefAttributes<HTMLElement>>;
@@ -26,12 +26,7 @@ export const List = forwardRef((_a, ref) => {
26
26
  var { items: itemsProp, search, pinBottom, pinTop, footerActiveElementsRefs, onKeyDown, tabIndex = 0, className, collapse = {} } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs", "onKeyDown", "tabIndex", "className", "collapse"]);
27
27
  const hasSearch = useMemo(() => Boolean(search), [search]);
28
28
  const memorizedItems = useMemo(() => addItemsIds((pinTop !== null && pinTop !== void 0 ? pinTop : []).concat(itemsProp).concat(pinBottom !== null && pinBottom !== void 0 ? pinBottom : [])), [itemsProp, pinBottom, pinTop]);
29
- const [openCollapsedItems, setOpenCollapsedItems] = useUncontrolledProp(collapse.value, (_b = collapse.defaultValue) !== null && _b !== void 0 ? _b : [], collapse.onChange
30
- ? cb => {
31
- var _a;
32
- (_a = collapse.onChange) === null || _a === void 0 ? void 0 : _a.call(collapse, cb(collapse.value));
33
- }
34
- : undefined);
29
+ const [openCollapsedItems, setOpenCollapsedItems] = useUncontrolledProp(collapse.value, (_b = collapse.defaultValue) !== null && _b !== void 0 ? _b : [], collapse.onChange);
35
30
  const { search: searchItem, footerRefs } = useItemsWithIds({
36
31
  search: hasSearch,
37
32
  footerActiveElementsRefs,
@@ -7,10 +7,7 @@ export declare const ListPrivate: import("react").ForwardRefExoticComponent<{
7
7
  pinBottom?: import("../../Items").ItemProps[] | undefined;
8
8
  footer?: import("react").ReactNode;
9
9
  footerActiveElementsRefs?: RefObject<HTMLElement>[] | undefined;
10
- search?: import("../../../types").SearchState | undefined;
11
- loading?: boolean | undefined;
12
- noData?: string | undefined;
13
- noResults?: string | undefined;
10
+ search?: import("../../..").SearchState | undefined;
14
11
  tabIndex?: number | undefined;
15
12
  collapse?: {
16
13
  value?: (string | number)[] | undefined;
@@ -19,7 +16,8 @@ export declare const ListPrivate: import("react").ForwardRefExoticComponent<{
19
16
  } | undefined;
20
17
  className?: string | undefined;
21
18
  onKeyDown?(e: import("react").KeyboardEvent<HTMLElement>): void;
22
- } & import("../contexts").SelectionState & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("../contexts").ListContextPrivateType & {
19
+ loading?: boolean | undefined;
20
+ } & import("../contexts").SelectionState & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("../types").EmptyState & import("../contexts").ListContextPrivateType & {
23
21
  nested?: boolean | undefined;
24
22
  active?: boolean | undefined;
25
23
  tabIndex?: number | undefined;
@@ -14,26 +14,26 @@ import cn from 'classnames';
14
14
  import { forwardRef, useMemo } from 'react';
15
15
  import { Spinner } from '@snack-uikit/loaders';
16
16
  import { Scroll } from '@snack-uikit/scroll';
17
- import { ToggleGroup } from '@snack-uikit/toggles';
18
17
  import { extractSupportProps } from '@snack-uikit/utils';
18
+ import { ListEmptyState, useEmptyState } from '../../../helperComponents';
19
19
  import { PinBottomGroupItem, PinTopGroupItem, SearchItem, useRenderItems } from '../../Items';
20
20
  import { ListContextProvider } from '../contexts';
21
21
  import commonStyles from '../styles.module.css';
22
22
  import styles from './styles.module.css';
23
23
  export const ListPrivate = forwardRef((_a, ref) => {
24
- var _b, _c;
25
- var { items, pinTop, pinBottom, onKeyDown, onBlur, onFocus, tabIndex, active, scroll, nested, search, scrollRef, scrollContainerRef, footer, loading, noData = 'No data', noResults = 'No results', size = 's', marker, limitedScrollHeight, className, parent = 'list' } = _a, props = __rest(_a, ["items", "pinTop", "pinBottom", "onKeyDown", "onBlur", "onFocus", "tabIndex", "active", "scroll", "nested", "search", "scrollRef", "scrollContainerRef", "footer", "loading", "noData", "noResults", "size", "marker", "limitedScrollHeight", "className", "parent"]);
24
+ var { items, pinTop, pinBottom, onKeyDown, onBlur, onFocus, tabIndex, active, scroll, nested, search, scrollRef, scrollContainerRef, footer, loading, size = 's', marker = true, limitedScrollHeight, className, parent = 'list', noDataState, noResultsState, errorDataState, dataError, dataFiltered } = _a, props = __rest(_a, ["items", "pinTop", "pinBottom", "onKeyDown", "onBlur", "onFocus", "tabIndex", "active", "scroll", "nested", "search", "scrollRef", "scrollContainerRef", "footer", "loading", "size", "marker", "limitedScrollHeight", "className", "parent", "noDataState", "noResultsState", "errorDataState", "dataError", "dataFiltered"]);
26
25
  const itemsJSX = useRenderItems(items);
27
26
  const itemsPinTopJSX = useRenderItems(pinTop !== null && pinTop !== void 0 ? pinTop : []);
28
27
  const itemsPinBottomJSX = useRenderItems(pinBottom !== null && pinBottom !== void 0 ? pinBottom : []);
29
- const hasNoItems = items.length + ((_b = pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) !== null && _b !== void 0 ? _b : 0) + ((_c = pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) !== null && _c !== void 0 ? _c : 0) === 0;
28
+ const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
29
+ const hasNoItems = items.length === 0;
30
30
  const loadingJSX = useMemo(() => loading && (_jsx("div", { role: 'spinbutton', tabIndex: -1, className: styles.loader, "data-size": size, "data-no-items": hasNoItems || undefined, "data-test-id": 'list__loader', children: _jsx(Spinner, { size: size === 'l' ? 's' : 'xs' }) })), [hasNoItems, loading, size]);
31
- const content = useMemo(() => (_jsxs("div", { className: styles.content, children: [itemsJSX, loadingJSX, hasNoItems && !(search === null || search === void 0 ? void 0 : search.value) && !loading && (_jsx("div", { className: commonStyles.infoBlock, "data-test-id": 'list__no-data', children: noData })), hasNoItems && (search === null || search === void 0 ? void 0 : search.value) && !loading && (_jsx("div", { className: commonStyles.infoBlock, "data-test-id": 'list__no-results', children: noResults }))] })), [hasNoItems, itemsJSX, loading, loadingJSX, noData, noResults, search === null || search === void 0 ? void 0 : search.value]);
32
- const listJSX = (_jsx("ul", Object.assign({ className: cn(commonStyles.listContainer, className), ref: ref, onKeyDown: onKeyDown, tabIndex: tabIndex, onFocus: !nested ? onFocus : undefined, onBlur: onBlur, "data-active": active || undefined, role: 'menu' }, extractSupportProps(props), { children: _jsxs(ToggleGroup, { selectionMode: 'multiple', children: [(Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 || search) && (_jsxs(PinTopGroupItem, { children: [search && _jsx(SearchItem, { search: search }), Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 && itemsPinTopJSX] })), scroll ? (_jsxs(Scroll, { className: cn({
33
- [commonStyles.scrollContainerS]: scroll && limitedScrollHeight && size === 's',
34
- [commonStyles.scrollContainerM]: scroll && limitedScrollHeight && size === 'm',
35
- [commonStyles.scrollContainerL]: scroll && limitedScrollHeight && size === 'l',
36
- }), barHideStrategy: 'leave', size: size === 's' ? 's' : 'm', ref: scrollContainerRef, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && _jsx("div", { className: styles.footer, children: footer })] }) })));
31
+ const content = useMemo(() => (_jsxs("div", { className: styles.content, children: [itemsJSX, loadingJSX, _jsx(ListEmptyState, { loading: loading, dataError: dataError, emptyStates: emptyStates, itemsLength: items.length, dataFiltered: dataFiltered !== null && dataFiltered !== void 0 ? dataFiltered : Boolean(search === null || search === void 0 ? void 0 : search.value) })] })), [dataError, dataFiltered, emptyStates, items.length, itemsJSX, loading, loadingJSX, search === null || search === void 0 ? void 0 : search.value]);
32
+ const listJSX = (_jsxs("ul", Object.assign({ className: cn(commonStyles.listContainer, className), ref: ref, onKeyDown: onKeyDown, tabIndex: tabIndex, onFocus: !nested ? onFocus : undefined, onBlur: onBlur, "data-active": active || undefined, role: 'menu' }, extractSupportProps(props), { children: [(Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 || search) && (_jsxs(PinTopGroupItem, { children: [search && _jsx(SearchItem, { search: search }), Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 && itemsPinTopJSX] })), scroll ? (_jsxs(Scroll, { className: cn({
33
+ [commonStyles.scrollContainerS]: scroll && limitedScrollHeight && size === 's',
34
+ [commonStyles.scrollContainerM]: scroll && limitedScrollHeight && size === 'm',
35
+ [commonStyles.scrollContainerL]: scroll && limitedScrollHeight && size === 'l',
36
+ }), barHideStrategy: 'never', size: size === 's' ? 's' : 'm', ref: scrollContainerRef, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && _jsx("div", { className: styles.footer, children: footer })] })));
37
37
  if (!nested) {
38
38
  return (_jsx(ListContextProvider, { size: size, marker: marker, parent: parent, children: listJSX }));
39
39
  }
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- type SelectionSingleValueType = string | number | undefined;
3
- type SelectionSingleState = {
2
+ export type SelectionSingleValueType = string | number | undefined;
3
+ export type SelectionSingleState = {
4
4
  /** Начальное состояние */
5
5
  defaultValue?: SelectionSingleValueType;
6
6
  /** Controlled состояние */
@@ -17,7 +17,7 @@ export type SelectionSingleProps = {
17
17
  /** Режим выбора multi */
18
18
  isSelectionMultiple: false;
19
19
  } & SelectionSingleState;
20
- type SelectionMultipleState = {
20
+ export type SelectionMultipleState = {
21
21
  /** Начальное состояние */
22
22
  defaultValue?: SelectionSingleValueType[];
23
23
  /** Controlled состояние */
@@ -45,18 +45,21 @@ function SelectionSingleProvider({ value: valueProp, defaultValue, onChange: onC
45
45
  }, children: children }));
46
46
  }
47
47
  function SelectionMultipleProvider({ value: valueProp, defaultValue, onChange: onChangeProp, children, }) {
48
- const [value, setValue] = useUncontrolledProp(valueProp, defaultValue, cb => {
49
- onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(cb(value));
50
- });
51
- const onChange = useCallback((newValue) => setValue((oldValues) => {
52
- if (Array.isArray(oldValues)) {
53
- if (oldValues.includes(newValue)) {
54
- return oldValues.filter(oldValue => oldValue !== newValue);
48
+ const [value, setValue] = useUncontrolledProp(valueProp, defaultValue, onChangeProp);
49
+ const onChange = useCallback((newValue) => {
50
+ setValue((oldValues) => {
51
+ if (Array.isArray(oldValues)) {
52
+ if (oldValues.includes(newValue)) {
53
+ return oldValues.filter(oldValue => oldValue !== newValue);
54
+ }
55
+ return oldValues.concat(newValue);
55
56
  }
56
- return oldValues.concat(newValue);
57
- }
58
- return undefined;
59
- }), [setValue]);
57
+ if (oldValues === undefined) {
58
+ return Array.isArray(newValue) ? newValue : [newValue];
59
+ }
60
+ return undefined;
61
+ });
62
+ }, [setValue]);
60
63
  return (_jsx(SelectionContext.Provider, { value: {
61
64
  value,
62
65
  onChange,
@@ -1,4 +1,4 @@
1
1
  export * from './Droplist';
2
2
  export * from './List';
3
3
  export type { ListProps, DroplistProps } from './types';
4
- export type { SelectionSingleProps, SelectionMultipleProps, isSelectionSingleProps, isSelectionMultipleProps, } from './contexts';
4
+ export type { SelectionSingleState, SelectionMultipleState, SelectionSingleProps, SelectionMultipleProps, isSelectionSingleProps, isSelectionMultipleProps, SelectionSingleValueType, } from './contexts';
@@ -57,18 +57,4 @@
57
57
  .scrollContainerL{
58
58
  height:auto;
59
59
  max-height:calc(var(--dimension-1m, 8px) * 48);
60
- }
61
-
62
- .infoBlock{
63
- font-family:var(--sans-body-s-font-family, SB Sans Interface);
64
- font-weight:var(--sans-body-s-font-weight, Regular);
65
- line-height:var(--sans-body-s-line-height, 16px);
66
- font-size:var(--sans-body-s-font-size, 12px);
67
- letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
68
- paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
69
- display:flex;
70
- align-items:center;
71
- justify-content:center;
72
- padding:var(--dimension-1m, 8px);
73
- color:var(--sys-neutral-text-support, #656771);
74
60
  }