Skip to content

Add new anchorSelect prop to improve how to attach multiple anchors to the same tooltip #928

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

Merged
merged 25 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dea1608
feat: add `anchorSelect` prop to types
gabrieljablonski Jan 30, 2023
9c0b6a0
docs: deprecate stuff
gabrieljablonski Feb 2, 2023
9548890
feat: implement `anchorSelect` logic
gabrieljablonski Feb 2, 2023
88d149d
chore: update dev example
gabrieljablonski Feb 2, 2023
1f29dda
chore: merge from master
gabrieljablonski Feb 14, 2023
8d20f32
chore: merge from master
gabrieljablonski Feb 14, 2023
60f287c
fix: event order when switch anchors quickly
gabrieljablonski Feb 14, 2023
11aaa9b
refactor: `data-tooltip-for` -> `data-tooltip-id`
gabrieljablonski Feb 14, 2023
7f11169
fix: increased rendered timeout
gabrieljablonski Feb 14, 2023
7e62bbb
fix: allow changing `place` prop dynamically
gabrieljablonski Feb 14, 2023
7472211
docs: update readme with `anchorSelect` changes
gabrieljablonski Feb 14, 2023
04dc2b3
docs: major docs overhaul for `anchorSelect`
gabrieljablonski Feb 14, 2023
d4ab568
docs: add anchor select example page
gabrieljablonski Feb 14, 2023
6f5f66c
chore: add link to docs on deprecation warnings
gabrieljablonski Feb 14, 2023
4b7371c
chore: increase bundlesize limit
gabrieljablonski Feb 14, 2023
6742563
docs: minor
gabrieljablonski Feb 14, 2023
be5e3c3
docs: mention attribute on deprecation warnings
gabrieljablonski Feb 16, 2023
04ddba5
chore: merge from master
gabrieljablonski Feb 16, 2023
a41ec13
fix: redundant `useEffect()` dependencies
gabrieljablonski Feb 16, 2023
e2f7b15
refactor: declaration position
gabrieljablonski Feb 16, 2023
dd315a8
test: update snapshot
gabrieljablonski Feb 16, 2023
4b95e5d
chore: remove provider from dev examples
gabrieljablonski Feb 16, 2023
4e384bd
docs: minor
gabrieljablonski Feb 16, 2023
0121022
test: remove provider/wrapper test
gabrieljablonski Feb 16, 2023
ec02ff0
fix: reset stale refs
gabrieljablonski Feb 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,20 @@ yarn add react-tooltip

## Usage

### Using NPM
> :warning: If you were already using `react-tooltip<=5.7.5`, you'll be getting some deprecation warnings regarding the `anchorId` prop and some other features.
In versions >=5.8.0, we've introduced the `data-tooltip-id` attribute, and the `anchorSelect` prop, which are our recommended methods of using the tooltip moving forward. Check [the docs](https://react-tooltip.com/docs/getting-started) for more details.

1 . Import the CSS file to set default styling
### Using NPM package

1 . Import the CSS file to set default styling.

```js
import 'react-tooltip/dist/react-tooltip.css'
```

This needs to be done only once. We suggest you do it on your `src/index.js` or equivalent file.

2 . Import `react-tooltip` after installation
2 . Import `react-tooltip` after installation.

```js
import { Tooltip } from 'react-tooltip'
Expand All @@ -68,20 +71,41 @@ or if you want to still use the name ReactTooltip as V4:
import { Tooltip as ReactTooltip } from 'react-tooltip'
```

3 . Add `data-tooltip-content="your placeholder"` to your element
3 . Add `data-tooltip-id="<tooltip id>"` and `data-tooltip-content="<your placeholder>"` to your element.

> `data-tooltip-id` is the equivalent of V4's `data-for`.

```jsx
<p id="my-element" data-tooltip-content="hello world">
Tooltip
</p>
<a data-tooltip-id="my-tooltip" data-tooltip-content="Hello world!">
◕‿‿◕
</a>
```

4 . Include react-tooltip component
4 . Include the `<Tooltip />` element.

> Don't forget to set the id, it won't work without it!

```jsx
<ReactTooltip anchorId="my-element" />
<Tooltip id="my-tooltip" />
```

#### Using multiple anchor elements

You can also set the `anchorSelect` tooltip prop to use the tooltip with multiple anchor elements without having to set `data-tooltip-id` on each of them.
`anchorSelect` must be a valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).

```jsx
<a className="my-anchor-element" data-tooltip-content="Hello world!">
◕‿‿◕
</a>
<a className="my-anchor-element" data-tooltip-content="Hello to you too!">
◕‿‿◕
</a>
<Tooltip anchorSelect=".my-anchor-element" />
```

Check [the V5 docs](https://react-tooltip.com/docs/getting-started) for more complex use cases.

### Standalone

You can import `node_modules/react-tooltip/dist/react-tooltip.[mode].js` into your page. Please make sure that you have already imported `react` and `react-dom` into your page.
Expand All @@ -98,27 +122,26 @@ PS: all the files have a minified version and a non-minified version.

For all available options, please check [React Tooltip Options](https://react-tooltip.com/docs/options)

### Security Note
### Security note

The `html` option allows a tooltip to directly display raw HTML. This is a security risk if any of that content is supplied by the user. Any user-supplied content must be sanitized, using a package like [sanitize-html](https://www.npmjs.com/package/sanitize-html). We chose not to include sanitization after discovering it [increased our package size](https://github.com/wwayne/react-tooltip/issues/429) too much - we don't want to penalize people who don't use the `html` option.

#### JSX Note
#### JSX note

You can use React's [`renderToStaticMarkup`-function](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) to use JSX instead of HTML.
You can use [`React.renderToStaticMarkup()` function](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) to use JSX instead of HTML.
**Example:**

```jsx
import ReactDOMServer from 'react-dom/server';
[...]
<p id="my-element" data-tooltip-html={ReactDOMServer.renderToString(<div>I am <b>JSX</b> content</div>)}>
Hover me
</p>
<a
data-tooltip-id="my-tooltip"
data-tooltip-html={ReactDOMServer.renderToStaticMarkup(<div>I am <b>JSX</b> content</div>)}
>
◕‿‿◕
</a>
```

#### Note

- **id** is necessary, because `<ReactTooltip anchorId="my-element" />` finds the tooltip via this attribute

## Article

[How I insert sass into react component](https://medium.com/@wwayne_me/how-i-insert-sass-into-my-npm-react-component-b46b9811c226#.gi4hxu44a)
Expand Down
6 changes: 3 additions & 3 deletions bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"files": [
{
"path": "./dist/react-tooltip.cjs.min.js",
"maxSize": "14 kB"
"maxSize": "14.5 kB"
},
{
"path": "./dist/react-tooltip.esm.min.js",
"maxSize": "14 kB"
"maxSize": "14.5 kB"
},
{
"path": "./dist/react-tooltip.umd.min.js",
"maxSize": "14 kB"
"maxSize": "14.5 kB"
}
]
}
2 changes: 1 addition & 1 deletion docs/docs/examples/_category_.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"position": 4,
"link": {
"type": "generated-index",
"description": "Examples using props and some use cases with ReactTooltip component"
"description": "Examples for the tooltip props and some interesting use cases."
}
}
202 changes: 202 additions & 0 deletions docs/docs/examples/anchor-select.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
---
sidebar_position: 1
---

# Anchor select

Default color stylings available for the ReactTooltip component.

import { Tooltip } from 'react-tooltip'
import 'react-tooltip/dist/react-tooltip.css'

export const TooltipAnchor = ({ children, id, ...rest }) => {
return (
<span
id={id}
style={{
display: 'flex',
justifyContent: 'center',
margin: 'auto',
alignItems: 'center',
width: '60px',
height: '60px',
borderRadius: '60px',
color: '#222',
background: 'rgba(255, 255, 255, 1)',
cursor: 'pointer',
boxShadow: '3px 4px 3px rgba(0, 0, 0, 0.5)',
border: '1px solid #333',
}}
{...rest}
>
{children}
</span>
)
}

### Basic usage

The `anchorSelect` prop uses a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) to attach the tooltip to the anchor elements. The most common use for this is selecting elements with a specific id, or with a CSS class.

#### Using id attribute

:::info

A CSS selector for a specific id begins with a `#`. Don't forget to put it before the id on your selector!

:::

```jsx
import { Tooltip } from 'react-tooltip';
import 'react-tooltip/dist/react-tooltip.css';

<a id="my-anchor-element-id">◕‿‿◕</a>
<Tooltip
// Don't forget the `#`!
anchorSelect="#my-anchor-element-id"
content="Hello world!"
/>
```

<TooltipAnchor id="my-anchor-element-id">◕‿‿◕</TooltipAnchor>
<Tooltip
anchorSelect="#my-anchor-element-id"
content="Hello world!"
/>

#### Using class attribute

:::info

A CSS selector for a specific id begins with a `.`. Don't forget to put it before the class on your selector!

:::

```jsx
import { Tooltip } from 'react-tooltip';
import 'react-tooltip/dist/react-tooltip.css';

<a className="my-anchor-element-class">◕‿‿◕</a>
<a className="my-anchor-element-class">◕‿‿◕</a>
<a className="my-anchor-element-class">◕‿‿◕</a>
<a className="my-anchor-element-class">◕‿‿◕</a>
<Tooltip
// Don't forget the `.`!
anchorSelect=".my-anchor-element-class"
content="Hello world!"
/>
```

<div style={{ display: 'flex', gap: '5px', width: 'fit-content', margin: 'auto' }}>
<TooltipAnchor className="my-anchor-element-class">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor className="my-anchor-element-class">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor className="my-anchor-element-class">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor className="my-anchor-element-class">
◕‿‿◕
</TooltipAnchor>
</div>
<Tooltip
anchorSelect=".my-anchor-element-class"
content="Hello world!"
/>

### Complex selectors

Once you've understood how it works, you can write CSS selectors as complex as you can imagine. Here are some interesting examples.

#### Attribute prefix

:::info

`[attr^='prefix']` can be read as "any element that has an attribute `attr` in which its value starts with `prefix`". Remove the `^` for an exact match.

This example uses the name attribute, but it works for any HTML attribute (id, class, ...).

:::

```jsx
import { Tooltip } from 'react-tooltip';
import 'react-tooltip/dist/react-tooltip.css';

<a name="my-anchor-element-1">◕‿‿◕</a>
<a name="my-anchor-element-2">◕‿‿◕</a>
<a name="my-anchor-element-3">◕‿‿◕</a>
<a name="my-anchor-element-4">◕‿‿◕</a>
<Tooltip
anchorSelect="[name^='my-anchor-element-']"
content="Hello world!"
/>
```

<div style={{ display: 'flex', gap: '5px', width: 'fit-content', margin: 'auto' }}>
<TooltipAnchor name="my-anchor-element-1">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor name="my-anchor-element-2">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor name="my-anchor-element-3">
◕‿‿◕
</TooltipAnchor>
<TooltipAnchor name="my-anchor-element-4">
◕‿‿◕
</TooltipAnchor>
</div>
<Tooltip
anchorSelect="[name^='my-anchor-element-']"
content="Hello world!"
/>

#### Child selector

:::info

Make sure there isn't an easier alternative before diving into complex selectors like this.

Often you can just use a class selector or something else much simpler.

:::

```jsx
import { Tooltip } from 'react-tooltip';
import 'react-tooltip/dist/react-tooltip.css';

<section id="section-anchor-select" style={{ marginTop: '100px' }}>
<a>◕‿‿◕</a>
<a>◕‿‿◕</a>
<a>◕‿‿◕</a>
<a>◕‿‿◕</a>
</section>
<Tooltip
anchorSelect="section[id='section-anchor-select'] > a:nth-child(odd)"
content="I am an odd child!"
/>
<Tooltip
anchorSelect="section[id='section-anchor-select'] > a:nth-child(even)"
content="I am an even child!"
/>
```

<section
id="section-anchor-select"
style={{ display: 'flex', gap: '5px', width: 'fit-content', margin: 'auto' }}
>
<TooltipAnchor>◕‿‿◕</TooltipAnchor>
<TooltipAnchor>◕‿‿◕</TooltipAnchor>
<TooltipAnchor>◕‿‿◕</TooltipAnchor>
<TooltipAnchor>◕‿‿◕</TooltipAnchor>
</section>
<Tooltip
anchorSelect="section[id='section-anchor-select'] > span:nth-child(odd)"
content="I am an odd child!"
/>
<Tooltip
anchorSelect="section[id='section-anchor-select'] > span:nth-child(even)"
content="I am an even child!"
/>
Loading