@synerise/ds-dropdown 2.0.3 → 2.1.1
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 +17 -0
- package/dist/Dropdown.d.ts +2 -2
- package/dist/Dropdown.js +1 -1
- package/dist/Dropdown.types.d.ts +1 -1
- package/dist/components/DropdownMenuList/DropdownMenuList.js +63 -24
- package/dist/components/DropdownOverlay/DropdownOverlay.js +1 -1
- package/dist/components/DropdownPopover/DropdownPopover.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
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
|
+
## [2.1.1](https://github.com/synerise/synerise-design/compare/@synerise/ds-dropdown@2.1.0...@synerise/ds-dropdown@2.1.1) (2026-09-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **dropdown:** clear the item-click close timer when the list unmounts ([07f32bb](https://github.com/synerise/synerise-design/commit/07f32bb9308955886b57739cfcb84f99f71914bc))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [2.1.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-dropdown@2.0.3...@synerise/ds-dropdown@2.1.0) (2026-09-16)
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
- **list-item:** add content-fitting size="auto" ([e269f0a](https://github.com/synerise/synerise-design/commit/e269f0a48ca7472f4766a50a957e22d7988c5e13))
|
|
22
|
+
|
|
6
23
|
## [2.0.3](https://github.com/synerise/synerise-design/compare/@synerise/ds-dropdown@2.0.2...@synerise/ds-dropdown@2.0.3) (2026-09-08)
|
|
7
24
|
|
|
8
25
|
**Note:** Version bump only for package @synerise/ds-dropdown
|
package/dist/Dropdown.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
2
|
import { default as SearchBar } from '@synerise/ds-search-bar';
|
|
3
|
-
import { Wrapper } from './Dropdown.styles';
|
|
4
|
-
import { DropdownProps } from './Dropdown.types';
|
|
5
3
|
import { BackAction } from './components/BackAction/BackAction';
|
|
6
4
|
import { BottomAction } from './components/BottomAction/BottomAction';
|
|
7
5
|
import { MenuWrapper } from './components/DropdownMenuList/DropdownMenuList.styles';
|
|
8
6
|
import { TextTrigger } from './components/TextTrigger/TextTrigger';
|
|
7
|
+
import { Wrapper } from './Dropdown.styles';
|
|
8
|
+
import { DropdownProps } from './Dropdown.types';
|
|
9
9
|
type SubComponents = {
|
|
10
10
|
Wrapper: typeof Wrapper;
|
|
11
11
|
MenuWrapper: typeof MenuWrapper;
|
package/dist/Dropdown.js
CHANGED
|
@@ -2,13 +2,13 @@ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useMemo } from "react";
|
|
3
3
|
import SearchBar from "@synerise/ds-search-bar";
|
|
4
4
|
import { getPopupContainer } from "@synerise/ds-utils";
|
|
5
|
-
import { Wrapper } from "./Dropdown.styles.js";
|
|
6
5
|
import { BackAction } from "./components/BackAction/BackAction.js";
|
|
7
6
|
import { BottomAction } from "./components/BottomAction/BottomAction.js";
|
|
8
7
|
import { DropdownFooter } from "./components/DropdownFooter/DropdownFooter.js";
|
|
9
8
|
import { MenuWrapper } from "./components/DropdownMenuList/DropdownMenuList.styles.js";
|
|
10
9
|
import { DropdownPopover } from "./components/DropdownPopover/DropdownPopover.js";
|
|
11
10
|
import { TextTrigger } from "./components/TextTrigger/TextTrigger.js";
|
|
11
|
+
import { Wrapper } from "./Dropdown.styles.js";
|
|
12
12
|
import { useDropdownVisibility } from "./hooks/useDropdownVisibility.js";
|
|
13
13
|
const Dropdown = ({
|
|
14
14
|
hideOnItemClick,
|
package/dist/Dropdown.types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CSSProperties, HTMLAttributes, ReactNode } from 'react';
|
|
2
1
|
import { OpenChangeReason } from '@floating-ui/react';
|
|
2
|
+
import { CSSProperties, HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
import { LegacyDropdownPlacement, PopoverOptions, PopoverTriggerType } from '@synerise/ds-popover';
|
|
4
4
|
import { WithHTMLAttributes } from '@synerise/ds-utils';
|
|
5
5
|
export type DropdownProps = Omit<WithHTMLAttributes<HTMLDivElement, DropdownSharedProps & {
|
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useMemo } from "react";
|
|
2
|
+
import { useCallback, useMemo, useRef, useEffect } from "react";
|
|
3
3
|
import { VariableSizeList } from "react-window";
|
|
4
4
|
import { SearchNoResultsL } from "@synerise/ds-icon";
|
|
5
|
-
import { LIST_ITEM_SIZE_MAPPING } from "@synerise/ds-list-item";
|
|
5
|
+
import { LIST_ITEM_SIZE_MAPPING, itemTypes, itemSizes } from "@synerise/ds-list-item";
|
|
6
6
|
import Scrollbar from "@synerise/ds-scrollbar";
|
|
7
|
+
import { useMeasuredRowHeights, useMeasuredRow } from "@synerise/ds-utils";
|
|
7
8
|
import { MAX_VISIBLE_ITEMS, SCROLLBAR_OFFSET } from "../../Dropdown.const.js";
|
|
8
9
|
import { ScrollableMenuWrapper, DropdownMenuList as DropdownMenuList$1, DropdownMenuListItem, EmptyStates } from "./DropdownMenuList.styles.js";
|
|
10
|
+
const DIVIDER_HEIGHT = 17;
|
|
11
|
+
const CLOSE_DELAY = 10;
|
|
12
|
+
const DropdownRow = ({
|
|
13
|
+
index,
|
|
14
|
+
style,
|
|
15
|
+
data
|
|
16
|
+
}) => {
|
|
17
|
+
const {
|
|
18
|
+
dataSource,
|
|
19
|
+
onItemClick,
|
|
20
|
+
measureRow
|
|
21
|
+
} = data;
|
|
22
|
+
const item = dataSource[index];
|
|
23
|
+
const rowRef = useMeasuredRow(index, measureRow);
|
|
24
|
+
return /* @__PURE__ */ jsx("div", { ref: rowRef, style: {
|
|
25
|
+
...style,
|
|
26
|
+
height: "auto",
|
|
27
|
+
minHeight: style.height
|
|
28
|
+
}, children: item.type === itemTypes.DIVIDER ? /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item }) : /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item, itemKey: item.key, onClick: (itemData) => {
|
|
29
|
+
item.onClick?.(itemData);
|
|
30
|
+
onItemClick();
|
|
31
|
+
} }) });
|
|
32
|
+
};
|
|
9
33
|
const DropdownMenuList = ({
|
|
10
34
|
dataSource,
|
|
11
35
|
maxVisibleItems = MAX_VISIBLE_ITEMS,
|
|
@@ -14,53 +38,68 @@ const DropdownMenuList = ({
|
|
|
14
38
|
closeOverlay,
|
|
15
39
|
texts
|
|
16
40
|
}) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
41
|
+
const getEstimatedItemSize = useCallback((index) => {
|
|
42
|
+
const item = dataSource[index];
|
|
43
|
+
return item.type === itemTypes.DIVIDER ? DIVIDER_HEIGHT : LIST_ITEM_SIZE_MAPPING[item.size || itemSizes.DEFAULT];
|
|
19
44
|
}, [dataSource]);
|
|
45
|
+
const rowKeys = useMemo(() => dataSource.map((item, index) => item.key ?? item.itemKey ?? index), [dataSource]);
|
|
46
|
+
const {
|
|
47
|
+
listRef,
|
|
48
|
+
getItemSize,
|
|
49
|
+
measureRow,
|
|
50
|
+
measurementVersion
|
|
51
|
+
} = useMeasuredRowHeights({
|
|
52
|
+
keys: rowKeys,
|
|
53
|
+
estimate: getEstimatedItemSize
|
|
54
|
+
});
|
|
55
|
+
const closeTimeoutRef = useRef();
|
|
20
56
|
const handleItemClick = useCallback(() => {
|
|
21
57
|
if (hideOnItemClick) {
|
|
22
|
-
|
|
58
|
+
clearTimeout(closeTimeoutRef.current);
|
|
59
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
23
60
|
closeOverlay();
|
|
24
|
-
},
|
|
61
|
+
}, CLOSE_DELAY);
|
|
25
62
|
}
|
|
26
63
|
}, [hideOnItemClick, closeOverlay]);
|
|
64
|
+
useEffect(() => () => clearTimeout(closeTimeoutRef.current), []);
|
|
27
65
|
const {
|
|
28
66
|
listHeight,
|
|
29
|
-
listMaxHeight
|
|
67
|
+
listMaxHeight,
|
|
68
|
+
hasAutoItem
|
|
30
69
|
} = useMemo(() => {
|
|
31
70
|
let height = 0;
|
|
32
71
|
let maxHeight = 0;
|
|
33
72
|
let visibleItems = 0;
|
|
73
|
+
let auto = false;
|
|
34
74
|
dataSource.forEach((item, index) => {
|
|
35
75
|
const itemHeight = getItemSize(index);
|
|
36
76
|
height += itemHeight;
|
|
37
77
|
if (visibleItems < maxVisibleItems) {
|
|
38
78
|
maxHeight += itemHeight;
|
|
39
79
|
}
|
|
40
|
-
if (item.type !==
|
|
80
|
+
if (item.type !== itemTypes.DIVIDER) {
|
|
41
81
|
visibleItems += 1;
|
|
42
82
|
}
|
|
83
|
+
if (item.size === itemSizes.AUTO) {
|
|
84
|
+
auto = true;
|
|
85
|
+
}
|
|
43
86
|
});
|
|
44
87
|
return {
|
|
45
88
|
listHeight: height,
|
|
46
|
-
listMaxHeight: maxHeight
|
|
89
|
+
listMaxHeight: maxHeight,
|
|
90
|
+
hasAutoItem: auto
|
|
47
91
|
};
|
|
48
|
-
}, [dataSource, getItemSize, maxVisibleItems]);
|
|
49
|
-
|
|
92
|
+
}, [dataSource, getItemSize, maxVisibleItems, measurementVersion]);
|
|
93
|
+
const itemData = useMemo(() => ({
|
|
94
|
+
dataSource,
|
|
95
|
+
onItemClick: handleItemClick,
|
|
96
|
+
measureRow
|
|
97
|
+
}), [dataSource, handleItemClick, measureRow]);
|
|
98
|
+
return /* @__PURE__ */ jsx(ScrollableMenuWrapper, { children: dataSource.length ? /* @__PURE__ */ jsx(Scrollbar, { absolute: true, maxHeight: !virtualised && hasAutoItem ? void 0 : listMaxHeight + SCROLLBAR_OFFSET, children: /* @__PURE__ */ jsx(DropdownMenuList$1, { children: virtualised ? /* @__PURE__ */ jsx(VariableSizeList, { ref: listRef, height: listHeight, itemData, itemCount: dataSource.length, itemSize: getItemSize, itemKey: (index) => rowKeys[index], estimatedItemSize: getEstimatedItemSize(0), width: "100%", style: {
|
|
50
99
|
paddingRight: "8px"
|
|
51
|
-
}, children: (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
index
|
|
55
|
-
} = listItemData;
|
|
56
|
-
const item = data[index];
|
|
57
|
-
return item.type === "divider" ? /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item }) : /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item, itemKey: item.key, onClick: (itemData) => {
|
|
58
|
-
item.onClick?.(itemData);
|
|
59
|
-
handleItemClick();
|
|
60
|
-
} });
|
|
61
|
-
} }) : /* @__PURE__ */ jsx(Fragment, { children: dataSource.map((item) => {
|
|
62
|
-
return item.type === "divider" ? /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item }) : /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item, itemKey: item.key, onClick: (itemData) => {
|
|
63
|
-
item.onClick?.(itemData);
|
|
100
|
+
}, children: DropdownRow }) : /* @__PURE__ */ jsx(Fragment, { children: dataSource.map((item) => {
|
|
101
|
+
return item.type === itemTypes.DIVIDER ? /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item }) : /* @__PURE__ */ jsx(DropdownMenuListItem, { ...item, itemKey: item.key, onClick: (clickedItem) => {
|
|
102
|
+
item.onClick?.(clickedItem);
|
|
64
103
|
handleItemClick();
|
|
65
104
|
} });
|
|
66
105
|
}) }) }) }) : /* @__PURE__ */ jsx(EmptyStates, { iconPosition: "top", customIcon: /* @__PURE__ */ jsx(SearchNoResultsL, {}), label: texts.noSearchResults }) });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMergeRefs } from "@floating-ui/react";
|
|
2
3
|
import classnames from "classnames";
|
|
3
4
|
import { forwardRef, useRef, useState, useEffect } from "react";
|
|
4
|
-
import { useMergeRefs } from "@floating-ui/react";
|
|
5
5
|
import { getDropdownWidth } from "../../utils/getDropdownWidth.js";
|
|
6
6
|
import { OverlayWrapper } from "./DropdownOverlay.styles.js";
|
|
7
7
|
const DropdownOverlay = forwardRef(({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRef } from "react";
|
|
3
2
|
import { FloatingList } from "@floating-ui/react";
|
|
3
|
+
import { useRef } from "react";
|
|
4
4
|
import { DropdownContextProvider } from "@synerise/ds-core";
|
|
5
5
|
import { getPlacement, Popover, PopoverTrigger, PopoverContent } from "@synerise/ds-popover";
|
|
6
6
|
import { POPOVER_SHIFT_CONFIG, POPOVER_FLIP_CONFIG, POPOVER_OFFSET_CONFIG, POPOVER_TRANSITION_DURATION } from "../../Dropdown.const.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { BackAction } from './components/BackAction/BackAction';
|
|
2
|
+
export { BottomAction } from './components/BottomAction/BottomAction';
|
|
2
3
|
export { DropdownMenu } from './components/DropdownMenu/DropdownMenu';
|
|
4
|
+
export type { DropdownMenuProps } from './components/DropdownMenu/DropdownMenu.types';
|
|
5
|
+
export type { DropdownMenuListItemProps } from './components/DropdownMenuList/DropdownMenuList.types';
|
|
3
6
|
export { DropdownOverlay } from './components/DropdownOverlay/DropdownOverlay';
|
|
4
7
|
export { TextTrigger } from './components/TextTrigger/TextTrigger';
|
|
5
|
-
export {
|
|
6
|
-
export { BottomAction } from './components/BottomAction/BottomAction';
|
|
8
|
+
export { Dropdown, default } from './Dropdown';
|
|
7
9
|
export type { DropdownPlacement, DropdownProps, DropdownSharedProps, DropdownSize, } from './Dropdown.types';
|
|
8
|
-
export { type DropdownMenuProps } from './components/DropdownMenu/DropdownMenu.types';
|
|
9
|
-
export { type DropdownMenuListItemProps } from './components/DropdownMenuList/DropdownMenuList.types';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackAction } from "./components/BackAction/BackAction.js";
|
|
2
|
+
import { BottomAction } from "./components/BottomAction/BottomAction.js";
|
|
2
3
|
import { DropdownMenu } from "./components/DropdownMenu/DropdownMenu.js";
|
|
3
4
|
import { DropdownOverlay } from "./components/DropdownOverlay/DropdownOverlay.js";
|
|
4
5
|
import { TextTrigger } from "./components/TextTrigger/TextTrigger.js";
|
|
5
|
-
import {
|
|
6
|
-
import { BottomAction } from "./components/BottomAction/BottomAction.js";
|
|
6
|
+
import { Dropdown, Dropdown as Dropdown2 } from "./Dropdown.js";
|
|
7
7
|
export {
|
|
8
8
|
BackAction,
|
|
9
9
|
BottomAction,
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { getDropdownWidth } from "./getDropdownWidth.js";
|
|
1
2
|
import { getTransitionConfig } from "./getTransitionConfig.js";
|
|
2
3
|
import { isSplitFooter } from "./isSplitFooter.js";
|
|
3
|
-
import { getDropdownWidth } from "./getDropdownWidth.js";
|
|
4
4
|
export {
|
|
5
5
|
getDropdownWidth,
|
|
6
6
|
getTransitionConfig,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-dropdown",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Dropdown UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "synerise/synerise-design",
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"types": "dist/index.d.ts",
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@floating-ui/react": "^0.27.16",
|
|
46
|
-
"@synerise/ds-divider": "^2.0.
|
|
47
|
-
"@synerise/ds-empty-states": "^2.0.
|
|
48
|
-
"@synerise/ds-icon": "^2.1.
|
|
49
|
-
"@synerise/ds-list-item": "^2.
|
|
50
|
-
"@synerise/ds-popover": "^2.0.
|
|
51
|
-
"@synerise/ds-scrollbar": "^2.0.
|
|
52
|
-
"@synerise/ds-search-bar": "^2.0.
|
|
53
|
-
"@synerise/ds-tooltip": "^2.0.
|
|
54
|
-
"@synerise/ds-typography": "^2.0.
|
|
55
|
-
"@synerise/ds-utils": "^2.
|
|
46
|
+
"@synerise/ds-divider": "^2.0.4",
|
|
47
|
+
"@synerise/ds-empty-states": "^2.0.3",
|
|
48
|
+
"@synerise/ds-icon": "^2.1.2",
|
|
49
|
+
"@synerise/ds-list-item": "^2.1.1",
|
|
50
|
+
"@synerise/ds-popover": "^2.0.2",
|
|
51
|
+
"@synerise/ds-scrollbar": "^2.0.3",
|
|
52
|
+
"@synerise/ds-search-bar": "^2.0.5",
|
|
53
|
+
"@synerise/ds-tooltip": "^2.0.4",
|
|
54
|
+
"@synerise/ds-typography": "^2.0.4",
|
|
55
|
+
"@synerise/ds-utils": "^2.1.1",
|
|
56
56
|
"classnames": "^2.5.1",
|
|
57
57
|
"react-window": "^1.8.11"
|
|
58
58
|
},
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"react-intl": "^6.8.7",
|
|
66
66
|
"styled-components": "^5.3.3"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "b1d905617dfb186b5d80966d63ce55bf29df743d"
|
|
69
69
|
}
|