6 Commits

Author SHA1 Message Date
liuly 80c0d08179 Fix zoom property crash after deleting a stop (#2153)
## Launch Checklist

<!-- Thanks for the PR! Feel free to add or remove items from the
checklist. -->

When a fixed paint value is converted to a zoom function, Maputnik
creates exactly two stops.

<img width="362" height="226" alt="image"
src="https://github.com/user-attachments/assets/209aebbf-7bb3-4422-b0c7-1019e20a9ddb"
/>

Deleting either one of those two stops leaves a single remaining value.
During the transition back to the ordinary field editor, `ZoomProperty`
can render with `stops` undefined. It previously called `.map`
unconditionally, causing the editor to crash.

<img width="2551" height="1248" alt="image"
src="https://github.com/user-attachments/assets/f5c2af59-dcae-4ffe-8245-f175eea9c843"
/>

This PR guards the stop list with optional chaining. The change only
protects the render path and does not alter zoom-function conversion or
value persistence.

Now, the remaining stop's value will be restored after deleting the
other stop:

<img width="367" height="168" alt="image"
src="https://github.com/user-attachments/assets/8d13236b-6140-451b-8613-0bc5f11893de"
/>

The regression test covers `circle-opacity`:

1. Convert a fixed value to a zoom function.
2. Change the second stop's value.
3. Delete the first of the two stops.
4. Verify that the ordinary field editor reappears.
5. Verify that the remaining stop's value is restored.
6. Edit the restored field and verify that the style updates
successfully.

 - [x] Briefly describe the changes in this PR.
 - [ ] Link to related issues.
- [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.
2026-09-09 18:04:32 +03:00
Nikita Maximilian Grimm 1301dc03e7 Fix layer group expansion state after deletion (#2146)
Deleting a layer changes the starting indices of later groups, so their
stored expansion state no longer matches. Preserve that state through
surviving layer IDs when rebuilding the group keys.

This keeps expanded groups open after deleting an earlier layer or the
first layer of a group. Separate groups with the same prefix retain
their own states; if deletion joins two groups, the merged group stays
expanded when either was expanded.

- Fixes #1781.

Adds five deletion regression tests, a small style fixture, and a
changelog entry.

Validation:

- All 33 layer-list E2E tests and 50 unit tests pass.
- Lint and the production build, including TypeScript checking, pass.
- Manually checked OSM Liberty: all 15 groups remain expanded after
deleting the background layer.
- The full E2E suite reports 160 passing tests and one failure in
`modals > open > upload` (`Could not get styleItem from localStorage`).
The same failure reproduces with the original production code restored.

---------

Co-authored-by: Harel M <harel.mazor@gmail.com>
2026-09-08 18:33:00 +00:00
Jamal Ali c0f76dfff8 fix(layer-list): title visibility button with the action it performs (#2135)
- Fixes #1675

## Problem

In the layer list, the show/hide button's `title` tooltip named the
layer's
current visibility instead of what a click does. A visible layer's
button read
`show` while clicking it hides the layer, and a hidden layer's button
read
`hide` while clicking it shows the layer — exactly reversed.

`LayerListItem.tsx` derived a single value from the layer state:

```ts
const visibilityAction = visibility === "visible" ? "show" : "hide";
```

and passed it to `IconAction` as `action`, which `IconAction` used for
three
different things: choosing the icon, building the `--show`/`--hide` CSS
modifier, and rendering `title={this.props.action}`. The first two are
correct
as a state indicator; only the tooltip needs the opposite verb.

## Change

- `IconAction` gets an optional `title` prop and falls back to `action`
when it
  is not given, so the delete and duplicate buttons are unchanged.
- `LayerListItem` keeps `visibilityAction` (icon +
`maputnik-layer-list-icon-action__visibility--hide`
CSS modifier, which `_layer.scss` relies on to keep the button visible
for
  hidden layers) and adds `visibilityTitle` for the inverted tooltip.

No icon, class name or click behaviour changes.

## Test

New regression test in `e2e/layers-list.spec.ts`: it asserts the button
is
titled `hide` while the layer is visible, clicks it, and asserts it is
titled
`show` once the layer is hidden. Against the unpatched component the
first
assertion fails with `Expected: "hide"` / `Received: "show"`,
reproducing the
reported behaviour.

`npm run lint`, `npx tsc --noEmit`, `npx vitest run` (50 tests) and
`npx playwright test e2e/layers-list.spec.ts` (28 tests) all pass.

## Note

The tooltips in this component (`delete`, `duplicate`, `show`, `hide`)
are
plain English literals and are not run through `t()` today, so this
change
keeps them as-is rather than introducing translation keys for one
button. Also
worth flagging separately: these buttons carry `aria-hidden="true"`, so
the
`title` never reaches assistive technology at all — out of scope here,
but it
means the label is a mouse-hover tooltip only.
2026-09-06 00:12:24 +03:00
Harel M f14eeae38b Increase coverage (#1997)
## Launch Checklist

This PR increases coverage by adding unit tests to lib folde, replace
the skipped end to end placeholder with actual tests and adds more end
to end tests.

This was mostly done by AI (Claude opus 4.8) and I reviewed it and
requested changes where needed.

 - [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.
 - [x] Add an entry to `CHANGELOG.md` under the `## main` section.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-12 15:46:30 +03:00
Harel M 2e0b7cdb8c Replace cypress with playwright (#1988)
## Launch Checklist

This PR replaces cypress with playwright.
<img width="1907" height="933" alt="image"
src="https://github.com/user-attachments/assets/b52075b3-eb3b-45dc-93dc-8c5e9cfd35dd"
/>

I hope this will make the end-to-end debugging and fixing easier due to
the async await support of playwright which is missing in cypress.

This is a pure refactoring change.

 - [x] Briefly describe the changes in this PR.
 - [x] Add an entry to `CHANGELOG.md` under the `## main` section.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-10 18:18:48 +00:00
Harel M be9456d11b Relocate e2e tests (#1989)
## Launch Checklist

Renames the e2e test and reduces changes as a preparation step from
playwright in the following PR:
- #1988

This is to keep as much history as possible.
<img width="1907" height="933" alt="image"
src="https://github.com/user-attachments/assets/b52075b3-eb3b-45dc-93dc-8c5e9cfd35dd"
/>

 - [x] Briefly describe the changes in this PR.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 11:38:59 +03:00