@qoretechnologies/reqore 0.34.2 → 0.34.4
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__/button.test.tsx +30 -1
- package/__tests__/containers/paging.test.tsx +1 -1
- package/__tests__/drawer.test.tsx +1 -1
- package/__tests__/heading.test.tsx +58 -0
- package/__tests__/hooks/useReqorePaging.test.tsx +16 -0
- package/__tests__/pagination.test.tsx +104 -3
- package/__tests__/panel.test.tsx +23 -2
- package/dist/components/Button/index.d.ts +3 -1
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +9 -7
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Collection/index.js +1 -2
- 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 +3 -3
- package/dist/components/ControlGroup/index.js.map +1 -1
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Drawer/index.js +3 -10
- package/dist/components/Drawer/index.js.map +1 -1
- package/dist/components/Dropdown/list.js +1 -1
- package/dist/components/Dropdown/list.js.map +1 -1
- package/dist/components/Header/index.d.ts +3 -3
- package/dist/components/Header/index.d.ts.map +1 -1
- package/dist/components/Header/index.js +5 -2
- package/dist/components/Header/index.js.map +1 -1
- package/dist/components/Paging/index.d.ts +2 -1
- package/dist/components/Paging/index.d.ts.map +1 -1
- package/dist/components/Paging/index.js +41 -7
- package/dist/components/Paging/index.js.map +1 -1
- package/dist/components/Panel/NonResponsiveActions.d.ts +18 -0
- package/dist/components/Panel/NonResponsiveActions.d.ts.map +1 -0
- package/dist/components/Panel/NonResponsiveActions.js +47 -0
- package/dist/components/Panel/NonResponsiveActions.js.map +1 -0
- package/dist/components/Panel/index.d.ts +5 -1
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +32 -19
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/components/Tag/group.js +4 -1
- package/dist/components/Tag/group.js.map +1 -1
- package/dist/containers/Paging.d.ts +3 -3
- package/dist/containers/Paging.d.ts.map +1 -1
- package/dist/containers/Paging.js +6 -6
- package/dist/containers/Paging.js.map +1 -1
- package/dist/hooks/usePaging.d.ts +5 -0
- package/dist/hooks/usePaging.d.ts.map +1 -1
- package/dist/hooks/usePaging.js +7 -1
- package/dist/hooks/usePaging.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Button/index.tsx +19 -14
- package/src/components/Collection/index.tsx +2 -2
- package/src/components/ControlGroup/index.tsx +2 -3
- package/src/components/Drawer/index.tsx +4 -10
- package/src/components/Dropdown/list.tsx +1 -1
- package/src/components/Header/index.tsx +9 -3
- package/src/components/Paging/index.tsx +46 -6
- package/src/components/Panel/NonResponsiveActions.tsx +79 -0
- package/src/components/Panel/index.tsx +128 -75
- package/src/components/Tag/group.tsx +1 -1
- package/src/containers/Paging.tsx +83 -37
- package/src/hooks/usePaging.ts +14 -0
- package/src/stories/Drawer/Drawer.stories.tsx +6 -1
- package/src/stories/Dropdown/Dropdown.stories.tsx +1 -0
- package/src/stories/Header/Header.stories.tsx +6 -8
- package/src/stories/Paging/Paging.stories.tsx +22 -2
- package/src/stories/Panel/Panel.stories.tsx +13 -3
- package/tests.json +1 -1
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
IWithReqoreFlat,
|
|
12
12
|
IWithReqoreFluid,
|
|
13
13
|
IWithReqoreMinimal,
|
|
14
|
-
IWithReqoreSize
|
|
14
|
+
IWithReqoreSize,
|
|
15
15
|
} from '../../types/global';
|
|
16
16
|
import { StyledHeader } from '../Header';
|
|
17
17
|
import { StyledParagraph } from '../Paragraph';
|
|
@@ -336,7 +336,6 @@ const ReqoreControlGroup = memo(
|
|
|
336
336
|
|
|
337
337
|
let newProps = {
|
|
338
338
|
...child.props,
|
|
339
|
-
key: child.props.reactKey || child.props.key || index,
|
|
340
339
|
minimal:
|
|
341
340
|
child.props?.minimal || child.props?.minimal === false
|
|
342
341
|
? child.props.minimal
|
|
@@ -430,13 +429,13 @@ const ReqoreControlGroup = memo(
|
|
|
430
429
|
tooltip={{
|
|
431
430
|
content: `Show ${React.Children.count(overflownChildren)} hidden items`,
|
|
432
431
|
}}
|
|
433
|
-
fixed
|
|
434
432
|
active={isOverflownDialogOpen}
|
|
435
433
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
436
434
|
e.stopPropagation();
|
|
437
435
|
setIsOverflownDialogOpen(!isOverflownDialogOpen);
|
|
438
436
|
}}
|
|
439
437
|
flat
|
|
438
|
+
fixed
|
|
440
439
|
/>,
|
|
441
440
|
]
|
|
442
441
|
: children,
|
|
@@ -218,16 +218,6 @@ export const ReqoreDrawer: React.FC<IReqoreDrawerProps> = ({
|
|
|
218
218
|
});
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
/* Adding a close button to the drawer. */
|
|
222
|
-
if (onClose) {
|
|
223
|
-
builtActions.push({
|
|
224
|
-
responsive: false,
|
|
225
|
-
icon: 'CloseLine',
|
|
226
|
-
onClick: onClose,
|
|
227
|
-
className: 'reqore-drawer-close-button',
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
221
|
return builtActions;
|
|
232
222
|
}, [hidable, position, onClose]);
|
|
233
223
|
|
|
@@ -370,6 +360,10 @@ export const ReqoreDrawer: React.FC<IReqoreDrawerProps> = ({
|
|
|
370
360
|
intent={intent}
|
|
371
361
|
rounded={floating || _isModal ? true : false}
|
|
372
362
|
flat={flat}
|
|
363
|
+
onClose={onClose}
|
|
364
|
+
closeButtonProps={{
|
|
365
|
+
className: 'reqore-drawer-close-button',
|
|
366
|
+
}}
|
|
373
367
|
className={`reqore-drawer`}
|
|
374
368
|
style={{
|
|
375
369
|
width: '100%',
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { memo, useMemo } from 'react';
|
|
1
|
+
import { memo, useMemo, useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import { HEADER_SIZE_TO_NUMBER, TSizes } from '../../constants/sizes';
|
|
4
4
|
import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
|
|
5
5
|
import { isStringSize } from '../../helpers/utils';
|
|
6
6
|
import { useReqoreTheme } from '../../hooks/useTheme';
|
|
7
|
-
import {
|
|
7
|
+
import { useTooltip } from '../../hooks/useTooltip';
|
|
8
|
+
import { IWithReqoreEffect, IWithReqoreTooltip } from '../../types/global';
|
|
8
9
|
import { StyledTextEffect } from '../Effect';
|
|
9
10
|
|
|
10
11
|
export interface IReqoreHeadingProps
|
|
11
12
|
extends IWithReqoreEffect,
|
|
13
|
+
IWithReqoreTooltip,
|
|
12
14
|
React.HTMLAttributes<HTMLHeadingElement> {
|
|
13
15
|
intent?: TReqoreIntent;
|
|
14
16
|
size?: 1 | 2 | 3 | 4 | 5 | 6 | TSizes;
|
|
@@ -45,18 +47,22 @@ export const StyledHeader = styled(StyledTextEffect)`
|
|
|
45
47
|
`;
|
|
46
48
|
|
|
47
49
|
export const ReqoreHeading = memo(
|
|
48
|
-
({ size, children, customTheme, intent, className, ...rest }: IReqoreHeadingProps) => {
|
|
50
|
+
({ size, children, customTheme, intent, className, tooltip, ...rest }: IReqoreHeadingProps) => {
|
|
51
|
+
const [ref, setRef] = useState<HTMLHeadingElement>(undefined);
|
|
49
52
|
const theme = useReqoreTheme('main', customTheme, intent);
|
|
50
53
|
const _size: number = isStringSize(size) ? HEADER_SIZE_TO_NUMBER[size] : size;
|
|
51
54
|
const HTMLheaderElement = useMemo(() => {
|
|
52
55
|
return `h${_size}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
53
56
|
}, [_size]);
|
|
54
57
|
|
|
58
|
+
useTooltip(ref, tooltip);
|
|
59
|
+
|
|
55
60
|
return (
|
|
56
61
|
<StyledHeader
|
|
57
62
|
as={HTMLheaderElement}
|
|
58
63
|
theme={theme}
|
|
59
64
|
intent={intent}
|
|
65
|
+
ref={setRef}
|
|
60
66
|
{...rest}
|
|
61
67
|
_size={_size}
|
|
62
68
|
className={`${className || ''} reqore-heading`}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { debounce } from 'lodash';
|
|
1
2
|
import { memo, useEffect, useRef, useState } from 'react';
|
|
2
3
|
import { useUnmount, useUpdateEffect } from 'react-use';
|
|
3
4
|
import styled from 'styled-components';
|
|
@@ -27,6 +28,7 @@ export interface IReqorePaginationComponentProps
|
|
|
27
28
|
showLabels?: boolean;
|
|
28
29
|
scrollOnLoadMore?: boolean;
|
|
29
30
|
autoLoadMore?: boolean;
|
|
31
|
+
changePageOnScroll?: 'vertical' | 'horizontal';
|
|
30
32
|
scrollContainer?: HTMLElement;
|
|
31
33
|
scrollToTopOnPageChange?: boolean;
|
|
32
34
|
}
|
|
@@ -79,24 +81,29 @@ function Pagination<T>({
|
|
|
79
81
|
renderControls,
|
|
80
82
|
scrollContainer,
|
|
81
83
|
scrollToTopOnPageChange = true,
|
|
84
|
+
changePageOnScroll,
|
|
82
85
|
...rest
|
|
83
86
|
}: IReqorePaginationProps<T>) {
|
|
84
87
|
const [loadMoreRef, setLoadMoreRef] = useState<HTMLButtonElement>(undefined);
|
|
85
88
|
const [scrollTargetRef, setScrollTargetRef] = useState<HTMLDivElement>(undefined);
|
|
86
89
|
const observer = useRef<IntersectionObserver>(null);
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
useUpdateEffect(() => {
|
|
92
|
+
// If scroll container is defined, do not scroll to load more button
|
|
93
|
+
// because it will be scrolled to the bottom of the container
|
|
94
|
+
// resulting in infinite scroll
|
|
95
|
+
if (!scrollContainer && scrollTargetRef && scrollOnLoadMore && !isLastPage && !isFirstPage) {
|
|
90
96
|
scrollTargetRef.scrollIntoView({
|
|
91
97
|
behavior: 'smooth',
|
|
92
98
|
block: 'end',
|
|
93
|
-
inline: '
|
|
99
|
+
inline: 'start',
|
|
94
100
|
});
|
|
95
101
|
}
|
|
96
|
-
}, [currentPage, scrollTargetRef, scrollOnLoadMore, isLastPage, isFirstPage]);
|
|
102
|
+
}, [currentPage, scrollTargetRef, scrollContainer, scrollOnLoadMore, isLastPage, isFirstPage]);
|
|
97
103
|
|
|
98
104
|
// Scroll to bottom on load more
|
|
99
|
-
|
|
105
|
+
// Scroll container has power over scroll target
|
|
106
|
+
useUpdateEffect(() => {
|
|
100
107
|
if (scrollContainer && scrollOnLoadMore && !isFirstPage) {
|
|
101
108
|
scrollContainer.scrollBy?.({
|
|
102
109
|
top: scrollContainer.scrollHeight,
|
|
@@ -106,7 +113,7 @@ function Pagination<T>({
|
|
|
106
113
|
}, [currentPage, scrollContainer, scrollOnLoadMore, isFirstPage]);
|
|
107
114
|
|
|
108
115
|
// Scroll to top on page change
|
|
109
|
-
|
|
116
|
+
useUpdateEffect(() => {
|
|
110
117
|
if (scrollContainer && scrollToTopOnPageChange && !infinite) {
|
|
111
118
|
scrollContainer.scrollTo?.({
|
|
112
119
|
top: 0,
|
|
@@ -115,6 +122,39 @@ function Pagination<T>({
|
|
|
115
122
|
}
|
|
116
123
|
}, [currentPage, scrollContainer, scrollToTopOnPageChange, infinite]);
|
|
117
124
|
|
|
125
|
+
// Switch pages when user scrolls and holds the Shift key
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
const handleScroll = debounce((e: WheelEvent) => {
|
|
128
|
+
const deltaKey = changePageOnScroll === 'vertical' ? 'deltaY' : 'deltaX';
|
|
129
|
+
// Only change pages when user holds the shift key
|
|
130
|
+
// aka horizontal scroll
|
|
131
|
+
if (
|
|
132
|
+
changePageOnScroll === 'vertical' ||
|
|
133
|
+
(changePageOnScroll === 'horizontal' && e.shiftKey)
|
|
134
|
+
) {
|
|
135
|
+
// Do not horizontal scroll
|
|
136
|
+
e.preventDefault();
|
|
137
|
+
// If the user scrolls to the right, go to the next page
|
|
138
|
+
if (e[deltaKey] > 20) {
|
|
139
|
+
next();
|
|
140
|
+
// If the user scrolls to the left, go to the previous page
|
|
141
|
+
} else if (e[deltaKey] < -20) {
|
|
142
|
+
back();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, 30);
|
|
146
|
+
|
|
147
|
+
if (scrollContainer && changePageOnScroll) {
|
|
148
|
+
scrollContainer.addEventListener('wheel', handleScroll);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return () => {
|
|
152
|
+
if (scrollContainer) {
|
|
153
|
+
scrollContainer.removeEventListener('wheel', handleScroll);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}, [currentPage, scrollContainer, changePageOnScroll]);
|
|
157
|
+
|
|
118
158
|
useUpdateEffect(() => {
|
|
119
159
|
if (loadMoreRef && autoLoadMore) {
|
|
120
160
|
observer.current = new IntersectionObserver(
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { size } from 'lodash';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { IReqorePanelProps } from '.';
|
|
4
|
+
import { ReqoreButton } from '../..';
|
|
5
|
+
import { IWithReqoreCustomTheme } from '../../types/global';
|
|
6
|
+
import ReqoreControlGroup, { IReqoreControlGroupProps } from '../ControlGroup';
|
|
7
|
+
|
|
8
|
+
export interface IReqorePanelNonResponsiveActionsProps
|
|
9
|
+
extends IWithReqoreCustomTheme,
|
|
10
|
+
Omit<IReqoreControlGroupProps, 'children'> {
|
|
11
|
+
onCollapseClick?: () => void;
|
|
12
|
+
onCloseClick?: () => void;
|
|
13
|
+
hasResponsiveActions?: boolean;
|
|
14
|
+
isCollapsed?: boolean;
|
|
15
|
+
showControlButtons?: boolean;
|
|
16
|
+
show?: boolean;
|
|
17
|
+
children?: IReqoreControlGroupProps['children'] | undefined;
|
|
18
|
+
closeButtonProps?: IReqorePanelProps['closeButtonProps'];
|
|
19
|
+
collapseButtonProps?: IReqorePanelProps['collapseButtonProps'];
|
|
20
|
+
isSmall: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const ReqorePanelNonResponsiveActions = memo(
|
|
24
|
+
({
|
|
25
|
+
onCollapseClick,
|
|
26
|
+
onCloseClick,
|
|
27
|
+
hasResponsiveActions,
|
|
28
|
+
isCollapsed,
|
|
29
|
+
customTheme,
|
|
30
|
+
children,
|
|
31
|
+
showControlButtons,
|
|
32
|
+
show,
|
|
33
|
+
collapseButtonProps,
|
|
34
|
+
closeButtonProps,
|
|
35
|
+
isSmall,
|
|
36
|
+
...rest
|
|
37
|
+
}: IReqorePanelNonResponsiveActionsProps) => {
|
|
38
|
+
if (!show || (!size(children) && !showControlButtons)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<ReqoreControlGroup
|
|
44
|
+
fixed={isSmall ? false : hasResponsiveActions}
|
|
45
|
+
fluid={isSmall ? true : !hasResponsiveActions}
|
|
46
|
+
horizontalAlign='flex-end'
|
|
47
|
+
{...rest}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
{!!onCollapseClick && showControlButtons ? (
|
|
51
|
+
<ReqoreButton
|
|
52
|
+
customTheme={customTheme}
|
|
53
|
+
icon={isCollapsed ? 'ArrowDownSLine' : 'ArrowUpSLine'}
|
|
54
|
+
onClick={(e) => {
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
onCollapseClick();
|
|
57
|
+
}}
|
|
58
|
+
tooltip={isCollapsed ? 'Expand' : 'Collapse'}
|
|
59
|
+
fixed
|
|
60
|
+
{...collapseButtonProps}
|
|
61
|
+
/>
|
|
62
|
+
) : null}
|
|
63
|
+
{!!onCloseClick && showControlButtons ? (
|
|
64
|
+
<ReqoreButton
|
|
65
|
+
fixed
|
|
66
|
+
customTheme={customTheme}
|
|
67
|
+
icon='CloseLine'
|
|
68
|
+
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
onCloseClick();
|
|
71
|
+
}}
|
|
72
|
+
tooltip='Close'
|
|
73
|
+
{...closeButtonProps}
|
|
74
|
+
/>
|
|
75
|
+
) : null}
|
|
76
|
+
</ReqoreControlGroup>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { size } from 'lodash';
|
|
2
2
|
import { darken, rgba } from 'polished';
|
|
3
|
-
import {
|
|
4
|
-
import { useUpdateEffect } from 'react-use';
|
|
3
|
+
import { forwardRef, ReactElement, useCallback, useMemo, useState } from 'react';
|
|
4
|
+
import { useMeasure, useUpdateEffect } from 'react-use';
|
|
5
5
|
import styled, { css } from 'styled-components';
|
|
6
6
|
import {
|
|
7
7
|
GAP_FROM_SIZE,
|
|
@@ -41,8 +41,9 @@ import ReqoreControlGroup from '../ControlGroup';
|
|
|
41
41
|
import ReqoreDropdown from '../Dropdown';
|
|
42
42
|
import { IReqoreDropdownItem } from '../Dropdown/list';
|
|
43
43
|
import { IReqoreEffect, StyledEffect, TReqoreEffectColor } from '../Effect';
|
|
44
|
-
import { ReqoreHeading } from '../Header';
|
|
44
|
+
import { ReqoreHeading, StyledHeader } from '../Header';
|
|
45
45
|
import ReqoreIcon, { IReqoreIconProps, StyledIconWrapper } from '../Icon';
|
|
46
|
+
import { ReqorePanelNonResponsiveActions } from './NonResponsiveActions';
|
|
46
47
|
|
|
47
48
|
export interface IReqorePanelAction extends IReqoreButtonProps, IWithReqoreTooltip, IReqoreIntent {
|
|
48
49
|
label?: string | number;
|
|
@@ -83,7 +84,11 @@ export interface IReqorePanelProps
|
|
|
83
84
|
badge?: TReqoreBadge | TReqoreBadge[];
|
|
84
85
|
collapsible?: boolean;
|
|
85
86
|
isCollapsed?: boolean;
|
|
87
|
+
collapseButtonProps?: IReqoreButtonProps;
|
|
88
|
+
|
|
86
89
|
onClose?: () => void;
|
|
90
|
+
closeButtonProps?: IReqoreButtonProps;
|
|
91
|
+
|
|
87
92
|
rounded?: boolean;
|
|
88
93
|
actions?: TReqorePanelActions;
|
|
89
94
|
bottomActions?: TReqorePanelBottomActions;
|
|
@@ -104,6 +109,8 @@ export interface IReqorePanelProps
|
|
|
104
109
|
responsiveActions?: boolean;
|
|
105
110
|
responsiveTitle?: boolean;
|
|
106
111
|
getContentRef?: (ref: HTMLDivElement) => any;
|
|
112
|
+
|
|
113
|
+
headerProps?: React.HTMLAttributes<unknown>;
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
export interface IStyledPanel extends IReqorePanelProps {
|
|
@@ -111,6 +118,40 @@ export interface IStyledPanel extends IReqorePanelProps {
|
|
|
111
118
|
noHorizontalPadding?: boolean;
|
|
112
119
|
}
|
|
113
120
|
|
|
121
|
+
export const StyledPanelTitleHeader = styled.div`
|
|
122
|
+
display: flex;
|
|
123
|
+
justify-content: flex-start;
|
|
124
|
+
align-items: center;
|
|
125
|
+
flex: 1 1 auto;
|
|
126
|
+
width: 100%;
|
|
127
|
+
overflow: hidden;
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
export const StyledPanelTitleHeaderContent = styled.div`
|
|
131
|
+
display: flex;
|
|
132
|
+
justify-content: flex-start;
|
|
133
|
+
align-items: center;
|
|
134
|
+
flex: 0 1 auto;
|
|
135
|
+
overflow: hidden;
|
|
136
|
+
min-width: ${({ iconSize, hasLabel, hasIcon }) => {
|
|
137
|
+
let width = 0;
|
|
138
|
+
|
|
139
|
+
if (hasIcon) {
|
|
140
|
+
width += iconSize;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (hasLabel) {
|
|
144
|
+
width += 50;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return width;
|
|
148
|
+
}}px;
|
|
149
|
+
|
|
150
|
+
${StyledHeader} {
|
|
151
|
+
min-width: 50px;
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
|
|
114
155
|
export const StyledPanel = styled(StyledEffect)<IStyledPanel>`
|
|
115
156
|
background-color: ${({ theme, opacity = 1 }: IStyledPanel) =>
|
|
116
157
|
rgba(changeDarkness(getMainBackgroundColor(theme), 0.03), opacity)};
|
|
@@ -139,7 +180,7 @@ export const StyledPanel = styled(StyledEffect)<IStyledPanel>`
|
|
|
139
180
|
cursor: pointer;
|
|
140
181
|
|
|
141
182
|
&:hover {
|
|
142
|
-
${StyledPanelTitle}
|
|
183
|
+
${StyledPanelTitle} ${StyledPanelTitleHeaderContent} > ${StyledIconWrapper} {
|
|
143
184
|
transform: scale(${ACTIVE_ICON_SCALE});
|
|
144
185
|
}
|
|
145
186
|
|
|
@@ -206,7 +247,7 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
|
|
|
206
247
|
flex: 0 0 auto;
|
|
207
248
|
gap: ${GAP_FROM_SIZE.normal}px;
|
|
208
249
|
|
|
209
|
-
|
|
250
|
+
${StyledPanelTitleHeaderContent} > ${StyledIconWrapper} {
|
|
210
251
|
transform: scale(${INACTIVE_ICON_SCALE});
|
|
211
252
|
}
|
|
212
253
|
|
|
@@ -215,7 +256,7 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
|
|
|
215
256
|
css`
|
|
216
257
|
cursor: pointer;
|
|
217
258
|
&:hover {
|
|
218
|
-
|
|
259
|
+
${StyledPanelTitleHeaderContent} > ${StyledIconWrapper} {
|
|
219
260
|
transform: scale(${ACTIVE_ICON_SCALE});
|
|
220
261
|
}
|
|
221
262
|
|
|
@@ -255,23 +296,15 @@ export const StyledPanelContent = styled.div<IStyledPanel>`
|
|
|
255
296
|
font-size: ${({ size }) => TEXT_FROM_SIZE[size]}px;
|
|
256
297
|
`;
|
|
257
298
|
|
|
258
|
-
export const StyledPanelTitleHeader = styled.div`
|
|
259
|
-
display: flex;
|
|
260
|
-
justify-content: flex-start;
|
|
261
|
-
align-items: center;
|
|
262
|
-
flex: 1 1 auto;
|
|
263
|
-
width: 100%;
|
|
264
|
-
overflow: hidden;
|
|
265
|
-
min-width: 100px;
|
|
266
|
-
`;
|
|
267
|
-
|
|
268
299
|
export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
269
300
|
(
|
|
270
301
|
{
|
|
271
302
|
children,
|
|
272
303
|
label,
|
|
304
|
+
collapseButtonProps = {},
|
|
273
305
|
collapsible,
|
|
274
306
|
onClose,
|
|
307
|
+
closeButtonProps = {},
|
|
275
308
|
rounded = true,
|
|
276
309
|
actions = [],
|
|
277
310
|
bottomActions = [],
|
|
@@ -300,6 +333,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
300
333
|
responsiveTitle = true,
|
|
301
334
|
size: panelSize = 'normal',
|
|
302
335
|
getContentRef,
|
|
336
|
+
headerProps = {},
|
|
303
337
|
...rest
|
|
304
338
|
}: IReqorePanelProps,
|
|
305
339
|
ref
|
|
@@ -315,6 +349,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
315
349
|
const isMobile = useReqoreProperty('isMobile');
|
|
316
350
|
const { targetRef } = useCombinedRefs(ref);
|
|
317
351
|
const [itemRef, setItemRef] = useState<HTMLDivElement>(undefined);
|
|
352
|
+
const [measureRef, { width }] = useMeasure();
|
|
318
353
|
|
|
319
354
|
useTooltip(itemRef, tooltip);
|
|
320
355
|
|
|
@@ -340,6 +375,8 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
340
375
|
[label, icon, badge]
|
|
341
376
|
);
|
|
342
377
|
|
|
378
|
+
const isSmall = useMemo(() => width < 480 && process.env.NODE_ENV !== 'test', [width]);
|
|
379
|
+
|
|
343
380
|
// If collapsible is true, toggle the isCollapsed state
|
|
344
381
|
// If the isCollapsed state is true, the component is expanded
|
|
345
382
|
// If the isCollapsed state is false, the component is collapsed
|
|
@@ -557,51 +594,80 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
557
594
|
opacity={opacity ?? (minimal ? 0 : 1)}
|
|
558
595
|
noHorizontalPadding={noHorizontalPadding}
|
|
559
596
|
responsive={responsiveTitle}
|
|
560
|
-
isMobile={isMobile}
|
|
597
|
+
isMobile={isMobile || isSmall}
|
|
598
|
+
ref={measureRef}
|
|
561
599
|
>
|
|
562
600
|
{hasTitleHeader && (
|
|
563
601
|
<StyledPanelTitleHeader>
|
|
564
|
-
{icon || iconImage ? (
|
|
565
|
-
<
|
|
566
|
-
size={
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
margin='right'
|
|
572
|
-
color={iconColor}
|
|
573
|
-
{...iconProps}
|
|
574
|
-
/>
|
|
575
|
-
) : null}
|
|
576
|
-
{typeof label === 'string' ? (
|
|
577
|
-
<ReqoreHeading
|
|
578
|
-
size={headerSize || panelSize}
|
|
579
|
-
customTheme={theme}
|
|
580
|
-
effect={{
|
|
581
|
-
noWrap: true,
|
|
582
|
-
...headerEffect,
|
|
583
|
-
}}
|
|
602
|
+
{icon || iconImage || label ? (
|
|
603
|
+
<StyledPanelTitleHeaderContent
|
|
604
|
+
size={panelSize}
|
|
605
|
+
{...headerProps}
|
|
606
|
+
hasLabel={!!label}
|
|
607
|
+
hasIcon={!!icon || !!iconImage}
|
|
608
|
+
iconSize={ICON_FROM_HEADER_SIZE[headerSize || HEADER_SIZE_TO_NUMBER[panelSize]]}
|
|
584
609
|
>
|
|
585
|
-
{
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
610
|
+
{icon || iconImage ? (
|
|
611
|
+
<ReqoreIcon
|
|
612
|
+
size={`${
|
|
613
|
+
ICON_FROM_HEADER_SIZE[headerSize || HEADER_SIZE_TO_NUMBER[panelSize]]
|
|
614
|
+
}px`}
|
|
615
|
+
icon={icon}
|
|
616
|
+
image={iconImage}
|
|
617
|
+
margin='right'
|
|
618
|
+
color={iconColor}
|
|
619
|
+
tooltip={{
|
|
620
|
+
content: label,
|
|
621
|
+
}}
|
|
622
|
+
{...iconProps}
|
|
623
|
+
/>
|
|
624
|
+
) : null}
|
|
625
|
+
{typeof label === 'string' ? (
|
|
626
|
+
<ReqoreHeading
|
|
627
|
+
size={headerSize || panelSize}
|
|
628
|
+
customTheme={theme}
|
|
629
|
+
effect={{
|
|
630
|
+
noWrap: true,
|
|
631
|
+
...headerEffect,
|
|
632
|
+
}}
|
|
633
|
+
tooltip={label}
|
|
634
|
+
>
|
|
635
|
+
{label}
|
|
636
|
+
</ReqoreHeading>
|
|
637
|
+
) : (
|
|
638
|
+
label
|
|
639
|
+
)}
|
|
640
|
+
</StyledPanelTitleHeaderContent>
|
|
641
|
+
) : null}
|
|
590
642
|
{badge || badge === 0 ? (
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
</>
|
|
643
|
+
<ButtonBadge
|
|
644
|
+
color={changeLightness(theme.main, 0.18)}
|
|
645
|
+
size={getOneHigherSize(panelSize)}
|
|
646
|
+
content={badge}
|
|
647
|
+
wrapGroup={isSmall}
|
|
648
|
+
/>
|
|
598
649
|
) : null}
|
|
650
|
+
<ReqorePanelNonResponsiveActions
|
|
651
|
+
show={isSmall}
|
|
652
|
+
isSmall={isSmall}
|
|
653
|
+
showControlButtons
|
|
654
|
+
size={panelSize}
|
|
655
|
+
hasResponsiveActions={hasResponsiveActions(actions)}
|
|
656
|
+
customTheme={theme}
|
|
657
|
+
isCollapsed={_isCollapsed}
|
|
658
|
+
onCollapseClick={collapsible ? handleCollapseClick : undefined}
|
|
659
|
+
onCloseClick={onClose}
|
|
660
|
+
closeButtonProps={closeButtonProps}
|
|
661
|
+
collapseButtonProps={collapseButtonProps}
|
|
662
|
+
fluid={false}
|
|
663
|
+
style={{ marginLeft: 'auto' }}
|
|
664
|
+
/>
|
|
599
665
|
</StyledPanelTitleHeader>
|
|
600
666
|
)}
|
|
601
667
|
{hasResponsiveActions(actions) && (
|
|
602
668
|
<ReqoreControlGroup
|
|
603
669
|
responsive={responsiveActions}
|
|
604
|
-
fluid={responsiveActions ||
|
|
670
|
+
fluid={responsiveActions || isSmall}
|
|
605
671
|
horizontalAlign='flex-end'
|
|
606
672
|
customTheme={theme}
|
|
607
673
|
size={panelSize}
|
|
@@ -611,34 +677,21 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
611
677
|
)}
|
|
612
678
|
{collapsible || onClose || hasNonResponsiveActions(actions) ? (
|
|
613
679
|
<>
|
|
614
|
-
<
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
680
|
+
<ReqorePanelNonResponsiveActions
|
|
681
|
+
show
|
|
682
|
+
isSmall={isSmall}
|
|
683
|
+
showControlButtons={!isSmall}
|
|
618
684
|
size={panelSize}
|
|
685
|
+
hasResponsiveActions={hasResponsiveActions(actions)}
|
|
686
|
+
customTheme={theme}
|
|
687
|
+
isCollapsed={_isCollapsed}
|
|
688
|
+
onCollapseClick={collapsible ? handleCollapseClick : undefined}
|
|
689
|
+
onCloseClick={onClose}
|
|
690
|
+
closeButtonProps={closeButtonProps}
|
|
691
|
+
collapseButtonProps={collapseButtonProps}
|
|
619
692
|
>
|
|
620
693
|
{actions.map(renderNonResponsiveActions())}
|
|
621
|
-
|
|
622
|
-
<ReqoreButton
|
|
623
|
-
customTheme={theme}
|
|
624
|
-
icon={_isCollapsed ? 'ArrowDownSLine' : 'ArrowUpSLine'}
|
|
625
|
-
onClick={handleCollapseClick}
|
|
626
|
-
tooltip={_isCollapsed ? 'Expand' : 'Collapse'}
|
|
627
|
-
fixed
|
|
628
|
-
/>
|
|
629
|
-
)}
|
|
630
|
-
{onClose && (
|
|
631
|
-
<ReqoreButton
|
|
632
|
-
fixed
|
|
633
|
-
customTheme={theme}
|
|
634
|
-
icon='CloseLine'
|
|
635
|
-
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
636
|
-
e.stopPropagation();
|
|
637
|
-
onClose?.();
|
|
638
|
-
}}
|
|
639
|
-
/>
|
|
640
|
-
)}
|
|
641
|
-
</ReqoreControlGroup>
|
|
694
|
+
</ReqorePanelNonResponsiveActions>
|
|
642
695
|
</>
|
|
643
696
|
) : null}
|
|
644
697
|
</StyledPanelTitle>
|
|
@@ -14,7 +14,7 @@ export interface IReqoreTagGroup
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const StyledTagGroup = styled.div`
|
|
17
|
-
flex-shrink: 0;
|
|
17
|
+
flex-shrink: ${({ wrap }: IReqoreTagGroup) => (wrap ? 1 : 0)};
|
|
18
18
|
display: flex;
|
|
19
19
|
flex-wrap: ${({ wrap }: IReqoreTagGroup) => (wrap ? 'wrap' : 'nowrap')};
|
|
20
20
|
gap: ${({ gapSize }: IReqoreTagGroup) => GAP_FROM_SIZE[gapSize]}px;
|