sbwb-ds 3.1.11 → 3.1.13
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/dist/sbwb-ds.js +4256 -4247
- package/dist/sbwb-ds.umd.cjs +152 -155
- package/dist/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/index.d.ts +8 -0
- package/dist/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/styles.d.ts +9 -0
- package/dist/src/presentation/components/atoms/FloatingButton/index.d.ts +8 -0
- package/dist/src/presentation/components/atoms/FloatingButton/styles.d.ts +5 -0
- package/dist/src/presentation/components/atoms/Tooltip/index.d.ts +3 -1
- package/dist/src/presentation/components/molecules/PopConfirm/index.d.ts +18 -0
- package/dist/src/presentation/components/molecules/PopConfirm/styles.d.ts +22 -0
- package/dist/src/presentation/components/molecules/SegmentedButton/index.d.ts +11 -0
- package/dist/src/presentation/components/molecules/SegmentedButton/styles.d.ts +13 -0
- package/package.json +2 -1
- package/src/presentation/components/atoms/ActionButton/styles.ts +1 -1
- package/src/presentation/components/atoms/Button/Button.stories.tsx +0 -1
- package/src/presentation/components/atoms/Button/styles.ts +1 -4
- package/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/index.tsx +29 -0
- package/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/styles.ts +59 -0
- package/src/presentation/components/atoms/FloatingButton/FloatingButton.stories.tsx +64 -0
- package/src/presentation/components/atoms/FloatingButton/index.tsx +78 -0
- package/src/presentation/components/atoms/FloatingButton/styles.ts +22 -0
- package/src/presentation/components/atoms/Tooltip/index.tsx +57 -50
- package/src/presentation/components/molecules/PopConfirm/PopConfirm.stories.tsx +72 -0
- package/src/presentation/components/molecules/PopConfirm/index.tsx +164 -0
- package/src/presentation/components/molecules/PopConfirm/styles.ts +126 -0
- package/src/presentation/components/molecules/SegmentedButton/SegmentedButton.stories.tsx +78 -0
- package/src/presentation/components/molecules/SegmentedButton/index.tsx +47 -0
- package/src/presentation/components/molecules/SegmentedButton/styles.ts +71 -0
package/dist/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface FloatingMenuProps {
|
|
3
|
+
refButton: React.RefObject<HTMLDivElement>;
|
|
4
|
+
floatingMenuPosition?: 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
listItems?: React.ReactNode[];
|
|
6
|
+
}
|
|
7
|
+
declare const FloatingMenu: ({ floatingMenuPosition, listItems, }: FloatingMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default FloatingMenu;
|
package/dist/src/presentation/components/atoms/FloatingButton/Components/FloatingMenu/styles.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface FloatingMenuProps {
|
|
2
|
+
floatingMenuPostion?: 'top' | 'bottom' | 'left' | 'right';
|
|
3
|
+
}
|
|
4
|
+
export declare const FloatingMenuContainer: import("styled-components").StyledComponent<"div", any, FloatingMenuProps, never>;
|
|
5
|
+
interface ItemWrapperProps {
|
|
6
|
+
index?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const ItemWrapper: import("styled-components").StyledComponent<"div", any, ItemWrapperProps, never>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface FloatingButtonProps {
|
|
3
|
+
readonly children?: React.ReactNode;
|
|
4
|
+
readonly refButton: React.RefObject<HTMLDivElement>;
|
|
5
|
+
readonly floatingMenuPosition?: 'top' | 'bottom' | 'left' | 'right';
|
|
6
|
+
listItems?: React.ReactNode[];
|
|
7
|
+
}
|
|
8
|
+
export default function FloatingButton({ refButton, children, floatingMenuPosition, listItems, }: FloatingButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -20,6 +20,8 @@ export interface TooltipProps {
|
|
|
20
20
|
tooltipMargin?: string;
|
|
21
21
|
wrapperStyles?: React.CSSProperties;
|
|
22
22
|
zIndex?: number;
|
|
23
|
+
hideOnScroll?: boolean;
|
|
24
|
+
interactive?: boolean;
|
|
23
25
|
}
|
|
24
|
-
declare const Tooltip: ({ id, children, label, position, size, customStyle, errorTooltip, successTooltip, isActive, isAlwaysVisible, width, height, maxWidth, arrow, color, wrapperWidth, wrapperHeight, tooltipMargin, wrapperStyles, zIndex, }: TooltipProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
declare const Tooltip: ({ id, children, label, position, size, customStyle, errorTooltip, successTooltip, isActive, isAlwaysVisible, width, height, maxWidth, arrow, color, wrapperWidth, wrapperHeight, tooltipMargin, wrapperStyles, zIndex, hideOnScroll, interactive, }: TooltipProps) => import("react/jsx-runtime").JSX.Element;
|
|
25
27
|
export default Tooltip;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface PopConfirmProps {
|
|
3
|
+
id?: string;
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
type: 'danger' | 'success' | 'warning';
|
|
6
|
+
title: string;
|
|
7
|
+
text?: string;
|
|
8
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
9
|
+
isActive?: boolean;
|
|
10
|
+
popConfirmMargin?: string;
|
|
11
|
+
wrapperWidth?: string;
|
|
12
|
+
wrapperHeight?: string;
|
|
13
|
+
wrapperStyles?: React.CSSProperties;
|
|
14
|
+
onClickConfirm?: () => void;
|
|
15
|
+
onClickCancel?: () => void;
|
|
16
|
+
}
|
|
17
|
+
declare const PopConfirm: ({ id, children, type, title, text, position, isActive, popConfirmMargin, wrapperWidth, wrapperHeight, wrapperStyles, onClickConfirm, onClickCancel, }: PopConfirmProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export default PopConfirm;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface PopConfirmWrapperProps {
|
|
2
|
+
wrapperWidth?: string;
|
|
3
|
+
wrapperHeight?: string;
|
|
4
|
+
wrapperStyles?: any;
|
|
5
|
+
}
|
|
6
|
+
export declare const PopConfirmWrapper: import("styled-components").StyledComponent<"div", any, PopConfirmWrapperProps, never>;
|
|
7
|
+
interface PopConfirmContainerProps {
|
|
8
|
+
height?: string;
|
|
9
|
+
width?: string;
|
|
10
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
11
|
+
}
|
|
12
|
+
export declare const PopconfirmContainer: import("styled-components").StyledComponent<"div", any, PopConfirmContainerProps, never>;
|
|
13
|
+
export declare const Header: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
14
|
+
export declare const Title: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
15
|
+
export declare const Content: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
16
|
+
export declare const Footer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
17
|
+
interface SpacingProps {
|
|
18
|
+
height?: string;
|
|
19
|
+
width?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const Spacing: import("styled-components").StyledComponent<"div", any, SpacingProps, never>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IconProps } from '../../atoms/Icon';
|
|
2
|
+
export interface SegmentedButtonProps {
|
|
3
|
+
buttons: {
|
|
4
|
+
label: string;
|
|
5
|
+
iconName?: IconProps['iconName'];
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
declare const SegmentedButton: ({ buttons }: SegmentedButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export default SegmentedButton;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const Container: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
2
|
+
interface BaseButtonContainerProps {
|
|
3
|
+
active?: boolean;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const BaseButtonContainer: import("styled-components").StyledComponent<"div", any, BaseButtonContainerProps, never>;
|
|
7
|
+
export declare const BaseButton: import("styled-components").StyledComponent<"button", any, {}, never>;
|
|
8
|
+
interface SpaceProps {
|
|
9
|
+
width: string;
|
|
10
|
+
height?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const Space: import("styled-components").StyledComponent<"div", any, SpaceProps, never>;
|
|
13
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sbwb-ds",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Sistema de design para padronização dos processos visuais do portal SUBWEB",
|
|
6
6
|
"main": "dist/sbwb-ds.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"color": "^4.2.3",
|
|
33
33
|
"dotenv": "^16.0.3",
|
|
34
34
|
"echarts": "^5.5.0",
|
|
35
|
+
"framer-motion": "^12.6.2",
|
|
35
36
|
"jest": "^29.7.0",
|
|
36
37
|
"jest-environment-jsdom": "^29.7.0",
|
|
37
38
|
"jest-transform-stub": "^2.0.0",
|
|
@@ -86,7 +86,7 @@ const defaultStateStyles = css<ActionButtonStyleProps>`
|
|
|
86
86
|
!isSelected &&
|
|
87
87
|
css`
|
|
88
88
|
background-color: ${buttonType === 'primary'
|
|
89
|
-
?
|
|
89
|
+
? sg.colors.backgroundColors.colorBackgroundGrass
|
|
90
90
|
: 'transparent'};
|
|
91
91
|
border: ${buttonType === 'primary'
|
|
92
92
|
? `${sg.borders.borderWidth.borderWidthThinner} solid ${sg.colors.neutralColors.colorNeutralClean}`
|
|
@@ -54,10 +54,7 @@ export const Button = styled.button<ButtonProps>`
|
|
|
54
54
|
`;
|
|
55
55
|
} else if (variant === 'secondary') {
|
|
56
56
|
return css`
|
|
57
|
-
background-color:
|
|
58
|
-
${convertHexToRGB(sg.colors.neutralColors.colorNeutralSoft)},
|
|
59
|
-
${sg.opacityLevels.light}
|
|
60
|
-
);
|
|
57
|
+
background-color: ${sg.colors.backgroundColors.colorBackgroundGrass};
|
|
61
58
|
color: ${sg.colors.neutralColors.colorNeutralDark};
|
|
62
59
|
border: 1px solid ${sg.colors.neutralColors.colorNeutralClean};
|
|
63
60
|
transition: filter 0.2s;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import * as C from './styles';
|
|
3
|
+
import { sg } from '../../../../../styles';
|
|
4
|
+
|
|
5
|
+
export interface FloatingMenuProps {
|
|
6
|
+
refButton: React.RefObject<HTMLDivElement>;
|
|
7
|
+
floatingMenuPosition?: 'top' | 'bottom' | 'left' | 'right';
|
|
8
|
+
listItems?: React.ReactNode[];
|
|
9
|
+
}
|
|
10
|
+
const FloatingMenu = ({
|
|
11
|
+
floatingMenuPosition,
|
|
12
|
+
listItems,
|
|
13
|
+
}: FloatingMenuProps) => {
|
|
14
|
+
const menuRef = useRef<HTMLDivElement>(null);
|
|
15
|
+
return (
|
|
16
|
+
<C.FloatingMenuContainer
|
|
17
|
+
ref={menuRef}
|
|
18
|
+
floatingMenuPostion={floatingMenuPosition}
|
|
19
|
+
>
|
|
20
|
+
{listItems?.map((item, index) => (
|
|
21
|
+
<C.ItemWrapper key={index} index={index}>
|
|
22
|
+
{item}
|
|
23
|
+
</C.ItemWrapper>
|
|
24
|
+
))}
|
|
25
|
+
</C.FloatingMenuContainer>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default FloatingMenu;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { sg } from '../../../../../styles';
|
|
3
|
+
|
|
4
|
+
interface FloatingMenuProps {
|
|
5
|
+
floatingMenuPostion?: 'top' | 'bottom' | 'left' | 'right';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const props = (floatingMenuPostion) => {
|
|
9
|
+
switch (floatingMenuPostion) {
|
|
10
|
+
case 'top':
|
|
11
|
+
return {
|
|
12
|
+
bottom: '100%',
|
|
13
|
+
marginBottom: sg.spacings.spacingInset.spacingInsetSm,
|
|
14
|
+
};
|
|
15
|
+
case 'left':
|
|
16
|
+
return {
|
|
17
|
+
right: '100%',
|
|
18
|
+
marginRight: sg.spacings.spacingInset.spacingInsetSm,
|
|
19
|
+
bottom: '0',
|
|
20
|
+
};
|
|
21
|
+
case 'right':
|
|
22
|
+
return {
|
|
23
|
+
left: '100%',
|
|
24
|
+
marginLeft: sg.spacings.spacingInset.spacingInsetSm,
|
|
25
|
+
bottom: '0',
|
|
26
|
+
};
|
|
27
|
+
default:
|
|
28
|
+
case 'bottom':
|
|
29
|
+
return {
|
|
30
|
+
top: '100%',
|
|
31
|
+
marginTop: sg.spacings.spacingInset.spacingInsetSm,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
export const FloatingMenuContainer = styled.div<FloatingMenuProps>`
|
|
36
|
+
position: absolute;
|
|
37
|
+
display: flex;
|
|
38
|
+
height: fit-content;
|
|
39
|
+
padding: ${sg.spacings.spacingInset.spacingInsetSm};
|
|
40
|
+
justify-content: center;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
align-items: center;
|
|
43
|
+
z-index: 1000;
|
|
44
|
+
transition: all 0.3s ease-in-out;
|
|
45
|
+
transform: translateY(0);
|
|
46
|
+
opacity: 1;
|
|
47
|
+
pointer-events: auto;
|
|
48
|
+
border-radius: ${sg.borders.borderRadius.borderRadiusPill};
|
|
49
|
+
background-color: ${sg.colors.neutralColors.colorNeutralSnow};
|
|
50
|
+
${({ floatingMenuPostion }) => props(floatingMenuPostion)}
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
interface ItemWrapperProps {
|
|
54
|
+
index?: number;
|
|
55
|
+
}
|
|
56
|
+
export const ItemWrapper = styled.div`
|
|
57
|
+
margin-top: ${({ index }: ItemWrapperProps) =>
|
|
58
|
+
index !== 0 ? sg.spacings.spacingInline.spacingInlineAnt : 0};
|
|
59
|
+
`;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
import FloatingButton from '.';
|
|
3
|
+
import ActionButton from '../ActionButton';
|
|
4
|
+
import { sg } from '../../../styles';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Buttons/FloatingButton',
|
|
8
|
+
component: FloatingButton,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: {},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const expandButton = (
|
|
14
|
+
<ActionButton
|
|
15
|
+
iconName="ExpandContentMd"
|
|
16
|
+
iconColor={sg.colors.neutralColors.colorNeutralDark}
|
|
17
|
+
onClick={() => alert('Expand')}
|
|
18
|
+
buttonType="secondary"
|
|
19
|
+
size="Large"
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const importButton = (
|
|
24
|
+
<ActionButton
|
|
25
|
+
iconName="OpenInNewMd"
|
|
26
|
+
iconColor={sg.colors.neutralColors.colorNeutralDark}
|
|
27
|
+
onClick={() => alert('Import')}
|
|
28
|
+
buttonType="secondary"
|
|
29
|
+
size="Large"
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
const listItems = [expandButton, importButton];
|
|
33
|
+
|
|
34
|
+
const Template = (args) => {
|
|
35
|
+
const buttonRef = useRef<HTMLDivElement>(null);
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
ref={buttonRef}
|
|
39
|
+
style={{
|
|
40
|
+
height: '500px',
|
|
41
|
+
width: '500px',
|
|
42
|
+
backgroundColor: '#f0f0f0',
|
|
43
|
+
margin: '20px',
|
|
44
|
+
boxSizing: 'border-box',
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<div>Área do FloatingButton</div>
|
|
48
|
+
<div
|
|
49
|
+
style={{
|
|
50
|
+
position: 'relative',
|
|
51
|
+
top: '50%',
|
|
52
|
+
left: '50%',
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<FloatingButton refButton={buttonRef} {...args} listItems={listItems} />
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const Default = Template.bind({});
|
|
62
|
+
Default.args = {
|
|
63
|
+
floatingMenuPosition: 'top',
|
|
64
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as C from './styles';
|
|
2
|
+
import { motion } from 'framer-motion';
|
|
3
|
+
import Icon from '../Icon';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { sg } from '../../../styles';
|
|
6
|
+
import FloatingMenu from './Components/FloatingMenu';
|
|
7
|
+
|
|
8
|
+
export interface FloatingButtonProps {
|
|
9
|
+
readonly children?: React.ReactNode;
|
|
10
|
+
readonly refButton: React.RefObject<HTMLDivElement>;
|
|
11
|
+
readonly floatingMenuPosition?: 'top' | 'bottom' | 'left' | 'right';
|
|
12
|
+
listItems?: React.ReactNode[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function FloatingButton({
|
|
16
|
+
refButton,
|
|
17
|
+
children,
|
|
18
|
+
floatingMenuPosition = 'top',
|
|
19
|
+
listItems,
|
|
20
|
+
}: FloatingButtonProps) {
|
|
21
|
+
const [isActive, setIsActive] = useState(false);
|
|
22
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
23
|
+
|
|
24
|
+
const toggleButton = () => {
|
|
25
|
+
setIsActive((prev) => !prev);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (children) {
|
|
29
|
+
return (
|
|
30
|
+
<motion.div
|
|
31
|
+
drag
|
|
32
|
+
dragConstraints={refButton}
|
|
33
|
+
dragMomentum={false}
|
|
34
|
+
style={{ height: 'fit-content', width: 'fit-content' }}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</motion.div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<motion.div
|
|
43
|
+
drag
|
|
44
|
+
dragConstraints={refButton}
|
|
45
|
+
dragMomentum={false}
|
|
46
|
+
style={{ height: 'fit-content', width: 'fit-content' }}
|
|
47
|
+
onDragStart={() => setIsDragging(true)}
|
|
48
|
+
onDragEnd={() => setTimeout(() => setIsDragging(false), 100)}
|
|
49
|
+
>
|
|
50
|
+
<motion.div>
|
|
51
|
+
<C.CircleButton
|
|
52
|
+
as={motion.div}
|
|
53
|
+
animate={{ rotate: isActive ? 90 : 0 }}
|
|
54
|
+
transition={{ duration: 0.3 }}
|
|
55
|
+
style={{ padding: sg.spacings.spacingInset.spacingInsetXs }}
|
|
56
|
+
isActive={isActive}
|
|
57
|
+
onClick={() => {
|
|
58
|
+
if (!isDragging) {
|
|
59
|
+
toggleButton();
|
|
60
|
+
}
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<Icon
|
|
64
|
+
iconName={isActive ? 'CloseLg' : 'MenuLg'}
|
|
65
|
+
color={sg.colors.neutralColors.colorNeutralDarkest}
|
|
66
|
+
/>
|
|
67
|
+
</C.CircleButton>
|
|
68
|
+
{isActive && (
|
|
69
|
+
<FloatingMenu
|
|
70
|
+
refButton={refButton}
|
|
71
|
+
floatingMenuPosition={floatingMenuPosition}
|
|
72
|
+
listItems={listItems}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
</motion.div>
|
|
76
|
+
</motion.div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { sg } from '../../../styles';
|
|
3
|
+
import { pxToRem } from '../../../../main/helpers/functions/measurementConverters';
|
|
4
|
+
|
|
5
|
+
interface CircleButtonProps {
|
|
6
|
+
isActive: boolean;
|
|
7
|
+
}
|
|
8
|
+
export const CircleButton = styled.div`
|
|
9
|
+
width: ${pxToRem('56px')};
|
|
10
|
+
height: ${pxToRem('56px')};
|
|
11
|
+
box-shadow: ${sg.shadows.shadowLevelElevation};
|
|
12
|
+
background-color: ${sg.colors.auxiliariesColors.colorAuxTwoLight};
|
|
13
|
+
border-radius: 50%;
|
|
14
|
+
display: flex;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
align-items: center;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
&:hover {
|
|
20
|
+
background-color: ${({ isActive }: CircleButtonProps) =>
|
|
21
|
+
isActive ? sg.colors.auxiliariesColors.colorAuxTwoLight : '#E6B843'};
|
|
22
|
+
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useRef, useEffect } from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
3
|
import * as C from './styles';
|
|
4
4
|
import { Icons } from '../../../../main/helpers/functions/icons';
|
|
5
5
|
|
|
@@ -38,6 +38,8 @@ export interface TooltipProps {
|
|
|
38
38
|
tooltipMargin?: string;
|
|
39
39
|
wrapperStyles?: React.CSSProperties;
|
|
40
40
|
zIndex?: number;
|
|
41
|
+
hideOnScroll?: boolean;
|
|
42
|
+
interactive?: boolean;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
const Tooltip = ({
|
|
@@ -61,6 +63,8 @@ const Tooltip = ({
|
|
|
61
63
|
tooltipMargin = '8px',
|
|
62
64
|
wrapperStyles,
|
|
63
65
|
zIndex = 99999999,
|
|
66
|
+
hideOnScroll = true,
|
|
67
|
+
interactive = true,
|
|
64
68
|
}: TooltipProps) => {
|
|
65
69
|
const targetRef = useRef<HTMLDivElement>(null);
|
|
66
70
|
const tooltipRef = useRef<HTMLDivElement>(null);
|
|
@@ -175,10 +179,12 @@ const Tooltip = ({
|
|
|
175
179
|
};
|
|
176
180
|
|
|
177
181
|
const handleMouseEnterTooltip = () => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
tooltipRef.current
|
|
181
|
-
|
|
182
|
+
if (interactive) {
|
|
183
|
+
isHovering.current = true;
|
|
184
|
+
if (tooltipRef.current) {
|
|
185
|
+
tooltipRef.current.style.opacity = '1';
|
|
186
|
+
tooltipRef.current.style.visibility = 'visible';
|
|
187
|
+
}
|
|
182
188
|
}
|
|
183
189
|
};
|
|
184
190
|
|
|
@@ -189,6 +195,14 @@ const Tooltip = ({
|
|
|
189
195
|
tooltipRef.current.style.visibility = 'hidden';
|
|
190
196
|
}
|
|
191
197
|
};
|
|
198
|
+
|
|
199
|
+
const handleScrollEvent = () => {
|
|
200
|
+
if (hideOnScroll && tooltipRef.current && !isAlwaysVisible) {
|
|
201
|
+
tooltipRef.current.style.opacity = '0';
|
|
202
|
+
tooltipRef.current.style.visibility = 'hidden';
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
192
206
|
useEffect(() => {
|
|
193
207
|
const handleMouseEnter = () => {
|
|
194
208
|
if (tooltipRef.current) {
|
|
@@ -199,28 +213,39 @@ const Tooltip = ({
|
|
|
199
213
|
};
|
|
200
214
|
|
|
201
215
|
const handleMouseLeave = () => {
|
|
202
|
-
|
|
216
|
+
// Só esconde o tooltip se não estiver sendo hover no próprio tooltip
|
|
217
|
+
// ou se o tooltip não for interativo
|
|
218
|
+
if (
|
|
219
|
+
tooltipRef.current &&
|
|
220
|
+
!isAlwaysVisible &&
|
|
221
|
+
(!isHovering.current || !interactive)
|
|
222
|
+
) {
|
|
203
223
|
tooltipRef.current.style.opacity = '0';
|
|
204
224
|
tooltipRef.current.style.visibility = 'hidden';
|
|
205
225
|
}
|
|
206
226
|
};
|
|
207
227
|
|
|
208
|
-
if (isActive) {
|
|
209
|
-
|
|
210
|
-
|
|
228
|
+
if (!isActive) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
211
231
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
232
|
+
// Atualiza a posição inicial e adiciona listener para redimensionamento
|
|
233
|
+
updateTooltipPosition();
|
|
234
|
+
window.addEventListener('resize', updateTooltipPosition);
|
|
235
|
+
|
|
236
|
+
// Adiciona listener de scroll se necessário
|
|
237
|
+
if (hideOnScroll) {
|
|
238
|
+
window.addEventListener('scroll', handleScrollEvent, true);
|
|
216
239
|
}
|
|
217
240
|
|
|
241
|
+
// Adiciona listeners para o elemento alvo
|
|
218
242
|
if (targetRef.current) {
|
|
219
243
|
targetRef.current.addEventListener('mouseenter', handleMouseEnter);
|
|
220
244
|
targetRef.current.addEventListener('mouseleave', handleMouseLeave);
|
|
221
245
|
}
|
|
222
246
|
|
|
223
|
-
|
|
247
|
+
// Adiciona listeners para o próprio tooltip apenas se for interativo
|
|
248
|
+
if (tooltipRef.current && interactive) {
|
|
224
249
|
tooltipRef.current.addEventListener(
|
|
225
250
|
'mouseenter',
|
|
226
251
|
handleMouseEnterTooltip
|
|
@@ -232,10 +257,18 @@ const Tooltip = ({
|
|
|
232
257
|
}
|
|
233
258
|
|
|
234
259
|
return () => {
|
|
260
|
+
// Remove todos os listeners da janela
|
|
235
261
|
window.removeEventListener('resize', updateTooltipPosition);
|
|
262
|
+
window.removeEventListener('scroll', handleScrollEvent, true);
|
|
263
|
+
|
|
264
|
+
// Remove listeners do elemento alvo, se existir
|
|
236
265
|
if (targetRef.current) {
|
|
237
266
|
targetRef.current.removeEventListener('mouseenter', handleMouseEnter);
|
|
238
267
|
targetRef.current.removeEventListener('mouseleave', handleMouseLeave);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Remove listeners do tooltip, se existir
|
|
271
|
+
if (tooltipRef.current && interactive) {
|
|
239
272
|
tooltipRef.current.removeEventListener(
|
|
240
273
|
'mouseenter',
|
|
241
274
|
handleMouseEnterTooltip
|
|
@@ -246,7 +279,14 @@ const Tooltip = ({
|
|
|
246
279
|
);
|
|
247
280
|
}
|
|
248
281
|
};
|
|
249
|
-
}, [
|
|
282
|
+
}, [
|
|
283
|
+
isActive,
|
|
284
|
+
position,
|
|
285
|
+
tooltipMargin,
|
|
286
|
+
hideOnScroll,
|
|
287
|
+
isAlwaysVisible,
|
|
288
|
+
interactive,
|
|
289
|
+
]);
|
|
250
290
|
|
|
251
291
|
if (!isActive || !label) {
|
|
252
292
|
return <>{children}</>;
|
|
@@ -275,39 +315,6 @@ const Tooltip = ({
|
|
|
275
315
|
</C.TooltipContent>
|
|
276
316
|
);
|
|
277
317
|
|
|
278
|
-
// const tooltipChartDataContent = tooltipChartData?.map((data, index) => {
|
|
279
|
-
// return (
|
|
280
|
-
// <div key="divkey" style={index === 0 ? { marginTop: '12px' } : {}}>
|
|
281
|
-
// <C.tooltipChartItem key={'Tooltip item ' + index}>
|
|
282
|
-
// <C.tooltipChartItemLabel>{`${data.label}:`}</C.tooltipChartItemLabel>
|
|
283
|
-
// <div style={{ width: '4px' }} />
|
|
284
|
-
// <C.tooltipChartItemValue>{data.value}</C.tooltipChartItemValue>
|
|
285
|
-
// </C.tooltipChartItem>
|
|
286
|
-
// </div>
|
|
287
|
-
// );
|
|
288
|
-
// });
|
|
289
|
-
// const tooltipChartContent = (
|
|
290
|
-
// <C.TooltipChart
|
|
291
|
-
// ref={tooltipRef}
|
|
292
|
-
// className={`tooltip tooltip-${position}`}
|
|
293
|
-
// height={height}
|
|
294
|
-
// width={width}
|
|
295
|
-
// color={color}
|
|
296
|
-
// position={position}
|
|
297
|
-
// isVisible={isAlwaysVisible}
|
|
298
|
-
// hasArrow={hasArrowOnTooltipChart}
|
|
299
|
-
// >
|
|
300
|
-
// {label && (
|
|
301
|
-
// <C.tooltipChartHeader color={color}>
|
|
302
|
-
// <C.tooltipChartHeaderTitle>{label}</C.tooltipChartHeaderTitle>
|
|
303
|
-
// </C.tooltipChartHeader>
|
|
304
|
-
// )}
|
|
305
|
-
// <div style={{ padding: '12px 0' }}>
|
|
306
|
-
// <C.tooltipChartBody>{tooltipChartDataContent}</C.tooltipChartBody>
|
|
307
|
-
// </div>
|
|
308
|
-
// </C.TooltipChart>
|
|
309
|
-
// );
|
|
310
|
-
|
|
311
318
|
return (
|
|
312
319
|
<C.TooltipWrapper
|
|
313
320
|
id={id}
|
|
@@ -315,8 +322,8 @@ const Tooltip = ({
|
|
|
315
322
|
wrapperWidth={wrapperWidth}
|
|
316
323
|
wrapperHeight={wrapperHeight}
|
|
317
324
|
wrapperStyles={wrapperStyles}
|
|
318
|
-
onMouseEnter={handleMouseEnterTooltip}
|
|
319
|
-
onMouseLeave={handleMouseLeaveTooltip}
|
|
325
|
+
onMouseEnter={interactive ? handleMouseEnterTooltip : undefined}
|
|
326
|
+
onMouseLeave={interactive ? handleMouseLeaveTooltip : undefined}
|
|
320
327
|
>
|
|
321
328
|
{children}
|
|
322
329
|
{ReactDOM.createPortal(tooltipContent, document.body)}
|