Add behavior picker component

This commit is contained in:
2022-04-02 19:25:57 +08:00
parent cfbb52afa5
commit 555648dbb0
9 changed files with 234 additions and 31 deletions
@@ -39,8 +39,11 @@ div.behavior-picker-list {
i.view-icon {
display: none;
}
}
i.view-icon:hover {
div.behavior-picker-line-icon-view:hover {
i.view-icon {
color: $lt-green;
}
}
@@ -57,16 +60,28 @@ div.behavior-picker-list {
}
}
div.behavior-picker-title.is-deleted {
div {
text-decoration: line-through;
opacity: 0.6;
}
}
div.behavior-picker-title.behavior-add-line {
width: calc(100% - 30px);
}
div.behavior-picker-line-delete-view {
width: 30px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
i:hover {
color: $lt-red;
}
div.behavior-picker-line-delete-view:hover i {
color: $lt-red;
}
}
@@ -1,77 +1,190 @@
import { DetailsList } from "@Component/DetailsList/DetailsList";
import { Component, ReactNode } from "react";
import { Component, ReactNode, createRef } from "react";
import { Behavior } from "@Model/Behavior";
import { Icon } from "@fluentui/react";
import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting";
import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
import { Localization } from "@Component/Localization/Localization";
import { PickerList } from "@Component/PickerList/PickerList";
import "./BehaviorPicker.scss";
interface IBehaviorPickerProps {
behavior: Behavior[];
focusBehavior?: Behavior;
click?: (behavior: Behavior) => void;
delete?: (behavior: Behavior) => void;
action?: (behavior: Behavior) => void;
add?: () => void;
add?: (behavior: Behavior) => void;
}
interface IBehaviorPickerState {
isPickerListOpen: boolean;
}
@useStatusWithEvent("behaviorChange")
@useSettingWithEvent("language")
class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps> {
class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps & IMixinStatusProps> {
public state = {
isPickerListOpen: false
}
private isInnerClick: boolean = false;
private clickLineRef = createRef<HTMLDivElement>();
private getData() {
let data: Array<{key: string, behavior: Behavior | undefined}> = [];
let data: Array<{select: boolean, key: string, behavior: Behavior | undefined}> = [];
for (let i = 0; i < this.props.behavior.length; i++) {
data.push({
key: this.props.behavior[i].id,
behavior: this.props.behavior[i]
behavior: this.props.behavior[i],
select: this.props.behavior[i].id === this.props.focusBehavior?.id
})
}
data.push({
key: "@@AddButton_List_Key",
behavior: undefined
behavior: undefined,
select: false
})
return data;
}
private renderLine = (behavior?: Behavior): ReactNode => {
if (behavior) {
const titleClassList: string[] = ["behavior-picker-title"];
if (this.props.setting) {
titleClassList.push(this.props.setting.language);
}
if (behavior.isDeleted()) {
titleClassList.push("is-deleted");
}
return <>
<div className="behavior-picker-line-color-view">
<div style={{ borderLeft: `10px solid ${behavior.color}` }}/>
</div>
<div className="behavior-picker-line-icon-view">
<Icon iconName={behavior.iconName} className="behavior-icon"/>
<Icon iconName="EditCreate" className="view-icon"/>
<div
className="behavior-picker-line-icon-view"
onClick={() => {
this.isInnerClick = true;
this.props.action && this.props.action(behavior);
}}
>
{
behavior.isDeleted() ?
<Icon iconName={behavior.iconName}/>:
<>
<Icon iconName={behavior.iconName} className="behavior-icon"/>
<Icon iconName="EditCreate" className="view-icon"/>
</>
}
</div>
<div className={`behavior-picker-title ${this.props.setting?.language}`}>
<div className={titleClassList.join(" ")}>
<div>{behavior.name}</div>
</div>
<div className="behavior-picker-line-delete-view">
<div
className="behavior-picker-line-delete-view"
onClick={() => {
this.isInnerClick = true;
this.props.delete && this.props.delete(behavior);
}}
>
<Icon iconName="Delete"/>
</div>
</>;
} else {
const openPicker = () => {
this.isInnerClick = true;
this.setState({
isPickerListOpen: true
});
}
return <>
<div className="behavior-picker-line-icon-view">
<div
className="behavior-picker-line-icon-view"
onClick={openPicker}
>
<Icon iconName="Add" className="add-icon"/>
</div>
<div className={`behavior-picker-title`}>
<div
className="behavior-picker-title behavior-add-line"
onClick={openPicker}
ref={this.clickLineRef}
>
<Localization i18nKey="Behavior.Picker.Add.Button"/>
</div>
</>;
}
}
public render(): ReactNode {
return <DetailsList
hideCheckBox
className="behavior-picker-list"
items={this.getData()}
columns={[{
className: "behavior-picker-line",
key: "behavior",
render: this.renderLine
}]}
private getAllData = (): Behavior[] => {
if (this.props.status) {
let res: Behavior[] = [];
for (let i = 0; i < this.props.status.model.behaviorPool.length; i++) {
let isAdded = false;
for (let j = 0; j < this.props.behavior.length; j++) {
if (this.props.status.model.behaviorPool[i].id === this.props.behavior[j].id) {
isAdded = true;
break;
}
}
if (!isAdded) {
res.push(this.props.status.model.behaviorPool[i]);
}
}
return res;
} else {
return [];
}
}
private renderPickerList(): ReactNode {
return <PickerList
objectList={this.getAllData()}
noData="Behavior.Picker.Add.Nodata"
target={this.clickLineRef}
clickObjectItems={((item) => {
if (item instanceof Behavior && this.props.add) {
this.props.add(item);
}
this.setState({
isPickerListOpen: false
})
})}
dismiss={() => {
this.setState({
isPickerListOpen: false
});
}}
/>
}
public render(): ReactNode {
return <>
<DetailsList
hideCheckBox
className="behavior-picker-list"
items={this.getData()}
clickLine={(item) => {
if (!this.isInnerClick && this.props.click && item.behavior) {
this.props.click(item.behavior);
}
this.isInnerClick = false;
}}
columns={[{
className: "behavior-picker-line",
key: "behavior",
render: this.renderLine
}]}
/>
{this.state.isPickerListOpen ? this.renderPickerList() : null}
</>
}
}
export { BehaviorPicker };