Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- import _ from 'lodash';
- import React from 'react';
- import { unstable_renderSubtreeIntoContainer, unmountComponentAtNode } from 'react-dom'; // eslint-disable-line camelcase
- import classNames from 'classnames';
- import TooltipJS from 'tooltip.js';
- type Props = {
- className: string,
- element: string,
- label: React.ReactChild,
- placement?: 'top'|'right'|'bottom'|'left',
- };
- export default class Tooltip extends React.Component<Props> {
- static defaultProps = {
- element: 'div',
- };
- componentDidMount() {
- const { children, placement, className } = this.props;
- this.tooltipRoot = document.createElement('div');
- document.body.appendChild(this.tooltipRoot);
- this.contentContainer = document.createElement('div');
- this._mountContent(children, { placement, className });
- }
- componentWillUpdate(nextProps: Props) {
- if (nextProps.children !== this.props.children) {
- const { children, placement, className } = nextProps;
- this._mountContent(children, { placement, className });
- }
- }
- componentWillUnmount() {
- if (this.contentContainer) {
- const parent = this.contentContainer.parentElement;
- parent && parent.removeChild(this.contentContainer);
- }
- this.tooltipRoot.parant && this.tooltipRoot.parant.removeChild(this.tooltipRoot);
- this.tooltipRoot = null;
- this.contentContainer = null;
- this.tooltip.dispose();
- }
- /** ReactでマウントされたDOM要素のルート */
- rootEl: HTMLDivElement;
- /** ツールチップのマウント先要素 */
- tooltipRoot: HTMLDivElement;
- /** ツールチップに表示するコンテンツのコンテナ */
- contentContainer: HTMLDivElement;
- tooltip: any;
- _bindRoot = el => this.rootEl = el
- _mountContent(content: React.ReactChild, { placement, className }: { placement: string }) {
- unmountComponentAtNode(this.contentContainer);
- this.tooltip && this.tooltip.show().dispose(); // HACK: 一瞬マウントしないとdisposeされない
- this.tooltip = null;
- // HACK: ツールチップは document.body に追加した div要素(= this.tooltipRoot)へマウントさせる。
- // そうしないとツールチップのコンテナ以上の要素が`overflow`に`hidden`や`scroll`を設定していた時に、ツールチップが見切れてしまう
- if (_.isObject(content)) { // maybe ReactComponent
- unstable_renderSubtreeIntoContainer(this, content, this.contentContainer);
- this.tooltip = new TooltipJS(this.rootEl, { title: this.contentContainer, html: true, placement, container: this.tooltipRoot });
- } else {
- this.tooltip = new TooltipJS(this.rootEl, { title: content, placement, container: this.tooltipRoot });
- }
- this.tooltip.show().hide(); // HACK: .show()でpopperInstanceを生成させている
- const node: HTMLElement = this.tooltip.popperInstance.popper;
- node.className = classNames('tooltip', className);
- }
- render() {
- const { label, element: Element } = this.props;
- return (
- <Element ref={this._bindRoot}>
- {label}
- </Element>
- );
- }
- }
Add Comment
Please, Sign In to add comment