rc-adminlte
Version:
AdminLTE template ported to React
118 lines (108 loc) • 3.72 kB
JSX
/* eslint-disable max-len */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import jQuery from 'jquery';
import './Sidebar.css';
import Item from './Item';
import Header from './Header';
import UserPanel from './UserPanel';
import Searchbar from './Searchbar';
class Sidebar extends Component {
state = {
searchValue: '',
}
constructor(props) {
super(props);
this.onSearchValueChange = this.onSearchValueChange.bind(this);
}
componentDidMount() {
jQuery(this.widgetReference).tree();
}
onSearchValueChange({ target: { value } }) {
this.setState({ searchValue: value });
}
render() {
const { children, searchbarFilter } = this.props;
let localChildren;
if (children) {
localChildren = children.length ? children : [children];
} else {
localChildren = [];
}
if (searchbarFilter) {
const localSearchbar = localChildren.find(p => p.type === Searchbar);
if (localSearchbar) {
const index = localChildren.map(p => p.type).indexOf(Searchbar);
const temp = [];
// eslint-disable-next-line no-plusplus
for (let i = 0; i < localChildren.length; ++i) {
if (i !== index) {
temp.push(localChildren[i]);
} else {
const { onChange, ...tempProps } = localSearchbar.props;
temp.push(React.cloneElement(localSearchbar, { onChange: this.onSearchValueChange, ...tempProps }));
}
}
localChildren = temp;
const { searchValue } = this.state;
if (searchValue.length > 0) {
const flatten = function flatten(element) {
if (!element.props) {
return [];
}
const { children: elemChildren, ...otherProps } = element.props;
const elemWithoutChildren = React.cloneElement(element, otherProps, null);
if (elemChildren) {
let intermediate;
if (typeof elemChildren !== 'string' && elemChildren.length) {
intermediate = elemChildren.map(flatten).flat();
} else {
intermediate = flatten(elemChildren);
}
intermediate.push(elemWithoutChildren);
return intermediate;
}
return [elemWithoutChildren];
};
const flattenChildren = localChildren.filter(p => p.type === Item).map(flatten).flat().filter(p => p.props.to);
const others = localChildren.filter(p => p.type === UserPanel || p.type === Searchbar);
localChildren = others.concat(flattenChildren
.filter(p => p.props.text.toUpperCase().indexOf(searchValue.toUpperCase()) > -1));
}
}
}
return (
<aside className="main-sidebar">
<section className="sidebar">
<ul className="sidebar-menu" data-widget="tree" ref={(c) => { this.widgetReference = c; }}>
{localChildren}
</ul>
</section>
</aside>
);
}
}
Sidebar.defaultProps = {
children: null,
searchbarFilter: false,
};
Sidebar.propTypes = {
children(props, propName, componentName) {
const prop = props[propName];
let error;
React.Children.forEach(prop, (el) => {
if (error) return;
if (el.type !== Item && el.type !== Header && el.type !== 'li' && el.type !== UserPanel && el.type !== Searchbar) {
error = new Error(
`\`${componentName}\` only accepts \`Item's, Header's, UserPanel, Searchbar and li's\`.`,
);
}
});
return error;
},
searchbarFilter: PropTypes.bool,
};
export default Sidebar;
export {
Item, Sidebar as Core, Header, UserPanel, Searchbar,
};