ReactJS + MaterialUI v1 автоматическое заполнение вложенным списком

У меня есть вложенные списки, и я не знаю, сколько их (рекурсивная функция). Как заставить их получить автоматическое заполнение?

В результате я получаю такой

ReactJS + MaterialUI v1 автоматическое заполнение вложенным списком:

И я хочу получить такой результат:

ReactJS + MaterialUI v1 автоматическое заполнение вложенным списком

Если я добавлю вложенные стили, они будут одинаковыми для всех вложенных списков. Мне нужно, чтобы отступы увеличивались с каждым следующим уровнем.

Вы можете помочь? (Все комментарии приветствуются!)

Код:

import React from 'react';
import {isNullOrUndefined} from "util";
import {TagNode} from "../interfaces/TagTree";
import HistoryDataUtility from "../../utilities/historyDataUtility";
import TreeUtility from "../../utilities/treeUtility";

import { createStyles } from '@material-ui/core/styles';
import { withStyles } from '@material-ui/core/styles';
import Checkbox from '@material-ui/core/Checkbox';
import Collapse from '@material-ui/core/Collapse';
import Icon from '@material-ui/core/Icon';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';


export interface TreeRendererProps {
    itemList: TagNode[],
    selectedTags: string[],
    expandedFolders: string[],
    onFolderToggle: any,
    onTagToggle: any,
    onSelectedFolderChange?: any,
    selectedFolder?: string,
    classes: {
        root: string;
        nested: string;
    }
}

const styles = createStyles({
    root: {
        width: '100%',
    },
    nested: {
        paddingLeft: 16
    }
});

const TreeRenderer: React.StatelessComponent<TreeRendererProps> = (props) => {


    const buildListItems = (item: TagNode,
                                                    selectedTags: string[],
                                                    onFolderToggle: any,
                                                    onTagToggle: any,
                                                    source: string) => {
        let key = HistoryDataUtility.combineTag(source, item.objId);
        let isExpanded = props.expandedFolders.indexOf(key) != -1;
        let isSelected: boolean = props.selectedFolder === key ? true : false;

        let children1: any, children2: any;

        if (!TreeUtility.isTagItem(item)) {
            children1 = item.children.filter(filterGroups).sort(sortOnTitle).map((child) => {
                                    return buildListItems(child,
                                        selectedTags,
                                        onFolderToggle,
                                        onTagToggle,
                                        source);
                                }) || null;
            children2 = item.children.filter(filterTags).sort(sortOnTitle).map((child) => {
                                    return buildListItems(child,
                                        selectedTags,
                                        onFolderToggle,
                                        onTagToggle,
                                        source);
                                }) || null;
        }

        let collapseItem: any;
        if (isExpanded && !isNullOrUndefined(item.children)) {
            collapseItem =
                <Collapse component = "li" in = {true} timeout = "auto" unmountOnExit>
                    <List disablePadding>
                        {children1}
                        {children2}
                    </List>
                </Collapse>
        }

        let key2 = "list" + Math.random().toString(36).substr(2, 9);

        return (
            !TreeUtility.isTagItem(item)
            ?
                <div key = {key2}>
                    <ListItem
                        button key = {key}
                        className = {props.classes.nested + " with-children"}
                        onClick = {onFolderToggle.bind(this, key)}
                        >
                        <ListItemIcon>
                            {isExpanded ? <Icon>remove</Icon> : <Icon>add</Icon>}
                        </ListItemIcon>
                        <ListItemText primary = {item.title} />
                        <ListItemSecondaryAction>
                            <Checkbox checked = {isSelected} color = "primary" onChange = {props.onSelectedFolderChange} value = {key} />
                        </ListItemSecondaryAction>
                    </ListItem>
                    {collapseItem}
                </div>

            :

                <ListItem
                    button
                    className = {props.classes.nested + " no-children" + ((selectedTags.indexOf(key) != -1 || selectedTags.indexOf(item.objId) != -1)    ? " tagitem-activated" : "")}
                    key = {key}
                    onClick = {onTagToggle.bind(this, key)}
                    >
                    <ListItemIcon><Icon className = "status">fiber_manual_record</Icon></ListItemIcon>
                    <ListItemText primary = {item.title} />
                </ListItem>
        );
    }

    const filterGroups = (item: TagNode): boolean => {
        return !TreeUtility.isTagItem(item);
    }

    const filterTags = (item: TagNode): boolean => {
        return TreeUtility.isTagItem(item);
    }

    const sortOnTitle = (a: TagNode, b: TagNode) => {
        var nameA = a.title.toUpperCase(); // ignore upper and lowercase
        var nameB = b.title.toUpperCase(); // ignore upper and lowercase
        if (nameA < nameB) {
            return -1;
        }
        if (nameA > nameB) {
            return 1;
        }
        // names must be equal
        return 0;
    }

    const buildList = (items: TagNode[],
                                         selectedTags: string[],
                                         onFolderToggle: any,
                                         onTagToggle: any) => {

        let children1: any, children2: any;

        children1 = items.filter(filterGroups).sort(sortOnTitle).map((item: TagNode) => {
                            let source = item.objId; //Use the top level group nodes id as source
                            return buildListItems(
                                item,
                                selectedTags,
                                onFolderToggle,
                                onTagToggle, source);
                        }) || null;

        children2 = items.filter(filterTags).sort(sortOnTitle).map((item: TagNode) => {
                            return buildListItems(
                                item,
                                selectedTags,
                                onFolderToggle,
                                onTagToggle, null);
                        }) || null;

        return (
             <List>
                {children1}
                {children2}
            </List>
        )
    }

    let tree;

    if (props.itemList.length > 0) {
        if (props.itemList[0].children != undefined) {
            tree = buildList(
                props.itemList[0].children,
                props.selectedTags,
                props.onFolderToggle,
                props.onTagToggle);
        } else {
            tree = <div>{props.itemList[0].name + ' : ' + props.itemList[0].title}</div>
        }
    } else {
        tree = <div><h2 className = "small">Model not found.</h2></div>;
    }

    return (<div>{tree}</div>);
}

export default withStyles(styles, { withTheme: true })(TreeRenderer);
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
0
698
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На самом деле решение удивительно простое. Просто измените эту строку:

<Collapse component = "li" in = {true} timeout = "auto" unmountOnExit>

к этому:

<Collapse component = "li" in = {true} timeout = "auto" unmountOnExit style = {{paddingLeft: '16px'}}>

Другие вопросы по теме