@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.
Files changed (103) hide show
  1. package/__tests__/collection.test.tsx +123 -5
  2. package/__tests__/hooks/useLatestZIndex.test.tsx +10 -0
  3. package/__tests__/hooks/useReqorePaging.test.tsx +251 -0
  4. package/__tests__/hooks/useTheme.test.tsx +31 -0
  5. package/__tests__/pagination.test.tsx +301 -0
  6. package/__tests__/popover.test.tsx +20 -6
  7. package/__tests__/setup.js +8 -0
  8. package/__tests__/tree.test.tsx +0 -1
  9. package/dist/components/Button/index.d.ts +1 -0
  10. package/dist/components/Button/index.d.ts.map +1 -1
  11. package/dist/components/Button/index.js +11 -7
  12. package/dist/components/Button/index.js.map +1 -1
  13. package/dist/components/Collection/index.d.ts +9 -3
  14. package/dist/components/Collection/index.d.ts.map +1 -1
  15. package/dist/components/Collection/index.js +34 -8
  16. package/dist/components/Collection/index.js.map +1 -1
  17. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  18. package/dist/components/ControlGroup/index.js +4 -2
  19. package/dist/components/ControlGroup/index.js.map +1 -1
  20. package/dist/components/Dropdown/index.d.ts +5 -2
  21. package/dist/components/Dropdown/index.d.ts.map +1 -1
  22. package/dist/components/Dropdown/index.js +2 -2
  23. package/dist/components/Dropdown/index.js.map +1 -1
  24. package/dist/components/Dropdown/list.d.ts +4 -1
  25. package/dist/components/Dropdown/list.d.ts.map +1 -1
  26. package/dist/components/Dropdown/list.js +3 -3
  27. package/dist/components/Dropdown/list.js.map +1 -1
  28. package/dist/components/Menu/item.d.ts +1 -0
  29. package/dist/components/Menu/item.d.ts.map +1 -1
  30. package/dist/components/Menu/item.js +14 -2
  31. package/dist/components/Menu/item.js.map +1 -1
  32. package/dist/components/MultiSelect/index.d.ts +1 -1
  33. package/dist/components/MultiSelect/index.d.ts.map +1 -1
  34. package/dist/components/Paging/index.d.ts +30 -0
  35. package/dist/components/Paging/index.d.ts.map +1 -0
  36. package/dist/components/Paging/index.js +106 -0
  37. package/dist/components/Paging/index.js.map +1 -0
  38. package/dist/components/Paragraph/index.js +1 -1
  39. package/dist/components/Spinner/index.d.ts +3 -2
  40. package/dist/components/Spinner/index.d.ts.map +1 -1
  41. package/dist/components/Spinner/index.js +13 -2
  42. package/dist/components/Spinner/index.js.map +1 -1
  43. package/dist/components/Tag/index.d.ts +3 -2
  44. package/dist/components/Tag/index.d.ts.map +1 -1
  45. package/dist/components/Tag/index.js +10 -7
  46. package/dist/components/Tag/index.js.map +1 -1
  47. package/dist/constants/colors.d.ts +2 -9
  48. package/dist/constants/colors.d.ts.map +1 -1
  49. package/dist/constants/colors.js +3 -1
  50. package/dist/constants/colors.js.map +1 -1
  51. package/dist/constants/paging.d.ts +10 -0
  52. package/dist/constants/paging.d.ts.map +1 -0
  53. package/dist/constants/paging.js +41 -0
  54. package/dist/constants/paging.js.map +1 -0
  55. package/dist/constants/theme.d.ts.map +1 -1
  56. package/dist/constants/theme.js +8 -7
  57. package/dist/constants/theme.js.map +1 -1
  58. package/dist/containers/ReqoreProvider.d.ts.map +1 -1
  59. package/dist/containers/ReqoreProvider.js +2 -2
  60. package/dist/containers/ReqoreProvider.js.map +1 -1
  61. package/dist/containers/UIProvider.d.ts.map +1 -1
  62. package/dist/containers/UIProvider.js +9 -3
  63. package/dist/containers/UIProvider.js.map +1 -1
  64. package/dist/hooks/useCombinedRefs.d.ts +2 -2
  65. package/dist/hooks/useCombinedRefs.d.ts.map +1 -1
  66. package/dist/hooks/useCombinedRefs.js.map +1 -1
  67. package/dist/hooks/usePaging.d.ts +27 -0
  68. package/dist/hooks/usePaging.d.ts.map +1 -0
  69. package/dist/hooks/usePaging.js +83 -0
  70. package/dist/hooks/usePaging.js.map +1 -0
  71. package/dist/index.d.ts +3 -0
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +8 -2
  74. package/dist/index.js.map +1 -1
  75. package/package.json +6 -4
  76. package/src/components/Button/index.tsx +18 -10
  77. package/src/components/Collection/index.tsx +96 -44
  78. package/src/components/ControlGroup/index.tsx +4 -2
  79. package/src/components/Dropdown/index.tsx +8 -2
  80. package/src/components/Dropdown/list.tsx +7 -1
  81. package/src/components/Menu/item.tsx +16 -2
  82. package/src/components/MultiSelect/index.tsx +1 -1
  83. package/src/components/Paging/index.tsx +232 -0
  84. package/src/components/Paragraph/index.tsx +1 -1
  85. package/src/components/Spinner/index.tsx +11 -3
  86. package/src/components/Tag/index.tsx +9 -7
  87. package/src/constants/colors.ts +5 -1
  88. package/src/constants/paging.ts +48 -0
  89. package/src/constants/theme.ts +8 -7
  90. package/src/containers/ReqoreProvider.tsx +3 -3
  91. package/src/containers/UIProvider.tsx +17 -4
  92. package/src/hooks/useCombinedRefs.ts +2 -2
  93. package/src/hooks/usePaging.ts +110 -0
  94. package/src/index.tsx +3 -0
  95. package/src/mock/collectionData.tsx +19 -0
  96. package/src/mock/tableData.ts +1 -0
  97. package/src/stories/Button/Button.stories.tsx +25 -8
  98. package/src/stories/Collection/Collection.stories.tsx +32 -42
  99. package/src/stories/Dropdown/Dropdown.stories.tsx +24 -1
  100. package/src/stories/Paging/Paging.stories.tsx +184 -0
  101. package/src/stories/Spinner/Spinner.stories.tsx +7 -2
  102. package/src/stories/Tag/Tag.stories.tsx +50 -0
  103. 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['openOnMount'];
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 extends IWithReqoreEffect {
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 vertical={centered} horizontalAlign={centered ? 'center' : undefined}>
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 }) => (!fixed ? '100%' : undefined)};
97
- flex: ${({ fluid, fixed }) => (fixed ? '0 0 auto' : fluid ? '1 auto' : '0 0 auto')};
98
- align-self: ${({ fixed, fluid }) => (fixed ? 'flex-start' : fluid ? 'stretch' : undefined)};
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
@@ -1,9 +1,13 @@
1
- export const Colors = {
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
+ }
@@ -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: '#0E5A8A',
98
- success: '#0A6640',
99
- pending: '#d1a036',
100
- warning: '#A66321',
101
- danger: '#A82A2A',
102
- muted: '#444444',
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: '#333333',
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) => {