@qoretechnologies/reqore 0.32.2 → 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/ControlGroup/index.d.ts.map +1 -1
- package/dist/components/ControlGroup/index.js +4 -2
- package/dist/components/ControlGroup/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/Paragraph/index.js +1 -1
- package/dist/components/Spinner/index.d.ts +3 -2
- package/dist/components/Spinner/index.d.ts.map +1 -1
- package/dist/components/Spinner/index.js +13 -2
- package/dist/components/Spinner/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 +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 +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 +96 -44
- package/src/components/ControlGroup/index.tsx +4 -2
- 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/Paragraph/index.tsx +1 -1
- package/src/components/Spinner/index.tsx +11 -3
- 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 +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 +32 -42
- package/src/stories/Dropdown/Dropdown.stories.tsx +24 -1
- package/src/stories/Paging/Paging.stories.tsx +184 -0
- package/src/stories/Spinner/Spinner.stories.tsx +7 -2
- package/src/stories/Tag/Tag.stories.tsx +50 -0
- package/tests.json +1 -1
|
@@ -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
|
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { memo, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useUnmount, useUpdateEffect } from 'react-use';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { ReqoreDropdown } from '../..';
|
|
5
|
+
import { IReqorePagingResult } from '../../hooks/usePaging';
|
|
6
|
+
import ReqoreButton, { IReqoreButtonProps, StyledButton } from '../Button';
|
|
7
|
+
import ReqoreControlGroup, { IReqoreControlGroupProps } from '../ControlGroup';
|
|
8
|
+
import { IReqoreDropdownProps } from '../Dropdown';
|
|
9
|
+
import { IReqoreDropdownItemProps } from '../Dropdown/item';
|
|
10
|
+
|
|
11
|
+
export interface IReqorePaginationComponentProps
|
|
12
|
+
extends Omit<IReqoreControlGroupProps, 'children'> {
|
|
13
|
+
pageButtonProps?: IReqoreButtonProps;
|
|
14
|
+
activePageButtonProps?: IReqoreButtonProps;
|
|
15
|
+
listPageButtonProps?: IReqoreDropdownProps;
|
|
16
|
+
controlPageButtonProps?: IReqoreButtonProps;
|
|
17
|
+
loadMoreButtonProps?: IReqoreButtonProps;
|
|
18
|
+
firstPageLabel?: string;
|
|
19
|
+
lastPageLabel?: string;
|
|
20
|
+
nextPageLabel?: string;
|
|
21
|
+
previousPageLabel?: string;
|
|
22
|
+
pageLabel?: string;
|
|
23
|
+
loadMoreLabel?: string;
|
|
24
|
+
showPages?: boolean;
|
|
25
|
+
showControls?: boolean;
|
|
26
|
+
showPagesAs?: 'buttons' | 'list';
|
|
27
|
+
showLabels?: boolean;
|
|
28
|
+
scrollOnLoadMore?: boolean;
|
|
29
|
+
autoLoadMore?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface IReqorePaginationProps<T>
|
|
32
|
+
extends Omit<IReqorePagingResult<T>, 'items'>,
|
|
33
|
+
IReqorePaginationComponentProps {}
|
|
34
|
+
|
|
35
|
+
export const StyledPagesWrapper = styled(ReqoreControlGroup)`
|
|
36
|
+
width: unset;
|
|
37
|
+
max-width: 100%;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
|
|
40
|
+
& > ${StyledButton} {
|
|
41
|
+
margin: 0;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
function Pagination<T>({
|
|
46
|
+
allPages,
|
|
47
|
+
back,
|
|
48
|
+
first,
|
|
49
|
+
currentPage,
|
|
50
|
+
isLastPage,
|
|
51
|
+
isFirstPage,
|
|
52
|
+
pageCount,
|
|
53
|
+
pages,
|
|
54
|
+
last,
|
|
55
|
+
next,
|
|
56
|
+
setPage,
|
|
57
|
+
infinite,
|
|
58
|
+
itemsLeft,
|
|
59
|
+
showPagesAs = 'buttons',
|
|
60
|
+
pageButtonProps = {},
|
|
61
|
+
activePageButtonProps = {},
|
|
62
|
+
listPageButtonProps = {},
|
|
63
|
+
controlPageButtonProps = {},
|
|
64
|
+
loadMoreButtonProps = {},
|
|
65
|
+
firstPageLabel = 'First',
|
|
66
|
+
lastPageLabel = 'Last',
|
|
67
|
+
nextPageLabel = 'Next',
|
|
68
|
+
previousPageLabel = 'Back',
|
|
69
|
+
pageLabel = 'Page',
|
|
70
|
+
loadMoreLabel = 'Load more',
|
|
71
|
+
showLabels,
|
|
72
|
+
showPages = true,
|
|
73
|
+
showControls = true,
|
|
74
|
+
scrollOnLoadMore,
|
|
75
|
+
autoLoadMore,
|
|
76
|
+
itemsPerPage,
|
|
77
|
+
...rest
|
|
78
|
+
}: IReqorePaginationProps<T>) {
|
|
79
|
+
const [loadMoreRef, setLoadMoreRef] = useState<HTMLButtonElement>(undefined);
|
|
80
|
+
const [scrollTargetRef, setScrollTargetRef] = useState<HTMLDivElement>(undefined);
|
|
81
|
+
const observer = useRef<IntersectionObserver>(null);
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (scrollTargetRef && scrollOnLoadMore && !isLastPage && !isFirstPage) {
|
|
85
|
+
scrollTargetRef.scrollIntoView({
|
|
86
|
+
behavior: 'smooth',
|
|
87
|
+
block: 'end',
|
|
88
|
+
inline: 'nearest',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}, [currentPage, scrollTargetRef, scrollOnLoadMore, isLastPage, isFirstPage]);
|
|
92
|
+
|
|
93
|
+
useUpdateEffect(() => {
|
|
94
|
+
if (loadMoreRef && autoLoadMore) {
|
|
95
|
+
observer.current = new IntersectionObserver(
|
|
96
|
+
(entries: IntersectionObserverEntry[]) => {
|
|
97
|
+
entries.forEach((entry) => {
|
|
98
|
+
if (entry.isIntersecting) {
|
|
99
|
+
next();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
threshold: 0.8,
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
observer.current.observe(loadMoreRef);
|
|
109
|
+
}
|
|
110
|
+
}, [loadMoreRef, autoLoadMore, isLastPage]);
|
|
111
|
+
|
|
112
|
+
useUnmount(() => {
|
|
113
|
+
observer.current?.disconnect();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
if (pageCount === 1 || pageCount === 0) return null;
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<ReqoreControlGroup
|
|
120
|
+
{...rest}
|
|
121
|
+
className={`${rest.className || ''} reqore-pagination-wrapper`}
|
|
122
|
+
style={{ justifyContent: 'center' }}
|
|
123
|
+
>
|
|
124
|
+
{infinite && !isLastPage ? (
|
|
125
|
+
<ReqoreControlGroup vertical>
|
|
126
|
+
<div className='reqore-auto-scroll-target' ref={setScrollTargetRef} />
|
|
127
|
+
<ReqoreButton
|
|
128
|
+
icon='ArrowDropDownLine'
|
|
129
|
+
badge={itemsLeft}
|
|
130
|
+
iconsAlign='center'
|
|
131
|
+
{...loadMoreButtonProps}
|
|
132
|
+
onClick={next}
|
|
133
|
+
ref={setLoadMoreRef}
|
|
134
|
+
style={{
|
|
135
|
+
scrollMarginTop: '200px',
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
{showLabels && loadMoreLabel}
|
|
139
|
+
</ReqoreButton>
|
|
140
|
+
</ReqoreControlGroup>
|
|
141
|
+
) : (
|
|
142
|
+
<>
|
|
143
|
+
{showPagesAs === 'list' || (showControls && !showPages) ? (
|
|
144
|
+
<ReqoreButton
|
|
145
|
+
icon='RewindMiniLine'
|
|
146
|
+
fixed
|
|
147
|
+
{...controlPageButtonProps}
|
|
148
|
+
onClick={first}
|
|
149
|
+
disabled={isFirstPage}
|
|
150
|
+
tooltip={!showLabels && firstPageLabel}
|
|
151
|
+
>
|
|
152
|
+
{showLabels && firstPageLabel}
|
|
153
|
+
</ReqoreButton>
|
|
154
|
+
) : null}
|
|
155
|
+
{showControls && (
|
|
156
|
+
<ReqoreButton
|
|
157
|
+
icon='ArrowDropLeftLine'
|
|
158
|
+
fixed
|
|
159
|
+
{...controlPageButtonProps}
|
|
160
|
+
onClick={back}
|
|
161
|
+
disabled={isFirstPage}
|
|
162
|
+
tooltip={!showLabels && previousPageLabel}
|
|
163
|
+
>
|
|
164
|
+
{showLabels && previousPageLabel}
|
|
165
|
+
</ReqoreButton>
|
|
166
|
+
)}
|
|
167
|
+
{showPages && (
|
|
168
|
+
<StyledPagesWrapper wrap horizontalAlign='center'>
|
|
169
|
+
{showPagesAs === 'buttons' ? (
|
|
170
|
+
pages.map((page) => (
|
|
171
|
+
<ReqoreButton
|
|
172
|
+
textAlign='center'
|
|
173
|
+
fixed
|
|
174
|
+
key={page}
|
|
175
|
+
onClick={() => setPage(page)}
|
|
176
|
+
active={page === currentPage}
|
|
177
|
+
{...(page === currentPage ? activePageButtonProps : pageButtonProps)}
|
|
178
|
+
>
|
|
179
|
+
{page}
|
|
180
|
+
</ReqoreButton>
|
|
181
|
+
))
|
|
182
|
+
) : (
|
|
183
|
+
<ReqoreDropdown
|
|
184
|
+
filterable
|
|
185
|
+
label={`${showLabels ? `${pageLabel} ` : ''}${currentPage} / ${pageCount}`}
|
|
186
|
+
items={pages.map((page) => ({
|
|
187
|
+
label: `${showLabels ? `${pageLabel} ` : ''}${page}`,
|
|
188
|
+
onClick: () => setPage(page),
|
|
189
|
+
selected: page === currentPage,
|
|
190
|
+
...(page === currentPage
|
|
191
|
+
? (activePageButtonProps as IReqoreDropdownItemProps)
|
|
192
|
+
: (pageButtonProps as IReqoreDropdownItemProps)),
|
|
193
|
+
}))}
|
|
194
|
+
placement='bottom'
|
|
195
|
+
inputProps={{ focusRules: { type: 'auto', viewportOnly: true } }}
|
|
196
|
+
scrollToSelected
|
|
197
|
+
{...listPageButtonProps}
|
|
198
|
+
/>
|
|
199
|
+
)}
|
|
200
|
+
</StyledPagesWrapper>
|
|
201
|
+
)}
|
|
202
|
+
{showControls && (
|
|
203
|
+
<ReqoreButton
|
|
204
|
+
icon='ArrowDropRightLine'
|
|
205
|
+
fixed
|
|
206
|
+
{...controlPageButtonProps}
|
|
207
|
+
onClick={next}
|
|
208
|
+
disabled={isLastPage}
|
|
209
|
+
tooltip={!showLabels && nextPageLabel}
|
|
210
|
+
>
|
|
211
|
+
{showLabels && nextPageLabel}
|
|
212
|
+
</ReqoreButton>
|
|
213
|
+
)}
|
|
214
|
+
{showPagesAs === 'list' || (showControls && !showPages) ? (
|
|
215
|
+
<ReqoreButton
|
|
216
|
+
icon='SpeedMiniLine'
|
|
217
|
+
fixed
|
|
218
|
+
{...controlPageButtonProps}
|
|
219
|
+
onClick={last}
|
|
220
|
+
disabled={isLastPage}
|
|
221
|
+
tooltip={!showLabels && lastPageLabel}
|
|
222
|
+
>
|
|
223
|
+
{showLabels && lastPageLabel}
|
|
224
|
+
</ReqoreButton>
|
|
225
|
+
) : null}
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
228
|
+
</ReqoreControlGroup>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export const ReqorePagination = memo(Pagination) as typeof Pagination;
|
|
@@ -15,8 +15,8 @@ export interface IReqoreParagraphProps
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export const StyledParagraph = styled(StyledTextEffect)`
|
|
18
|
-
margin: 0;
|
|
19
18
|
padding: 0;
|
|
19
|
+
margin: 0;
|
|
20
20
|
color: ${({ theme, intent }) => (intent ? theme.intents[intent] : 'inherit')};
|
|
21
21
|
font-size: ${({ _size }) => (isStringSize(_size) ? `${TEXT_FROM_SIZE[_size]}px` : _size)};
|
|
22
22
|
`;
|
|
@@ -3,10 +3,12 @@ import { ReqoreIcon, ReqoreP } from '../..';
|
|
|
3
3
|
import { TSizes } from '../../constants/sizes';
|
|
4
4
|
import { TReqoreIntent } from '../../constants/theme';
|
|
5
5
|
import { IWithReqoreEffect } from '../../types/global';
|
|
6
|
-
import ReqoreControlGroup from '../ControlGroup';
|
|
6
|
+
import ReqoreControlGroup, { IReqoreControlGroupProps } from '../ControlGroup';
|
|
7
7
|
import { IReqoreEffect, TReqoreEffectColor } from '../Effect';
|
|
8
8
|
|
|
9
|
-
export interface IReqoreSpinnerProps
|
|
9
|
+
export interface IReqoreSpinnerProps
|
|
10
|
+
extends Omit<IReqoreControlGroupProps, 'children' | 'size'>,
|
|
11
|
+
IWithReqoreEffect {
|
|
10
12
|
size?: TSizes | string;
|
|
11
13
|
intent?: TReqoreIntent;
|
|
12
14
|
children?: any;
|
|
@@ -27,6 +29,7 @@ export const ReqoreSpinner = ({
|
|
|
27
29
|
effect,
|
|
28
30
|
iconMargin,
|
|
29
31
|
centered,
|
|
32
|
+
...rest
|
|
30
33
|
}: IReqoreSpinnerProps) => {
|
|
31
34
|
const renderContent = useCallback(() => {
|
|
32
35
|
return (
|
|
@@ -44,7 +47,12 @@ export const ReqoreSpinner = ({
|
|
|
44
47
|
|
|
45
48
|
if (children) {
|
|
46
49
|
return (
|
|
47
|
-
<ReqoreControlGroup
|
|
50
|
+
<ReqoreControlGroup
|
|
51
|
+
{...rest}
|
|
52
|
+
vertical={centered}
|
|
53
|
+
horizontalAlign={centered ? 'center' : undefined}
|
|
54
|
+
verticalAlign='center'
|
|
55
|
+
>
|
|
48
56
|
{renderContent()}
|
|
49
57
|
<ReqoreP
|
|
50
58
|
size={size}
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
IReqoreDisabled,
|
|
26
26
|
IReqoreIntent,
|
|
27
27
|
IWithReqoreEffect,
|
|
28
|
-
IWithReqoreFixed,
|
|
29
28
|
IWithReqoreFluid,
|
|
30
29
|
IWithReqoreMinimal,
|
|
31
30
|
IWithReqoreTooltip,
|
|
@@ -52,8 +51,8 @@ export interface IReqoreTagProps
|
|
|
52
51
|
IReqoreDisabled,
|
|
53
52
|
IWithReqoreMinimal,
|
|
54
53
|
IWithReqoreFluid,
|
|
55
|
-
IWithReqoreFixed,
|
|
56
54
|
IWithReqoreEffect {
|
|
55
|
+
fixed?: boolean | 'key' | 'label';
|
|
57
56
|
size?: TSizes;
|
|
58
57
|
label?: string | number;
|
|
59
58
|
labelKey?: string | number;
|
|
@@ -93,9 +92,10 @@ export const StyledTag = styled(StyledEffect)<IReqoreTagStyle>`
|
|
|
93
92
|
font-size: ${({ size }) => TEXT_FROM_SIZE[size]}px;
|
|
94
93
|
|
|
95
94
|
min-width: ${({ size }) => SIZE_TO_PX[size]}px;
|
|
96
|
-
max-width: ${({ fixed }) => (
|
|
97
|
-
flex: ${({ fluid, fixed }) => (fixed ? '0 0 auto' : fluid ? '1 auto' : '0 0 auto')};
|
|
98
|
-
align-self: ${({ fixed, fluid }) =>
|
|
95
|
+
max-width: ${({ fixed }) => (fixed !== true ? '100%' : undefined)};
|
|
96
|
+
flex: ${({ fluid, fixed }) => (fixed === true ? '0 0 auto' : fluid ? '1 auto' : '0 0 auto')};
|
|
97
|
+
align-self: ${({ fixed, fluid }) =>
|
|
98
|
+
fixed === true ? 'flex-start' : fluid ? 'stretch' : undefined};
|
|
99
99
|
border-radius: ${({ asBadge, size }) => (asBadge ? 18 : RADIUS_FROM_SIZE[size])}px;
|
|
100
100
|
width: ${({ width }) => width || undefined};
|
|
101
101
|
transition: all 0.2s ease-out;
|
|
@@ -163,7 +163,7 @@ const StyledTagKeyWrapper = styled.span<{ size: TSizes }>`
|
|
|
163
163
|
display: flex;
|
|
164
164
|
align-items: center;
|
|
165
165
|
justify-content: center;
|
|
166
|
-
flex: ${({ hasKey }) => (hasKey ? 1 : undefined)};
|
|
166
|
+
flex: ${({ hasKey, fixed }) => (hasKey ? (fixed === 'key' ? '0 0 auto' : 1) : undefined)};
|
|
167
167
|
flex-shrink: 0;
|
|
168
168
|
min-height: 100%;
|
|
169
169
|
`;
|
|
@@ -172,7 +172,7 @@ const StyledTagContentWrapper = styled.span<{ size: TSizes }>`
|
|
|
172
172
|
display: flex;
|
|
173
173
|
align-items: center;
|
|
174
174
|
justify-content: center;
|
|
175
|
-
flex: 1;
|
|
175
|
+
flex: ${({ fixed }) => (fixed === 'label' ? '0 0 auto' : 1)};
|
|
176
176
|
flex-shrink: 0;
|
|
177
177
|
min-height: 100%;
|
|
178
178
|
`;
|
|
@@ -311,6 +311,7 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
|
|
|
311
311
|
wrap={wrap}
|
|
312
312
|
hasWidth={!!width}
|
|
313
313
|
hasKey={!!labelKey}
|
|
314
|
+
fixed={rest.fixed}
|
|
314
315
|
>
|
|
315
316
|
{icon && (
|
|
316
317
|
<ReqoreIcon
|
|
@@ -345,6 +346,7 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
|
|
|
345
346
|
wrap={wrap}
|
|
346
347
|
hasWidth={!!width}
|
|
347
348
|
hasKey={!!labelKey}
|
|
349
|
+
fixed={rest.fixed}
|
|
348
350
|
>
|
|
349
351
|
{label || label === 0 ? (
|
|
350
352
|
<StyledTagContent
|
package/src/constants/colors.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { TReqoreHexColor } from '../components/Effect';
|
|
2
|
+
|
|
3
|
+
export const Colors: Record<string, TReqoreHexColor> = {
|
|
2
4
|
DARK: '#000000',
|
|
5
|
+
DARK_THEME: '#333333',
|
|
3
6
|
LIGHT: '#ffffff',
|
|
4
7
|
BLUE: '#0E5A8A',
|
|
5
8
|
GREEN: '#0A6640',
|
|
6
9
|
YELLOW: '#d1a036',
|
|
7
10
|
ORANGE: '#A66321',
|
|
8
11
|
RED: '#A82A2A',
|
|
12
|
+
GRAY: '#444444',
|
|
9
13
|
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { IReqoreCollectionPagingOptions } from '../components/Collection';
|
|
2
|
+
import { IReqorePaginationProps } from '../components/Paging';
|
|
3
|
+
import { IReqorePagingOptions } from '../hooks/usePaging';
|
|
4
|
+
|
|
5
|
+
export type TReqorePaginationType =
|
|
6
|
+
| true
|
|
7
|
+
| 'list'
|
|
8
|
+
| 'infinite'
|
|
9
|
+
| 'auto-load'
|
|
10
|
+
| IReqoreCollectionPagingOptions;
|
|
11
|
+
|
|
12
|
+
export function getPaginationOptionsFromType<T>(type: TReqorePaginationType): {
|
|
13
|
+
pagingOptions?: Omit<IReqorePagingOptions<T>, 'items'>;
|
|
14
|
+
componentOptions?: Partial<Omit<IReqorePaginationProps<T>, 'items'>>;
|
|
15
|
+
pageControlsPosition?: 'top' | 'bottom' | 'both';
|
|
16
|
+
} {
|
|
17
|
+
if (!type) return {};
|
|
18
|
+
|
|
19
|
+
if (typeof type === 'object') {
|
|
20
|
+
const {
|
|
21
|
+
infinite,
|
|
22
|
+
itemsPerPage,
|
|
23
|
+
pagesToShow,
|
|
24
|
+
startPage,
|
|
25
|
+
pageControlsPosition = 'bottom',
|
|
26
|
+
...componentOptions
|
|
27
|
+
} = type;
|
|
28
|
+
return {
|
|
29
|
+
pagingOptions: { infinite, itemsPerPage, pagesToShow, startPage },
|
|
30
|
+
pageControlsPosition,
|
|
31
|
+
componentOptions,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
switch (type) {
|
|
36
|
+
case true:
|
|
37
|
+
return {};
|
|
38
|
+
case 'list':
|
|
39
|
+
return {
|
|
40
|
+
componentOptions: {
|
|
41
|
+
showPagesAs: 'list',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
case 'infinite':
|
|
45
|
+
case 'auto-load':
|
|
46
|
+
return { pagingOptions: { infinite: true } };
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/constants/theme.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
TReqoreEffectGradientAnimationTrigger,
|
|
4
4
|
TReqoreHexColor,
|
|
5
5
|
} from '../components/Effect';
|
|
6
|
+
import { Colors } from './colors';
|
|
6
7
|
|
|
7
8
|
export interface IReqoreSidebarTheme {
|
|
8
9
|
main?: TReqoreHexColor;
|
|
@@ -94,16 +95,16 @@ export interface IReqoreIntents {
|
|
|
94
95
|
export type TReqoreIntent = 'info' | 'success' | 'pending' | 'warning' | 'danger' | 'muted';
|
|
95
96
|
|
|
96
97
|
export const DEFAULT_INTENTS: IReqoreIntents = {
|
|
97
|
-
info:
|
|
98
|
-
success:
|
|
99
|
-
pending:
|
|
100
|
-
warning:
|
|
101
|
-
danger:
|
|
102
|
-
muted:
|
|
98
|
+
info: Colors.BLUE,
|
|
99
|
+
success: Colors.GREEN,
|
|
100
|
+
pending: Colors.YELLOW,
|
|
101
|
+
warning: Colors.ORANGE,
|
|
102
|
+
danger: Colors.RED,
|
|
103
|
+
muted: Colors.GRAY,
|
|
103
104
|
};
|
|
104
105
|
|
|
105
106
|
export const DEFAULT_THEME: IReqoreTheme = {
|
|
106
|
-
main:
|
|
107
|
+
main: Colors.DARK_THEME,
|
|
107
108
|
text: {
|
|
108
109
|
dim: true,
|
|
109
110
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { size } from 'lodash';
|
|
2
|
-
import React, { useRef, useState } from 'react';
|
|
2
|
+
import React, { useCallback, useRef, useState } from 'react';
|
|
3
3
|
import { useMedia } from 'react-use';
|
|
4
4
|
import shortid from 'shortid';
|
|
5
5
|
import { useContext } from 'use-context-selector';
|
|
@@ -62,11 +62,11 @@ const ReqoreProvider: React.FC<IReqoreNotifications> = ({ children, options = {}
|
|
|
62
62
|
: useMedia('(min-width: 480px) and (max-width: 1200px)');
|
|
63
63
|
const isMobileOrTablet = isMobile || isTablet;
|
|
64
64
|
|
|
65
|
-
const getAndIncreaseZIndex = (): number => {
|
|
65
|
+
const getAndIncreaseZIndex = useCallback((): number => {
|
|
66
66
|
latestZIndex.current += 1;
|
|
67
67
|
|
|
68
68
|
return latestZIndex.current;
|
|
69
|
-
};
|
|
69
|
+
}, [latestZIndex.current]);
|
|
70
70
|
|
|
71
71
|
const confirmAction = (data: IReqoreConfirmationModal): void => {
|
|
72
72
|
setConfirmationModal({
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { cloneDeep } from 'lodash';
|
|
2
2
|
import merge from 'lodash/merge';
|
|
3
3
|
import { rgba } from 'polished';
|
|
4
|
-
import React, { useState } from 'react';
|
|
5
|
-
import styled, { createGlobalStyle } from 'styled-components';
|
|
4
|
+
import React, { forwardRef, useState } from 'react';
|
|
5
|
+
import styled, { createGlobalStyle, css } from 'styled-components';
|
|
6
6
|
import ReqoreLayoutWrapper from '../components/Layout';
|
|
7
7
|
import { IReqoreNotificationsPosition } from '../components/Notifications';
|
|
8
8
|
import { DEFAULT_THEME, IReqoreTheme } from '../constants/theme';
|
|
9
9
|
import ThemeContext from '../context/ThemeContext';
|
|
10
|
-
import { buildTheme, getMainBackgroundColor } from '../helpers/colors';
|
|
10
|
+
import { buildTheme, getMainBackgroundColor, getReadableColor } from '../helpers/colors';
|
|
11
11
|
import PopoverProvider from './PopoverProvider';
|
|
12
12
|
import ReqoreProvider from './ReqoreProvider';
|
|
13
13
|
import ReqoreThemeProvider from './ThemeProvider';
|
|
@@ -56,11 +56,24 @@ const GlobalStyle = createGlobalStyle`
|
|
|
56
56
|
|
|
57
57
|
const StyledPortal = styled.div`
|
|
58
58
|
z-index: 9999;
|
|
59
|
+
|
|
59
60
|
* {
|
|
60
61
|
box-sizing: border-box;
|
|
61
62
|
}
|
|
63
|
+
|
|
64
|
+
${({ theme }) => css`
|
|
65
|
+
color: ${getReadableColor(theme, undefined, undefined, true)};
|
|
66
|
+
`}
|
|
62
67
|
`;
|
|
63
68
|
|
|
69
|
+
const ReqorePortal = forwardRef<HTMLDivElement, {}>((_props, ref) => {
|
|
70
|
+
return (
|
|
71
|
+
<ReqoreThemeProvider>
|
|
72
|
+
<StyledPortal id='reqore-portal' ref={ref} />
|
|
73
|
+
</ReqoreThemeProvider>
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
64
77
|
const ReqoreUIProvider: React.FC<IReqoreUIProviderProps> = ({ children, theme, options }) => {
|
|
65
78
|
const [modalPortal, setModalPortal] = useState<any>(false);
|
|
66
79
|
|
|
@@ -81,8 +94,8 @@ const ReqoreUIProvider: React.FC<IReqoreUIProviderProps> = ({ children, theme, o
|
|
|
81
94
|
</ReqoreProvider>
|
|
82
95
|
) : null}
|
|
83
96
|
</ReqoreLayoutWrapper>
|
|
97
|
+
<ReqorePortal ref={setModalPortal} />
|
|
84
98
|
</ThemeContext.Provider>
|
|
85
|
-
<StyledPortal id='reqore-portal' ref={setModalPortal} />
|
|
86
99
|
</>
|
|
87
100
|
);
|
|
88
101
|
};
|
|
@@ -6,9 +6,9 @@ import React from 'react';
|
|
|
6
6
|
* @param refs - An array of refs to combine.
|
|
7
7
|
* @returns A ref object.
|
|
8
8
|
*/
|
|
9
|
-
export function useCombinedRefs(...refs) {
|
|
9
|
+
export function useCombinedRefs<T = any>(...refs) {
|
|
10
10
|
const [_innerRef, setInnerRef] = React.useState(null);
|
|
11
|
-
const targetRef = React.useRef();
|
|
11
|
+
const targetRef = React.useRef<T>();
|
|
12
12
|
|
|
13
13
|
React.useEffect(() => {
|
|
14
14
|
[...refs, setInnerRef].forEach((ref) => {
|