@cloud-ru/ds-list 2.3.3-preview-a22f149a.0 → 2.3.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-ru/ds-list",
3
- "version": "2.3.3-preview-a22f149a.0",
3
+ "version": "2.3.4",
4
4
  "description": "Списочный UI — компонент List для плоских/вложенных списков с выбором, группами и поиском и Droplist — тот же список в поповере.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -48,24 +48,24 @@
48
48
  "@tanstack/react-virtual": "^3.14.8",
49
49
  "classnames": "^2.5.1",
50
50
  "merge-refs": "^2.0.0",
51
- "@cloud-ru/ds-adaptive": "1.0.2",
52
- "@cloud-ru/ds-button": "1.0.4",
53
- "@cloud-ru/ds-divider": "1.0.2",
54
- "@cloud-ru/ds-drag-and-drop": "1.1.3",
55
- "@cloud-ru/ds-dropdown": "1.1.2-preview-a22f149a.0",
56
- "@cloud-ru/ds-bottom-sheet": "2.0.1-preview-a22f149a.0",
57
- "@cloud-ru/ds-icons": "1.5.1-preview-a22f149a.0",
58
- "@cloud-ru/ds-info-block": "1.0.3",
59
- "@cloud-ru/ds-loader": "1.0.3",
60
- "@cloud-ru/ds-materials": "2.0.1",
61
- "@cloud-ru/ds-portal-context": "1.0.2",
62
- "@cloud-ru/ds-scroll": "1.0.5",
63
- "@cloud-ru/ds-search-private": "1.0.15-preview-a22f149a.0",
64
- "@cloud-ru/ds-truncate-string": "1.0.13-preview-a22f149a.0",
65
- "@cloud-ru/ds-toggles": "1.1.10-preview-a22f149a.0",
66
- "@cloud-ru/ds-utils": "1.2.0"
51
+ "@cloud-ru/ds-adaptive": "^1.0.2",
52
+ "@cloud-ru/ds-bottom-sheet": "^2.0.1",
53
+ "@cloud-ru/ds-button": "^1.0.4",
54
+ "@cloud-ru/ds-divider": "^1.0.2",
55
+ "@cloud-ru/ds-drag-and-drop": "^1.1.3",
56
+ "@cloud-ru/ds-dropdown": "^1.1.2",
57
+ "@cloud-ru/ds-icons": "^1.5.1",
58
+ "@cloud-ru/ds-info-block": "^1.0.3",
59
+ "@cloud-ru/ds-loader": "^1.0.3",
60
+ "@cloud-ru/ds-materials": "^2.0.1",
61
+ "@cloud-ru/ds-portal-context": "^1.0.2",
62
+ "@cloud-ru/ds-scroll": "^1.0.5",
63
+ "@cloud-ru/ds-toggles": "^1.1.10",
64
+ "@cloud-ru/ds-truncate-string": "^1.0.13",
65
+ "@cloud-ru/ds-search-private": "^1.0.15",
66
+ "@cloud-ru/ds-utils": "^1.2.0"
67
67
  },
68
68
  "peerDependencies": {
69
- "@cloud-ru/ds-locale": "1.0.0"
69
+ "@cloud-ru/ds-locale": "^1.0.0"
70
70
  }
71
71
  }
@@ -5,19 +5,22 @@ import { ForwardedRef, forwardRef, KeyboardEvent, useCallback, useMemo, useRef }
5
5
 
6
6
  import { DEFAULT_SIZE } from '../../../constants';
7
7
  import { HiddenTabButton } from '../../../helperComponents';
8
+ import { Item } from '../../Items';
8
9
  import { CollapseContext, FocusListContext, NewListContextProvider, SelectionProvider } from '../contexts';
9
10
  import { useListItemsModel, useNewKeyboardNavigation } from '../hooks';
10
11
  import { ListPrivate } from '../ListPrivate';
11
12
  import styles from '../styles.module.scss';
12
13
  import { ListImplProps, ListProps, ReorderableListProps } from '../types';
13
14
 
15
+ const EMPTY_ITEMS: Item[] = [];
16
+
14
17
  const ListImpl = forwardRef(
15
18
  (
16
19
  {
17
- items: itemsProp = [],
20
+ items: itemsProp = EMPTY_ITEMS,
18
21
  search,
19
- pinBottom: pinBottomProp = [],
20
- pinTop: pinTopProp = [],
22
+ pinBottom: pinBottomProp = EMPTY_ITEMS,
23
+ pinTop: pinTopProp = EMPTY_ITEMS,
21
24
  footerActiveElementsRefs,
22
25
  onKeyDown,
23
26
  tabIndex = 0,
@@ -17,7 +17,7 @@ import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrate
17
17
  import { Spinner } from '@cloud-ru/ds-loader';
18
18
  import { usePortalContext } from '@cloud-ru/ds-portal-context';
19
19
  import { Scroll } from '@cloud-ru/ds-scroll';
20
- import { extractSupportProps, isBrowser, useLayoutEffect } from '@cloud-ru/ds-utils';
20
+ import { extractSupportProps, isBrowser, isNil, useLayoutEffect } from '@cloud-ru/ds-utils';
21
21
  import { useVirtualizer } from '@tanstack/react-virtual';
22
22
  import cn from 'classnames';
23
23
  import mergeRefs from 'merge-refs';
@@ -174,6 +174,7 @@ export const ListPrivate = forwardRef(
174
174
  const portalRoot = usePortalContext();
175
175
 
176
176
  const innerScrollRef = useRef<HTMLElement | null>(null);
177
+ const lastCenteredItemRef = useRef<{ id: ItemId; container: HTMLElement } | null>(null);
177
178
  // `@cloud-ru/ds-scroll` (OverlayScrollbars) разрешает свой ref в viewport-элемент только после
178
179
  // инициализации инстанса. До этого `innerScrollRef.current` === null, и виртуализатор
179
180
  // не получает scroll-элемент → рендерит пустой контейнер. Флаг поднимается из
@@ -198,12 +199,12 @@ export const ListPrivate = forwardRef(
198
199
  selectedItem: undefined,
199
200
  };
200
201
 
201
- if (!scrollToSelectedItem || !value) {
202
+ if (!scrollToSelectedItem || isNil(value)) {
202
203
  return result;
203
204
  }
204
205
 
205
206
  const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
206
- if (!selectedItem?.id) {
207
+ if (!selectedItem || isNil(selectedItem.id)) {
207
208
  return result;
208
209
  }
209
210
 
@@ -330,7 +331,8 @@ export const ListPrivate = forwardRef(
330
331
  // ведут эффекты выше через виртуализатор, поэтому здесь только `!virtualized`. Хелпер тот
331
332
  // же `centerItemInScrollContainer` — обычному листу отдельный виртуализатор не нужен.
332
333
  useEffect(() => {
333
- if (virtualized || !scroll || !scrollToSelectedItem || !scrollElementReady) {
334
+ if (virtualized || !scroll || !scrollToSelectedItem || !scrollElementReady || !selectedItem) {
335
+ lastCenteredItemRef.current = null;
334
336
  return;
335
337
  }
336
338
 
@@ -340,7 +342,15 @@ export const ListPrivate = forwardRef(
340
342
  return;
341
343
  }
342
344
 
345
+ if (
346
+ lastCenteredItemRef.current?.id === selectedItem.originalId &&
347
+ lastCenteredItemRef.current.container === container
348
+ ) {
349
+ return;
350
+ }
351
+
343
352
  centerItemInScrollContainer(container, item);
353
+ lastCenteredItemRef.current = { id: selectedItem.originalId, container };
344
354
  }, [virtualized, scroll, scrollToSelectedItem, scrollElementReady, selectedItem]);
345
355
 
346
356
  const loadingJSX = useMemo(