Files
editor/src/components/LayerListItem.tsx
Harel M cb9b7beb32 Update dependencies, fix tranlations, remove deprecated tools. (#1683)
It migrates to next gen translation extraction tool and updates other
libraries with their relevant changes.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-03 14:14:39 +02:00

167 lines
4.7 KiB
TypeScript

import React from "react";
import classnames from "classnames";
import { MdContentCopy, MdVisibility, MdVisibilityOff, MdDelete } from "react-icons/md";
import { IconContext } from "react-icons";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import IconLayer from "./IconLayer";
import type { VisibilitySpecification } from "maplibre-gl";
type DraggableLabelProps = {
layerId: string
layerType: string
dragAttributes?: React.HTMLAttributes<HTMLElement>
dragListeners?: React.HTMLAttributes<HTMLElement>
};
const DraggableLabel: React.FC<DraggableLabelProps> = (props) => {
const { dragAttributes, dragListeners } = props;
return <div className="maputnik-layer-list-item-handle" {...dragAttributes} {...dragListeners}>
<IconLayer
className="layer-handle__icon"
type={props.layerType}
style={{ width: "1em", height: "1em", verticalAlign: "middle" }}
/>
<button className="maputnik-layer-list-item-id">
{props.layerId}
</button>
</div>;
};
type IconActionProps = {
action: string
onClick(...args: unknown[]): unknown
wdKey?: string
classBlockName?: string
classBlockModifier?: string
};
class IconAction extends React.Component<IconActionProps> {
renderIcon() {
switch (this.props.action) {
case "duplicate": return <MdContentCopy />;
case "show": return <MdVisibility />;
case "hide": return <MdVisibilityOff />;
case "delete": return <MdDelete />;
}
}
render() {
const { classBlockName, classBlockModifier } = this.props;
let classAdditions = "";
if (classBlockName) {
classAdditions = `maputnik-layer-list-icon-action__${classBlockName}`;
if (classBlockModifier) {
classAdditions += ` maputnik-layer-list-icon-action__${classBlockName}--${classBlockModifier}`;
}
}
return <button
tabIndex={-1}
title={this.props.action}
className={`maputnik-layer-list-icon-action ${classAdditions}`}
data-wd-key={this.props.wdKey}
onClick={this.props.onClick}
aria-hidden="true"
>
{this.renderIcon()}
</button>;
}
}
type LayerListItemProps = {
id?: string
layerIndex: number
layerId: string
layerType: string
isSelected?: boolean
visibility?: VisibilitySpecification
className?: string
onLayerSelect(index: number): void;
onLayerCopy?(...args: unknown[]): unknown
onLayerDestroy?(...args: unknown[]): unknown
onLayerVisibilityToggle?(...args: unknown[]): unknown
};
const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>((props, ref) => {
const {
isSelected = false,
visibility = "visible",
onLayerCopy = () => { },
onLayerDestroy = () => { },
onLayerVisibilityToggle = () => { },
} = props;
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({ id: props.layerId });
const style = {
transform: CSS.Transform.toString(transform),
transition,
opacity: isDragging ? 0.5 : 1,
};
const visibilityAction = visibility === "visible" ? "show" : "hide";
// Cast ref to MutableRefObject since we know from the codebase that's what's always passed
const refObject = ref as React.MutableRefObject<HTMLLIElement | null> | null;
return <IconContext.Provider value={{ size: "14px" }}>
<li
ref={(node) => {
setNodeRef(node);
if (refObject) {
refObject.current = node;
}
}}
style={style}
id={props.id}
onClick={_e => props.onLayerSelect(props.layerIndex)}
data-wd-key={"layer-list-item:" + props.layerId}
className={classnames({
"maputnik-layer-list-item": true,
"maputnik-layer-list-item-selected": isSelected,
[props.className!]: true,
})}>
<DraggableLabel
layerId={props.layerId}
layerType={props.layerType}
dragAttributes={attributes}
dragListeners={listeners}
/>
<span style={{ flexGrow: 1 }} />
<IconAction
wdKey={"layer-list-item:" + props.layerId + ":delete"}
action={"delete"}
classBlockName="delete"
onClick={_e => onLayerDestroy!(props.layerIndex)}
/>
<IconAction
wdKey={"layer-list-item:" + props.layerId + ":copy"}
action={"duplicate"}
classBlockName="duplicate"
onClick={_e => onLayerCopy!(props.layerIndex)}
/>
<IconAction
wdKey={"layer-list-item:" + props.layerId + ":toggle-visibility"}
action={visibilityAction}
classBlockName="visibility"
classBlockModifier={visibilityAction}
onClick={_e => onLayerVisibilityToggle!(props.layerIndex)}
/>
</li>
</IconContext.Provider>;
});
export default LayerListItem;