Add support for sprite object (#1488)

## Launch Checklist

- Fixes #1302

When a sprite object is used, the current settings modal does not
present it well and does not allow editing.
This changes the input from a string to json.
It does make the editing a bit more cumbersome as you need to type `"`
now instead of just placing the address, but if you click the info
button you should be able to understand that this is a special field.
The fact that it looks like a code editor should also help guide users
to place different input there.

Before:
<img width="710" height="297" alt="image"
src="https://github.com/user-attachments/assets/a615dddd-6c06-45fb-b5a9-1820e6a5c077"
/>


After:
<img width="710" height="297" alt="image"
src="https://github.com/user-attachments/assets/fdb89ada-91ca-4bf4-8380-ce3c25373b41"
/>


 - [x] Briefly describe the changes in this PR.
 - [x] Link to related issues.
- [x] Include before/after visuals or gifs if this PR includes visual
changes.
 - [x] Write tests for all new functionality.
 - [ ] Add an entry to `CHANGELOG.md` under the `## main` section.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Harel M
2025-11-06 14:18:30 +02:00
committed by GitHub
parent 85bf0e02a4
commit 4ba09144e9
4 changed files with 25 additions and 8 deletions

View File

@@ -11,6 +11,7 @@
- Added color highlight for problematic properties
- Upgraded codemirror from version 5 to version 6
- Add code editor to allow editing the entire style
- Add support for sprite object in setting modal
- _...Add new stuff here..._
### 🐞 Bug fixes

View File

@@ -199,6 +199,10 @@ export class MaputnikDriver {
appendTextInJsonEditor: (text: string) => {
this.helper.get.element(".cm-line").first().click().type(text, { parseSpecialCharSequences: false });
},
setTextInJsonEditor: (text: string) => {
this.helper.get.element(".cm-line").first().click().clear().type(text, { parseSpecialCharSequences: false });
}
};

View File

@@ -170,12 +170,22 @@ describe("modals", () => {
});
it("sprite url", () => {
when.setValue("modal:settings.sprite", "http://example.com");
when.setTextInJsonEditor("\"http://example.com\"");
when.click("modal:settings.name");
then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
sprite: "http://example.com",
});
});
it("sprite object", () => {
when.setTextInJsonEditor(JSON.stringify([{id: "1", url: "2"}]));
when.click("modal:settings.name");
then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
sprite: [{ id: "1", url: "2"}],
});
});
it("glyphs url", () => {
const glyphsUrl = "http://example.com/{fontstack}/{range}.pbf";
when.setValue("modal:settings.glyphs", glyphsUrl);

View File

@@ -11,6 +11,8 @@ import FieldSelect from "../FieldSelect";
import FieldEnum from "../FieldEnum";
import FieldColor from "../FieldColor";
import Modal from "./Modal";
import FieldJson from "../FieldJson";
import Block from "../Block";
import fieldSpecAdditional from "../../libs/field-spec-additional";
import type {OnStyleChangedCallback, StyleSpecificationWithId} from "../../libs/definitions";
@@ -144,13 +146,13 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
value={(this.props.mapStyle as any).owner}
onChange={(value) => this.changeStyleProperty("owner", value)}
/>
<FieldUrl
fieldSpec={latest.$root.sprite}
label={t("Sprite URL")}
data-wd-key="modal:settings.sprite"
value={this.props.mapStyle.sprite as string}
onChange={(value) => this.changeStyleProperty("sprite", value)}
/>
<Block label={t("Sprite URL")} fieldSpec={latest.$root.sprite} data-wd-key="modal:settings.sprite">
<FieldJson
lintType="json"
value={this.props.mapStyle.sprite as any}
onChange={(value) => this.changeStyleProperty("sprite", value)}
/>
</Block>
<FieldUrl
label={t("Glyphs URL")}