@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.
- package/__tests__/collection.test.tsx +144 -5
- package/__tests__/containers/paging.test.tsx +106 -0
- package/__tests__/hooks/useLatestZIndex.test.tsx +10 -0
- package/__tests__/hooks/useReqorePaging.test.tsx +255 -0
- package/__tests__/hooks/useTheme.test.tsx +31 -0
- package/__tests__/pagination.test.tsx +305 -0
- package/__tests__/popover.test.tsx +20 -6
- package/__tests__/setup.js +8 -0
- package/__tests__/tree.test.tsx +0 -1
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +11 -7
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Collection/index.d.ts +4 -3
- package/dist/components/Collection/index.d.ts.map +1 -1
- package/dist/components/Collection/index.js +31 -13
- package/dist/components/Collection/index.js.map +1 -1
- package/dist/components/Dropdown/index.d.ts +9 -2
- package/dist/components/Dropdown/index.d.ts.map +1 -1
- package/dist/components/Dropdown/index.js +2 -2
- package/dist/components/Dropdown/index.js.map +1 -1
- package/dist/components/Dropdown/list.d.ts +6 -1
- package/dist/components/Dropdown/list.d.ts.map +1 -1
- package/dist/components/Dropdown/list.js +13 -5
- package/dist/components/Dropdown/list.js.map +1 -1
- package/dist/components/Menu/index.d.ts +1 -0
- package/dist/components/Menu/index.d.ts.map +1 -1
- package/dist/components/Menu/index.js +4 -1
- package/dist/components/Menu/index.js.map +1 -1
- package/dist/components/Menu/item.d.ts +1 -0
- package/dist/components/Menu/item.d.ts.map +1 -1
- package/dist/components/Menu/item.js +14 -2
- package/dist/components/Menu/item.js.map +1 -1
- package/dist/components/MultiSelect/index.d.ts +1 -1
- package/dist/components/MultiSelect/index.d.ts.map +1 -1
- package/dist/components/Paging/index.d.ts +32 -0
- package/dist/components/Paging/index.d.ts.map +1 -0
- package/dist/components/Paging/index.js +127 -0
- package/dist/components/Paging/index.js.map +1 -0
- package/dist/components/Panel/index.d.ts +1 -0
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +2 -2
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/components/Tag/index.d.ts +3 -2
- package/dist/components/Tag/index.d.ts.map +1 -1
- package/dist/components/Tag/index.js +10 -7
- package/dist/components/Tag/index.js.map +1 -1
- package/dist/constants/colors.d.ts +2 -9
- package/dist/constants/colors.d.ts.map +1 -1
- package/dist/constants/colors.js +3 -1
- package/dist/constants/colors.js.map +1 -1
- package/dist/constants/paging.d.ts +17 -0
- package/dist/constants/paging.d.ts.map +1 -0
- package/dist/constants/paging.js +45 -0
- package/dist/constants/paging.js.map +1 -0
- package/dist/constants/theme.d.ts.map +1 -1
- package/dist/constants/theme.js +8 -7
- package/dist/constants/theme.js.map +1 -1
- package/dist/containers/Paging.d.ts +15 -0
- package/dist/containers/Paging.d.ts.map +1 -0
- package/dist/containers/Paging.js +51 -0
- package/dist/containers/Paging.js.map +1 -0
- package/dist/containers/ReqoreProvider.d.ts.map +1 -1
- package/dist/containers/ReqoreProvider.js +2 -2
- package/dist/containers/ReqoreProvider.js.map +1 -1
- package/dist/containers/UIProvider.d.ts.map +1 -1
- package/dist/containers/UIProvider.js +9 -3
- package/dist/containers/UIProvider.js.map +1 -1
- package/dist/hooks/useCombinedRefs.d.ts +2 -2
- package/dist/hooks/useCombinedRefs.d.ts.map +1 -1
- package/dist/hooks/useCombinedRefs.js.map +1 -1
- package/dist/hooks/usePaging.d.ts +28 -0
- package/dist/hooks/usePaging.d.ts.map +1 -0
- package/dist/hooks/usePaging.js +85 -0
- package/dist/hooks/usePaging.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/src/components/Button/index.tsx +18 -10
- package/src/components/Collection/index.tsx +78 -49
- package/src/components/ControlGroup/index.tsx +1 -1
- package/src/components/Dropdown/index.tsx +27 -12
- package/src/components/Dropdown/list.tsx +49 -24
- package/src/components/Menu/index.tsx +3 -2
- package/src/components/Menu/item.tsx +16 -2
- package/src/components/MultiSelect/index.tsx +1 -1
- package/src/components/Paging/index.tsx +260 -0
- package/src/components/Panel/index.tsx +4 -1
- package/src/components/Tag/index.tsx +9 -7
- package/src/constants/colors.ts +5 -1
- package/src/constants/paging.ts +67 -0
- package/src/constants/theme.ts +8 -7
- package/src/containers/Paging.tsx +90 -0
- package/src/containers/ReqoreProvider.tsx +3 -3
- package/src/containers/UIProvider.tsx +17 -4
- package/src/hooks/useCombinedRefs.ts +2 -2
- package/src/hooks/usePaging.ts +114 -0
- package/src/index.tsx +3 -0
- package/src/mock/collectionData.tsx +19 -0
- package/src/mock/tableData.ts +1 -0
- package/src/stories/Button/Button.stories.tsx +25 -8
- package/src/stories/Collection/Collection.stories.tsx +51 -42
- package/src/stories/Dropdown/Dropdown.stories.tsx +71 -29
- package/src/stories/Menu/Menu.stories.tsx +4 -0
- package/src/stories/Paging/Paging.stories.tsx +202 -0
- package/src/stories/Tag/Tag.stories.tsx +50 -0
- 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 {
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
214
|
-
onClearClick: () =>
|
|
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,
|
|
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
|
-
{
|
|
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
|
};
|
|
@@ -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
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
|
101
|
-
(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
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['
|
|
31
|
+
openOnMount?: IReqoreDropdownProps['isDefaultOpen'];
|
|
32
32
|
enterKeySelects?: boolean;
|
|
33
33
|
}
|
|
34
34
|
|