Skip to content

Commit

Permalink
fix(Tip): Fixes hover gap and click issues with ToolTips and PreviewTips
Browse files Browse the repository at this point in the history
Fix hover gap and click tooltip bugs on `floating` tooltips
  • Loading branch information
dreamwasp authored Jan 31, 2025
1 parent 9537b3b commit 84030ff
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 32 deletions.
17 changes: 11 additions & 6 deletions packages/gamut/src/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useWindowScroll, useWindowSize } from 'react-use';
import { FocusTrap } from '../FocusTrap';
import {
Beak,
BeakBox,
PatternContainer,
PopoverContainer,
PopoverPortal,
Expand Down Expand Up @@ -172,12 +173,16 @@ export const Popover: React.FC<PopoverProps> = ({
widthRestricted={widthRestricted}
>
{beak && (
<Beak
outline={outline ? 'outline' : 'boxShadow'}
beak={`${position}-${beak}${variant === 'secondary' ? '-sml' : ''}`}
data-testid="popover-beak"
size={variant === 'secondary' ? 'sml' : 'lrg'}
/>
<BeakBox variant={position}>
<Beak
beak={`${position}-${beak}${
variant === 'secondary' ? '-sml' : ''
}`}
data-testid="popover-beak"
size={variant === 'secondary' ? 'sml' : 'lrg'}
hasBorder={outline || variant === 'secondary'}
/>
</BeakBox>
)}
{children}
</RaisedDiv>
Expand Down
13 changes: 9 additions & 4 deletions packages/gamut/src/Popover/elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { AnimatePresence, motion } from 'framer-motion';
import * as React from 'react';

import { BodyPortal } from '../BodyPortal';
import { Box } from '../Box';
import { Box, FlexBox } from '../Box';
import { popoverToolTipBodyAlignments } from '../Tip/shared/styles';
import { WithChildrenProp } from '../utils';
import {
beakBorderStates,
beakBoxVariants,
beakSize,
beakVariants,
outlineVariants,
Expand Down Expand Up @@ -39,10 +41,13 @@ export const RaisedDiv = styled.div<

export const Beak = styled(Box)<
StyleProps<typeof popoverStates> &
StyleProps<typeof outlineVariants> &
StyleProps<typeof beakVariants> &
StyleProps<typeof beakSize>
>(beakVariants, beakSize);
StyleProps<typeof beakSize> &
StyleProps<typeof beakBorderStates>
>(beakBorderStates, beakVariants, beakSize);

export const BeakBox =
styled(FlexBox)<StyleProps<typeof beakBoxVariants>>(beakBoxVariants);

export const PatternContainer = styled.div(
variant({
Expand Down
30 changes: 27 additions & 3 deletions packages/gamut/src/Popover/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const raisedDivVariants = variant({
},
});

const borderStyles = { border: 1 } as const;
export const outlineVariants = variant({
defaultVariant: 'boxShadow',
prop: 'outline',
Expand All @@ -36,8 +37,7 @@ export const outlineVariants = variant({
boxShadow: '0 0 16px rgba(0, 0, 0, 0.1), 0 0 24px rgba(0, 0, 0, 0.15)',
},
outline: {
borderColor: 'secondary',
border: 1,
...borderStyles,
boxShadow: 'none',
},
},
Expand All @@ -50,6 +50,28 @@ export const widthStates = states({
},
});

export const beakBorderStates = states({
hasBorder: borderStyles,
});

export const beakBoxVariants = variant({
base: {
alignItems: 'flex-end',
height: '15px',
justifyContent: 'center',
left: 0,
position: 'absolute',
width: '100%',
},
variants: {
above: {
bottom: -15,
},
below: {
top: -15,
},
},
});
const beakVariantsArray = [
'below-left',
'below-right',
Expand All @@ -72,8 +94,10 @@ const beakVariantStyles = createVariantsFromAlignments(

export const beakVariants = variant({
base: {
position: 'absolute',
transform: 'rotate(45deg)',
background: 'transparent',
zIndex: 1,
position: 'fixed',
},
prop: 'beak',
variants: beakVariantStyles,
Expand Down
16 changes: 8 additions & 8 deletions packages/gamut/src/Popover/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { theme } from '@codecademy/gamut-styles';
import { tooltipBackgroundColor } from '../Tip/shared/styles';

const popoverAbove = {
borderRight: 'inherit',
borderBottom: 'inherit',
borderLeft: 'none',
borderTop: 'none',
top: 'calc(100% - 10px)',
} as const;

const popoverBelow = {
borderLeft: 'inherit',
borderTop: 'inherit',
borderRight: 'none',
borderBottom: 'none',
top: '-10px',
} as const;

Expand All @@ -27,14 +27,14 @@ const beakCenter = {
};

const popoverAboveSml = {
borderRight: 'inherit',
borderBottom: 'inherit',
borderLeft: 'none',
borderTop: 'none',
top: 'calc(100% - 8px)',
} as const;

const popoverBelowSml = {
borderLeft: 'inherit',
borderTop: 'inherit',
borderRight: 'none',
borderBottom: 'none',
top: '-8px',
} as const;

Expand Down
20 changes: 12 additions & 8 deletions packages/gamut/src/Tip/shared/FloatingTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { useLayoutEffect, useRef, useState } from 'react';
import * as React from 'react';
import { useMeasure } from 'react-use';

import { Box, FlexBox } from '../../Box';
import { Box } from '../../Box';
import { PreviewTipContents } from '../PreviewTip/elements';
import { FloatingTipBody, TargetContainer } from './elements';
import { narrowWidth } from './styles';
import {
FloatingTipBody,
FloatingTipTextWrapper,
TargetContainer,
} from './elements';
import { TipWrapperProps } from './types';
import { getAlignmentWidths, getPopoverAlignment, runWithDelay } from './utils';

Expand Down Expand Up @@ -113,6 +116,7 @@ export const FloatingTip: React.FC<TipWrapperProps> = ({
onFocus={toolOnlyEventFunc}
onBlur={toolOnlyEventFunc}
onMouseEnter={toolOnlyEventFunc}
onMouseDown={(e) => e.preventDefault()}
onKeyDown={
escapeKeyPressHandler ? (e) => escapeKeyPressHandler(e) : undefined
}
Expand All @@ -133,14 +137,14 @@ export const FloatingTip: React.FC<TipWrapperProps> = ({
variant="secondary"
widthRestricted={false}
>
<FlexBox
alignItems={isHoverType ? undefined : 'flex-start'}
flexDirection="column"
<FloatingTipTextWrapper
ref={childRef}
width={narrow ? narrowWidth : undefined}
isHoverType={isHoverType}
narrow={narrow}
centered={alignment.includes('center')}
>
{contents}
</FlexBox>
</FloatingTipTextWrapper>
</FloatingTipBody>
</Box>
);
Expand Down
22 changes: 20 additions & 2 deletions packages/gamut/src/Tip/shared/elements.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import { css, timing } from '@codecademy/gamut-styles';
import { css, states, timing } from '@codecademy/gamut-styles';
import { StyleProps } from '@codecademy/variance';
import styled from '@emotion/styled';

import { Box } from '../../Box';
import { Box, FlexBox } from '../../Box';
import { Selectors } from '../../ButtonBase/ButtonBase';
import { Popover } from '../../Popover';
import {
centerWidths,
inlineToolTipBodyAlignments,
narrowWidth,
toolTipBodyCss,
toolTipWidthRestrictions,
} from './styles';

const tipWrapperStyles = {
position: 'relative',
display: 'inline-flex',
overflowWrap: 'break-word',
} as const;

const floatingTipTextStates = states({
isHoverType: { alignItems: 'flexStart' },
narrow: { width: narrowWidth },
centered: {
...centerWidths,
},
});

export const FloatingTipTextWrapper = styled(FlexBox)<
StyleProps<typeof floatingTipTextStates>
>(
css({ flexDirection: 'column', overflowWrap: 'break-word' }),
floatingTipTextStates
);

export const ToolTipWrapper = styled.div(
css({
'&:hover > div, &:focus-within > div': {
Expand Down
15 changes: 15 additions & 0 deletions packages/gamut/src/Tip/shared/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export const topStyles = {
pb: containerOffsetVertical,
} as const;

const beforeStyles = {
content: '""',
position: 'absolute',
width: '100%',
};

export const topStylesBefore = { ...beforeStyles, height: 16, bottom: '-4px' };

export const topStylesAfter = {
borderColor: 'currentColor',
borderWidth: '0 1px 1px 0',
Expand All @@ -42,6 +50,12 @@ export const bottomStyles = {
pt: containerOffsetVertical,
} as const;

export const bottomStylesBefore = {
...beforeStyles,
height: 24,
top: '-8px',
};

export const bottomStylesAfter = {
borderColor: 'currentColor',
borderWidth: '1px 0 0 1px',
Expand Down Expand Up @@ -104,6 +118,7 @@ export const toolTipAlignmentVariants = variant({
opacity: 0,
position: 'absolute',
visibility: 'hidden',

'&::after': {
content: '""',
display: 'block',
Expand Down
11 changes: 10 additions & 1 deletion packages/gamut/src/Tip/shared/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
bottomCenterStylesAfter,
bottomStyles,
bottomStylesAfter,
bottomStylesBefore,
centerStyles,
centerStylesAfter,
leftStyles,
Expand All @@ -14,6 +15,7 @@ import {
topCenterStylesAfter,
topStyles,
topStylesAfter,
topStylesBefore,
} from './styles';
import { TipPlacementComponentProps, TipWrapperProps } from './types';

Expand Down Expand Up @@ -62,13 +64,16 @@ export const getPopoverAlignment = ({
export const createToolTipVariantFromAlignment = (alignment: string) => {
let styleObject = {};
let styleObjectAfter = {};
let styleObjectBefore = {};

if (alignment.includes('top')) {
styleObject = { ...topStyles };
styleObjectAfter = { ...topStylesAfter };
styleObjectBefore = { ...topStylesBefore };
} else {
styleObject = { ...bottomStyles };
styleObjectAfter = { ...bottomStylesAfter };
styleObjectBefore = { ...bottomStylesBefore };
}

if (alignment.includes('center')) {
Expand All @@ -87,7 +92,11 @@ export const createToolTipVariantFromAlignment = (alignment: string) => {
styleObjectAfter = { ...styleObjectAfter, ...leftStylesAfter };
}

return { ...styleObject, '&::after': styleObjectAfter };
return {
...styleObject,
'&::after': styleObjectAfter,
'&::before': styleObjectBefore,
};
};

export const createVariantsFromAlignments = (
Expand Down

0 comments on commit 84030ff

Please sign in to comment.