web: components: Styling AdvancedSelector for People groups selector
This commit is contained in:
parent
aade91af35
commit
30027112f9
@ -12,6 +12,8 @@ import { isArrayEqual } from "../../utils/array";
|
||||
import findIndex from "lodash/findIndex";
|
||||
import filter from "lodash/filter";
|
||||
import DropDown from "../drop-down";
|
||||
import { handleAnyClick } from "../../utils/event";
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable react/prop-types */
|
||||
@ -32,16 +34,27 @@ const Container = ({
|
||||
groups,
|
||||
selectedGroups,
|
||||
onChangeGroup,
|
||||
isOpen,
|
||||
isDropDown,
|
||||
containerWidth,
|
||||
containerHeight,
|
||||
...props
|
||||
}) => <div {...props} />;
|
||||
/* eslint-enable react/prop-types */
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
const StyledContainer = styled(Container)`
|
||||
${props => (props.width ? `width: ${props.width}px;` : "")}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
${props => (props.containerWidth ? `width: ${props.containerWidth}px;` : "")}
|
||||
${props =>
|
||||
props.containerHeight
|
||||
? `height: ${props.containerHeight}px;`
|
||||
: ""}
|
||||
|
||||
.data_container {
|
||||
margin: 16px;
|
||||
margin: 16px 16px 0 16px;
|
||||
|
||||
.options_searcher {
|
||||
margin-bottom: 12px;
|
||||
@ -53,7 +66,7 @@ const StyledContainer = styled(Container)`
|
||||
|
||||
.option_select_all_checkbox {
|
||||
margin-bottom: 12px;
|
||||
margin-left: 8px;
|
||||
/*margin-left: 8px;*/
|
||||
}
|
||||
|
||||
.options_list {
|
||||
@ -62,25 +75,26 @@ const StyledContainer = styled(Container)`
|
||||
cursor: pointer;
|
||||
|
||||
.option_checkbox {
|
||||
margin-left: 8px;
|
||||
/*margin-left: 8px;*/
|
||||
}
|
||||
|
||||
.option_link {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
/*&:hover {
|
||||
background-color: #eceef1;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button_container {
|
||||
border-top: 1px solid #eceef1;
|
||||
display: flex;
|
||||
|
||||
.add_members_btn {
|
||||
margin: 16px;
|
||||
width: 293px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -89,6 +103,8 @@ class AdvancedSelector extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.ref = React.createRef();
|
||||
|
||||
const groups = this.convertGroups(this.props.groups);
|
||||
const currentGroup = this.getCurrentGroup(groups);
|
||||
|
||||
@ -98,25 +114,53 @@ class AdvancedSelector extends React.Component {
|
||||
groups: groups,
|
||||
currentGroup: currentGroup
|
||||
};
|
||||
|
||||
if (props.isOpen) handleAnyClick(true, this.handleClick);
|
||||
}
|
||||
|
||||
handleClick = e => {
|
||||
if (this.props.isOpen && !this.ref.current.contains(e.target)) {
|
||||
this.props.onSelect && this.props.onSelect(this.state.selectedOptions);
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
handleAnyClick(false, this.handleClick);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
let newState = {};
|
||||
|
||||
if (!isArrayEqual(this.props.selectedOptions, prevProps.selectedOptions)) {
|
||||
this.setState({ selectedOptions: this.props.selectedOptions });
|
||||
newState = { selectedOptions: this.props.selectedOptions };
|
||||
}
|
||||
|
||||
if (this.props.isMultiSelect !== prevProps.isMultiSelect) {
|
||||
this.setState({ selectedOptions: [] });
|
||||
newState = Object.assign({}, newState, {
|
||||
selectedOptions: []
|
||||
});
|
||||
}
|
||||
|
||||
if (this.props.selectedAll !== prevProps.selectedAll) {
|
||||
this.setState({ selectedAll: this.props.selectedAll });
|
||||
newState = Object.assign({}, newState, {
|
||||
selectedAll: this.props.selectedAll
|
||||
});
|
||||
}
|
||||
|
||||
if (!isArrayEqual(this.props.groups, prevProps.groups)) {
|
||||
const groups = this.convertGroups(this.props.groups);
|
||||
const currentGroup = this.getCurrentGroup(groups);
|
||||
this.setState({ groups, currentGroup });
|
||||
newState = Object.assign({}, newState, {
|
||||
groups, currentGroup
|
||||
});
|
||||
}
|
||||
|
||||
if(!isEmpty(newState)) {
|
||||
this.setState({ ...this.state, ...newState });
|
||||
}
|
||||
|
||||
if (this.props.isOpen !== prevProps.isOpen) {
|
||||
handleAnyClick(this.props.isOpen, this.handleClick);
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +259,6 @@ class AdvancedSelector extends React.Component {
|
||||
const {
|
||||
value,
|
||||
placeholder,
|
||||
maxHeight,
|
||||
isDisabled,
|
||||
onSearchChanged,
|
||||
options,
|
||||
@ -225,9 +268,19 @@ class AdvancedSelector extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
const { selectedOptions, selectedAll, currentGroup, groups } = this.state;
|
||||
|
||||
const containerHeight = !groups || !groups.length ? 336 : 545;
|
||||
const containerWidth = !groups || !groups.length ? 325 : 690;
|
||||
const listHeight = 176;
|
||||
const itemHeight = 32;
|
||||
|
||||
return (
|
||||
<StyledContainer {...this.props}>
|
||||
<div className="data_container">
|
||||
<StyledContainer
|
||||
containerHeight={containerHeight}
|
||||
containerWidth={containerWidth}
|
||||
{...this.props}
|
||||
>
|
||||
<div className="data_container" ref={this.ref}>
|
||||
<SearchInput
|
||||
className="options_searcher"
|
||||
isDisabled={isDisabled}
|
||||
@ -264,10 +317,10 @@ class AdvancedSelector extends React.Component {
|
||||
)}
|
||||
<FixedSizeList
|
||||
className="options_list"
|
||||
height={maxHeight}
|
||||
itemSize={32}
|
||||
itemCount={options.length}
|
||||
itemData={options}
|
||||
height={listHeight}
|
||||
itemSize={itemHeight}
|
||||
itemCount={this.props.options.length}
|
||||
itemData={this.props.options}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
>
|
||||
{this.renderRow.bind(this)}
|
||||
@ -310,8 +363,7 @@ AdvancedSelector.propTypes = {
|
||||
value: PropTypes.string,
|
||||
placeholder: PropTypes.string,
|
||||
isMultiSelect: PropTypes.bool,
|
||||
mode: PropTypes.oneOf(["base", "compact"]),
|
||||
width: PropTypes.number,
|
||||
mode: PropTypes.oneOf(["compact", "full"]),
|
||||
maxHeight: PropTypes.number,
|
||||
isDisabled: PropTypes.bool,
|
||||
onSearchChanged: PropTypes.func,
|
||||
@ -330,9 +382,7 @@ AdvancedSelector.propTypes = {
|
||||
|
||||
AdvancedSelector.defaultProps = {
|
||||
isMultiSelect: false,
|
||||
width: 325,
|
||||
maxHeight: 545,
|
||||
mode: "base",
|
||||
mode: "compact",
|
||||
buttonLabel: "Add members",
|
||||
selectAllLabel: "Select all"
|
||||
};
|
||||
|
@ -0,0 +1,98 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { withKnobs, text } from "@storybook/addon-knobs/react";
|
||||
import AdvancedSelector from "../advanced-selector";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import { boolean } from "@storybook/addon-knobs/dist/deprecated";
|
||||
import { ArrayValue, BooleanValue } from "react-values";
|
||||
import Button from "../button";
|
||||
|
||||
storiesOf("EXAMPLES|AdvancedSelector", module)
|
||||
.addDecorator(withKnobs)
|
||||
// To set a default viewport for all the stories for this component
|
||||
.addParameters({ viewport: { defaultViewport: "responsive" } })
|
||||
.add("people group selector", () => {
|
||||
const options = [
|
||||
{
|
||||
key: "group-all",
|
||||
label: "All groups",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-dev",
|
||||
label: "Development",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-management",
|
||||
label: "Management",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-marketing",
|
||||
label: "Marketing",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-mobile",
|
||||
label: "Mobile",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-support",
|
||||
label: "Support",
|
||||
total: 0
|
||||
},
|
||||
{
|
||||
key: "group-web",
|
||||
label: "Web",
|
||||
total: 0
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<BooleanValue
|
||||
defaultValue={true}
|
||||
onChange={() => action("isOpen changed")}
|
||||
>
|
||||
{({ value: isOpen, toggle }) => (
|
||||
<div style={{ position: "relative" }}>
|
||||
<Button label="Toggle dropdown" onClick={toggle} />
|
||||
<ArrayValue
|
||||
defaultValue={options}
|
||||
onChange={() => action("options onChange")}
|
||||
>
|
||||
{({ value, set }) => (
|
||||
<AdvancedSelector
|
||||
isDropDown={true}
|
||||
isOpen={isOpen}
|
||||
maxHeight={336}
|
||||
width={379}
|
||||
placeholder={text("placeholder", "Search")}
|
||||
onSearchChanged={value => {
|
||||
action("onSearchChanged")(value);
|
||||
set(
|
||||
options.filter(option => {
|
||||
return option.label.indexOf(value) > -1;
|
||||
})
|
||||
);
|
||||
}}
|
||||
options={value}
|
||||
isMultiSelect={boolean("isMultiSelect", true)}
|
||||
buttonLabel={text("buttonLabel", "Add departments")}
|
||||
selectAllLabel={text("selectAllLabel", "Select all")}
|
||||
onSelect={selectedOptions => {
|
||||
action("onSelect")(selectedOptions);
|
||||
toggle();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ArrayValue>
|
||||
</div>
|
||||
)}
|
||||
</BooleanValue>
|
||||
</Section>
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user