Compare commits

...

1101 Commits

Author SHA1 Message Date
HarelM
72b9e624a7 deploy: c168e65d86 2025-12-03 11:40:13 +00:00
HarelM
4c847faaae deploy: 74a21e1b77 2025-12-02 10:04:09 +00:00
HarelM
7089ca1b5c deploy: 9d19ab8606 2025-12-02 09:34:09 +00:00
HarelM
2cd6019cb2 deploy: 522815b4c5 2025-11-20 10:56:01 +00:00
HarelM
775b5f4a39 deploy: 7a93d592ff 2025-11-09 21:58:08 +00:00
HarelM
93baf3d5e2 deploy: 876a3d70df 2025-11-09 11:03:19 +00:00
HarelM
74f44a49af deploy: 0fbba4b362 2025-11-06 14:32:20 +00:00
HarelM
6310d6f11e deploy: 4ba09144e9 2025-11-06 12:19:37 +00:00
HarelM
8153050d38 deploy: 5b34a3791f 2025-11-04 07:12:13 +00:00
HarelM
917da6bc7d deploy: 696e43b474 2025-11-02 13:38:53 +00:00
HarelM
5f0ea7be24 deploy: fe2571addb 2025-10-17 23:43:49 +00:00
HarelM
8db5842e85 deploy: 7e784f80f6 2025-10-17 20:17:50 +00:00
HarelM
5a8effb363 deploy: 8cd5e28f3a 2025-10-10 13:41:06 +00:00
HarelM
236058e95b deploy: 39d63ec7b1 2025-10-05 13:39:07 +00:00
HarelM
2da67c7963 deploy: 1730e9cb1c 2025-09-17 17:52:33 +00:00
HarelM
f67704c545 deploy: 3c3fcadbb6 2025-09-16 13:43:10 +00:00
HarelM
83b96e8f80 deploy: b42afd0027 2025-09-15 05:15:59 +00:00
birkskyum
59cf0fc47c deploy: 5312d61598 2025-09-14 09:49:28 +00:00
HarelM
bc8f9fd685 deploy: 56cdfd23df 2025-09-14 09:13:23 +00:00
HarelM
542e7777d8 deploy: 69143ea5d6 2025-09-14 08:14:50 +00:00
HarelM
12c5dd912b deploy: a322afdcee 2025-09-13 22:47:26 +00:00
HarelM
95dbed3f69 deploy: c6f599cc61 2025-09-13 20:12:13 +00:00
HarelM
3acf7ccf5b deploy: 42e1273241 2025-09-11 17:44:17 +00:00
HarelM
6c4758c89c deploy: d81316435b 2025-09-11 10:10:22 +00:00
HarelM
9bfea8f868 deploy: c3c6118df1 2025-09-10 11:45:37 +00:00
HarelM
2d2a4739f1 deploy: 9c85883b8a 2025-09-10 11:38:22 +00:00
HarelM
fd218db356 deploy: 3725f83b48 2025-09-09 22:53:51 +00:00
HarelM
bc2b08ed92 deploy: 7bfc3188f7 2025-09-09 22:47:57 +00:00
HarelM
9af15e5359 deploy: 25d6e9693d 2025-09-09 22:18:15 +00:00
HarelM
669781ccca deploy: 7fc334ad85 2025-09-09 14:33:27 +00:00
HarelM
18da95d2a6 deploy: 55a487d0c8 2025-09-08 19:09:30 +00:00
HarelM
b47d105e1f deploy: abe6230932 2025-09-08 12:23:28 +00:00
HarelM
5f9c21cf2b deploy: 6f4c34b29a 2025-09-07 14:43:38 +00:00
HarelM
956d24c524 deploy: 54c1b761fd 2025-09-07 14:30:51 +00:00
HarelM
4e02c6e12d deploy: 4d5c74f4ee 2025-09-07 10:06:13 +00:00
HarelM
e9966e5a20 deploy: e2e29d7f5e 2025-08-17 08:07:25 +00:00
birkskyum
3deb491306 deploy: 727bc7dfae 2025-08-07 18:35:15 +00:00
louwers
34572dc3f0 deploy: b2fa703ceb 2025-07-10 04:07:56 +00:00
louwers
6bf79c2121 deploy: 3ddb55aec7 2025-07-05 18:31:48 +00:00
louwers
a925995f89 deploy: 2fef0467b6 2025-07-05 12:47:58 +00:00
louwers
c674575fbc deploy: eb985f4d95 2025-07-05 11:59:23 +00:00
louwers
b030a2a707 deploy: c486aa2139 2025-07-05 11:56:00 +00:00
louwers
74aa3b48db deploy: 533f647c71 2025-07-05 09:33:30 +00:00
louwers
a399df0adc deploy: 4b977fd33e 2025-07-04 21:50:06 +00:00
louwers
1282062b32 deploy: e58b92b0cd 2025-07-04 20:22:52 +00:00
louwers
bb243db63c deploy: 599240033a 2025-07-04 08:28:00 +00:00
HarelM
45c1281490 deploy: 851e4bad21 2025-06-13 04:20:07 +00:00
nyurik
40e452d547 deploy: 19389ca3d3 2025-05-28 18:39:19 +00:00
HarelM
2e62b1802a deploy: 4f52df7c3b 2025-05-04 04:40:44 +00:00
HarelM
ea4c3f4e3e deploy: b6afbb0321 2025-04-21 19:45:41 +00:00
HarelM
19c538a29e deploy: d691d49538 2025-03-28 13:34:48 +00:00
HarelM
d379d462f2 deploy: 699241b691 2025-03-14 20:35:35 +00:00
nyurik
8eb9fe062f deploy: 9540686b40 2025-02-25 10:02:16 +00:00
HarelM
9ca274805c deploy: da361509d2 2025-02-04 06:36:51 +00:00
birkskyum
fc507c7e79 deploy: abf3bd1fa0 2025-01-28 12:58:40 +00:00
HarelM
66453a46ca deploy: b87c8fb5c3 2025-01-25 07:25:28 +00:00
HarelM
96b0c53fd2 deploy: 5af2cc2f9e 2025-01-23 09:00:05 +00:00
birkskyum
663034b749 deploy: dcdbac35ff 2025-01-22 11:43:15 +00:00
birkskyum
c82696d268 deploy: 2852fa62ff 2025-01-22 10:39:26 +00:00
birkskyum
7d987cf68b deploy: 87cd79e86f 2025-01-21 21:39:06 +00:00
birkskyum
075437555a deploy: cd7d607f13 2025-01-21 15:22:33 +00:00
HarelM
654dc9c31b deploy: b429bb16d7 2025-01-21 14:26:07 +00:00
birkskyum
2c8bc5aa04 deploy: a21efcc4d5 2025-01-21 13:48:26 +00:00
HarelM
07bee66764 deploy: 3e6994084c 2025-01-21 13:25:16 +00:00
HarelM
f675c7ff7b deploy: 69e4888d71 2025-01-21 12:25:50 +00:00
HarelM
ad85fd8f12 deploy: 2a3e7ea4bb 2025-01-21 12:09:54 +00:00
HarelM
634d664e46 deploy: a97287a66e 2025-01-21 12:09:04 +00:00
HarelM
0046122c87 deploy: 9a866179b7 2025-01-21 12:01:16 +00:00
HarelM
c0f798a6f6 deploy: 84e9a73d86 2025-01-21 12:00:58 +00:00
HarelM
47941e3738 deploy: 53fbc1ffe9 2025-01-21 11:57:51 +00:00
HarelM
237457a159 deploy: b357e1f352 2025-01-21 11:57:31 +00:00
HarelM
d9dad5614e deploy: c5f6d51ea1 2025-01-21 11:54:31 +00:00
HarelM
f18a594131 deploy: 117f37139e 2025-01-21 11:53:25 +00:00
HarelM
fde3d8fc18 deploy: 39aef39b72 2025-01-21 11:52:48 +00:00
HarelM
a493d6df52 deploy: 1657aa4676 2025-01-21 11:50:24 +00:00
HarelM
7e8eca6f97 deploy: b09d41e41d 2025-01-21 11:49:20 +00:00
HarelM
c3764b65d9 deploy: f17f529ede 2025-01-21 11:48:57 +00:00
HarelM
56e151329d deploy: f12af91a55 2025-01-21 11:48:16 +00:00
HarelM
28d6589928 deploy: e87e122067 2025-01-21 11:47:53 +00:00
birkskyum
7adf516383 deploy: 6af3165418 2025-01-21 10:23:43 +00:00
birkskyum
9a1385823e deploy: b1d4b53548 2025-01-21 09:51:57 +00:00
HarelM
2fc5ab4509 deploy: 69124d0752 2025-01-21 08:49:52 +00:00
HarelM
3108b88e59 deploy: 405b8aa951 2025-01-16 21:54:38 +00:00
HarelM
b910e4fdb6 deploy: d50ea76347 2025-01-09 16:55:36 +00:00
louwers
907c09a927 deploy: c6174a57d9 2024-11-25 11:41:18 +00:00
HarelM
16fb99d9b1 deploy: af01346279 2024-11-14 21:54:28 +00:00
HarelM
a364176a3e deploy: 687f9abaf2 2024-10-31 19:04:51 +00:00
HarelM
48164f5a9d deploy: 172d4d5278 2024-10-15 07:13:06 +00:00
HarelM
046b1b3bb2 deploy: b03af2c039 2024-09-29 13:10:39 +00:00
HarelM
f33e09df62 deploy: 6089cde302 2024-09-29 12:02:38 +00:00
HarelM
7333eb6378 deploy: 25cf61a825 2024-09-25 07:23:54 +00:00
HarelM
ffdc04b3aa deploy: 0f1000c5b0 2024-09-18 04:02:23 +00:00
louwers
223809dda5 deploy: fa4ece22cf 2024-09-16 23:39:50 +00:00
HarelM
744ad0f917 deploy: 00f431c50e 2024-09-03 05:25:36 +00:00
HarelM
2f324c695b deploy: 60785f53bc 2024-09-02 09:45:51 +00:00
HarelM
dd4cbb1b3d deploy: 32fa02d289 2024-09-01 06:59:24 +00:00
HarelM
e61aa393c6 deploy: 482e6ec545 2024-08-29 19:15:18 +00:00
HarelM
e9c24d5ac9 deploy: 4dd34e99fd 2024-08-29 17:23:36 +00:00
HarelM
a7ed7cdb45 deploy: 66c5a5c953 2024-08-29 14:08:36 +00:00
HarelM
dea98ad7b6 deploy: 8184ac8393 2024-08-21 05:58:07 +00:00
HarelM
987c3cd31e deploy: 6a0d2e8ee5 2024-08-21 04:18:41 +00:00
HarelM
6d970fe73f deploy: 58edd262b0 2024-08-19 09:44:12 +00:00
nyurik
9cfd0ced73 deploy: 35840409b8 2024-07-26 02:51:28 +00:00
HarelM
1464a337e3 deploy: d0f6e0fadb 2024-07-12 18:19:25 +00:00
HarelM
1eaba084ed deploy: 0de304ca3e 2024-06-24 05:10:30 +00:00
HarelM
37ba7457d5 deploy: c82c6158e6 2024-05-29 07:48:23 +00:00
HarelM
43a7c058fd deploy: 41cd7dfad1 2024-05-20 11:44:06 +00:00
HarelM
87c7c7ff93 deploy: 7591b031ce 2024-04-16 05:27:23 +00:00
HarelM
8c8241b13b deploy: f34529ef06 2024-04-03 17:27:41 +00:00
HarelM
c187f02c27 deploy: a73b11805d 2024-03-26 23:13:29 +00:00
HarelM
617adcdc48 deploy: ff15b77b7f 2024-03-21 20:52:33 +00:00
HarelM
e71c49e38c deploy: 355b663e7e 2024-03-14 19:03:54 +00:00
HarelM
9572eefd48 deploy: 3c043fd5e0 2024-03-13 20:49:07 +00:00
HarelM
3303a25737 deploy: 5f54dd0ccf 2024-03-09 21:04:29 +00:00
HarelM
49f91a69f1 deploy: 3727f5da48 2024-02-21 05:18:43 +00:00
HarelM
c853c754b1 deploy: bc5ecfade6 2024-02-07 08:33:35 +00:00
HarelM
1b5596052c deploy: c84c7a7b96 2024-02-04 14:39:01 +00:00
HarelM
1c1b5cd208 deploy: cb77c6b4e2 2024-02-04 09:38:30 +00:00
HarelM
c948814efc deploy: ea42f434eb 2024-02-04 08:02:30 +00:00
HarelM
7b9d3512c6 deploy: 6f82c12861 2024-02-04 07:19:30 +00:00
HarelM
edf3a58ea6 deploy: 3b95b25777 2024-01-13 12:40:08 +00:00
HarelM
5a4b5fb9e9 deploy: 1da65f2116 2024-01-12 16:47:24 +00:00
HarelM
6f9f53add6 deploy: a62db148cd 2024-01-12 09:01:06 +00:00
HarelM
e0199c9ce7 deploy: 6ed10a862f 2024-01-11 20:58:23 +00:00
Harel M
e1ed42f16f Fix static files reference 2024-01-11 20:00:59 +00:00
Harel M
104c3c0c10 another attempt to fix base-href 2024-01-11 19:53:30 +00:00
Harel M
f4a1aa4729 Add base tag to html 2024-01-11 19:48:33 +00:00
Harel M
fda7fac260 Publish the current version of maputnik 2024-01-11 19:45:24 +00:00
Harel M
87cf81d1c9 Prepare for on boarding (#858)
I believe this solves most of the missing checkboxes:
- https://github.com/maplibre/maplibre/issues/352

Let me know if there's anything else missing.
Other configuration can be done after the repo has been migrated I
believe.
2024-01-11 17:08:42 +02:00
ShellyDCMS
8e35ed97e6 Improve drivers (#856)
Co-authored-by: shelly_goldblit <shelly_goldblit@dell.com>
Co-authored-by: HarelM <harel.mazor@gmail.com>
2024-01-02 12:12:06 +02:00
Harel M
124ae98bf3 E2E: Improve tests, lint, and add more drivers (#855)
This PR introduces lint to cypress code, adds drivers to try and
abstract the usage of cypress as much as possible.
Nothing very interesting, mainly to try out the driver pattern for the
e2e tests.
2023-12-27 20:58:24 +02:00
Harel M
b784bf2b84 Improve tests (#854)
Recover commented out tests, 
Improve usage of helper in driver, 
Added data-wd-key for test to use instead of classes
Moved all non tsx file to a single folder (lib) instead of lib and utils

---------

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2023-12-27 10:19:59 +02:00
Max
09a1f3f87b Use nginx to serve built files (#808)
Resolves #842
Better suited than python + handles sigterm better

Co-authored-by: Harel M <harel.mazor@gmail.com>
2023-12-26 23:28:17 +02:00
Harel M
a22476cab2 Add lint to CI and fix errors (#853)
Adds lint to CI and fixes errors.
I'm not sure I'm fully proud of all the solutions there.
But there's no lint issues and the lint is being checked as part of the
CI.

---------

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2023-12-26 23:13:22 +02:00
ShellyDCMS
a324ddb654 add code coverage (#852)
Add Cypress code coverage using Istanbul nyc

![image](https://github.com/maputnik/editor/assets/60476837/e7c364b7-7b54-4bf1-85aa-ee6fb19cc40c)

---------

Co-authored-by: shelly_goldblit <shelly_goldblit@dell.com>
Co-authored-by: Harel M <harel.mazor@gmail.com>
2023-12-26 12:04:43 +02:00
Harel M
656264f2bc Migration of jsx files to tsx 3 (#851)
This is in continue to:
- #850
- #848

The last files should be converted as part of this PR, there are only a
handful left.
2023-12-25 15:48:46 +02:00
Harel M
974dd7bfd9 Migration of jsx files to tsx 2 (#850)
This is to continue the work of migrating all the jsx files into tsx
files.
The MO is basically described here: #848.

About 7 files to go...
2023-12-22 23:32:25 +02:00
Harel M
fa182e66fa Migration of jsx files to tsx 1 (#848)
In this PR I have changed some of the jsx files to tsx file.
I'm starting off with the "leafs" so that migration of the rest will be
easier, hopefully.

What I'm basically doing is taking a jsx file, copy paste it into:
https://mskelton.dev/ratchet

And after that I'm fixing the types as needed.
It's not a very long process.

Hopefully more PRs will follow and this will be over soon.
I don't plan to migrate the storybook as I generally don't understand
why is it useful, I'll open an issue to see if anyone thinks
differently.
2023-12-21 23:46:56 +02:00
Harel M
3bf0e510e6 Migrate all the non react components code to typescript (#847)
This completes the migration to typescript of all the non react
components code.
The only changes introduced besides types are the type checks using
`"something" in object` which narrows down types in typescript.
2023-12-21 00:07:53 +02:00
Harel M
e8d07fa694 Initial migration to typescript (#845)
This migrates some utilities classes from javascript to typescript.
Nothing special about the migration, mainly added types and made sure
the code adheres to the strict mode.

I have picked some small files so git doesn't think they are the same
since they are "very different".
I hope that in later PRs, when migrating lager files this won't be an
issues.
2023-12-20 22:56:33 +02:00
Harel M
4d1e2e6893 Refactor driver for E2E (#843)
This is basically the content of #841 with the code review changes and
relevant fixes to tests/driver code to pass the tests.
CC: @ShellyDCMS

After this we should lint the project and add the lint to the CI to make
sure it doesn't break.

---------

Co-authored-by: ShellyDCMS <60476837+ShellyDCMS@users.noreply.github.com>
Co-authored-by: shelly_goldblit <shelly_goldblit@dell.com>
2023-12-20 16:34:46 +02:00
Harel M
f219ff1e17 Fix favicon (#844)
This PR fixes the missing facicon.
As part of the migration to vite, this issue was introduced.
- #836
2023-12-20 07:18:13 +02:00
Yuri Astrakhan
8eabfa5519 Fix incorrect CI tag filter (#838) 2023-12-18 06:21:43 +02:00
Harel M
ad69cbdb20 Vite + TypeScript (#836)
Resolves #803

This is an initial commit to allow migrating to typescript bit by bit.
It introduces vite.
It removes all the webpack configuration (which I have no clue what all
the profiling are needed for, and couldn't find anything in the readme).
It also changes a single file from javascript to typescript:
`urlopen.js` -> `urlopen.ts`
Which was done manually, later on I'll see if I can automate most of the
migration.
For now, everything seems to work as expected.
I also upgrades storybook to use vite and renames the stories to jsx (I
honestly don't know why this complexity is needed here, but I'll keep it
for now).

cc: @damianstasik
2023-12-17 22:52:19 -05:00
Yuri Astrakhan
17eaa3f204 Rename primary branch to main (#837)
Co-authored-by: Harel M <harel.mazor@gmail.com>
2023-12-18 00:09:10 +02:00
Harel M
1df2e36dbb Replace WebDriverIO with Cypress (#831)
This does the following:
1. Moves the WDIO code from javascript to typescript
2. Moves to use files that are `cy.ts` instead of `index.js`
3. Replace e2e to use cypress
4. Introduce back some skipped tests

This is in continue to the conversation here:
https://github.com/HarelM/editor/pull/3

Before:
```
 "spec" Reporter:
------------------------------------------------------------------
[chrome 120.0.6099.71 linux #0-0] Running: chrome (v120.0.6099.71) on linux
[chrome 120.0.6099.71 linux #0-0] Session ID: ee9a87bcfce007ac7721929c6e6234d0
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0] » /test/functional/index.js
[chrome 120.0.6099.71 linux #0-0] maputnik
[chrome 120.0.6099.71 linux #0-0]     history
[chrome 120.0.6099.71 linux #0-0]        - undo/redo
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     layers
[chrome 120.0.6099.71 linux #0-0]         ops
[chrome 120.0.6099.71 linux #0-0]            ✓ delete
[chrome 120.0.6099.71 linux #0-0]            ✓ duplicate
[chrome 120.0.6099.71 linux #0-0]            ✓ hide
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         background
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]             modify
[chrome 120.0.6099.71 linux #0-0]                 layer
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    ✓ id
[chrome 120.0.6099.71 linux #0-0]                    ✓ min-zoom
[chrome 120.0.6099.71 linux #0-0]                    ✓ max-zoom
[chrome 120.0.6099.71 linux #0-0]                    ✓ comments
[chrome 120.0.6099.71 linux #0-0]                    - color
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 filter
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - compound filter
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 paint
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - color
[chrome 120.0.6099.71 linux #0-0]                    - pattern
[chrome 120.0.6099.71 linux #0-0]                    - opacity
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 json-editor
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - modify
[chrome 120.0.6099.71 linux #0-0]                    - parse error
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         fill
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]            - change source
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         line
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]            - groups
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         symbol
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         raster
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         circle
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         fill extrusion
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         groups
[chrome 120.0.6099.71 linux #0-0]            ✓ simple
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     map
[chrome 120.0.6099.71 linux #0-0]         zoom level
[chrome 120.0.6099.71 linux #0-0]            - via url
[chrome 120.0.6099.71 linux #0-0]            - via map controls
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     modals
[chrome 120.0.6099.71 linux #0-0]         open
[chrome 120.0.6099.71 linux #0-0]            ✓ close
[chrome 120.0.6099.71 linux #0-0]            - upload
[chrome 120.0.6099.71 linux #0-0]            ✓ load from url
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         shortcuts
[chrome 120.0.6099.71 linux #0-0]            ✓ open/close
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         export
[chrome 120.0.6099.71 linux #0-0]            ✓ close
[chrome 120.0.6099.71 linux #0-0]            - download
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         sources
[chrome 120.0.6099.71 linux #0-0]            - active sources
[chrome 120.0.6099.71 linux #0-0]            - public source
[chrome 120.0.6099.71 linux #0-0]            - add new source
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         inspect
[chrome 120.0.6099.71 linux #0-0]            ✓ toggle
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         style settings
[chrome 120.0.6099.71 linux #0-0]            ✓ name
[chrome 120.0.6099.71 linux #0-0]            ✓ owner
[chrome 120.0.6099.71 linux #0-0]            ✓ sprite url
[chrome 120.0.6099.71 linux #0-0]            ✓ glyphs url
[chrome 120.0.6099.71 linux #0-0]            ✓ maptiler access token
[chrome 120.0.6099.71 linux #0-0]            ✓ thunderforest access token
[chrome 120.0.6099.71 linux #0-0]            ✓ style renderer
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         sources
[chrome 120.0.6099.71 linux #0-0]            - toggle
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     screenshots
[chrome 120.0.6099.71 linux #0-0]        ✓ front_page
[chrome 120.0.6099.71 linux #0-0]        ✓ open
[chrome 120.0.6099.71 linux #0-0]        ✓ export
[chrome 120.0.6099.71 linux #0-0]        ✓ sources
[chrome 120.0.6099.71 linux #0-0]        ✓ style settings
[chrome 120.0.6099.71 linux #0-0]        ✓ inspect
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     accessibility
[chrome 120.0.6099.71 linux #0-0]         skip links
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to layer list
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to layer editor
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to map view
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     keyboard
[chrome 120.0.6099.71 linux #0-0]         shortcuts
[chrome 120.0.6099.71 linux #0-0]            ✓ ESC should unfocus
[chrome 120.0.6099.71 linux #0-0]            ✓ '?' should show shortcuts modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'o' should show open modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'e' should show export modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'd' should show sources modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 's' should show settings modal
[chrome 120.0.6099.71 linux #0-0]            - 'i' should change map to inspect mode
[chrome 120.0.6099.71 linux #0-0]            ✓ 'm' should focus map
[chrome 120.0.6099.71 linux #0-0]            ✓ '!' should show debug modal
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0] 44 passing (58.8s)
[chrome 120.0.6099.71 linux #0-0] 23 skipped
```

After:
```
accessibility
    skip links
      - skip link to layer list
      - skip link to layer editor
      - skip link to map view

history
    ✓ undo/redo (4894ms)

keyboard
    shortcuts
      ✓ ESC should unfocus (1912ms)
      ✓ '?' should show shortcuts modal (458ms)
      ✓ 'o' should show open modal (710ms)
      ✓ 'e' should show export modal (692ms)
      ✓ 'd' should show sources modal (588ms)
      ✓ 's' should show settings modal (894ms)
      ✓ 'i' should change map to inspect mode (804ms)
      ✓ 'm' should focus map (837ms)
      ✓ '!' should show debug modal (607ms)

layers
    ops
      ✓ delete (4313ms)
      ✓ duplicate (1780ms)
      ✓ hide (1862ms)
    background
      ✓ add (1675ms)
      modify
        layer
          - expand/collapse
          ✓ id (3735ms)
          ✓ min-zoom (2209ms)
          ✓ max-zoom (2127ms)
          ✓ comments (2515ms)
          ✓ color (2022ms)
        filter
          - expand/collapse
          - compound filter
        paint
          - expand/collapse
          - color
          - pattern
          - opacity
        json-editor
          - expand/collapse
          - modify
          - parse error
    fill
      ✓ add (1831ms)
      - change source
    line
      ✓ add (1844ms)
      ✓ groups (687ms)
    symbol
      ✓ add (2035ms)
    raster
      ✓ add (1814ms)
    circle
      ✓ add (1867ms)
    fill extrusion
      ✓ add (1963ms)
    groups
      ✓ simple (2653ms)

map
    zoom level
      ✓ via url (2279ms)
      ✓ via map controls (733ms)

modals
    open
      ✓ close (2519ms)
      - upload
      ✓ load from url (1557ms)
    shortcuts
      ✓ open/close (1136ms)
    export
      ✓ close (755ms)
      - download
    sources
      - active sources
      - public source
      - add new source
    inspect
      ✓ toggle (1020ms)
    style settings
      ✓ name (1085ms)
      ✓ owner (1060ms)
      ✓ sprite url (1214ms)
      ✓ glyphs url (1553ms)
      ✓ maptiler access token (1111ms)
      ✓ thunderforest access token (1102ms)
      ✓ style renderer (922ms)
    sources
      - toggle



      Spec                                              Tests  Passing  Failing  Pending  Skipped  
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✔  accessibility.cy.ts                       52ms        3        -        -        3        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  history.cy.ts                            00:06        1        1        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  keyboard.cy.ts                           00:10        9        9        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  layers.cy.ts                             00:39       28       17        -       11        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  map.cy.ts                                00:04        2        2        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  modals.cy.ts                             00:16       18       12        -        6        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    ✔  All specs passed!                        01:18       61       41        -       20        -  
```

---------

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2023-12-17 21:49:23 +02:00
Birk Skyum
0c46affda9 Add dependabot (#826)
It has a low limit on how many PRs it's allowed to open at a time, so it
should not flood the repo.
2023-12-17 01:16:47 -05:00
Harel M
18f45e932b Use driver pattern for e2e tests (#829)
I've moved all the logic relevant to WBIO into a single file in order to
be able to replace it.
I have tried to upgrade WDIO in order to use the latest version and it
got stuck on my computer.
Furthermore, I was not able to run it locally which made this whole
cycle very long.
After this will be merged I will replace WDIO with cypress.
This doesn't change anything, only moves some code in the tests to a
single file, removes unneeded files and uses the driver pattern, which
will later allow switching the underline WDIO with Cypress.

cc: @nyurik
2023-12-17 01:14:23 -05:00
Yuri Astrakhan
31d56c9fae Bump CI versions (#830) 2023-12-17 00:49:34 -05:00
Birk Skyum
b7838ad6e1 Use latest firefox (#825) 2023-10-23 08:06:02 +02:00
Birk Skyum
c92fd12854 Bump to node 18 (#824) 2023-10-22 22:11:06 +02:00
Birk Skyum
eb55796461 Merge pull request #823 from birkskyum/new-webdriver
Chrome new headless
2023-10-22 20:20:26 +02:00
Yuri Astrakhan
4b97f82980 Revert "Revert "Resolve #821 (#822)""
This reverts commit e4d559f953.
2023-10-21 18:33:48 -04:00
Yuri Astrakhan
5d0b6e3201 Revert "Revert "Added checkbox for cluster attribute (#810)""
This reverts commit 52f949e152.
2023-10-21 18:33:46 -04:00
Birk Skyum
5ab9be9fdb update node version 2023-10-22 00:27:41 +02:00
Birk Skyum
9659d41b83 chrome new headless 2023-10-22 00:20:55 +02:00
Yuri Astrakhan
52f949e152 Revert "Added checkbox for cluster attribute (#810)"
This reverts commit 393f4a38b9.
2023-10-21 18:19:24 -04:00
Yuri Astrakhan
e4d559f953 Revert "Resolve #821 (#822)"
This reverts commit 577663f706.
2023-10-21 18:19:21 -04:00
zstadler
577663f706 Resolve #821 (#822)
Please see code analysis at
https://github.com/maputnik/editor/issues/821#issuecomment-1772360990
2023-10-20 11:01:20 -04:00
Eliav-B
393f4a38b9 Added checkbox for cluster attribute (#810)
* Added additional checkbox to set the cluster attribute when adding a GeoJson source

* Fixed default source function in the 'geojson_json' case

---------

Co-authored-by: shimon <ruisuhsh100@gmail.com>
2023-10-20 10:54:40 -04:00
Kevin Schaul
3727c9ad5e 814/remove mapbox references (#816)
Fixes #814

* fix: remove outdated references to mapbox
* docs: fix references in readme
* chore: fix mapbox references in tests
* chore: fix mapbox references in stories, webpack config
* chore: remove empty array
2023-08-28 22:17:49 -04:00
Yuri Astrakhan
a99cbc00ba Merge pull request #812 from kevinschaul/switch-to-maplibre-ks
Convert from Mapbox GL to MapLibre
2023-07-18 23:32:11 +02:00
Kevin Schaul
fe5f7e8b8c upgrade to setup-go@v3 2023-07-18 15:16:29 -05:00
Kevin Schaul
3ed4b8f2d7 add GOBIN to CI 2023-07-18 11:31:01 -05:00
Kevin Schaul
f17c2e8112 reenable go modules in CI 2023-07-18 10:50:48 -05:00
Kevin Schaul
2be447f105 downgrade to node 16 to avoid ssl issue (for now) 2023-07-18 10:10:08 -05:00
Kevin Schaul
2fe6fa2be6 Update workflow to latest desktop, drop old node 2023-07-18 09:52:29 -05:00
Kevin Schaul
83dd21414b Merge branch 'master' into switch-to-maplibre-ks 2023-07-13 14:48:38 -05:00
Kevin Schaul
56d96a248d Remove JSON.stringify in call to validate 2023-07-13 14:43:18 -05:00
Kevin Schaul
5b1ee7296b Fix Buffer is undefined error 2023-07-13 14:35:16 -05:00
Kevin Schaul
8e0546fba4 Get map rendering with maplibre 2023-07-12 16:37:19 -05:00
Yuri Astrakhan
2ff3d08bb0 Merge pull request #796 from maputnik/dependabot/npm_and_yarn/async-2.6.4
Bump async from 2.6.3 to 2.6.4
2022-12-15 15:14:51 -05:00
dependabot[bot]
afe7a492a7 Bump async from 2.6.3 to 2.6.4
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-15 19:54:14 +00:00
Yuri Astrakhan
1f26ab707f Merge pull request #792 from maputnik/dependabot/npm_and_yarn/deep-object-diff-1.1.9
Bump deep-object-diff from 1.1.7 to 1.1.9
2022-12-15 14:53:11 -05:00
Yuri Astrakhan
233191e27c Merge pull request #793 from maputnik/dependabot/npm_and_yarn/loader-utils-1.4.2
Bump loader-utils from 1.4.1 to 1.4.2
2022-12-15 14:52:58 -05:00
Yuri Astrakhan
246f9a191d Merge pull request #795 from maputnik/dependabot/npm_and_yarn/decode-uri-component-0.2.2
Bump decode-uri-component from 0.2.0 to 0.2.2
2022-12-15 14:52:17 -05:00
dependabot[bot]
07f6efe45d Bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 23:57:21 +00:00
dependabot[bot]
ccd0402eea Bump loader-utils from 1.4.1 to 1.4.2
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-18 00:36:06 +00:00
dependabot[bot]
8ccee0ba75 Bump deep-object-diff from 1.1.7 to 1.1.9
Bumps [deep-object-diff](https://github.com/mattphillips/deep-object-diff) from 1.1.7 to 1.1.9.
- [Release notes](https://github.com/mattphillips/deep-object-diff/releases)
- [Commits](https://github.com/mattphillips/deep-object-diff/commits)

---
updated-dependencies:
- dependency-name: deep-object-diff
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-16 23:59:29 +00:00
Yuri Astrakhan
d6b67be7b2 Merge pull request #780 from maputnik/dependabot/npm_and_yarn/ejs-3.1.7
Bump ejs from 3.1.6 to 3.1.7
2022-11-09 14:52:11 -05:00
Yuri Astrakhan
ac56ea4627 Merge pull request #791 from maputnik/dependabot/npm_and_yarn/loader-utils-1.4.1
Bump loader-utils from 1.4.0 to 1.4.1
2022-11-09 14:51:37 -05:00
dependabot[bot]
b00cf66ea6 Bump loader-utils from 1.4.0 to 1.4.1
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-09 03:55:59 +00:00
Luke Seelenbinder
8e329a0ff9 Remove missed reference to mapbox-gl.
* Also removes specialized support for Mapbox URLs.
2022-11-01 10:24:05 +01:00
Luke Seelenbinder
74cacd5bdf Initial work to convert from Mapbox GL v1.13 to MapLibre v2.4.0. 2022-10-27 14:02:47 +02:00
pathmapper
7d5fb23130 Merge pull request #782 from maputnik/dependabot/npm_and_yarn/got-11.8.5
Bump got from 11.8.3 to 11.8.5
2022-08-14 09:25:13 +02:00
pathmapper
08bbd55f13 Merge pull request #784 from maputnik/dependabot/npm_and_yarn/terser-4.8.1
Bump terser from 4.8.0 to 4.8.1
2022-08-14 09:25:00 +02:00
dependabot[bot]
d6d4930513 Bump terser from 4.8.0 to 4.8.1
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-21 03:45:50 +00:00
dependabot[bot]
6220e15723 Bump got from 11.8.3 to 11.8.5
Bumps [got](https://github.com/sindresorhus/got) from 11.8.3 to 11.8.5.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.3...v11.8.5)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-23 14:02:05 +00:00
dependabot[bot]
72053a2dba Bump ejs from 3.1.6 to 3.1.7
Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.7.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.7)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-07 04:59:25 +00:00
pathmapper
bf27a35ef5 Merge pull request #778 from propheel/feat/updateDependencies
Update dependencies
2022-05-07 06:57:58 +02:00
Filip Proborszcz
4705bf823a Use geckodriver 0.30 for firefox until 0.31 works 2022-05-02 15:13:42 +02:00
Filip Proborszcz
a8f6208561 Fix layer drag&drop and init warning 2022-05-01 11:28:15 +02:00
Filip Proborszcz
af2629be75 Make layer list sortable again 2022-04-10 22:22:16 +02:00
pathmapper
8bfad6c9fd Merge pull request #777 from maputnik/npm-ci
Use npm ci for workflow
2022-04-09 07:51:55 +02:00
Filip Proborszcz
5c3713da90 Use proper version of array-move 2022-04-08 04:14:58 +02:00
Filip Proborszcz
174eae1cf4 Use selenium standalone service to run tests 2022-04-08 03:37:40 +02:00
Filip Proborszcz
d73add77e7 Fixes for breaking changes
- new webpack dev server options
- babel support for async functions in hooks
- new uuid import style
- automatically open browser for testing
2022-04-08 02:23:43 +02:00
Filip Proborszcz
ab00c9f426 Many dependency updates
@storybook 6.4.20 blocks most of others like: react 18, webpack 5,
and keeps lots of unnecessary dependencies due to chakra 2 dep.
2022-04-07 17:21:34 +02:00
pathmapper
d6ab302815 Use npm ci for workflow
https://docs.npmjs.com/cli/v8/commands/npm-ci
2022-04-07 03:28:47 +02:00
pathmapper
f5646f57d1 Merge pull request #776 from propheel/useNode16
Use node 16.x
2022-04-07 03:11:13 +02:00
Filip Proborszcz
c77d8f6625 Use shared SHM for Docker image 2022-04-07 00:37:20 +02:00
Filip Proborszcz
e34c1ca4be Use node 16.x
It required converting mocha tests code into async since [@wdio/sync is
deprecated](https://webdriver.io/docs/sync-vs-async/) starting with
node v16.
It removed the dependency on fibers and on [node-gyp + python](https://
webdriver.io/docs/sync-vs-async/#common-issues-in-sync-mode) indirectly
though which is a great thing.

Also moved away from node-sass to sass since [node-sass is deprecated]
(https://sass-lang.com/blog/libsass-is-deprecated).
2022-04-06 14:05:15 +02:00
Orange Mug
87745f1fc9 Merge pull request #752 from pathmapper/webpack_stats
Webpack stats
2021-08-06 17:59:46 +01:00
pathmapper
9ba0fd5f39 Remove yarn.lock 2021-08-04 09:44:33 +02:00
pathmapper
70decbb5c1 Change webpack-dev-server info 2021-08-04 09:36:37 +02:00
pathmapper
51fa4a4377 Merge pull request #739 from pathmapper/maputnik_tag
Request using 'maputnik' tag for SE questions
2020-10-10 20:16:33 +02:00
pathmapper
fb6f4d73e2 Mention 'maputnik' tag in comment 2020-10-04 12:11:00 +02:00
pathmapper
63b14933ba Merge pull request #729 from orangemug/fix/issue-712-v2
Correctly upgrade old-style filter functions to expressions
2020-09-15 19:10:49 +02:00
Orange Mug
a86c31cefa Merge pull request #727 from orangemug/feature/added-html-option-to-export
Added HTML export option to export modal.
2020-09-10 19:20:40 +01:00
orangemug
25e2554412 Another commit to force a rebuild 2020-09-10 18:07:47 +01:00
Orange Mug
34bb3bc0a7 Merge pull request #726 from orangemug/fix/issue-718
Fix to not change layer key while editing layer
2020-09-10 18:06:03 +01:00
orangemug
852243cd52 onChange -> onInput for <FieldId/> component. 2020-09-09 20:22:52 +01:00
Orange Mug
40faf86adf Merge pull request #725 from orangemug/fix/issue-710
Added 'base' to functions
2020-09-09 20:15:18 +01:00
Orange Mug
bb69f143b8 Merge pull request #724 from orangemug/fix/issue-707
Remove key/value from style when editing style results in empty array
2020-09-09 20:14:58 +01:00
orangemug
bb43200887 Move logic into checkIfSimpleFilter function and added FILTER_OPS check. 2020-09-09 16:12:18 +01:00
orangemug
ae3f79f4ad Attempt to correctly upgrade old-style filter functions to expressions. 2020-09-09 15:55:20 +01:00
orangemug
731a315624 Merge remote-tracking branch 'upstream/master' into feature/added-html-option-to-export 2020-09-09 15:12:23 +01:00
orangemug
5e441454d5 Merge remote-tracking branch 'upstream/master' into fix/issue-718 2020-09-09 15:11:52 +01:00
orangemug
a55716bbd9 Merge remote-tracking branch 'upstream/master' into fix/issue-710 2020-09-09 15:08:42 +01:00
orangemug
44aea3745e Merge remote-tracking branch 'upstream/master' into fix/issue-707 2020-09-09 15:07:35 +01:00
Orange Mug
a572bc02a6 Merge pull request #728 from orangemug/fix/disable-host-check
Disable host check for codesandbox
2020-09-09 15:06:54 +01:00
orangemug
4dee95fa2e Added --disable-host-check 2020-09-09 15:02:14 +01:00
orangemug
381ff6292f Removed disableHostCheck from ./config/webpack.config.js 2020-09-09 14:56:39 +01:00
orangemug
c12db1703b Changed start script for codesandbox. 2020-09-09 14:55:51 +01:00
orangemug
2676583833 Added start-sandbox script. 2020-09-09 14:55:12 +01:00
orangemug
6ca2af7f8a Change codesandbox check. 2020-09-09 14:46:09 +01:00
orangemug
553b17822d Try disable host check for codesandbox. 2020-09-09 14:19:06 +01:00
orangemug
a6148e5f40 Added HTML export option to export modal. 2020-09-09 14:06:48 +01:00
orangemug
4f77629eb7 Fix to not change layer key while editing layer. 2020-09-08 17:58:33 +01:00
orangemug
9103d9560a Added 'base' to functions. 2020-09-08 16:50:29 +01:00
orangemug
06c63509f7 Remove key/value from style when editing style results in empty array 2020-09-08 16:12:41 +01:00
pathmapper
bbe0af6c0e Merge pull request #716 from pathmapper/Use-desktop-v1.0.7
Use desktop v1.0.7 for CI workflow
2020-07-24 19:11:54 +02:00
pathmapper
7455ccc3b7 Use desktop v1.0.7 2020-07-24 18:41:11 +02:00
Orange Mug
8b766777ac Merge pull request #706 from orangemug/fix/input-label-a11y
Improved label accessibility
2020-06-30 10:50:37 +01:00
orangemug
8441abe907 Added padding to 'maputnik-doc-button' and removed cursor from doc label. 2020-06-30 10:30:26 +01:00
orangemug
ca56951256 Fix styling in export model 2020-06-30 09:48:55 +01:00
orangemug
5981151b27 Added cursor pointer to SDK docs button 2020-06-30 09:43:24 +01:00
orangemug
21dbc6c4d9 Added back in https://github.com/maputnik/editor link 2020-06-30 09:42:05 +01:00
Orange Mug
6f060c2a0a Merge pull request #708 from pathmapper/update_mb_deps
Update mb-gl
2020-06-30 09:27:02 +01:00
pathmapper
24327541c5 Update mb-gl 2020-06-30 09:16:53 +02:00
orangemug
0d6b9ee9d4 Fixed source modal CSS for new block definitions. 2020-06-29 16:26:28 +01:00
orangemug
3ad487dce7 Removed isRequired from label incase null. 2020-06-29 16:18:04 +01:00
orangemug
a46c834874 Fixed data functions. 2020-06-29 16:14:35 +01:00
orangemug
67bdea1827 Re-added info button and SDK docs to fields after refactor. 2020-06-29 16:03:59 +01:00
Orange Mug
cc4133aac1 Merge pull request #703 from pathmapper/fix_674
Add again shouldComponentUpdate
2020-06-29 15:41:49 +01:00
orangemug
4a6f58d61c Changed heading sizes for modals. 2020-06-10 20:37:46 +01:00
orangemug
e3dc98b76d <h2/> -> <h1/> 2020-06-10 20:37:08 +01:00
orangemug
09373dda44 Fixed changing between zoom/data functions. 2020-06-10 20:26:39 +01:00
orangemug
c4b05b62b3 Remove logging. 2020-06-10 19:44:05 +01:00
orangemug
06bccfab10 Fix for checkboxes within non-clickable label 2020-06-10 19:21:29 +01:00
orangemug
b83c9a1ad9 Fix block styling issues. 2020-06-10 19:20:18 +01:00
orangemug
0279daf7bd 'getApplicationNode' doesn't appear to be required as the modal is already a dialog 2020-06-10 18:17:25 +01:00
orangemug
bfada7cace Added aria-label to things that are otherwise labelled in the UI. 2020-06-10 18:16:43 +01:00
orangemug
6c751fe1c4 Updated maputnik/design to diagnose axe accessibility checker issue with SVGs 2020-06-10 17:18:11 +01:00
orangemug
34299c94ee Fixed some 'axe' accessibility checker issues. 2020-06-10 16:22:13 +01:00
orangemug
5804b3c72a CSS outline fixes for keyboard users. 2020-06-10 13:04:04 +01:00
orangemug
8ae6e9fc61 Fix to ignore click suppression on inputs 2020-06-10 13:02:38 +01:00
orangemug
40579c3e0c Added back in action buttons to input label/fieldset 2020-06-10 10:59:44 +01:00
orangemug
f3906c8dd8 A role="navigation" should not be on <ul/> as it changes how screen readers announce them. 2020-06-10 10:25:56 +01:00
orangemug
f911ed3522 Fix <InputColor/> issues when trying to close picker. 2020-06-10 10:10:40 +01:00
orangemug
2cc179acc1 Fixed more input accessibility issues, also
- Added searchParams based router for easier testing
 - Added more stories to the storybook
2020-06-09 19:11:07 +01:00
Orange Mug
2912db6e32 Merge pull request #704 from pathmapper/update_omt_styles
Update Basic and Toner styles
2020-06-06 12:32:34 +01:00
pathmapper
70eb3e785a Trigger codesandbox 2020-06-06 12:48:34 +02:00
pathmapper
8f944d9973 Empty Commit to trigger codesanbox again 2020-06-06 12:46:53 +02:00
pathmapper
8faf841f3d Update Basic and Toner 2020-06-06 11:29:24 +02:00
pathmapper
d8ba8fcbfb Add again shouldComponentUpdate 2020-06-05 15:11:49 +02:00
orangemug
d6f31ec82e Block* -> Field* 2020-06-03 17:11:47 +01:00
Orange Mug
b19eacf4f9 Merge pull request #699 from orangemug/maintenance/component-refactor
Tidy of components + added storybook.js
2020-06-03 16:18:04 +01:00
Orange Mug
3d158a791a Merge pull request #698 from pathmapper/issue_668
Integrate desktop builds in ci workflow
2020-06-03 14:53:06 +01:00
pathmapper
04b3b42524 Use desktop version instead of SHA 2020-06-03 15:37:17 +02:00
pathmapper
af92aac7ec Remove tests 2020-06-03 13:45:59 +02:00
orangemug
90dfbf37e0 Added 'a11y' and 'source' addons to storybook as well as more stories 2020-06-03 09:52:54 +01:00
pathmapper
e21f412933 Update ci.yml 2020-06-03 10:26:44 +02:00
pathmapper
da297fe82c Checkout a particular SHA
https://github.com/maputnik/editor/pull/698#issuecomment-636748873
2020-06-03 10:12:32 +02:00
orangemug
624ccb5b00 Tidy of components
- Moved all components into a single directory like nextjs
 - Made component names consistent with each other
 - Made component names consistent with their export class names
 - Added storybook for a few components with the aim to extend this further.
2020-06-01 16:09:32 +01:00
pathmapper
9f0e5641ab Integrate desktop builds in ci workflow 2020-05-31 21:54:53 +02:00
Orange Mug
d07b40ccef Merge pull request #696 from orangemug/feature/add-more-functional-tests
Added more webdriver tests
2020-05-31 16:05:28 +01:00
orangemug
e0abd8251d Remove temp file 2020-05-31 15:57:23 +01:00
orangemug
324452e714 Disable undo/redo again. 2020-05-31 15:48:20 +01:00
orangemug
8d3ad6b1a1 Added more functional tests. 2020-05-31 15:33:09 +01:00
Orange Mug
3d4cc34a08 Merge pull request #695 from pathmapper/node_14
Add Node 14 to CI workflow
2020-05-28 11:48:59 +01:00
pathmapper
ff351716b6 Update node-sass 2020-05-28 12:26:28 +02:00
Orange Mug
c963a8cc59 Merge pull request #694 from pathmapper/issue_templates
Point users to https://gis.stackexchange.com/ in issue template
2020-05-28 09:39:53 +01:00
Orange Mug
52ad980aef Merge pull request #693 from pathmapper/update-mb-deps
Update GL JS and Style Spec
2020-05-28 09:38:56 +01:00
pathmapper
fb04cce650 Update wdio deps 2020-05-28 08:56:23 +02:00
pathmapper
4b8acb10b0 Add Node 14 2020-05-28 08:39:57 +02:00
pathmapper
86d67389fc Update bug_report.md 2020-05-28 08:30:11 +02:00
pathmapper
9dad53e444 Point users to https://gis.stackexchange.com/ 2020-05-28 08:23:14 +02:00
pathmapper
d5afeb14c1 Update bug_report.md 2020-05-28 08:04:15 +02:00
pathmapper
85bb1d4d40 Update MB dependencies 2020-05-28 07:29:55 +02:00
Orange Mug
d95e25d185 Merge pull request #692 from orangemug/feature/codesandbox-ci
Added back in codesandbox CI config
2020-05-27 11:12:00 +01:00
Orange Mug
a88f2bc0a3 Merge pull request #691 from orangemug/fix/readme-styling
Fixed README styling
2020-05-27 11:11:46 +01:00
orangemug
5a4254d300 Added back in codesandbox CI config. 2020-05-27 10:45:52 +01:00
orangemug
6bfe2aa364 Reordered header items in README. 2020-05-27 10:37:01 +01:00
orangemug
0acd1fec0a Fixed README styling, updated logo and removed broken badges. 2020-05-27 10:32:03 +01:00
pathmapper
3046fedb55 Merge pull request #690 from pathmapper/other_issue_template
Add other issue template
2020-05-27 11:26:23 +02:00
Orange Mug
1574b49b01 Merge pull request #687 from orangemug/feature/github-actions-ci
Added new CI workflow using GitHub actions
2020-05-27 10:20:21 +01:00
pathmapper
4417a2d8f1 Add other issue template 2020-05-27 11:18:27 +02:00
pathmapper
1f34e927e7 Merge pull request #689 from pathmapper/master
Add issue template for bug report
2020-05-27 10:58:00 +02:00
pathmapper
9af6a537ef Update issue templates
Add custom bug report
2020-05-27 10:48:54 +02:00
Orange Mug
6e07142f13 Merge pull request #546 from nyurik/dockerfile
Optimize docker image
2020-05-25 09:41:15 +01:00
orangemug
d2853f34a4 Removed meta-demo-comment as it won't work from forked repos 2020-05-25 06:58:57 +01:00
orangemug
7faed0d27e Added firefox tests and fixed docker deploy 2020-05-24 12:56:52 +01:00
Orange Mug
22101f93ad Merge pull request #686 from orangemug/fix/issue-322
Added tip to JSON editor about how to unfocus
2020-05-24 12:04:35 +01:00
orangemug
0661899d54 Fixes for code review comments. 2020-05-24 11:46:47 +01:00
Orange Mug
862ac84464 Merge pull request #683 from orangemug/fix/a11y-issue-320
Fix some accessibility issues
2020-05-24 11:44:41 +01:00
Orange Mug
1e4aadbb6d Merge pull request #684 from orangemug/fix/issue-533
Fix for updating available sources cache when updating style
2020-05-24 11:42:15 +01:00
orangemug
ce731e7d6b Added new CI workflow using GitHub actions.
Also

 - Fixed screenshot tests
 - Fixed code coverage
 - Removed appveyor
 - Removed circleci
 - Updated wdio related dependencies
 - Added docker image deploy to the GitHub registry
2020-05-24 11:13:16 +01:00
orangemug
5448cdbe4e Don't remember state when toggling <AddModal/> 2020-05-21 10:07:22 +01:00
orangemug
315a9b82c0 Fixed for initial focus of JSON editor message. 2020-05-21 09:22:42 +01:00
orangemug
9e1c0e4c82 Added aria-hidden to JSON editor message. 2020-05-21 09:20:47 +01:00
orangemug
7db675e0d1 Added ESC note to JSON editor. 2020-05-19 12:21:12 +01:00
orangemug
0aa629164a Fix for updating available sources when updating style. 2020-05-19 10:24:59 +01:00
orangemug
c2ec77e869 Fixed lint errors. 2020-05-18 19:41:09 +01:00
orangemug
b28407a4a0 Accessibility fixes
- Aria landmarks
 - Title attributes to all icon only buttons
 - <Multibutton/> now internally a radio group
 - Replaced 1 'skip navigation link' with UI group links
 - Added map specific shortcuts to the shortcut menu
 - Hidden layer list actions from tab index
2020-05-18 19:37:49 +01:00
Orange Mug
e3e6647e03 Merge pull request #682 from orangemug/fix/issue-681
Fix open modal URL entry to use form submission
2020-05-14 15:32:09 +01:00
orangemug
eb0f833d49 Fixed typo. 2020-05-14 13:33:57 +01:00
orangemug
c5c1dd12b9 Added missing prop validation 2020-05-14 13:27:43 +01:00
orangemug
b7e414a042 Fix URL entry to use form submission and improved errors if protocol isn't present. 2020-05-14 12:13:47 +01:00
Orange Mug
81a6f31803 Merge pull request #680 from pathmapper/mb_styles
Fix token input
2020-05-14 11:49:33 +01:00
pathmapper
65cd050a18 Fix token input 2020-05-05 09:40:43 +02:00
Orange Mug
c426dd7349 Merge pull request #673 from pathmapper/update_mb_dependencies
Update MB deps
2020-05-02 09:33:10 +01:00
Orange Mug
c5af645546 Merge pull request #675 from nspringer-trimble/feature/inspect-source-name
Add source name to inspect popup
2020-05-02 09:32:07 +01:00
pathmapper
1bf0abfb5a Update MB deps 2020-04-30 09:18:13 +02:00
Nick Springer
18338de21a Add source name to inspect popup 2020-04-27 15:30:07 -04:00
Orange Mug
857117eb71 Merge pull request #666 from orangemug/fix/issue-646
Fix to make layer list header visible at all times
2020-04-26 10:15:33 +01:00
Orange Mug
8d86bca8b3 Merge pull request #671 from pathmapper/update_readme
Remove v1.7.0-beta from readme
2020-04-26 10:02:51 +01:00
orangemug
dc4e6a0925 Fix vertical align of view/select in toolbar 2020-04-26 09:58:21 +01:00
pathmapper
e9d6119ac6 Remove v1.7.0-beta from readme 2020-04-26 10:58:01 +02:00
orangemug
cbdf45c852 Fixed <select/> styling in firefox and improved in chrome. 2020-04-26 09:23:18 +01:00
Orange Mug
a191c36f96 Merge pull request #667 from orangemug/fix/issue-656
Support multiple tiles URLs for source
2020-04-25 13:52:30 +01:00
orangemug
0a8d0974ca Fixed field spec for image/video. 2020-04-25 13:31:15 +01:00
orangemug
8e6c54564b Add <DynamicArrayInput/> to source tile urls to support multiple values. 2020-04-25 11:38:13 +01:00
orangemug
4bbe2ce1ea Fix to make layer list header visible at all times.
Also improved scrollbar styling/positioning for toolbar and layers list.
2020-04-25 11:05:34 +01:00
orangemug
1d48ab7ecf 1.7.0 2020-04-23 21:12:38 +01:00
Orange Mug
d85ed36e70 Merge pull request #663 from nspringer-trimble/patch-1
Fix for desktop build
2020-04-22 20:30:00 +01:00
Nick Springer
b554f4427b Fix for desktop build 2020-04-21 09:17:30 -04:00
orangemug
184bfeeaf8 1.7.0-beta4 2020-04-20 13:13:36 +01:00
orangemug
e45f8d960d Added space for beta tag in logo/version header 2020-04-20 13:12:48 +01:00
Orange Mug
1fede3af3a Merge pull request #661 from orangemug/fix/issue-660-v2
Added JSON linting back into <SourceTypeEditor/>
2020-04-20 13:09:29 +01:00
orangemug
5ad74048bd Added JSON linting back into <SourceTypeEditor/> 2020-04-20 11:07:08 +01:00
orangemug
a0a91474de 1.7.0-beta3 2020-04-19 08:45:18 +01:00
Orange Mug
c3670701e5 Merge pull request #606 from orangemug/fix/issue-591
Added style formatting into the api store
2020-04-19 08:38:37 +01:00
Orange Mug
86923330d9 Merge pull request #658 from pathmapper/feature_id_inspect
Add feature id to FeaturePropertyPopup
2020-04-19 08:00:00 +01:00
pathmapper
4517148e5a Add underscore to label 2020-04-18 11:43:52 +02:00
pathmapper
0433d66f45 Add feature id to FeaturePropertyPopup 2020-04-18 11:25:54 +02:00
Orange Mug
0c592bacab Merge pull request #650 from orangemug/fix/issue-647
Fixed crash raised in issue #647
2020-04-14 21:15:59 +01:00
Orange Mug
d98637cb12 Merge pull request #645 from orangemug/feature/add-support-for-identity-functions
Add support for identity functions
2020-04-14 09:12:35 +01:00
orangemug
1070209cb5 Another attempt and maputnik inspect crashing issue. 2020-04-14 09:11:09 +01:00
orangemug
b6189f77c4 Added icons to buttons. 2020-04-14 08:31:55 +01:00
Orange Mug
25322a3952 Merge pull request #655 from orangemug/fix/issue-653
Added missing inline error for 'source' field
2020-04-13 10:57:01 +01:00
Orange Mug
5943c6f282 Merge pull request #654 from orangemug/fix/issue-649
Fixed default values for <FontInput/>
2020-04-13 10:56:47 +01:00
orangemug
090a26bb40 Added missing inline error for 'source' field. 2020-04-13 09:10:30 +01:00
orangemug
af03b010a4 Fixed default values for <FontInput/> 2020-04-13 08:53:33 +01:00
orangemug
578a920b6d Fixed crash raised in issue #647 2020-04-13 08:39:23 +01:00
pathmapper
0858a16ffc Merge pull request #644 from orangemug/fix/remove-heavy-thunderforest-tiles
Remove notes from thunderforest sources
2020-04-12 21:04:35 +02:00
orangemug
7cfe0563bc Added support for identity functions. 2020-04-12 16:25:32 +01:00
orangemug
ee72389534 Remove mentions of 'heavy' from thunderforest tiles. 2020-04-12 12:14:56 +01:00
pathmapper
8f722c59de Merge pull request #642 from pathmapper/upgrade_thunderforest
Upgrade Thunderforest tilesets from v1 to v2
2020-04-11 15:48:03 +02:00
pathmapper
94d2e958eb Add version to titles 2020-04-10 18:23:31 +02:00
pathmapper
d931c7cb38 Upgrade Thunderforest tilesets 2020-04-10 18:13:23 +02:00
orangemug
6da83c4670 1.7.0-beta2 2020-04-06 16:57:02 +01:00
Orange Mug
d26af16003 Merge pull request #639 from orangemug/fix/only-scroll-layer-list-if-item-not-in-view
Only scroll to selected item in <LayerList/> if not already in view.
2020-04-06 16:55:26 +01:00
Orange Mug
d75b86c927 Merge pull request #638 from orangemug/maintenance/update-deps-20200406
Update all deps
2020-04-06 16:54:06 +01:00
orangemug
a0cd087ccc Revert webdriverio version updates. 2020-04-06 15:47:12 +01:00
orangemug
313b639a5f Only scroll to selected item in <LayerList/> if not already in view. 2020-04-06 15:30:16 +01:00
orangemug
93c45d5340 Update all deps. 2020-04-06 15:14:21 +01:00
Orange Mug
3be6cb5926 Merge pull request #637 from orangemug/fix/console-errors-2020-04-06
Fix a bunch of errors/warnings from the console
2020-04-06 15:06:39 +01:00
Orange Mug
9d151fdc1f Merge pull request #636 from pathmapper/promote_beta
Promote v1.7.0-beta in readme
2020-04-06 14:32:29 +01:00
orangemug
44d1a7a6b0 {arrayMove} will no longer be included in 'react-sortable-hoc', move to array-move. 2020-04-06 14:18:41 +01:00
pathmapper
0e5676eae0 Promote v1.7.0-beta in readme 2020-04-06 15:14:42 +02:00
orangemug
b8739915b2 Lots of smaller fixes found in the console logs during testing. 2020-04-06 13:59:08 +01:00
Orange Mug
a1dedd1aa6 Merge pull request #634 from orangemug/fix/issue-630
Scroll selected <LayerListItem/> into view
2020-04-06 13:11:53 +01:00
Orange Mug
33b4a40c35 Merge pull request #635 from orangemug/fix/issue-633
Fixes for <NumberInput/>
2020-04-06 13:10:48 +01:00
orangemug
a624909819 Reset dirtyValue on resetValue 2020-04-06 10:40:30 +01:00
orangemug
d5d387f349 Removed placeholder on range (doesn't work) in favour 'default' value merged into 'value'. 2020-04-06 10:24:31 +01:00
orangemug
c58ae0f895 Fix <NumberInput/> to allow for decimal numbers. 2020-04-06 09:55:07 +01:00
orangemug
c9e360d675 Fix layer selection via <FeatureLayerPopup/> 2020-04-06 08:47:13 +01:00
orangemug
75ece350bd Merge remote-tracking branch 'upstream/master' into fix/issue-630 2020-04-04 15:48:52 +01:00
Orange Mug
45680151ef Merge pull request #632 from orangemug/fix/color-popup-swatch
Fix color in <FeatureLayerPopup/>
2020-04-04 15:48:35 +01:00
orangemug
87bae82b17 Merge remote-tracking branch 'upstream/master' into fix/issue-630 2020-04-04 15:44:29 +01:00
orangemug
fcad636f85 Scroll selected <LayerListItem/> into view 2020-04-04 15:41:35 +01:00
orangemug
bac8495b3c Made <FeatureLayerPopup/> swatch simplier because colors from features are already evaluated 2020-04-04 10:45:11 +01:00
orangemug
df98cb9c7b Fix layer color swatch in <FeatureLayerPopup/> 2020-04-04 10:21:58 +01:00
Orange Mug
34c3015b42 Merge pull request #625 from orangemug/fix/invalid-style-with-duplicate-layer-ids
Fix UI when loading invalid style with duplicate layer ids
2020-03-30 20:38:25 +01:00
orangemug
7d51ea9b25 1.7.0-beta 2020-03-30 17:44:26 +01:00
orangemug
ca7bf9f4a7 Fixed lint errors. 2020-03-30 09:57:14 +01:00
orangemug
61ba399e1c Duplicate layer ids now show errors inline. 2020-03-30 09:47:46 +01:00
orangemug
b5c09a4f17 Merge remote-tracking branch 'upstream/master' into fix/invalid-style-with-duplicate-layer-ids 2020-03-30 08:52:37 +01:00
Orange Mug
fcfc7ab874 Merge pull request #626 from orangemug/fix/issue-321-accessible-layer-groups
Moved to using react-accessible-accordion for <LayerEditorGroup/>
2020-03-29 16:12:33 +01:00
pathmapper
a0bc4744a2 Merge pull request #627 from orangemug/fix/make-scrollbar-wider
Wider scrollbar
2020-03-29 13:55:55 +02:00
orangemug
e6e4c928f3 Make the scrollbar wider so it's easier to grab with the mouse pointer. 2020-03-29 07:40:43 +01:00
orangemug
00388e03b8 Moved to using react-accessible-accordion for <LayerEditorGroup/> 2020-03-28 12:53:46 +00:00
orangemug
6f83839a4c Added missing file. 2020-03-28 11:06:45 +00:00
orangemug
74b47e7e74 Fix UI when loading invalid style with duplicate layer ids.
Also fix for throwing error when 2 layers exist with empty strings as ids.
2020-03-28 10:58:47 +00:00
Orange Mug
f70d078ec6 Merge pull request #624 from orangemug/maintenance/update-deps-20200328
Update dependencies
2020-03-28 09:49:59 +00:00
orangemug
1d8131fb85 Update dependencies. 2020-03-28 08:33:57 +00:00
Orange Mug
8c82db9162 Merge pull request #620 from orangemug/feature/ui-errors-and-expressions
Added support for expressions and UI errors
2020-03-27 17:51:02 +00:00
orangemug
f23f60807a Tidy 2020-03-16 10:17:04 +00:00
orangemug
8f581956e8 Revert jsonlint 2020-03-08 19:00:36 +00:00
orangemug
87fb0f6a5c Updated lockfile. 2020-03-08 18:44:04 +00:00
orangemug
1c953bc296 Remove old hack 'src/vendor/codemirror/addon/lint/json-lint' 2020-03-08 18:43:46 +00:00
orangemug
ce976991d4 Added inline errors to the code-mirror editors based on field spec. 2020-03-08 18:38:32 +00:00
orangemug
be7642976b Can't use object as react-dom key. 2020-02-25 09:27:29 +00:00
orangemug
a5b226d9f3 Fixed lint error. 2020-02-25 09:25:52 +00:00
orangemug
1b3d8b5b79 Added JSON error to expression editor 2020-02-25 09:20:14 +00:00
orangemug
97a61afc24 Merge remote-tracking branch 'upstream/master' into feature/ui-errors-and-expressions 2020-02-23 13:34:05 +00:00
Orange Mug
d1f6bc95db Merge pull request #621 from orangemug/fix/CheckboxInput-props-error
Added default to <CheckboxInput/> value to fix warning in console.
2020-02-23 13:24:16 +00:00
orangemug
10b03c4e00 Also fixed invalid DOM nesting warning. 2020-02-22 18:47:46 +00:00
Orange Mug
449d8e7665 Merge pull request #617 from orangemug/fix/map-controls-and-improve-zoom-styling
Improved map control zoom styling
2020-02-22 18:41:05 +00:00
orangemug
4b8800e8ac Added default to <CheckboxInput/> value to fix warning in console. 2020-02-22 18:39:24 +00:00
orangemug
874c6460f6 Merge remote-tracking branch 'upstream/master' into fix/map-controls-and-improve-zoom-styling 2020-02-22 17:59:24 +00:00
orangemug
55cb86f721 Disabled survey modal on first visit to website. 2020-02-22 17:52:20 +00:00
orangemug
a30017fd2c Inline survey modal image 2020-02-22 17:50:14 +00:00
orangemug
3b5ba6c59e Fixed lint errors. 2020-02-22 13:15:55 +00:00
orangemug
a693f6db4e Added infobox for old style filters to allow you to switch to the filter editor. 2020-02-22 11:54:59 +00:00
Orange Mug
5be7e0c7ec Merge pull request #619 from orangemug/maintenance/update-deps-20200217-v2
Update all the deps
2020-02-22 08:57:07 +00:00
orangemug
7c6b3c0d80 Bumped deps. 2020-02-21 09:07:25 +00:00
orangemug
e5e03be382 Fixed missing command update to appveyor.yml 2020-02-21 08:46:46 +00:00
orangemug
0d35106cc8 Tidy test scripts. 2020-02-21 08:06:01 +00:00
orangemug
5710edcff7 Fixed invalid lockfile. 2020-02-18 21:42:25 +00:00
orangemug
2cc7c63bb1 Updated to new webdriverio config api, and fixed failing tests. 2020-02-18 21:39:11 +00:00
orangemug
ba9d21c045 Merge remote-tracking branch 'upstream/master' into maintenance/update-deps-20200217-v2 2020-02-18 19:10:20 +00:00
orangemug
4ef6ecb7eb Moved from magnify icon to 'zoom:' label. Also increased contrast on compass arrow. 2020-02-18 18:50:30 +00:00
orangemug
52e8b21b3d Tidy function. 2020-02-18 08:06:36 +00:00
Orange Mug
c6ba4f66e2 Merge pull request #618 from orangemug/feature/improve-loader
Added improved loader with maputnik logo
2020-02-18 07:50:56 +00:00
orangemug
5a47a96f09 Update all the deps 2020-02-17 19:38:59 +00:00
orangemug
ae878f6000 Added missing plugin from production. 2020-02-17 19:03:19 +00:00
orangemug
aebfe62a8e Fixed image path. 2020-02-17 18:55:28 +00:00
orangemug
6be3543616 Added improved loader. 2020-02-17 18:52:16 +00:00
orangemug
0f6708d9d4 Improved zoom styling and fixed zoom in/out button styling. 2020-02-17 15:39:54 +00:00
orangemug
0705522a24 Fixed width issue with expression error UI. 2020-02-17 13:44:05 +00:00
orangemug
35098111ac Include missing errors from expressions UI. 2020-02-17 13:41:11 +00:00
orangemug
39333953d7 Only show 'switch to layer' button if layer not already selected. 2020-02-17 13:24:14 +00:00
orangemug
adea3d0f13 Added ability to switch to layer from global error panel. 2020-02-17 13:19:26 +00:00
orangemug
d1cb2690fc Fixed lint errors. 2020-02-17 11:55:16 +00:00
orangemug
3ffdcc9639 Added the ability to convert from data/zoom function to expression 2020-02-17 11:52:40 +00:00
orangemug
793b5d15ad Fixed lint errors 2020-02-17 11:30:48 +00:00
orangemug
cff32696cc Better handling of undo history for expressions. 2020-02-17 11:29:05 +00:00
orangemug
029eff9317 Added margin-left to function errors to line up with values. 2020-02-16 22:02:05 +00:00
orangemug
b7d08dfaa6 Fixed data function display issues. 2020-02-16 21:56:03 +00:00
orangemug
94089836bf Fixed lint errors. 2020-02-16 21:30:27 +00:00
orangemug
ff8a8fb749 Added errors to filter functions 2020-02-16 21:25:41 +00:00
orangemug
1300951a29 Removed height from '.maputnik-layout-bottom' to allow it to expand. 2020-02-16 20:31:51 +00:00
orangemug
3cb1ed9403 Made function to check if expression/function more robust. 2020-02-16 20:25:43 +00:00
orangemug
a5ac1cc93d Guard against errors producing dirty map state. 2020-02-16 18:22:21 +00:00
orangemug
29a0ef0d1c Change to always attempt rendering of map state, even if broken, allowing the user to fix style issues step-by-step. 2020-02-16 18:11:47 +00:00
orangemug
26907f7014 Fix button style in disabled state as reported by @pathmapper 2020-02-16 17:34:23 +00:00
orangemug
3ac06c7cb1 Merge remote-tracking branch 'upstream/master' into feature/ui-errors-and-expressions 2020-02-10 15:57:25 +00:00
Orange Mug
f268f09ca2 Merge pull request #616 from orangemug/fix/error-bar-width
Fixed overflowing error bar
2020-02-10 15:50:53 +00:00
orangemug
f4c18fd91b Fixed error bar from overflowing. 2020-02-09 17:23:50 +00:00
orangemug
0567b098ec Fixed undo button disabled state for expressions. 2020-02-09 16:48:52 +00:00
orangemug
dc6006fd6d Fixed lint errors. 2020-02-09 16:36:17 +00:00
orangemug
109261ba00 Fixed filter defaults and removed auto-migrate. 2020-02-09 16:33:47 +00:00
orangemug
b539644b2b Added expression support for filters. 2020-02-09 15:08:24 +00:00
orangemug
be36eec93d Added 'undo' alongside 'trash' button 2020-02-08 10:38:31 +00:00
pathmapper
fe5066a2a4 Merge pull request #614 from orangemug/fix/map-container-background-color
Make background map container white to match html page default
2020-02-02 17:59:35 +01:00
Orange Mug
642e5c0b29 Merge pull request #613 from orangemug/fix/brackets-color-clash-with-cursor
Changed bracket matching color
2020-02-02 15:26:39 +00:00
orangemug
97bdc93a39 Fixed lint error. 2020-02-02 11:56:51 +00:00
orangemug
c770b440c2 Make background map container white to match html page default. 2020-02-02 11:47:37 +00:00
orangemug
7559985a2e Changed bracket matching color so it doesn't clash with cursor. 2020-02-02 11:32:58 +00:00
orangemug
532bbecb47 Only disable <LayerTypeBlock/> in <LayerEditor/> 2020-02-02 08:05:01 +00:00
orangemug
8ed67e98ce Fixed lint errors 2020-02-02 07:44:20 +00:00
orangemug
5792c632f9 hopefulMapStyle -> dirtyMapStyle 2020-02-01 17:55:26 +00:00
orangemug
3e2927e6a4 Fixed undo/redo 2020-02-01 17:53:01 +00:00
orangemug
f09cc25a3b Merge remote-tracking branch 'upstream/master' into feature/ui-errors-and-expressions 2020-02-01 17:36:59 +00:00
orangemug
c5c3e93aff Better support for expressions
- Expression editing state
 - CodeMirror JSON editor
 - Improved styling
2020-02-01 17:07:52 +00:00
Orange Mug
cc371d6a70 Merge pull request #612 from orangemug/fix/color-field-name-is-not-required
'name' is not a required property of <ColorField />
2020-01-30 09:47:06 +00:00
Orange Mug
1b17e8fa0a Merge pull request #610 from orangemug/fix/issue-609
Fix for stuck/unchanging pop-up in Inspect view
2020-01-30 09:22:43 +00:00
Orange Mug
bc4706de83 Merge pull request #607 from orangemug/fix/issue-567-better-solution-for-tooltips
Inline property documentation and SDK docs
2020-01-30 09:21:10 +00:00
orangemug
0f22eb83d3 'name' is not a required property of <ColorField /> 2020-01-30 09:18:23 +00:00
orangemug
a8cbe19f09 Added style_renderer to field-spec-additional 2020-01-30 08:54:08 +00:00
orangemug
c714e23d79 'id' is not guaranteed to be unique, see <https://github.com/maputnik/editor/pull/610/files#r372521304> 2020-01-30 08:46:26 +00:00
orangemug
5b3d579f87 Fix to fallback to index for unique feature key in <FeaturePropertyPopup /> 2020-01-29 08:44:27 +00:00
orangemug
725b752e35 Added initial expression work and UI errors. 2020-01-29 08:22:03 +00:00
orangemug
223721a65d Code review fixes
- Added docs to export modal
 - Fixed 'source type' doc in data sources modal
2020-01-27 08:49:44 +00:00
orangemug
9b4d924dff Fix to ignore modified styleSpec. 2020-01-24 17:46:43 +00:00
orangemug
b31537e063 Added property values to docs 2020-01-24 09:04:32 +00:00
Orange Mug
63ed8c1de3 Merge pull request #605 from orangemug/maintenance/update-deps-2020-01-19
Updated deps
2020-01-23 08:50:01 +00:00
Orange Mug
7aa0298f7c Merge pull request #603 from orangemug/feature/add-image-and-video-sources
Added ability to add image/video sources
2020-01-23 08:49:37 +00:00
orangemug
62f3cbe8fb Lint fixes. 2020-01-23 08:42:20 +00:00
orangemug
30facc885f Tidy inline docs and added sdk support table. 2020-01-23 08:33:12 +00:00
orangemug
17aa88e3b6 Merge remote-tracking branch 'upstream/master' into fix/issue-567-better-solution-for-tooltips 2020-01-22 08:57:45 +00:00
Orange Mug
5b9af07ebc Merge pull request #604 from orangemug/feature/issue-82
Link to OSM from debug panel
2020-01-19 20:11:30 +00:00
orangemug
6b45dc8b4d Added style formatting into apistore 2020-01-19 20:05:11 +00:00
orangemug
0009c74948 Fixes lat/lon precision and center change via zoom without pan. 2020-01-19 19:09:04 +00:00
Orange Mug
8911f83ef3 Merge pull request #522 from orangemug/feature/add-range-slider
Add range input for minZoom/maxZoom
2020-01-19 18:54:07 +00:00
orangemug
2fafafe0dc Updated deps 2020-01-19 16:39:41 +00:00
orangemug
27e6675d26 Fix replacing of access tokens in MapboxGl. 2020-01-19 16:30:27 +00:00
orangemug
4269e4573c Fixed lint errors. 2020-01-19 16:00:29 +00:00
orangemug
096e2b6aec Fixed image/video coord labels. 2020-01-19 15:48:11 +00:00
orangemug
33e04b3527 Added ability to add/edit image and video sources 2020-01-19 14:40:35 +00:00
orangemug
79fa2b3508 Feature to update current map view in OSM 2020-01-19 13:37:56 +00:00
orangemug
d5ef412300 Safari fixes. 2020-01-19 11:53:27 +00:00
orangemug
0726a494be Only set dirtyValue on valid change. 2020-01-19 11:41:37 +00:00
orangemug
926969b921 Always change via step from keyboard. 2020-01-19 11:28:03 +00:00
orangemug
59e070f463 Merge remote-tracking branch 'upstream/master' into feature/add-range-slider 2020-01-19 11:06:39 +00:00
orangemug
2ccd1d227e rangeValue -> dirtyValue 2020-01-19 11:06:24 +00:00
orangemug
655877f67e Fixed another bug with change events for <NumberInput/> and added range input keyboard support. Remove logging as react props/state is enough for debugging. 2020-01-19 10:30:08 +00:00
Orange Mug
6c240d53e4 Merge pull request #601 from orangemug/fix/issue-588
Added new fieldSpec.type 'resolvedImage'
2020-01-19 09:59:41 +00:00
Orange Mug
f89f8ed4ea Merge pull request #587 from pathmapper/matchingbrackets_addon
Add matchbrackets addon to JSON editor
2020-01-19 09:48:08 +00:00
Orange Mug
6123b464de Merge pull request #600 from orangemug/fix/issue-589
Fix feature selection in <FeatureLayerPopup />
2020-01-19 09:46:57 +00:00
Orange Mug
49dba02e8f Merge branch 'master' into matchingbrackets_addon 2020-01-19 08:29:25 +00:00
pathmapper
fb49a3abe5 Merge pull request #602 from orangemug/fix/issue-565
Update react-collapse
2020-01-19 08:54:28 +01:00
orangemug
c88f9ab5dc Believed fix for race condition in setting dirtyValue 2020-01-19 07:37:49 +00:00
orangemug
d886b14d09 Fix to set "editing: false" in blur/pointerup 2020-01-19 07:15:50 +00:00
orangemug
bd1204a7a5 Added react-collapse transition, required for react-collapse@^5 2020-01-18 22:11:02 +00:00
orangemug
9cadda0236 Update react-collapse which was needlessly updating and causing scroll position jump. 2020-01-18 22:03:29 +00:00
orangemug
90ea6323c1 Added new fieldSpec.type 'resolvedImage' 2020-01-18 20:57:59 +00:00
orangemug
51f2cfac16 Fix feature selection in <FeatureLayerPopup /> 2020-01-18 20:42:38 +00:00
Orange Mug
4dbb423ac2 Merge pull request #599 from pathmapper/update_omt_styles
Update OMT styles for v3.11
2020-01-15 10:06:58 +00:00
Orange Mug
a3ee1cc27e Merge pull request #595 from pathmapper/maxzoom
Increase maximum zoom level of the map to 24
2020-01-15 10:06:20 +00:00
pathmapper
fea0798349 Update OMT styles for v3.11 2020-01-14 10:28:32 +01:00
pathmapper
bd8abffa28 Merge pull request #597 from pathmapper/appveyor_vs_2019
Update appveyor to "Visual Studio 2019"
2020-01-13 09:39:48 +01:00
pathmapper
a5f3a43cde Merge pull request #596 from pathmapper/remove_node_v8
Remove node v8 from test runners
2020-01-13 09:39:28 +01:00
pathmapper
6c5dc7e06b Update appveyor to "Visual Studio 2019" 2020-01-11 10:26:07 +01:00
pathmapper
b1c8a12e88 Remove node v8 from appveyor 2020-01-11 09:39:09 +01:00
pathmapper
401c6971f4 Remove node v8 from circleci 2020-01-11 09:38:20 +01:00
pathmapper
7e5a5ce077 Set map maxZoom to 24 2020-01-10 14:06:17 +01:00
pathmapper
6b245c9894 Improve matchingbrackets and cursor visibility 2019-10-30 12:24:25 +01:00
pathmapper
b963fe9619 Add matchbrackets addon 2019-10-29 10:52:06 +01:00
Orange Mug
673887d93b Merge pull request #582 from orangemug/fix/add-source-errors
Add open modal and source http/https errors
2019-10-28 18:19:21 +00:00
Orange Mug
06898429fd Merge pull request #584 from orangemug/fix/issue-576
A hack fix for blocked popup
2019-10-28 18:18:33 +00:00
pathmapper
0196ba4eb4 Merge pull request #585 from orangemug/fix/issue-403
Update map style even if inspectModeEnabled=true
2019-10-28 06:38:49 +01:00
orangemug
ef81534a17 Update map style even if inspectModeEnabled=true 2019-10-27 20:04:57 +00:00
orangemug
a958ec943b Lint fix. 2019-10-27 19:16:13 +00:00
orangemug
4e3b395b3d A hack fix for blocked popup. 2019-10-27 19:11:34 +00:00
Orange Mug
5e7fd4f93c Update src/components/inputs/UrlInput.jsx
CORs -> CORS

Co-Authored-By: pathmapper <pathmapper@posteo.de>
2019-10-27 19:07:49 +00:00
orangemug
25cad5bb25 Added to GeoJSON url. 2019-10-27 18:58:22 +00:00
orangemug
f9c230414e Fix width of modal. 2019-10-27 18:54:40 +00:00
orangemug
866f8d034a Switched to <UrlInput/> for glyphs and sprites 2019-10-27 18:45:49 +00:00
pathmapper
be6aa559fb Merge pull request #583 from orangemug/feature/make-osm-liberty-the-default
Make osm-liberty the default style
2019-10-27 19:38:11 +01:00
orangemug
a560176d83 Add even more logging. 2019-10-27 18:15:54 +00:00
Orange Mug
4644e78fd2 Merge pull request #579 from orangemug/fix/function-field-fixes
Function field fixes
2019-10-27 17:58:06 +00:00
orangemug
237cc16b97 Make osm-liberty the default style. 2019-10-27 17:46:34 +00:00
orangemug
dffa54afb0 Removed more old styleUrlElement refs 2019-10-27 17:42:45 +00:00
orangemug
225e5c48e4 Fixed lint error. 2019-10-27 17:38:57 +00:00
orangemug
2e017d252a Added <UrlInput/> to open modal. 2019-10-27 17:36:20 +00:00
orangemug
e728e5f7e4 Exposed onInput in <UrlInput/> 2019-10-27 17:35:56 +00:00
orangemug
f0371b41b1 Also validate on constructor 2019-10-27 17:27:50 +00:00
orangemug
a51442921a Fix font-size inline with the rest of the UI. 2019-10-27 17:19:03 +00:00
orangemug
f39fb34f36 Protocol logic and lint fixes. 2019-10-27 17:15:17 +00:00
orangemug
566201fb45 Added UrlInput component to tidy things up a little. 2019-10-27 17:08:23 +00:00
orangemug
88841b56e7 Added another fix attempt and yet more logging. 2019-10-27 15:56:22 +00:00
orangemug
5aa0b4e7d9 More logging additional attempt at fixes. 2019-10-27 11:01:33 +00:00
Orange Mug
f19fc4a8a1 Merge pull request #581 from orangemug/fix/issue-535-data-field-ordering
Fix zoom ordering for data property fields
2019-10-27 10:18:34 +00:00
orangemug
cd162309a8 Added hopeful fix + logging. 2019-10-27 10:15:11 +00:00
orangemug
aead867e27 Incorrectly checking for falsey when should be checking for presence. 2019-10-27 10:05:05 +00:00
orangemug
663f295623 Added default protocol and stub in error. 2019-10-27 10:00:22 +00:00
orangemug
c588164190 console.log map errors. 2019-10-26 18:27:11 +01:00
orangemug
d61d0a5795 Fix test for range slider. 2019-10-26 18:09:07 +01:00
orangemug
dddd604f7b Removed left over conflict markers and set default. 2019-10-26 17:41:56 +01:00
orangemug
ea3b9a20c5 Merge remote-tracking branch 'upstream/master' into feature/add-range-slider 2019-10-26 17:22:52 +01:00
Orange Mug
7415b8af08 Merge pull request #580 from pathmapper/update_mb_deps
Update mbgl and style-spec
2019-10-26 17:19:04 +01:00
orangemug
d06e053d34 Fix zoom ordering for data property fields. 2019-10-26 17:15:25 +01:00
pathmapper
7075a8b05e Update mbgl and style-spec 2019-10-26 07:10:30 +02:00
orangemug
4cbcf14588 Make up defaults from function field if we can't find one from the spec. 2019-10-25 22:54:08 +01:00
orangemug
ca202d7701 Use <EnumInput/> for enums again 2019-10-25 22:48:37 +01:00
Orange Mug
8dfc16e7ee Merge pull request #577 from fredj/del_btn_style
Simplify and fix vertical alignment of the delete button
2019-10-25 22:15:23 +01:00
Frederic Junod
fbf5cec670 Simplify and fix vertical alignment
Use the same css as the `maputnik-make-data-function` and `maputnik-make-zoom-function` buttons.
2019-10-25 13:16:09 +02:00
Orange Mug
14d4383f8a Merge pull request #575 from snodnipper/feature/zoomstack-v2
set OS Zoomstack endpoints to v2
2019-10-24 17:58:54 +01:00
Oliver Snowden
58bdd39f9e set OS Zoomstack endpoints to v2 2019-10-25 00:24:55 +08:00
Orange Mug
ab9ab7acc7 Merge pull request #574 from fredj/GitHub_sponsor
Activate sponsor button in GitHub
2019-10-24 16:02:16 +01:00
Frederic Junod
be39fd2ec8 Activate sponsor button in GitHub
See: https://help.github.com/en/github/building-a-strong-community/displaying-a-sponsor-button-in-your-repository
2019-10-24 16:51:45 +02:00
pathmapper
3c0185da27 Merge pull request #573 from pathmapper/node_13
Add node v13 to test runners
2019-10-24 05:59:12 +02:00
pathmapper
b37b7276fb Add node v13 to test runners 2019-10-23 11:10:05 +02:00
Orange Mug
c45cf2f0c8 Merge pull request #563 from orangemug/feature/more-root-property-support
Added support for more root level properties
2019-10-21 10:18:37 +01:00
Orange Mug
1f03fdbb50 Merge pull request #571 from orangemug/fix/map-perf-improvement
Remove shouldComponentUpdate from <MapboxGlMap/>
2019-10-20 12:50:33 +01:00
orangemug
f3b8c5362a Remove shouldComponentUpdate because mapbox-gl will do the diff for us, so updates will no longer diff twice. 2019-10-20 12:25:43 +01:00
Orange Mug
c9a5dd01be Merge pull request #570 from orangemug/feature/issue-559-add-raw-geojson-as-source
Add support for raw GeoJSON as source
2019-10-20 12:23:37 +01:00
orangemug
0fa4d40e92 Remove duplicate import rule. 2019-10-20 11:21:38 +01:00
orangemug
8a6e64c8c2 Merge remote-tracking branch 'upstream/master' into feature/issue-559-add-raw-geojson-as-source 2019-10-20 11:19:34 +01:00
orangemug
72b6dd1ae9 Fix lint errors. 2019-10-20 11:12:54 +01:00
orangemug
ee525631fa Fixes for codemirror in sources modal
- Allows for max height
 - Override GeoJSON data when changing type
2019-10-20 11:09:20 +01:00
pathmapper
ee9e055af3 Merge pull request #562 from orangemug/feature/json-editor-perf-improvements
react-codemirror2 -> codemirror directly
2019-10-19 21:56:59 +02:00
pathmapper
b214c6ac7e Merge pull request #566 from orangemug/feature/add-profiling-build
Added profiling build to CI
2019-10-19 21:55:20 +02:00
orangemug
eb75020861 Merge branch 'feature/json-editor-perf-improvements' into fix/issue-567-better-solution-for-tooltips 2019-10-19 16:56:45 +01:00
orangemug
a44e757e31 Initial work for new help text implementation. 2019-10-19 14:43:27 +01:00
orangemug
9ac908948d Changed label/content styling for input blocks. 2019-10-19 13:12:09 +01:00
orangemug
19e82e5890 Added support for raw GeoJSON 2019-10-19 13:11:29 +01:00
orangemug
bf84fd24ee Moved profiling to wdio-steps 2019-10-19 12:33:54 +01:00
orangemug
affeb7c751 Fixed lint errors. 2019-10-19 12:21:38 +01:00
orangemug
9743361e0d Added back in 'light position' and 'center' with fixes for <ArrayInput/>
This also improves the usage of *-translate which uses the <ArrayInput/>
2019-10-19 12:16:56 +01:00
orangemug
ab16120af2 Added invalid style to inputs 2019-10-19 12:07:08 +01:00
orangemug
37e5ba0fff Remove 'center' and 'light position', as they weren't working properly. 2019-10-16 22:36:41 +01:00
orangemug
0aa0dad7fb Remove undefined root properties. 2019-10-16 22:31:29 +01:00
orangemug
2910efde6e Allow removal of light/transition properties. 2019-10-16 21:58:24 +01:00
orangemug
eac7656786 <NumberInput/> unsetting fix. 2019-10-16 21:57:29 +01:00
Orange Mug
be3175beae Merge pull request #569 from fredj/layer-type-test-issue
Fix the layer type test in LayerEditor component
2019-10-16 19:21:03 +01:00
Frederic Junod
26de95a263 Fix the layer type test in LayerEditor component
`LayerSourceLayerBlock` was always included
2019-10-16 15:36:25 +02:00
orangemug
d0a47bd122 Added support for transition root property 2019-10-16 10:15:46 +01:00
orangemug
8c760bb810 Added default support to <EnumInput/> 2019-10-16 10:12:59 +01:00
orangemug
c27deefdef Added profiling build to CI 2019-10-16 09:56:26 +01:00
orangemug
392a845460 Moved "Style Renderer" options to bottom of list. 2019-10-16 08:24:25 +01:00
orangemug
e7622c2080 Added root level light property support. 2019-10-16 08:17:25 +01:00
orangemug
3a558412ba Merge remote-tracking branch 'upstream/master' into feature/added-light-property-support 2019-10-16 08:16:28 +01:00
Orange Mug
95e205943a Merge pull request #564 from orangemug/fix/typo-in-export
Fixed typo in export
2019-10-16 08:14:21 +01:00
orangemug
eb8686325c Fixed typo in export. 2019-10-16 08:13:37 +01:00
orangemug
1f77e156e6 Added support for root level properties
- center
 - zoom
 - bearing
 - pitch
2019-10-16 07:38:50 +01:00
orangemug
92ee50a4a4 Added default support to <ArrayInput/> 2019-10-16 07:36:30 +01:00
orangemug
ef23f01e67 Removed react-codemirror2 as we no longer use it 2019-10-16 06:49:11 +01:00
orangemug
22b6a4a2bf Added max-width to allow overfow scroll on JSONEditor 2019-10-16 06:46:30 +01:00
Orange Mug
201ecac156 Merge pull request #561 from fredj/ol_attribution_color
Set a color for the OpenLayers attribution control
2019-10-15 17:37:47 +01:00
orangemug
563a78ed42 Moved away from react-codemirror2 to interacting with codemirror directly. 2019-10-15 17:34:36 +01:00
Frederic Junod
47acc2640b Set a color for the OpenLayers attribution control 2019-10-15 14:37:04 +02:00
Orange Mug
f088788246 Merge pull request #557 from orangemug/feature/perf-improvements
LayerList performance improvements
2019-10-15 09:35:56 +01:00
Orange Mug
e219dcd332 Merge pull request #556 from orangemug/feature/add-new-mgljs-features
Added new features from the mapbox-gl spec
2019-10-14 10:04:42 +01:00
orangemug
b8829d9a5c Remove *-sort-key until we support expressions. 2019-10-14 09:22:21 +01:00
pathmapper
2c83c976c6 Merge pull request #558 from pathmapper/liberty_thumbnail
Update thumbnail source for OSM Liberty
2019-10-14 06:59:58 +02:00
orangemug
d63782ddf2 Remove react warnings. 2019-10-13 18:03:58 +01:00
orangemug
3eabcbec72 Fix <NumberInput/> to allow for empty value (reset value) 2019-10-13 18:00:32 +01:00
orangemug
00ab303e44 Stop LayerEditor using same DOM elements for different layers. 2019-10-13 17:59:11 +01:00
pathmapper
38bf12701e Update thumbnail source for OSM Liberty 2019-10-13 17:30:43 +02:00
orangemug
e4ec1d155a Added mapbox-gl features 'text-variable-anchor' and 'text-radial-offset' 2019-10-13 13:32:42 +01:00
orangemug
361f083687 Merge remote-tracking branch 'upstream/master' into feature/add-new-mgljs-features 2019-10-13 12:40:56 +01:00
orangemug
c1a59200e2 1.6.1 2019-10-13 12:02:26 +01:00
orangemug
6e0432ff5e Added back in minifcation. 2019-10-13 11:43:23 +01:00
orangemug
1c83de08c1 Fixed lint errors. 2019-10-12 12:08:25 +01:00
orangemug
0af828543b Disable minify 2019-10-12 12:06:33 +01:00
Orange Mug
369cc23a30 Merge pull request #553 from orangemug/maintenance/update-deps-20191009
Update dependencies
2019-10-12 11:56:38 +01:00
orangemug
db56ad8b2e Remove duplicate formatColor call. 2019-10-12 10:16:46 +01:00
orangemug
7fa17d81ac Some perf improvements when updating the layers list, also throttled color picker. 2019-10-12 10:10:33 +01:00
orangemug
019c6a0086 Merge remote-tracking branch 'origin/maintenance/update-deps-20191009' into maintenance/update-deps-20191009 2019-10-12 09:10:42 +01:00
orangemug
c1bee74b57 Switched back from using yarn to npm for lockfiles. 2019-10-12 09:09:39 +01:00
Orange Mug
b794279304 Bumped mapbox-gl to 1.4.1
Co-Authored-By: pathmapper <pathmapper@posteo.de>
2019-10-12 07:08:30 +01:00
Orange Mug
935dfa1704 Merge pull request #555 from pathmapper/update_omt_styles
Update OMT styles
2019-10-12 07:03:17 +01:00
pathmapper
bda7a0e659 Update OMT styles 2019-10-11 16:13:08 +02:00
orangemug
8d1cc340b8 Added new features text-writing-mode and *-sort-key 2019-10-10 08:52:36 +01:00
orangemug
338c6b59a8 Lock deps in package.json 2019-10-09 22:06:59 +01:00
orangemug
021f8ab400 Update all the dependencies 2019-10-09 19:51:57 +01:00
Orange Mug
f305db9e3e Merge pull request #551 from pathmapper/update_readme
Remove 1.6-beta from readme
2019-10-08 21:25:02 +01:00
pathmapper
e916b25594 Remove 1.6-beta from readme 2019-10-08 21:59:34 +02:00
orangemug
5f1e212759 1.6.0 2019-10-08 18:28:56 +01:00
pathmapper
2b7db498ef Merge pull request #548 from pathmapper/popup_scroll
Make popups scrollable
2019-09-17 10:00:29 +02:00
pathmapper
e6464790f6 Merge pull request #549 from pathmapper/beta_readme
Add 1.6.0-beta to readme
2019-08-22 10:55:31 +02:00
pathmapper
13ddf9f754 Link 1.6 beta from readme 2019-08-22 10:26:53 +02:00
pathmapper
30edb881ed Ensure popup is fully visible 2019-08-21 14:41:14 +02:00
pathmapper
b30bbdc248 Calculate popup height depending on viewport 2019-08-10 10:37:39 +02:00
pathmapper
824616f6bd Make popups scrollable 2019-08-09 15:55:52 +02:00
Yuri Astrakhan
2a832955c4 Updated docs, rm creds 2019-08-03 15:02:16 -04:00
Yuri Astrakhan
608b836fe0 fix readme 2019-08-03 12:37:19 -04:00
Yuri Astrakhan
de9c4fcc4a Optimize docker image
* Use 2 stage docker building to produce a tiny python3-slim based docker image with just the compilation results.
2019-08-03 12:08:54 -04:00
orangemug
109198a524 1.6.0-beta 2019-08-02 18:08:21 +02:00
pathmapper
920e4fe630 Merge pull request #545 from pathmapper/navcontrols
Fix css and increase color contrast for navcontrols
2019-08-01 14:21:51 +02:00
pathmapper
5e143e0a8e Fix css and increase color contrast 2019-08-01 13:59:34 +02:00
pathmapper
57f803d52c Merge pull request #544 from pathmapper/update_styles
Update available styles
2019-07-30 14:19:38 +02:00
pathmapper
c55d342c7e Remove empty line 2019-07-30 13:58:18 +02:00
pathmapper
e9065635cd Add toner and move empty style 2019-07-30 13:51:05 +02:00
pathmapper
6057721249 Merge pull request #543 from pathmapper/update_mb_dependencies
Update mapbox dependencies to current version
2019-07-30 10:51:04 +02:00
pathmapper
975487d271 Use visualizePitch option 2019-07-30 08:10:56 +02:00
pathmapper
46b2fd5978 Update mapbox dependencies to current version 2019-07-30 06:45:21 +02:00
pathmapper
f61313449f Merge pull request #542 from pathmapper/update_maptiler_key
Update Maptiler key
2019-07-29 20:35:07 +02:00
pathmapper
366ad4d7df Update Maptiler key
Provided by @klokan via e-mail
2019-07-29 18:21:42 +02:00
pathmapper
b5cfb44cf0 Merge pull request #512 from JesseCrocker/local-port
Add support for connecting to a local server on port other than 8000
2019-07-29 17:16:36 +02:00
pathmapper
050cc9cea9 Merge pull request #539 from pathmapper/update_mbgl
Update mapbox-gl and style spec to latest release
2019-07-17 09:41:58 +02:00
pathmapper
b2f194eeee Update mapbox-gl to 1.1.1 2019-07-17 09:18:47 +02:00
pathmapper
97b0b8541d Update mapbox-gl and style spec 2019-07-02 11:04:44 +02:00
Orange Mug
b5eb74fe20 Merge pull request #532 from pathmapper/fix_issue_471
Remove UNSAFE_componentWillUpdate
2019-06-28 16:42:08 +01:00
pathmapper
0500172d42 Update layer types 2019-06-23 09:55:32 +02:00
pathmapper
0e7bd98485 Use componentDidUpdate 2019-06-23 09:53:52 +02:00
Orange Mug
ff0ece5149 Merge pull request #531 from orangemug/fix/issue-509
Ability to delete properties completely
2019-06-21 17:42:09 +01:00
orangemug
db9ad86ac2 Filter empty strings in <FontInput/> 2019-06-21 08:05:09 +01:00
orangemug
a066710bfb Always put an empty field and the end of the FontInput and remove blank fields if empty 2019-06-21 07:58:43 +01:00
orangemug
52740483b6 Merge remote-tracking branch 'upstream/master' into fix/issue-509 2019-06-20 20:40:22 +01:00
orangemug
518a624e20 Updated to mapbox-gl 1.1.0-beta.1 2019-06-20 20:37:26 +01:00
pathmapper
4ba71c8bd5 Remove UNSAFE_componentWillUpdate 2019-06-20 09:52:54 +02:00
orangemug
ceeb628784 Added ability to delete color value. 2019-06-19 20:44:27 +01:00
orangemug
2ec6a90dc3 Allow removal of properties. 2019-06-19 20:34:28 +01:00
Orange Mug
4e37d834ed Merge pull request #530 from pathmapper/remove_node11
Remove node v11 from test runners
2019-06-17 09:03:28 +01:00
pathmapper
a7922d894d Remove node v11 from test runners 2019-06-17 09:05:39 +02:00
pathmapper
eeda3296ab Merge pull request #514 from pathmapper/node_v12_test_runners
Add node v12 to test runners
2019-06-17 06:49:30 +02:00
pathmapper
acd26e0162 Update only if wanted version is not available 2019-06-16 22:03:37 +02:00
pathmapper
fbf828e202 Merge branch 'master' into node_v12_test_runners 2019-06-16 21:21:33 +02:00
pathmapper
af9015f529 Merge pull request #526 from pathmapper/update_wdio
Update WebdriverIO to v5
2019-06-16 11:53:09 +02:00
Orange Mug
7a172b2022 Merge pull request #528 from pathmapper/renderer_metadata
Set default renderer if undefined
2019-06-16 10:03:37 +01:00
pathmapper
a609dc4029 Set default renderer if undefined 2019-06-16 05:27:53 +02:00
pathmapper
92bfee4bcc Use number input again for min/max-zoom tests 2019-06-13 07:18:35 +02:00
pathmapper
559d4618d1 Update wdio dependencies 2019-06-13 07:05:02 +02:00
pathmapper
5c391ee287 Update selenium-standalone used for testing and move wdio-steps to node active LTS 2019-06-08 18:34:03 +02:00
pathmapper
db74cfeb2a Update express and is-docker dependencies 2019-06-08 18:10:54 +02:00
pathmapper
726b825e4c Update mocha dependency 2019-06-08 17:55:08 +02:00
pathmapper
84d56b2606 Skip "upload" test for the open modal 2019-06-08 17:16:51 +02:00
pathmapper
e9a8b094a2 Update tests for WebdriverIO v5 2019-06-08 07:19:18 +02:00
pathmapper
924b14621a Update wdio.conf.js 2019-06-08 07:04:41 +02:00
pathmapper
b072e3a98c Update wdio and selenium dependencies 2019-06-08 06:59:47 +02:00
Orange Mug
827bd5fa24 Merge pull request #524 from orangemug/feature/ol-improvements
Further OpenLayers improvements
2019-06-01 17:39:40 +01:00
orangemug
9e0410afe6 Fix to reset map state on renderer change. 2019-06-01 08:28:22 +01:00
orangemug
ef08a9347e Disable debugToolbox by default. 2019-05-29 19:18:24 +01:00
orangemug
9b732540a6 Remove commented out code. 2019-05-29 19:16:17 +01:00
orangemug
24c52074b8 Fixed lint errors. 2019-05-29 18:59:26 +01:00
orangemug
cb6c6e0d9f Remove projection code for now. 2019-05-29 18:54:32 +01:00
orangemug
884dc6fa49 Fixed typos. 2019-05-29 18:28:47 +01:00
orangemug
efe42021f1 Some more openlayers improvments as well as initial work for projection support 2019-05-29 17:37:55 +01:00
pathmapper
470277c253 Merge pull request #523 from orangemug/feature/update-ol-plus-stability-fixes
Update openlayers + stability fixes
2019-05-22 09:47:13 +02:00
orangemug
c1cab38c7a Merge remote-tracking branch 'upstream/master' into feature/update-ol-plus-stability-fixes 2019-05-22 07:51:13 +01:00
orangemug
1cf36ddb08 Updated ol-mapbox-style/ol, added throttle to ol map update and fix to clear layers. 2019-05-22 07:32:06 +01:00
orangemug
1fec89b69e Moved back to data-wd-key approach and fixed tests 2019-05-21 19:07:28 +01:00
orangemug
911549aca3 Moved data-wd-key onto element 2019-05-21 18:54:09 +01:00
orangemug
41329ec2f8 Fixes for firefox, this makes the range input only update on pointerup 2019-05-21 18:42:19 +01:00
orangemug
15cdfbc980 Changed default of step 0.01 -> 1 2019-05-20 11:28:27 +01:00
orangemug
5053058c32 Fixed default values for range slider. 2019-05-20 11:21:23 +01:00
orangemug
8a8cfad303 Merge remote-tracking branch 'upstream/master' into feature/add-range-slider 2019-05-20 10:20:55 +01:00
Orange Mug
cc3c17078d Merge pull request #517 from orangemug/fix/editing-of-number-and-string-inputs
Fix for string/number inputs when inputting invalid of intermediate values
2019-05-20 10:15:25 +01:00
pathmapper
47965d5f57 Merge pull request #518 from orangemug/fix/color-accessibility-ua-switch
Toggle color accessibility based on user agent
2019-05-19 19:58:42 +02:00
Orange Mug
c947d9e3ed Merge pull request #516 from orangemug/fix/prevent-default-browser-undo-redo
Prevent native browser undo/redo when handled by app
2019-05-19 18:52:14 +01:00
Orange Mug
8318180e96 Merge pull request #519 from orangemug/feature/debug-modal
Added semi-hidden debug modal
2019-05-19 18:51:43 +01:00
orangemug
87daf6fb76 Fixes because I was incorrectly assuming mgljs only 2019-05-19 10:09:44 +01:00
pathmapper
5d254ac2ff Merge pull request #520 from orangemug/fix/color-filters-with-ol
Layout issues in accessibility color filters with the openlayers renderer
2019-05-19 10:04:16 +02:00
orangemug
482f322d9f Fixed layout issues in accessibilty color filters with the openlayers renderer
Also updated ol & ol-mapbox-style
2019-05-19 06:25:28 +01:00
orangemug
b1d097a40f Merge remote-tracking branch 'upstream/master' into feature/add-range-slider 2019-05-19 06:04:21 +01:00
Orange Mug
da456b08fe Merge pull request #444 from orangemug/feature/issue-433
Added color swatch to <FeatureLayerPopup/>
2019-05-18 19:15:27 +01:00
orangemug
2776ac3ce0 Added back in onOpenToggle 2019-05-18 19:06:54 +01:00
orangemug
eb2fc4c715 Fixed prop-type name. 2019-05-18 19:02:51 +01:00
orangemug
d2ffc3a0b1 Added semi-hidden debug modal and removed all this url param awkwardness 2019-05-18 18:54:10 +01:00
orangemug
40a9978f31 Removed console.log 2019-05-18 18:23:02 +01:00
orangemug
22688933b3 Toggle color accessibility based on user agent
It's only supported in chrome and firefox and we can't feature detect this.
2019-05-18 18:19:23 +01:00
orangemug
7cf01f0c12 Merge remote-tracking branch 'upstream/master' into feature/issue-433 2019-05-18 17:33:31 +01:00
orangemug
1e87765f95 Tidy and added fallback (exception) color. 2019-05-18 17:29:59 +01:00
orangemug
cc8fe4e02e Fix for buggy string/number inputs when inputting invalid of intermediate values 2019-05-18 15:56:14 +01:00
orangemug
979fc98e70 Prevent native browser undo/redo when handled by app 2019-05-18 15:47:51 +01:00
pathmapper
c3c0c35d8a Merge pull request #513 from pathmapper/update_readme
Update readme
2019-05-05 15:13:47 +02:00
pathmapper
f9913cad63 Use jsDelivr for Maputnik logo and sponsor images
To make them appear on https://hub.docker.com/r/maputnik/editor/.
2019-05-05 09:14:11 +02:00
pathmapper
0ed64f94e8 Fix link devDependencies 2019-05-05 08:58:34 +02:00
pathmapper
1deecd4e2a Update node-sass 2019-05-05 08:48:25 +02:00
pathmapper
e0e9201b46 Add node v12 to appveyor 2019-05-05 07:57:41 +02:00
pathmapper
362c7b437e Add node v12 to circleci 2019-05-05 07:47:50 +02:00
Jesse Crocker
efd0b547e9 Fix this being undefined 2019-04-16 09:19:36 -06:00
Jesse Crocker
afbaaa66bc Add support for using a port other than 8000 2019-04-16 08:23:21 -06:00
pathmapper
de8c687dfb Merge pull request #483 from sk1p/popup-cleanup
Various cleanups regarding popups and inspect mode
2019-04-16 07:29:19 +02:00
pathmapper
1bb079f078 Merge pull request #501 from pathmapper/issue_484
Fix JSON-editor
2019-04-16 07:05:43 +02:00
pathmapper
b35322522f Merge pull request #499 from pathmapper/scrollbar-ff
Firefox scrollbar styling
2019-04-15 07:48:15 +02:00
pathmapper
6a605571e0 Firefox scrollbar styling 2019-04-15 07:14:10 +02:00
pathmapper
c4ec77c911 Merge pull request #511 from pathmapper/update_stylelint
Update stylelint and remove node 6 from test-runners
2019-04-15 06:39:26 +02:00
pathmapper
f7643cee7e Fix appveyor lint-styles 2019-04-14 10:05:15 +02:00
pathmapper
cd95202dcc Update stylelint and remove node 6 from test-runners 2019-04-14 09:35:58 +02:00
pathmapper
facba3998b Merge pull request #510 from lukaswelte/master
Update mapbox dependencies to current version
2019-04-11 09:24:54 +02:00
Lukas Welte
1f9cc2ce33 Update mapbox dependencies to current version 2019-04-10 14:09:44 +02:00
pathmapper
ad505378ab Merge pull request #508 from pathmapper/master
Change Maptiler URLs
2019-04-08 10:13:16 +02:00
pathmapper
fb7b30c81d Add backwards compability for tilehosting URLs 2019-04-06 12:00:48 +02:00
pathmapper
cb3f93c67d Change Maptiler URLs 2019-04-03 09:51:43 +02:00
pathmapper
76cb5a6b7c Merge pull request #505 from maputnik/revert-504-readme_images
Revert "Readme: Use absolute URLs for logo and sponsor images"
2019-03-11 20:45:15 +01:00
pathmapper
990e47cb24 Revert "Readme: Use absolute URLs for logo and sponsor images" 2019-03-11 20:07:08 +01:00
pathmapper
8be7465428 Merge pull request #504 from pathmapper/readme_images
Use absolute URLs for logo and sponsor images
2019-03-11 19:31:14 +01:00
pathmapper
e2b7a6a517 Use absolute URLs for logo and sponsor images 2019-03-11 14:47:47 +01:00
pathmapper
284e00b665 Merge pull request #500 from pathmapper/appveyor_lint-styles
Appveyor add again lint-styles
2019-03-11 10:26:31 +01:00
pathmapper
1fbfa8428b Remove unused argument 2019-03-07 13:47:53 +01:00
pathmapper
b13b89c7ce Fix JSON-editor 2019-03-07 13:06:02 +01:00
pathmapper
3fa31e2a2e Merge pull request #485 from sk1p/icon-input-value-type
IconInput value type should be string, not array
2019-03-06 07:22:23 +01:00
pathmapper
0e7d2d8ff5 Appveyor lint-styles 2019-03-05 13:43:34 +01:00
pathmapper
2def3820dd Merge pull request #498 from pathmapper/node10-slim_for_docker
Use node:10-slim for Docker
2019-03-01 17:42:13 +01:00
pathmapper
e1a489f318 Use node:10-slim for Docker 2019-02-27 13:50:27 +01:00
pathmapper
760839eb83 Merge pull request #497 from pathmapper/externally-accessible-dev-server
How to start externally accessible dev server
2019-02-15 19:51:30 +01:00
pathmapper
7136d2dea3 How to start externally accessible dev server 2019-02-15 19:25:14 +01:00
pathmapper
21f4d26b50 Merge pull request #482 from sk1p/type-formatted-hotfix
Use StringInput for 'formatted' field type
2019-02-11 12:50:38 +01:00
pathmapper
627ea268c9 Merge pull request #495 from maputnik/fix/popup-tip-border-color
Fix/popup tip border color
2019-02-10 19:09:24 +01:00
pathmapper
65f77db4d6 Merge pull request #494 from pathmapper/fix-docker
Fix Docker
2019-02-10 10:11:12 +01:00
pathmapper
03b4f1eb8d Update Dockerfile 2019-02-10 07:58:37 +01:00
pathmapper
82d1fc0a8b Merge pull request #492 from pathmapper/pathmapper-readme-cli
Adding information regarding CLI
2019-02-09 14:36:38 +01:00
pathmapper
3b16de5df4 Adding information regarding CLI again 2019-02-09 14:15:23 +01:00
pathmapper
94d4070653 Merge pull request #490 from pathmapper/pathmapper-warning_docker
Dockerfile fix warning
2019-01-31 09:05:03 +01:00
pathmapper
d856a1cd8e Dockerfile fix warning 2019-01-29 14:14:28 +01:00
pathmapper
7c1d0f7bee Merge pull request #480 from pathmapper/update_status_badge
Update status badge: travis -> circleci
2019-01-22 14:46:36 +01:00
pathmapper
d02036321f Merge pull request #486 from fredj/spelling
Correct some spelling mistake in README
2019-01-22 14:44:45 +01:00
Frederic Junod
1edadcc6bb Correct some spelling mistake in README 2019-01-18 16:30:36 +01:00
Alexander Clausen
aa92091d2d IconInput value type should be string, not array 2019-01-06 18:07:38 +01:00
Alexander Clausen
14e0385575 Reflect current view in dropdown
Useful if the view is toggled between inspect and map via keyboard
shortcut.
2019-01-06 06:20:03 +01:00
Alexander Clausen
6cf861d44e Keep inspect mode consistent across renderer changes
If you were in inspect mode, switched to open layers, and back to
MapboxGlMap, the state in MapboxGlMap and MapboxInspect diverged,
meaning MapboxGlMap thought it was in inspect mode, while MapboxInspect
had inspector mode disabled.
2019-01-06 06:02:10 +01:00
Alexander Clausen
1375240bfa For better debuggability, actually keep one popup node around 2019-01-06 06:01:04 +01:00
Alexander Clausen
8f391d7d52 Cleanup popup nodes
Before, the component instances used for rendering popup content were
kept around, slowly leaking memory. This could be observed using react
developer tools.
2019-01-06 05:49:03 +01:00
Alexander Clausen
84654e81af MapboxGlMap: remove unused state variables 2019-01-06 05:39:19 +01:00
Alexander Clausen
7ff0524bb7 Allow inspect mode to count properly
Example: https://maputnik.github.io/editor/#12.86/54.38618/9.76697
2019-01-06 05:35:43 +01:00
Alexander Clausen
06c3c92fd6 Ensure key uniqueness in FeaturePropertyPopup 2019-01-06 05:35:11 +01:00
Alexander Clausen
4c2941e9b6 Use StringInput for 'formatted' field type 2019-01-05 22:38:58 +01:00
pathmapper
ed7a25646e Use master branch 2019-01-05 08:16:22 +01:00
pathmapper
8c821176cf Update status badge: travis -> circleci 2019-01-04 20:31:01 +01:00
Orange Mug
98ded98583 Merge pull request #476 from pathmapper/fix_issue_404
Use access token for fetchSources
2019-01-04 14:34:26 +00:00
Orange Mug
10ae69e41f Merge pull request #479 from maputnik/revert-465-source_layer_list
Revert "Use replaceAccessTokens in onStyleChanged"
2019-01-04 14:33:35 +00:00
Orange Mug
04531b4305 Revert "Use replaceAccessTokens in onStyleChanged" 2019-01-04 14:32:41 +00:00
Orange Mug
7ab4b2481c Merge pull request #477 from pathmapper/update_OMT_styles
Update OMT styles for v3.9
2019-01-04 14:31:37 +00:00
Orange Mug
6fa88e6869 Merge pull request #468 from meetar/shouldComponentUpdate-patch
shouldComponentUpdate hack
2019-01-04 14:31:14 +00:00
Orange Mug
5b90c31645 Merge pull request #465 from pathmapper/source_layer_list
Use replaceAccessTokens in onStyleChanged
2019-01-04 14:29:55 +00:00
pathmapper
5eba11faee Update OMT styles for v3.9 2018-12-19 10:57:06 +01:00
pathmapper
54b4fc473c Use access token for fetchSources 2018-11-27 13:51:26 +01:00
Orange Mug
fe8595cdc9 Merge pull request #474 from pathmapper/empty_style
Update empty-style URL
2018-11-26 10:48:07 +00:00
Orange Mug
2565a89474 Merge pull request #475 from pathmapper/rtl_blob
Set MIME type for RTL blob
2018-11-26 10:47:42 +00:00
pathmapper
92b970377d Set MIME type for RTL blob 2018-11-25 08:13:21 +01:00
pathmapper
dd3a550ec3 Update empty-style URL 2018-11-24 20:15:05 +01:00
Orange Mug
7d5d9e2d82 Merge pull request #470 from pathmapper/node_v11
Add node v11 to test runners and fix Appveyor
2018-11-19 11:42:52 +00:00
pathmapper
9daa71befc Bump node-sass 2018-11-18 19:23:06 +01:00
pathmapper
f10a2d28df Use Visual Studio 2015 for Appveyor 2018-11-18 11:05:29 +01:00
Orange Mug
d52c6c70bb Merge pull request #469 from morlay/master
make docker simpler
2018-11-17 15:34:18 +00:00
Orange Mug
6e2f46a0da Merge pull request #464 from pathmapper/fix-wobbling
Fix layer list wobbling
2018-11-17 15:18:41 +00:00
Orange Mug
2d6f91d0cd Merge pull request #447 from orangemug/fix/lock-logo-size-in-survey-popup
Fix the size of the logo in the survey modal
2018-11-17 15:17:51 +00:00
pathmapper
f409079d93 Bump wdio-mocha-framework 2018-11-17 13:48:17 +01:00
pathmapper
7004259867 Use previous VS image 2018-11-17 12:19:15 +01:00
pathmapper
f3128cb6d2 Add node v11 to test runners 2018-11-17 11:08:55 +01:00
Morlay
1dfd4d8d48 make docker simpler 2018-11-14 14:48:08 +08:00
Peter Richardson
2f30eb6cbe rm build 2018-11-12 20:50:20 -08:00
Peter Richardson
cf45c04069 add shouldComponentUpdate
checks for differences in props and state - addresses https://github.com/maputnik/editor/issues/467
2018-11-12 20:47:24 -08:00
Peter Richardson
05d149bcfa added build 2018-11-12 16:35:18 -08:00
pathmapper
3acbc3291c Remove duplicated line 2018-11-05 21:08:34 +01:00
pathmapper
24aa2fd5fa Use replaceAccessToken onStyleChanged 2018-11-05 08:17:21 +01:00
pathmapper
cc7d7a56f5 Fix wobbling 2018-11-04 10:38:58 +01:00
Orange Mug
da17646b8d Merge pull request #463 from pathmapper/color-contrast
Increase color contrast (fixes #318)
2018-11-04 09:08:30 +00:00
pathmapper
f9233a1e31 Increase color contrast 2018-11-03 18:01:34 +01:00
Orange Mug
c94f536e5a Merge pull request #459 from orangemug/feature/layer-list-ui-handle
Make whole layer label draggable
2018-11-02 20:48:14 +00:00
orangemug
b712e7f184 Merge remote-tracking branch 'upstream/master' into feature/layer-list-ui-handle
Conflicts:
	src/styles/_layer.scss
2018-11-02 17:57:42 +00:00
Orange Mug
b8ab802de5 Merge pull request #461 from pathmapper/helper
Style layer which is dragged
2018-11-02 17:55:44 +00:00
pathmapper
a74eb2989c Add helper class and style the helper 2018-11-02 14:25:31 +01:00
orangemug
3a0fc6eeac Fixed typo 2018-11-02 08:54:20 +00:00
Orange Mug
0f0684e701 Merge pull request #458 from pathmapper/debug
Add 'show-overdraw-inspector' query parameter
2018-11-02 08:50:20 +00:00
orangemug
e9b5bfb572 Remove old code. 2018-11-02 08:34:56 +00:00
orangemug
b456b59c44 Fix to allow high precision on text input and integer on range. 2018-11-02 08:28:51 +00:00
pathmapper
59ad91fdf8 Add 'show-overdraw-inspector' query parameter 2018-11-02 09:07:01 +01:00
orangemug
e18d304313 Changed min/max zoom range step from 0.1 -> 1 2018-11-01 18:28:58 +00:00
orangemug
5de5281b49 Prevent title resize. 2018-11-01 18:26:21 +00:00
orangemug
fe0df2a4ef Make range step configurable 2018-11-01 08:28:49 +00:00
orangemug
deec7894dd Make the whole layer label draggable 2018-11-01 08:12:40 +00:00
Orange Mug
c9a0c0400e Merge pull request #455 from pathmapper/autocomplete_z-index
Add z-index to autocomplete
2018-10-31 18:21:15 +00:00
pathmapper
419e62f69b Add z-index to autocomplete 2018-10-31 18:53:15 +01:00
Orange Mug
9ffbe3a7a2 Merge pull request #453 from orangemug/fix/more-menu-icon-size
Increase more-menu icon size, broken by react-icons update
2018-10-31 13:44:48 +00:00
orangemug
c8e548e3be Increase more-menu icon size, broken by react-icons update 2018-10-31 08:19:12 +00:00
Orange Mug
b9160bd333 Merge pull request #451 from pathmapper/firefox_select
Improve select styling
2018-10-31 08:05:22 +00:00
Orange Mug
8ad8b4cdea Merge pull request #450 from pathmapper/activate_renderer-test
Update tests for style settings modal
2018-10-31 08:03:18 +00:00
Orange Mug
c51c40a20e Merge pull request #448 from orangemug/fix/shortcut-fixes
Shortcut fixes
2018-10-31 08:02:13 +00:00
Orange Mug
2ccb1a8e0a Merge pull request #446 from pathmapper/fix-445
Remove node v9 from appveyor and update readme
2018-10-31 08:00:48 +00:00
pathmapper
008bb75c04 Remove border for select select 2018-10-30 22:12:52 +01:00
orangemug
a51fdb8435 Merge remote-tracking branch 'upstream/master' into feature/add-range-slider 2018-10-30 20:35:55 +00:00
orangemug
cdd5d27908 Added range slider to <NumberInput /> 2018-10-30 20:35:22 +00:00
orangemug
82d3c934c8 Merge remote-tracking branch 'upstream/master' into fix/lock-logo-size-in-survey-popup 2018-10-30 20:26:17 +00:00
orangemug
f2f0270936 Use KeyboardEvent.key rather than keyCode in attempt to support more keyboard layouts. 2018-10-30 20:12:48 +00:00
pathmapper
00f646d489 Update test runners and readme 2018-10-30 21:08:42 +01:00
Orange Mug
90a02df45c Merge pull request #449 from orangemug/fix/popup-tip-border-color
Fixes for 'mapboxgl-popup-tip' border color.
2018-10-30 19:57:52 +00:00
Orange Mug
ad40a15a77 Merge pull request #443 from pathmapper/style-parameter
Warning when style parameter is used
2018-10-30 19:50:26 +00:00
Orange Mug
d6809cb504 Merge pull request #409 from orangemug/fix/color-accessibility-styling-issue
Added hacks to fix styling issue
2018-10-30 19:46:41 +00:00
pathmapper
ff8d3055b4 Add test for TF access token 2018-10-30 20:37:56 +01:00
orangemug
1f81449e3c Added a visible drag handle. 2018-10-30 19:32:20 +00:00
pathmapper
c59e0cb046 Activate renderer test 2018-10-30 20:06:52 +01:00
pathmapper
2d1675c181 Fixes for code review comments 2018-10-29 17:35:12 +01:00
orangemug
48ebca6236 Fix the size of the logo in the survey modal so it doesn't cause a visual jump when it loads. 2018-10-29 13:12:01 +00:00
orangemug
bce8e8b807 Shortcut fixes
- Allow shortcuts to trigger from the shortcut modal
 - Fix inspect/map toggle shortcut
2018-10-29 13:07:49 +00:00
pathmapper
1f4dfa7603 Update readme (Node versions and CLI) 2018-10-29 13:56:09 +01:00
pathmapper
c23af0063d Add node v11 to the test runners 2018-10-29 13:42:01 +01:00
pathmapper
9f6250c489 Update tests 2018-10-29 11:16:27 +01:00
orangemug
cf6c6f1c17 Fixes for 'mapboxgl-popup-tip' border color. 2018-10-27 14:41:50 +01:00
orangemug
c6163b6ba2 Added missing css for popup changes 2018-10-27 14:14:20 +01:00
orangemug
7121a680b4 Add missing prop type 2018-10-27 14:08:23 +01:00
orangemug
cf391031f0 Added color swatch to <FeatureLayerPopup/> 2018-10-27 14:04:13 +01:00
pathmapper
9cac5305cd Warning when style parameter is used 2018-10-25 19:37:39 +02:00
pathmapper
b0adb8cd3d Remove style querystring parameter 2018-10-25 19:34:19 +02:00
Orange Mug
3d2a1d5d19 Merge pull request #439 from orangemug/feature/style-spec-additions
Style spec additions
2018-10-24 19:13:53 +01:00
Orange Mug
3c93c41de1 Merge pull request #442 from pathmapper/export-style-name
Use style name for export filename if available
2018-10-24 08:36:22 +01:00
Orange Mug
4baed5d8ab Merge pull request #441 from pathmapper/image_property
Move image property
2018-10-24 08:32:47 +01:00
pathmapper
f17b02b1fe Slugify result in lower case 2018-10-23 13:31:38 +02:00
pathmapper
3c72d07a88 Export stylename if available 2018-10-23 13:04:23 +02:00
orangemug
7495c0dfcf Added support for 'fill-extrusion-vertical-gradient' and 'symbol-z-order'
Also updated @mapbox/mapbox-gl-style-spec
2018-10-22 22:29:23 +01:00
Orange Mug
b0c877d4ae Merge pull request #418 from orangemug/fix/modal-exit-apply-changes
Delay modal close until blur events have triggered
2018-10-22 16:32:39 +01:00
Orange Mug
e1fd0f8014 Merge pull request #438 from pathmapper/top_issues
Create .topissuesrc
2018-10-21 11:48:21 +01:00
pathmapper
cb2198b661 Move image property 2018-10-21 11:28:05 +02:00
pathmapper
68beeeb599 Create .topissuesrc 2018-10-20 18:35:35 +02:00
orangemug
218ce148d5 Delay modal close until blur events have triggered. 2018-10-19 08:39:07 +01:00
Orange Mug
d0cafb06ee Merge pull request #414 from pathmapper/osm-libety_gh-pages
Use GitHub Pages for OSM Liberty
2018-10-17 13:06:13 +01:00
Orange Mug
5671a58704 Merge pull request #415 from pathmapper/pathmapper-update_empty-style
Update Empty Style
2018-10-17 13:05:19 +01:00
pathmapper
9cf74ca405 Update empty-style.json 2018-10-17 13:16:10 +02:00
pathmapper
1c6e3648eb Use GitHub Pages for OSM Liberty 2018-10-16 07:32:25 +02:00
Orange Mug
b3a4628a79 Merge pull request #413 from pathmapper/rawgit_shutdown
rawgit.com -> jsDelivr
2018-10-15 15:03:31 +01:00
pathmapper
941cc37c87 rawgit.com -> jsDelivr 2018-10-13 09:13:34 +02:00
Orange Mug
906d7ac3d5 Merge pull request #411 from orangemug/fix/autocomplete-only-autocomplete-strings
Stop autocomplete crashing the editor
2018-10-12 19:24:35 +01:00
orangemug
588b18d10e Only render strings in the autocomplete menu.
Expression objects were making there way into this menu which was crashing the editor.
2018-10-11 21:39:52 +01:00
Orange Mug
90024c5ec7 Merge pull request #408 from orangemug/maintenance/update-deps-2018-10-06
Updated dependencies
2018-10-10 15:15:26 +01:00
orangemug
889005de6c Set default value of autocomplete shouldItemRender value param as sometimes it's undefined 2018-10-09 21:11:47 +01:00
orangemug
843d3df8bc Fixed react-icons size/position. 2018-10-09 20:58:14 +01:00
orangemug
825b9044b9 Tidy naming. 2018-10-09 20:48:10 +01:00
orangemug
92a1be83b6 Moved babel config back out into .babelrc
This is due to .babelrc being used for other tooling.
2018-10-09 20:45:03 +01:00
orangemug
36e35eb208 Tidy webpack configs. 2018-10-09 20:43:35 +01:00
orangemug
2fcdb47fe5 Moved babel config, removed uglifyJs and decorators plugins 2018-10-09 20:14:16 +01:00
orangemug
012e4b670e Updated mapbox-gl and react-sortable-hoc usage 2018-10-08 09:32:21 +01:00
orangemug
492cc244d8 Added hacks to fix styling issue
See <https://github.com/maputnik/editor/pull/392#issuecomment-427595172>
2018-10-06 22:14:59 +01:00
orangemug
d17d6b43c0 Fixed merge issue. 2018-10-06 21:57:24 +01:00
orangemug
1bf10cd6d6 Merge remote-tracking branch 'upstream/master' into maintenance/update-deps-2018-10-06
Conflicts:
	src/components/App.jsx
	src/components/Toolbar.jsx
2018-10-06 21:39:26 +01:00
orangemug
b0cd9140be Updated remaining deps. 2018-10-06 21:21:42 +01:00
orangemug
cc6196969f Updated lockfile 2018-10-06 21:07:48 +01:00
orangemug
802a7eb1be Updated babel/webpack 2018-10-06 21:05:33 +01:00
Orange Mug
a666f86be0 Merge pull request #397 from orangemug/feature/ol-experimental-support
Added back in experimental OpenLayers support
2018-10-06 16:59:13 +01:00
Orange Mug
44fad76d45 Merge pull request #392 from orangemug/feature/color-accessibility-ui
Color accessibility UI
2018-10-06 16:58:32 +01:00
orangemug
c8d23a534e Updated some dev deps 2018-10-06 16:44:23 +01:00
orangemug
cf3650c8cd Updated react-icons 2018-10-06 16:38:08 +01:00
orangemug
1a8349f821 Updated deps with no API changes. 2018-10-06 16:01:34 +01:00
orangemug
855771a6b6 npm is getting confused about the lockfile. This now works locally from fresh install 2018-10-06 15:13:25 +01:00
orangemug
b711168e44 Move package-lock.json fixes... :/ 2018-10-06 15:00:34 +01:00
orangemug
4134919dde Added missing key attribute to <option/> 2018-10-06 14:44:12 +01:00
orangemug
158153e366 Revert package-lock.json update and build against node:10 2018-10-06 14:42:33 +01:00
orangemug
6b890d162a Merge remote-tracking branch 'upstream/master' into feature/ol-experimental-support 2018-10-06 14:06:10 +01:00
orangemug
1525807d06 setValue -> selectByValue 2018-10-06 13:59:50 +01:00
orangemug
a356bfd601 Switch from react-aria-menubutton to <select/> 2018-10-06 13:54:02 +01:00
Orange Mug
e6d2a6d5ff Merge pull request #384 from orangemug/feature/os-open-zoomstack
OS Open Zoomstack
2018-10-06 13:25:23 +01:00
Orange Mug
c8a004422f Merge pull request #406 from emuanalytics/bug/#380
Fix for Issue #380
2018-10-06 13:18:31 +01:00
Orange Mug
df457fc7bf Merge pull request #407 from pathmapper/get-name
Get name from package.json
2018-10-04 18:15:42 +01:00
pathmapper
6e03f1f077 get name from package.json 2018-10-04 16:42:39 +02:00
Robin Summerhill
4c13350c14 Issue #380 - fix for data functions 2018-10-03 20:11:53 +01:00
Orange Mug
63a2495c68 Merge pull request #405 from pathmapper/update-tilehosting
Update tilehosting URL
2018-10-01 21:21:24 +01:00
pathmapper
f9de73e18a Update tilehosting URL 2018-10-01 10:13:00 +02:00
Orange Mug
e6e2be61f0 Merge pull request #398 from orangemug/fix/load-url-error
Show error if style fails to load and disabled button if input is empty
2018-09-26 18:35:51 +01:00
Gregory Wolanski
060f7aa42c Merge pull request #400 from orangemug/feature/make-layer-visibility-always-shown
Make layer visibility icon shown when hidden
2018-09-24 22:19:07 +02:00
orangemug
8b0ae178b8 Added in thumbnails 2018-09-24 21:17:41 +01:00
orangemug
6b94e9b78b Merge remote-tracking branch 'upstream/master' into feature/os-open-zoomstack
Conflicts:
	src/config/styles.json
2018-09-24 21:14:55 +01:00
orangemug
b171bf3127 Fixes for code review comments. 2018-09-24 21:01:37 +01:00
orangemug
0c6a179cec Switch to using styleUrl for disabling button 2018-09-24 20:58:43 +01:00
Orange Mug
aa50785c12 Merge pull request #399 from orangemug/fix/added-default-prop
Added default isActive prop to Collapse component
2018-09-24 20:44:04 +01:00
orangemug
252403b1e3 Added classBlockModifier to <LayerAction/> and switched to only displaying icons for hidden layers 2018-09-24 20:40:51 +01:00
orangemug
bc1d0de057 Added default isActive prop to Collapse component 2018-09-24 16:55:53 +01:00
orangemug
4a0b9fd0de Added missing prop type 2018-09-24 15:13:35 +01:00
orangemug
e8777e1857 Updated package-lock.json 2018-09-24 15:10:00 +01:00
orangemug
94a2a16330 Updated ol* versions 2018-09-24 14:51:25 +01:00
orangemug
004d135d93 Show error if style fails to load and disabled button if input is empty 2018-09-24 14:41:09 +01:00
orangemug
0973dcee8a Added back in experimental OpenLayers support 2018-09-24 14:05:53 +01:00
Orange Mug
c908f7dcd0 Merge pull request #394 from orangemug/fix/request-abort-and-oerlapping-modals
Fix overlapping modals & request canceling
2018-09-23 22:28:39 +01:00
orangemug
b7fd889fcd Removed signal from fetch as not supported in all browsers. 2018-09-23 21:00:17 +01:00
orangemug
35600c253d Revert react-aria-modal 2018-09-23 20:43:34 +01:00
orangemug
673465af77 Use AbortController in activeRequest 2018-09-23 19:53:32 +01:00
orangemug
cc5d0dc4fe Merge remote-tracking branch 'upstream/master' into fix/request-abort-and-oerlapping-modals 2018-09-23 19:45:47 +01:00
orangemug
e6da977c48 Prevented overlapping modals in react tree and fixed request canceling. 2018-09-23 19:40:50 +01:00
orangemug
e4aa016713 Fixed lint errors 2018-09-23 14:50:29 +01:00
orangemug
8b67499a64 Removed external svg from filter command. 2018-09-23 14:48:19 +01:00
orangemug
bcdc7c6811 Improved color accessibility UI 2018-09-23 14:39:02 +01:00
orangemug
8f07a79a49 Merge remote-tracking branch 'upstream/master' into feature/color-accessibility-ui
Conflicts:
	src/components/App.jsx
	src/styles/_components.scss
2018-09-23 11:39:15 +01:00
orangemug
cdcf16196c Merge remote-tracking branch 'upstream/master' into feature/make-layer-visibility-always-shown
Conflicts:
	src/components/layers/LayerListItem.jsx
2018-09-23 09:07:02 +01:00
orangemug
a0ed6a379b Always show layer visibility toggle in layer list 2018-09-23 09:05:08 +01:00
Orange Mug
7ffb44f604 Merge pull request #391 from orangemug/maintenance/remove-mapbox-for-now
Remove mapbox for the time being
2018-09-22 18:28:00 +01:00
Orange Mug
225d0388ce Merge pull request #386 from orangemug/fix/showTileBoundaries-error
Added guard to map object
2018-09-22 16:15:00 +01:00
Orange Mug
0468db8cc2 Merge pull request #390 from orangemug/fix/switch-visibility-icons
Switch visibility icons
2018-09-22 15:51:10 +01:00
Orange Mug
695f612110 Merge pull request #389 from orangemug/maintenance/remove-travis
Remove travis CI
2018-09-22 15:50:49 +01:00
Orange Mug
9c07852b87 Merge pull request #388 from orangemug/fix/glyph-key-replace
Fix glyph key replace
2018-09-22 15:50:12 +01:00
orangemug
9ef198fb86 Merge remote-tracking branch 'upstream/master' into maintenance/remove-mapbox-for-now 2018-09-22 14:19:44 +01:00
orangemug
fd34e31462 Merge remote-tracking branch 'upstream/master' into fix/showTileBoundaries-error 2018-09-22 14:17:16 +01:00
orangemug
8eb49427fd Merge remote-tracking branch 'upstream/master' into fix/switch-visibility-icons 2018-09-22 14:15:43 +01:00
orangemug
ebafb3c3dd Merge remote-tracking branch 'upstream/master' into maintenance/remove-travis 2018-09-22 14:14:12 +01:00
orangemug
09c6154949 Merge remote-tracking branch 'upstream/master' into fix/glyph-key-replace 2018-09-22 14:12:39 +01:00
Orange Mug
53c8661cd3 Merge pull request #358 from orangemug/fix/remove-componentWillUpdate
Remove UNSAFE_componentWillReceiveProps
2018-09-22 14:11:58 +01:00
orangemug
3d5eec897e Try moving to 'Visual Studio 2017' image 2018-09-22 13:44:41 +01:00
orangemug
3763ec3737 Remove mapbox until we have a valid access token. 2018-09-22 13:18:52 +01:00
orangemug
f1216795d2 Swap layer visibility icons. 2018-09-22 13:12:36 +01:00
orangemug
0ac70df00f Remove travis as we now have CircleCI. 2018-09-22 13:06:56 +01:00
orangemug
7d0a985f1d Only replace glyphs key if a replacement exists. 2018-09-22 13:04:12 +01:00
orangemug
c5ff67b6e0 Appveyor nodejs -v6 +v10 2018-09-22 12:50:40 +01:00
orangemug
db6b9ac176 Added OS Open Zoomstack and styles 2018-09-20 19:26:53 +01:00
orangemug
77475af3c6 Added guard to map object 2018-09-20 19:16:23 +01:00
Orange Mug
805133d10c Merge pull request #383 from pathmapper/master
Access token labels OMT -> MapTiler
2018-09-15 10:03:21 +01:00
pathmapper
fff8fb72c5 Access token labels OMT - MapTiler 2018-09-14 09:08:04 +02:00
Orange Mug
e02b18cea3 Merge pull request #378 from pathmapper/patch-1
fix typo
2018-09-13 08:52:12 +01:00
pathmapper
b8e9307ce2 fix typo 2018-09-11 13:52:39 +02:00
orangemug
00b22eb902 OpenLayers removed in previous PR. 2018-09-10 15:11:06 +01:00
orangemug
be954143c3 Switch to setTimeout(fn, 0) 2018-09-10 15:09:34 +01:00
orangemug
b314642586 Rollback to setImmediate 2018-09-10 14:55:45 +01:00
orangemug
b5fc315b37 setImmediate -> process.nextTick 2018-09-10 14:51:22 +01:00
orangemug
26ff9f63bb Merge remote-tracking branch 'upstream/master' into fix/remove-componentWillUpdate
Conflicts:
	src/components/map/MapboxGlMap.jsx
	src/components/modals/ExportModal.jsx
2018-09-10 14:46:52 +01:00
Orange Mug
7e5fb4d42f Merge pull request #364 from orangemug/maintenance/reduce-bundle-size-v2
Reduce bundle size
2018-09-10 14:12:03 +01:00
Orange Mug
762bb786be Merge pull request #365 from orangemug/feature/added-no-webgl-error
Added no WebGL error message to MapboxGL map component
2018-09-10 14:09:09 +01:00
Orange Mug
cec87765fc Merge pull request #366 from loicgasser/maintenance/transform-class-properties-and-arrow-func
Take advantage of transform-class-properties and use arrow functions
2018-09-10 14:08:46 +01:00
orangemug
b966fae926 1.5.0 2018-09-10 13:18:21 +01:00
orangemug
f1ddf4e57e 1.5.0-beta3 2018-09-03 21:17:50 +01:00
Orange Mug
64e65dc7d3 Merge pull request #377 from orangemug/fix/glyphs-for-tilehosting
Updated regex to tilehosting.com
2018-09-03 21:15:01 +01:00
orangemug
1e07a88aed Updated regex to tilehosting.com, partial revert of #367 2018-09-03 21:02:38 +01:00
orangemug
6e49cc65a9 1.5.0-beta2 2018-09-03 20:37:16 +01:00
Orange Mug
06d579118a Merge pull request #367 from loicgasser/bugfix/default-token
Fix glyph access key for openmaptiles
2018-09-03 20:34:01 +01:00
orangemug
f0e4b5b930 1.5.0-beta 2018-09-01 11:09:19 +01:00
Loïc Gasser
088127a9a5 Fix glyph access key for openmaptiles 2018-08-27 16:18:43 -04:00
Loïc Gasser
a4b4d077fa Fix .babelrc 2018-08-23 00:18:39 -04:00
Loïc Gasser
bc2ec4d0b7 Remove unused imports 2018-08-23 00:18:39 -04:00
Loïc Gasser
e4de101553 Take advantage of transform-class-properties and use arrow functions instead of bind 2018-08-23 00:18:37 -04:00
orangemug
6207416b32 Added no WebGL error message to MapboxGL map component 2018-08-22 22:05:46 +01:00
orangemug
f0202241f4 Remove old base64 loader. 2018-08-22 18:51:58 +01:00
orangemug
0e8c94af1e Remove logging. 2018-08-22 18:51:42 +01:00
orangemug
922ee616ec Reduce bundle size
- Use the browsers fetch rather than the request module
 - base64-loader -> raw-loader
 - Remove ol3 because it's been broken for a while
 - Removed old GitHub gist support as it's no longer functional
 - Removed Mousetrap as we were only using a small part of the functionality
 - Moved to single js file to make things simplier
2018-08-22 09:36:34 +01:00
Orange Mug
98c235bc21 Merge pull request #363 from orangemug/feature/added-show-collision-boxes
Added 'show-collision-boxes' query parameter
2018-08-19 19:48:03 +01:00
orangemug
70f1f9ffac Added 'show-collision-boxes' query parameter 2018-08-19 17:32:18 +01:00
orangemug
409f81f0d8 More componentWillUpdate transition fixes. 2018-08-07 20:13:45 +01:00
orangemug
1aa90bef37 Removed componentWillUpdate 2018-08-06 22:27:03 +01:00
Orange Mug
c5ea9494df Merge pull request #357 from chriswhong/356-zoom-button-fix
find correct zoom attribute in spec
2018-08-04 09:20:31 +01:00
Chris Whong
9a34db7008 find correct zoom attribute in spec 2018-08-03 15:25:05 -04:00
Orange Mug
988b7fca0f Merge pull request #355 from orangemug/fix/failing-tests
Disable survey in test runner
2018-08-01 22:14:36 +01:00
orangemug
bdc6489db4 Disable survey in test runner, which was making the tests fail. 2018-08-01 20:59:42 +01:00
Orange Mug
49b096b601 Merge pull request #352 from orangemug/feature/add-thunderforest-source-v2
Added thunderforest source
2018-08-01 20:48:12 +01:00
Orange Mug
31d83f6a26 Merge pull request #354 from orangemug/maintenance/updated-mapbox-deps
Updated mapbox dependencies
2018-08-01 20:47:39 +01:00
orangemug
03e52b7a72 Added support for 'raster-resampling' 2018-08-01 20:34:26 +01:00
orangemug
551e950c39 Updated mapbox dependencies 2018-08-01 20:33:33 +01:00
orangemug
a7620f83a6 Fixed broken token replacer function. 2018-07-28 16:36:01 +01:00
orangemug
0384181ee1 Added final bits for thunderforest integration 2018-07-27 16:25:53 +01:00
orangemug
fd59f42819 Merge remote-tracking branch 'upstream/master' into feature/add-thunderforest-source
Conflicts:
	src/components/App.jsx
2018-07-27 15:43:02 +01:00
orangemug
cc51774259 1.4.0 2018-07-27 13:19:14 +01:00
Orange Mug
5a19245ee0 Merge pull request #349 from orangemug/fix/react-codemirror-overflow
Fix to prevent contents of react-codemirror being hidden
2018-07-18 19:16:14 +01:00
orangemug
45f45b7547 Fix to prevent contents of react-codemirror being hidden 2018-07-18 08:07:35 +01:00
Orange Mug
530bfaf3b3 Merge pull request #348 from orangemug/fix/color-filter-undefined
Undefined filter fix (color accessibility)
2018-07-17 21:51:54 +01:00
orangemug
6ea70ab9cf Fix what I believe to be a 'first boot' error. 2018-07-17 20:45:12 +01:00
orangemug
a0e2d68dae Only apply filter if defined. 2018-07-17 20:40:23 +01:00
Orange Mug
1447e8bfb5 Merge pull request #345 from orangemug/feature/option-to-download-with-own-tokens
Option to download styles with your own tokens
2018-07-16 08:10:43 +01:00
orangemug
c0480a50ea Option to download styles with own tokens. 2018-07-15 22:51:57 +01:00
Orange Mug
09ba2be416 Merge pull request #344 from orangemug/fix/map-overflow-zoom-issues
Fixed map width so it no longer overflows
2018-07-15 22:44:51 +01:00
Orange Mug
115ce3305d Merge pull request #343 from orangemug/fix/disable-bounce-scroll
Prevent bounce scroll on <body/>
2018-07-15 22:11:18 +01:00
orangemug
960b2022ed Fixed map width (fixes #260) 2018-07-15 22:08:06 +01:00
orangemug
252b442ca9 The UI is 100% height so prevent bounce scroll on OSX 2018-07-15 21:51:25 +01:00
Orange Mug
03b9ddda9c Merge pull request #342 from orangemug/fix/layer-editor-overflow
Fixed <LayerEditor/> overflow issues
2018-07-15 21:49:17 +01:00
orangemug
968d7d7fda Fixed <LayerEditor/> overflow issues. 2018-07-15 13:17:47 +01:00
orangemug
b211f1cd12 1.3.0 2018-07-12 15:54:01 +01:00
Orange Mug
870d4349f4 Merge pull request #341 from orangemug/fix/normalizeSourceURL-import-error
Fixed normalizeSourceURL import issue
2018-07-12 14:23:16 +01:00
orangemug
d88bc59720 Fixed normalizeSourceURL import issue. 2018-07-12 12:33:40 +01:00
orangemug
7c00775515 1.3.0-beta 2018-07-11 08:22:30 +01:00
Orange Mug
4b5536b282 Merge pull request #335 from gregorywolanski/survey
Survey
2018-07-08 15:50:29 +01:00
Gregory Wolanski
fb84cfee1c Survey (#328): Proper contrast ratio 2018-07-08 16:27:59 +02:00
Gregory Wolanski
9132262106 Merge branch 'survey' of https://github.com/gregorywolanski/editor into survey 2018-07-08 14:43:03 +02:00
Gregory Wolanski
5de9e708e9 Survey (#328): Cleaning 2018-07-08 14:42:49 +02:00
Gregory Wolanski
4df63c7287 Update _base.scss 2018-07-08 14:38:52 +02:00
Gregory Wolanski
a88ca031d0 Survey (#328)
Elements promoting the survey inside Maputnik after feedback
2018-07-08 14:34:46 +02:00
Gregory Wolanski
452706f35c Survey (#328) 2018-06-30 10:17:14 +02:00
Gregory Wolanski
8b0aa194cf Survey (#328)
Elements promoting the survey inside Maputnik after feedback
2018-06-30 10:09:23 +02:00
Orange Mug
b9aa7e9206 Merge pull request #333 from pathmapper/master
Update repository for OSM Liberty
2018-06-30 07:09:15 +02:00
pathmapper
e35f106482 Update repository for OSM Liberty 2018-06-29 11:20:32 +02:00
Gregory Wolanski
b7a97cf8ee Survey (#328)
Elements promoting the survey inside Maputnik
2018-06-25 19:52:48 +02:00
orangemug
85a28999fb Initial color accessibility UI 2018-06-18 20:28:24 +01:00
Orange Mug
9208115981 Merge pull request #330 from orangemug/feature/loading-modal
Loading dialog
2018-06-18 20:27:39 +01:00
orangemug
afbdaecd0a Abstracted out <LoadingModal/> 2018-06-18 19:06:16 +01:00
orangemug
558f3d649d Added dialog styling. 2018-06-18 18:17:33 +01:00
Orange Mug
417511d577 Merge pull request #329 from orangemug/feature/osm-donate-readme
Added link to <https://maputnik.github.io/donate>
2018-06-16 09:48:18 +01:00
orangemug
df350534ce Added link to <https://maputnik.github.io/donate> 2018-06-16 09:46:30 +01:00
orangemug
7167235146 Added loading modal when opening styles. 2018-06-15 20:57:39 +01:00
Orange Mug
7a7f2eb7de Merge pull request #315 from orangemug/feature/option-to-display-tile-boundaries
Added option to display tile boundaries
2018-06-03 20:26:17 +01:00
orangemug
cd28a53f6a Fixed failing tests, these weren't flaky tests... ooops! 2018-06-03 18:28:55 +01:00
orangemug
1fe31ac0ec Fix for bad lint error. 2018-06-03 17:55:46 +01:00
orangemug
ffce8e3ba5 Added missing file. 2018-06-03 17:37:54 +01:00
Orange Mug
a28a417ebc Merge pull request #314 from orangemug/fix/various-fixes
Small bug fixes
2018-06-03 17:35:44 +01:00
orangemug
6cdb56d13f Improved showTileBoundaries and query string support 2018-06-03 17:33:08 +01:00
orangemug
0516e587b4 Added option to display tile boundries (issue #202) 2018-06-03 17:17:45 +01:00
orangemug
5b4063105b Added missing 'noopener noreferrer' 2018-06-03 16:59:41 +01:00
orangemug
d9a5548762 Small bug fixes
- Logo DOM sctrucutre now valid, no longer <a/> within </a>
 - `data-wd-key` not longer required
 - `maputnik-doc-popup` not longer hidden by LayerEditor accordion
2018-06-03 16:37:46 +01:00
Orange Mug
cae6cffb7b Merge pull request #313 from orangemug/feature/shortcuts
Keyboard shortcuts
2018-06-03 11:18:16 +01:00
orangemug
ede782abed Fixed typo. 2018-06-03 10:18:55 +01:00
orangemug
00afbad7ac Fixed lint errors. 2018-06-03 10:00:50 +01:00
Orange Mug
edd09ef585 Merge pull request #306 from orangemug/feature/accessibility-list-reorder
Keyboard accessible layer options
2018-06-03 09:57:00 +01:00
orangemug
1e09066779 Merge branch 'feature/accessibility-list-reorder' into feature/shortcuts
Conflicts:
	src/components/App.jsx
2018-06-03 09:41:07 +01:00
orangemug
32edb48e16 Fix for when 'layout.visibility' is undefined 2018-06-03 09:31:02 +01:00
orangemug
b116eef147 Merge remote-tracking branch 'upstream/master' into feature/accessibility-list-reorder
Conflicts:
	src/components/App.jsx
2018-06-03 09:22:02 +01:00
orangemug
74d1cd2d01 Renamed 'Sources' -> 'Data Sources' to make it clearer and make shortcuts easier to remember. 2018-06-03 09:17:53 +01:00
Orange Mug
fd48d82e42 Merge pull request #312 from orangemug/feature/color-filters
Color blindness emulation
2018-06-02 10:21:39 +01:00
orangemug
480d54c2d8 Finished shortcuts modal styling 2018-06-02 10:17:39 +01:00
orangemug
ab9c39b862 Removed additional close button 2018-06-01 20:51:42 +01:00
orangemug
dd122d1bac Hide hidden FileReaderInput from keyboard focus 2018-06-01 20:45:05 +01:00
orangemug
f9f5e8f925 Changed close button from <a> to <button> 2018-06-01 20:40:51 +01:00
orangemug
aa2f4a091c Initial attempt at color blindness emulation 2018-06-01 09:22:18 +01:00
orangemug
13fc699d4a Styling fixes. 2018-05-31 21:09:31 +01:00
orangemug
f5e8d473ad Changed toggle visibility text from hide to show/hide 2018-05-31 20:40:21 +01:00
orangemug
35353d75f5 Added application shortcuts and shortcut modal.
Also moved modals into App.jsx to move the business logic to one place.
2018-05-29 17:06:00 +01:00
Orange Mug
0f103c3c00 Merge pull request #309 from orangemug/feature/skip-menu
Added skip-menu link for keyboard users
2018-05-28 13:17:02 +01:00
orangemug
019428a241 Added missing prop-types. 2018-05-28 12:06:22 +01:00
orangemug
6200edea25 Added initial shortcuts. 2018-05-28 12:03:47 +01:00
orangemug
fc7395df96 Fixed CircleCI cache to include {{arch}} 2018-05-28 11:34:12 +01:00
orangemug
272f662a34 Changed 'skip' wording
As outlined in <https://webaim.org/techniques/skipnav/>
2018-05-28 11:29:49 +01:00
orangemug
d59d9cde95 Fixed OSX working directory if CircleCI config. 2018-05-28 11:19:04 +01:00
orangemug
c71fbcf436 Tidy 2018-05-28 11:15:16 +01:00
Orange Mug
54c79445db Merge pull request #307 from orangemug/fix/public-source-button-size
Fixed public source button size
2018-05-28 10:52:23 +01:00
orangemug
a82ba26f86 Added skip-menu link for keyboard users. 2018-05-28 10:50:19 +01:00
orangemug
28af87391d Fixed public source button size. 2018-05-22 21:43:35 +01:00
orangemug
0aabd33538 Remove empty scss blocks 2018-05-22 21:26:11 +01:00
orangemug
bd9076c4ff Added additional menu in <LayerEditor/>
This is to make the following options accessible to keyboard users

 - reorder layers
 - duplicate layer
 - delete layer
 - hide/show layer
2018-05-22 21:16:46 +01:00
Orange Mug
1aed761893 Merge pull request #305 from orangemug/feature/public-style-aria-labels
Added aria-label to public styles
2018-05-19 09:39:13 +01:00
orangemug
a2a6f6dcab Added aria-label to public styles, also fixed button to reserve space in DOM (fixes #245) 2018-05-19 08:23:41 +01:00
Orange Mug
db5dd0f6ee Merge pull request #304 from orangemug/fix/disable-spellcheck-v2
Disable spellcheck on <input/>'s
2018-05-19 07:56:06 +01:00
orangemug
42c3dcf258 Updated package-lock.json 2018-05-17 13:49:24 +01:00
orangemug
51a115d65a Disable spell checking on <input>'s 2018-05-17 13:44:54 +01:00
Orange Mug
fc0fbd6a37 Merge pull request #302 from orangemug/feature/terrarium-encoding
Added support for encoding to raster-dem source
2018-05-17 13:42:01 +01:00
orangemug
d80d76724c Fixed more lint errors. 2018-05-17 11:46:33 +01:00
orangemug
77da0a6d30 React v16.3.0 fixes. 2018-05-17 11:24:39 +01:00
orangemug
79b251d8b9 DRY up the code. 2018-05-17 10:55:55 +01:00
orangemug
4f19f6a08c Added support for encoding to raster-dem source, enabling terrarium tiles. 2018-05-17 10:44:54 +01:00
Orange Mug
d2a6eab1e6 Merge pull request #291 from orangemug/feature/circle-ci-osx-builds
CircleCI OSX builds
2018-05-11 15:50:48 +01:00
Orange Mug
c7cf051502 Merge pull request #296 from orangemug/feature/prefers-reduced-motion
Added prefers-reduced-motion support
2018-05-11 15:50:08 +01:00
Orange Mug
6e21503e6b Merge pull request #297 from orangemug/accessibility/larger-color-swatch
Make color swatch larger so its easier to see
2018-05-11 15:49:32 +01:00
orangemug
78d71a4e7e Fixed duplicate definition. 2018-05-11 14:53:06 +01:00
orangemug
b8f32d46cf Rename <CollapseReducedMotion/> to <Collapse/> 2018-05-11 14:03:46 +01:00
Orange Mug
443782decf Merge pull request #300 from orangemug/accessibility/react-aria-modal
Added accessible modal via react-aria-modal
2018-05-11 13:54:39 +01:00
orangemug
54e79e5eb8 Added missing data-wd-key attribute. 2018-05-11 11:26:43 +01:00
orangemug
221cd4ffd2 Added accessible modal via react-aria-modal 2018-05-11 10:56:34 +01:00
Orange Mug
354b2fb3cb Merge pull request #298 from orangemug/fix/keyboard-accessible-buttons
Made buttons keyboard accessible
2018-05-11 10:47:11 +01:00
orangemug
7cb2c36ac9 Move accessibility checks into module. 2018-05-11 09:32:57 +01:00
orangemug
11d73595fc Made buttons keyboard accessible. 2018-05-10 16:50:37 +01:00
orangemug
c241a6e280 Ignore 'prefers-reduced-motion' in stylelint 2018-05-10 16:30:23 +01:00
orangemug
198ff143f6 Make color swatch larger so its easier to see. 2018-05-10 16:18:13 +01:00
orangemug
7b8b797f9c Fixed typo. 2018-05-10 16:07:34 +01:00
orangemug
a41b25eea7 Added 'prefers-reduced-motion' css support. 2018-05-10 16:05:55 +01:00
Orange Mug
06eac68f9d Merge pull request #293 from orangemug/maintenance/update-deps-20180509
Updated deps
2018-05-10 08:33:18 +01:00
orangemug
8abf84ebc0 Updated deps. 2018-05-09 09:39:03 +01:00
orangemug
e9aa1f6dd6 Fixed typo 2018-05-08 17:34:09 +01:00
orangemug
8e7b838bf7 Altered versions for node.js release schedule
See <https://github.com/nodejs/Release>
2018-05-08 17:30:42 +01:00
orangemug
32db3c3c9b Added build-osx-node-v9 to CircleCI 2018-05-08 17:23:03 +01:00
orangemug
502586e5d5 1.2.0 2018-05-08 16:11:13 +01:00
Orange Mug
d92d599d8a Merge pull request #290 from orangemug/fix/disable-gist
Disable gist export
2018-05-08 15:55:23 +01:00
orangemug
3487056c7d Disable gist, see <https://github.com/maputnik/editor/issues/269> 2018-05-08 15:21:14 +01:00
orangemug
dbcfb08c15 1.2.0-beta2 2018-04-20 15:31:00 +01:00
Orange Mug
e96141090e Merge pull request #287 from orangemug/fix/beta-version-wrapping
Fix to allow beta version strings to not wrap
2018-04-20 15:27:48 +01:00
orangemug
5bd25fc2ed Fix to allow beta version strings to not wrap. 2018-04-20 15:09:37 +01:00
orangemug
45bdf53a41 Added thunderforest maputnik token. 2018-04-11 16:20:23 +01:00
orangemug
00e94212bd Added initial thunderforest source integration 2018-04-11 15:53:40 +01:00
167 changed files with 1115 additions and 26738 deletions

View File

@@ -1,13 +0,0 @@
{
"presets": ["env", "react"],
"plugins": ["transform-object-rest-spread", "transform-class-properties"],
"env": {
"test": {
"plugins": [
["istanbul", {
exclude: ["node_modules/**", "test/**"]
}]
]
}
}
}

View File

@@ -1,84 +0,0 @@
version: 2
templates:
# Test the build **only** no webdriver
build-steps: &build-steps
- checkout
- run:
name: "Create artifacts directory"
command: mkdir /tmp/artifacts
- restore_cache:
key: v1-dependencies-{{ checksum "package.json" }}
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run: mkdir -p /tmp/artifacts/logs
- run: npm run build
- run: npm run lint
- run: npm run lint-styles
- store_artifacts:
path: /tmp/artifacts
destination: /artifacts
# Test in webdriver
wdio-steps: &wdio-steps
- checkout
- run:
name: "Create artifacts directory"
command: mkdir /tmp/artifacts
- restore_cache:
key: v1-dependencies-{{ checksum "package.json" }}
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run: mkdir -p /tmp/artifacts/logs
- run: npm run build
- run: npm run lint
- run: npm run lint-styles
- run: DOCKER_HOST=localhost npm test
- run: ./node_modules/.bin/istanbul report --include /tmp/artifacts/coverage/coverage.json --dir /tmp/artifacts/coverage html lcov
- store_artifacts:
path: /tmp/artifacts
destination: /artifacts
jobs:
build-linux-node-v6:
docker:
- image: node:6
working_directory: ~/repo-linux-node-v6
steps: *build-steps
build-linux-node-v8:
docker:
- image: node:8
- image: selenium/standalone-chrome:3.8.1
working_directory: ~/repo-linux-node-v8
steps: *wdio-steps
build-linux-node-v9:
docker:
- image: node:9
working_directory: ~/repo-linux-node-v9
steps: *build-steps
build-osx-node-v9:
macos:
xcode: "9.0"
dependencies:
override:
- brew install node@9
working_directory: ~/repo-linux-node-v9
steps: *build-steps
workflows:
version: 2
build:
jobs:
- build-linux-node-v6
- build-linux-node-v8
- build-linux-node-v9

View File

@@ -1,14 +0,0 @@
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,jsx,html,sass}]
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

35
.gitignore vendored
View File

@@ -1,35 +0,0 @@
# Logs
logs
*.log
*.swp
*.swo
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# Ignore build files
public
/errorShots
/old
/build

View File

@@ -1,22 +0,0 @@
language: node_js
matrix:
include:
- os: osx
node_js: "6"
- os: osx
node_js: "8"
- os: osx
node_js: "9"
install:
- npm install
script:
- mkdir public
- node --stack_size=100000 $(which npm) run build
- npm run lint
- npm run lint-styles
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

View File

@@ -1,15 +0,0 @@
FROM nodesource/xenial:6.1.0
EXPOSE 8888
ENV HOME /maputnik
RUN mkdir ${HOME}
COPY . ${HOME}/
WORKDIR ${HOME}
RUN npm install -d --dev
RUN npm run build
CMD npm run start -- --host 0.0.0.0

22
LICENSE
View File

@@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Lukas Martinelli
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

162
README.md
View File

@@ -1,162 +0,0 @@
# Maputnik
[![Build Status](https://travis-ci.org/maputnik/editor.svg?branch=master)][travis]
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/anelbgv6jdb3qnh9/branch/master?svg=true)][appveyor]
[![Dependency Status](https://david-dm.org/maputnik/editor.svg)][dm-prod]
[![Dev Dependency Status](https://david-dm.org/maputnik/editor/dev-status.svg)][dm-dev]
[![License](https://img.shields.io/badge/license-MIT-blue.svg)][license]
[travis]: https://travis-ci.org/maputnik/editor
[appveyor]: https://ci.appveyor.com/project/lukasmartinelli/editor
[dm-prod]: https://david-dm.org/maputnik/editor
[dm-dev]: https://david-dm.org/maputnik/editor#info=devDependencies
[license]: https://tldrlegal.com/license/mit-license
<img width="200" align="right" alt="Maputnik" src="src/img/maputnik.png" />
A free and open visual editor for the [Mapbox GL styles](https://www.mapbox.com/mapbox-gl-style-spec/)
targeted at developers and map designers.
- :link: Design your maps online at **<https://maputnik.github.io/editor/>** (all in local storage)
- :link: Use the [Maputnik CLI](https://github.com/maputnik/editor/wiki/Maputnik-CLI) for local style development
Mapbox has built one of the best and most amazing OSS ecosystems. A key component to ensure its longevity and independance is an OSS map designer.
## Documentation
The documentation can be found in the [Wiki](https://github.com/maputnik/editor/wiki). You are welcome to collaborate!
- :link: **Study the [Maputnik Wiki](https://github.com/maputnik/editor/wiki)**
- :video_camera: Design a map from Scratch https://youtu.be/XoDh0gEnBQo
[![Design Map from Scratch](https://j.gifs.com/g5XMgl.gif)](https://youtu.be/XoDh0gEnBQo)
## Develop
Maputnik is written in ES6 and is using [React](https://github.com/facebook/react) and [Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api/).
We ensure building and developing Maputnik works with
- Linux, OSX and Windows
- Node >4
Install the deps, start the dev server and open the web browser on `http://localhost:8888/`.
```bash
# install dependencies
npm install
# start dev server
npm start
```
The build process will watch for changes to the filesystem, rebuild and autoreload the editor. However note this from the webpack-dev-server docs
> webpack uses the file system to get notified of file changes. In some cases this does not work. For example, when using Network File System (NFS). Vagrant also has a lot of problems with this.
Snippet from <https://webpack.js.org/configuration/dev-server/#devserver-watchoptions->
To enable polling add `export WEBPACK_DEV_SERVER_POLLING=1` to your enviroment.
```
npm run build
```
Lint the JavaScript code.
```
# run linter
npm run lint
npm run lint-styles
```
## Tests
For testing we use [webdriverio](http://webdriver.io) and [selenium-standalone](https://github.com/vvo/selenium-standalone)
[selenium-standalone](https://github.com/vvo/selenium-standalone) starts a server that will launch browsers on your local machine. We use chrome so you **must** have chrome installed on your machine.
Now open and terminal and run the following. This will install the drivers on your local machine
```
./node_modules/.bin/selenium-standalone install
```
Now start the standalone server
```
./node_modules/.bin/selenium-standalone start
```
Then open another terminal and run
```
npm test
```
After some time you should see a browser launch which will be automated by the test runner.
## Related Projects
- [maputnik-dev-server](https://github.com/nycplanning/labs-maputnik-dev-server) - An express.js server that allows for quickly loading the style from any mapboxGL map into mapuntnik.
## Sponsors
Thanks to the supporters of the **[Kickstarter campaign](https://www.kickstarter.com/projects/174808720/maputnik-visual-map-editor-for-mapbox-gl)**. This project would not be possible without these commercial and individual sponsors.
### Gold
- [Wemap](https://getwemap.com/)
- [Orbicon Informatik](https://www.orbiconinformatik.dk/)
- [Terranodo](http://terranodo.io/)
<a href="https://getwemap.com/">
<img width="33%" alt="Wemap" style="display:inline" src="media/sponsors/wemap.jpg" />
</a>
<a href="http://terranodo.io/">
<img width="33%" alt="Terranodo" style="display:inline" src="media/sponsors/terranodo.png" />
</a>
<a href="https://www.orbiconinformatik.dk/">
<img width="32%" alt="Terranodo" style="display:inline" src="media/sponsors/orbicon_informatik.png" />
</a>
<br/>
### Silver
- [Klokan Technologies](https://www.klokantech.com/)
- [Geofabrik](http://www.geofabrik.de/)
- [Dreipol](https://www.dreipol.ch/)
<a href="https://www.klokantech.com/">
<img width="18%" alt="Klokan Technologies" style="display:inline-block" src="media/sponsors/klokantech.png" />
</a>
<a href="http://www.geofabrik.de/">
<img width="18%" alt="Geofabrik" style="display:inline-block" src="media/sponsors/geofabrik.png" />
</a>
<a href="https://www.dreipol.ch/">
<img width="18%" alt="Dreipol" style="display:inline-block" src="media/sponsors/dreipol.png" />
</a>
<br/>
### Individuals
**Influential Stakeholder**
Alan McConchie, Odi, Mats Norén, Uli [geOps](http://geops.ch/), Helge Fahrnberger ([Toursprung](http://www.toursprung.com/)), Kirusanth Poopalasingam
**Stakeholder**
Brian Flood, Vasile Coțovanu, Andreas Kalkbrenner, Christian Mäder, Gregor Wassmann, Lee Armstrong, Rafel, Jon Burgess, Lukas Lehmann, Joachim Ungar, Alois Ackermann, Zsolt Ero, Jordan Meek
**Supporter**
Sina Martinelli, Nicholas Doiron, Neil Cawse, Urs42, Benedikt Groß, Manuel Roth, Janko Mihelić, Moritz Stefaner, Sebastian Ahoi, Juerg Uhlmann, Tom Wider, Nadia Panchaud, Oliver Snowden, Stephan Heuel, Tobin Bradley, Adrian Herzog, Antti Lehto, Pascal Mages, Marc Gehling, Imre Samu, Lauri K., Visahavel Parthasarathy, Christophe Waterlot-Buisine, Max Galka, ubahnverleih, Wouter van Dam, Jakob Lobensteiner, Samuel Kurath, Brian Bancroft
## License
Maputnik is [licensed under MIT](LICENSE) and is Copyright (c) Lukas Martinelli and contributors.
**Disclaimer** This project is not affiliated with Mapbox or Mapbox Studio. It is a independent style editor for the
open source technology in the Mapbox GL ecosystem.
As contributor please take extra care of not violating any Mapbox trademarks. Do not get inspired by Mapbox Studio and make your own decisions for a good style editor.

View File

@@ -1,17 +0,0 @@
environment:
matrix:
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "9"
platform:
- x86
- x64
install:
- ps: Install-Product node $env:nodejs_version
- md public
- npm install --global --production windows-build-tools
- npm install
build_script:
- npm run build
test_script:
- npm run lint

View File

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

962
assets/index-DtxAbt8L.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-BhJ-ufwk.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-BrzYPxJn.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-CQD4fuPu.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-CZ64AJ8H.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-XoriI0W-.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"translation-aD1CAGoy.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

View File

@@ -1,62 +0,0 @@
var webpack = require("webpack");
var WebpackDevServer = require("webpack-dev-server");
var webpackConfig = require("./webpack.config");
var testConfig = require("../test/config/specs");
var artifacts = require("../test/artifacts");
var isDocker = require("is-docker");
var server;
var SCREENSHOT_PATH = artifacts.pathSync("screenshots");
exports.config = {
specs: [
'./test/functional/index.js'
],
exclude: [
],
maxInstances: 10,
capabilities: [{
maxInstances: 5,
browserName: 'chrome'
}],
sync: true,
logLevel: 'verbose',
coloredLogs: true,
bail: 0,
screenshotPath: SCREENSHOT_PATH,
// Note: This is here because @orangemug currently runs Maputnik inside a docker container.
host: process.env.DOCKER_HOST || "0.0.0.0",
baseUrl: 'http://localhost',
waitforTimeout: 10000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
framework: 'mocha',
reporters: ['spec'],
mochaOpts: {
ui: 'bdd',
// Because we don't know how long the initial build will take...
timeout: 4*60*1000
},
onPrepare: function (config, capabilities) {
return new Promise(function(resolve, reject) {
var compiler = webpack(webpackConfig);
server = new WebpackDevServer(compiler, {
stats: {
colors: true
}
});
server.listen(testConfig.port, (isDocker() ? "0.0.0.0" : "localhost"), function(err) {
if(err) {
reject(err);
}
else {
resolve();
}
});
})
},
onComplete: function(exitCode) {
server.close()
}
}

View File

@@ -1,70 +0,0 @@
"use strict";
var webpack = require('webpack');
var path = require('path');
var loaders = require('./webpack.loaders');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
const HOST = process.env.HOST || "127.0.0.1";
const PORT = process.env.PORT || "8888";
module.exports = {
target: 'web',
entry: [
`webpack-dev-server/client?http://${HOST}:${PORT}`,
`webpack/hot/only-dev-server`,
`./src/index.jsx` // Your appʼs entry point
],
devtool: process.env.WEBPACK_DEVTOOL || 'cheap-module-source-map',
output: {
path: path.join(__dirname, '..', 'public'),
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
noParse: [
/mapbox-gl\/dist\/mapbox-gl.js/
],
loaders: loaders
},
node: {
fs: "empty",
net: 'empty',
tls: 'empty'
},
devServer: {
contentBase: "./public",
// do not print bundle build stats
noInfo: true,
// enable HMR
hot: true,
// embed the webpack-dev-server runtime into the bundle
inline: true,
// serve index.html in place of 404 responses to allow HTML5 history
historyApiFallback: true,
port: PORT,
host: HOST,
watchOptions: {
// Disabled polling by default as it causes lots of CPU usage and hence drains laptop batteries. To enable polling add WEBPACK_DEV_SERVER_POLLING to your environment
// See <https://webpack.js.org/configuration/watch/#watchoptions-poll> for details
poll: (!!process.env.WEBPACK_DEV_SERVER_POLLING ? true : false),
watch: false
}
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
title: 'Maputnik',
template: './src/template.html'
}),
new CopyWebpackPlugin([
{
from: './src/manifest.json',
to: 'manifest.json'
}
])
]
};

View File

@@ -1,55 +0,0 @@
module.exports = [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components|public)/,
loaders: ['react-hot-loader/webpack']
},
// HACK: This is a massive hack and reaches into the mapbox-gl private API.
// We have to include this for access to `normalizeSourceURL`. We should
// remove this ASAP, see <https://github.com/mapbox/mapbox-gl-js/issues/2416>
{
test: /.*node_modules[\/\\]mapbox-gl[\/\\]src[\/\\]util[\/\\].*\.js/,
loader: 'babel-loader',
query: {
presets: ['env', 'react', 'flow'],
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties'],
}
},
{
test: /\.jsx?$/,
// Note: These modules aren't ES5 therefore we much compile them.
exclude: /(.*node_modules(?![\/\\](@mapbox[\/\\]mapbox-gl-style-spec|ol|mapbox-to-ol-style))|bower_components|public)/,
loader: 'babel-loader',
query: {
presets: ['env', 'react'],
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties'],
}
},
{
test: /\.(eot|ttf|woff|woff2)$/,
loader: 'file-loader?name=fonts/[name].[ext]'
},
{
test: /\.ico$/,
loader: 'file-loader?name=[name].[ext]'
},
{
test: /\.(svg|gif|jpg|png)$/,
loader: 'file-loader?name=img/[name].[ext]'
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /[\/\\](node_modules|global|src)[\/\\].*\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /[\/\\](node_modules|global|src)[\/\\].*\.css$/,
loaders: [
'style-loader?sourceMap',
'css-loader'
]
}
];

View File

@@ -1,88 +0,0 @@
var webpack = require('webpack');
var path = require('path');
var loaders = require('./webpack.loaders');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var CopyWebpackPlugin = require('copy-webpack-plugin');
var artifacts = require("../test/artifacts");
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
var OUTPATH = artifacts.pathSync("/build");
module.exports = {
entry: {
app: './src/index.jsx',
vendor: [
'file-saver',
'mapbox-gl/dist/mapbox-gl.js',
"lodash.clonedeep",
"lodash.throttle",
'color',
'react',
"react-dom",
"react-color",
"react-file-reader-input",
"react-collapse",
"react-height",
"react-icon-base",
"react-motion",
"react-sortable-hoc",
"request",
//TODO: Icons raise multi vendor errors?
//"react-icons",
]
},
output: {
path: OUTPATH,
filename: '[name].[chunkhash].js',
chunkFilename: '[chunkhash].js'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
noParse: [
/mapbox-gl\/dist\/mapbox-gl.js/
],
loaders
},
node: {
fs: "empty",
net: 'empty',
tls: 'empty'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: '[chunkhash].vendor.js' }),
new WebpackCleanupPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new UglifyJsPlugin(),
new ExtractTextPlugin('[contenthash].css', {
allChunks: true
}),
new HtmlWebpackPlugin({
template: './src/template.html',
title: 'Maputnik'
}),
new CopyWebpackPlugin([
{
from: './src/manifest.json',
to: 'manifest.json'
}
]),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
defaultSizes: 'gzip',
openAnalyzer: false,
generateStatsFile: true,
reportFilename: 'bundle-stats.html',
statsFilename: 'bundle-stats.json',
})
]
};

133
index.html Normal file
View File

@@ -0,0 +1,133 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Maputnik</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="/maputnik/assets/manifest-BrZzkYP9.json">
<link rel="icon" href="/maputnik/assets/favicon-DBn6BKLx.ico" type="image/x-icon" />
<style>
html {
background-color: rgb(28, 31, 36);
}
.loading {
text-align: center;
position: absolute;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.loading__logo img {
width: 200px;
height: 200px;
}
.loading__text {
font-family: sans-serif;
color: white;
font-size: 1.2em;
padding-bottom: 2em;
}
</style>
<script type="module" crossorigin src="/maputnik/assets/index-DtxAbt8L.js"></script>
<link rel="stylesheet" crossorigin href="/maputnik/assets/index-CuVViU0P.css">
</head>
<body>
<!-- From <https://github.com/hail2u/color-blindness-emulation> -->
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
version="1.1">
<defs>
<filter id="protanopia">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.567, 0.433, 0, 0, 0
0.558, 0.442, 0, 0, 0
0, 0.242, 0.758, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="protanomaly">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.817, 0.183, 0, 0, 0
0.333, 0.667, 0, 0, 0
0, 0.125, 0.875, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="deuteranopia">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.625, 0.375, 0, 0, 0
0.7, 0.3, 0, 0, 0
0, 0.3, 0.7, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="deuteranomaly">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.8, 0.2, 0, 0, 0
0.258, 0.742, 0, 0, 0
0, 0.142, 0.858, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="tritanopia">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.95, 0.05, 0, 0, 0
0, 0.433, 0.567, 0, 0
0, 0.475, 0.525, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="tritanomaly">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.967, 0.033, 0, 0, 0
0, 0.733, 0.267, 0, 0
0, 0.183, 0.817, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="achromatopsia">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.299, 0.587, 0.114, 0, 0
0.299, 0.587, 0.114, 0, 0
0.299, 0.587, 0.114, 0, 0
0, 0, 0, 1, 0"/>
</filter>
<filter id="achromatomaly">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0.618, 0.320, 0.062, 0, 0
0.163, 0.775, 0.062, 0, 0
0.163, 0.320, 0.516, 0, 0
0, 0, 0, 1, 0"/>
</filter>
</defs>
</svg>
<div id="app"></div>
<div class="loading">
<div class="loading__logo">
<img inline src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='1200'%20height='1200'%20viewBox='0%200%20100%20100'%3e%3cstyle%3e@keyframes%20circle-anim{0%25,40%25{fill-opacity:0}60%25,to{fill-opacity:1}}.circle0,.circle1,.circle2,.circle3,.circle4,.circle5{stroke-opacity:0;animation-name:circle-anim;will-change:transform;animation-timing-function:east-in-out;animation-duration:800ms;animation-iteration-count:infinite;animation-direction:alternate}.circle0{animation-delay:100ms}.circle1{animation-delay:200ms}.circle2{animation-delay:300ms}.circle3{animation-delay:400ms}.circle4{animation-delay:500ms}.circle5{animation-delay:600ms}%3c/style%3e%3cg%20class='map'%20stroke='%23000'%3e%3cuse%20xlink:href='%23ref-1--map__main'%20fill='%234eba6f'%3e%3c/use%3e%3cuse%20xlink:href='%23ref-1--map__line1'%20fill='none'%3e%3c/use%3e%3cuse%20xlink:href='%23ref-1--map__line2'%20fill='none'%3e%3c/use%3e%3cuse%20xlink:href='%23ref-1--map__line3'%20fill='none'%3e%3c/use%3e%3c/g%3e%3cg%20class='palette'%3e%3cuse%20xlink:href='%23ref-1--palette__main'%20fill='%23fff'%20stroke='%23000'%3e%3c/use%3e%3cuse%20xlink:href='%23ref-1--palette__inner'%20fill='none'%20stroke='%23000'%3e%3c/use%3e%3cuse%20class='circle5'%20xlink:href='%23ref-1--palette__circle5'%20fill='%23f7c44c'%3e%3c/use%3e%3cuse%20class='circle4'%20xlink:href='%23ref-1--palette__circle4'%20fill='%234eba6f'%3e%3c/use%3e%3cuse%20class='circle3'%20xlink:href='%23ref-1--palette__circle3'%20fill='%23f7c44c'%3e%3c/use%3e%3cuse%20class='circle2'%20xlink:href='%23ref-1--palette__circle2'%20fill='%234eba6f'%3e%3c/use%3e%3cuse%20class='circle1'%20xlink:href='%23ref-1--palette__circle1'%20fill='%23f7c44c'%3e%3c/use%3e%3cuse%20class='circle0'%20xlink:href='%23ref-1--palette__circle0'%20fill='%234eba6f'%3e%3c/use%3e%3c/g%3e%3cg%20class='brush'%20stroke='%23000'%3e%3cuse%20xlink:href='%23ref-1--brush__bottom'%20fill='%23f7c44c'%3e%3c/use%3e%3cuse%20xlink:href='%23ref-1--brush__top'%20fill='%23fff'%3e%3c/use%3e%3c/g%3e%3cdefs%3e%3cpath%20id='ref-1--map__main'%20stroke-width='2.366'%20stroke-linejoin='round'%20d='M18.84%207.717l15.44%207.542%2015.75-7.762%2015.7%207.857L81.005%207.67%2096.31%2054.052%2073.598%2062.12%2050.93%2053.872l-25.1%208.066-22.668-8.066z'%3e%3c/path%3e%3cpath%20id='ref-1--map__line1'%20d='M65.556%2015.07l7.647%2046.838'%20stroke-width='1.104'%3e%3c/path%3e%3cpath%20id='ref-1--map__line2'%20d='M50.261%207.422l.717%2046.6'%20stroke-width='1.104'%3e%3c/path%3e%3cpath%20id='ref-1--map__line3'%20d='M34.011%2015.07l-8.603%2046.6'%20stroke-width='1.104'%3e%3c/path%3e%3cpath%20id='ref-1--palette__main'%20stroke-width='2.3'%20d='M47.352%2030.887c7.993.226%2016.934%209.725%2017.954%2015.25%201.02%205.527-.743%2011.125-4.298%2013.875-3.554%202.75-8.6%202.905-8.723%208.302-.097%204.237%208.457%208.5%208.088%2015.653-.406%207.857-15.508%2013.15-30.943%206.102-8.556-3.906-14.249-13.653-13.385-26.238C16.833%2052.334%2022.32%2043.658%2027.382%2039c5.977-5.503%2011.977-8.337%2019.97-8.112z'%3e%3c/path%3e%3ccircle%20id='ref-1--palette__inner'%20stroke-width='2.3'%20cx='41.873'%20cy='61.901'%20r='6.389'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle5'%20cy='44.56'%20cx='54.347'%20r='4.336'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle4'%20cx='40.443'%20cy='41.555'%20r='4.336'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle3'%20r='4.336'%20cy='51.102'%20cx='29.651'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle2'%20cx='25.293'%20cy='65.836'%20r='4.336'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle1'%20r='4.336'%20cy='79.326'%20cx='32.764'%3e%3c/circle%3e%3ccircle%20id='ref-1--palette__circle0'%20cx='46.669'%20cy='80.571'%20r='4.336'%3e%3c/circle%3e%3cpath%20id='ref-1--brush__bottom'%20d='M76.333%2089.333c-1.645-9.794-4.375-35.26-4.32-37.887.056-2.627%202.52-4.34%205.36-4.317%202.842.022%205.098%201.87%205.314%204.27.107%201.2-1.576%2028.06-2.318%2037.844-.332%204.374-3.31%204.413-4.036.09z'%20stroke-width='2.3'%20stroke-linejoin='round'%3e%3c/path%3e%3cpath%20id='ref-1--brush__top'%20stroke-linejoin='round'%20stroke-width='2.3'%20d='M77.184%2026.428s-5.621%207.02-5.621%2011.978c0%204.957%202.206%206.878%205.81%206.878%203.606%200%205.148-1.708%205.29-6.736.142-5.028-5.479-12.12-5.479-12.12z'%3e%3c/path%3e%3c/defs%3e%3c/svg%3e" />
</div>
<div class="loading__text">Loading&hellip;</div>
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

17021
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,148 +0,0 @@
{
"name": "maputnik",
"version": "1.2.0-beta",
"description": "A MapboxGL visual style editor",
"main": "''",
"scripts": {
"stats": "webpack --config config/webpack.production.config.js --profile --json > stats.json",
"build": "webpack --config config/webpack.production.config.js --progress --profile --colors",
"test": "cross-env NODE_ENV=test wdio config/wdio.conf.js",
"test-watch": "cross-env NODE_ENV=test wdio config/wdio.conf.js --watch",
"start": "webpack-dev-server --progress --profile --colors --config config/webpack.config.js",
"lint": "eslint --ext js --ext jsx {src,test}",
"lint-styles": "stylelint 'src/styles/*.scss'",
"nsp": "nsp check --reporter summary"
},
"repository": {
"type": "git",
"url": "https://github.com/maputnik/editor"
},
"author": "Lukas Martinelli",
"license": "MIT",
"homepage": "https://github.com/maputnik/editor#readme",
"dependencies": {
"@mapbox/mapbox-gl-rtl-text": "^0.1.1",
"@mapbox/mapbox-gl-style-spec": "^11.1.1",
"classnames": "^2.2.5",
"codemirror": "^5.36.0",
"color": "^3.0.0",
"file-saver": "^1.3.8",
"github-api": "^3.0.0",
"jsonlint": "github:josdejong/jsonlint#85a19d7",
"lodash.capitalize": "^4.2.1",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0",
"lodash.throttle": "^4.1.1",
"mapbox-gl": "^0.44.2",
"mapbox-gl-inspect": "^1.3.1",
"maputnik-design": "github:maputnik/design",
"mousetrap": "^1.6.1",
"ol-mapbox-style": "^2.10.1",
"ol": "^4.6.5",
"prop-types": "^15.6.0",
"react": "^16.3.2",
"react-addons-pure-render-mixin": "^15.6.2",
"react-autocomplete": "^1.7.2",
"react-codemirror2": "^4.2.1",
"react-collapse": "^4.0.3",
"react-color": "^2.14.1",
"react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.3.2",
"react-file-reader-input": "^1.1.4",
"react-height": "^3.0.0",
"react-icon-base": "^2.1.1",
"react-icons": "^2.2.7",
"react-motion": "^0.5.2",
"react-sortable-hoc": "^0.6.8",
"reconnecting-websocket": "^3.2.2",
"request": "^2.85.0",
"url": "^0.11.0"
},
"jshintConfig": {
"esversion": 6
},
"stylelint": {
"extends": "stylelint-config-recommended-scss",
"rules": {
"no-descending-specificity": null
}
},
"eslintConfig": {
"plugins": [
"react"
],
"extends": [
"plugin:react/recommended"
],
"env": {
"browser": true,
"node": true,
"es6": true
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"impliedStrict": true,
"experimentalObjectRestSpread": true,
"jsx": true
}
}
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.3",
"babel-loader": "7.1.4",
"babel-plugin-istanbul": "^4.1.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-react": "^6.24.1",
"babel-register": "^6.26.0",
"babel-runtime": "^6.26.0",
"base64-loader": "^1.0.0",
"copy-webpack-plugin": "^4.5.1",
"cors": "^2.8.4",
"cross-env": "^5.1.4",
"css-loader": "^0.28.11",
"eslint": "^4.19.1",
"eslint-plugin-react": "^7.4.0",
"express": "^4.16.3",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^3.2.0",
"is-docker": "^1.1.0",
"istanbul": "^0.4.5",
"istanbul-lib-coverage": "^1.2.0",
"json-loader": "^0.5.7",
"mkdirp": "^0.5.1",
"mocha": "^5.1.0",
"node-sass": "^4.8.3",
"nsp": "^3.1.0",
"react-hot-loader": "^3.1.1",
"sass-loader": "^7.0.1",
"selenium-standalone": "^6.14.0",
"style-loader": "^0.20.3",
"stylelint": "^9.2.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-scss": "^3.0.0",
"transform-loader": "^0.2.4",
"uglifyjs-webpack-plugin": "^1.2.4",
"uuid": "^3.1.0",
"wdio-mocha-framework": "^0.5.13",
"wdio-phantomjs-service": "^0.2.2",
"wdio-selenium-standalone-service": "0.0.10",
"wdio-spec-reporter": "^0.1.2",
"webdriverio": "^4.12.0",
"webpack": "^3.8.1",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-cleanup-plugin": "^0.5.1",
"webpack-dev-server": "^2.9.4"
}
}

View File

@@ -1,51 +0,0 @@
.cm-s-maputnik.CodeMirror {
height: 100%;
font-size: 12px;
}
.cm-s-maputnik.CodeMirror, .cm-s-maputnik .CodeMirror-gutters {
color: #8e8e8e;
border: none;
}
.cm-s-maputnik.CodeMirror {
background: transparent;
}
.cm-s-maputnik .CodeMirror-gutters {
background: #212328;
}
.cm-s-maputnik .CodeMirror-cursor {
border-left: solid thin #8e8e8e !important;
}
.cm-s-maputnik.CodeMirror-focused div.CodeMirror-selected {
background: rgba(255, 255, 255, 0.10);
}
.cm-s-maputnik .CodeMirror-line::selection,
.cm-s-maputnik .CodeMirror-line > span::selection,
.cm-s-maputnik .CodeMirror-line > span > span::selection {
background: rgba(255, 255, 255, 0.10);
}
.cm-s-maputnik .CodeMirror-line::-moz-selection,
.cm-s-maputnik .CodeMirror-line > span::-moz-selection,
.cm-s-maputnik .CodeMirror-line > span > span::-moz-selection {
background: rgba(255, 255, 255, 0.10);
}
.cm-s-maputnik span.cm-string, .cm-s-maputnik span.cm-string-2 {
color: #8f9d6a;
}
.cm-s-maputnik span.cm-number { color: #91675f; }
.cm-s-maputnik span.cm-property { color: #b8a077; }
.cm-s-maputnik .CodeMirror-activeline-background {
background: rgba(255,255,255,0.1);
}
.cm-s-maputnik .CodeMirror-matchingbracket {
text-decoration: underline; color: white !important;
}

View File

@@ -1,329 +0,0 @@
import React from 'react'
import Mousetrap from 'mousetrap'
import MapboxGlMap from './map/MapboxGlMap'
import OpenLayers3Map from './map/OpenLayers3Map'
import LayerList from './layers/LayerList'
import LayerEditor from './layers/LayerEditor'
import Toolbar from './Toolbar'
import AppLayout from './AppLayout'
import MessagePanel from './MessagePanel'
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import style from '../libs/style.js'
import { initialStyleUrl, loadStyleUrl } from '../libs/urlopen'
import { undoMessages, redoMessages } from '../libs/diffmessage'
import { loadDefaultStyle, StyleStore } from '../libs/stylestore'
import { ApiStyleStore } from '../libs/apistore'
import { RevisionStore } from '../libs/revisions'
import LayerWatcher from '../libs/layerwatcher'
import tokens from '../config/tokens.json'
import isEqual from 'lodash.isequal'
import Debug from '../libs/debug'
import MapboxGl from 'mapbox-gl'
import mapboxUtil from 'mapbox-gl/src/util/mapbox'
function updateRootSpec(spec, fieldName, newValues) {
return {
...spec,
$root: {
...spec.$root,
[fieldName]: {
...spec.$root[fieldName],
values: newValues
}
}
}
}
export default class App extends React.Component {
constructor(props) {
super(props)
this.revisionStore = new RevisionStore()
this.styleStore = new ApiStyleStore({
onLocalStyleChange: mapStyle => this.onStyleChanged(mapStyle, false)
})
const styleUrl = initialStyleUrl()
if(styleUrl) {
this.styleStore = new StyleStore()
loadStyleUrl(styleUrl, mapStyle => this.onStyleChanged(mapStyle))
} else {
this.styleStore.init(err => {
if(err) {
console.log('Falling back to local storage for storing styles')
this.styleStore = new StyleStore()
}
this.styleStore.latestStyle(mapStyle => this.onStyleChanged(mapStyle))
if(Debug.enabled()) {
Debug.set("maputnik", "styleStore", this.styleStore);
Debug.set("maputnik", "revisionStore", this.revisionStore);
}
})
}
if(Debug.enabled()) {
Debug.set("maputnik", "revisionStore", this.revisionStore);
Debug.set("maputnik", "styleStore", this.styleStore);
}
this.state = {
errors: [],
infos: [],
mapStyle: style.emptyStyle,
selectedLayerIndex: 0,
sources: {},
vectorLayers: {},
inspectModeEnabled: false,
spec: styleSpec.latest,
}
this.layerWatcher = new LayerWatcher({
onVectorLayersChange: v => this.setState({ vectorLayers: v })
})
}
componentDidMount() {
Mousetrap.bind(['mod+z'], this.onUndo.bind(this));
Mousetrap.bind(['mod+y', 'mod+shift+z'], this.onRedo.bind(this));
}
componentWillUnmount() {
Mousetrap.unbind(['mod+z'], this.onUndo.bind(this));
Mousetrap.unbind(['mod+y', 'mod+shift+z'], this.onRedo.bind(this));
}
saveStyle(snapshotStyle) {
this.styleStore.save(snapshotStyle)
}
updateFonts(urlTemplate) {
const metadata = this.state.mapStyle.metadata || {}
const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles
let glyphUrl = (typeof urlTemplate === 'string')? urlTemplate.replace('{key}', accessToken): urlTemplate;
downloadGlyphsMetadata(glyphUrl, fonts => {
this.setState({ spec: updateRootSpec(this.state.spec, 'glyphs', fonts)})
})
}
updateIcons(baseUrl) {
downloadSpriteMetadata(baseUrl, icons => {
this.setState({ spec: updateRootSpec(this.state.spec, 'sprite', icons)})
})
}
onStyleChanged(newStyle, save=true) {
const errors = styleSpec.validate(newStyle, styleSpec.latest)
if(errors.length === 0) {
if(newStyle.glyphs !== this.state.mapStyle.glyphs) {
this.updateFonts(newStyle.glyphs)
}
if(newStyle.sprite !== this.state.mapStyle.sprite) {
this.updateIcons(newStyle.sprite)
}
this.revisionStore.addRevision(newStyle)
if(save) this.saveStyle(newStyle)
this.setState({
mapStyle: newStyle,
errors: [],
})
} else {
this.setState({
errors: errors.map(err => err.message)
})
}
this.fetchSources();
}
onUndo() {
const activeStyle = this.revisionStore.undo()
const messages = undoMessages(this.state.mapStyle, activeStyle)
this.saveStyle(activeStyle)
this.setState({
mapStyle: activeStyle,
infos: messages,
})
}
onRedo() {
const activeStyle = this.revisionStore.redo()
const messages = redoMessages(this.state.mapStyle, activeStyle)
this.saveStyle(activeStyle)
this.setState({
mapStyle: activeStyle,
infos: messages,
})
}
onLayersChange(changedLayers) {
const changedStyle = {
...this.state.mapStyle,
layers: changedLayers
}
this.onStyleChanged(changedStyle)
}
onLayerIdChange(oldId, newId) {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, oldId)
changedLayers[idx] = {
...changedLayers[idx],
id: newId
}
this.onLayersChange(changedLayers)
}
onLayerChanged(layer) {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layer.id)
changedLayers[idx] = layer
this.onLayersChange(changedLayers)
}
changeInspectMode() {
this.setState({
inspectModeEnabled: !this.state.inspectModeEnabled
})
}
fetchSources() {
const sourceList = {...this.state.sources};
for(let [key, val] of Object.entries(this.state.mapStyle.sources)) {
if(sourceList.hasOwnProperty(key)) {
continue;
}
sourceList[key] = {
type: val.type,
layers: []
};
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector" && val.hasOwnProperty("url")) {
let url = val.url;
try {
url = mapboxUtil.normalizeSourceURL(url, MapboxGl.accessToken);
} catch(err) {
console.warn("Failed to normalizeSourceURL: ", err);
}
fetch(url)
.then((response) => {
return response.json();
})
.then((json) => {
if(!json.hasOwnProperty("vector_layers")) {
return;
}
// Create new objects before setState
const sources = Object.assign({}, this.state.sources);
for(let layer of json.vector_layers) {
sources[key].layers.push(layer.id)
}
console.debug("Updating source: "+key);
this.setState({
sources: sources
});
})
.catch((err) => {
console.error("Failed to process sources for '%s'", url, err);
})
}
}
if(!isEqual(this.state.sources, sourceList)) {
console.debug("Setting sources");
this.setState({
sources: sourceList
})
}
}
mapRenderer() {
const mapProps = {
mapStyle: style.replaceAccessToken(this.state.mapStyle, {allowFallback: true}),
onDataChange: (e) => {
this.layerWatcher.analyzeMap(e.map)
this.fetchSources();
},
}
const metadata = this.state.mapStyle.metadata || {}
const renderer = metadata['maputnik:renderer'] || 'mbgljs'
// Check if OL3 code has been loaded?
if(renderer === 'ol3') {
return <OpenLayers3Map {...mapProps} />
} else {
return <MapboxGlMap {...mapProps}
inspectModeEnabled={this.state.inspectModeEnabled}
highlightedLayer={this.state.mapStyle.layers[this.state.selectedLayerIndex]}
onLayerSelect={this.onLayerSelect.bind(this)} />
}
}
onLayerSelect(layerId) {
const idx = style.indexOfLayer(this.state.mapStyle.layers, layerId)
this.setState({ selectedLayerIndex: idx })
}
render() {
const layers = this.state.mapStyle.layers || []
const selectedLayer = layers.length > 0 ? layers[this.state.selectedLayerIndex] : null
const metadata = this.state.mapStyle.metadata || {}
const toolbar = <Toolbar
mapStyle={this.state.mapStyle}
inspectModeEnabled={this.state.inspectModeEnabled}
sources={this.state.sources}
onStyleChanged={this.onStyleChanged.bind(this)}
onStyleOpen={this.onStyleChanged.bind(this)}
onInspectModeToggle={this.changeInspectMode.bind(this)}
/>
const layerList = <LayerList
onLayersChange={this.onLayersChange.bind(this)}
onLayerSelect={this.onLayerSelect.bind(this)}
selectedLayerIndex={this.state.selectedLayerIndex}
layers={layers}
sources={this.state.sources}
/>
const layerEditor = selectedLayer ? <LayerEditor
layer={selectedLayer}
sources={this.state.sources}
vectorLayers={this.state.vectorLayers}
spec={this.state.spec}
onLayerChanged={this.onLayerChanged.bind(this)}
onLayerIdChange={this.onLayerIdChange.bind(this)}
/> : null
const bottomPanel = (this.state.errors.length + this.state.infos.length) > 0 ? <MessagePanel
errors={this.state.errors}
infos={this.state.infos}
/> : null
return <AppLayout
toolbar={toolbar}
layerList={layerList}
layerEditor={layerEditor}
map={this.mapRenderer()}
bottom={bottomPanel}
/>
}
}

View File

@@ -1,46 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import ScrollContainer from './ScrollContainer'
class AppLayout extends React.Component {
static propTypes = {
toolbar: PropTypes.element.isRequired,
layerList: PropTypes.element.isRequired,
layerEditor: PropTypes.element,
map: PropTypes.element.isRequired,
bottom: PropTypes.element,
}
static childContextTypes = {
reactIconBase: PropTypes.object
}
getChildContext() {
return {
reactIconBase: { size: 14 }
}
}
render() {
return <div className="maputnik-layout">
{this.props.toolbar}
<div className="maputnik-layout-list">
<ScrollContainer>
{this.props.layerList}
</ScrollContainer>
</div>
<div className="maputnik-layout-drawer">
<ScrollContainer>
{this.props.layerEditor}
</ScrollContainer>
</div>
{this.props.map}
{this.props.bottom && <div className="maputnik-layout-bottom">
{this.props.bottom}
</div>
}
</div>
}
}
export default AppLayout

View File

@@ -1,25 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
class Button extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
onClick: PropTypes.func,
style: PropTypes.object,
className: PropTypes.string,
children: PropTypes.node
}
render() {
return <a
onClick={this.props.onClick}
className={classnames("maputnik-button", this.props.className)}
data-wd-key={this.props["data-wd-key"]}
style={this.props.style}>
{this.props.children}
</a>
}
}
export default Button

View File

@@ -1,27 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class MessagePanel extends React.Component {
static propTypes = {
errors: PropTypes.array,
infos: PropTypes.array,
}
render() {
const errors = this.props.errors.map((m, i) => {
return <p key={"error-"+i} className="maputnik-message-panel-error">{m}</p>
})
const infos = this.props.infos.map((m, i) => {
return <p key={"info-"+i}>{m}</p>
})
return <div className="maputnik-message-panel">
{errors}
{infos}
</div>
}
}
export default MessagePanel

View File

@@ -1,16 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class ScrollContainer extends React.Component {
static propTypes = {
children: PropTypes.node
}
render() {
return <div className="maputnik-scroll-container">
{this.props.children}
</div>
}
}
export default ScrollContainer

View File

@@ -1,178 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import FileReaderInput from 'react-file-reader-input'
import classnames from 'classnames'
import MdFileDownload from 'react-icons/lib/md/file-download'
import MdFileUpload from 'react-icons/lib/md/file-upload'
import OpenIcon from 'react-icons/lib/md/open-in-browser'
import SettingsIcon from 'react-icons/lib/md/settings'
import MdInfo from 'react-icons/lib/md/info'
import SourcesIcon from 'react-icons/lib/md/layers'
import MdSave from 'react-icons/lib/md/save'
import MdStyle from 'react-icons/lib/md/style'
import MdMap from 'react-icons/lib/md/map'
import MdInsertEmoticon from 'react-icons/lib/md/insert-emoticon'
import MdFontDownload from 'react-icons/lib/md/font-download'
import HelpIcon from 'react-icons/lib/md/help-outline'
import InspectionIcon from 'react-icons/lib/md/find-in-page'
import logoImage from 'maputnik-design/logos/logo-color.svg'
import SettingsModal from './modals/SettingsModal'
import ExportModal from './modals/ExportModal'
import SourcesModal from './modals/SourcesModal'
import OpenModal from './modals/OpenModal'
import pkgJson from '../../package.json'
import style from '../libs/style'
class IconText extends React.Component {
static propTypes = {
children: PropTypes.node,
}
render() {
return <span className="maputnik-icon-text">{this.props.children}</span>
}
}
class ToolbarLink extends React.Component {
static propTypes = {
className: PropTypes.string,
children: PropTypes.node,
href: PropTypes.string,
}
render() {
return <a
className={classnames('maputnik-toolbar-link', this.props.className)}
href={this.props.href}
rel="noopener noreferrer"
target="_blank"
>
{this.props.children}
</a>
}
}
class ToolbarAction extends React.Component {
static propTypes = {
children: PropTypes.node,
onClick: PropTypes.func,
wdKey: PropTypes.string
}
render() {
return <a
className='maputnik-toolbar-action'
data-wd-key={this.props.wdKey}
onClick={this.props.onClick}
>
{this.props.children}
</a>
}
}
export default class Toolbar extends React.Component {
static propTypes = {
mapStyle: PropTypes.object.isRequired,
inspectModeEnabled: PropTypes.bool.isRequired,
onStyleChanged: PropTypes.func.isRequired,
// A new style has been uploaded
onStyleOpen: PropTypes.func.isRequired,
// A dict of source id's and the available source layers
sources: PropTypes.object.isRequired,
onInspectModeToggle: PropTypes.func.isRequired,
children: PropTypes.node
}
constructor(props) {
super(props)
this.state = {
isOpen: {
settings: false,
sources: false,
open: false,
add: false,
export: false,
}
}
}
toggleModal(modalName) {
this.setState({
isOpen: {
...this.state.isOpen,
[modalName]: !this.state.isOpen[modalName]
}
})
}
render() {
return <div className='maputnik-toolbar'>
<SettingsModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.settings}
onOpenToggle={this.toggleModal.bind(this, 'settings')}
/>
<ExportModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.export}
onOpenToggle={this.toggleModal.bind(this, 'export')}
/>
<OpenModal
isOpen={this.state.isOpen.open}
onStyleOpen={this.props.onStyleOpen}
onOpenToggle={this.toggleModal.bind(this, 'open')}
/>
<SourcesModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.sources}
onOpenToggle={this.toggleModal.bind(this, 'sources')}
/>
<div className="maputnik-toolbar__inner">
<ToolbarLink
href={"https://github.com/maputnik/editor"}
className="maputnik-toolbar-logo"
>
<img src={logoImage} alt="Maputnik" />
<h1>Maputnik
<span className="maputnik-toolbar-version">v{pkgJson.version}</span>
</h1>
</ToolbarLink>
<div className="maputnik-toolbar__actions">
<ToolbarAction wdKey="nav:open" onClick={this.toggleModal.bind(this, 'open')}>
<OpenIcon />
<IconText>Open</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:export" onClick={this.toggleModal.bind(this, 'export')}>
<MdFileDownload />
<IconText>Export</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:sources" onClick={this.toggleModal.bind(this, 'sources')}>
<SourcesIcon />
<IconText>Sources</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:settings" onClick={this.toggleModal.bind(this, 'settings')}>
<SettingsIcon />
<IconText>Style Settings</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:inspect" onClick={this.props.onInspectModeToggle}>
<InspectionIcon />
<IconText>
{ this.props.inspectModeEnabled && <span>Map Mode</span> }
{ !this.props.inspectModeEnabled && <span>Inspect Mode</span> }
</IconText>
</ToolbarAction>
<ToolbarLink href={"https://github.com/maputnik/editor/wiki"}>
<HelpIcon />
<IconText>Help</IconText>
</ToolbarLink>
</div>
</div>
</div>
}
}

View File

@@ -1,121 +0,0 @@
import React from 'react'
import Color from 'color'
import ChromePicker from 'react-color/lib/components/chrome/Chrome'
import PropTypes from 'prop-types'
function formatColor(color) {
const rgb = color.rgb
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${rgb.a})`
}
/*** Number fields with support for min, max and units and documentation*/
class ColorField extends React.Component {
static propTypes = {
onChange: PropTypes.func.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.string,
doc: PropTypes.string,
style: PropTypes.object,
default: PropTypes.string,
}
constructor(props) {
super(props)
this.state = {
pickerOpened: false,
}
}
//TODO: I much rather would do this with absolute positioning
//but I am too stupid to get it to work together with fixed position
//and scrollbars so I have to fallback to JavaScript
calcPickerOffset() {
const elem = this.colorInput
if(elem) {
const pos = elem.getBoundingClientRect()
return {
top: pos.top,
left: pos.left + 196,
}
} else {
return {
top: 160,
left: 555,
}
}
}
togglePicker() {
this.setState({ pickerOpened: !this.state.pickerOpened })
}
get color() {
// Catch invalid color.
try {
return Color(this.props.value).rgb()
}
catch(err) {
console.warn("Error parsing color: ", err);
return Color("rgb(255,255,255)");
}
}
render() {
const offset = this.calcPickerOffset()
var currentColor = this.color.object()
currentColor = {
r: currentColor.r,
g: currentColor.g,
b: currentColor.b,
// Rename alpha -> a for ChromePicker
a: currentColor.alpha
}
const picker = <div
className="maputnik-color-picker-offset"
style={{
position: 'fixed',
zIndex: 1,
left: offset.left,
top: offset.top,
}}>
<ChromePicker
color={currentColor}
onChange={c => this.props.onChange(formatColor(c))}
/>
<div
className="maputnik-color-picker-offset"
onClick={this.togglePicker.bind(this)}
style={{
zIndex: -1,
position: 'fixed',
top: '0px',
right: '0px',
bottom: '0px',
left: '0px',
}}
/>
</div>
var swatchStyle = {
backgroundColor: this.props.value
};
return <div className="maputnik-color-wrapper">
{this.state.pickerOpened && picker}
<div className="maputnik-color-swatch" style={swatchStyle}></div>
<input
className="maputnik-color"
ref={(input) => this.colorInput = input}
onClick={this.togglePicker.bind(this)}
style={this.props.style}
name={this.props.name}
placeholder={this.props.default}
value={this.props.value ? this.props.value : ""}
onChange={(e) => this.props.onChange(e.target.value)}
/>
</div>
}
}
export default ColorField

View File

@@ -1,23 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
export default class DocLabel extends React.Component {
static propTypes = {
label: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string
]).isRequired,
doc: PropTypes.string.isRequired,
}
render() {
return <label className="maputnik-doc-wrapper">
<div className="maputnik-doc-target">
<span>{this.props.label}</span>
<div className="maputnik-doc-popup">
{this.props.doc}
</div>
</div >
</label>
}
}

View File

@@ -1,139 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import SpecProperty from './_SpecProperty'
import DataProperty from './_DataProperty'
import ZoomProperty from './_ZoomProperty'
function isZoomField(value) {
return typeof value === 'object' && value.stops && typeof value.property === 'undefined'
}
function isDataField(value) {
return typeof value === 'object' && value.stops && typeof value.property !== 'undefined'
}
/** Supports displaying spec field for zoom function objects
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
*/
export default class FunctionSpecProperty extends React.Component {
static propTypes = {
onChange: PropTypes.func.isRequired,
fieldName: PropTypes.string.isRequired,
fieldSpec: PropTypes.object.isRequired,
value: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.number,
PropTypes.bool,
PropTypes.array
]),
}
addStop() {
const stops = this.props.value.stops.slice(0)
const lastStop = stops[stops.length - 1]
if (typeof lastStop[0] === "object") {
stops.push([
{zoom: lastStop[0].zoom + 1, value: lastStop[0].value},
lastStop[1]
])
}
else {
stops.push([lastStop[0] + 1, lastStop[1]])
}
const changedValue = {
...this.props.value,
stops: stops,
}
this.props.onChange(this.props.fieldName, changedValue)
}
deleteStop(stopIdx) {
const stops = this.props.value.stops.slice(0)
stops.splice(stopIdx, 1)
let changedValue = {
...this.props.value,
stops: stops,
}
if(stops.length === 1) {
changedValue = stops[0][1]
}
this.props.onChange(this.props.fieldName, changedValue)
}
makeZoomFunction() {
const zoomFunc = {
stops: [
[6, this.props.value],
[10, this.props.value]
]
}
this.props.onChange(this.props.fieldName, zoomFunc)
}
makeDataFunction() {
const dataFunc = {
property: "",
type: "categorical",
stops: [
[{zoom: 6, value: 0}, this.props.value],
[{zoom: 10, value: 0}, this.props.value]
]
}
this.props.onChange(this.props.fieldName, dataFunc)
}
render() {
const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property"
let specField;
if (isZoomField(this.props.value)) {
specField = (
<ZoomProperty
onChange={this.props.onChange.bind(this)}
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
onDeleteStop={this.deleteStop.bind(this)}
onAddStop={this.addStop.bind(this)}
/>
)
}
else if (isDataField(this.props.value)) {
specField = (
<DataProperty
onChange={this.props.onChange.bind(this)}
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
onDeleteStop={this.deleteStop.bind(this)}
onAddStop={this.addStop.bind(this)}
/>
)
}
else {
specField = (
<SpecProperty
onChange={this.props.onChange.bind(this)}
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
onZoomClick={this.makeZoomFunction.bind(this)}
onDataClick={this.makeDataFunction.bind(this)}
/>
)
}
return <div className={propClass} data-wd-key={"spec-field:"+this.props.fieldName}>
{specField}
</div>
}
}

View File

@@ -1,71 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import FunctionSpecField from './FunctionSpecField'
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
/** Extract field spec by {@fieldName} from the {@layerType} in the
* style specification from either the paint or layout group */
function getFieldSpec(spec, layerType, fieldName) {
const groupName = getGroupName(spec, layerType, fieldName)
const group = spec[groupName + '_' + layerType]
const fieldSpec = group[fieldName]
if(iconProperties.indexOf(fieldName) >= 0) {
return {
...fieldSpec,
values: spec.$root.sprite.values
}
}
if(fieldName === 'text-font') {
return {
...fieldSpec,
values: spec.$root.glyphs.values
}
}
return fieldSpec
}
function getGroupName(spec, layerType, fieldName) {
const paint = spec['paint_' + layerType] || {}
if (fieldName in paint) {
return 'paint'
} else {
return 'layout'
}
}
export default class PropertyGroup extends React.Component {
static propTypes = {
layer: PropTypes.object.isRequired,
groupFields: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
spec: PropTypes.object.isRequired,
}
onPropertyChange(property, newValue) {
const group = getGroupName(this.props.spec, this.props.layer.type, property)
this.props.onChange(group , property, newValue)
}
render() {
const fields = this.props.groupFields.map(fieldName => {
const fieldSpec = getFieldSpec(this.props.spec, this.props.layer.type, fieldName)
const paint = this.props.layer.paint || {}
const layout = this.props.layer.layout || {}
const fieldValue = fieldName in paint ? paint[fieldName] : layout[fieldName]
return <FunctionSpecField
onChange={this.onPropertyChange.bind(this)}
key={fieldName}
fieldName={fieldName}
value={fieldValue === undefined ? fieldSpec.default : fieldValue}
fieldSpec={fieldSpec}
/>
})
return <div className="maputnik-property-group">
{fields}
</div>
}
}

View File

@@ -1,136 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import color from 'color'
import ColorField from './ColorField'
import NumberInput from '../inputs/NumberInput'
import CheckboxInput from '../inputs/CheckboxInput'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
import MultiButtonInput from '../inputs/MultiButtonInput'
import ArrayInput from '../inputs/ArrayInput'
import DynamicArrayInput from '../inputs/DynamicArrayInput'
import FontInput from '../inputs/FontInput'
import IconInput from '../inputs/IconInput'
import capitalize from 'lodash.capitalize'
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
function labelFromFieldName(fieldName) {
let label = fieldName.split('-').slice(1).join(' ')
if(label.length > 0) {
label = label.charAt(0).toUpperCase() + label.slice(1);
}
return label
}
function optionsLabelLength(options) {
let sum = 0;
options.forEach(([_, label]) => {
sum += label.length
})
return sum
}
/** Display any field from the Mapbox GL style spec and
* choose the correct field component based on the @{fieldSpec}
* to display @{value}. */
export default class SpecField extends React.Component {
static propTypes = {
onChange: PropTypes.func.isRequired,
fieldName: PropTypes.string.isRequired,
fieldSpec: PropTypes.object.isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.array,
PropTypes.bool
]),
/** Override the style of the field */
style: PropTypes.object,
}
render() {
const commonProps = {
style: this.props.style,
value: this.props.value,
default: this.props.fieldSpec.default,
name: this.props.fieldName,
onChange: newValue => this.props.onChange(this.props.fieldName, newValue)
}
function childNodes() {
switch(this.props.fieldSpec.type) {
case 'number': return (
<NumberInput
{...commonProps}
min={this.props.fieldSpec.minimum}
max={this.props.fieldSpec.maximum}
/>
)
case 'enum':
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)])
if(options.length <= 3 && optionsLabelLength(options) <= 20) {
return <MultiButtonInput
{...commonProps}
options={options}
/>
} else {
return <SelectInput
{...commonProps}
options={options}
/>
}
case 'string':
if(iconProperties.indexOf(this.props.fieldName) >= 0) {
return <IconInput
{...commonProps}
icons={this.props.fieldSpec.values}
/>
} else {
return <StringInput
{...commonProps}
/>
}
case 'color': return (
<ColorField
{...commonProps}
/>
)
case 'boolean': return (
<CheckboxInput
{...commonProps}
/>
)
case 'array':
if(this.props.fieldName === 'text-font') {
return <FontInput
{...commonProps}
fonts={this.props.fieldSpec.values}
/>
} else {
if (this.props.fieldSpec.length) {
return <ArrayInput
{...commonProps}
type={this.props.fieldSpec.value}
length={this.props.fieldSpec.length}
/>
} else {
return <DynamicArrayInput
{...commonProps}
type={this.props.fieldSpec.value}
/>
}
}
default: return null
}
}
return (
<div data-wd-key={"spec-field:"+this.props.fieldName}>
{childNodes.call(this)}
</div>
);
}
}

View File

@@ -1,182 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
import SpecField from './SpecField'
import NumberInput from '../inputs/NumberInput'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
import DocLabel from './DocLabel'
import InputBlock from '../inputs/InputBlock'
import labelFromFieldName from './_labelFromFieldName'
import DeleteStopButton from './_DeleteStopButton'
export default class DataProperty extends React.Component {
static propTypes = {
onChange: PropTypes.func,
onDeleteStop: PropTypes.func,
onAddStop: PropTypes.func,
fieldName: PropTypes.string,
fieldSpec: PropTypes.object,
value: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.number,
PropTypes.bool,
PropTypes.array
]),
}
getFieldFunctionType(fieldSpec) {
if (fieldSpec.function === "interpolated") {
return "exponential"
}
if (fieldSpec.type === "number") {
return "interval"
}
return "categorical"
}
getDataFunctionTypes(functionType) {
if (functionType === "interpolated") {
return ["categorical", "interval", "exponential"]
}
else {
return ["categorical", "interval"]
}
}
changeStop(changeIdx, stopData, value) {
const stops = this.props.value.stops.slice(0)
const changedStop = stopData.zoom === undefined ? stopData.value : stopData
stops[changeIdx] = [changedStop, value]
const changedValue = {
...this.props.value,
stops: stops,
}
this.props.onChange(this.props.fieldName, changedValue)
}
changeDataProperty(propName, propVal) {
if (propVal) {
this.props.value[propName] = propVal
}
else {
delete this.props.value[propName]
}
this.props.onChange(this.props.fieldName, this.props.value)
}
render() {
if (typeof this.props.value.type === "undefined") {
this.props.value.type = this.getFieldFunctionType(this.props.fieldSpec)
}
const dataFields = this.props.value.stops.map((stop, idx) => {
const zoomLevel = typeof stop[0] === 'object' ? stop[0].zoom : undefined;
const dataLevel = typeof stop[0] === 'object' ? stop[0].value : stop[0];
const value = stop[1]
const deleteStopBtn = <DeleteStopButton onClick={this.props.onDeleteStop.bind(this, idx)} />
const dataProps = {
label: "Data value",
value: dataLevel,
onChange: newData => this.changeStop(idx, { zoom: zoomLevel, value: newData }, value)
}
let dataInput;
if(this.props.value.type === "categorical") {
dataInput = <StringInput {...dataProps} />
}
else {
dataInput = <NumberInput {...dataProps} />
}
let zoomInput = null;
if(zoomLevel !== undefined) {
zoomInput = <div className="maputnik-data-spec-property-stop-edit">
<NumberInput
value={zoomLevel}
onChange={newZoom => this.changeStop(idx, {zoom: newZoom, value: dataLevel}, value)}
min={0}
max={22}
/>
</div>
}
return <InputBlock key={idx} action={deleteStopBtn} label="">
{zoomInput}
<div className="maputnik-data-spec-property-stop-data">
{dataInput}
</div>
<div className="maputnik-data-spec-property-stop-value">
<SpecField
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={value}
onChange={(_, newValue) => this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)}
/>
</div>
</InputBlock>
})
return <div className="maputnik-data-spec-block">
<div className="maputnik-data-spec-property">
<InputBlock
doc={this.props.fieldSpec.doc}
label={labelFromFieldName(this.props.fieldName)}
>
<div className="maputnik-data-spec-property-group">
<DocLabel
label="Property"
doc={"Input a data property to base styles off of."}
/>
<div className="maputnik-data-spec-property-input">
<StringInput
value={this.props.value.property}
onChange={propVal => this.changeDataProperty("property", propVal)}
/>
</div>
</div>
<div className="maputnik-data-spec-property-group">
<DocLabel
label="Type"
doc={"Select a type of data scale (default is 'categorical')."}
/>
<div className="maputnik-data-spec-property-input">
<SelectInput
value={this.props.value.type}
onChange={propVal => this.changeDataProperty("type", propVal)}
options={this.getDataFunctionTypes(this.props.fieldSpec.function)}
/>
</div>
</div>
<div className="maputnik-data-spec-property-group">
<DocLabel
label="Default"
doc={"Input a default value for data if not covered by the scales."}
/>
<div className="maputnik-data-spec-property-input">
<SpecField
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value.default}
onChange={(_, propVal) => this.changeDataProperty("default", propVal)}
/>
</div>
</div>
</InputBlock>
</div>
{dataFields}
<Button
className="maputnik-add-stop"
onClick={this.props.onAddStop.bind(this)}
>
Add stop
</Button>
</div>
}
}

View File

@@ -1,25 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import DocLabel from './DocLabel'
import Button from '../Button'
import DeleteIcon from 'react-icons/lib/md/delete'
export default class DeleteStopButton extends React.Component {
static propTypes = {
onClick: PropTypes.func,
}
render() {
return <Button
className="maputnik-delete-stop"
onClick={this.props.onClick}
>
<DocLabel
label={<DeleteIcon />}
doc={"Remove zoom level stop."}
/>
</Button>
}
}

View File

@@ -1,49 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import DocLabel from './DocLabel'
import Button from '../Button'
import FunctionIcon from 'react-icons/lib/md/functions'
import MdInsertChart from 'react-icons/lib/md/insert-chart'
export default class FunctionButtons extends React.Component {
static propTypes = {
fieldSpec: PropTypes.object,
onZoomClick: PropTypes.func,
onDataClick: PropTypes.func,
}
render() {
let makeZoomButton, makeDataButton
if (this.props.fieldSpec['zoom-function']) {
makeZoomButton = <Button
className="maputnik-make-zoom-function"
onClick={this.props.onZoomClick}
>
<DocLabel
label={<FunctionIcon />}
cursorTargetStyle={{ cursor: 'pointer' }}
doc={"Turn property into a zoom function to enable a map feature to change with map's zoom level."}
/>
</Button>
if (this.props.fieldSpec['property-function'] && ['piecewise-constant', 'interpolated'].indexOf(this.props.fieldSpec['function']) !== -1) {
makeDataButton = <Button
className="maputnik-make-data-function"
onClick={this.props.onDataClick}
>
<DocLabel
label={<MdInsertChart />}
cursorTargetStyle={{ cursor: 'pointer' }}
doc={"Turn property into a data function to enable a map feature to change according to data properties and the map's zoom level."}
/>
</Button>
}
return <div>{makeDataButton}{makeZoomButton}</div>
}
else {
return null
}
}
}

View File

@@ -1,34 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import SpecField from './SpecField'
import FunctionButtons from './_FunctionButtons'
import InputBlock from '../inputs/InputBlock'
import labelFromFieldName from './_labelFromFieldName'
export default class SpecProperty extends React.Component {
static propTypes = {
onZoomClick: PropTypes.func.isRequired,
onDataClick: PropTypes.func.isRequired,
fieldName: PropTypes.string,
fieldSpec: PropTypes.object
}
render() {
const functionBtn = <FunctionButtons
fieldSpec={this.props.fieldSpec}
onZoomClick={this.props.onZoomClick}
onDataClick={this.props.onDataClick}
/>
return <InputBlock
doc={this.props.fieldSpec.doc}
label={labelFromFieldName(this.props.fieldName)}
action={functionBtn}
>
<SpecField {...this.props} />
</InputBlock>
}
}

View File

@@ -1,161 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
import SpecField from './SpecField'
import NumberInput from '../inputs/NumberInput'
import InputBlock from '../inputs/InputBlock'
import DeleteStopButton from './_DeleteStopButton'
import labelFromFieldName from './_labelFromFieldName'
import docUid from '../../libs/document-uid'
import sortNumerically from '../../libs/sort-numerically'
export default class ZoomProperty extends React.Component {
static propTypes = {
onChange: PropTypes.func,
onDeleteStop: PropTypes.func,
onAddStop: PropTypes.func,
fieldName: PropTypes.string,
fieldSpec: PropTypes.object,
value: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.number,
PropTypes.bool,
PropTypes.array
]),
}
constructor() {
super()
this.state = {
refs: {}
}
}
componentWillMount() {
this.setState({
refs: this.setStopRefs(this.props)
})
}
/**
* We cache a reference for each stop by its index.
*
* When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus.
*/
setStopRefs(props) {
// This is initialsed below only if required to improved performance.
let newRefs;
if(props.value && props.value.stops) {
props.value.stops.forEach((val, idx) => {
if(!this.state.refs.hasOwnProperty(idx)) {
if(!newRefs) {
newRefs = {...this.state.refs};
}
newRefs[idx] = docUid("stop-");
}
})
}
return newRefs;
}
componentWillReceiveProps(nextProps) {
const newRefs = this.setStopRefs(nextProps);
if(newRefs) {
this.setState({
refs: newRefs
})
}
}
// Order the stops altering the refs to reflect their new position.
orderStopsByZoom(stops) {
const mappedWithRef = stops
.map((stop, idx) => {
return {
ref: this.state.refs[idx],
data: stop
}
})
// Sort by zoom
.sort((a, b) => sortNumerically(a.data[0], b.data[0]));
// Fetch the new position of the stops
const newRefs = {};
mappedWithRef
.forEach((stop, idx) =>{
newRefs[idx] = stop.ref;
})
this.setState({
refs: newRefs
});
return mappedWithRef.map((item) => item.data);
}
changeZoomStop(changeIdx, stopData, value) {
const stops = this.props.value.stops.slice(0);
stops[changeIdx] = [stopData, value];
const orderedStops = this.orderStopsByZoom(stops);
const changedValue = {
...this.props.value,
stops: orderedStops
}
this.props.onChange(this.props.fieldName, changedValue)
}
render() {
const zoomFields = this.props.value.stops.map((stop, idx) => {
const zoomLevel = stop[0]
const key = this.state.refs[idx];
const value = stop[1]
const deleteStopBtn= <DeleteStopButton onClick={this.props.onDeleteStop.bind(this, idx)} />
return <InputBlock
key={key}
doc={this.props.fieldSpec.doc}
label={labelFromFieldName(this.props.fieldName)}
action={deleteStopBtn}
>
<div>
<div className="maputnik-zoom-spec-property-stop-edit">
<NumberInput
value={zoomLevel}
onChange={changedStop => this.changeZoomStop(idx, changedStop, value)}
min={0}
max={22}
/>
</div>
<div className="maputnik-zoom-spec-property-stop-value">
<SpecField
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={value}
onChange={(_, newValue) => this.changeZoomStop(idx, zoomLevel, newValue)}
/>
</div>
</div>
</InputBlock>
});
return <div className="maputnik-zoom-spec-property">
{zoomFields}
<Button
className="maputnik-add-stop"
onClick={this.props.onAddStop.bind(this)}
>
Add stop
</Button>
</div>
}
}

View File

@@ -1,6 +0,0 @@
import capitalize from 'lodash.capitalize'
export default function labelFromFieldName(fieldName) {
let label = fieldName.split('-').slice(1).join(' ')
return capitalize(label)
}

View File

@@ -1,114 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import { combiningFilterOps } from '../../libs/filterops.js'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import DocLabel from '../fields/DocLabel'
import SelectInput from '../inputs/SelectInput'
import SingleFilterEditor from './SingleFilterEditor'
import FilterEditorBlock from './FilterEditorBlock'
import Button from '../Button'
import DeleteIcon from 'react-icons/lib/md/delete'
import AddIcon from 'react-icons/lib/fa/plus'
function hasCombiningFilter(filter) {
return combiningFilterOps.indexOf(filter[0]) >= 0
}
function hasNestedCombiningFilter(filter) {
if(hasCombiningFilter(filter)) {
const combinedFilters = filter.slice(1)
return filter.slice(1).map(f => hasCombiningFilter(f)).filter(f => f == true).length > 0
}
return false
}
export default class CombiningFilterEditor extends React.Component {
static propTypes = {
/** Properties of the vector layer and the available fields */
properties: PropTypes.object,
filter: PropTypes.array,
onChange: PropTypes.func.isRequired,
}
// Convert filter to combining filter
combiningFilter() {
let filter = this.props.filter || ['all']
let combiningOp = filter[0]
let filters = filter.slice(1)
if(combiningFilterOps.indexOf(combiningOp) < 0) {
combiningOp = 'all'
filters = [filter.slice(0)]
}
return [combiningOp, ...filters]
}
onFilterPartChanged(filterIdx, newPart) {
const newFilter = this.combiningFilter().slice(0)
newFilter[filterIdx] = newPart
this.props.onChange(newFilter)
}
deleteFilterItem(filterIdx) {
const newFilter = this.combiningFilter().slice(0)
console.log('Delete', filterIdx, newFilter)
newFilter.splice(filterIdx + 1, 1)
this.props.onChange(newFilter)
}
addFilterItem() {
const newFilterItem = this.combiningFilter().slice(0)
newFilterItem.push(['==', 'name', ''])
this.props.onChange(newFilterItem)
}
render() {
const filter = this.combiningFilter()
let combiningOp = filter[0]
let filters = filter.slice(1)
const editorBlocks = filters.map((f, idx) => {
return <FilterEditorBlock key={idx} onDelete={this.deleteFilterItem.bind(this, idx)}>
<SingleFilterEditor
properties={this.props.properties}
filter={f}
onChange={this.onFilterPartChanged.bind(this, idx + 1)}
/>
</FilterEditorBlock>
})
//TODO: Implement support for nested filter
if(hasNestedCombiningFilter(filter)) {
return <div className="maputnik-filter-editor-unsupported">
Nested filters are not supported.
</div>
}
return <div className="maputnik-filter-editor">
<div className="maputnik-filter-editor-compound-select" data-wd-key="layer-filter">
<DocLabel
label={"Compound Filter"}
doc={styleSpec.latest.layer.filter.doc + " Combine multiple filters together by using a compound filter."}
/>
<SelectInput
value={combiningOp}
onChange={this.onFilterPartChanged.bind(this, 0)}
options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]}
/>
</div>
{editorBlocks}
<div className="maputnik-filter-editor-add-wrapper">
<Button
data-wd-key="layer-filter-button"
className="maputnik-add-filter"
onClick={this.addFilterItem.bind(this)}>
Add filter
</Button>
</div>
</div>
}
}

View File

@@ -1,29 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
import DeleteIcon from 'react-icons/lib/md/delete'
class FilterEditorBlock extends React.Component {
static propTypes = {
onDelete: PropTypes.func.isRequired,
children: PropTypes.element.isRequired,
}
render() {
return <div className="maputnik-filter-editor-block">
<div className="maputnik-filter-editor-block-action">
<Button
className="maputnik-delete-filter"
onClick={this.props.onDelete}
>
<DeleteIcon />
</Button>
</div>
<div className="maputnik-filter-editor-block-content">
{this.props.children}
</div>
</div>
}
}
export default FilterEditorBlock

View File

@@ -1,93 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import { otherFilterOps } from '../../libs/filterops.js'
import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
import SelectInput from '../inputs/SelectInput'
function tryParseInt(v) {
if (v === '') return v
if (isNaN(v)) return v
return parseFloat(v)
}
function tryParseBool(v) {
const isString = (typeof(v) === "string");
if(!isString) {
return v;
}
if(v.match(/^\s*true\s*$/)) {
return true;
}
else if(v.match(/^\s*false\s*$/)) {
return false;
}
else {
return v;
}
}
function parseFilter(v) {
v = tryParseInt(v);
v = tryParseBool(v);
return v;
}
class SingleFilterEditor extends React.Component {
static propTypes = {
filter: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
properties: PropTypes.object,
}
static defaultProps = {
properties: {},
}
onFilterPartChanged(filterOp, propertyName, filterArgs) {
let newFilter = [filterOp, propertyName, ...filterArgs.map(parseFilter)]
if(filterOp === 'has' || filterOp === '!has') {
newFilter = [filterOp, propertyName]
} else if(filterArgs.length === 0) {
newFilter = [filterOp, propertyName, '']
}
this.props.onChange(newFilter)
}
render() {
const f = this.props.filter
const filterOp = f[0]
const propertyName = f[1]
const filterArgs = f.slice(2)
return <div className="maputnik-filter-editor-single">
<div className="maputnik-filter-editor-property">
<AutocompleteInput
value={propertyName}
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
/>
</div>
<div className="maputnik-filter-editor-operator">
<SelectInput
value={filterOp}
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
options={otherFilterOps}
/>
</div>
{filterArgs.length > 0 &&
<div className="maputnik-filter-editor-args">
<StringInput
value={filterArgs.join(',')}
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
/>
</div>
}
</div>
}
}
export default SingleFilterEditor

View File

@@ -1,15 +0,0 @@
import React from 'react'
import IconBase from 'react-icon-base'
export default class BackgroundIcon extends React.Component {
render() {
return (
<IconBase viewBox="0 0 20 20" {...this.props}>
<path d="m 1.821019,10.255581 7.414535,5.020197 c 0.372277,0.25206 0.958697,0.239771 1.30985,-0.02745 L 17.539255,9.926162 C 17.89041,9.658941 17.873288,9.238006 17.501015,8.985946 L 10.08648,3.9657402 C 9.714204,3.7136802 9.127782,3.7259703 8.776627,3.9931918 L 1.782775,9.315365 c -0.3511551,0.267221 -0.3340331,0.688156 0.03824,0.940216 z" />
</IconBase>
)
}
}

View File

@@ -1,15 +0,0 @@
import React from 'react'
import IconBase from 'react-icon-base'
export default class FillIcon extends React.Component {
render() {
return (
<IconBase viewBox="0 0 20 20" {...this.props}>
<path transform="translate(2 2)" d="M7.5,0C11.6422,0,15,3.3578,15,7.5S11.6422,15,7.5,15 S0,11.6422,0,7.5S3.3578,0,7.5,0z M7.5,1.6666c-3.2217,0-5.8333,2.6117-5.8333,5.8334S4.2783,13.3334,7.5,13.3334 s5.8333-2.6117,5.8333-5.8334S10.7217,1.6666,7.5,1.6666z"></path>
</IconBase>
)
}
}

View File

@@ -1,15 +0,0 @@
import React from 'react'
import IconBase from 'react-icon-base'
export default class FillIcon extends React.Component {
render() {
return (
<IconBase viewBox="0 0 20 20" {...this.props}>
<path d="M 2.84978,9.763512 9.462149,4.7316391 16.47225,9.478015 9.859886,14.509879 2.84978,9.763512 m -1.028761,0.492069 7.414535,5.020197 c 0.372277,0.25206 0.958697,0.239771 1.30985,-0.02745 L 17.539255,9.926162 C 17.89041,9.658941 17.873288,9.238006 17.501015,8.985946 L 10.08648,3.9657402 C 9.714204,3.7136802 9.127782,3.7259703 8.776627,3.9931918 L 1.782775,9.315365 c -0.3511551,0.267221 -0.3340331,0.688156 0.03824,0.940216 l 0,0 z" />
</IconBase>
)
}
}

View File

@@ -1,32 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import LineIcon from './LineIcon.jsx'
import FillIcon from './FillIcon.jsx'
import SymbolIcon from './SymbolIcon.jsx'
import BackgroundIcon from './BackgroundIcon.jsx'
import CircleIcon from './CircleIcon.jsx'
class LayerIcon extends React.Component {
static propTypes = {
type: PropTypes.string.isRequired,
style: PropTypes.object,
}
render() {
const iconProps = { style: this.props.style }
switch(this.props.type) {
case 'fill-extrusion': return <BackgroundIcon {...iconProps} />
case 'raster': return <FillIcon {...iconProps} />
case 'hillshade': return <FillIcon {...iconProps} />
case 'heatmap': return <FillIcon {...iconProps} />
case 'fill': return <FillIcon {...iconProps} />
case 'background': return <BackgroundIcon {...iconProps} />
case 'line': return <LineIcon {...iconProps} />
case 'symbol': return <SymbolIcon {...iconProps} />
case 'circle': return <CircleIcon {...iconProps} />
}
}
}
export default LayerIcon

View File

@@ -1,15 +0,0 @@
import React from 'react'
import IconBase from 'react-icon-base'
export default class FillIcon extends React.Component {
render() {
return (
<IconBase viewBox="0 0 20 20" {...this.props}>
<path d="M 12.34,1.29 C 12.5114,1.1076 12.7497,1.0029 13,1 13.5523,1 14,1.4477 14,2 14.0047,2.2478 13.907,2.4866 13.73,2.66 9.785626,6.5516986 6.6148407,9.7551593 2.65,13.72 2.4793,13.8963 2.2453,13.9971 2,14 1.4477,14 1,13.5523 1,13 0.9953,12.7522 1.093,12.5134 1.27,12.34 4.9761967,8.7018093 9.0356422,4.5930579 12.34,1.29 Z" transform="translate(2,2)" />
</IconBase>
)
}
}

View File

@@ -1,18 +0,0 @@
import React from 'react'
import IconBase from 'react-icon-base'
export default class SymbolIcon extends React.Component {
render() {
return (
<IconBase viewBox="0 0 20 20" {...this.props}>
<g transform="matrix(1.2718518,0,0,1.2601269,16.559526,-7.4065264)">
<path d="m -9.7959773,11.060163 c -0.3734787,-0.724437 -0.3580577,-1.2147051 -0.00547,-1.8767873 l 8.6034029,-0.019416 c 0.39670292,0.6865644 0.38365934,1.4750693 -0.011097,1.8864953 l -3.1359613,-0.0033 -0.013695,7.1305 c -0.4055357,0.397083 -1.3146432,0.397083 -1.7769191,-0.02274 l 0.030226,-7.104422 z" />
</g>
</IconBase>
)
}
}

View File

@@ -1,49 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import StringInput from './StringInput'
import NumberInput from './NumberInput'
class ArrayInput extends React.Component {
static propTypes = {
value: PropTypes.array,
type: PropTypes.string,
length: PropTypes.number,
default: PropTypes.array,
onChange: PropTypes.func,
}
changeValue(idx, newValue) {
console.log(idx, newValue)
const values = this.values.slice(0)
values[idx] = newValue
this.props.onChange(values)
}
get values() {
return this.props.value || this.props.default || []
}
render() {
const inputs = this.values.map((v, i) => {
if(this.props.type === 'number') {
return <NumberInput
key={i}
value={v}
onChange={this.changeValue.bind(this, i)}
/>
} else {
return <StringInput
key={i}
value={v}
onChange={this.changeValue.bind(this, i)}
/>
}
})
return <div className="maputnik-array">
{inputs}
</div>
}
}
export default ArrayInput

View File

@@ -1,92 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Autocomplete from 'react-autocomplete'
const MAX_HEIGHT = 140;
class AutocompleteInput extends React.Component {
static propTypes = {
value: PropTypes.string,
options: PropTypes.array,
onChange: PropTypes.func,
keepMenuWithinWindowBounds: PropTypes.bool
}
static defaultProps = {
onChange: () => {},
options: [],
}
constructor(props) {
super(props);
this.state = {
maxHeight: MAX_HEIGHT
};
}
calcMaxHeight() {
if(this.props.keepMenuWithinWindowBounds) {
const maxHeight = window.innerHeight - this.autocompleteMenuEl.getBoundingClientRect().top;
const limitedMaxHeight = Math.min(maxHeight, MAX_HEIGHT);
if(limitedMaxHeight != this.state.maxHeight) {
this.setState({
maxHeight: limitedMaxHeight
})
}
}
}
componentDidMount() {
this.calcMaxHeight();
}
componentDidUpdate() {
this.calcMaxHeight();
}
render() {
return <div
ref={(el) => {
this.autocompleteMenuEl = el;
}}
>
<Autocomplete
menuStyle={{
position: "fixed",
overflow: "auto",
maxHeight: this.state.maxHeight
}}
wrapperProps={{
className: "maputnik-autocomplete",
style: null
}}
inputProps={{
className: "maputnik-string"
}}
value={this.props.value}
items={this.props.options}
getItemValue={(item) => item[0]}
onSelect={v => this.props.onChange(v)}
onChange={(e, v) => this.props.onChange(v)}
shouldItemRender={(item, value) => {
return item[0].toLowerCase().indexOf(value.toLowerCase()) > -1
}}
renderItem={(item, isHighlighted) => (
<div
key={item[0]}
className={classnames({
"maputnik-autocomplete-menu-item": true,
"maputnik-autocomplete-menu-item-selected": isHighlighted,
})}
>
{item[1]}
</div>
)}
/>
</div>
}
}
export default AutocompleteInput

View File

@@ -1,31 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class CheckboxInput extends React.Component {
static propTypes = {
value: PropTypes.bool.isRequired,
style: PropTypes.object,
onChange: PropTypes.func,
}
render() {
return <label className="maputnik-checkbox-wrapper">
<input
className="maputnik-checkbox"
type="checkbox"
style={this.props.style}
onChange={e => this.props.onChange(!this.props.value)}
checked={this.props.value}
/>
<div className="maputnik-checkbox-box">
<svg style={{
display: this.props.value ? 'inline' : 'none'
}} className="maputnik-checkbox-icon" viewBox='0 0 32 32'>
<path d='M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z' />
</svg>
</div>
</label>
}
}
export default CheckboxInput

View File

@@ -1,106 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import StringInput from './StringInput'
import NumberInput from './NumberInput'
import Button from '../Button'
import DeleteIcon from 'react-icons/lib/md/delete'
import DocLabel from '../fields/DocLabel'
class DynamicArrayInput extends React.Component {
static propTypes = {
value: PropTypes.array,
type: PropTypes.string,
default: PropTypes.array,
onChange: PropTypes.func,
style: PropTypes.object,
}
changeValue(idx, newValue) {
console.log(idx, newValue)
const values = this.values.slice(0)
values[idx] = newValue
this.props.onChange(values)
}
get values() {
return this.props.value || this.props.default || []
}
addValue() {
const values = this.values.slice(0)
if (this.props.type === 'number') {
values.push(0)
} else {
values.push("")
}
this.props.onChange(values)
}
deleteValue(valueIdx) {
const values = this.values.slice(0)
values.splice(valueIdx, 1)
this.props.onChange(values)
}
render() {
const inputs = this.values.map((v, i) => {
const deleteValueBtn= <DeleteValueButton onClick={this.deleteValue.bind(this, i)} />
const input = this.props.type === 'number'
? <NumberInput
value={v}
onChange={this.changeValue.bind(this, i)}
/>
: <StringInput
value={v}
onChange={this.changeValue.bind(this, i)}
/>
return <div
style={this.props.style}
key={i}
className="maputnik-array-block"
>
<div className="maputnik-array-block-action">
{deleteValueBtn}
</div>
<div className="maputnik-array-block-content">
{input}
</div>
</div>
})
return <div className="maputnik-array">
{inputs}
<Button
className="maputnik-array-add-value"
onClick={this.addValue.bind(this)}
>
Add value
</Button>
</div>
}
}
class DeleteValueButton extends React.Component {
static propTypes = {
onClick: PropTypes.func,
}
render() {
return <Button
className="maputnik-delete-stop"
onClick={this.props.onClick}
>
<DocLabel
label={<DeleteIcon />}
doc={"Remove array entry."}
/>
</Button>
}
}
export default DynamicArrayInput

View File

@@ -1,44 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import AutocompleteInput from './AutocompleteInput'
class FontInput extends React.Component {
static propTypes = {
value: PropTypes.array.isRequired,
default: PropTypes.array,
fonts: PropTypes.array,
style: PropTypes.object,
onChange: PropTypes.func.isRequired,
}
static defaultProps = {
fonts: []
}
get values() {
return this.props.value || this.props.default.slice(1) || []
}
changeFont(idx, newValue) {
const changedValues = this.values.slice(0)
changedValues[idx] = newValue
this.props.onChange(changedValues)
}
render() {
const inputs = this.values.map((value, i) => {
return <AutocompleteInput
key={i}
value={value}
options={this.props.fonts.map(f => [f, f])}
onChange={this.changeFont.bind(this, i)}
/>
})
return <div className="maputnik-font">
{inputs}
</div>
}
}
export default FontInput

View File

@@ -1,28 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import AutocompleteInput from './AutocompleteInput'
class IconInput extends React.Component {
static propTypes = {
value: PropTypes.array,
icons: PropTypes.array,
style: PropTypes.object,
onChange: PropTypes.func.isRequired,
}
static defaultProps = {
icons: []
}
render() {
return <AutocompleteInput
value={this.props.value}
options={this.props.icons.map(f => [f, f])}
onChange={this.props.onChange}
wrapperStyle={this.props.style}
/>
}
}
export default IconInput

View File

@@ -1,59 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import DocLabel from '../fields/DocLabel'
/** Wrap a component with a label */
class InputBlock extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
label: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
]).isRequired,
doc: PropTypes.string,
action: PropTypes.element,
children: PropTypes.node.isRequired,
style: PropTypes.object,
onChange: PropTypes.func,
}
onChange(e) {
const value = e.target.value
return this.props.onChange(value === "" ? null: value)
}
render() {
return <div style={this.props.style}
data-wd-key={this.props["data-wd-key"]}
className={classnames({
"maputnik-input-block": true,
"maputnik-action-block": this.props.action
})}
>
{this.props.doc &&
<div className="maputnik-input-block-label">
<DocLabel
label={this.props.label}
doc={this.props.doc}
/>
</div>
}
{!this.props.doc &&
<label className="maputnik-input-block-label">
{this.props.label}
</label>
}
{this.props.action &&
<div className="maputnik-input-block-action">
{this.props.action}
</div>
}
<div className="maputnik-input-block-content">
{this.props.children}
</div>
</div>
}
}
export default InputBlock

View File

@@ -1,36 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Button from '../Button'
class MultiButtonInput extends React.Component {
static propTypes = {
value: PropTypes.string.isRequired,
options: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
}
render() {
let options = this.props.options
if(options.length > 0 && !Array.isArray(options[0])) {
options = options.map(v => [v, v])
}
const selectedValue = this.props.value || options[0][0]
const buttons = options.map(([val, label])=> {
return <Button
key={val}
onClick={e => this.props.onChange(val)}
className={classnames({"maputnik-button-selected": val === selectedValue})}
>
{label}
</Button>
})
return <div className="maputnik-multibutton">
{buttons}
</div>
}
}
export default MultiButtonInput

View File

@@ -1,79 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class NumberInput extends React.Component {
static propTypes = {
value: PropTypes.number,
default: PropTypes.number,
min: PropTypes.number,
max: PropTypes.number,
onChange: PropTypes.func,
}
constructor(props) {
super(props)
this.state = {
value: props.value
}
}
componentWillReceiveProps(nextProps) {
this.setState({ value: nextProps.value })
}
changeValue(newValue) {
const value = parseFloat(newValue)
const hasChanged = this.state.value !== value
if(this.isValid(value) && hasChanged) {
this.props.onChange(value)
} else {
this.setState({ value: newValue })
}
}
isValid(v) {
const value = parseFloat(v)
if(isNaN(value)) {
return false
}
if(!isNaN(this.props.min) && value < this.props.min) {
return false
}
if(!isNaN(this.props.max) && value > this.props.max) {
return false
}
return true
}
resetValue() {
// Reset explicitly to default value if value has been cleared
if(this.state.value === "") {
return this.changeValue(this.props.default)
}
// If set value is invalid fall back to the last valid value from props or at last resort the default value
if(!this.isValid(this.state.value)) {
if(this.isValid(this.props.value)) {
this.changeValue(this.props.value)
} else {
this.changeValue(this.props.default)
}
}
}
render() {
return <input
className="maputnik-number"
placeholder={this.props.default}
value={this.state.value}
onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue.bind(this)}
/>
}
}
export default NumberInput

View File

@@ -1,32 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class SelectInput extends React.Component {
static propTypes = {
value: PropTypes.string.isRequired,
"data-wd-key": PropTypes.string.isRequired,
options: PropTypes.array.isRequired,
style: PropTypes.object,
onChange: PropTypes.func.isRequired,
}
render() {
let options = this.props.options
if(options.length > 0 && !Array.isArray(options[0])) {
options = options.map(v => [v, v])
}
return <select
className="maputnik-select"
data-wd-key={this.props["data-wd-key"]}
style={this.props.style}
value={this.props.value}
onChange={e => this.props.onChange(e.target.value)}
>
{ options.map(([val, label]) => <option key={val} value={val}>{label}</option>) }
</select>
}
}
export default SelectInput

View File

@@ -1,61 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
class StringInput extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
value: PropTypes.string,
style: PropTypes.object,
default: PropTypes.string,
onChange: PropTypes.func,
multi: PropTypes.bool,
}
constructor(props) {
super(props)
this.state = {
value: props.value || ''
}
}
componentWillReceiveProps(nextProps) {
this.setState({ value: nextProps.value || '' })
}
render() {
let tag;
let classes;
if(!!this.props.multi) {
tag = "textarea"
classes = [
"maputnik-string",
"maputnik-string--multi"
]
}
else {
tag = "input"
classes = [
"maputnik-string"
]
}
return React.createElement(tag, {
"data-wd-key": this.props["data-wd-key"],
className: classes.join(" "),
style: this.props.style,
value: this.state.value,
placeholder: this.props.default,
onChange: e => {
this.setState({
value: e.target.value
})
},
onBlur: () => {
if(this.state.value!==this.props.value) this.props.onChange(this.state.value)
}
});
}
}
export default StringInput

View File

@@ -1,21 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import CollapseOpenIcon from 'react-icons/lib/md/arrow-drop-down'
import CollapseCloseIcon from 'react-icons/lib/md/arrow-drop-up'
export default class Collapser extends React.Component {
static propTypes = {
isCollapsed: PropTypes.bool.isRequired,
style: PropTypes.object,
}
render() {
const iconStyle = {
width: 20,
height: 20,
...this.props.style,
}
return this.props.isCollapsed ? <CollapseCloseIcon style={iconStyle}/> : <CollapseOpenIcon style={iconStyle} />
}
}

View File

@@ -1,29 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
class MetadataBlock extends React.Component {
static propTypes = {
value: PropTypes.string,
onChange: PropTypes.func.isRequired,
}
render() {
return <InputBlock
label={"Comments"}
doc={"Comments for the current layer. This is non-standard and not in the spec."}
data-wd-key="layer-comment"
>
<StringInput
multi={true}
value={this.props.value}
onChange={this.props.onChange}
default="Comment..."
/>
</InputBlock>
}
}
export default MetadataBlock

View File

@@ -1,90 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import {Controlled as CodeMirror} from 'react-codemirror2'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import 'codemirror/mode/javascript/javascript'
import 'codemirror/addon/lint/lint'
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/lint/lint.css'
import '../../codemirror-maputnik.css'
import jsonlint from 'jsonlint'
// This is mainly because of this issue <https://github.com/zaach/jsonlint/issues/57> also the API has changed, see comment in file
import '../../vendor/codemirror/addon/lint/json-lint'
class JSONEditor extends React.Component {
static propTypes = {
layer: PropTypes.object.isRequired,
onChange: PropTypes.func,
}
constructor(props) {
super(props)
this.state = {
code: JSON.stringify(props.layer, null, 2)
}
}
componentWillReceiveProps(nextProps) {
this.setState({
code: JSON.stringify(nextProps.layer, null, 2)
})
}
shouldComponentUpdate(nextProps, nextState) {
try {
const parsedLayer = JSON.parse(this.state.code)
// If the structure is still the same do not update
// because it affects editing experience by reformatting all the time
return nextState.code !== JSON.stringify(parsedLayer, null, 2)
} catch(err) {
return true
}
}
onCodeUpdate(newCode) {
try {
const parsedLayer = JSON.parse(newCode)
this.props.onChange(parsedLayer)
} catch(err) {
console.warn(err)
} finally {
this.setState({
code: newCode
})
}
}
resetValue() {
console.log('reset')
this.setState({
code: JSON.stringify(this.props.layer, null, 2)
})
}
render() {
const codeMirrorOptions = {
mode: {name: "javascript", json: true},
tabSize: 2,
theme: 'maputnik',
viewportMargin: Infinity,
lineNumbers: true,
lint: true,
gutters: ["CodeMirror-lint-markers"],
scrollbarStyle: "null",
}
return <CodeMirror
value={this.state.code}
onBeforeChange={(editor, data, value) => this.onCodeUpdate(value)}
onFocusChange={focused => focused ? true : this.resetValue()}
options={codeMirrorOptions}
/>
}
}
export default JSONEditor

View File

@@ -1,200 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import JSONEditor from './JSONEditor'
import FilterEditor from '../filter/FilterEditor'
import PropertyGroup from '../fields/PropertyGroup'
import LayerEditorGroup from './LayerEditorGroup'
import LayerTypeBlock from './LayerTypeBlock'
import LayerIdBlock from './LayerIdBlock'
import MinZoomBlock from './MinZoomBlock'
import MaxZoomBlock from './MaxZoomBlock'
import CommentBlock from './CommentBlock'
import LayerSourceBlock from './LayerSourceBlock'
import LayerSourceLayerBlock from './LayerSourceLayerBlock'
import InputBlock from '../inputs/InputBlock'
import MultiButtonInput from '../inputs/MultiButtonInput'
import { changeType, changeProperty } from '../../libs/layer'
import layout from '../../config/layout.json'
function layoutGroups(layerType) {
const layerGroup = {
title: 'Layer',
type: 'layer'
}
const filterGroup = {
title: 'Filter',
type: 'filter'
}
const editorGroup = {
title: 'JSON Editor',
type: 'jsoneditor'
}
return [layerGroup, filterGroup].concat(layout[layerType].groups).concat([editorGroup])
}
/** Layer editor supporting multiple types of layers. */
export default class LayerEditor extends React.Component {
static propTypes = {
layer: PropTypes.object.isRequired,
sources: PropTypes.object,
vectorLayers: PropTypes.object,
spec: PropTypes.object.isRequired,
onLayerChanged: PropTypes.func,
onLayerIdChange: PropTypes.func,
}
static defaultProps = {
onLayerChanged: () => {},
onLayerIdChange: () => {},
onLayerDestroyed: () => {},
}
static childContextTypes = {
reactIconBase: PropTypes.object
}
constructor(props) {
super(props)
//TODO: Clean this up and refactor into function
const editorGroups = {}
layoutGroups(this.props.layer.type).forEach(group => {
editorGroups[group.title] = true
})
this.state = { editorGroups }
}
componentWillReceiveProps(nextProps) {
const additionalGroups = { ...this.state.editorGroups }
layout[nextProps.layer.type].groups.forEach(group => {
if(!(group.title in additionalGroups)) {
additionalGroups[group.title] = true
}
})
this.setState({
editorGroups: additionalGroups
})
}
getChildContext () {
return {
reactIconBase: {
size: 14,
color: '#8e8e8e',
}
}
}
changeProperty(group, property, newValue) {
this.props.onLayerChanged(changeProperty(this.props.layer, group, property, newValue))
}
onGroupToggle(groupTitle, active) {
const changedActiveGroups = {
...this.state.editorGroups,
[groupTitle]: active,
}
this.setState({
editorGroups: changedActiveGroups
})
}
renderGroupType(type, fields) {
let comment = ""
if(this.props.layer.metadata) {
comment = this.props.layer.metadata['maputnik:comment']
}
let sourceLayerIds;
if(this.props.sources.hasOwnProperty(this.props.layer.source)) {
sourceLayerIds = this.props.sources[this.props.layer.source].layers;
}
switch(type) {
case 'layer': return <div>
<LayerIdBlock
value={this.props.layer.id}
wdKey="layer-editor.layer-id"
onChange={newId => this.props.onLayerIdChange(this.props.layer.id, newId)}
/>
<LayerTypeBlock
value={this.props.layer.type}
onChange={newType => this.props.onLayerChanged(changeType(this.props.layer, newType))}
/>
{this.props.layer.type !== 'background' && <LayerSourceBlock
sourceIds={Object.keys(this.props.sources)}
value={this.props.layer.source}
onChange={v => this.changeProperty(null, 'source', v)}
/>
}
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
<LayerSourceLayerBlock
sourceLayerIds={sourceLayerIds}
value={this.props.layer['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)}
/>
}
<MinZoomBlock
value={this.props.layer.minzoom}
onChange={v => this.changeProperty(null, 'minzoom', v)}
/>
<MaxZoomBlock
value={this.props.layer.maxzoom}
onChange={v => this.changeProperty(null, 'maxzoom', v)}
/>
<CommentBlock
value={comment}
onChange={v => this.changeProperty('metadata', 'maputnik:comment', v == "" ? undefined : v)}
/>
</div>
case 'filter': return <div>
<div className="maputnik-filter-editor-wrapper">
<FilterEditor
filter={this.props.layer.filter}
properties={this.props.vectorLayers[this.props.layer['source-layer']]}
onChange={f => this.changeProperty(null, 'filter', f)}
/>
</div>
</div>
case 'properties': return <PropertyGroup
layer={this.props.layer}
groupFields={fields}
spec={this.props.spec}
onChange={this.changeProperty.bind(this)}
/>
case 'jsoneditor': return <JSONEditor
layer={this.props.layer}
onChange={this.props.onLayerChanged}
/>
}
}
render() {
const layerType = this.props.layer.type
const groups = layoutGroups(layerType).filter(group => {
return !(layerType === 'background' && group.type === 'source')
}).map(group => {
return <LayerEditorGroup
data-wd-key={group.title}
key={group.title}
title={group.title}
isActive={this.state.editorGroups[group.title]}
onActiveToggle={this.onGroupToggle.bind(this, group.title)}
>
{this.renderGroupType(group.type, group.fields)}
</LayerEditorGroup>
})
return <div className="maputnik-layer-editor"
>
{groups}
</div>
}
}

View File

@@ -1,32 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Collapse from 'react-collapse'
import Collapser from './Collapser'
export default class LayerEditorGroup extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
title: PropTypes.string.isRequired,
isActive: PropTypes.bool.isRequired,
children: PropTypes.element.isRequired,
onActiveToggle: PropTypes.func.isRequired
}
render() {
return <div>
<div className="maputnik-layer-editor-group"
data-wd-key={"layer-editor-group:"+this.props["data-wd-key"]}
onClick={e => this.props.onActiveToggle(!this.props.isActive)}
>
<span>{this.props.title}</span>
<span style={{flexGrow: 1}} />
<Collapser isCollapsed={this.props.isActive} />
</div>
<Collapse isOpened={this.props.isActive}>
<div className="react-collapse-container">
{this.props.children}
</div>
</Collapse>
</div>
}
}

View File

@@ -1,27 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
class LayerIdBlock extends React.Component {
static propTypes = {
value: PropTypes.string.isRequired,
wdKey: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"ID"} doc={styleSpec.latest.layer.id.doc}
data-wd-key={this.props.wdKey}
>
<StringInput
value={this.props.value}
onChange={this.props.onChange}
/>
</InputBlock>
}
}
export default LayerIdBlock

View File

@@ -1,254 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import cloneDeep from 'lodash.clonedeep'
import Button from '../Button'
import LayerListGroup from './LayerListGroup'
import LayerListItem from './LayerListItem'
import AddIcon from 'react-icons/lib/md/add-circle-outline'
import AddModal from '../modals/AddModal'
import style from '../../libs/style.js'
import {SortableContainer, SortableHandle, arrayMove} from 'react-sortable-hoc';
const layerListPropTypes = {
layers: PropTypes.array.isRequired,
selectedLayerIndex: PropTypes.number.isRequired,
onLayersChange: PropTypes.func.isRequired,
onLayerSelect: PropTypes.func,
sources: PropTypes.object.isRequired,
}
function layerPrefix(name) {
return name.replace(' ', '-').replace('_', '-').split('-')[0]
}
function findClosestCommonPrefix(layers, idx) {
const currentLayerPrefix = layerPrefix(layers[idx].id)
let closestIdx = idx
for (let i = idx; i > 0; i--) {
const previousLayerPrefix = layerPrefix(layers[i-1].id)
if(previousLayerPrefix === currentLayerPrefix) {
closestIdx = i - 1
} else {
return closestIdx
}
}
return closestIdx
}
// List of collapsible layer editors
@SortableContainer
class LayerListContainer extends React.Component {
static propTypes = {...layerListPropTypes}
static defaultProps = {
onLayerSelect: () => {},
}
constructor(props) {
super(props)
this.state = {
collapsedGroups: {},
areAllGroupsExpanded: false,
isOpen: {
add: false,
}
}
}
onLayerDestroy(layerId) {
const remainingLayers = this.props.layers.slice(0)
const idx = style.indexOfLayer(remainingLayers, layerId)
remainingLayers.splice(idx, 1);
this.props.onLayersChange(remainingLayers)
}
onLayerCopy(layerId) {
const changedLayers = this.props.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
const clonedLayer = cloneDeep(changedLayers[idx])
clonedLayer.id = clonedLayer.id + "-copy"
changedLayers.splice(idx, 0, clonedLayer)
this.props.onLayersChange(changedLayers)
}
onLayerVisibilityToggle(layerId) {
const changedLayers = this.props.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
const layer = { ...changedLayers[idx] }
const changedLayout = 'layout' in layer ? {...layer.layout} : {}
changedLayout.visibility = changedLayout.visibility === 'none' ? 'visible' : 'none'
layer.layout = changedLayout
changedLayers[idx] = layer
this.props.onLayersChange(changedLayers)
}
toggleModal(modalName) {
this.setState({
isOpen: {
...this.state.isOpen,
[modalName]: !this.state.isOpen[modalName]
}
})
}
toggleLayers() {
let idx=0
let newGroups=[]
this.groupedLayers().forEach(layers => {
const groupPrefix = layerPrefix(layers[0].id)
const lookupKey = [groupPrefix, idx].join('-')
if (layers.length > 1) {
newGroups[lookupKey] = this.state.areAllGroupsExpanded
}
layers.forEach((layer) => {
idx += 1
})
});
this.setState({
collapsedGroups: newGroups,
areAllGroupsExpanded: !this.state.areAllGroupsExpanded
})
}
groupedLayers() {
const groups = []
for (let i = 0; i < this.props.layers.length; i++) {
const previousLayer = this.props.layers[i-1]
const layer = this.props.layers[i]
if(previousLayer && layerPrefix(previousLayer.id) == layerPrefix(layer.id)) {
const lastGroup = groups[groups.length - 1]
lastGroup.push(layer)
} else {
groups.push([layer])
}
}
return groups
}
toggleLayerGroup(groupPrefix, idx) {
const lookupKey = [groupPrefix, idx].join('-')
const newGroups = { ...this.state.collapsedGroups }
if(lookupKey in this.state.collapsedGroups) {
newGroups[lookupKey] = !this.state.collapsedGroups[lookupKey]
} else {
newGroups[lookupKey] = false
}
this.setState({
collapsedGroups: newGroups
})
}
isCollapsed(groupPrefix, idx) {
const collapsed = this.state.collapsedGroups[[groupPrefix, idx].join('-')]
return collapsed === undefined ? true : collapsed
}
render() {
const listItems = []
let idx = 0
this.groupedLayers().forEach(layers => {
const groupPrefix = layerPrefix(layers[0].id)
if(layers.length > 1) {
const grp = <LayerListGroup
data-wd-key={[groupPrefix, idx].join('-')}
key={[groupPrefix, idx].join('-')}
title={groupPrefix}
isActive={!this.isCollapsed(groupPrefix, idx) || idx === this.props.selectedLayerIndex}
onActiveToggle={this.toggleLayerGroup.bind(this, groupPrefix, idx)}
/>
listItems.push(grp)
}
layers.forEach((layer, idxInGroup) => {
const groupIdx = findClosestCommonPrefix(this.props.layers, idx)
const listItem = <LayerListItem
className={classnames({
'maputnik-layer-list-item-collapsed': layers.length > 1 && this.isCollapsed(groupPrefix, groupIdx) && idx !== this.props.selectedLayerIndex,
'maputnik-layer-list-item-group-last': idxInGroup == layers.length - 1 && layers.length > 1
})}
index={idx}
key={layer.id}
layerId={layer.id}
layerType={layer.type}
visibility={(layer.layout || {}).visibility}
isSelected={idx === this.props.selectedLayerIndex}
onLayerSelect={this.props.onLayerSelect}
onLayerDestroy={this.onLayerDestroy.bind(this)}
onLayerCopy={this.onLayerCopy.bind(this)}
onLayerVisibilityToggle={this.onLayerVisibilityToggle.bind(this)}
/>
listItems.push(listItem)
idx += 1
})
})
return <div className="maputnik-layer-list">
<AddModal
layers={this.props.layers}
sources={this.props.sources}
isOpen={this.state.isOpen.add}
onOpenToggle={this.toggleModal.bind(this, 'add')}
onLayersChange={this.props.onLayersChange}
/>
<header className="maputnik-layer-list-header">
<span className="maputnik-layer-list-header-title">Layers</span>
<span className="maputnik-space" />
<div className="maputnik-default-property">
<div className="maputnik-multibutton">
<a
onClick={this.toggleLayers.bind(this)}
className="maputnik-button">
{this.state.areAllGroupsExpanded === true ? "Collapse" : "Expand"}
</a>
</div>
</div>
<div className="maputnik-default-property">
<div className="maputnik-multibutton">
<a
onClick={this.toggleModal.bind(this, 'add')}
data-wd-key="layer-list:add-layer"
className="maputnik-button maputnik-button-selected">
Add Layer
</a>
</div>
</div>
</header>
<ul className="maputnik-layer-list-container">
{listItems}
</ul>
</div>
}
}
export default class LayerList extends React.Component {
static propTypes = {...layerListPropTypes}
onSortEnd(move) {
const { oldIndex, newIndex } = move
if(oldIndex === newIndex) return
let layers = this.props.layers.slice(0)
layers = arrayMove(layers, oldIndex, newIndex)
this.props.onLayersChange(layers)
}
render() {
return <LayerListContainer
{...this.props}
onSortEnd={this.onSortEnd.bind(this)}
useDragHandle={true}
/>
}
}

View File

@@ -1,28 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Collapser from './Collapser'
export default class LayerListGroup extends React.Component {
static propTypes = {
title: PropTypes.string.isRequired,
"data-wd-key": PropTypes.string,
isActive: PropTypes.bool.isRequired,
onActiveToggle: PropTypes.func.isRequired
}
render() {
return <li className="maputnik-layer-list-group">
<div className="maputnik-layer-list-group-header"
data-wd-key={"layer-list-group:"+this.props["data-wd-key"]}
onClick={e => this.props.onActiveToggle(!this.props.isActive)}
>
<span className="maputnik-layer-list-group-title">{this.props.title}</span>
<span className="maputnik-space" />
<Collapser
style={{ height: 14, width: 14 }}
isCollapsed={this.props.isActive}
/>
</div>
</li>
}
}

View File

@@ -1,124 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Color from 'color'
import classnames from 'classnames'
import CopyIcon from 'react-icons/lib/md/content-copy'
import VisibilityIcon from 'react-icons/lib/md/visibility'
import VisibilityOffIcon from 'react-icons/lib/md/visibility-off'
import DeleteIcon from 'react-icons/lib/md/delete'
import LayerIcon from '../icons/LayerIcon'
import LayerEditor from './LayerEditor'
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
@SortableHandle
class LayerTypeDragHandle extends React.Component {
static propTypes = LayerIcon.propTypes
render() {
return <LayerIcon
{...this.props}
style={{
cursor: 'move',
width: 14,
height: 14,
paddingRight: 3,
}}
/>
}
}
class IconAction extends React.Component {
static propTypes = {
action: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
wdKey: PropTypes.string
}
renderIcon() {
switch(this.props.action) {
case 'copy': return <CopyIcon />
case 'show': return <VisibilityIcon />
case 'hide': return <VisibilityOffIcon />
case 'delete': return <DeleteIcon />
}
}
render() {
return <a
className="maputnik-layer-list-icon-action"
data-wd-key={this.props.wdKey}
onClick={this.props.onClick}
>
{this.renderIcon()}
</a>
}
}
@SortableElement
class LayerListItem extends React.Component {
static propTypes = {
layerId: PropTypes.string.isRequired,
layerType: PropTypes.string.isRequired,
isSelected: PropTypes.bool,
visibility: PropTypes.string,
className: PropTypes.string,
onLayerSelect: PropTypes.func.isRequired,
onLayerCopy: PropTypes.func,
onLayerDestroy: PropTypes.func,
onLayerVisibilityToggle: PropTypes.func,
}
static defaultProps = {
isSelected: false,
visibility: 'visible',
onLayerCopy: () => {},
onLayerDestroy: () => {},
onLayerVisibilityToggle: () => {},
}
static childContextTypes = {
reactIconBase: PropTypes.object
}
getChildContext() {
return {
reactIconBase: { size: 14 }
}
}
render() {
return <li
key={this.props.layerId}
onClick={e => this.props.onLayerSelect(this.props.layerId)}
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,
})}>
<LayerTypeDragHandle type={this.props.layerType} />
<span className="maputnik-layer-list-item-id">{this.props.layerId}</span>
<span style={{flexGrow: 1}} />
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":delete"}
action={'delete'}
onClick={e => this.props.onLayerDestroy(this.props.layerId)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":copy"}
action={'copy'}
onClick={e => this.props.onLayerCopy(this.props.layerId)}
/>
<IconAction
wdKey={"layer-list-item:"+this.props.layerId+":toggle-visibility"}
action={this.props.visibility === 'visible' ? 'hide' : 'show'}
onClick={e => this.props.onLayerVisibilityToggle(this.props.layerId)}
/>
</li>
}
}
export default LayerListItem;

View File

@@ -1,35 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
class LayerSourceBlock extends React.Component {
static propTypes = {
value: PropTypes.string,
wdKey: PropTypes.string,
onChange: PropTypes.func,
sourceIds: PropTypes.array,
}
static defaultProps = {
onChange: () => {},
sourceIds: [],
}
render() {
return <InputBlock label={"Source"} doc={styleSpec.latest.layer.source.doc}
data-wd-key={this.props.wdKey}
>
<AutocompleteInput
value={this.props.value}
onChange={this.props.onChange}
options={this.props.sourceIds.map(src => [src, src])}
/>
</InputBlock>
}
}
export default LayerSourceBlock

View File

@@ -1,37 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
class LayerSourceLayer extends React.Component {
static propTypes = {
value: PropTypes.string,
onChange: PropTypes.func,
sourceLayerIds: PropTypes.array,
isFixed: PropTypes.bool,
}
static defaultProps = {
onChange: () => {},
sourceLayerIds: [],
isFixed: false
}
render() {
return <InputBlock label={"Source Layer"} doc={styleSpec.latest.layer['source-layer'].doc}
data-wd-key="layer-source-layer"
>
<AutocompleteInput
keepMenuWithinWindowBounds={!!this.props.isFixed}
value={this.props.value}
onChange={this.props.onChange}
options={this.props.sourceLayerIds.map(l => [l, l])}
/>
</InputBlock>
}
}
export default LayerSourceLayer

View File

@@ -1,38 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import SelectInput from '../inputs/SelectInput'
class LayerTypeBlock extends React.Component {
static propTypes = {
value: PropTypes.string.isRequired,
wdKey: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"Type"} doc={styleSpec.latest.layer.type.doc}
data-wd-key={this.props.wdKey}
>
<SelectInput
options={[
['background', 'Background'],
['fill', 'Fill'],
['line', 'Line'],
['symbol', 'Symbol'],
['raster', 'Raster'],
['circle', 'Circle'],
['fill-extrusion', 'Fill Extrusion'],
['hillshade', 'Hillshade'],
['heatmap', 'Heatmap'],
]}
onChange={this.props.onChange}
value={this.props.value}
/>
</InputBlock>
}
}
export default LayerTypeBlock

View File

@@ -1,29 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import NumberInput from '../inputs/NumberInput'
class MaxZoomBlock extends React.Component {
static propTypes = {
value: PropTypes.number,
onChange: PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"Max Zoom"} doc={styleSpec.latest.layer.maxzoom.doc}
data-wd-key="max-zoom"
>
<NumberInput
value={this.props.value}
onChange={this.props.onChange}
min={styleSpec.latest.layer.maxzoom.minimum}
max={styleSpec.latest.layer.maxzoom.maximum}
default={styleSpec.latest.layer.maxzoom.maximum}
/>
</InputBlock>
}
}
export default MaxZoomBlock

View File

@@ -1,29 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import NumberInput from '../inputs/NumberInput'
class MinZoomBlock extends React.Component {
static propTypes = {
value: PropTypes.number,
onChange: PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"Min Zoom"} doc={styleSpec.latest.layer.minzoom.doc}
data-wd-key="min-zoom"
>
<NumberInput
value={this.props.value}
onChange={this.props.onChange}
min={styleSpec.latest.layer.minzoom.minimum}
max={styleSpec.latest.layer.minzoom.maximum}
default={styleSpec.latest.layer.minzoom.minimum}
/>
</InputBlock>
}
}
export default MinZoomBlock

View File

@@ -1,70 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import LayerIcon from '../icons/LayerIcon'
function groupFeaturesBySourceLayer(features) {
const sources = {}
let returnedFeatures = {};
features.forEach(feature => {
if(returnedFeatures.hasOwnProperty(feature.layer.id)) {
returnedFeatures[feature.layer.id]++
const featureObject = sources[feature.layer['source-layer']].find(f => f.layer.id === feature.layer.id)
featureObject.counter = returnedFeatures[feature.layer.id]
} else {
sources[feature.layer['source-layer']] = sources[feature.layer['source-layer']] || []
sources[feature.layer['source-layer']].push(feature)
returnedFeatures[feature.layer.id] = 1
}
})
return sources
}
class FeatureLayerPopup extends React.Component {
static propTypes = {
onLayerSelect: PropTypes.func.isRequired,
features: PropTypes.array
}
render() {
const sources = groupFeaturesBySourceLayer(this.props.features)
const items = Object.keys(sources).map(vectorLayerId => {
const layers = sources[vectorLayerId].map((feature, idx) => {
return <label
key={idx}
className="maputnik-popup-layer"
onClick={() => {
this.props.onLayerSelect(feature.layer.id)
}}
>
<LayerIcon type={feature.layer.type} style={{
width: 14,
height: 14,
paddingRight: 3
}}/>
{feature.layer.id}
{feature.counter && <span> × {feature.counter}</span>}
</label>
})
return <div key={vectorLayerId}>
<div className="maputnik-popup-layer-id">{vectorLayerId}</div>
{layers}
</div>
})
return <div className="maputnik-feature-layer-popup">
{items}
</div>
}
}
export default FeatureLayerPopup

View File

@@ -1,71 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
function displayValue(value) {
if (typeof value === 'undefined' || value === null) return value;
if (value instanceof Date) return value.toLocaleString();
if (typeof value === 'object' ||
typeof value === 'number' ||
typeof value === 'string') return value.toString();
return value;
}
function renderProperties(feature) {
return Object.keys(feature.properties).map(propertyName => {
const property = feature.properties[propertyName]
return <InputBlock key={propertyName} label={propertyName}>
<StringInput value={displayValue(property)} style={{backgroundColor: 'transparent'}}/>
</InputBlock>
})
}
function renderFeature(feature) {
return <div key={feature.id}>
<div className="maputnik-popup-layer-id">{feature.layer['source-layer']}{feature.inspectModeCounter && <span> × {feature.inspectModeCounter}</span>}</div>
<InputBlock key={"property-type"} label={"$type"}>
<StringInput value={feature.geometry.type} style={{backgroundColor: 'transparent'}} />
</InputBlock>
{renderProperties(feature)}
</div>
}
function removeDuplicatedFeatures(features) {
let uniqueFeatures = [];
features.forEach(feature => {
const featureIndex = uniqueFeatures.findIndex(feature2 => {
return feature.layer['source-layer'] === feature2.layer['source-layer']
&& JSON.stringify(feature.properties) === JSON.stringify(feature2.properties)
})
if(featureIndex === -1) {
uniqueFeatures.push(feature)
} else {
if(uniqueFeatures[featureIndex].hasOwnProperty('counter')) {
uniqueFeatures[featureIndex].inspectModeCounter++
} else {
uniqueFeatures[featureIndex].inspectModeCounter = 2
}
}
})
return uniqueFeatures
}
class FeaturePropertyPopup extends React.Component {
static propTypes = {
features: PropTypes.array
}
render() {
const features = removeDuplicatedFeatures(this.props.features)
return <div className="maputnik-feature-property-popup">
{features.map(renderFeature)}
</div>
}
}
export default FeaturePropertyPopup

View File

@@ -1,159 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import MapboxGl from 'mapbox-gl'
import MapboxInspect from 'mapbox-gl-inspect'
import FeatureLayerPopup from './FeatureLayerPopup'
import FeaturePropertyPopup from './FeaturePropertyPopup'
import style from '../../libs/style.js'
import tokens from '../../config/tokens.json'
import colors from 'mapbox-gl-inspect/lib/colors'
import Color from 'color'
import ZoomControl from '../../libs/zoomcontrol'
import { colorHighlightedLayer } from '../../libs/highlight'
import 'mapbox-gl/dist/mapbox-gl.css'
import '../../mapboxgl.css'
import '../../libs/mapbox-rtl'
function renderPropertyPopup(features) {
var mountNode = document.createElement('div');
ReactDOM.render(<FeaturePropertyPopup features={features} />, mountNode)
return mountNode.innerHTML;
}
function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
const backgroundLayer = {
"id": "background",
"type": "background",
"paint": {
"background-color": '#1c1f24',
}
}
const layer = colorHighlightedLayer(highlightedLayer)
if(layer) {
coloredLayers.push(layer)
}
const sources = {}
Object.keys(originalMapStyle.sources).forEach(sourceId => {
const source = originalMapStyle.sources[sourceId]
if(source.type !== 'raster' && source.type !== 'raster-dem') {
sources[sourceId] = source
}
})
const inspectStyle = {
...originalMapStyle,
sources: sources,
layers: [backgroundLayer].concat(coloredLayers)
}
return inspectStyle
}
export default class MapboxGlMap extends React.Component {
static propTypes = {
onDataChange: PropTypes.func,
onLayerSelect: PropTypes.func.isRequired,
mapStyle: PropTypes.object.isRequired,
inspectModeEnabled: PropTypes.bool.isRequired,
highlightedLayer: PropTypes.object,
}
static defaultProps = {
onMapLoaded: () => {},
onDataChange: () => {},
onLayerSelect: () => {},
mapboxAccessToken: tokens.mapbox,
}
constructor(props) {
super(props)
MapboxGl.accessToken = tokens.mapbox
this.state = {
map: null,
inspect: null,
isPopupOpen: false,
popupX: 0,
popupY: 0,
}
}
componentWillReceiveProps(nextProps) {
if(!this.state.map) return
const metadata = nextProps.mapStyle.metadata || {}
MapboxGl.accessToken = metadata['maputnik:mapbox_access_token'] || tokens.mapbox
if(!nextProps.inspectModeEnabled) {
//Mapbox GL now does diffing natively so we don't need to calculate
//the necessary operations ourselves!
this.state.map.setStyle(nextProps.mapStyle, { diff: true})
}
}
componentDidUpdate(prevProps) {
if(this.props.inspectModeEnabled !== prevProps.inspectModeEnabled) {
this.state.inspect.toggleInspector()
}
if(this.props.inspectModeEnabled) {
this.state.inspect.render()
}
}
componentDidMount() {
const map = new MapboxGl.Map({
container: this.container,
style: this.props.mapStyle,
hash: true,
})
const zoom = new ZoomControl;
map.addControl(zoom, 'top-right');
const nav = new MapboxGl.NavigationControl();
map.addControl(nav, 'top-right');
const inspect = new MapboxInspect({
popup: new MapboxGl.Popup({
closeOnClick: false
}),
showMapPopup: true,
showMapPopupOnHover: false,
showInspectMapPopupOnHover: true,
showInspectButton: false,
blockHoverPopupOnClick: true,
assignLayerColor: (layerId, alpha) => {
return Color(colors.brightColor(layerId, alpha)).desaturate(0.5).string()
},
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
renderPopup: features => {
if(this.props.inspectModeEnabled) {
return renderPropertyPopup(features)
} else {
var mountNode = document.createElement('div');
ReactDOM.render(<FeatureLayerPopup features={features} onLayerSelect={this.props.onLayerSelect} />, mountNode)
return mountNode
}
}
})
map.addControl(inspect)
map.on("style.load", () => {
this.setState({ map, inspect });
})
map.on("data", e => {
if(e.dataType !== 'tile') return
this.props.onDataChange({
map: this.state.map
})
})
}
render() {
return <div
className="maputnik-map"
ref={x => this.container = x}
></div>
}
}

View File

@@ -1,80 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import style from '../../libs/style.js'
import isEqual from 'lodash.isequal'
import { loadJSON } from '../../libs/urlopen'
import 'ol/ol.css'
class OpenLayers3Map extends React.Component {
static propTypes = {
onDataChange: PropTypes.func,
mapStyle: PropTypes.object.isRequired,
accessToken: PropTypes.string,
style: PropTypes.object,
}
static defaultProps = {
onMapLoaded: () => {},
onDataChange: () => {},
}
constructor(props) {
super(props)
this.map = null
}
updateStyle(newMapStyle) {
const olms = require('ol-mapbox-style');
const styleFunc = olms.apply(this.map, newMapStyle)
}
componentWillReceiveProps(nextProps) {
require.ensure(["ol", "ol-mapbox-style"], () => {
if(!this.map) return
this.updateStyle(nextProps.mapStyle)
})
}
componentDidMount() {
//Load OpenLayers dynamically once we need it
//TODO: Make this more convenient
require.ensure(["ol", "ol/map", "ol/view", "ol/control/zoom", "ol-mapbox-style"], ()=> {
console.log('Loaded OpenLayers3 renderer')
const olMap = require('ol/map').default
const olView = require('ol/view').default
const olZoom = require('ol/control/zoom').default
const map = new olMap({
target: this.container,
layers: [],
view: new olView({
zoom: 2,
center: [52.5, -78.4]
})
})
map.addControl(new olZoom())
this.map = map
this.updateStyle(this.props.mapStyle)
})
}
render() {
return <div
ref={x => this.container = x}
style={{
position: "fixed",
top: 40,
right: 0,
bottom: 0,
height: 'calc(100% - 40px)',
width: "75%",
backgroundColor: '#fff',
...this.props.style,
}}>
</div>
}
}
export default OpenLayers3Map

View File

@@ -1,164 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import Modal from './Modal'
import LayerTypeBlock from '../layers/LayerTypeBlock'
import LayerIdBlock from '../layers/LayerIdBlock'
import LayerSourceBlock from '../layers/LayerSourceBlock'
import LayerSourceLayerBlock from '../layers/LayerSourceLayerBlock'
class AddModal extends React.Component {
static propTypes = {
layers: PropTypes.array.isRequired,
onLayersChange: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
onOpenToggle: PropTypes.func.isRequired,
// A dict of source id's and the available source layers
sources: PropTypes.object.isRequired,
}
addLayer() {
const changedLayers = this.props.layers.slice(0)
const layer = {
id: this.state.id,
type: this.state.type,
}
if(this.state.type !== 'background') {
layer.source = this.state.source
if(this.state.type !== 'raster' && this.state['source-layer']) {
layer['source-layer'] = this.state['source-layer']
}
}
changedLayers.push(layer)
this.props.onLayersChange(changedLayers)
this.props.onOpenToggle(false)
}
constructor(props) {
super(props)
this.state = {
type: 'fill',
id: '',
}
if(props.sources.length > 0) {
this.state.source = Object.keys(this.props.sources)[0]
this.state['source-layer'] = this.props.sources[this.state.source][0]
}
}
componentWillUpdate(nextProps, nextState) {
// Check if source is valid for new type
const oldType = this.state.type;
const newType = nextState.type;
const availableSourcesOld = this.getSources(oldType);
const availableSourcesNew = this.getSources(newType);
if(
// Type has changed
oldType !== newType
&& this.state.source !== ""
// Was a valid source previously
&& availableSourcesOld.indexOf(this.state.source) > -1
// And is not a valid source now
&& availableSourcesNew.indexOf(nextState.source) < 0
) {
// Clear the source
this.setState({
source: ""
});
}
}
getLayersForSource(source) {
const sourceObj = this.props.sources[source] || {};
return sourceObj.layers || [];
}
getSources(type) {
const sources = [];
const types = {
vector: [
"fill",
"line",
"symbol",
"circle",
"fill-extrusion"
],
raster: [
"raster"
]
}
for(let [key, val] of Object.entries(this.props.sources)) {
if(types[val.type] && types[val.type].indexOf(type) > -1) {
sources.push(key);
}
}
return sources;
}
render() {
const sources = this.getSources(this.state.type);
const layers = this.getLayersForSource(this.state.source);
return <Modal
isOpen={this.props.isOpen}
onOpenToggle={this.props.onOpenToggle}
title={'Add Layer'}
data-wd-key="modal:add-layer"
>
<div className="maputnik-add-layer">
<LayerIdBlock
value={this.state.id}
wdKey="add-layer.layer-id"
onChange={v => {
this.setState({ id: v })
}}
/>
<LayerTypeBlock
value={this.state.type}
wdKey="add-layer.layer-type"
onChange={v => this.setState({ type: v })}
/>
{this.state.type !== 'background' &&
<LayerSourceBlock
sourceIds={sources}
wdKey="add-layer.layer-source-block"
value={this.state.source}
onChange={v => this.setState({ source: v })}
/>
}
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
<LayerSourceLayerBlock
isFixed={true}
sourceLayerIds={layers}
value={this.state['source-layer']}
onChange={v => this.setState({ 'source-layer': v })}
/>
}
<Button
className="maputnik-add-layer-button"
onClick={this.addLayer.bind(this)}
data-wd-key="add-layer"
>
Add Layer
</Button>
</div>
</Modal>
}
}
export default AddModal

View File

@@ -1,269 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import { saveAs } from 'file-saver'
import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import CheckboxInput from '../inputs/CheckboxInput'
import Button from '../Button'
import Modal from './Modal'
import MdFileDownload from 'react-icons/lib/md/file-download'
import TiClipboard from 'react-icons/lib/ti/clipboard'
import style from '../../libs/style.js'
import GitHub from 'github-api'
import { CopyToClipboard } from 'react-copy-to-clipboard'
class Gist extends React.Component {
static propTypes = {
mapStyle: PropTypes.object.isRequired,
onStyleChanged: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
this.state = {
preview: false,
public: false,
saving: false,
latestGist: null,
}
}
componentWillReceiveProps(nextProps) {
this.setState({
...this.state,
preview: !!(nextProps.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']
})
}
onSave() {
this.setState({
...this.state,
saving: true
});
const preview = this.state.preview;
const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token'];
const mapStyleStr = preview ?
styleSpec.format(stripAccessTokens(style.replaceAccessToken(this.props.mapStyle))) :
styleSpec.format(stripAccessTokens(this.props.mapStyle));
const styleTitle = this.props.mapStyle.name || 'Style';
const htmlStr = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>`+styleTitle+` Preview</title>
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.css" />
<script src="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = '${mapboxToken}';
var map = new mapboxgl.Map({
container: 'map',
style: 'style.json',
attributionControl: true,
hash: true
});
map.addControl(new mapboxgl.NavigationControl());
</script>
</body>
</html>
`
const files = {
"style.json": {
content: mapStyleStr
}
}
if(preview) {
files["index.html"] = {
content: htmlStr
}
}
const gh = new GitHub();
let gist = gh.getGist(); // not a gist yet
gist.create({
public: this.state.public,
description: styleTitle,
files: files
}).then(function({data}) {
return gist.read();
}).then(function({data}) {
this.setState({
...this.state,
latestGist: data,
saving: false,
});
}.bind(this));
}
onPreviewChange(value) {
this.setState({
...this.state,
preview: value
})
}
onPublicChange(value) {
this.setState({
...this.state,
public: value
})
}
changeMetadataProperty(property, value) {
const changedStyle = {
...this.props.mapStyle,
metadata: {
...this.props.mapStyle.metadata,
[property]: value
}
}
this.props.onStyleChanged(changedStyle)
}
renderPreviewLink() {
const gist = this.state.latestGist;
const user = gist.user || 'anonymous';
const preview = !!gist.files['index.html'];
if(preview) {
return <span><a target="_blank" rel="noopener noreferrer" href={"https://bl.ocks.org/"+user+"/"+gist.id}>Preview</a>,{' '}</span>
}
return null;
}
renderLatestGist() {
const gist = this.state.latestGist;
const saving = this.state.saving;
if(saving) {
return <p>Saving...</p>
} else if(gist) {
const user = gist.user || 'anonymous';
const rawGistLink = "https://gist.githubusercontent.com/" + user + "/" + gist.id + "/raw/" + gist.history[0].version + "/style.json"
const maputnikStyleLink = "https://maputnik.github.io/editor/?style=" + rawGistLink
return <div className="maputnik-render-gist">
<p>
Latest saved gist:{' '}
{this.renderPreviewLink(this)}
<a target="_blank" rel="noopener noreferrer" href={"https://gist.github.com/" + user + "/" + gist.id}>Source</a>
</p>
<p>
<CopyToClipboard text={maputnikStyleLink}>
<span>Share this style: <Button><TiClipboard size={18} /></Button></span>
</CopyToClipboard>
<StringInput value={maputnikStyleLink} />
</p>
</div>
}
}
render() {
return <div className="maputnik-export-gist">
<Button onClick={this.onSave.bind(this)}>
<MdFileDownload />
Save to Gist (anonymous)
</Button>
<div className="maputnik-modal-sub-section">
<CheckboxInput
value={this.state.public}
name='gist-style-public'
onChange={this.onPublicChange.bind(this)}
/>
<span> Public gist</span>
</div>
<div className="maputnik-modal-sub-section">
<CheckboxInput
value={this.state.preview}
name='gist-style-preview'
onChange={this.onPreviewChange.bind(this)}
/>
<span> Include preview</span>
</div>
{this.state.preview ?
<div>
<InputBlock
label={"OpenMapTiles Access Token: "}>
<StringInput
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}/>
</InputBlock>
<InputBlock
label={"Mapbox Access Token: "}>
<StringInput
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}/>
</InputBlock>
<a target="_blank" rel="noopener noreferrer" href="https://openmaptiles.com/hosting/">Get your free access token</a>
</div>
: null}
{this.renderLatestGist()}
</div>
}
}
function stripAccessTokens(mapStyle) {
const changedMetadata = { ...mapStyle.metadata }
delete changedMetadata['maputnik:mapbox_access_token']
delete changedMetadata['maputnik:openmaptiles_access_token']
return {
...mapStyle,
metadata: changedMetadata
}
}
class ExportModal extends React.Component {
static propTypes = {
mapStyle: PropTypes.object.isRequired,
onStyleChanged: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
onOpenToggle: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
}
downloadStyle() {
const blob = new Blob([styleSpec.format(stripAccessTokens(this.props.mapStyle))], {type: "application/json;charset=utf-8"});
saveAs(blob, this.props.mapStyle.id + ".json");
}
render() {
return <Modal
data-wd-key="export-modal"
isOpen={this.props.isOpen}
onOpenToggle={this.props.onOpenToggle}
title={'Export Style'}
>
<div className="maputnik-modal-section">
<h4>Download Style</h4>
<p>
Download a JSON style to your computer.
</p>
<Button onClick={this.downloadStyle.bind(this)}>
<MdFileDownload />
Download
</Button>
</div>
<div className="maputnik-modal-section">
<h4>Save style</h4>
<Gist mapStyle={this.props.mapStyle} onStyleChanged={this.props.onStyleChanged}/>
</div>
</Modal>
}
}
export default ExportModal

Some files were not shown because too many files have changed in this diff Show More