Skip to content

Commit

Permalink
feat: TET-868 add tooltip (#153)
Browse files Browse the repository at this point in the history
* feat: TET-868 add Tooltip component

* feat: TET-868 improve tooltip

* feat: TET-868 add export to index file

* feat: TET-868 add tests

* feat: TET-868 fix reccurency

* feat: TET-868 update tooltip component

* feat: TET-868 add Tooltip to Label component

* feat: TET-868 adjust styling

* feat: TET-868 resolve edge case

* feat: TET-868 adjust documentation

* feat: TET-868 add tests and add small fixes

* feat: TET-868 review changes

* feat: TET-868 review changes
  • Loading branch information
karolinaszarek authored Sep 2, 2024
1 parent d48dd7f commit 7250e0a
Show file tree
Hide file tree
Showing 15 changed files with 873 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/components/Label/Label.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const defaultConfig = {
display: 'flex',
alignItems: 'center',
minHeight: '$size-xSmall',
justifyContent: 'center',
},
optional: {
color: '$color-content-tertiary',
Expand Down
10 changes: 7 additions & 3 deletions src/components/Label/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { type FC, useMemo } from 'react';
import type { LabelProps } from './Label.props';
import { stylesBuilder } from './stylesBuilder';
import { Button } from '../Button';
import { Tooltip } from '../Tooltip';

import { tet } from '@/tetrisly';
import type { MarginProps } from '@/types/MarginProps';
Expand All @@ -26,11 +27,14 @@ export const Label: FC<LabelProps & MarginProps> = ({
{optional}
</tet.span>
)}
{/* TODO: add tooltip instead of bare icon, when we get one */}
{tooltip && (
<tet.span {...styles.tooltip} data-testid="label-tooltip">
<Tooltip
{...styles.tooltip}
text="label tooltip"
data-testid="label-tooltip"
>
<Icon name="16-info" />
</tet.span>
</Tooltip>
)}
{!!action && (
<Button
Expand Down
84 changes: 84 additions & 0 deletions src/components/Tooltip/Arrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { FC } from 'react';

import { TooltipPositionType } from './Tooltip.props';

import { tet } from '@/tetrisly';

type ArrowObjectProps = {
pathDefinition: string;
viewBox: string;
height: number;
width: number;
};

const ArrowObject = ({
pathDefinition,
viewBox,
height,
width,
}: ArrowObjectProps) => (
<svg
width={width}
height={height}
viewBox={viewBox}
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<tet.path d={pathDefinition} fill="$color-background-inverted" />
</svg>
);

type ArrowProps = {
arrowType: TooltipPositionType;
};

export const Arrow: FC<ArrowProps> = ({ arrowType }) => {
switch (arrowType) {
case 'bottom':
return (
<ArrowObject
width={12}
height={6}
viewBox="0 0 12 6"
pathDefinition="M0 6H12L7.41421 1.41421C6.63317 0.633166 5.36684 0.633165 4.58579 1.41421L0 6Z"
/>
);
case 'top':
return (
<ArrowObject
width={12}
height={6}
viewBox="0 0 12 6"
pathDefinition="M0 0H12L7.41421 4.58579C6.63317 5.36683 5.36684 5.36684 4.58579 4.58579L0 0Z"
/>
);

case 'right':
return (
<ArrowObject
width={6}
height={12}
viewBox="0 0 6 12"
pathDefinition="M6 12L6 0L1.41421 4.58579C0.633166 5.36683 0.633165 6.63316 1.41421 7.41421L6 12Z"
/>
);
case 'left':
return (
<ArrowObject
width={6}
height={12}
viewBox="0 0 6 12"
pathDefinition="M0 12L0 0L4.58579 4.58579C5.36683 5.36683 5.36684 6.63316 4.58579 7.41421L0 12Z"
/>
);
default:
return (
<ArrowObject
width={12}
height={6}
viewBox="0 0 12 6"
pathDefinition="M0 6H12L7.41421 1.41421C6.63317 0.633166 5.36684 0.633165 4.58579 1.41421L0 6Z"
/>
);
}
};
11 changes: 11 additions & 0 deletions src/components/Tooltip/Tooltip.props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { TooltipConfig } from './Tooltip.styles';

export type ArrowheadPositionType = 'start' | 'middle' | 'end';
export type TooltipPositionType = 'top' | 'bottom' | 'left' | 'right';

export type TooltipProps = {
arrowheadPosition?: ArrowheadPositionType;
tooltipPosition?: TooltipPositionType;
text: string;
custom?: TooltipConfig;
};
75 changes: 75 additions & 0 deletions src/components/Tooltip/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Tooltip } from './Tooltip';
import { TooltipElement } from './TooltipElement';
import { Button } from '../Button';

import { TetDocs } from '@/docs-components/TetDocs';
import { TooltipDocs } from '@/docs-components/TooltipDocs';
import { tet } from '@/tetrisly';

const meta = {
title: 'Tooltip',
component: TooltipElement,
tags: ['autodocs'],
args: {
text: 'Tooltip placeholder',
arrowheadPosition: 'start',
tooltipPosition: 'top',
},
argTypes: {
arrowheadPosition: {
options: ['start', 'middle', 'end'],
defaultValue: 'start',
control: { type: 'radio' },
},
tooltipPosition: {
options: ['top', 'bottom', 'left', 'right'],
defaultValue: 'top',
control: { type: 'radio' },
},
},
parameters: {
docs: {
Description: {
component:
'Brief, additional information or context that appears when the user hovers over or focuses on a particular element. Tooltips help provide explanations, hints, or tips without cluttering up the interface.',
},
page: () => (
<TetDocs docs="https://docs.tetrisly.com/components/list/tooltip">
<TooltipDocs />
</TetDocs>
),
},
},
} satisfies Meta<typeof Tooltip>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
arrowheadPosition: 'middle',
tooltipPosition: 'top',
},
};

export const WithButtonTootlip: Story = {
render: () => (
<tet.div
margin={20}
display="flex"
flexDirection="column"
alignItems="start"
>
<Tooltip
text="Button tooltip"
arrowheadPosition="end"
tooltipPosition="top"
>
<Button label="Button" />
</Tooltip>
</tet.div>
),
};
63 changes: 63 additions & 0 deletions src/components/Tooltip/Tooltip.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BaseProps } from '@/types/BaseProps';

export type TooltipConfig = {
innerElements?: {
arrow: BaseProps & {
right: BaseProps;
left: BaseProps;
top: BaseProps;
bottom: BaseProps;
};
content: BaseProps;
container: BaseProps;
};
} & BaseProps;

export const defaultConfig = {
display: 'inline-flex',
position: 'relative',
innerElements: {
arrow: {
right: {
padding: '$space-component-padding-small 0',
paddingLeft: '$space-component-padding-xSmall',
},
left: {
padding: '$space-component-padding-small 0',
paddingRight: '$space-component-padding-xSmall',
},
top: {
padding: '0 $space-component-padding-small',
paddingBottom: '$space-component-padding-xSmall',
},
bottom: {
padding: '0 $space-component-padding-small',
paddingTop: '$space-component-padding-xSmall',
},
},
content: {
backgroundColor: '$color-background-inverted',
color: '$color-content-primary-inverted',
padding: '$space-component-padding-xSmall $space-component-padding-small',
borderRadius: '$border-radius-medium',
text: '$typo-body-small',
minWidth: '20px',
minHeight: '28px',
w: 'max-content',
maxWidth: '240px',
},
container: {
position: 'absolute',
alignContent: 'center',
justifyContent: 'center',
w: 'fit-content',
transition: 'opacity .2s ease-in-out',
display: 'inline-flex',
zIndex: 1,
},
},
} satisfies TooltipConfig;

export const TooltipStyles = {
defaultConfig,
};
Loading

0 comments on commit 7250e0a

Please sign in to comment.