Skip to content

Commit

Permalink
Feat(web-react): Use the new Placement dictionary in Tooltip #DS-923
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkudrna committed Oct 19, 2023
1 parent 0cb30d5 commit 07fe0df
Show file tree
Hide file tree
Showing 14 changed files with 279 additions and 69 deletions.
38 changes: 20 additions & 18 deletions packages/web-react/src/components/Tooltip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,27 @@ const toggleHandler = () => setOpen(!open);

## Tooltip Props

| Name | Type | Default | Required | Description |
| ------------------ | ------------------------------------------------- | -------- | -------- | ----------------------------------------- |
| `children` | `ReactNode` ||| Tooltip children's nodes |
| `closeLabel` | `string` | `Close` || Tooltip label on close button |
| `isDismissible` | `bool` ||| When it should appear with a close button |
| `onClose` | `(event: ClickEvent) => void` ||| Close button callback |
| `open` | `bool` ||| Tooltip open state control |
| `placement` | [`top` \| `right` \| `bottom` \| `left` \| `off`] | `bottom` || Tooltip placement |
| `UNSAFE_className` | `string` ||| Tooltip custom class name |
| `UNSAFE_style` | `CSSProperties` ||| Tooltip custom style |
| Name | Type | Default | Required | Description |
| ------------------ | --------------------------------------------------- | -------- | -------- | ----------------------------------------- |
| `children` | `ReactNode` ||| Tooltip children's nodes |
| `closeLabel` | `string` | `Close` || Tooltip label on close button |
| `isDismissible` | `bool` ||| When it should appear with a close button |
| `onClose` | `(event: ClickEvent) => void` ||| Close button callback |
| `open` | `bool` ||| Tooltip open state control |
| `placement` | [Placement dictionary][dictionary-placement], 'off' | `bottom` || Tooltip placement |
| `UNSAFE_className` | `string` ||| Tooltip custom class name |
| `UNSAFE_style` | `CSSProperties` ||| Tooltip custom style |

## UncontrolledTooltip Props

| Name | Type | Default | Required | Description |
| ------------------ | ------------------------------------------------- | -------- | -------- | ----------------------------------------- |
| `children` | `ReactNode` ||| Tooltip children's nodes |
| `closeLabel` | `string` | `Close` || Tooltip label on close button |
| `isDismissible` | `bool` ||| When it should appear with a close button |
| `placement` | [`top` \| `right` \| `bottom` \| `left` \| `off`] | `bottom` || Tooltip placement |
| `UNSAFE_className` | `string` ||| Tooltip custom class name |
| `UNSAFE_style` | `CSSProperties` ||| Tooltip custom style |
| Name | Type | Default | Required | Description |
| ------------------ | --------------------------------------------------- | -------- | -------- | ----------------------------------------- |
| `children` | `ReactNode` ||| Tooltip children's nodes |
| `closeLabel` | `string` | `Close` || Tooltip label on close button |
| `isDismissible` | `bool` ||| When it should appear with a close button |
| `placement` | [Placement dictionary][dictionary-placement], 'off' | `bottom` || Tooltip placement |
| `UNSAFE_className` | `string` ||| Tooltip custom class name |
| `UNSAFE_style` | `CSSProperties` ||| Tooltip custom style |

## TooltipWrapper Props

Expand Down Expand Up @@ -219,3 +219,5 @@ const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, d
</Tooltip>
</div>;
```
[dictionary-placement]: https://github.com/lmc-eu/spirit-design-system/tree/main/docs/DICTIONARIES.md#placement
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { renderHook } from '@testing-library/react-hooks';
import { useTooltipStyleProps } from '../useTooltipStyleProps';
import { PlacementDictionaryType } from '../../../types';
import { useTooltipStyleProps, UseTooltipStyleProps } from '../useTooltipStyleProps';

describe('useTooltipStyleProps', () => {
it('should return defaults', () => {
const { result } = renderHook(() => useTooltipStyleProps({}));

expect(result.current.classProps).toBeDefined();
expect(result.current.classProps.rootClassName).toBe('Tooltip Tooltip--bottom');
expect(result.current.classProps.wrapperClassName).toBe('TooltipWrapper');
expect(result.current.classProps.arrowClassName).toBe('Tooltip__arrow');
expect(result.current.classProps.closeButtonClassName).toBe('Tooltip__close');
});

it('should change placement', () => {
const props = {
placement: 'top-right' as PlacementDictionaryType,
} as UseTooltipStyleProps;
const { result } = renderHook(() => useTooltipStyleProps(props));

expect(result.current.classProps.rootClassName).toBe('Tooltip Tooltip--topRight');
});

it('should return dismissible class', () => {
const { result } = renderHook(() => useTooltipStyleProps({ isDismissible: true }));

expect(result.current.classProps).toBeDefined();
expect(result.current.classProps.rootClassName).toBe('Tooltip Tooltip--bottom Tooltip--dismissible');
});
});
46 changes: 46 additions & 0 deletions packages/web-react/src/components/Tooltip/demo/TooltipOnHover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { ButtonLink } from '../../Button';
import TooltipWrapper from '../TooltipWrapper';
import Tooltip from '../Tooltip';

const TooltipOnHover = () => (
<>
<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-top" UNSAFE_className="TooltipTarget">
Tooltip on top
</ButtonLink>
<Tooltip id="my-tooltip-hover-top" placement="top">
Hello there!
</Tooltip>
</TooltipWrapper>

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-right" UNSAFE_className="TooltipTarget">
Tooltip on right
</ButtonLink>
<Tooltip id="my-tooltip-hover-right" placement="right">
Hello there!
</Tooltip>
</TooltipWrapper>

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-bottom" UNSAFE_className="TooltipTarget">
Tooltip on bottom
</ButtonLink>
<Tooltip id="my-tooltip-hover-bottom" placement="bottom">
Hello there!
</Tooltip>
</TooltipWrapper>

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-left" UNSAFE_className="TooltipTarget">
Tooltip on left
</ButtonLink>
<Tooltip id="my-tooltip-hover-left" placement="left">
Hello there!
</Tooltip>
</TooltipWrapper>
</>
);

export default TooltipOnHover;
177 changes: 138 additions & 39 deletions packages/web-react/src/components/Tooltip/demo/TooltipPlacements.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,145 @@
import React from 'react';
import { ButtonLink } from '../../Button';
import React, { ChangeEvent, useState } from 'react';
import DocsBox from '../../../../docs/DocsBox';
import { PlacementDictionaryType } from '../../../types';
import { Radio } from '../../Radio';
import TooltipWrapper from '../TooltipWrapper';
import Tooltip from '../Tooltip';

const TooltipPlacements = () => (
<>
<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-top" UNSAFE_className="TooltipTarget">
Tooltip on top
</ButtonLink>
<Tooltip id="my-tooltip-hover-top" placement="top">
Hello there!
</Tooltip>
</TooltipWrapper>
const TooltipPlacements = () => {
const [placement, setPlacement] = useState<PlacementDictionaryType>('bottom');

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-right" UNSAFE_className="TooltipTarget">
Tooltip on right
</ButtonLink>
<Tooltip id="my-tooltip-hover-right" placement="right">
Hello there!
</Tooltip>
</TooltipWrapper>
const handlePlacementChange = (e: ChangeEvent<HTMLInputElement>) => {
setPlacement(e.target.value as PlacementDictionaryType);
};

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-bottom" UNSAFE_className="TooltipTarget">
Tooltip on bottom
</ButtonLink>
<Tooltip id="my-tooltip-hover-bottom" placement="bottom">
Hello there!
</Tooltip>
</TooltipWrapper>

<TooltipWrapper>
<ButtonLink href="#" aria-describedby="my-tooltip-hover-left" UNSAFE_className="TooltipTarget">
Tooltip on left
</ButtonLink>
<Tooltip id="my-tooltip-hover-left" placement="left">
Hello there!
</Tooltip>
</TooltipWrapper>
</>
);
return (
<form autoComplete="off" className="mx-auto">
<div className="Grid Grid--cols-3" style={{ alignItems: 'center', justifyItems: 'center' }}>
<div style={{ gridRow: 1, gridColumn: 2 }}>
<Radio
name="placement"
isChecked={placement === 'top-left'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_top_left"
label="top-left"
value="top-left"
/>{' '}
<Radio
name="placement"
isChecked={placement === 'top'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_top"
label="top"
value="top"
/>{' '}
<Radio
name="placement"
isChecked={placement === 'top-right'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_top_right"
label="top-right"
value="top-right"
/>
</div>
<div style={{ gridRow: 3, gridColumn: 2 }}>
<Radio
name="placement"
isChecked={placement === 'bottom-left'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_bottom_left"
label="bottom-left"
value="bottom-left"
/>{' '}
<Radio
name="placement"
isChecked={placement === 'bottom'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_bottom"
label="bottom"
value="bottom"
/>{' '}
<Radio
name="placement"
isChecked={placement === 'bottom-right'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_bottom_right"
label="bottom-right"
value="bottom-right"
/>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gridRow: 2, gridColumn: 1 }}>
<Radio
name="placement"
isChecked={placement === 'left-top'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_left_top"
label="left-top"
value="left-top"
/>
<Radio
name="placement"
isChecked={placement === 'left'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_left"
label="left"
value="left"
/>
<Radio
name="placement"
isChecked={placement === 'left-bottom'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_left_bottom"
label="left-bottom"
value="left-bottom"
/>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gridRow: 2, gridColumn: 3 }}>
<Radio
name="placement"
isChecked={placement === 'right-top'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_right_top"
label="right-top"
value="right-top"
/>
<Radio
name="placement"
isChecked={placement === 'right'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_right"
label="right"
value="right"
/>
<Radio
name="placement"
isChecked={placement === 'right-bottom'}
isLabelHidden
onChange={handlePlacementChange}
id="placement_right_bottom"
label="right-bottom"
value="right-bottom"
/>
</div>
<div style={{ gridRow: 2, gridColumn: 2 }}>
<TooltipWrapper UNSAFE_style={{ margin: '6rem auto' }}>
<DocsBox>Click the dots!</DocsBox>
<Tooltip placement={placement as PlacementDictionaryType}>Hello!</Tooltip>
</TooltipWrapper>
</div>
</div>
</form>
);
};

export default TooltipPlacements;
8 changes: 6 additions & 2 deletions packages/web-react/src/components/Tooltip/demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import ReactDOM from 'react-dom/client';
import icons from '@lmc-eu/spirit-icons/dist/icons';
import DocsSection from '../../../../docs/DocsSections';
import { IconsProvider } from '../../../context';
import TooltipDefault from './TooltipDefault';
import TooltipPlacements from './TooltipPlacements';
import TooltipDefault from './TooltipDefault';
import TooltipOnHover from './TooltipOnHover';
import TooltipClickable from './TooltipClickable';
import TooltipDismissible from './TooltipDismissible';
import TooltipFloatingUI from './TooltipFloatingUi';
Expand All @@ -17,11 +18,14 @@ import TooltipDismissibleViaJS from './TooltipDismissibleViaJS';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<IconsProvider value={icons}>
<DocsSection title="Placements">
<TooltipPlacements />
</DocsSection>
<DocsSection title="Static Tooltip (No Interaction)">
<TooltipDefault />
</DocsSection>
<DocsSection title="Tooltip on Hover (Pure CSS)">
<TooltipPlacements />
<TooltipOnHover />
</DocsSection>
<DocsSection title="Tooltip on Click (JavaScript)">
<TooltipClickable />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react';
import { Markdown } from '@storybook/blocks';
import type { Meta, StoryObj } from '@storybook/react';

import { Placements } from '../../../constants';

import { Button } from '../..';
import ReadMe from '../README.md';
import { Tooltip, TooltipWrapper } from '..';
Expand Down Expand Up @@ -33,7 +35,7 @@ const meta: Meta<typeof Tooltip> = {
},
placement: {
control: 'select',
options: ['top', 'right', 'bottom', 'left', 'off'],
options: [...Object.values(Placements), 'off'],
table: {
defaultValue: { summary: 'bottom' },
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';

import { Placements } from '../../../constants';

import { Button } from '../..';
import { TooltipWrapper, UncontrolledTooltip } from '..';

Expand All @@ -25,7 +27,7 @@ const meta: Meta<typeof UncontrolledTooltip> = {
},
placement: {
control: 'select',
options: ['top', 'right', 'bottom', 'left', 'off'],
options: [...Object.values(Placements), 'off'],
table: {
defaultValue: { summary: 'bottom' },
},
Expand Down
Loading

0 comments on commit 07fe0df

Please sign in to comment.