diff --git a/index.d.ts b/index.d.ts index d6fa046..750eda6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,5 +1,5 @@ -import React from 'react'; -import { Instance, Props } from 'tippy.js'; +import React from 'react' +import { Instance, Props } from 'tippy.js' type Omit = Pick> @@ -7,6 +7,8 @@ export interface TippyProps extends Omit { content: React.ReactNode | string children: React.ReactNode onCreate?: (tip: Instance) => void + isVisible?: boolean + isEnabled?: boolean } export default class Tippy extends React.Component {} diff --git a/src/Tippy.js b/src/Tippy.js index daf1cb9..4ca6504 100644 --- a/src/Tippy.js +++ b/src/Tippy.js @@ -3,15 +3,17 @@ import ReactDOM from 'react-dom' import PropTypes from 'prop-types' import tippy from 'tippy.js' -// Avoid Babel's large '_objectWithoutProperties' helper function -const getNativeTippyProps = props => { - const nativeProps = {} - for (const prop in props) { - if (prop !== 'children' && prop !== 'onCreate') { - nativeProps[prop] = props[prop] +// These props are not native to `tippy.js` and are specific to React only. +const REACT_ONLY_PROPS = ['children', 'onCreate', 'isVisible', 'isEnabled'] + +// Avoid Babel's large '_objectWithoutProperties' helper function. +function getNativeTippyProps(props) { + return Object.keys(props).reduce((acc, key) => { + if (REACT_ONLY_PROPS.indexOf(key) === -1) { + acc[key] = props[key] } - } - return nativeProps + return acc + }, {}) } class Tippy extends React.Component { @@ -23,7 +25,9 @@ class Tippy extends React.Component { content: PropTypes.oneOfType([PropTypes.string, PropTypes.element]) .isRequired, children: PropTypes.element.isRequired, - onCreate: PropTypes.func + onCreate: PropTypes.func, + isVisible: PropTypes.bool, + isEnabled: PropTypes.bool } get isReactElementContent() { @@ -37,21 +41,55 @@ class Tippy extends React.Component { } } + get isManualTrigger() { + return this.props.trigger === 'manual' + } + componentDidMount() { this.setState({ isMounted: true }) + this.tip = tippy.one(ReactDOM.findDOMNode(this), this.options) - this.props.onCreate && this.props.onCreate(this.tip) + + const { onCreate, isEnabled, isVisible } = this.props + + if (onCreate) { + onCreate(this.tip) + } + + if (isEnabled === false) { + this.tip.disable() + } + + if (this.isManualTrigger && isVisible === true) { + this.tip.show() + } } componentDidUpdate() { this.tip.set(this.options) + + const { isEnabled, isVisible } = this.props + + if (isEnabled === true) { + this.tip.enable() + } + if (isEnabled === false) { + this.tip.disable() + } + + if (this.isManualTrigger) { + if (isVisible === true) { + this.tip.show() + } + if (isVisible === false) { + this.tip.hide() + } + } } componentWillUnmount() { - if (this.tip) { - this.tip.destroy() - this.tip = null - } + this.tip.destroy() + this.tip = null } render() { diff --git a/test/Tippy.test.js b/test/Tippy.test.js index cf3b70b..9ba50d8 100644 --- a/test/Tippy.test.js +++ b/test/Tippy.test.js @@ -1,121 +1,104 @@ import React from 'react' import Tippy from '../src/Tippy' -import { mount } from 'enzyme' import ReactDOMServer from 'react-dom/server' +import { render, fireEvent, cleanup } from 'react-testing-library' + +afterEach(cleanup) describe('', () => { test('renders only the child element', () => { - const wrapper = mount( + const stringContent = render( ') + const reactElementContent = render( + tooltip}> + ') }) test('adds a tippy instance to the child node', () => { - const wrapper = mount( + const { container } = render( - - + render( + + - } - } - const wrapper = mount( -
- -
+ const Child = () =>