All files / TreeSelect index.js

100% Statements 19/19
100% Branches 6/6
100% Functions 6/6
100% Lines 18/18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58            2x 11x 11x 84x 84x 84x       2x 22x 22x 22x   22x   9x         22x   11x 11x 84x         22x                             2x            
import React, { useState, useEffect } from "react"
import TreeNodes from "./TreeNodes"
import PropTypes from "prop-types"
import SearchInput from "../SearchInput"
import styles from "./styles.css"
 
const mapNodes = (filter, nodes) => {
    filter = filter.toLowerCase()
    return nodes.map(node => {
        const label = node.label.toLowerCase()
        const hidden = label.indexOf(filter) < 0
        return { ...node, props: { hidden } }
    })
}
 
const TreeSelect = React.memo(props => {
    const [nodes, setNodes] = useState(props.nodes)
    const [visibleNodes, setVisibleNodes] = useState(props.nodes)
    const [filter, setFilter] = useState(props.filter || "")
 
    useEffect(
        () => {
            setFilter(props.filter || "")
        },
        [props.filter]
    )
 
    useEffect(
        () => {
            const mappedNodes = mapNodes(filter, props.nodes)
            setNodes(mappedNodes)
            setVisibleNodes(mappedNodes.filter(n => !n.props.hidden))
        },
        [props.nodes, filter]
    )
 
    return (
        <div className={styles.root}>
            <SearchInput value={filter} onChange={setFilter} />
            {!!visibleNodes.length && (
                <TreeNodes
                    nodes={nodes}
                    onChange={props.onChange}
                    values={props.values}
                    unremovableValues={props.unremovableValues}
                />
            )}
        </div>
    )
})
 
TreeSelect.propTypes = {
    nodes: PropTypes.array.isRequired,
    values: PropTypes.array
}
 
export default TreeSelect