Skip to content

Adding middlewares #912

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 4 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/docs/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import 'react-tooltip/dist/react-tooltip.css'
| setIsOpen | function | false | | | the tooltip can be controlled or uncontrolled, this attribute can be used to handle show and hide tooltip outside tooltip |
| afterShow | function | false | | | a function to be called after the tooltip is shown |
| afterHide | function | false | | | a function to be called after the tooltip is hidden |
| middlewares | array | false | | array of valid `floating-ui` middlewares | allows for advanced customization. check the [`floating-ui` docs](https://floating-ui.com/docs/middleware) for more information |

### Data attributes

Expand Down
60 changes: 60 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TooltipProvider, TooltipWrapper } from 'components/TooltipProvider'
import { IPosition } from 'components/Tooltip/TooltipTypes.d'
import { useState } from 'react'
import styles from './styles.module.css'
import { inline, offset } from './index'

function WithProviderMinimal() {
return (
Expand Down Expand Up @@ -202,6 +203,65 @@ function App() {
content="Showing tooltip and calling afterShow method"
/>
</div>

<div
style={{
width: 700,
position: 'relative',
overflow: 'hidden',
marginTop: '1rem',

boxSizing: 'border-box',
}}
>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
<span id="withoutCustomMiddleware" style={{ color: 'blue', fontWeight: 'bold' }}>
labore et dolore magna aliqua
</span>
. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>

<Tooltip
place="top"
anchorId="withoutCustomMiddleware"
content="Showing tooltip with default middlewares"
positionStrategy="fixed"
/>
</div>

<div
style={{
width: 700,
position: 'relative',
overflow: 'hidden',
marginTop: '1rem',

boxSizing: 'border-box',
}}
>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
<span id="withCustomMiddleware" style={{ color: 'blue', fontWeight: 'bold' }}>
labore et dolore magna aliqua
</span>
. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>

<Tooltip
place="top"
anchorId="withCustomMiddleware"
content="Showing tooltip with custom inline middleware"
positionStrategy="fixed"
middlewares={[inline(), offset(10)]}
/>
</div>
</main>
)
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const Tooltip = ({
offset = 10,
events = ['hover'],
positionStrategy = 'absolute',
middlewares,
wrapper: WrapperElement = 'div',
children = null,
delayShow = 0,
Expand Down Expand Up @@ -150,6 +151,7 @@ const Tooltip = ({
tooltipReference: tooltipRef.current,
tooltipArrowReference: tooltipArrowRef.current,
strategy: positionStrategy,
middlewares,
}).then((computedStylesData) => {
setCalculatingPosition(false)
if (Object.keys(computedStylesData.tooltipStyles).length) {
Expand Down Expand Up @@ -299,6 +301,7 @@ const Tooltip = ({
tooltipReference: tooltipRef.current,
tooltipArrowReference: tooltipArrowRef.current,
strategy: positionStrategy,
middlewares,
}).then((computedStylesData) => {
if (!mounted) {
// invalidate computed positions after remount
Expand Down
4 changes: 4 additions & 0 deletions src/components/Tooltip/TooltipTypes.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ElementType, ReactNode, CSSProperties } from 'react'
import type { Middleware } from '@floating-ui/dom'

export type PlacesType = 'top' | 'right' | 'bottom' | 'left'

Expand All @@ -12,6 +13,8 @@ export type EventsType = 'hover' | 'click'

export type PositionStrategy = 'absolute' | 'fixed'

export type Middleware = Middleware

export type DataAttribute =
| 'place'
| 'content'
Expand Down Expand Up @@ -44,6 +47,7 @@ export interface ITooltip {
children?: ChildrenType
events?: EventsType[]
positionStrategy?: PositionStrategy
middlewares?: Middleware[]
delayShow?: number
delayHide?: number
float?: boolean
Expand Down
2 changes: 2 additions & 0 deletions src/components/TooltipController/TooltipController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const TooltipController = ({
children = null,
events = ['hover'],
positionStrategy = 'absolute',
middlewares,
delayShow = 0,
delayHide = 0,
float = false,
Expand Down Expand Up @@ -180,6 +181,7 @@ const TooltipController = ({
wrapper: tooltipWrapper,
events: tooltipEvents,
positionStrategy: tooltipPositionStrategy,
middlewares,
delayShow: tooltipDelayShow,
delayHide: tooltipDelayHide,
float: tooltipFloat,
Expand Down
2 changes: 2 additions & 0 deletions src/components/TooltipController/TooltipControllerTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
EventsType,
PositionStrategy,
IPosition,
Middleware,
} from 'components/Tooltip/TooltipTypes'

export interface ITooltipController {
Expand All @@ -24,6 +25,7 @@ export interface ITooltipController {
children?: ChildrenType
events?: EventsType[]
positionStrategy?: PositionStrategy
middlewares?: Middleware[]
delayShow?: number
delayHide?: number
float?: boolean
Expand Down
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
import type { ITooltipController } from './components/TooltipController/TooltipControllerTypes'
import type { ITooltipWrapper } from './components/TooltipProvider/TooltipProviderTypes'

export { offset, inline, shift, flip, autoPlacement, size } from '@floating-ui/dom'
export { TooltipController as Tooltip } from './components/TooltipController'
export { TooltipProvider, TooltipWrapper } from './components/TooltipProvider'
export type {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/compute-positions-types.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { Middleware } from '../components/Tooltip/TooltipTypes'

export interface IComputePositions {
elementReference?: Element | HTMLElement | null
tooltipReference?: Element | HTMLElement | null
tooltipArrowReference?: Element | HTMLElement | null
place?: 'top' | 'right' | 'bottom' | 'left'
offset?: number
strategy?: 'absolute' | 'fixed'
middlewares?: Middleware[]
}
6 changes: 4 additions & 2 deletions src/utils/compute-positions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computePosition, offset, flip, shift, arrow } from '@floating-ui/dom'
import { computePosition, offset, shift, arrow, flip } from '@floating-ui/dom'
import type { IComputePositions } from './compute-positions-types'

export const computeTooltipPosition = async ({
Expand All @@ -8,6 +8,7 @@ export const computeTooltipPosition = async ({
place = 'top',
offset: offsetValue = 10,
strategy = 'absolute',
middlewares = [offset(Number(offsetValue)), flip(), shift({ padding: 5 })],
}: IComputePositions) => {
if (!elementReference) {
// elementReference can be null or undefined and we will not compute the position
Expand All @@ -20,10 +21,11 @@ export const computeTooltipPosition = async ({
return { tooltipStyles: {}, tooltipArrowStyles: {} }
}

const middleware = [offset(Number(offsetValue)), flip(), shift({ padding: 5 })]
const middleware = middlewares

if (tooltipArrowReference) {
middleware.push(arrow({ element: tooltipArrowReference as HTMLElement, padding: 5 }))

return computePosition(elementReference as HTMLElement, tooltipReference as HTMLElement, {
placement: place,
strategy,
Expand Down