-
-
Notifications
You must be signed in to change notification settings - Fork 275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FIX: flicking device status #16873
FIX: flicking device status #16873
Changes from all commits
6f117a4
32f68d1
0473ff1
9b7707c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = 'test-file-stub'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { act, render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import { Tooltip } from './Tooltip'; | ||
|
||
describe('Tooltip', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fantastisch! |
||
it('should show tooltip on hover when isActive is true', async () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip delayShow={0} content={tooltipContent} isActive={true}> | ||
<button>Hover me</button> | ||
</Tooltip>, | ||
); | ||
|
||
const trigger = screen.getByText('Hover me'); | ||
await userEvent.hover(trigger); | ||
|
||
const tooltip = screen.getByText(tooltipContent); | ||
expect(tooltip).toBeInTheDocument(); | ||
}); | ||
|
||
it('should show tooltip on hover when isActive is not defined (default behavior)', async () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip delayShow={0} content={tooltipContent}> | ||
<button id="hover-me">Hover me</button> | ||
</Tooltip>, | ||
); | ||
await act(() => {}); | ||
|
||
const trigger = screen.getByText('Hover me'); | ||
|
||
await userEvent.hover(trigger); | ||
|
||
const tooltip = screen.getByText(tooltipContent); | ||
expect(tooltip).toBeInTheDocument(); | ||
}); | ||
|
||
it('should not show tooltip on hover when isActive is false', async () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip delayShow={0} content={tooltipContent} isActive={false}> | ||
<button>Hover me</button> | ||
</Tooltip>, | ||
); | ||
|
||
const trigger = screen.getByText('Hover me'); | ||
await userEvent.hover(trigger); | ||
|
||
const tooltip = screen.queryByText(tooltipContent); | ||
expect(tooltip).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('should hide tooltip when mouse leaves trigger element', async () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip isActive delayShow={0} delayHide={0} content={tooltipContent}> | ||
<button>Hover me</button> | ||
</Tooltip>, | ||
); | ||
|
||
const trigger = screen.getByText('Hover me'); | ||
|
||
await userEvent.hover(trigger); | ||
|
||
const currentTrigger = screen.getByText('Hover me'); | ||
expect(currentTrigger.parentElement).toHaveAttribute('data-state', 'open'); | ||
|
||
await userEvent.unhover(trigger); | ||
|
||
const triggerBefore = screen.getByText('Hover me'); | ||
|
||
// NOTE: for some reason, the content is still in the DOM but the state is definitely closed | ||
const parent = triggerBefore.parentElement; | ||
expect(parent).toHaveAttribute('data-state', 'closed'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is completely werid though, the tooltip content is still in the dom, it is possibly hidden with some CSS, but rather, I used this state. This test isn't perfect at all, but I guess it is better than nothing |
||
}); | ||
|
||
it('should apply the cursor prop to the content wrapper', () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip content={tooltipContent} cursor="pointer"> | ||
<button>Hover me</button> | ||
</Tooltip>, | ||
); | ||
|
||
expect(screen.getByText('Hover me').parentElement).toHaveStyle({ cursor: 'pointer' }); | ||
}); | ||
|
||
it('should should apply the default=help cursor when the passed cursor is undefined', () => { | ||
const tooltipContent = 'Tooltip Content'; | ||
render( | ||
<Tooltip content={tooltipContent} cursor={undefined}> | ||
<button>Hover me</button> | ||
</Tooltip>, | ||
); | ||
|
||
expect(screen.getByText('Hover me').parentElement).toHaveStyle({ cursor: 'help' }); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,25 +11,37 @@ import { TooltipBox, TooltipBoxProps } from './TooltipBox'; | |
import { TOOLTIP_DELAY_SHORT, TooltipDelay } from './TooltipDelay'; | ||
import { TooltipContent, TooltipFloatingUi, TooltipTrigger } from './TooltipFloatingUi'; | ||
import { intermediaryTheme } from '../../config/colors'; | ||
import { | ||
FrameProps, | ||
FramePropsKeys, | ||
pickAndPrepareFrameProps, | ||
withFrameProps, | ||
} from '../../utils/frameProps'; | ||
import { TransientProps } from '../../utils/transientProps'; | ||
import { Icon } from '../Icon/Icon'; | ||
|
||
export type Cursor = 'inherit' | 'pointer' | 'help' | 'default' | 'not-allowed'; | ||
export type TooltipInteraction = 'none' | 'hover'; | ||
|
||
export const allowedTooltipFrameProps = ['cursor'] as const satisfies FramePropsKeys[]; | ||
export type AllowedFrameProps = Pick<FrameProps, (typeof allowedTooltipFrameProps)[number]>; | ||
|
||
const Wrapper = styled.div<{ $isFullWidth: boolean }>` | ||
width: ${({ $isFullWidth }) => ($isFullWidth ? '100%' : 'auto')}; | ||
`; | ||
|
||
const Content = styled.div<{ $dashed: boolean; $isInline: boolean; $cursor: Cursor }>` | ||
const Content = styled.div< | ||
{ $dashed: boolean; $isInline: boolean } & TransientProps<AllowedFrameProps> | ||
>` | ||
display: ${({ $isInline }) => ($isInline ? 'inline-flex' : 'flex')}; | ||
align-items: center; | ||
justify-content: flex-start; | ||
gap: ${spacingsPx.xxs}; | ||
cursor: ${({ $cursor }) => $cursor}; | ||
border-bottom: ${({ $dashed, theme }) => | ||
$dashed && `1.5px dotted ${transparentize(0.66, theme.textSubdued)}`}; | ||
`; | ||
|
||
export type TooltipInteraction = 'none' | 'hover'; | ||
${withFrameProps} | ||
`; | ||
|
||
type ManagedModeProps = { | ||
isOpen?: boolean; | ||
|
@@ -46,27 +58,27 @@ type UnmanagedModeProps = { | |
}; | ||
|
||
type TooltipUiProps = { | ||
isActive?: boolean; | ||
children: ReactNode; | ||
className?: string; | ||
disabled?: boolean; | ||
dashed?: boolean; | ||
offset?: number; | ||
shift?: ShiftOptions; | ||
cursor?: Cursor; | ||
isFullWidth?: boolean; | ||
placement?: Placement; | ||
hasArrow?: boolean; | ||
hasIcon?: boolean; | ||
appendTo?: HTMLElement | null | MutableRefObject<HTMLElement | null>; | ||
zIndex?: ZIndexValues; | ||
isInline?: boolean; | ||
}; | ||
} & AllowedFrameProps; | ||
|
||
export type TooltipProps = (ManagedModeProps | UnmanagedModeProps) & | ||
TooltipUiProps & | ||
TooltipBoxProps; | ||
|
||
export const Tooltip = ({ | ||
isActive = true, | ||
placement = 'top', | ||
children, | ||
isLarge = false, | ||
|
@@ -75,12 +87,10 @@ export const Tooltip = ({ | |
delayHide = TOOLTIP_DELAY_SHORT, | ||
maxWidth = 400, | ||
offset = spacings.sm, | ||
cursor = 'help', | ||
content, | ||
addon, | ||
title, | ||
headerIcon, | ||
disabled, | ||
className, | ||
isFullWidth = false, | ||
isInline = false, | ||
|
@@ -90,7 +100,10 @@ export const Tooltip = ({ | |
appendTo, | ||
shift, | ||
zIndex = zIndices.tooltip, | ||
...rest | ||
}: TooltipProps) => { | ||
const frameProps = pickAndPrepareFrameProps(rest, allowedTooltipFrameProps); | ||
|
||
if (!content || !children) { | ||
return <>{children}</>; | ||
} | ||
|
@@ -101,6 +114,7 @@ export const Tooltip = ({ | |
return ( | ||
<Wrapper $isFullWidth={isFullWidth} className={className} as={elType}> | ||
<TooltipFloatingUi | ||
isActive={isActive} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Turns out, that I would really used this change in this other PR of mine: https://github.com/trezor/trezor-suite/pull/16815/files |
||
placement={placement} | ||
isOpen={isOpen} | ||
offset={offset} | ||
|
@@ -111,8 +125,9 @@ export const Tooltip = ({ | |
<Content | ||
$dashed={dashed} | ||
$isInline={isInline} | ||
$cursor={disabled ? 'default' : cursor} | ||
as={elType} | ||
{...frameProps} | ||
$cursor={frameProps.$cursor ?? 'help'} | ||
> | ||
{children} | ||
{hasIcon && <Icon name="question" size="medium" />} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What for is this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the source code, there is import to
.svg
file and due to that, tests wouldn't start