@qoretechnologies/reqore 0.32.3 → 0.33.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 +123 -5
- package/__tests__/hooks/useLatestZIndex.test.tsx +10 -0
- package/__tests__/hooks/useReqorePaging.test.tsx +251 -0
- package/__tests__/hooks/useTheme.test.tsx +31 -0
- package/__tests__/pagination.test.tsx +301 -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 +9 -3
- package/dist/components/Collection/index.d.ts.map +1 -1
- package/dist/components/Collection/index.js +34 -8
- package/dist/components/Collection/index.js.map +1 -1
- package/dist/components/Dropdown/index.d.ts +5 -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 +4 -1
- package/dist/components/Dropdown/list.d.ts.map +1 -1
- package/dist/components/Dropdown/list.js +3 -3
- package/dist/components/Dropdown/list.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 +30 -0
- package/dist/components/Paging/index.d.ts.map +1 -0
- package/dist/components/Paging/index.js +106 -0
- package/dist/components/Paging/index.js.map +1 -0
- 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 +10 -0
- package/dist/constants/paging.d.ts.map +1 -0
- package/dist/constants/paging.js +41 -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/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 +27 -0
- package/dist/hooks/usePaging.d.ts.map +1 -0
- package/dist/hooks/usePaging.js +83 -0
- package/dist/hooks/usePaging.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -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 +96 -44
- package/src/components/ControlGroup/index.tsx +1 -1
- package/src/components/Dropdown/index.tsx +8 -2
- package/src/components/Dropdown/list.tsx +7 -1
- package/src/components/Menu/item.tsx +16 -2
- package/src/components/MultiSelect/index.tsx +1 -1
- package/src/components/Paging/index.tsx +232 -0
- package/src/components/Tag/index.tsx +9 -7
- package/src/constants/colors.ts +5 -1
- package/src/constants/paging.ts +48 -0
- package/src/constants/theme.ts +8 -7
- 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 +110 -0
- package/src/index.tsx +2 -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 +32 -42
- package/src/stories/Dropdown/Dropdown.stories.tsx +24 -1
- package/src/stories/Paging/Paging.stories.tsx +184 -0
- package/src/stories/Tag/Tag.stories.tsx +50 -0
- package/tests.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoretechnologies/reqore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "ReQore is a highly theme-able and modular UI library for React",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@storybook/react": "^6.5.13",
|
|
54
54
|
"@storybook/testing-library": "^0.0.13",
|
|
55
55
|
"@testing-library/jest-dom": "^5.16.5",
|
|
56
|
-
"@testing-library/react": "^
|
|
56
|
+
"@testing-library/react": "^13.4.0",
|
|
57
57
|
"@types/jest": "^26.0.19",
|
|
58
58
|
"@types/lodash": "^4.14.166",
|
|
59
59
|
"@types/node": "^14.14.14",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"babel-jest": "^26.6.3",
|
|
63
63
|
"babel-loader": "^8.2.2",
|
|
64
64
|
"chromatic": "^6.3.3",
|
|
65
|
-
"jest": "^
|
|
65
|
+
"jest": "^29.4.3",
|
|
66
|
+
"jest-environment-jsdom": "^29.4.3",
|
|
66
67
|
"jest-github-actions-reporter": "^1.0.2",
|
|
67
68
|
"npm-cli-login": "^0.1.1",
|
|
68
69
|
"playwright": "^1.16.3",
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
"react-test-renderer": "^18.2.0",
|
|
74
75
|
"storybook-addon-outline": "^1.4.2",
|
|
75
76
|
"storybook-dark-mode": "^1.1.2",
|
|
76
|
-
"ts-jest": "^
|
|
77
|
+
"ts-jest": "^29.0.5",
|
|
77
78
|
"ts-node": "^9.1.1",
|
|
78
79
|
"typescript": "^4.7.3",
|
|
79
80
|
"viteshot": "^0.3.1"
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
"react-popper": "^2.3.0",
|
|
95
96
|
"react-scrollbar": "^0.5.6",
|
|
96
97
|
"react-use": "^17.4.0",
|
|
98
|
+
"react-use-pagination-hook": "^1.1.2",
|
|
97
99
|
"react-window": "^1.8.6",
|
|
98
100
|
"scheduler": "^0.23.0",
|
|
99
101
|
"shortid": "^2.2.16",
|
|
@@ -69,6 +69,7 @@ export interface IReqoreButtonProps
|
|
|
69
69
|
description?: string | number;
|
|
70
70
|
maxWidth?: string;
|
|
71
71
|
textAlign?: 'left' | 'center' | 'right';
|
|
72
|
+
iconsAlign?: 'center' | 'sides';
|
|
72
73
|
iconColor?: TReqoreEffectColor;
|
|
73
74
|
leftIconColor?: TReqoreEffectColor;
|
|
74
75
|
rightIconColor?: TReqoreEffectColor;
|
|
@@ -393,6 +394,7 @@ const ReqoreButton = memo(
|
|
|
393
394
|
leftIconColor,
|
|
394
395
|
rightIconColor,
|
|
395
396
|
iconColor,
|
|
397
|
+
iconsAlign,
|
|
396
398
|
...rest
|
|
397
399
|
}: IReqoreButtonProps,
|
|
398
400
|
ref
|
|
@@ -455,17 +457,18 @@ const ReqoreButton = memo(
|
|
|
455
457
|
size={size}
|
|
456
458
|
color={leftIconColor || iconColor}
|
|
457
459
|
style={
|
|
458
|
-
textAlign !== 'left'
|
|
460
|
+
textAlign !== 'left' || iconsAlign === 'center'
|
|
459
461
|
? {
|
|
460
|
-
marginRight: 'auto',
|
|
461
|
-
marginLeft:
|
|
462
|
+
marginRight: iconsAlign !== 'center' || !children ? 'auto' : undefined,
|
|
463
|
+
marginLeft:
|
|
464
|
+
iconsAlign === 'center' || (textAlign === 'center' && !children)
|
|
465
|
+
? 'auto'
|
|
466
|
+
: undefined,
|
|
462
467
|
}
|
|
463
468
|
: undefined
|
|
464
469
|
}
|
|
465
470
|
/>
|
|
466
|
-
{children ||
|
|
467
|
-
<ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
|
|
468
|
-
) : null}
|
|
471
|
+
{children || rightIcon ? <ReqoreSpacer width={PADDING_FROM_SIZE[size]} /> : null}
|
|
469
472
|
</>
|
|
470
473
|
) : children ? (
|
|
471
474
|
<ReqoreHorizontalSpacer
|
|
@@ -476,7 +479,9 @@ const ReqoreButton = memo(
|
|
|
476
479
|
{children && (
|
|
477
480
|
<StyledAnimatedTextWrapper
|
|
478
481
|
textAlign={textAlign}
|
|
479
|
-
style={
|
|
482
|
+
style={
|
|
483
|
+
textAlign === 'center' && iconsAlign !== 'center' ? { margin: 'auto' } : undefined
|
|
484
|
+
}
|
|
480
485
|
>
|
|
481
486
|
<StyledActiveContent wrap={wrap} effect={labelEffect}>
|
|
482
487
|
{children}
|
|
@@ -509,10 +514,13 @@ const ReqoreButton = memo(
|
|
|
509
514
|
icon={rightIcon}
|
|
510
515
|
size={size}
|
|
511
516
|
style={
|
|
512
|
-
textAlign !== 'right'
|
|
517
|
+
textAlign !== 'right' || iconsAlign === 'center'
|
|
513
518
|
? {
|
|
514
|
-
marginLeft: 'auto',
|
|
515
|
-
marginRight:
|
|
519
|
+
marginLeft: iconsAlign !== 'center' || !children ? 'auto' : undefined,
|
|
520
|
+
marginRight:
|
|
521
|
+
iconsAlign === 'center' || (textAlign === 'center' && !children)
|
|
522
|
+
? 'auto'
|
|
523
|
+
: undefined,
|
|
516
524
|
}
|
|
517
525
|
: undefined
|
|
518
526
|
}
|
|
@@ -1,17 +1,26 @@
|
|
|
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 { getPaginationOptionsFromType, TReqorePaginationType } from '../../constants/paging';
|
|
5
6
|
import { PADDING_FROM_SIZE } from '../../constants/sizes';
|
|
7
|
+
import { IReqorePagingOptions, useReqorePaging } from '../../hooks/usePaging';
|
|
6
8
|
import { IReqoreIconName } from '../../types/icons';
|
|
7
9
|
import { IReqoreColumnsProps, StyledColumns } from '../Columns';
|
|
8
10
|
import ReqoreInput, { IReqoreInputProps } from '../Input';
|
|
9
11
|
import ReqoreMessage from '../Message';
|
|
12
|
+
import { IReqorePaginationComponentProps, ReqorePagination } from '../Paging';
|
|
10
13
|
import { IReqorePanelAction, IReqorePanelProps, ReqorePanel, TReqorePanelActions } from '../Panel';
|
|
11
14
|
import { ReqoreVerticalSpacer } from '../Spacer';
|
|
12
15
|
import { sortTableData } from '../Table/helpers';
|
|
13
16
|
import { IReqoreCollectionItemProps, ReqoreCollectionItem } from './item';
|
|
14
17
|
|
|
18
|
+
export interface IReqoreCollectionPagingOptions
|
|
19
|
+
extends Omit<IReqorePagingOptions<IReqoreCollectionItemProps>, 'items'>,
|
|
20
|
+
IReqorePaginationComponentProps {
|
|
21
|
+
pageControlsPosition?: 'top' | 'bottom' | 'both';
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export interface IReqoreCollectionProps
|
|
16
25
|
extends Pick<
|
|
17
26
|
IReqorePanelProps,
|
|
@@ -48,8 +57,10 @@ export interface IReqoreCollectionProps
|
|
|
48
57
|
selectedIcon?: IReqoreIconName;
|
|
49
58
|
searchDelay?: number;
|
|
50
59
|
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
contentRenderer?: (
|
|
61
|
+
children: React.ReactNode,
|
|
62
|
+
items: IReqoreCollectionItemProps[]
|
|
63
|
+
) => React.ReactNode;
|
|
53
64
|
|
|
54
65
|
onQueryChange?: (query: string) => void;
|
|
55
66
|
|
|
@@ -57,6 +68,8 @@ export interface IReqoreCollectionProps
|
|
|
57
68
|
sortButtonTooltip?: (sort?: 'asc' | 'desc') => string;
|
|
58
69
|
displayButtonTooltip?: (display?: 'list' | 'grid') => string;
|
|
59
70
|
inputPlaceholder?: (items?: IReqoreCollectionItemProps[]) => string;
|
|
71
|
+
|
|
72
|
+
paging?: TReqorePaginationType;
|
|
60
73
|
}
|
|
61
74
|
|
|
62
75
|
export const StyledCollectionWrapper = styled(StyledColumns)`
|
|
@@ -92,13 +105,13 @@ export const ReqoreCollection = ({
|
|
|
92
105
|
minimal,
|
|
93
106
|
transparent = true,
|
|
94
107
|
onQueryChange,
|
|
95
|
-
|
|
96
|
-
childrenAfter,
|
|
108
|
+
contentRenderer = (children) => children,
|
|
97
109
|
searchDelay = 300,
|
|
98
110
|
emptyMessage = 'No data in this collection, try changing your search query or filters',
|
|
99
111
|
sortButtonTooltip = (sort) => (sort === 'desc' ? 'Sort ascending' : 'Sort descending'),
|
|
100
112
|
displayButtonTooltip = (display) => (display === 'grid' ? 'Show as list' : 'Show as grid'),
|
|
101
113
|
inputPlaceholder = (items) => `Search in ${size(items)} items`,
|
|
114
|
+
paging,
|
|
102
115
|
...rest
|
|
103
116
|
}: IReqoreCollectionProps) => {
|
|
104
117
|
const [_showAs, setShowAs] = useState<'list' | 'grid'>(showAs);
|
|
@@ -152,7 +165,7 @@ export const ReqoreCollection = ({
|
|
|
152
165
|
});
|
|
153
166
|
}, [items, sort]);
|
|
154
167
|
|
|
155
|
-
const
|
|
168
|
+
const filteredItems: IReqoreCollectionItemProps[] = useMemo(() => {
|
|
156
169
|
if (!filterable || query === '') {
|
|
157
170
|
return sortedItems;
|
|
158
171
|
}
|
|
@@ -170,6 +183,18 @@ export const ReqoreCollection = ({
|
|
|
170
183
|
});
|
|
171
184
|
}, [items, query, sortedItems]);
|
|
172
185
|
|
|
186
|
+
const {
|
|
187
|
+
pagingOptions = {},
|
|
188
|
+
componentOptions = {},
|
|
189
|
+
pageControlsPosition,
|
|
190
|
+
} = useMemo(() => getPaginationOptionsFromType(paging), [paging]);
|
|
191
|
+
|
|
192
|
+
const { items: finalItems, ...pagingData } = useReqorePaging({
|
|
193
|
+
items: filteredItems,
|
|
194
|
+
...pagingOptions,
|
|
195
|
+
enabled: !!paging,
|
|
196
|
+
});
|
|
197
|
+
|
|
173
198
|
const handlePreQueryChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
174
199
|
setPreQuery(event.target.value);
|
|
175
200
|
};
|
|
@@ -210,8 +235,11 @@ export const ReqoreCollection = ({
|
|
|
210
235
|
props: {
|
|
211
236
|
key: 'search',
|
|
212
237
|
fixed: false,
|
|
213
|
-
placeholder: inputPlaceholder(
|
|
214
|
-
onClearClick: () =>
|
|
238
|
+
placeholder: inputPlaceholder(items),
|
|
239
|
+
onClearClick: () => {
|
|
240
|
+
setQuery('');
|
|
241
|
+
setPreQuery('');
|
|
242
|
+
},
|
|
215
243
|
onChange: handlePreQueryChange,
|
|
216
244
|
value: preQuery,
|
|
217
245
|
icon: 'Search2Line',
|
|
@@ -225,6 +253,65 @@ export const ReqoreCollection = ({
|
|
|
225
253
|
return [...actions, toolbarGroup];
|
|
226
254
|
}, [filterable, preQuery, query, rest.actions, _showAs, sort, sortable, finalItems]);
|
|
227
255
|
|
|
256
|
+
const renderContent = useCallback(() => {
|
|
257
|
+
return contentRenderer(
|
|
258
|
+
<>
|
|
259
|
+
{!!paging && (pageControlsPosition === 'top' || pageControlsPosition === 'both') ? (
|
|
260
|
+
<>
|
|
261
|
+
<ReqorePagination size={rest.size} {...pagingData} {...componentOptions} />
|
|
262
|
+
<ReqoreVerticalSpacer height={PADDING_FROM_SIZE[rest.size || 'normal']} />
|
|
263
|
+
</>
|
|
264
|
+
) : null}
|
|
265
|
+
{!size(finalItems) ? (
|
|
266
|
+
<ReqoreMessage flat icon='Search2Line'>
|
|
267
|
+
{emptyMessage}
|
|
268
|
+
</ReqoreMessage>
|
|
269
|
+
) : (
|
|
270
|
+
<StyledCollectionWrapper
|
|
271
|
+
columns={_showAs === 'grid' ? 'auto-fit' : 1}
|
|
272
|
+
columnsGap={stacked ? '0px' : columnsGap}
|
|
273
|
+
rounded={rounded}
|
|
274
|
+
stacked={stacked}
|
|
275
|
+
{...rest}
|
|
276
|
+
>
|
|
277
|
+
{finalItems?.map((item, index) => (
|
|
278
|
+
<ReqoreCollectionItem
|
|
279
|
+
size={rest.size}
|
|
280
|
+
{...item}
|
|
281
|
+
icon={item.icon || (item.selected ? selectedIcon : undefined)}
|
|
282
|
+
key={index}
|
|
283
|
+
rounded={!stacked}
|
|
284
|
+
maxContentHeight={maxItemHeight}
|
|
285
|
+
/>
|
|
286
|
+
))}
|
|
287
|
+
</StyledCollectionWrapper>
|
|
288
|
+
)}
|
|
289
|
+
{!!paging &&
|
|
290
|
+
(!pageControlsPosition ||
|
|
291
|
+
pageControlsPosition === 'bottom' ||
|
|
292
|
+
pageControlsPosition === 'both') ? (
|
|
293
|
+
<>
|
|
294
|
+
<ReqoreVerticalSpacer height={PADDING_FROM_SIZE[rest.size || 'normal']} />
|
|
295
|
+
<ReqorePagination size={rest.size} {...pagingData} {...componentOptions} />
|
|
296
|
+
</>
|
|
297
|
+
) : null}
|
|
298
|
+
</>,
|
|
299
|
+
finalItems
|
|
300
|
+
);
|
|
301
|
+
}, [
|
|
302
|
+
contentRenderer,
|
|
303
|
+
finalItems,
|
|
304
|
+
_showAs,
|
|
305
|
+
columnsGap,
|
|
306
|
+
emptyMessage,
|
|
307
|
+
maxItemHeight,
|
|
308
|
+
rest,
|
|
309
|
+
rounded,
|
|
310
|
+
selectedIcon,
|
|
311
|
+
size,
|
|
312
|
+
stacked,
|
|
313
|
+
]);
|
|
314
|
+
|
|
228
315
|
return (
|
|
229
316
|
<ReqorePanel
|
|
230
317
|
{...rest}
|
|
@@ -239,42 +326,7 @@ export const ReqoreCollection = ({
|
|
|
239
326
|
actions={finalActions}
|
|
240
327
|
className={`reqore-collection ${rest.className || ''}`}
|
|
241
328
|
>
|
|
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}
|
|
329
|
+
{renderContent()}
|
|
278
330
|
</ReqorePanel>
|
|
279
331
|
);
|
|
280
332
|
};
|
|
@@ -4,9 +4,10 @@ import { ReqorePopover } from '../..';
|
|
|
4
4
|
import { IPopoverOptions } from '../../hooks/usePopover';
|
|
5
5
|
import { IReqoreIconName } from '../../types/icons';
|
|
6
6
|
import ReqoreButton, { IReqoreButtonProps } from '../Button';
|
|
7
|
+
import { IReqoreInputProps } from '../Input';
|
|
7
8
|
import ReqoreDropdownList, { IReqoreDropdownItem, TDropdownItemOnClick } from './list';
|
|
8
9
|
|
|
9
|
-
export interface IReqoreDropdownProps extends Partial<IPopoverOptions
|
|
10
|
+
export interface IReqoreDropdownProps extends Partial<Omit<IPopoverOptions, 'openOnMount'>> {
|
|
10
11
|
items?: IReqoreDropdownItem[];
|
|
11
12
|
multiSelect?: boolean;
|
|
12
13
|
buttonStyle?: React.CSSProperties;
|
|
@@ -23,6 +24,8 @@ export interface IReqoreDropdownProps extends Partial<IPopoverOptions> {
|
|
|
23
24
|
isDefaultOpen?: boolean;
|
|
24
25
|
onItemSelect?: TDropdownItemOnClick;
|
|
25
26
|
style?: React.CSSProperties;
|
|
27
|
+
inputProps?: IReqoreInputProps;
|
|
28
|
+
scrollToSelected?: boolean;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
|
|
@@ -50,13 +53,14 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
|
|
|
50
53
|
maxWidth,
|
|
51
54
|
noArrow = true,
|
|
52
55
|
transparent,
|
|
53
|
-
openOnMount,
|
|
54
56
|
show,
|
|
55
57
|
targetElement,
|
|
56
58
|
useTargetWidth,
|
|
57
59
|
listWidth,
|
|
58
60
|
listHeight,
|
|
59
61
|
passPopoverData,
|
|
62
|
+
inputProps,
|
|
63
|
+
scrollToSelected,
|
|
60
64
|
...rest
|
|
61
65
|
}: IReqoreDropdownProps & T) {
|
|
62
66
|
const componentProps = useMemo(
|
|
@@ -82,6 +86,8 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
|
|
|
82
86
|
items={items}
|
|
83
87
|
filterable={filterable}
|
|
84
88
|
onItemSelect={onItemSelect}
|
|
89
|
+
inputProps={inputProps}
|
|
90
|
+
scrollToSelected={scrollToSelected}
|
|
85
91
|
/>
|
|
86
92
|
) : undefined;
|
|
87
93
|
}, [items]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { IReqoreComponent } from '../../types/global';
|
|
3
|
-
import ReqoreInput from '../Input';
|
|
3
|
+
import ReqoreInput, { IReqoreInputProps } from '../Input';
|
|
4
4
|
import ReqoreMenu from '../Menu';
|
|
5
5
|
import ReqoreMenuDivider from '../Menu/divider';
|
|
6
6
|
import ReqoreMenuItem, { IReqoreMenuItemProps } from '../Menu/item';
|
|
@@ -25,6 +25,8 @@ export interface IReqoreDropdownListProps extends IReqoreComponent {
|
|
|
25
25
|
height?: string;
|
|
26
26
|
filterable?: boolean;
|
|
27
27
|
onItemSelect?: TDropdownItemOnClick;
|
|
28
|
+
inputProps?: IReqoreInputProps;
|
|
29
|
+
scrollToSelected?: boolean;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
const ReqoreDropdownList = memo(
|
|
@@ -37,6 +39,8 @@ const ReqoreDropdownList = memo(
|
|
|
37
39
|
width,
|
|
38
40
|
height,
|
|
39
41
|
onItemSelect,
|
|
42
|
+
inputProps,
|
|
43
|
+
scrollToSelected,
|
|
40
44
|
}: IReqoreDropdownListProps) => {
|
|
41
45
|
const [_items, setItems] = useState<TReqoreDropdownItems>(items);
|
|
42
46
|
const [query, setQuery] = useState<string>('');
|
|
@@ -94,6 +98,7 @@ const ReqoreDropdownList = memo(
|
|
|
94
98
|
onChange={handleQueryChange}
|
|
95
99
|
placeholder='Filter'
|
|
96
100
|
onClearClick={() => setQuery('')}
|
|
101
|
+
{...inputProps}
|
|
97
102
|
/>
|
|
98
103
|
</>
|
|
99
104
|
)}
|
|
@@ -108,6 +113,7 @@ const ReqoreDropdownList = memo(
|
|
|
108
113
|
label={item.label || item.value}
|
|
109
114
|
onClick={() => handleItemClick({ ...item, onClick })}
|
|
110
115
|
rightIcon={item.selected ? 'CheckLine' : undefined}
|
|
116
|
+
scrollIntoView={scrollToSelected && item.selected && !multiSelect}
|
|
111
117
|
/>
|
|
112
118
|
)
|
|
113
119
|
)}
|
|
@@ -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
|
|