@qoretechnologies/reqore 0.32.3 → 0.34.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 (109) hide show
  1. package/__tests__/collection.test.tsx +144 -5
  2. package/__tests__/containers/paging.test.tsx +106 -0
  3. package/__tests__/hooks/useLatestZIndex.test.tsx +10 -0
  4. package/__tests__/hooks/useReqorePaging.test.tsx +255 -0
  5. package/__tests__/hooks/useTheme.test.tsx +31 -0
  6. package/__tests__/pagination.test.tsx +305 -0
  7. package/__tests__/popover.test.tsx +20 -6
  8. package/__tests__/setup.js +8 -0
  9. package/__tests__/tree.test.tsx +0 -1
  10. package/dist/components/Button/index.d.ts +1 -0
  11. package/dist/components/Button/index.d.ts.map +1 -1
  12. package/dist/components/Button/index.js +11 -7
  13. package/dist/components/Button/index.js.map +1 -1
  14. package/dist/components/Collection/index.d.ts +4 -3
  15. package/dist/components/Collection/index.d.ts.map +1 -1
  16. package/dist/components/Collection/index.js +31 -13
  17. package/dist/components/Collection/index.js.map +1 -1
  18. package/dist/components/Dropdown/index.d.ts +9 -2
  19. package/dist/components/Dropdown/index.d.ts.map +1 -1
  20. package/dist/components/Dropdown/index.js +2 -2
  21. package/dist/components/Dropdown/index.js.map +1 -1
  22. package/dist/components/Dropdown/list.d.ts +6 -1
  23. package/dist/components/Dropdown/list.d.ts.map +1 -1
  24. package/dist/components/Dropdown/list.js +13 -5
  25. package/dist/components/Dropdown/list.js.map +1 -1
  26. package/dist/components/Menu/index.d.ts +1 -0
  27. package/dist/components/Menu/index.d.ts.map +1 -1
  28. package/dist/components/Menu/index.js +4 -1
  29. package/dist/components/Menu/index.js.map +1 -1
  30. package/dist/components/Menu/item.d.ts +1 -0
  31. package/dist/components/Menu/item.d.ts.map +1 -1
  32. package/dist/components/Menu/item.js +14 -2
  33. package/dist/components/Menu/item.js.map +1 -1
  34. package/dist/components/MultiSelect/index.d.ts +1 -1
  35. package/dist/components/MultiSelect/index.d.ts.map +1 -1
  36. package/dist/components/Paging/index.d.ts +32 -0
  37. package/dist/components/Paging/index.d.ts.map +1 -0
  38. package/dist/components/Paging/index.js +127 -0
  39. package/dist/components/Paging/index.js.map +1 -0
  40. package/dist/components/Panel/index.d.ts +1 -0
  41. package/dist/components/Panel/index.d.ts.map +1 -1
  42. package/dist/components/Panel/index.js +2 -2
  43. package/dist/components/Panel/index.js.map +1 -1
  44. package/dist/components/Tag/index.d.ts +3 -2
  45. package/dist/components/Tag/index.d.ts.map +1 -1
  46. package/dist/components/Tag/index.js +10 -7
  47. package/dist/components/Tag/index.js.map +1 -1
  48. package/dist/constants/colors.d.ts +2 -9
  49. package/dist/constants/colors.d.ts.map +1 -1
  50. package/dist/constants/colors.js +3 -1
  51. package/dist/constants/colors.js.map +1 -1
  52. package/dist/constants/paging.d.ts +17 -0
  53. package/dist/constants/paging.d.ts.map +1 -0
  54. package/dist/constants/paging.js +45 -0
  55. package/dist/constants/paging.js.map +1 -0
  56. package/dist/constants/theme.d.ts.map +1 -1
  57. package/dist/constants/theme.js +8 -7
  58. package/dist/constants/theme.js.map +1 -1
  59. package/dist/containers/Paging.d.ts +15 -0
  60. package/dist/containers/Paging.d.ts.map +1 -0
  61. package/dist/containers/Paging.js +51 -0
  62. package/dist/containers/Paging.js.map +1 -0
  63. package/dist/containers/ReqoreProvider.d.ts.map +1 -1
  64. package/dist/containers/ReqoreProvider.js +2 -2
  65. package/dist/containers/ReqoreProvider.js.map +1 -1
  66. package/dist/containers/UIProvider.d.ts.map +1 -1
  67. package/dist/containers/UIProvider.js +9 -3
  68. package/dist/containers/UIProvider.js.map +1 -1
  69. package/dist/hooks/useCombinedRefs.d.ts +2 -2
  70. package/dist/hooks/useCombinedRefs.d.ts.map +1 -1
  71. package/dist/hooks/useCombinedRefs.js.map +1 -1
  72. package/dist/hooks/usePaging.d.ts +28 -0
  73. package/dist/hooks/usePaging.d.ts.map +1 -0
  74. package/dist/hooks/usePaging.js +85 -0
  75. package/dist/hooks/usePaging.js.map +1 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +8 -2
  79. package/dist/index.js.map +1 -1
  80. package/package.json +6 -4
  81. package/src/components/Button/index.tsx +18 -10
  82. package/src/components/Collection/index.tsx +78 -49
  83. package/src/components/ControlGroup/index.tsx +1 -1
  84. package/src/components/Dropdown/index.tsx +27 -12
  85. package/src/components/Dropdown/list.tsx +49 -24
  86. package/src/components/Menu/index.tsx +3 -2
  87. package/src/components/Menu/item.tsx +16 -2
  88. package/src/components/MultiSelect/index.tsx +1 -1
  89. package/src/components/Paging/index.tsx +260 -0
  90. package/src/components/Panel/index.tsx +4 -1
  91. package/src/components/Tag/index.tsx +9 -7
  92. package/src/constants/colors.ts +5 -1
  93. package/src/constants/paging.ts +67 -0
  94. package/src/constants/theme.ts +8 -7
  95. package/src/containers/Paging.tsx +90 -0
  96. package/src/containers/ReqoreProvider.tsx +3 -3
  97. package/src/containers/UIProvider.tsx +17 -4
  98. package/src/hooks/useCombinedRefs.ts +2 -2
  99. package/src/hooks/usePaging.ts +114 -0
  100. package/src/index.tsx +3 -0
  101. package/src/mock/collectionData.tsx +19 -0
  102. package/src/mock/tableData.ts +1 -0
  103. package/src/stories/Button/Button.stories.tsx +25 -8
  104. package/src/stories/Collection/Collection.stories.tsx +51 -42
  105. package/src/stories/Dropdown/Dropdown.stories.tsx +71 -29
  106. package/src/stories/Menu/Menu.stories.tsx +4 -0
  107. package/src/stories/Paging/Paging.stories.tsx +202 -0
  108. package/src/stories/Tag/Tag.stories.tsx +50 -0
  109. package/tests.json +1 -1
@@ -1,14 +1,14 @@
1
1
  import { size } from 'lodash';
2
- import { useMemo, useState } from 'react';
2
+ import { useCallback, useMemo, useState } from 'react';
3
3
  import { useDebounce, useUpdateEffect } from 'react-use';
4
4
  import styled, { css } from 'styled-components';
5
- import { PADDING_FROM_SIZE } from '../../constants/sizes';
5
+ import { TReqorePaginationType } from '../../constants/paging';
6
+ import { ReqorePaginationContainer } from '../../containers/Paging';
6
7
  import { IReqoreIconName } from '../../types/icons';
7
8
  import { IReqoreColumnsProps, StyledColumns } from '../Columns';
8
9
  import ReqoreInput, { IReqoreInputProps } from '../Input';
9
10
  import ReqoreMessage from '../Message';
10
11
  import { IReqorePanelAction, IReqorePanelProps, ReqorePanel, TReqorePanelActions } from '../Panel';
11
- import { ReqoreVerticalSpacer } from '../Spacer';
12
12
  import { sortTableData } from '../Table/helpers';
13
13
  import { IReqoreCollectionItemProps, ReqoreCollectionItem } from './item';
14
14
 
@@ -48,8 +48,10 @@ export interface IReqoreCollectionProps
48
48
  selectedIcon?: IReqoreIconName;
49
49
  searchDelay?: number;
50
50
 
51
- childrenBefore?: React.ReactNode;
52
- childrenAfter?: React.ReactNode;
51
+ contentRenderer?: (
52
+ children: React.ReactNode,
53
+ items: IReqoreCollectionItemProps[]
54
+ ) => React.ReactNode;
53
55
 
54
56
  onQueryChange?: (query: string) => void;
55
57
 
@@ -57,6 +59,8 @@ export interface IReqoreCollectionProps
57
59
  sortButtonTooltip?: (sort?: 'asc' | 'desc') => string;
58
60
  displayButtonTooltip?: (display?: 'list' | 'grid') => string;
59
61
  inputPlaceholder?: (items?: IReqoreCollectionItemProps[]) => string;
62
+
63
+ paging?: TReqorePaginationType<IReqoreCollectionItemProps>;
60
64
  }
61
65
 
62
66
  export const StyledCollectionWrapper = styled(StyledColumns)`
@@ -92,19 +96,20 @@ export const ReqoreCollection = ({
92
96
  minimal,
93
97
  transparent = true,
94
98
  onQueryChange,
95
- childrenBefore,
96
- childrenAfter,
99
+ contentRenderer = (children) => children,
97
100
  searchDelay = 300,
98
101
  emptyMessage = 'No data in this collection, try changing your search query or filters',
99
102
  sortButtonTooltip = (sort) => (sort === 'desc' ? 'Sort ascending' : 'Sort descending'),
100
103
  displayButtonTooltip = (display) => (display === 'grid' ? 'Show as list' : 'Show as grid'),
101
104
  inputPlaceholder = (items) => `Search in ${size(items)} items`,
105
+ paging,
102
106
  ...rest
103
107
  }: IReqoreCollectionProps) => {
104
108
  const [_showAs, setShowAs] = useState<'list' | 'grid'>(showAs);
105
109
  const [sort, setSort] = useState<'asc' | 'desc'>('asc');
106
110
  const [query, setQuery] = useState<string>('');
107
111
  const [preQuery, setPreQuery] = useState<string>('');
112
+ const [contentRef, setContentRef] = useState<HTMLDivElement>(undefined);
108
113
 
109
114
  useUpdateEffect(() => {
110
115
  setShowAs(showAs);
@@ -152,7 +157,7 @@ export const ReqoreCollection = ({
152
157
  });
153
158
  }, [items, sort]);
154
159
 
155
- const finalItems: IReqoreCollectionItemProps[] = useMemo(() => {
160
+ const filteredItems: IReqoreCollectionItemProps[] = useMemo(() => {
156
161
  if (!filterable || query === '') {
157
162
  return sortedItems;
158
163
  }
@@ -184,7 +189,7 @@ export const ReqoreCollection = ({
184
189
  icon: _showAs === 'grid' ? 'ListUnordered' : 'GridLine',
185
190
  onClick: () => setShowAs(_showAs === 'grid' ? 'list' : 'grid'),
186
191
  tooltip: displayButtonTooltip(_showAs),
187
- disabled: !size(finalItems),
192
+ disabled: !size(filteredItems),
188
193
  textAlign: 'center',
189
194
  ...displayButtonProps,
190
195
  },
@@ -196,7 +201,7 @@ export const ReqoreCollection = ({
196
201
  icon: sort === 'desc' ? 'SortDesc' : 'SortAsc',
197
202
  onClick: () => setSort(sort === 'desc' ? 'asc' : 'desc'),
198
203
  tooltip: sortButtonTooltip(sort),
199
- disabled: !size(finalItems),
204
+ disabled: !size(filteredItems),
200
205
  textAlign: 'center',
201
206
  ...sortButtonProps,
202
207
  });
@@ -210,8 +215,11 @@ export const ReqoreCollection = ({
210
215
  props: {
211
216
  key: 'search',
212
217
  fixed: false,
213
- placeholder: inputPlaceholder(finalItems),
214
- onClearClick: () => setQuery(''),
218
+ placeholder: inputPlaceholder(items),
219
+ onClearClick: () => {
220
+ setQuery('');
221
+ setPreQuery('');
222
+ },
215
223
  onChange: handlePreQueryChange,
216
224
  value: preQuery,
217
225
  icon: 'Search2Line',
@@ -223,7 +231,63 @@ export const ReqoreCollection = ({
223
231
  }
224
232
 
225
233
  return [...actions, toolbarGroup];
226
- }, [filterable, preQuery, query, rest.actions, _showAs, sort, sortable, finalItems]);
234
+ }, [filterable, preQuery, query, rest.actions, _showAs, sort, sortable, filteredItems]);
235
+
236
+ const renderContent = useCallback(() => {
237
+ return contentRenderer(
238
+ <>
239
+ <ReqorePaginationContainer
240
+ items={filteredItems}
241
+ type={paging}
242
+ size={rest.size}
243
+ scrollContainer={contentRef}
244
+ >
245
+ {(finalItems) => (
246
+ <>
247
+ {!size(finalItems) ? (
248
+ <ReqoreMessage flat icon='Search2Line'>
249
+ {emptyMessage}
250
+ </ReqoreMessage>
251
+ ) : (
252
+ <StyledCollectionWrapper
253
+ columns={_showAs === 'grid' ? 'auto-fit' : 1}
254
+ columnsGap={stacked ? '0px' : columnsGap}
255
+ rounded={rounded}
256
+ stacked={stacked}
257
+ ref={setContentRef}
258
+ {...rest}
259
+ >
260
+ {finalItems?.map((item, index) => (
261
+ <ReqoreCollectionItem
262
+ size={rest.size}
263
+ {...item}
264
+ icon={item.icon || (item.selected ? selectedIcon : undefined)}
265
+ key={index}
266
+ rounded={!stacked}
267
+ maxContentHeight={maxItemHeight}
268
+ />
269
+ ))}
270
+ </StyledCollectionWrapper>
271
+ )}
272
+ </>
273
+ )}
274
+ </ReqorePaginationContainer>
275
+ </>,
276
+ filteredItems
277
+ );
278
+ }, [
279
+ contentRenderer,
280
+ filteredItems,
281
+ _showAs,
282
+ columnsGap,
283
+ emptyMessage,
284
+ maxItemHeight,
285
+ rest,
286
+ rounded,
287
+ selectedIcon,
288
+ size,
289
+ stacked,
290
+ ]);
227
291
 
228
292
  return (
229
293
  <ReqorePanel
@@ -239,42 +303,7 @@ export const ReqoreCollection = ({
239
303
  actions={finalActions}
240
304
  className={`reqore-collection ${rest.className || ''}`}
241
305
  >
242
- {childrenBefore ? (
243
- <>
244
- {childrenBefore}
245
- <ReqoreVerticalSpacer height={PADDING_FROM_SIZE[rest.size || 'normal']} />
246
- </>
247
- ) : null}
248
- {!size(finalItems) ? (
249
- <ReqoreMessage flat icon='Search2Line'>
250
- {emptyMessage}
251
- </ReqoreMessage>
252
- ) : (
253
- <StyledCollectionWrapper
254
- columns={_showAs === 'grid' ? 'auto-fit' : 1}
255
- columnsGap={stacked ? '0px' : columnsGap}
256
- rounded={rounded}
257
- stacked={stacked}
258
- {...rest}
259
- >
260
- {finalItems?.map((item, index) => (
261
- <ReqoreCollectionItem
262
- size={rest.size}
263
- {...item}
264
- icon={item.icon || (item.selected ? selectedIcon : undefined)}
265
- key={index}
266
- rounded={!stacked}
267
- maxContentHeight={maxItemHeight}
268
- />
269
- ))}
270
- </StyledCollectionWrapper>
271
- )}
272
- {childrenAfter ? (
273
- <>
274
- <ReqoreVerticalSpacer height={PADDING_FROM_SIZE[rest.size || 'normal']} />
275
- {childrenAfter}
276
- </>
277
- ) : null}
306
+ {renderContent()}
278
307
  </ReqorePanel>
279
308
  );
280
309
  };
@@ -11,7 +11,7 @@ import {
11
11
  IWithReqoreFlat,
12
12
  IWithReqoreFluid,
13
13
  IWithReqoreMinimal,
14
- IWithReqoreSize,
14
+ IWithReqoreSize
15
15
  } from '../../types/global';
16
16
  import { StyledHeader } from '../Header';
17
17
  import { StyledParagraph } from '../Paragraph';
@@ -1,12 +1,15 @@
1
1
  import { size } from 'lodash';
2
2
  import React, { memo, useMemo } from 'react';
3
- import { ReqorePopover } from '../..';
3
+ import { ReqorePanel, ReqorePopover } from '../..';
4
+ import { TReqorePaginationType } from '../../constants/paging';
4
5
  import { IPopoverOptions } from '../../hooks/usePopover';
5
6
  import { IReqoreIconName } from '../../types/icons';
6
7
  import ReqoreButton, { IReqoreButtonProps } from '../Button';
8
+ import { IReqoreInputProps } from '../Input';
9
+ import { IReqorePanelProps } from '../Panel';
7
10
  import ReqoreDropdownList, { IReqoreDropdownItem, TDropdownItemOnClick } from './list';
8
11
 
9
- export interface IReqoreDropdownProps extends Partial<IPopoverOptions> {
12
+ export interface IReqoreDropdownProps extends Partial<Omit<IPopoverOptions, 'openOnMount'>> {
10
13
  items?: IReqoreDropdownItem[];
11
14
  multiSelect?: boolean;
12
15
  buttonStyle?: React.CSSProperties;
@@ -23,6 +26,10 @@ export interface IReqoreDropdownProps extends Partial<IPopoverOptions> {
23
26
  isDefaultOpen?: boolean;
24
27
  onItemSelect?: TDropdownItemOnClick;
25
28
  style?: React.CSSProperties;
29
+ inputProps?: IReqoreInputProps;
30
+ wrapperProps?: IReqorePanelProps;
31
+ scrollToSelected?: boolean;
32
+ paging?: TReqorePaginationType<IReqoreDropdownItem>;
26
33
  }
27
34
 
28
35
  function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
@@ -50,13 +57,16 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
50
57
  maxWidth,
51
58
  noArrow = true,
52
59
  transparent,
53
- openOnMount,
54
60
  show,
55
61
  targetElement,
56
62
  useTargetWidth,
57
63
  listWidth,
58
64
  listHeight,
59
65
  passPopoverData,
66
+ inputProps,
67
+ scrollToSelected,
68
+ wrapperProps,
69
+ paging,
60
70
  ...rest
61
71
  }: IReqoreDropdownProps & T) {
62
72
  const componentProps = useMemo(
@@ -74,15 +84,20 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
74
84
 
75
85
  const popoverContent = useMemo(() => {
76
86
  return size(items) ? (
77
- <ReqoreDropdownList
78
- multiSelect={multiSelect}
79
- listStyle={listStyle}
80
- width={useTargetWidth ? '100%' : listWidth}
81
- height={listHeight}
82
- items={items}
83
- filterable={filterable}
84
- onItemSelect={onItemSelect}
85
- />
87
+ <ReqorePanel flat size='small' {...wrapperProps}>
88
+ <ReqoreDropdownList
89
+ multiSelect={multiSelect}
90
+ listStyle={listStyle}
91
+ width={useTargetWidth ? '100%' : listWidth}
92
+ height={listHeight}
93
+ items={items}
94
+ filterable={filterable}
95
+ onItemSelect={onItemSelect}
96
+ inputProps={inputProps}
97
+ scrollToSelected={scrollToSelected}
98
+ paging={paging}
99
+ />
100
+ </ReqorePanel>
86
101
  ) : undefined;
87
102
  }, [items]);
88
103
 
@@ -1,9 +1,14 @@
1
+ import { size } from 'lodash';
1
2
  import React, { memo, useEffect, useMemo, useState } from 'react';
3
+ import { TReqorePaginationType } from '../../constants/paging';
4
+ import { PADDING_FROM_SIZE } from '../../constants/sizes';
5
+ import { ReqorePaginationContainer } from '../../containers/Paging';
2
6
  import { IReqoreComponent } from '../../types/global';
3
- import ReqoreInput from '../Input';
7
+ import ReqoreInput, { IReqoreInputProps } from '../Input';
4
8
  import ReqoreMenu from '../Menu';
5
9
  import ReqoreMenuDivider from '../Menu/divider';
6
10
  import ReqoreMenuItem, { IReqoreMenuItemProps } from '../Menu/item';
11
+ import { ReqoreVerticalSpacer } from '../Spacer';
7
12
 
8
13
  export type TDropdownItemOnClick = (item: IReqoreDropdownItem) => void;
9
14
  export interface IReqoreDropdownItem
@@ -25,6 +30,9 @@ export interface IReqoreDropdownListProps extends IReqoreComponent {
25
30
  height?: string;
26
31
  filterable?: boolean;
27
32
  onItemSelect?: TDropdownItemOnClick;
33
+ inputProps?: IReqoreInputProps;
34
+ scrollToSelected?: boolean;
35
+ paging?: TReqorePaginationType<TReqoreDropdownItem>;
28
36
  }
29
37
 
30
38
  const ReqoreDropdownList = memo(
@@ -37,9 +45,13 @@ const ReqoreDropdownList = memo(
37
45
  width,
38
46
  height,
39
47
  onItemSelect,
48
+ inputProps,
49
+ scrollToSelected,
50
+ paging,
40
51
  }: IReqoreDropdownListProps) => {
41
52
  const [_items, setItems] = useState<TReqoreDropdownItems>(items);
42
53
  const [query, setQuery] = useState<string>('');
54
+ const [menuRef, setMenuRef] = useState<HTMLDivElement>(undefined);
43
55
 
44
56
  useEffect(() => {
45
57
  setItems(items);
@@ -80,38 +92,51 @@ const ReqoreDropdownList = memo(
80
92
  };
81
93
 
82
94
  return (
83
- <ReqoreMenu
84
- _insidePopover={!multiSelect}
85
- _popoverId={_popoverId}
86
- style={listStyle}
87
- width={width}
88
- maxHeight={height || '300px'}
89
- >
95
+ <>
90
96
  {filterable && (
91
97
  <>
92
98
  <ReqoreInput
93
99
  value={query}
100
+ icon='SearchLine'
94
101
  onChange={handleQueryChange}
95
- placeholder='Filter'
102
+ placeholder={`Search ${size(_items)} items...`}
96
103
  onClearClick={() => setQuery('')}
104
+ {...inputProps}
97
105
  />
106
+ <ReqoreVerticalSpacer height={PADDING_FROM_SIZE.normal} />
98
107
  </>
99
108
  )}
100
- {filteredItems.map(
101
- ({ onClick, dividerAlign, divider, ...item }: IReqoreDropdownItem, index: number) =>
102
- divider ? (
103
- <ReqoreMenuDivider key={index} {...item} align={dividerAlign} />
104
- ) : (
105
- <ReqoreMenuItem
106
- key={index}
107
- {...item}
108
- label={item.label || item.value}
109
- onClick={() => handleItemClick({ ...item, onClick })}
110
- rightIcon={item.selected ? 'CheckLine' : undefined}
111
- />
112
- )
113
- )}
114
- </ReqoreMenu>
109
+ <ReqorePaginationContainer type={paging} items={filteredItems} scrollContainer={menuRef}>
110
+ {(finalItems, Controls, { includeBottomControls }) => (
111
+ <ReqoreMenu
112
+ _insidePopover={!multiSelect}
113
+ _popoverId={_popoverId}
114
+ style={listStyle}
115
+ width={width}
116
+ maxHeight={height || '300px'}
117
+ padded={false}
118
+ ref={setMenuRef}
119
+ >
120
+ {finalItems.map(
121
+ ({ onClick, dividerAlign, divider, ...item }: IReqoreDropdownItem, index: number) =>
122
+ divider ? (
123
+ <ReqoreMenuDivider key={index} {...item} align={dividerAlign} />
124
+ ) : (
125
+ <ReqoreMenuItem
126
+ key={index}
127
+ {...item}
128
+ label={item.label || item.value}
129
+ onClick={() => handleItemClick({ ...item, onClick })}
130
+ rightIcon={item.selected ? 'CheckLine' : undefined}
131
+ scrollIntoView={scrollToSelected && item.selected && !multiSelect}
132
+ />
133
+ )
134
+ )}
135
+ {!includeBottomControls && <Controls />}
136
+ </ReqoreMenu>
137
+ )}
138
+ </ReqorePaginationContainer>
139
+ </>
115
140
  );
116
141
  }
117
142
  );
@@ -21,6 +21,7 @@ export interface IReqoreMenuProps
21
21
  wrapText?: boolean;
22
22
  flat?: boolean;
23
23
  rounded?: boolean;
24
+ padded?: boolean;
24
25
  }
25
26
 
26
27
  export interface IReqoreMenuStyle extends IReqoreMenuProps {
@@ -30,7 +31,7 @@ export interface IReqoreMenuStyle extends IReqoreMenuProps {
30
31
  const StyledReqoreMenu = styled.div<IReqoreMenuStyle>`
31
32
  width: ${({ width }) => width || undefined};
32
33
  min-width: ${({ width }) => (width ? undefined : '160px')};
33
- padding: 5px;
34
+ padding: ${({ padded = true }) => (padded ? '5px' : undefined)};
34
35
  max-height: ${({ maxHeight }) => maxHeight || undefined};
35
36
  overflow-y: auto;
36
37
  overflow-x: hidden;
@@ -68,7 +69,7 @@ const ReqoreMenu = forwardRef<HTMLDivElement, IReqoreMenuProps>(
68
69
  minimal,
69
70
  ...rest
70
71
  }: IReqoreMenuProps,
71
- ref: any
72
+ ref
72
73
  ) => {
73
74
  const theme = useReqoreTheme('main', customTheme, intent);
74
75
 
@@ -1,8 +1,9 @@
1
- import React, { forwardRef } from 'react';
1
+ import React, { forwardRef, useEffect, useState } from 'react';
2
2
  import { useContext } from 'use-context-selector';
3
3
  import { ReqoreButton, ReqoreControlGroup } from '../..';
4
4
  import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
5
5
  import PopoverContext from '../../context/PopoverContext';
6
+ import { useCombinedRefs } from '../../hooks/useCombinedRefs';
6
7
  import { IReqoreComponent } from '../../types/global';
7
8
  import { IReqoreButtonProps } from '../Button';
8
9
 
@@ -17,6 +18,7 @@ export interface IReqoreMenuItemProps
17
18
  itemId?: string;
18
19
  onRightIconClick?: (itemId?: string, event?: React.MouseEvent<HTMLElement>) => void;
19
20
  onClick?: (itemId?: string, event?: React.MouseEvent<HTMLElement>) => void;
21
+ scrollIntoView?: boolean;
20
22
  }
21
23
 
22
24
  export interface IReqoreMenuItemStyle {
@@ -50,11 +52,14 @@ const ReqoreMenuItem = forwardRef<HTMLButtonElement, IReqoreMenuItemProps>(
50
52
  tooltip,
51
53
  intent,
52
54
  flat = true,
55
+ scrollIntoView,
53
56
  ...rest
54
57
  }: IReqoreMenuItemProps,
55
58
  ref
56
59
  ) => {
57
60
  const { removePopover } = useContext(PopoverContext);
61
+ const { targetRef } = useCombinedRefs<HTMLButtonElement>(ref);
62
+ const [itemRef, setItemRef] = useState<HTMLButtonElement>(undefined);
58
63
 
59
64
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
60
65
  event.persist();
@@ -79,6 +84,12 @@ const ReqoreMenuItem = forwardRef<HTMLButtonElement, IReqoreMenuItemProps>(
79
84
  }
80
85
  };
81
86
 
87
+ useEffect(() => {
88
+ if (scrollIntoView && itemRef) {
89
+ itemRef.scrollIntoView?.({ behavior: 'smooth', block: 'center', inline: 'center' });
90
+ }
91
+ }, [itemRef, scrollIntoView]);
92
+
82
93
  return (
83
94
  <ReqoreControlGroup stack={!!onRightIconClick} fluid>
84
95
  <ReqoreButton
@@ -90,7 +101,10 @@ const ReqoreMenuItem = forwardRef<HTMLButtonElement, IReqoreMenuItemProps>(
90
101
  fluid
91
102
  onClick={handleClick}
92
103
  active={selected}
93
- ref={ref}
104
+ ref={(ref) => {
105
+ targetRef.current = ref;
106
+ setItemRef(ref);
107
+ }}
94
108
  disabled={disabled}
95
109
  intent={intent}
96
110
  icon={icon}
@@ -28,7 +28,7 @@ export interface IReqoreMultiSelectProps
28
28
  selectedItemEffect?: IReqoreEffect;
29
29
  selectedItemSize?: TSizes;
30
30
  selectorProps?: Omit<IReqoreInputProps, 'value' | 'onValueChange'> & IReqoreDropdownProps;
31
- openOnMount?: IReqoreDropdownProps['openOnMount'];
31
+ openOnMount?: IReqoreDropdownProps['isDefaultOpen'];
32
32
  enterKeySelects?: boolean;
33
33
  }
34
34