Как развернуть и свернуть каждый элемент списка с помощью react?

#css #reactjs

#css — код #reactjs

Вопрос:

я хочу отобразить список элементов на боковой панели. Если высота содержимого в элементе списка превышает 36 пикселей, я хочу скрыть содержимое размером более 36 пикселей и показать кнопку расширения для этого элемента списка (содержимое которого превысило 36 пикселей), и нажатие кнопки расширения должно показать все содержимое элемента списка.

Что я пробовал до сих пор? Я добавил ссылку к элементу span, содержащему переполняемый текст. и кнопка «Развернуть» появляется, если высота элемента span превышает 36 пикселей, а нажатие кнопки «Развернуть» показывает содержимое элемента списка.

В чем проблема сейчас? Это работает нормально. за исключением того, что кнопки расширения добавляются в конце всех элементов списка …. я хочу, чтобы они отображались внизу этого конкретного элемента списка, содержимое которого превышает 36 пикселей.

Это работает так, как показано на рисунке ниже.

пример изображения

Ниже приведен код,

 switch (notification.type) {
    case 'new_model_uploaded':
        return (
            <Notification
                icon={<SvgProject width="26" height="26"/>}
                text={<Text
                    base_height={36}
                    name={name}
                    text=' created'
                    item_name={itemname}/>}
                timestamp={notification.timestamp}>
                <div className="additional_details">
                    <Image
                        width={70}
                        height={70}
                        item_id={filtered_item.id}
                    />
                </div>
            </Notification>
        );
    case 'deleted':
        return (
            <List
                icon={<Svg width="20" height="22"/>}
                text={<Text
                    base_height={36}
                    name={list.name}
                    text=' deleted item '
                    item_name={itemname}/>}
                    timestamp={item.timestamp}/>
        );
    default:
        return null;
}

function List(props) {
    return (
        <li className="list">
            <div className="details_container">
                <div className="details">
                    {props.icon}
                    {props.text}
                    <Time>{props.timestamp}</Time>
                </div>
                {props.children}
            </div>
        </li>
    );
}

class Text extends React.PureComponent {
    constructor(props) {
        super(props);
        this.span_ref = React.createRef();
        this.state = {
            expanded: false,
            overflow: false,
        };
     }

     componentDidMount () {
         if (this.span_ref.current.offsetHeight < 
         this.span_ref.current.scrollHeight) {
             this.setState({overflow: true});
         }
     }

     set_expanded = () => {
          this.setState({expanded: !this.state.expanded});
     };

     render () {
         return (
             <span ref={this.span_ref} className={this.props.classname} 
                 style={{overflow: 'hidden', height: (this.state.expanded ? 
                 null : this.props.base_height)}}>
                 <span className="red">{name}</span> {this.props.text} 
                     <span className="red">{this.props.name} 
                         {this.props.item_name}</span>
                         {this.props.additional_text}

                {this.state.overflow amp;amp; <button onClick={this.set_expanded} 
                    style={{position: 'absolute', bottom: 
                    0}}>expand</button>}
           </span> 
       );
    }
}

.list {
    display: flex;
    flex-direction: row;
    font-size: 12px;
    padding: 8px;
    min-height: 49px;

    li {
        list-style: none;
    }

   .details_container {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        margin-right: 8px;

       .details {
            display: flex;
            color: #333;
            align-items: center;
            justify-content: center;
            flex-grow: 1;

            svg {
                margin-right: 8px;
                margin-left: 7px;
                flex: 0 0 auto;
                align-self: center;
                flex-shrink: 0;
            }

            span {
                flex-grow: 1;
            }


            time {
                flex: 0 0 auto;
                margin-left: 8px;
                padding-top: 2px;
                color: #CCCCCC;
            }
        } 

        span {
            word-break: break-all;
        }
    }
}
 

Комментарии:

1. Хотя код не завершен, но можете ли вы попробовать поместить position: relative для самого внешнего диапазона в текстовом компоненте, чтобы кнопка располагалась относительно этого диапазона?

2. спасибо добавил контейнер для элемента span и добавил к нему ссылку.