Log

いろいろ

Reactで長文を短縮表示してツールチップを表示する

ググると出てくる-webkit-boxを利用した方法。IE終焉により思いきれる人も多そうです。今年はIEがWebアプリケーションへたくさん貢献していますね。

実装は宗教上の理由でレガシーなReactで書きます。「Deprecatedォォォオオオ!!!!!」とエディタに怒られて悲しいです。

import React, { Component } from 'react';


export default class EllipsisText extends Component {
    constructor(props) {
        super(props);
        this.ref = React.createRef();
        this.state = {
            isEllipsis: false
        };
    }

    componentDidMount() {
        this.resizeObserver = new ResizeObserver(() =>{
            this.setIsEllipsis(this.ref.current);
        });
        this.resizeObserver.observe(this.ref.current);
    }

    componentWillUnmount() {
        this.resizeObserver.disconnect();
    }

    setIsEllipsis(element) {
        if (element) {
            this.setState({ isEllipsis: element.offsetHeight < element.scrollHeight });
        }
    }

    render() {
        return (
            <div
                ref={this.ref}
                className='ellipsis-text'
                style={{ WebkitLineClamp: this.props.maxRows }}
                title={this.state.isEllipsis && this.props.value}
            >
                {this.props.value}
            </div>
        )
    }
}
.ellipsis-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
}

CSSはAutoprexierによって-webkit-box-orient: vertical;が抹消されることがある点に注意。

Autoprefixer導入時に「-webkit-box-orient」が消える問題への対応 - Qiita

React.createRef()を使ってdivへの参照を保持します。this.ref.currentでアクセスして通常のDOM操作ができます。

Ref と DOM – React

あとはリサイズ監視。resizeイベントだと要素のリサイズは検知できないのでResizeObserverを使います。

ResizeObserver - Web API | MDN

参考

javascript - How to detect overflow of React component without ReactDOM? - Stack Overflow