固定数据中的悬停工具提示内容 Table

Hover tooltip content in Fixed Data Table

我想为 Fixed Data Table component. I use react-tippy 单元格中的工具提示内容实现 clickhover 事件,用于带有 html 选项的工具提示以创建下拉菜单。我可以显示工具提示,但我无法为工具提示中的内容添加额外的事件。

onMouseEnteronClick ActionCell.jsx中的.actions-list__item事件未被触发。

react-tippy-data-table.firebaseapp.com

我无法在 jsfiddle 中 运行 react-tippy,所以我将示例项目部署到 firebase 中。

Table.jsx

import React, { Component } from 'react';
import debounce from 'lodash/debounce';
import { Table, Column, Cell } from 'fixed-data-table-2';
import ActionCell from './ActionCell.jsx';
import 'fixed-data-table-2/dist/fixed-data-table.min.css';

export default class TestMeetView extends Component {
  static propTypes = {};

  state = {
    tableData: [
      {
        start: '5/19',
        end: '5/20',
        host: 'DACA',
      },
      {
        start: '6/15',
        end: '6/15',
        host: 'DACA',
      },
      {
        start: '6/16',
        end: '6/17',
        host: 'DACA',
      },
      {
        start: '7/15',
        end: '7/16',
        host: 'DACA',
      },
      {
        start: '7/30',
        end: '7/31',
        host: 'DACA',
      },
    ],
    columnWidths: {
      start: 200,
      end: 200,
      host: 200,
      action: 100,
    },
    tableContainerWidth: 0,
    scrollToRow: null,
  };

  componentDidMount() {
    this.updateWidth();
    this.updateWidth = debounce(this.updateWidth, 200);
    window.addEventListener('resize', this.updateWidth);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateWidth);
  }

  onTableColumnResizeEndCallback = (newColumnWidth, columnKey) => {
    this.setState(({ columnWidths }) => ({
      columnWidths: {
        ...columnWidths,
        [columnKey]: newColumnWidth,
      },
    }));
  };

  updateWidth = () => {
    if (
      this.tableContainer &&
      this.tableContainer.offsetWidth !== this.state.tableContainerWidth
    ) {
      const newTableContainerWidth = this.tableContainer.offsetWidth;
      this.setState({
        tableContainerWidth: newTableContainerWidth,
        columnWidths: {
          start: newTableContainerWidth / 4,
          end: newTableContainerWidth / 4,
          host: newTableContainerWidth / 4,
          action: newTableContainerWidth / 4,
        },
      });
    }
  };

  render() {
    return (
      <div className="test-view">
        <div className="container-fluid">
          <div className="mb-5" ref={el => (this.tableContainer = el)}>
            <Table
              scrollToRow={this.state.scrollToRow}
              rowsCount={this.state.tableData.length}
              rowHeight={50}
              headerHeight={50}
              width={this.state.tableContainerWidth}
              height={300}
              touchScrollEnabled
              onColumnResizeEndCallback={this.onTableColumnResizeEndCallback}
              isColumnResizing={false}
            >
              <Column
                columnKey="start"
                header={<Cell>Start</Cell>}
                cell={props => <Cell {...props}>{this.state.tableData[props.rowIndex].start}</Cell>}
                width={this.state.columnWidths.start}
                isResizable
              />
              <Column
                columnKey="end"
                header={<Cell>End</Cell>}
                cell={props => <Cell {...props}>{this.state.tableData[props.rowIndex].end}</Cell>}
                width={this.state.columnWidths.end}
                isResizable
              />
              <Column
                columnKey="host"
                header={<Cell>Host</Cell>}
                cell={props => <Cell {...props}>{this.state.tableData[props.rowIndex].host}</Cell>}
                width={this.state.columnWidths.host}
                isResizable
              />
              <Column
                columnKey="action"
                header={<Cell>Action</Cell>}
                cell={<ActionCell />}
                width={this.state.columnWidths.action}
                isResizable
              />
            </Table>
          </div>
        </div>
      </div>
    );
  }
}

ActionCell.jsx

import React from 'react';
import { Cell } from 'fixed-data-table-2';
import { Tooltip } from 'react-tippy';
import 'actionCell.scss';

const { StyleSheet, css } = require('aphrodite');

export default class ActionCell extends React.PureComponent {
  render() {
    const {data, rowIndex, columnKey, collapsedRows, callback, ...props} = this.props;
    return (
      <Cell {...props} className={css(styles.actionCell)}
      onMouseEnter={() => { console.log('cell mouse enter') }}
      onMouseLeave={() => { console.log('cell mouse leave') }}
      >
        <Tooltip
          title="action"
          position="bottom"
          trigger="click"
          animation="fade"
          theme="light"
          arrow
          html={
            <ul className="actions-list">
              <li className="actions-list__item text-left"
              onMouseEnter={() => { console.log('list item mouse enter') }}
              onMouseLeave={() => { console.log('list item mouse leave') }}
              onClick={() => { console.log('list item click') }}>Close</li>
              <li className="actions-list__item text-left">Details</li>
              <li className="actions-list__item text-left">Edit</li>
              <li className="actions-list__item text-left">Delete</li>
            </ul>
        }
        >
          <div className="action-cell">
            <i className="fa fa-ellipsis-h fa-lg action-cell__icon" />
          </div>
        </Tooltip>
      </Cell>
    );
  }
}

const styles = StyleSheet.create({
  actionCell: {
    cursor: 'pointer',
  },
});

我需要使用 interactive parameter for react-tippy

<pre>
    import React from 'react';

    import Tooltip from './Tooltip';

    interface IProps {
        className?: string;
        value?: string;
        colSpan?: number;
    };

    interface IState {
        status: boolean
    };

    class TableCell extends React.Component<IProps, IState> {
        private myRef = React.createRef();
        constructor (props: IProps) {
            super(props);
            this.state = {
                status: false
            }
        }
        hoverHandler(event: any) {
            if (event.target.scrollWidth > event.target.offsetWidth) {
                this.setState({
                    status: true
                });
            } else {
                this.setState({
                    status: false
                });
            }
        }
        render () {
            return (
                <td colSpan={this.props.colSpan} className={this.props.className}>
                    <span onMouseEnter={this.hoverHandler.bind(this)} className="td-overflow">
                        {this.props.value}
                    </span>
                    <Tooltip
                        status={this.state.status}
                        value={this.props.value}>
                    </Tooltip>
                </td>
            );
        }
    };

    export default TableCell;

    // in other file use the custom Tooltip component
    import React from 'react';

    interface IProps {
        value?: string;
        status?: boolean;
    };

    interface IState {
    };

    class Tooltip extends React.Component<IProps, IState> {
        render () {
            if (this.props.status) {
                return (
                    <span className="tooltip">
                        {this.props.value}
                    </span>
                );
            }
            return (
                <span>
                </span>
            );
        }
    };

    export default Tooltip;

    // corresponding css

    .tooltip {
      display: none;
      position: absolute; 
      z-index: 100;
      border: 1px;
      background-color:white;
      border-style: solid;
      border-width: 1px;
      border-color:#0c7c84;
      padding: 5px;
      color:#0c7c84;
      font-size: 16px;
      border-radius: 5px;
      top: -50px;
      left: 50px;
      white-space: pre-line;
      word-break: break-all;
      width:100%;
    }
    .td-overflow {
      display: inline-block;
      overflow: hidden;
      width: 90%;
      text-overflow: ellipsis;
    }
</pre>

you can use the custom tooltip component to show tooltip on hover, tooltip visible only if data is over flow in td.