mirror of
https://github.com/maputnik/editor.git
synced 2026-10-17 00:13:44 +00:00
Add font-faces, sky, roll and centerAltitude (#2189)
After: <img width="425" height="366" alt="image" src="https://github.com/user-attachments/assets/f737de31-57e8-4445-b114-a5acdabb619c" /> ## Launch Checklist - [x] Briefly describe the changes in this PR. - [x] Include before/after visuals or gifs if this PR includes visual changes. - [x] Write tests for all new functionality. - [x] Add an entry to `CHANGELOG.md` under the `## main` section.
This commit is contained in:
@@ -10,12 +10,14 @@ import type { StylePropertySpecification } from "maplibre-gl";
|
||||
import type { TransactionSpec } from "@codemirror/state";
|
||||
|
||||
export type InputJsonProps = {
|
||||
value: object
|
||||
value: object | undefined
|
||||
className?: string
|
||||
onChange(object: object): void
|
||||
onChange(object: object | undefined): void
|
||||
onFocus?(...args: unknown[]): unknown
|
||||
onBlur?(...args: unknown[]): unknown
|
||||
lintType: "layer" | "style" | "expression" | "json"
|
||||
/** When set, an empty editor is valid and means the value is unset */
|
||||
optional?: boolean
|
||||
spec?: StylePropertySpecification | undefined
|
||||
/**
|
||||
* When setting this and using search and replace, the editor will scroll to the selected text
|
||||
@@ -49,6 +51,10 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
|
||||
}
|
||||
|
||||
getPrettyJson(data: any) {
|
||||
// An unset value is shown as an empty editor
|
||||
if (data === undefined) {
|
||||
return "";
|
||||
}
|
||||
return stringifyPretty(data, {indent: 2, maxLength: 40});
|
||||
}
|
||||
|
||||
@@ -57,10 +63,11 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
|
||||
parent: this._el!,
|
||||
value: this.getPrettyJson(this.props.value),
|
||||
lintType: this.props.lintType || "layer",
|
||||
onChange: (value:string) => this.onChange(value),
|
||||
onChange: (value: string) => this.onChange(value),
|
||||
onFocus: () => this.onFocus(),
|
||||
onBlur: () => this.onBlur(),
|
||||
spec: this.props.spec
|
||||
spec: this.props.spec,
|
||||
optional: this.props.optional
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,6 +114,13 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
|
||||
const newCode = this._view!.state.doc.toString();
|
||||
|
||||
if (this.state.prevValue !== newCode) {
|
||||
if (this.props.optional && newCode.trim() === "") {
|
||||
this.props.onChange(undefined);
|
||||
this.setState({
|
||||
prevValue: newCode,
|
||||
});
|
||||
return;
|
||||
}
|
||||
let parsedLayer, err;
|
||||
try {
|
||||
parsedLayer = JSON.parse(newCode);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
|
||||
import type {LightSpecification, ProjectionSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from "maplibre-gl";
|
||||
import type {LightSpecification, ProjectionSpecification, SkySpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from "maplibre-gl";
|
||||
import { type WithTranslation, withTranslation } from "react-i18next";
|
||||
|
||||
import { FieldArray } from "../FieldArray";
|
||||
@@ -81,6 +81,24 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
});
|
||||
}
|
||||
|
||||
changeSkyProperty(property: keyof SkySpecification, value: any) {
|
||||
const sky = {
|
||||
...this.props.mapStyle.sky,
|
||||
};
|
||||
|
||||
if (value === undefined) {
|
||||
delete sky[property];
|
||||
}
|
||||
else {
|
||||
sky[property] = value;
|
||||
}
|
||||
|
||||
this.props.onStyleChanged({
|
||||
...this.props.mapStyle,
|
||||
sky,
|
||||
});
|
||||
}
|
||||
|
||||
changeProjectionType(value: any) {
|
||||
const projection = {
|
||||
...this.props.mapStyle.projection,
|
||||
@@ -124,6 +142,7 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
const transition = this.props.mapStyle.transition || {};
|
||||
const terrain = this.props.mapStyle.terrain || {} as TerrainSpecification;
|
||||
const projection = this.props.mapStyle.projection || {} as ProjectionSpecification;
|
||||
const sky = this.props.mapStyle.sky || {};
|
||||
|
||||
return <Modal
|
||||
data-wd-key="modal:settings"
|
||||
@@ -149,6 +168,7 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
<Block label={t("Sprite URL")} fieldSpec={latest.$root.sprite} data-wd-key="modal:settings.sprite">
|
||||
<FieldJson
|
||||
lintType="json"
|
||||
optional
|
||||
value={this.props.mapStyle.sprite as any}
|
||||
onChange={(value) => this.changeStyleProperty("sprite", value)}
|
||||
/>
|
||||
@@ -162,6 +182,15 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
onChange={(value) => this.changeStyleProperty("glyphs", value)}
|
||||
/>
|
||||
|
||||
<Block label={t("Font faces")} fieldSpec={latest.$root["font-faces"]} data-wd-key="modal:settings.font-faces">
|
||||
<FieldJson
|
||||
lintType="json"
|
||||
optional
|
||||
value={this.props.mapStyle["font-faces"] as any}
|
||||
onChange={(value) => this.changeStyleProperty("font-faces", value)}
|
||||
/>
|
||||
</Block>
|
||||
|
||||
<FieldString
|
||||
label={fsa.maputnik.maptiler_access_token.label}
|
||||
fieldSpec={fsa.maputnik.maptiler_access_token}
|
||||
@@ -231,6 +260,23 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
onChange={(value) => this.changeStyleProperty("pitch", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Roll")}
|
||||
data-wd-key="modal:settings.roll"
|
||||
fieldSpec={latest.$root.roll}
|
||||
value={mapStyle.roll}
|
||||
default={latest.$root.roll.default}
|
||||
onChange={(value) => this.changeStyleProperty("roll", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Center altitude")}
|
||||
data-wd-key="modal:settings.center-altitude"
|
||||
fieldSpec={latest.$root.centerAltitude}
|
||||
value={mapStyle.centerAltitude}
|
||||
onChange={(value) => this.changeStyleProperty("centerAltitude", value)}
|
||||
/>
|
||||
|
||||
<FieldEnum
|
||||
label={t("Light anchor")}
|
||||
fieldSpec={latest.light.anchor}
|
||||
@@ -285,6 +331,66 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
|
||||
onChange={(value) => this.changeTerrainProperty("exaggeration", value)}
|
||||
/>
|
||||
|
||||
<FieldColor
|
||||
label={t("Sky color")}
|
||||
fieldSpec={latest.sky["sky-color"]}
|
||||
value={sky["sky-color"] as string}
|
||||
default={latest.sky["sky-color"].default}
|
||||
onChange={(value) => this.changeSkyProperty("sky-color", value)}
|
||||
/>
|
||||
|
||||
<FieldColor
|
||||
label={t("Horizon color")}
|
||||
fieldSpec={latest.sky["horizon-color"]}
|
||||
value={sky["horizon-color"] as string}
|
||||
default={latest.sky["horizon-color"].default}
|
||||
onChange={(value) => this.changeSkyProperty("horizon-color", value)}
|
||||
/>
|
||||
|
||||
<FieldColor
|
||||
label={t("Fog color")}
|
||||
fieldSpec={latest.sky["fog-color"]}
|
||||
value={sky["fog-color"] as string}
|
||||
default={latest.sky["fog-color"].default}
|
||||
onChange={(value) => this.changeSkyProperty("fog-color", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Sky horizon blend")}
|
||||
data-wd-key="modal:settings.sky-horizon-blend"
|
||||
fieldSpec={latest.sky["sky-horizon-blend"]}
|
||||
value={sky["sky-horizon-blend"] as number}
|
||||
default={latest.sky["sky-horizon-blend"].default}
|
||||
onChange={(value) => this.changeSkyProperty("sky-horizon-blend", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Horizon fog blend")}
|
||||
data-wd-key="modal:settings.horizon-fog-blend"
|
||||
fieldSpec={latest.sky["horizon-fog-blend"]}
|
||||
value={sky["horizon-fog-blend"] as number}
|
||||
default={latest.sky["horizon-fog-blend"].default}
|
||||
onChange={(value) => this.changeSkyProperty("horizon-fog-blend", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Fog ground blend")}
|
||||
data-wd-key="modal:settings.fog-ground-blend"
|
||||
fieldSpec={latest.sky["fog-ground-blend"]}
|
||||
value={sky["fog-ground-blend"] as number}
|
||||
default={latest.sky["fog-ground-blend"].default}
|
||||
onChange={(value) => this.changeSkyProperty("fog-ground-blend", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Atmosphere blend")}
|
||||
data-wd-key="modal:settings.atmosphere-blend"
|
||||
fieldSpec={latest.sky["atmosphere-blend"]}
|
||||
value={sky["atmosphere-blend"] as number}
|
||||
default={latest.sky["atmosphere-blend"].default}
|
||||
onChange={(value) => this.changeSkyProperty("atmosphere-blend", value)}
|
||||
/>
|
||||
|
||||
<FieldNumber
|
||||
label={t("Transition delay")}
|
||||
data-wd-key="modal:settings.transition-delay"
|
||||
|
||||
Reference in New Issue
Block a user