mirror of
https://github.com/maputnik/editor.git
synced 2025-12-07 23:00:01 +00:00
This PR aims at updating some packages. I'll keep this in draft until I'll be more happy with the results. Current setup seems to work, I'll let the CI run and see how bad this is. Packages that needs to be updated/replaces: - [x] ~autocompete - The only warning left in the console is related to the autocomplete, which probably needs to be updated since it's a package that wasn't updated in the last 6 years.~ #611 - [x] ~Codemirror is also something that will need an update, but it looks too complicated at this point in time, so let's see how this goes.~ #891 - [ ] react-color - [x] ~react-aria-menubutton~ #846 - [ ] Others? Most of the changes here are related to types, which is good.
104 lines
2.7 KiB
TypeScript
104 lines
2.7 KiB
TypeScript
import React, {PropsWithChildren, SyntheticEvent} from 'react'
|
|
import classnames from 'classnames'
|
|
import FieldDocLabel from './FieldDocLabel'
|
|
import Doc from './Doc'
|
|
|
|
|
|
type BlockProps = PropsWithChildren & {
|
|
"data-wd-key"?: string
|
|
label?: string
|
|
action?: React.ReactElement
|
|
style?: object
|
|
onChange?(...args: unknown[]): unknown
|
|
fieldSpec?: object
|
|
wideMode?: boolean
|
|
error?: {message: string}
|
|
};
|
|
|
|
type BlockState = {
|
|
showDoc: boolean
|
|
};
|
|
|
|
/** Wrap a component with a label */
|
|
export default class Block extends React.Component<BlockProps, BlockState> {
|
|
_blockEl: HTMLDivElement | null = null;
|
|
|
|
constructor (props: BlockProps) {
|
|
super(props);
|
|
this.state = {
|
|
showDoc: false,
|
|
}
|
|
}
|
|
|
|
onChange(e: React.BaseSyntheticEvent<Event, HTMLInputElement, HTMLInputElement>) {
|
|
const value = e.target.value
|
|
if (this.props.onChange) {
|
|
return this.props.onChange(value === "" ? undefined : value)
|
|
}
|
|
}
|
|
|
|
onToggleDoc = (val: boolean) => {
|
|
this.setState({
|
|
showDoc: val
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Some fields for example <InputColor/> bind click events inside the element
|
|
* to close the picker. This in turn propagates to the <label/> element
|
|
* causing the picker to reopen. This causes a scenario where the picker can
|
|
* never be closed once open.
|
|
*/
|
|
onLabelClick = (event: SyntheticEvent<any, any>) => {
|
|
const el = event.nativeEvent.target;
|
|
const contains = this._blockEl?.contains(el);
|
|
|
|
if (event.nativeEvent.target.nodeName !== "INPUT" && !contains) {
|
|
event.stopPropagation();
|
|
}
|
|
event.preventDefault();
|
|
}
|
|
|
|
render() {
|
|
return <label style={this.props.style}
|
|
data-wd-key={this.props["data-wd-key"]}
|
|
className={classnames({
|
|
"maputnik-input-block": true,
|
|
"maputnik-input-block--wide": this.props.wideMode,
|
|
"maputnik-action-block": this.props.action
|
|
})}
|
|
onClick={this.onLabelClick}
|
|
>
|
|
{this.props.fieldSpec &&
|
|
<div className="maputnik-input-block-label">
|
|
<FieldDocLabel
|
|
label={this.props.label}
|
|
onToggleDoc={this.onToggleDoc}
|
|
fieldSpec={this.props.fieldSpec}
|
|
/>
|
|
</div>
|
|
}
|
|
{!this.props.fieldSpec &&
|
|
<div className="maputnik-input-block-label">
|
|
{this.props.label}
|
|
</div>
|
|
}
|
|
<div className="maputnik-input-block-action">
|
|
{this.props.action}
|
|
</div>
|
|
<div className="maputnik-input-block-content" ref={el => this._blockEl = el}>
|
|
{this.props.children}
|
|
</div>
|
|
{this.props.fieldSpec &&
|
|
<div
|
|
className="maputnik-doc-inline"
|
|
style={{display: this.state.showDoc ? '' : 'none'}}
|
|
>
|
|
<Doc fieldSpec={this.props.fieldSpec} />
|
|
</div>
|
|
}
|
|
</label>
|
|
}
|
|
}
|
|
|