@synerise/ds-factors 0.25.0 → 0.25.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 CHANGED
@@ -3,6 +3,18 @@
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.25.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-factors@0.25.0...@synerise/ds-factors@0.25.1) (2024-09-11)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **context-selector:** updated search logic ([dfadc02](https://github.com/Synerise/synerise-design/commit/dfadc02928651905f31c58a374d48368b8375eb3))
12
+ * **factors:** make all dropdowns same fixed height ([40e86d1](https://github.com/Synerise/synerise-design/commit/40e86d183dddb925c2b75c499615c1455b93b7c4))
13
+
14
+
15
+
16
+
17
+
6
18
  # [0.25.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-factors@0.24.0...@synerise/ds-factors@0.25.0) (2024-09-03)
7
19
 
8
20
 
package/README.md CHANGED
@@ -33,6 +33,7 @@ import Factors from '@synerise/ds-factors'
33
33
  groups: [{
34
34
  name: 'Recent',
35
35
  id: 1,
36
+ allowEmpty: true,
36
37
  defaultGroup: true,
37
38
  },{
38
39
  name: 'All',
@@ -151,10 +152,11 @@ Type of value depends on current factor type and can contain values: `string` \
151
152
 
152
153
  ### ParameterOptions
153
154
 
154
- | Property | Description | Type | Default |
155
- |-----------------------|------------------------------------------------------------|--------------------------|---------|
156
- | buttonIcon | Icon in button | React.ReactNode | - |
157
- | buttonLabel | Label of button | string \ React.ReactNode | - |
158
- | groups | Array of parameter groups | ParameterGroup[] | - |
159
- | items | Array of parameters | ParameterItem[] | - |
160
- | selectedButtonColored | Whether to use green custom color if parameter is selected | boolean | - |
155
+ | Property | Description | Type | Default |
156
+ |-------------------------|------------------------------------------------------------|--------------------------|---------|
157
+ | buttonIcon | Icon in button | React.ReactNode | - |
158
+ | buttonLabel | Label of button | string \ React.ReactNode | - |
159
+ | groups | Array of parameter groups | ParameterGroup[] | - |
160
+ | items | Array of parameters | ParameterItem[] | - |
161
+ | selectedButtonColored | Whether to use green custom color if parameter is selected | boolean | - |
162
+ | maxSearchResultsInGroup | How many search results should be shown per group | number | 4 |
@@ -24,7 +24,6 @@ var DateRangeInput = function DateRangeInput(_ref) {
24
24
  return /*#__PURE__*/React.createElement(DateRangePicker, {
25
25
  intl: intl,
26
26
  onApply: changeHandler,
27
- onValueChange: changeHandler,
28
27
  showTime: true,
29
28
  getPopupContainer: getPopupContainerOverride || getPopupContainer,
30
29
  showFilter: true,
@@ -0,0 +1,14 @@
1
+ import { CSSProperties } from 'react';
2
+ export declare const LIST_STYLE: CSSProperties;
3
+ export declare const NO_GROUP_NAME = "NO_GROUP_NAME";
4
+ export declare const ITEM_SIZE: {
5
+ large: number;
6
+ default: number;
7
+ title: number;
8
+ };
9
+ export declare const DROPDOWN_HEIGHT = 420;
10
+ export declare const DROPDOWN_HEIGHT_BELOW_THRESHOLD = 350;
11
+ export declare const DROPDOWN_HEIGHT_THRESHOLD = 800;
12
+ export declare const SEARCH_HEGIHT = 53;
13
+ export declare const TABS_HEIGHT = 50;
14
+ export declare const SUBGROUP_HEADER_HEIGHT = 53;
@@ -0,0 +1,15 @@
1
+ var _ITEM_SIZE;
2
+
3
+ import { itemSizes } from '@synerise/ds-list-item';
4
+ export var LIST_STYLE = {
5
+ overflowX: 'unset',
6
+ overflowY: 'unset'
7
+ };
8
+ export var NO_GROUP_NAME = 'NO_GROUP_NAME';
9
+ export var ITEM_SIZE = (_ITEM_SIZE = {}, _ITEM_SIZE[itemSizes.LARGE] = 50, _ITEM_SIZE[itemSizes.DEFAULT] = 32, _ITEM_SIZE.title = 32, _ITEM_SIZE);
10
+ export var DROPDOWN_HEIGHT = 420;
11
+ export var DROPDOWN_HEIGHT_BELOW_THRESHOLD = 350;
12
+ export var DROPDOWN_HEIGHT_THRESHOLD = 800;
13
+ export var SEARCH_HEGIHT = 53;
14
+ export var TABS_HEIGHT = 50;
15
+ export var SUBGROUP_HEADER_HEIGHT = 53;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { InputProps } from '../../Factors.types';
3
- declare const ParameterInput: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, getMenuEntryProps, }: InputProps) => React.JSX.Element;
3
+ declare const ParameterInput: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, loading, getMenuEntryProps, }: InputProps) => React.JSX.Element;
4
4
  export default ParameterInput;
@@ -1,4 +1,4 @@
1
- var _excluded = ["buttonIcon", "buttonLabel", "selectedButtonColored", "loading"];
1
+ var _excluded = ["buttonIcon", "buttonLabel", "selectedButtonColored", "dropdownDimensionsConfig"];
2
2
 
3
3
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
4
4
 
@@ -19,6 +19,7 @@ import { getPopupContainer } from '@synerise/ds-utils';
19
19
  import InformationCard from '@synerise/ds-information-card';
20
20
  import { Value } from './Parameter.style';
21
21
  import ParameterDropdown from './ParameterDropdown';
22
+ import { DROPDOWN_HEIGHT, DROPDOWN_HEIGHT_BELOW_THRESHOLD, DROPDOWN_HEIGHT_THRESHOLD } from './Parameter.constants';
22
23
 
23
24
  var ParameterInput = function ParameterInput(_ref) {
24
25
  var value = _ref.value,
@@ -34,19 +35,30 @@ var ParameterInput = function ParameterInput(_ref) {
34
35
  _ref$readOnly = _ref.readOnly,
35
36
  readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
36
37
  error = _ref.error,
38
+ loading = _ref.loading,
37
39
  getMenuEntryProps = _ref.getMenuEntryProps;
38
40
 
39
41
  // @ts-ignore
40
42
  var buttonIcon = parameters.buttonIcon,
41
43
  buttonLabel = parameters.buttonLabel,
42
44
  selectedButtonColored = parameters.selectedButtonColored,
43
- loading = parameters.loading,
45
+ dropdownDimensionsConfig = parameters.dropdownDimensionsConfig,
44
46
  restParameters = _objectWithoutPropertiesLoose(parameters, _excluded);
45
47
 
48
+ var dimensionsConfig = _objectSpread({
49
+ defaultHeight: DROPDOWN_HEIGHT,
50
+ lowerHeight: DROPDOWN_HEIGHT_BELOW_THRESHOLD,
51
+ threshold: DROPDOWN_HEIGHT_THRESHOLD
52
+ }, dropdownDimensionsConfig);
53
+
46
54
  var _useState = useState(false),
47
55
  dropdownVisible = _useState[0],
48
56
  setDropdownVisible = _useState[1];
49
57
 
58
+ var _useState2 = useState(dimensionsConfig.defaultHeight),
59
+ outerHeight = _useState2[0],
60
+ setOuterHeight = _useState2[1];
61
+
50
62
  var parameter = useMemo(function () {
51
63
  return value;
52
64
  }, [value]);
@@ -135,6 +147,17 @@ var ParameterInput = function ParameterInput(_ref) {
135
147
  } : undefined
136
148
  }, getMenuEntryProps == null ? void 0 : getMenuEntryProps(parameter))]
137
149
  });
150
+ useEffect(function () {
151
+ var checkViewportHeight = function checkViewportHeight() {
152
+ return setOuterHeight(window.innerHeight < dimensionsConfig.threshold ? dimensionsConfig.lowerHeight : dimensionsConfig.defaultHeight);
153
+ };
154
+
155
+ checkViewportHeight();
156
+ window.addEventListener('resize', checkViewportHeight);
157
+ return function () {
158
+ window.removeEventListener('resize', checkViewportHeight);
159
+ };
160
+ }, [dimensionsConfig.defaultHeight, dimensionsConfig.lowerHeight, dimensionsConfig.threshold]);
138
161
  return readOnly ? trigger : /*#__PURE__*/React.createElement("div", {
139
162
  "data-popup-container": true,
140
163
  "data-testid": "ds-factors-parameter"
@@ -147,7 +170,9 @@ var ParameterInput = function ParameterInput(_ref) {
147
170
  setSelected: handleChange
148
171
  }, restParameters, {
149
172
  texts: texts,
150
- loading: loading
173
+ loading: loading,
174
+ outerHeight: outerHeight,
175
+ value: isSelected ? parameter : undefined
151
176
  }))
152
177
  }, trigger));
153
178
  };
@@ -1,8 +1,16 @@
1
- import { FixedSizeList } from 'react-window';
1
+ /// <reference types="react" />
2
+ import { VariableSizeList } from 'react-window';
2
3
  export declare const TabsWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
3
4
  export declare const ContentPlaceholder: import("styled-components").StyledComponent<"div", any, {}, never>;
4
- export declare const ItemsList: import("styled-components").StyledComponent<"div", any, {}, never>;
5
+ export declare const ItemsList: import("styled-components").StyledComponent<"div", any, {
6
+ contentHeight?: number | undefined;
7
+ }, never>;
5
8
  export declare const SearchResult: import("styled-components").StyledComponent<"span", any, {}, never>;
6
9
  export declare const SearchResultHighlight: import("styled-components").StyledComponent<"span", any, {}, never>;
7
10
  export declare const Value: import("styled-components").StyledComponent<"span", any, {}, never>;
8
- export declare const StyledList: import("styled-components").StyledComponent<typeof FixedSizeList, any, {}, never>;
11
+ export declare const StyledList: import("styled-components").StyledComponent<typeof VariableSizeList, any, {}, never>;
12
+ export declare const Skeleton: import("styled-components").StyledComponent<({ size, numberOfSkeletons, width, height, className }: import("@synerise/ds-skeleton").SkeletonProps) => import("react").JSX.Element, any, {
13
+ contentHeight?: number | undefined;
14
+ }, never>;
15
+ export declare const Title: import("styled-components").StyledComponent<"div", any, {}, never>;
16
+ export declare const ShowMoreItem: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -1,5 +1,6 @@
1
1
  import styled from 'styled-components';
2
- import { FixedSizeList } from 'react-window';
2
+ import DropdownSkeleton from '@synerise/ds-skeleton';
3
+ import { VariableSizeList } from 'react-window';
3
4
  export var TabsWrapper = styled.div.withConfig({
4
5
  displayName: "Parameterstyle__TabsWrapper",
5
6
  componentId: "u2uvgh-0"
@@ -11,7 +12,9 @@ export var ContentPlaceholder = styled.div.withConfig({
11
12
  export var ItemsList = styled.div.withConfig({
12
13
  displayName: "Parameterstyle__ItemsList",
13
14
  componentId: "u2uvgh-2"
14
- })(["width:100%;"]);
15
+ })(["width:100%;", ""], function (props) {
16
+ return props.contentHeight !== undefined && "height: " + props.contentHeight + "px;";
17
+ });
15
18
  export var SearchResult = styled.span.withConfig({
16
19
  displayName: "Parameterstyle__SearchResult",
17
20
  componentId: "u2uvgh-3"
@@ -28,7 +31,23 @@ export var Value = styled.span.withConfig({
28
31
  displayName: "Parameterstyle__Value",
29
32
  componentId: "u2uvgh-5"
30
33
  })(["max-width:110px;text-overflow:ellipsis;overflow:hidden;"]);
31
- export var StyledList = styled(FixedSizeList).withConfig({
34
+ export var StyledList = styled(VariableSizeList).withConfig({
32
35
  displayName: "Parameterstyle__StyledList",
33
36
  componentId: "u2uvgh-6"
34
- })(["overflowx:unset;overflowy:unset;height:auto !important;max-height:300px;"]);
37
+ })(["overflowx:unset;overflowy:unset;height:auto !important;max-height:300px;"]);
38
+ export var Skeleton = styled(DropdownSkeleton).withConfig({
39
+ displayName: "Parameterstyle__Skeleton",
40
+ componentId: "u2uvgh-7"
41
+ })(["", ""], function (props) {
42
+ return props.contentHeight !== undefined && "height: " + props.contentHeight + "px;";
43
+ });
44
+ export var Title = styled.div.withConfig({
45
+ displayName: "Parameterstyle__Title",
46
+ componentId: "u2uvgh-8"
47
+ })(["font-size:10px;line-height:1.6;font-weight:500;text-transform:uppercase;color:", ";padding:8px 12px;"], function (props) {
48
+ return props.theme.palette['grey-500'];
49
+ });
50
+ export var ShowMoreItem = styled.div.withConfig({
51
+ displayName: "Parameterstyle__ShowMoreItem",
52
+ componentId: "u2uvgh-9"
53
+ })(["font-weight:500;"]);
@@ -0,0 +1,18 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ import type { ParameterItem, ParameterGroup } from '../../Factors.types';
3
+ export type DropdownItem<ItemType extends ParameterItem | ParameterGroup> = {
4
+ item: ItemType;
5
+ searchQuery: string;
6
+ clearSearch?: () => void;
7
+ hideDropdown?: () => void;
8
+ select: (item: ItemType) => void;
9
+ className: string;
10
+ style?: CSSProperties;
11
+ label?: ReactNode;
12
+ };
13
+ export type DropdownItemProps<ItemType extends ParameterItem | ParameterGroup> = ParameterDropdownTitleProps | DropdownItem<ItemType>;
14
+ export type ParameterDropdownTitleProps = {
15
+ title?: string;
16
+ type?: string;
17
+ };
18
+ export type MixedDropdownItemProps = DropdownItemProps<ParameterItem> | DropdownItemProps<ParameterGroup>;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { ParameterDropdownProps } from '../../Factors.types';
3
- declare const ParameterDropdown: ({ setSelected, texts, groups, items, setDropdownVisible, loading, onFetchData, hasMoreItems, }: ParameterDropdownProps) => React.JSX.Element;
3
+ declare const ParameterDropdown: ({ setSelected, texts, groups, items, setDropdownVisible, loading, onFetchData, hasMoreItems, outerHeight, value, renderEmptyGroups, maxSearchResultsInGroup, }: ParameterDropdownProps) => React.JSX.Element;
4
4
  export default ParameterDropdown;
@@ -1,20 +1,22 @@
1
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
- import React, { createRef, useRef, useState, useMemo, useCallback } from 'react';
3
+ import React, { useRef, useState, useMemo, useCallback, useEffect } from 'react';
4
+ import { v4 as uuid } from 'uuid';
4
5
  import Dropdown from '@synerise/ds-dropdown';
5
- import Icon, { SearchM } from '@synerise/ds-icon';
6
+ import Icon, { ArrowRightCircleM, SearchM } from '@synerise/ds-icon';
6
7
  import Tabs from '@synerise/ds-tabs';
7
- import { focusWithArrowKeys, useOnClickOutside, getClosest } from '@synerise/ds-utils';
8
+ import { useSearchResults, getGroupName, focusWithArrowKeys, useOnClickOutside, getClosest } from '@synerise/ds-utils';
8
9
  import Result from '@synerise/ds-result';
9
10
  import { theme } from '@synerise/ds-core';
10
11
  import Scrollbar from '@synerise/ds-scrollbar';
11
- import { v4 as uuid } from 'uuid';
12
- import DropdownSkeleton from '@synerise/ds-skeleton';
12
+ import { itemSizes } from '@synerise/ds-list-item';
13
13
  import * as S from './Parameter.style';
14
14
  import ParameterDropdownItem from './ParameterDropdownItem';
15
- var LIST_STYLE = {
16
- overflowX: 'unset',
17
- overflowY: 'unset'
15
+ import { useGroups } from './useGroups';
16
+ import { DROPDOWN_HEIGHT, SEARCH_HEGIHT, TABS_HEIGHT, SUBGROUP_HEADER_HEIGHT, ITEM_SIZE, LIST_STYLE, NO_GROUP_NAME } from './Parameter.constants';
17
+
18
+ var isListTitle = function isListTitle(element) {
19
+ return element.title !== undefined;
18
20
  };
19
21
 
20
22
  var ParameterDropdown = function ParameterDropdown(_ref) {
@@ -25,15 +27,22 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
25
27
  setDropdownVisible = _ref.setDropdownVisible,
26
28
  loading = _ref.loading,
27
29
  onFetchData = _ref.onFetchData,
28
- hasMoreItems = _ref.hasMoreItems;
29
- var listRef = createRef();
30
- var defaultTab = useMemo(function () {
31
- var defaultIndex = groups == null ? void 0 : groups.findIndex(function (group) {
32
- return group.defaultGroup;
33
- });
34
- return defaultIndex || 0;
35
- }, [groups]);
30
+ hasMoreItems = _ref.hasMoreItems,
31
+ _ref$outerHeight = _ref.outerHeight,
32
+ outerHeight = _ref$outerHeight === void 0 ? DROPDOWN_HEIGHT : _ref$outerHeight,
33
+ value = _ref.value,
34
+ _ref$renderEmptyGroup = _ref.renderEmptyGroups,
35
+ renderEmptyGroups = _ref$renderEmptyGroup === void 0 ? false : _ref$renderEmptyGroup,
36
+ _ref$maxSearchResults = _ref.maxSearchResultsInGroup,
37
+ maxSearchResultsInGroup = _ref$maxSearchResults === void 0 ? 4 : _ref$maxSearchResults;
38
+ var listRef = useRef(null);
36
39
  var overlayRef = useRef(null);
40
+ var scrollBarRef = useRef(null);
41
+
42
+ var _useGroups = useGroups(items, groups, renderEmptyGroups),
43
+ visibleGroups = _useGroups.visibleGroups,
44
+ tabs = _useGroups.tabs,
45
+ defaultTab = _useGroups.defaultTab;
37
46
 
38
47
  var _useState = useState(''),
39
48
  searchQuery = _useState[0],
@@ -60,33 +69,85 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
60
69
  }
61
70
  });
62
71
  var currentTabItems = useMemo(function () {
63
- return groups == null ? void 0 : groups.find(function (group, index) {
72
+ return visibleGroups == null ? void 0 : visibleGroups.find(function (_group, index) {
64
73
  return activeTab === index;
65
74
  });
66
- }, [groups, activeTab]);
67
- var handleClearSearch = useCallback(function () {
75
+ }, [visibleGroups, activeTab]);
76
+ var clearSearch = useCallback(function () {
68
77
  setSearchQuery('');
69
78
  }, []);
70
- var handleHideDropdown = useCallback(function () {
79
+ var handleOnSetGroup = useCallback(function (item) {
80
+ setActiveGroup(item);
81
+ }, []);
82
+ var hideDropdown = useCallback(function () {
71
83
  setDropdownVisible(false);
72
84
  }, [setDropdownVisible]);
73
- var filteredItems = useMemo(function () {
74
- return items == null ? void 0 : items.filter(function (item) {
75
- return item.name.toLowerCase().includes(searchQuery.toLowerCase());
76
- }).map(function (item) {
77
- return {
78
- className: classNames,
79
- item: item,
80
- searchQuery: searchQuery,
81
- clearSearch: handleClearSearch,
82
- hideDropdown: handleHideDropdown,
83
- select: setSelected
84
- };
85
+ var groupByGroupName = useCallback(function (dropdownItems, maxItemsInGroup) {
86
+ var itemsNumber = dropdownItems == null ? void 0 : dropdownItems.length;
87
+ var groupedItems = {};
88
+
89
+ for (var i = 0; i < itemsNumber; i += 1) {
90
+ var _item = dropdownItems[i]; // @ts-ignore
91
+
92
+ var groupName = _item.groupName || NO_GROUP_NAME;
93
+ var group = groupedItems[groupName] || [];
94
+ group.push(_item);
95
+ groupedItems[groupName] = group;
96
+ }
97
+
98
+ var resultItems = [];
99
+ Object.keys(groupedItems).forEach(function (key) {
100
+ if (key !== NO_GROUP_NAME && !activeGroup) {
101
+ resultItems.push({
102
+ type: 'title',
103
+ title: key
104
+ });
105
+ }
106
+
107
+ var groupItems = maxItemsInGroup ? groupedItems[key].slice(0, maxItemsInGroup) : groupedItems[key];
108
+ groupItems.forEach(function (item) {
109
+ var resultItem = !item.groupId ? {
110
+ className: classNames,
111
+ item: item,
112
+ searchQuery: searchQuery,
113
+ select: handleOnSetGroup
114
+ } : {
115
+ className: classNames,
116
+ item: item,
117
+ searchQuery: searchQuery,
118
+ clearSearch: clearSearch,
119
+ hideDropdown: hideDropdown,
120
+ select: setSelected,
121
+ selected: value && item.id === (value == null ? void 0 : value.id)
122
+ };
123
+ resultItems.push(resultItem);
124
+ });
125
+
126
+ if (maxItemsInGroup && groupedItems[key].length > maxItemsInGroup) {
127
+ var anyItem = groupItems[0];
128
+ resultItems.push({
129
+ className: classNames,
130
+ select: handleOnSetGroup,
131
+ searchQuery: searchQuery,
132
+ label: /*#__PURE__*/React.createElement(S.ShowMoreItem, null, texts.parameter.showMore),
133
+ item: {
134
+ isGroup: true,
135
+ id: anyItem.groupId,
136
+ name: getGroupName(anyItem.groupId, groups || []) || '',
137
+ icon: /*#__PURE__*/React.createElement(ArrowRightCircleM, null)
138
+ }
139
+ });
140
+ }
85
141
  });
86
- }, [items, searchQuery, classNames, handleClearSearch, handleHideDropdown, setSelected]);
142
+ return resultItems;
143
+ }, [activeGroup, classNames, searchQuery, handleOnSetGroup, clearSearch, hideDropdown, setSelected, value, texts.parameter.showMore, groups]);
144
+
145
+ var _useSearchResults = useSearchResults(items || [], groups || [], activeTab, groupByGroupName, activeGroup, searchQuery, maxSearchResultsInGroup),
146
+ searchResults = _useSearchResults.searchResults;
147
+
87
148
  var currentItems = useMemo(function () {
88
149
  if (searchQuery) {
89
- return filteredItems;
150
+ return searchResults;
90
151
  }
91
152
 
92
153
  var hasSubgroups = Boolean(currentTabItems == null ? void 0 : currentTabItems.subGroups);
@@ -112,21 +173,21 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
112
173
  className: classNames,
113
174
  item: item,
114
175
  searchQuery: searchQuery,
115
- hideDropdown: handleHideDropdown,
176
+ hideDropdown: hideDropdown,
116
177
  select: setSelected
117
178
  };
118
179
  });
119
180
  }
120
181
 
121
- if (activeTab && groups && groups[activeTab]) {
182
+ if (activeTab && visibleGroups && visibleGroups[activeTab]) {
122
183
  return items == null ? void 0 : items.filter(function (item) {
123
- return item.groupId === groups[activeTab].id;
184
+ return item.groupId === visibleGroups[activeTab].id;
124
185
  }).map(function (item) {
125
186
  return {
126
187
  className: classNames,
127
188
  item: item,
128
189
  searchQuery: searchQuery,
129
- hideDropdown: handleHideDropdown,
190
+ hideDropdown: hideDropdown,
130
191
  select: setSelected
131
192
  };
132
193
  });
@@ -137,22 +198,14 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
137
198
  className: classNames,
138
199
  item: item,
139
200
  searchQuery: searchQuery,
140
- hideDropdown: handleHideDropdown,
201
+ hideDropdown: hideDropdown,
141
202
  select: setSelected
142
203
  };
143
204
  });
144
- }, [searchQuery, currentTabItems, activeGroup, groups, items, filteredItems, classNames, handleHideDropdown, setSelected, activeTab]);
145
- var handleSearch = useCallback(function (value) {
146
- setSearchQuery(value);
205
+ }, [searchQuery, currentTabItems, activeGroup, visibleGroups, items, searchResults, classNames, hideDropdown, setSelected, activeTab]);
206
+ var handleSearch = useCallback(function (newSearchQuery) {
207
+ setSearchQuery(newSearchQuery);
147
208
  }, [setSearchQuery]);
148
- var getTabs = useMemo(function () {
149
- return (groups == null ? void 0 : groups.map(function (group) {
150
- return {
151
- label: group.name,
152
- icon: group.icon
153
- };
154
- })) || [];
155
- }, [groups]);
156
209
  var getNoResultContainer = useMemo(function () {
157
210
  return /*#__PURE__*/React.createElement(Result, {
158
211
  noSearchResults: true,
@@ -165,21 +218,42 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
165
218
  var currentTarget = _ref2.currentTarget;
166
219
  var scrollTop = currentTarget.scrollTop;
167
220
 
168
- if (listRef.current !== null) {
221
+ if (listRef.current) {
169
222
  listRef.current.scrollTo(scrollTop);
170
223
  }
171
224
  };
172
225
 
226
+ useEffect(function () {
227
+ if (scrollBarRef.current && listRef.current) {
228
+ scrollBarRef.current.scrollTo({
229
+ top: 0
230
+ });
231
+ listRef.current.resetAfterIndex(0);
232
+ }
233
+ }, [searchQuery, activeGroup, activeTab]);
234
+
235
+ var getItemSize = function getItemSize(index) {
236
+ var item = currentItems && currentItems[index];
237
+ if (isListTitle(item)) return ITEM_SIZE.title;
238
+ return ITEM_SIZE[itemSizes.DEFAULT];
239
+ };
240
+
241
+ var hasTabs = tabs.length > 1;
242
+ var hasSearch = Boolean(searchQuery);
243
+ var dropdownContentHeight = useMemo(function () {
244
+ var fixedContentHeight = SEARCH_HEGIHT + (!hasSearch && hasTabs ? TABS_HEIGHT : 0) + (activeGroup ? SUBGROUP_HEADER_HEIGHT : 0);
245
+ return outerHeight - fixedContentHeight;
246
+ }, [activeGroup, hasSearch, hasTabs, outerHeight]);
173
247
  return /*#__PURE__*/React.createElement(Dropdown.Wrapper, {
174
248
  "data-testid": "ds-factors-parameter-dropdown-wrapper",
175
249
  style: {
176
250
  width: '300px'
177
251
  },
178
252
  ref: overlayRef,
179
- onKeyDown: function onKeyDown(e) {
253
+ onKeyDown: function onKeyDown(event) {
180
254
  setSearchInputFocus(false); // eslint-disable-next-line @typescript-eslint/no-empty-function
181
255
 
182
- searchQuery && focusWithArrowKeys(e, classNames.split(' ')[1], function () {
256
+ searchQuery && focusWithArrowKeys(event, classNames.split(' ')[1], function () {
183
257
  setSearchInputFocus(true);
184
258
  });
185
259
  }
@@ -196,9 +270,9 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
196
270
  component: /*#__PURE__*/React.createElement(SearchM, null),
197
271
  color: theme.palette['grey-600']
198
272
  })
199
- }), searchQuery === '' && getTabs.length > 1 && /*#__PURE__*/React.createElement(S.TabsWrapper, null, /*#__PURE__*/React.createElement(Tabs, {
273
+ }), tabs.length > 1 && /*#__PURE__*/React.createElement(S.TabsWrapper, null, /*#__PURE__*/React.createElement(Tabs, {
200
274
  block: true,
201
- tabs: getTabs,
275
+ tabs: tabs,
202
276
  activeTab: activeTab,
203
277
  handleTabClick: function handleTabClick(index) {
204
278
  setActiveTab(index);
@@ -209,9 +283,13 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
209
283
  onClick: function onClick() {
210
284
  return setActiveGroup(undefined);
211
285
  }
212
- }), loading ? /*#__PURE__*/React.createElement(DropdownSkeleton, {
213
- size: "M"
214
- }) : /*#__PURE__*/React.createElement(S.ItemsList, null, currentItems != null && currentItems.length ? /*#__PURE__*/React.createElement(Scrollbar, {
286
+ }), loading ? /*#__PURE__*/React.createElement(S.Skeleton, {
287
+ contentHeight: dropdownContentHeight,
288
+ size: "M",
289
+ numberOfSkeletons: 3
290
+ }) : /*#__PURE__*/React.createElement(S.ItemsList, {
291
+ contentHeight: dropdownContentHeight
292
+ }, currentItems != null && currentItems.length ? /*#__PURE__*/React.createElement(Scrollbar, {
215
293
  absolute: true,
216
294
  style: {
217
295
  padding: 8
@@ -219,20 +297,30 @@ var ParameterDropdown = function ParameterDropdown(_ref) {
219
297
  loading: loading,
220
298
  hasMore: hasMoreItems,
221
299
  onYReachEnd: onFetchData,
222
- onScroll: handleScroll
300
+ onScroll: handleScroll,
301
+ maxHeight: dropdownContentHeight,
302
+ ref: scrollBarRef
223
303
  }, /*#__PURE__*/React.createElement(S.StyledList, {
224
304
  width: "100%",
225
305
  height: 300,
226
306
  itemCount: currentItems.length,
227
- itemSize: 32,
307
+ itemSize: getItemSize,
228
308
  style: LIST_STYLE,
229
309
  ref: listRef
230
310
  }, function (_ref3) {
231
311
  var index = _ref3.index,
232
312
  style = _ref3.style;
313
+ var listItem = currentItems[index];
314
+
315
+ if (isListTitle(listItem)) {
316
+ return /*#__PURE__*/React.createElement(S.Title, {
317
+ style: style
318
+ }, listItem.title);
319
+ }
320
+
233
321
  return /*#__PURE__*/React.createElement(ParameterDropdownItem, _extends({
234
322
  style: style
235
- }, currentItems[index]));
323
+ }, listItem));
236
324
  })) : getNoResultContainer));
237
325
  };
238
326
 
@@ -1,13 +1,5 @@
1
- import React, { CSSProperties } from 'react';
1
+ import React from 'react';
2
2
  import { ParameterGroup, ParameterItem } from '../../Factors.types';
3
- export type DropdownItem = {
4
- item: ParameterItem | ParameterGroup;
5
- searchQuery: string;
6
- clearSearch?: () => void;
7
- hideDropdown?: () => void;
8
- select: (item: ParameterItem | ParameterGroup) => void;
9
- className: string;
10
- style?: CSSProperties;
11
- };
12
- declare const ParameterDropdownItem: ({ item, clearSearch, searchQuery, hideDropdown, select, className, style, }: DropdownItem) => React.JSX.Element;
3
+ import { DropdownItem } from './Parameter.types';
4
+ declare const ParameterDropdownItem: <ItemType extends ParameterGroup | ParameterItem>({ item, clearSearch, searchQuery, hideDropdown, select, className, style, label, }: DropdownItem<ItemType>) => React.JSX.Element;
13
5
  export default ParameterDropdownItem;
@@ -15,7 +15,8 @@ var ParameterDropdownItem = function ParameterDropdownItem(_ref) {
15
15
  hideDropdown = _ref.hideDropdown,
16
16
  select = _ref.select,
17
17
  className = _ref.className,
18
- style = _ref.style;
18
+ style = _ref.style,
19
+ label = _ref.label;
19
20
 
20
21
  var id = item.id,
21
22
  icon = item.icon,
@@ -34,7 +35,7 @@ var ParameterDropdownItem = function ParameterDropdownItem(_ref) {
34
35
  hideDropdown && hideDropdown();
35
36
  select && select(item);
36
37
  }
37
- }), item.name);
38
+ }), label || item.name);
38
39
  };
39
40
 
40
41
  export default ParameterDropdownItem;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { ParameterItem, ParameterGroup } from '../../Factors.types';
3
+ export declare const useGroups: (items?: ParameterItem[], groups?: ParameterGroup[], renderEmptyGroups?: boolean) => {
4
+ visibleGroups: ParameterGroup[] | undefined;
5
+ tabs: {
6
+ label: string;
7
+ icon: import("react").ReactNode;
8
+ }[];
9
+ defaultTab: number;
10
+ };
@@ -0,0 +1,76 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import { useMemo } from 'react';
8
+
9
+ var itemIsParameterGroup = function itemIsParameterGroup(item) {
10
+ return Boolean(item);
11
+ };
12
+
13
+ export var useGroups = function useGroups(items, groups, renderEmptyGroups) {
14
+ var defaultTab = useMemo(function () {
15
+ var defaultIndex = groups == null ? void 0 : groups.findIndex(function (group) {
16
+ return group.defaultGroup;
17
+ });
18
+ return defaultIndex || 0;
19
+ }, [groups]);
20
+ var visibleGroups = useMemo(function () {
21
+ if (renderEmptyGroups) {
22
+ return groups;
23
+ }
24
+
25
+ var groupIds = groups == null ? void 0 : groups.map(function (group) {
26
+ return group.subGroups || group;
27
+ }).flat().filter(function (group, index) {
28
+ return !(group.allowEmpty || index === 0);
29
+ }).map(function (group) {
30
+ return group.id;
31
+ });
32
+ var groupsToSkip = groupIds == null ? void 0 : groupIds.filter(function (groupId) {
33
+ return !(items != null && items.find(function (item) {
34
+ return item.groupId === groupId;
35
+ }));
36
+ });
37
+ var cleanGroups = groups == null ? void 0 : groups.map(function (group) {
38
+ if (group.subGroups && group.subGroups.length) {
39
+ var filteredSubGroups = group.subGroups.filter(function (subGroup) {
40
+ return !(groupsToSkip != null && groupsToSkip.includes(subGroup.id));
41
+ });
42
+
43
+ switch (filteredSubGroups.length) {
44
+ case 0:
45
+ return undefined;
46
+
47
+ case 1:
48
+ return _objectSpread({}, filteredSubGroups[0], {
49
+ icon: undefined
50
+ });
51
+
52
+ default:
53
+ return _objectSpread({}, group, {
54
+ subGroups: filteredSubGroups
55
+ });
56
+ }
57
+ }
58
+
59
+ return groupsToSkip != null && groupsToSkip.includes(group.id) ? undefined : group;
60
+ }).filter(itemIsParameterGroup);
61
+ return cleanGroups;
62
+ }, [groups, items, renderEmptyGroups]);
63
+ var tabs = useMemo(function () {
64
+ return (visibleGroups == null ? void 0 : visibleGroups.map(function (group) {
65
+ return {
66
+ label: group.name,
67
+ icon: group.icon
68
+ };
69
+ })) || [];
70
+ }, [visibleGroups]);
71
+ return {
72
+ visibleGroups: visibleGroups,
73
+ tabs: tabs,
74
+ defaultTab: defaultTab
75
+ };
76
+ };
package/dist/Factors.d.ts CHANGED
@@ -14,12 +14,12 @@ export declare const factorTypes: {
14
14
  parameter: {
15
15
  icon: React.JSX.Element;
16
16
  name: string;
17
- input: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, getMenuEntryProps, }: import("./Factors.types").InputProps) => React.JSX.Element;
17
+ input: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, loading, getMenuEntryProps, }: import("./Factors.types").InputProps) => React.JSX.Element;
18
18
  };
19
19
  contextParameter: {
20
20
  icon: React.JSX.Element;
21
21
  name: string;
22
- input: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, getMenuEntryProps, }: import("./Factors.types").InputProps) => React.JSX.Element;
22
+ input: ({ value, onChange, onParamsClick, parameters, texts, opened, preventAutoloadData, getPopupContainerOverride, onActivate, onDeactivate, readOnly, error, loading, getMenuEntryProps, }: import("./Factors.types").InputProps) => React.JSX.Element;
23
23
  };
24
24
  dynamicKey: {
25
25
  icon: React.JSX.Element;
package/dist/Factors.js CHANGED
@@ -371,6 +371,10 @@ var Factors = function Factors(_ref) {
371
371
  loadingParameter: formatMessage({
372
372
  id: 'DS.FACTORS.PARAMETER.LOADING_PARAMETERS',
373
373
  defaultMessage: 'Loading parameters'
374
+ }),
375
+ showMore: formatMessage({
376
+ id: 'DS.FACTORS.PARAMETER.SHOW_MORE',
377
+ defaultMessage: 'Show more'
374
378
  })
375
379
  },
376
380
  valuePlaceholder: formatMessage({
@@ -30,6 +30,7 @@ export type ParameterGroup = {
30
30
  name: string;
31
31
  defaultGroup?: boolean;
32
32
  icon?: ReactNode;
33
+ allowEmpty?: boolean;
33
34
  subGroups?: ParameterGroup[];
34
35
  };
35
36
  export type ParameterItem = {
@@ -65,6 +66,7 @@ export type FactorsTexts = {
65
66
  searchPlaceholder: string;
66
67
  noResults: string;
67
68
  loadingParameter: string;
69
+ showMore: string;
68
70
  };
69
71
  valuePlaceholder: string;
70
72
  modalApply: string;
@@ -100,7 +102,13 @@ export type FactorsProps = {
100
102
  selectedButtonColored?: boolean;
101
103
  groups?: ParameterGroup[];
102
104
  items: ParameterItem[];
105
+ renderEmptyGroups?: boolean;
103
106
  showAllGroup?: boolean;
107
+ dropdownDimensionsConfig?: {
108
+ defaultHeight?: number;
109
+ lowerHeight?: number;
110
+ threshold?: number;
111
+ };
104
112
  };
105
113
  onParamsClick?: () => void;
106
114
  formulaEditor?: ReactNode;
@@ -145,10 +153,14 @@ export type ParameterDropdownProps = {
145
153
  setSelected: (val: ParameterItem) => void;
146
154
  groups?: ParameterGroup[];
147
155
  items?: ParameterItem[];
156
+ value?: ParameterValueType;
148
157
  texts: FactorsTexts;
149
158
  loading?: boolean;
150
159
  onFetchData?: () => void;
151
160
  hasMoreItems?: boolean;
161
+ outerHeight?: number;
162
+ renderEmptyGroups?: boolean;
163
+ maxSearchResultsInGroup?: number;
152
164
  };
153
165
  export type FormulaModalProps = {
154
166
  value: FormulaValueType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-factors",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Factors UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -33,26 +33,26 @@
33
33
  ],
34
34
  "types": "dist/index.d.ts",
35
35
  "dependencies": {
36
- "@synerise/ds-autocomplete": "^0.8.16",
37
- "@synerise/ds-badge": "^0.8.7",
38
- "@synerise/ds-button": "^0.21.8",
39
- "@synerise/ds-date-picker": "^0.11.14",
40
- "@synerise/ds-date-range-picker": "^0.29.9",
41
- "@synerise/ds-dropdown": "^0.18.12",
42
- "@synerise/ds-icon": "^0.65.3",
43
- "@synerise/ds-information-card": "^0.5.6",
44
- "@synerise/ds-inline-edit": "^0.8.8",
45
- "@synerise/ds-input": "^0.24.2",
46
- "@synerise/ds-input-number": "^0.10.3",
47
- "@synerise/ds-list-item": "^0.4.8",
48
- "@synerise/ds-menu": "^0.19.12",
49
- "@synerise/ds-modal": "^0.17.39",
50
- "@synerise/ds-result": "^0.7.2",
51
- "@synerise/ds-scrollbar": "^0.11.8",
52
- "@synerise/ds-skeleton": "^0.6.6",
53
- "@synerise/ds-tabs": "^0.15.5",
54
- "@synerise/ds-tooltip": "^0.14.38",
55
- "@synerise/ds-utils": "^0.29.0",
36
+ "@synerise/ds-autocomplete": "^0.8.17",
37
+ "@synerise/ds-badge": "^0.8.8",
38
+ "@synerise/ds-button": "^0.21.9",
39
+ "@synerise/ds-date-picker": "^0.11.15",
40
+ "@synerise/ds-date-range-picker": "^0.29.10",
41
+ "@synerise/ds-dropdown": "^0.18.13",
42
+ "@synerise/ds-icon": "^0.65.4",
43
+ "@synerise/ds-information-card": "^0.5.7",
44
+ "@synerise/ds-inline-edit": "^0.8.9",
45
+ "@synerise/ds-input": "^0.24.3",
46
+ "@synerise/ds-input-number": "^0.10.4",
47
+ "@synerise/ds-list-item": "^0.4.9",
48
+ "@synerise/ds-menu": "^0.19.13",
49
+ "@synerise/ds-modal": "^0.17.40",
50
+ "@synerise/ds-result": "^0.7.3",
51
+ "@synerise/ds-scrollbar": "^0.11.9",
52
+ "@synerise/ds-skeleton": "^0.6.7",
53
+ "@synerise/ds-tabs": "^0.15.6",
54
+ "@synerise/ds-tooltip": "^0.14.39",
55
+ "@synerise/ds-utils": "^0.29.1",
56
56
  "lodash": "^4.17.19",
57
57
  "react-intl": "3.12.0",
58
58
  "react-window": "1.8.5",
@@ -64,5 +64,5 @@
64
64
  "react": ">=16.9.0 <= 17.0.2",
65
65
  "styled-components": "5.0.1"
66
66
  },
67
- "gitHead": "6fe94d574f25c5267c7593dec9399527f441b23a"
67
+ "gitHead": "fcf3fa64e906cf9fefb37a61ee28218c8eed9b73"
68
68
  }