More componenet migration

This commit is contained in:
HarelM
2023-12-23 15:40:27 +02:00
parent 90b692158a
commit 08f7a427f6
3 changed files with 83 additions and 63 deletions

View File

@@ -10,6 +10,7 @@ import IconMissing from './IconMissing'
type IconLayerProps = {
type: string
style?: object
className?: string
};
export default class IconLayer extends React.Component<IconLayerProps> {

View File

@@ -1,5 +1,4 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import lodash from 'lodash';
@@ -8,20 +7,13 @@ import LayerListItem from './LayerListItem'
import ModalAdd from './ModalAdd'
import {SortableContainer} from 'react-sortable-hoc';
import { LayerSpecification } from '@maplibre/maplibre-gl-style-spec';
const layerListPropTypes = {
layers: PropTypes.array.isRequired,
selectedLayerIndex: PropTypes.number.isRequired,
onLayersChange: PropTypes.func.isRequired,
onLayerSelect: PropTypes.func,
sources: PropTypes.object.isRequired,
}
function layerPrefix(name) {
function layerPrefix(name: string) {
return name.replace(' ', '-').replace('_', '-').split('-')[0]
}
function findClosestCommonPrefix(layers, idx) {
function findClosestCommonPrefix(layers: LayerSpecification[], idx: number) {
const currentLayerPrefix = layerPrefix(layers[idx].id)
let closestIdx = idx
for (let i = idx; i > 0; i--) {
@@ -37,14 +29,34 @@ function findClosestCommonPrefix(layers, idx) {
let UID = 0;
type LayerListContainerProps = {
layers: LayerSpecification[]
selectedLayerIndex: number
onLayersChange(...args: unknown[]): unknown
onLayerSelect(...args: unknown[]): unknown
onLayerDestroy?(...args: unknown[]): unknown
onLayerCopy(...args: unknown[]): unknown
onLayerVisibilityToggle(...args: unknown[]): unknown
sources: object
errors: any[]
};
type LayerListContainerState = {
collapsedGroups: {[ket: string]: boolean}
areAllGroupsExpanded: boolean
keys: {[key: string]: number}
isOpen: {[key: string]: boolean}
};
// List of collapsible layer editors
class LayerListContainer extends React.Component {
static propTypes = {...layerListPropTypes}
class LayerListContainer extends React.Component<LayerListContainerProps, LayerListContainerState> {
static defaultProps = {
onLayerSelect: () => {},
}
selectedItemRef: React.RefObject<any>;
scrollContainerRef: React.RefObject<HTMLElement>;
constructor(props) {
constructor(props: LayerListContainerProps) {
super(props);
this.selectedItemRef = React.createRef();
this.scrollContainerRef = React.createRef();
@@ -60,7 +72,7 @@ class LayerListContainer extends React.Component {
}
}
toggleModal(modalName) {
toggleModal(modalName: string) {
this.setState({
keys: {
...this.state.keys,
@@ -74,9 +86,9 @@ class LayerListContainer extends React.Component {
}
toggleLayers = () => {
let idx=0
let idx = 0
let newGroups=[]
let newGroups: {[key:string]: boolean} = {}
this.groupedLayers().forEach(layers => {
const groupPrefix = layerPrefix(layers[0].id)
@@ -87,7 +99,7 @@ class LayerListContainer extends React.Component {
newGroups[lookupKey] = this.state.areAllGroupsExpanded
}
layers.forEach((layer) => {
layers.forEach((_layer) => {
idx += 1
})
});
@@ -98,7 +110,7 @@ class LayerListContainer extends React.Component {
})
}
groupedLayers() {
groupedLayers(): (LayerSpecification & {key: string})[][] {
const groups = []
const layerIdCount = new Map();
@@ -122,7 +134,7 @@ class LayerListContainer extends React.Component {
return groups
}
toggleLayerGroup(groupPrefix, idx) {
toggleLayerGroup(groupPrefix: string, idx: number) {
const lookupKey = [groupPrefix, idx].join('-')
const newGroups = { ...this.state.collapsedGroups }
if(lookupKey in this.state.collapsedGroups) {
@@ -135,12 +147,12 @@ class LayerListContainer extends React.Component {
})
}
isCollapsed(groupPrefix, idx) {
isCollapsed(groupPrefix: string, idx: number) {
const collapsed = this.state.collapsedGroups[[groupPrefix, idx].join('-')]
return collapsed === undefined ? true : collapsed
}
shouldComponentUpdate (nextProps, nextState) {
shouldComponentUpdate (nextProps: LayerListContainerProps, nextState: LayerListContainerState) {
// Always update on state change
if (this.state !== nextState) {
return true;
@@ -148,8 +160,8 @@ class LayerListContainer extends React.Component {
// This component tree only requires id and visibility from the layers
// objects
function getRequiredProps (layer) {
const out = {
function getRequiredProps(layer: LayerSpecification) {
const out: {id: string, layout?: { visibility: any}} = {
id: layer.id,
};
@@ -165,10 +177,10 @@ class LayerListContainer extends React.Component {
this.props.layers.map(getRequiredProps),
);
function withoutLayers (props) {
function withoutLayers(props: LayerListContainerProps) {
const out = {
...props
};
} as LayerListContainerProps & { layers?: any };
delete out['layers'];
return out;
}
@@ -184,7 +196,7 @@ class LayerListContainer extends React.Component {
return propsChanged;
}
componentDidUpdate (prevProps) {
componentDidUpdate (prevProps: LayerListContainerProps) {
if (prevProps.selectedLayerIndex !== this.props.selectedLayerIndex) {
const selectedItemNode = this.selectedItemRef.current;
if (selectedItemNode && selectedItemNode.node) {
@@ -207,7 +219,7 @@ class LayerListContainer extends React.Component {
render() {
const listItems = []
const listItems: JSX.Element[] = []
let idx = 0
const layersByGroup = this.groupedLayers();
layersByGroup.forEach(layers => {
@@ -235,7 +247,7 @@ class LayerListContainer extends React.Component {
);
});
const additionalProps = {};
const additionalProps: {ref?: React.RefObject<any>} = {};
if (idx === this.props.selectedLayerIndex) {
additionalProps.ref = this.selectedItemRef;
}
@@ -255,7 +267,7 @@ class LayerListContainer extends React.Component {
visibility={(layer.layout || {}).visibility}
isSelected={idx === this.props.selectedLayerIndex}
onLayerSelect={this.props.onLayerSelect}
onLayerDestroy={this.props.onLayerDestroy.bind(this)}
onLayerDestroy={this.props.onLayerDestroy?.bind(this)}
onLayerCopy={this.props.onLayerCopy.bind(this)}
onLayerVisibilityToggle={this.props.onLayerVisibilityToggle.bind(this)}
{...additionalProps}
@@ -316,11 +328,13 @@ class LayerListContainer extends React.Component {
}
}
const LayerListContainerSortable = SortableContainer((props) => <LayerListContainer {...props} />)
const LayerListContainerSortable = SortableContainer((props: LayerListContainerProps) => <LayerListContainer {...props} />)
export default class LayerList extends React.Component {
static propTypes = {...layerListPropTypes}
type LayerListProps = LayerListContainerProps & {
onMoveLayer(...args: unknown[]): unknown
};
export default class LayerList extends React.Component<LayerListProps> {
render() {
return <LayerListContainerSortable
{...this.props}

View File

@@ -8,7 +8,12 @@ import IconLayer from './IconLayer'
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
const DraggableLabel = SortableHandle((props) => {
type DraggableLabelProps = {
layerId: string
layerType: string
};
const DraggableLabel = SortableHandle((props: DraggableLabelProps) => {
return <div className="maputnik-layer-list-item-handle">
<IconLayer
className="layer-handle__icon"
@@ -20,15 +25,15 @@ const DraggableLabel = SortableHandle((props) => {
</div>
});
class IconAction extends React.Component {
static propTypes = {
action: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
wdKey: PropTypes.string,
classBlockName: PropTypes.string,
classBlockModifier: PropTypes.string,
}
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 />
@@ -51,7 +56,7 @@ class IconAction extends React.Component {
}
return <button
tabIndex="-1"
tabIndex={-1}
title={this.props.action}
className={`maputnik-layer-list-icon-action ${classAdditions}`}
data-wd-key={this.props.wdKey}
@@ -63,21 +68,21 @@ class IconAction extends React.Component {
}
}
class LayerListItem extends React.Component {
static propTypes = {
layerIndex: PropTypes.number.isRequired,
layerId: PropTypes.string.isRequired,
layerType: PropTypes.string.isRequired,
isSelected: PropTypes.bool,
visibility: PropTypes.string,
className: PropTypes.string,
onLayerSelect: PropTypes.func.isRequired,
onLayerCopy: PropTypes.func,
onLayerDestroy: PropTypes.func,
onLayerVisibilityToggle: PropTypes.func,
}
type LayerListItemProps = {
id?: string
layerIndex: number
layerId: string
layerType: string
isSelected?: boolean
visibility?: string
className?: string
onLayerSelect(...args: unknown[]): unknown
onLayerCopy?(...args: unknown[]): unknown
onLayerDestroy?(...args: unknown[]): unknown
onLayerVisibilityToggle?(...args: unknown[]): unknown
};
class LayerListItem extends React.Component<LayerListItemProps> {
static defaultProps = {
isSelected: false,
visibility: 'visible',
@@ -102,12 +107,12 @@ class LayerListItem extends React.Component {
return <li
id={this.props.id}
key={this.props.layerId}
onClick={e => this.props.onLayerSelect(this.props.layerIndex)}
onClick={_e => this.props.onLayerSelect(this.props.layerIndex)}
data-wd-key={"layer-list-item:"+this.props.layerId}
className={classnames({
"maputnik-layer-list-item": true,
"maputnik-layer-list-item-selected": this.props.isSelected,
[this.props.className]: true,
[this.props.className!]: true,
})}>
<DraggableLabel {...this.props} />
<span style={{flexGrow: 1}} />
@@ -115,25 +120,25 @@ class LayerListItem extends React.Component {
wdKey={"layer-list-item:"+this.props.layerId+":delete"}
action={'delete'}
classBlockName="delete"
onClick={e => this.props.onLayerDestroy(this.props.layerIndex)}
onClick={_e => this.props.onLayerDestroy!(this.props.layerIndex)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":copy"}
action={'duplicate'}
classBlockName="duplicate"
onClick={e => this.props.onLayerCopy(this.props.layerIndex)}
onClick={_e => this.props.onLayerCopy!(this.props.layerIndex)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":toggle-visibility"}
action={visibilityAction}
classBlockName="visibility"
classBlockModifier={visibilityAction}
onClick={e => this.props.onLayerVisibilityToggle(this.props.layerIndex)}
onClick={_e => this.props.onLayerVisibilityToggle!(this.props.layerIndex)}
/>
</li>
}
}
const LayerListItemSortable = SortableElement((props) => <LayerListItem {...props} />);
const LayerListItemSortable = SortableElement((props: LayerListItemProps) => <LayerListItem {...props} />);
export default LayerListItemSortable;