Remove legacy context API (#1258)

## Summary
- replace `childContextTypes` usage with `IconContext` providers
- drop `prop-types` imports

## Testing
- `npm run lint`
- `npm run build`


------
https://chatgpt.com/codex/tasks/task_e_6868431f6ecc83318393a5d079ca736e
This commit is contained in:
Bart Louwers
2025-07-04 23:49:11 +02:00
committed by GitHub
parent e58b92b0cd
commit 4b977fd33e
4 changed files with 104 additions and 128 deletions

View File

@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import ScrollContainer from './ScrollContainer'
import { WithTranslation, withTranslation } from 'react-i18next';
import { IconContext } from 'react-icons';
type AppLayoutInternalProps = {
toolbar: React.ReactElement
@@ -13,38 +13,31 @@ type AppLayoutInternalProps = {
} & WithTranslation;
class AppLayoutInternal extends React.Component<AppLayoutInternalProps> {
static childContextTypes = {
reactIconBase: PropTypes.object
}
getChildContext() {
return {
reactIconBase: { size: 14 }
}
}
render() {
document.body.dir = this.props.i18n.dir();
return <div className="maputnik-layout">
{this.props.toolbar}
<div className="maputnik-layout-main">
<div className="maputnik-layout-list">
{this.props.layerList}
return <IconContext.Provider value={{size: '14px'}}>
<div className="maputnik-layout">
{this.props.toolbar}
<div className="maputnik-layout-main">
<div className="maputnik-layout-list">
{this.props.layerList}
</div>
<div className="maputnik-layout-drawer">
<ScrollContainer>
{this.props.layerEditor}
</ScrollContainer>
</div>
{this.props.map}
</div>
<div className="maputnik-layout-drawer">
<ScrollContainer>
{this.props.layerEditor}
</ScrollContainer>
{this.props.bottom && <div className="maputnik-layout-bottom">
{this.props.bottom}
</div>
{this.props.map}
}
{this.props.modals}
</div>
{this.props.bottom && <div className="maputnik-layout-bottom">
{this.props.bottom}
</div>
}
{this.props.modals}
</div>
</IconContext.Provider>
}
}

View File

@@ -1,8 +1,8 @@
import React, {type JSX} from 'react'
import PropTypes from 'prop-types'
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton'
import {Accordion} from 'react-accessible-accordion';
import {MdMoreVert} from 'react-icons/md'
import { IconContext } from 'react-icons'
import {BackgroundLayerSpecification, LayerSpecification, SourceSpecification} from 'maplibre-gl';
import FieldJson from './FieldJson'
@@ -86,10 +86,6 @@ class LayerEditorInternal extends React.Component<LayerEditorInternalProps, Laye
onLayerDestroyed: () => {},
}
static childContextTypes = {
reactIconBase: PropTypes.object
}
constructor(props: LayerEditorInternalProps) {
super(props)
@@ -116,14 +112,6 @@ class LayerEditorInternal extends React.Component<LayerEditorInternalProps, Laye
};
}
getChildContext () {
return {
reactIconBase: {
size: 14,
color: '#8e8e8e',
}
}
}
changeProperty(group: keyof LayerSpecification | null, property: string, newValue: any) {
this.props.onLayerChanged(
@@ -311,53 +299,55 @@ class LayerEditorInternal extends React.Component<LayerEditorInternalProps, Laye
items[id].handler();
}
return <section className="maputnik-layer-editor"
role="main"
aria-label={t("Layer editor")}
>
<header>
<div className="layer-header">
<h2 className="layer-header__title">
{t("Layer: {{layerId}}", { layerId: formatLayerId(this.props.layer.id) })}
</h2>
<div className="layer-header__info">
<Wrapper
className='more-menu'
onSelection={handleSelection}
closeOnSelection={false}
>
<Button
id="skip-target-layer-editor"
data-wd-key="skip-target-layer-editor"
className='more-menu__button'
title={"Layer options"}>
<MdMoreVert className="more-menu__button__svg" />
</Button>
<Menu>
<ul className="more-menu__menu">
{Object.keys(items).map((id) => {
const item = items[id];
return <li key={id}>
<MenuItem value={id} className='more-menu__menu__item'>
{item.text}
</MenuItem>
</li>
})}
</ul>
</Menu>
</Wrapper>
</div>
</div>
</header>
<Accordion
allowMultipleExpanded={true}
allowZeroExpanded={true}
preExpanded={groupIds}
return <IconContext.Provider value={{size: '14px', color: '#8e8e8e'}}>
<section className="maputnik-layer-editor"
role="main"
aria-label={t("Layer editor")}
>
{groups}
</Accordion>
</section>
<header>
<div className="layer-header">
<h2 className="layer-header__title">
{t("Layer: {{layerId}}", { layerId: formatLayerId(this.props.layer.id) })}
</h2>
<div className="layer-header__info">
<Wrapper
className='more-menu'
onSelection={handleSelection}
closeOnSelection={false}
>
<Button
id="skip-target-layer-editor"
data-wd-key="skip-target-layer-editor"
className='more-menu__button'
title={"Layer options"}>
<MdMoreVert className="more-menu__button__svg" />
</Button>
<Menu>
<ul className="more-menu__menu">
{Object.keys(items).map((id) => {
const item = items[id];
return <li key={id}>
<MenuItem value={id} className='more-menu__menu__item'>
{item.text}
</MenuItem>
</li>
})}
</ul>
</Menu>
</Wrapper>
</div>
</div>
</header>
<Accordion
allowMultipleExpanded={true}
allowZeroExpanded={true}
preExpanded={groupIds}
>
{groups}
</Accordion>
</section>
</IconContext.Provider>
}
}

View File

@@ -1,8 +1,8 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import {MdContentCopy, MdVisibility, MdVisibilityOff, MdDelete} from 'react-icons/md'
import { IconContext } from 'react-icons'
import IconLayer from './IconLayer'
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
@@ -91,51 +91,43 @@ class LayerListItem extends React.Component<LayerListItemProps> {
onLayerVisibilityToggle: () => {},
}
static childContextTypes = {
reactIconBase: PropTypes.object
}
getChildContext() {
return {
reactIconBase: { size: 14 }
}
}
render() {
const visibilityAction = this.props.visibility === 'visible' ? 'show' : 'hide';
return <li
id={this.props.id}
key={this.props.layerId}
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,
})}>
<DraggableLabel {...this.props} />
<span style={{flexGrow: 1}} />
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":delete"}
action={'delete'}
classBlockName="delete"
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)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":toggle-visibility"}
action={visibilityAction}
classBlockName="visibility"
classBlockModifier={visibilityAction}
onClick={_e => this.props.onLayerVisibilityToggle!(this.props.layerIndex)}
/>
</li>
return <IconContext.Provider value={{size: '14px'}}>
<li
id={this.props.id}
key={this.props.layerId}
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,
})}>
<DraggableLabel {...this.props} />
<span style={{flexGrow: 1}} />
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":delete"}
action={'delete'}
classBlockName="delete"
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)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":toggle-visibility"}
action={visibilityAction}
classBlockName="visibility"
classBlockModifier={visibilityAction}
onClick={_e => this.props.onLayerVisibilityToggle!(this.props.layerIndex)}
/>
</li>
</IconContext.Provider>
}
}