Add behavior list component
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
@import "../Theme/Theme.scss";
|
||||
|
||||
$behavior-item-height: 45px;
|
||||
|
||||
div.behavior-list {
|
||||
margin: -5px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
div.behavior-item {
|
||||
margin: 5px;
|
||||
height: $behavior-item-height;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
|
||||
div.behavior-color-view {
|
||||
height: $behavior-item-height;
|
||||
width: 3px;
|
||||
min-width: 3px;
|
||||
border-radius: 3px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
div.behavior-icon-view {
|
||||
height: $behavior-item-height;
|
||||
min-width: $behavior-item-height;
|
||||
width: $behavior-item-height;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
div.behavior-content-view {
|
||||
width: calc( 100% - 68px );
|
||||
max-width: 100px;
|
||||
height: $behavior-item-height;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
div.title-view {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.info-view {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
|
||||
div.behavior-action-view {
|
||||
height: $behavior-item-height;
|
||||
min-width: 20px;
|
||||
width: 20px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
|
||||
div.behavior-action-button {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.behavior-action-button.hover-red:hover i {
|
||||
color: $lt-red;
|
||||
}
|
||||
|
||||
div.behavior-action-button.hover-blue:hover i {
|
||||
color: $lt-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.dark.behavior-list {
|
||||
|
||||
div.behavior-item {
|
||||
background-color: $lt-bg-color-lvl3-dark;
|
||||
}
|
||||
|
||||
div.behavior-item:hover {
|
||||
color: $lt-font-color-lvl2-dark;
|
||||
background-color: $lt-bg-color-lvl2-dark;
|
||||
}
|
||||
|
||||
div.behavior-item.focus {
|
||||
color: $lt-font-color-lvl1-dark;
|
||||
background-color: $lt-bg-color-lvl1-dark;
|
||||
}
|
||||
}
|
||||
|
||||
div.light.behavior-list {
|
||||
|
||||
div.behavior-item {
|
||||
background-color: $lt-bg-color-lvl3-light;
|
||||
}
|
||||
|
||||
div.behavior-item:hover {
|
||||
color: $lt-font-color-lvl2-light;
|
||||
background-color: $lt-bg-color-lvl2-light;
|
||||
}
|
||||
|
||||
div.behavior-item.focus {
|
||||
color: $lt-font-color-lvl1-light;
|
||||
background-color: $lt-bg-color-lvl1-light;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
import { Theme } from "@Component/Theme/Theme";
|
||||
import { Component, ReactNode } from "react";
|
||||
import { IRenderBehavior, Behavior, BehaviorRecorder } from "@Model/Behavior";
|
||||
import { Icon } from "@fluentui/react";
|
||||
import { Localization } from "@Component/Localization/Localization";
|
||||
import "./BehaviorList.scss";
|
||||
|
||||
interface IBehaviorListProps {
|
||||
behaviors: IRenderBehavior[];
|
||||
focusBehaviors?: IRenderBehavior[];
|
||||
click?: (behavior: IRenderBehavior) => void;
|
||||
action?: (behavior: IRenderBehavior) => void;
|
||||
actionType?: "info" | "delete";
|
||||
}
|
||||
|
||||
class BehaviorList extends Component<IBehaviorListProps> {
|
||||
|
||||
private isFocus(behavior: IRenderBehavior): boolean {
|
||||
if (this.props.focusBehaviors) {
|
||||
for (let i = 0; i < this.props.focusBehaviors.length; i++) {
|
||||
if (this.props.focusBehaviors[i] === behavior) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private renderActionButton(behavior: IRenderBehavior) {
|
||||
|
||||
const classList: string[] = ["info-button", "behavior-action-button"];
|
||||
let iconName = "Info";
|
||||
|
||||
switch (this.props.actionType) {
|
||||
case "delete":
|
||||
classList.push("hover-red");
|
||||
iconName = "Delete";
|
||||
break;
|
||||
case "info":
|
||||
classList.push("hover-blue");
|
||||
iconName = "Info";
|
||||
break;
|
||||
default:
|
||||
classList.push("hover-blue");
|
||||
}
|
||||
|
||||
return <div
|
||||
className={classList.join(" ")}
|
||||
onClick={() => {
|
||||
this.isActionClick = true;
|
||||
if (this.props.action) {
|
||||
this.props.action(behavior)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon iconName={iconName}/>
|
||||
</div>
|
||||
}
|
||||
|
||||
private renderTerm(key: string, className: string, needLocal: boolean) {
|
||||
if (needLocal) {
|
||||
return <div className={className}>
|
||||
<Localization i18nKey={key as any}/>
|
||||
</div>;
|
||||
} else {
|
||||
return <div className={className}>
|
||||
{key}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
private isActionClick: boolean = false;
|
||||
|
||||
private renderBehavior(behavior: IRenderBehavior) {
|
||||
|
||||
let id: string = behavior.behaviorId;
|
||||
let name: string = behavior.behaviorName;
|
||||
let icon: string = behavior.iconName;
|
||||
let info: string = behavior.describe;
|
||||
let color: string = "";
|
||||
let needLocal: boolean = true;
|
||||
let focus = this.isFocus(behavior);
|
||||
|
||||
if (behavior instanceof Behavior) {
|
||||
id = behavior.id;
|
||||
name = behavior.name;
|
||||
color = behavior.color;
|
||||
needLocal = false;
|
||||
}
|
||||
|
||||
if (behavior instanceof BehaviorRecorder) {
|
||||
needLocal = true;
|
||||
if (focus) {
|
||||
color = "rgb(81, 79, 235)";
|
||||
}
|
||||
}
|
||||
|
||||
if (!color) {
|
||||
color = "transparent";
|
||||
}
|
||||
|
||||
return <div
|
||||
key={id}
|
||||
className={"behavior-item" + (focus ? " focus" : "")}
|
||||
onClick={() => {
|
||||
if (this.props.click && !this.isActionClick) {
|
||||
this.props.click(behavior);
|
||||
}
|
||||
this.isActionClick = false;
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="behavior-color-view"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
<div className="behavior-icon-view">
|
||||
<Icon iconName={icon}/>
|
||||
</div>
|
||||
<div className="behavior-content-view">
|
||||
{this.renderTerm(name, "title-view", needLocal)}
|
||||
{this.renderTerm(info, "info-view", needLocal)}
|
||||
</div>
|
||||
<div className="behavior-action-view">
|
||||
{this.renderActionButton(behavior)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
public render(): ReactNode {
|
||||
return <Theme className="behavior-list">
|
||||
{this.props.behaviors.map((behavior) => {
|
||||
return this.renderBehavior(behavior);
|
||||
})}
|
||||
</Theme>
|
||||
}
|
||||
}
|
||||
|
||||
export { BehaviorList };
|
||||
Reference in New Issue
Block a user