mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Use new EntityIcon for non-hotbar uses
- Allow executing entity's onRun from catalog Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
baef6944aa
commit
b56ce826b0
@ -28,7 +28,7 @@ import { action, makeObservable, observable, reaction, runInAction, when } from
|
|||||||
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
||||||
import { navigate } from "../../navigation";
|
import { navigate } from "../../navigation";
|
||||||
import { MenuItem, MenuActions } from "../menu";
|
import { MenuItem, MenuActions } from "../menu";
|
||||||
import type { CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../api/catalog-entity";
|
import { CatalogEntityContextMenu, CatalogEntityContextMenuContext, catalogEntityRunContext } from "../../api/catalog-entity";
|
||||||
import { HotbarStore } from "../../../common/hotbar-store";
|
import { HotbarStore } from "../../../common/hotbar-store";
|
||||||
import { ConfirmDialog } from "../confirm-dialog";
|
import { ConfirmDialog } from "../confirm-dialog";
|
||||||
import { catalogCategoryRegistry, CatalogEntity } from "../../../common/catalog";
|
import { catalogCategoryRegistry, CatalogEntity } from "../../../common/catalog";
|
||||||
@ -41,7 +41,7 @@ import { makeCss } from "../../../common/utils/makeCss";
|
|||||||
import { CatalogEntityDetails } from "./catalog-entity-details";
|
import { CatalogEntityDetails } from "./catalog-entity-details";
|
||||||
import { catalogURL, CatalogViewRouteParam } from "../../../common/routes";
|
import { catalogURL, CatalogViewRouteParam } from "../../../common/routes";
|
||||||
import { CatalogMenu } from "./catalog-menu";
|
import { CatalogMenu } from "./catalog-menu";
|
||||||
import { HotbarIcon } from "../hotbar/hotbar-icon";
|
import { EntityIcon } from "../entity-icon";
|
||||||
|
|
||||||
export const previousActiveTab = createAppStorage("catalog-previous-active-tab", "");
|
export const previousActiveTab = createAppStorage("catalog-previous-active-tab", "");
|
||||||
|
|
||||||
@ -172,13 +172,14 @@ export class Catalog extends React.Component<Props> {
|
|||||||
|
|
||||||
renderIcon(item: CatalogEntityItem<CatalogEntity>) {
|
renderIcon(item: CatalogEntityItem<CatalogEntity>) {
|
||||||
return (
|
return (
|
||||||
<HotbarIcon
|
<EntityIcon
|
||||||
uid={`catalog-icon-${item.getId()}`}
|
|
||||||
title={item.getName()}
|
title={item.getName()}
|
||||||
source={item.source}
|
source={item.source}
|
||||||
src={item.entity.spec.icon?.src}
|
src={item.entity.spec.icon?.src}
|
||||||
material={item.entity.spec.icon?.material}
|
material={item.entity.spec.icon?.material}
|
||||||
background={item.entity.spec.icon?.background}
|
background={item.entity.spec.icon?.background}
|
||||||
|
onClick={() => item.onRun(catalogEntityRunContext)}
|
||||||
|
hoverWidth="1.5px"
|
||||||
size={24}
|
size={24}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import GraphemeSplitter from "grapheme-splitter";
|
|||||||
import { Avatar as MaterialAvatar, AvatarTypeMap } from "@material-ui/core";
|
import { Avatar as MaterialAvatar, AvatarTypeMap } from "@material-ui/core";
|
||||||
import { iter } from "../../utils";
|
import { iter } from "../../utils";
|
||||||
|
|
||||||
interface Props extends DOMAttributes<HTMLElement>, Partial<AvatarTypeMap> {
|
export interface AvatarProps extends DOMAttributes<HTMLElement>, Partial<AvatarTypeMap> {
|
||||||
title: string;
|
title: string;
|
||||||
colorHash?: string;
|
colorHash?: string;
|
||||||
width?: number;
|
width?: number;
|
||||||
@ -33,6 +33,7 @@ interface Props extends DOMAttributes<HTMLElement>, Partial<AvatarTypeMap> {
|
|||||||
src?: string;
|
src?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
background?: string;
|
background?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNameParts(name: string): string[] {
|
function getNameParts(name: string): string[] {
|
||||||
@ -69,8 +70,8 @@ function getIconString(title: string) {
|
|||||||
].filter(Boolean).join("");
|
].filter(Boolean).join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Avatar(props: Props) {
|
export function Avatar(props: AvatarProps) {
|
||||||
const { title, width = 32, height = 32, colorHash, children, background, ...settings } = props;
|
const { title, width = 32, height = 32, colorHash, children, style, background, ...settings } = props;
|
||||||
|
|
||||||
const getBackgroundColor = () => {
|
const getBackgroundColor = () => {
|
||||||
if (background) {
|
if (background) {
|
||||||
@ -89,7 +90,8 @@ export function Avatar(props: Props) {
|
|||||||
backgroundColor: getBackgroundColor(),
|
backgroundColor: getBackgroundColor(),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
textTransform: "uppercase"
|
textTransform: "uppercase",
|
||||||
|
...style,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
32
src/renderer/components/entity-icon/entity-icon.scss
Normal file
32
src/renderer/components/entity-icon/entity-icon.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 OpenLens Authors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.EntityIcon {
|
||||||
|
&.active {
|
||||||
|
box-shadow: 0 0 0px var(--hover-width) var(--clusterMenuBackground), 0 0 0px calc(2*var(--hover-width)) var(--textColorAccent);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&:not(.active) {
|
||||||
|
box-shadow: 0 0 0px var(--hover-width) var(--clusterMenuBackground), 0 0 0px calc(2*var(--hover-width)) #ffffff50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/renderer/components/entity-icon/entity-icon.tsx
Normal file
56
src/renderer/components/entity-icon/entity-icon.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 OpenLens Authors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "./entity-icon.scss";
|
||||||
|
|
||||||
|
import React, { DOMAttributes } from "react";
|
||||||
|
import { cssNames, IClassName } from "../../utils";
|
||||||
|
import { Avatar } from "../avatar/avatar";
|
||||||
|
import { Icon } from "../icon";
|
||||||
|
|
||||||
|
export interface EntityIconProps extends DOMAttributes<HTMLElement> {
|
||||||
|
title: string;
|
||||||
|
size?: number;
|
||||||
|
source: string;
|
||||||
|
src?: string;
|
||||||
|
material?: string;
|
||||||
|
background?: string;
|
||||||
|
active?: boolean;
|
||||||
|
className?: IClassName;
|
||||||
|
hoverWidth?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EntityIcon({ active, size = 40, hoverWidth = "3px", material, className, ...props }: EntityIconProps) {
|
||||||
|
return (
|
||||||
|
<Avatar
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
colorHash={`${props.title}-${props.source}`}
|
||||||
|
className={cssNames("EntityIcon", className, active ? "active" : "default")}
|
||||||
|
style={{
|
||||||
|
"--hover-width": hoverWidth,
|
||||||
|
} as React.CSSProperties}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{material && <Icon className="materialIcon" material={material} />}
|
||||||
|
</Avatar>
|
||||||
|
);
|
||||||
|
}
|
||||||
22
src/renderer/components/entity-icon/index.ts
Normal file
22
src/renderer/components/entity-icon/index.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 OpenLens Authors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from "./entity-icon";
|
||||||
@ -31,6 +31,7 @@ import { cssNames, IClassName } from "../../utils";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { HotbarIcon } from "./hotbar-icon";
|
import { HotbarIcon } from "./hotbar-icon";
|
||||||
import { HotbarStore } from "../../../common/hotbar-store";
|
import { HotbarStore } from "../../../common/hotbar-store";
|
||||||
|
import { catalogEntityRunContext } from "../../api/catalog-entity";
|
||||||
|
|
||||||
interface Props extends DOMAttributes<HTMLElement> {
|
interface Props extends DOMAttributes<HTMLElement> {
|
||||||
entity: CatalogEntity;
|
entity: CatalogEntity;
|
||||||
@ -44,20 +45,16 @@ interface Props extends DOMAttributes<HTMLElement> {
|
|||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class HotbarEntityIcon extends React.Component<Props> {
|
export class HotbarEntityIcon extends React.Component<Props> {
|
||||||
@observable private contextMenu: CatalogEntityContextMenuContext;
|
@observable private contextMenu: CatalogEntityContextMenuContext = {
|
||||||
|
menuItems: [],
|
||||||
|
navigate: (url: string) => navigate(url),
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.contextMenu = {
|
|
||||||
menuItems: [],
|
|
||||||
navigate: (url: string) => navigate(url),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get kindIcon() {
|
get kindIcon() {
|
||||||
const className = "badge";
|
const className = "badge";
|
||||||
const category = catalogCategoryRegistry.getCategoryForEntity(this.props.entity);
|
const category = catalogCategoryRegistry.getCategoryForEntity(this.props.entity);
|
||||||
@ -92,20 +89,17 @@ export class HotbarEntityIcon extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.contextMenu) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
entity, errorClass, add, remove,
|
entity, errorClass, add, remove,
|
||||||
index, children, ...elemProps
|
index, children, className, ...elemProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const className = cssNames("HotbarEntityIcon", this.props.className, {
|
const classNames = cssNames("HotbarEntityIcon", className, {
|
||||||
interactive: true,
|
interactive: true,
|
||||||
active: this.isActive(entity),
|
active: this.isActive(entity),
|
||||||
disabled: !entity
|
disabled: !entity
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(entity);
|
||||||
const isPersisted = this.isPersisted(entity);
|
const isPersisted = this.isPersisted(entity);
|
||||||
const onOpen = async () => {
|
const onOpen = async () => {
|
||||||
const menuItems: CatalogEntityContextMenu[] = [];
|
const menuItems: CatalogEntityContextMenu[] = [];
|
||||||
@ -136,11 +130,12 @@ export class HotbarEntityIcon extends React.Component<Props> {
|
|||||||
src={entity.spec.icon?.src}
|
src={entity.spec.icon?.src}
|
||||||
material={entity.spec.icon?.material}
|
material={entity.spec.icon?.material}
|
||||||
background={entity.spec.icon?.background}
|
background={entity.spec.icon?.background}
|
||||||
className={className}
|
className={classNames}
|
||||||
active={isActive}
|
active={isActive}
|
||||||
onMenuOpen={onOpen}
|
onMenuOpen={onOpen}
|
||||||
menuItems={this.contextMenu.menuItems}
|
menuItems={this.contextMenu.menuItems}
|
||||||
tooltip={`${entity.metadata.name} (${entity.metadata.source})`}
|
tooltip={`${entity.metadata.name} (${entity.metadata.source})`}
|
||||||
|
onClick={() => entity.onRun(catalogEntityRunContext)}
|
||||||
{...elemProps}
|
{...elemProps}
|
||||||
>
|
>
|
||||||
{ this.ledIcon }
|
{ this.ledIcon }
|
||||||
|
|||||||
@ -64,23 +64,6 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.MuiAvatar-root {
|
|
||||||
width: var(--size);
|
|
||||||
height: var(--size);
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.interactive {
|
|
||||||
&:hover {
|
|
||||||
&:not(.active) {
|
|
||||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.led {
|
.led {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 3px;
|
left: 3px;
|
||||||
|
|||||||
@ -28,9 +28,8 @@ import { cssNames, IClassName } from "../../utils";
|
|||||||
import { ConfirmDialog } from "../confirm-dialog";
|
import { ConfirmDialog } from "../confirm-dialog";
|
||||||
import { Menu, MenuItem } from "../menu";
|
import { Menu, MenuItem } from "../menu";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Avatar } from "../avatar/avatar";
|
import { EntityIcon } from "../entity-icon";
|
||||||
import { Icon } from "../icon";
|
import { Tooltip } from "@material-ui/core";
|
||||||
import { Tooltip } from "../tooltip";
|
|
||||||
|
|
||||||
export interface HotbarIconProps extends DOMAttributes<HTMLElement> {
|
export interface HotbarIconProps extends DOMAttributes<HTMLElement> {
|
||||||
uid: string;
|
uid: string;
|
||||||
@ -74,34 +73,27 @@ export const HotbarIcon = observer(({menuItems = [], size = 40, tooltip, ...prop
|
|||||||
setMenuOpen(!menuOpen);
|
setMenuOpen(!menuOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderIcon = () => {
|
|
||||||
return (
|
|
||||||
<Avatar
|
|
||||||
{...rest}
|
|
||||||
title={title}
|
|
||||||
colorHash={`${title}-${source}`}
|
|
||||||
className={cssNames(active ? "active" : "default", { interactive: !!onClick })}
|
|
||||||
width={size}
|
|
||||||
height={size}
|
|
||||||
src={src}
|
|
||||||
onClick={(event) => {
|
|
||||||
if (!disabled) {
|
|
||||||
onClick?.(event);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{material && <Icon className="materialIcon" material={material}/>}
|
|
||||||
</Avatar>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("HotbarIcon flex", className, { disabled, contextMenuAvailable: menuItems.length > 0 })}>
|
<div className={cssNames("HotbarIcon flex", className, { disabled })}>
|
||||||
{tooltip && <Tooltip targetId={id}>{tooltip}</Tooltip>}
|
<Tooltip title={`${title || "unknown"} (${source || "unknown"})`} placement="right">
|
||||||
<div id={id}>
|
<div id={id}>
|
||||||
{renderIcon()}
|
<EntityIcon
|
||||||
{children}
|
title={title}
|
||||||
</div>
|
size={size}
|
||||||
|
active={active}
|
||||||
|
src={src}
|
||||||
|
source={source}
|
||||||
|
material={material}
|
||||||
|
onClick={event => {
|
||||||
|
if (!disabled) {
|
||||||
|
onClick?.(event);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
<Menu
|
<Menu
|
||||||
usePortal
|
usePortal
|
||||||
htmlFor={id}
|
htmlFor={id}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import { HotbarEntityIcon } from "./hotbar-entity-icon";
|
|||||||
import { cssNames, IClassName } from "../../utils";
|
import { cssNames, IClassName } from "../../utils";
|
||||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||||
import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store";
|
import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store";
|
||||||
import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity";
|
import type { CatalogEntity } from "../../api/catalog-entity";
|
||||||
import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd";
|
import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd";
|
||||||
import { HotbarSelector } from "./hotbar-selector";
|
import { HotbarSelector } from "./hotbar-selector";
|
||||||
import { HotbarCell } from "./hotbar-cell";
|
import { HotbarCell } from "./hotbar-cell";
|
||||||
@ -126,51 +126,45 @@ export class HotbarMenu extends React.Component<Props> {
|
|||||||
>
|
>
|
||||||
{item && (
|
{item && (
|
||||||
<Draggable draggableId={item.entity.uid} key={item.entity.uid} index={0} >
|
<Draggable draggableId={item.entity.uid} key={item.entity.uid} index={0} >
|
||||||
{(provided, snapshot) => {
|
{(provided, snapshot) => (
|
||||||
const style = {
|
<div
|
||||||
zIndex: defaultHotbarCells - index,
|
key={item.entity.uid}
|
||||||
position: "absolute",
|
ref={provided.innerRef}
|
||||||
...provided.draggableProps.style,
|
{...provided.draggableProps}
|
||||||
} as React.CSSProperties;
|
{...provided.dragHandleProps}
|
||||||
|
style={{
|
||||||
return (
|
zIndex: defaultHotbarCells - index,
|
||||||
<div
|
position: "absolute",
|
||||||
key={item.entity.uid}
|
...provided.draggableProps.style,
|
||||||
ref={provided.innerRef}
|
}}
|
||||||
{...provided.draggableProps}
|
>
|
||||||
{...provided.dragHandleProps}
|
{entity ? (
|
||||||
style={style}
|
<HotbarEntityIcon
|
||||||
>
|
key={index}
|
||||||
{entity ? (
|
index={index}
|
||||||
<HotbarEntityIcon
|
entity={entity}
|
||||||
key={index}
|
className={cssNames({ isDragging: snapshot.isDragging })}
|
||||||
index={index}
|
remove={this.removeItem}
|
||||||
entity={entity}
|
add={this.addItem}
|
||||||
onClick={() => entity.onRun(catalogEntityRunContext)}
|
size={40}
|
||||||
className={cssNames({ isDragging: snapshot.isDragging })}
|
/>
|
||||||
remove={this.removeItem}
|
) : (
|
||||||
add={this.addItem}
|
<HotbarIcon
|
||||||
size={40}
|
uid={item.entity.uid}
|
||||||
/>
|
title={item.entity.name}
|
||||||
) : (
|
source={item.entity.source}
|
||||||
<HotbarIcon
|
menuItems={[
|
||||||
uid={`hotbar-icon-${item.entity.uid}`}
|
{
|
||||||
title={item.entity.name}
|
title: "Unpin from Hotbar",
|
||||||
source={item.entity.source}
|
onClick: () => this.removeItem(item.entity.uid)
|
||||||
tooltip={`${item.entity.name} (${item.entity.source})`}
|
}
|
||||||
menuItems={[
|
]}
|
||||||
{
|
disabled
|
||||||
title: "Unpin from Hotbar",
|
size={40}
|
||||||
onClick: () => this.removeItem(item.entity.uid)
|
/>
|
||||||
}
|
)}
|
||||||
]}
|
</div>
|
||||||
disabled
|
)}
|
||||||
size={40}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Draggable>
|
</Draggable>
|
||||||
)}
|
)}
|
||||||
{provided.placeholder}
|
{provided.placeholder}
|
||||||
|
|||||||
@ -21,25 +21,24 @@
|
|||||||
|
|
||||||
// Helper for combining css classes inside components
|
// Helper for combining css classes inside components
|
||||||
|
|
||||||
export type IClassName = string | string[] | IClassNameMap;
|
export type IClassName = string | string[] | Record<string, any> | undefined | null;
|
||||||
export type IClassNameMap = {
|
|
||||||
[className: string]: boolean | any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function cssNames(...args: IClassName[]): string {
|
export function cssNames(...args: IClassName[]): string {
|
||||||
const map: IClassNameMap = {};
|
const names: string[] = [];
|
||||||
|
|
||||||
args.forEach(className => {
|
for (const arg of args) {
|
||||||
if (typeof className === "string" || Array.isArray(className)) {
|
if (typeof arg === "string") {
|
||||||
[].concat(className).forEach(name => map[name] = true);
|
names.push(arg.trim());
|
||||||
|
} else if (Array.isArray(arg)) {
|
||||||
|
names.push(...arg.map(name => name.trim()));
|
||||||
|
} else if (arg && typeof arg === "object") {
|
||||||
|
for (const [name, isActive] of Object.entries(arg)) {
|
||||||
|
if (isActive) {
|
||||||
|
names.push(name.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
Object.assign(map, className);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Object.entries(map)
|
return names.filter(Boolean).join(" ");
|
||||||
.filter(([, isActive]) => !!isActive)
|
|
||||||
.map(([className]) => className.trim())
|
|
||||||
.join(" ");
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user