Skip to content

Commit

Permalink
add support for multi-trigger tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsinulhaq committed Oct 26, 2019
1 parent f0282cb commit 9cbad00
Show file tree
Hide file tree
Showing 9 changed files with 835 additions and 265 deletions.
14 changes: 7 additions & 7 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"dist/cjs/react-popper-tooltip.js": {
"bundled": 14603,
"minified": 7833,
"gzipped": 2309
"bundled": 14528,
"minified": 7979,
"gzipped": 2340
},
"dist/esm/react-popper-tooltip.js": {
"bundled": 14564,
"minified": 7809,
"gzipped": 2303,
"bundled": 14489,
"minified": 7955,
"gzipped": 2335,
"treeshaked": {
"rollup": {
"code": 172,
"import_statements": 152
},
"webpack": {
"code": 8517
"code": 8654
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ Each placement can have a variation from this list:

### trigger

> `string` | defaults to `hover`
> `string` or `string[]` | defaults to `"hover"`
The event that triggers the tooltip. One of `click`, `right-click`, `hover`, `focus`, and `none`.
The event(s) that trigger the tooltip. One of `click`, `right-click`, `hover`, `focus`, and `none`, or an array of them.

### getTriggerRef

Expand Down
8 changes: 8 additions & 0 deletions docs/readme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ _`followCursor` prop_
</div>
</Playground>

## Multi-trigger

<Playground>
<BasicTooltipTrigger trigger={['click', 'hover']} tooltip="Hello, World!">
Click or hover me!
</BasicTooltipTrigger>
</Playground>

## Controlled

_`tooltipShown` prop_
Expand Down
44 changes: 27 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-popper-tooltip",
"version": "2.9.1",
"version": "2.10.0",
"description": "React tooltip library built around react-popper",
"homepage": "https://react-popper-tooltip.netlify.com",
"repository": {
Expand All @@ -19,18 +19,27 @@
],
"scripts": {
"build": "rm -rf dist && rollup -c && cp src/styles.css dist && yarn tsc && rm -rf compiled",
"prepublishOnly": "yarn typecheck && yarn lint && yarn test && yarn build",
"prepublishOnly": "yarn typecheck && yarn lint && yarn build && yarn test",
"docs": "docz dev",
"docs:build": "docz build",
"typecheck": "tsc --noEmit",
"lint": "eslint src/**/*.{ts,tsx}",
"test": "jest"
},
"pre-commit": [
"typecheck",
"lint",
"test"
],
"husky": {
"hooks": {
"pre-commit": "yarn typecheck && yarn build && yarn test && lint-staged"
}
},
"lint-staged": {
"src/**/*.(ts|tsx)": [
"prettier --write",
"yarn lint --fix"
],
"*": [
"git add"
]
},
"keywords": [
"react",
"tooltip",
Expand Down Expand Up @@ -58,26 +67,27 @@
"@babel/preset-react": "^7.6.3",
"@babel/preset-typescript": "^7.6.0",
"@testing-library/react": "^9.3.0",
"@types/jest": "^24.0.19",
"@types/react": "^16.9.9",
"@types/react-dom": "^16.9.2",
"@typescript-eslint/eslint-plugin": "^2.4.0",
"@typescript-eslint/parser": "^2.4.0",
"@types/jest": "^24.0.20",
"@types/react": "^16.9.11",
"@types/react-dom": "^16.9.3",
"@typescript-eslint/eslint-plugin": "^2.5.0",
"@typescript-eslint/parser": "^2.5.0",
"docz": "^1.3.2",
"docz-plugin-css": "^0.11.0",
"docz-theme-default": "^1.2.0",
"eslint": "^6.5.1",
"eslint": "^6.6.0",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-react": "^7.16.0",
"husky": "^3.0.9",
"jest": "^24.9.0",
"pre-commit": "^1.2.2",
"lint-staged": "^9.4.2",
"prettier": "^1.18.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-hot-loader": "^4.12.15",
"rollup": "^1.25.0",
"rollup": "^1.25.2",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-size-snapshot": "^0.10.0",
Expand Down
4 changes: 2 additions & 2 deletions src/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Tooltip extends Component<TooltipProps> {
}));
observer.observe(this.tooltipRef!, MUTATION_OBSERVER_CONFIG);

if (trigger !== 'none') {
if (trigger !== 'none' && trigger !== 'focus') {
const {
removeParentOutsideClickHandler,
removeParentOutsideRightClickHandler
Expand Down Expand Up @@ -48,7 +48,7 @@ class Tooltip extends Component<TooltipProps> {
this.observer.disconnect();
}

if (trigger !== 'none') {
if (trigger !== 'none' && trigger !== 'focus') {
const {
isParentNoneTriggered,
addParentOutsideClickHandler,
Expand Down
33 changes: 17 additions & 16 deletions src/TooltipTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Tooltip from './Tooltip';
import {
GetTriggerPropsArg,
TooltipTriggerProps,
TooltipTriggerState
TooltipTriggerState,
TriggerTypes
} from './types';
import {callAll, canUseDOM, noop} from './utils';

Expand Down Expand Up @@ -204,31 +205,31 @@ class TooltipTrigger extends Component<
this[action]({pageX, pageY});
};

private getTriggerProps = (props: GetTriggerPropsArg = {}) => {
const {trigger, followCursor} = this.props;
const isClickTriggered = trigger === 'click';
const isHoverTriggered = trigger === 'hover';
const isRightClickTriggered = trigger === 'right-click';
const isFocusTriggered = trigger === 'focus';
private isTriggeredBy(event: TriggerTypes) {
const {trigger} = this.props;
return (
trigger === event || (Array.isArray(trigger) && trigger.includes(event))
);
}

private getTriggerProps = (props: GetTriggerPropsArg = {}) => {
return {
...props,
...(isClickTriggered && {
...(this.isTriggeredBy('click') && {
onClick: callAll(this.clickToggle, props.onClick),
onTouchEnd: callAll(this.clickToggle, props.onTouchEnd)
}),
...(isRightClickTriggered && {
...(this.isTriggeredBy('right-click') && {
onContextMenu: callAll(this.contextMenuToggle, props.onContextMenu)
}),
...(isHoverTriggered && {
...(this.isTriggeredBy('hover') && {
onMouseEnter: callAll(this.showTooltip, props.onMouseEnter),
onMouseLeave: callAll(this.hideTooltip, props.onMouseLeave)
}),
...(isHoverTriggered &&
followCursor && {
onMouseLeave: callAll(this.hideTooltip, props.onMouseLeave),
...(this.props.followCursor && {
onMouseMove: callAll(this.showTooltip, props.onMouseMove)
}),
...(isFocusTriggered && {
})
}),
...(this.isTriggeredBy('focus') && {
onFocus: callAll(this.showTooltip, props.onFocus),
onBlur: callAll(this.hideTooltip, props.onBlur)
})
Expand Down
5 changes: 3 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import ReactPopper from 'react-popper';

export type TriggerTypes = 'none' | 'click' | 'right-click' | 'hover' | 'focus';
export type Trigger = TriggerTypes | TriggerTypes[];

export interface GetTriggerPropsArg {
onTouchEnd?(event: React.SyntheticEvent): void;
Expand Down Expand Up @@ -102,7 +103,7 @@ export interface TooltipTriggerProps {
* Event that triggers the tooltip
* @default hover
*/
trigger: TriggerTypes;
trigger: Trigger;
/**
* Whether to use React.createPortal for creating tooltip
* @default true // for browser environments
Expand Down Expand Up @@ -136,7 +137,7 @@ export interface TooltipProps {
outOfBoundaries: boolean | null;
placement: PopperJS.Placement;
style: React.CSSProperties;
trigger: TriggerTypes;
trigger: Trigger;
clearScheduled(): void;
hideTooltip(): void;
tooltip(arg: TooltipArg): React.ReactNode;
Expand Down
37 changes: 37 additions & 0 deletions tests/TooltipTrigger.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,43 @@ describe('focus trigger', () => {
});
});

describe('multi trigger', () => {
let container: HTMLElement;
let queryByText: any;

beforeEach(() => {
({container, queryByText} = render(
<BasicTooltipTrigger trigger={['hover', 'focus']} tooltip={Tooltip}>
{Trigger}
</BasicTooltipTrigger>
));
fireEvent.focus(container.firstChild as HTMLElement);
jest.runAllTimers();
});

it('opens tooltip on focus', () => {
expect(queryByText(Tooltip)).toBeTruthy();
});

it('closes tooltip on blur', () => {
fireEvent.blur(container.firstChild as HTMLElement);
jest.runAllTimers();
expect(queryByText(Tooltip)).toBeFalsy();
});

it('opens tooltip on mouseEnter', () => {
fireEvent.mouseEnter(container.firstChild as HTMLElement);
jest.runAllTimers();
expect(queryByText(Tooltip)).toBeTruthy();
});

it('closes tooltip on mouseLeave', () => {
fireEvent.mouseLeave(container.firstChild as HTMLElement);
jest.runAllTimers();
expect(queryByText(Tooltip)).toBeFalsy();
});
});

it('closes on outside click', () => {
const {container, queryByText} = render(
<>
Expand Down
Loading

0 comments on commit 9cbad00

Please sign in to comment.