Compare commits

..

61 Commits

Author SHA1 Message Date
HarelM b09c629be4 Update agents.md file with the relevant information. 2026-07-12 11:16:49 +03:00
HarelM 89be954485 Improve unit test. 2026-07-12 11:08:54 +03:00
pre-commit-ci[bot] 83c099bef4 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-12 07:52:25 +00:00
HarelM 382ba69134 Add access token tests. 2026-07-12 10:52:10 +03:00
HarelM dbe5d3916d Remove redundant comment 2026-07-12 10:46:13 +03:00
HarelM 373b57a6f4 Improve tests 2026-07-12 10:43:03 +03:00
HarelM f2579e2a19 Split tests 2026-07-12 10:36:47 +03:00
pre-commit-ci[bot] aa9530274f [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-12 07:25:39 +00:00
HarelM 0ba7b3704f Restore urlopen test file. 2026-07-12 10:24:55 +03:00
HarelM be11f75c9f Add more end to end tests to increase coverage 2026-07-12 10:23:17 +03:00
HarelM 03a41cf17a fix import style 2026-07-12 10:05:02 +03:00
HarelM 192df96a79 import style 2026-07-12 10:04:01 +03:00
HarelM 10d47c561b Remove unneeded unit tests. 2026-07-12 10:02:36 +03:00
HarelM c22f7404e7 Add more end-to-end tests 2026-07-12 09:34:58 +03:00
HarelM 36073b2b1f Fix build 2026-07-12 09:34:58 +03:00
HarelM ca66f47be0 fix build 2026-07-12 09:34:58 +03:00
HarelM a5c47437ee Remove dead code 2026-07-12 09:34:58 +03:00
Harel M 91a6335d09 Apply suggestion from @HarelM 2026-07-12 09:00:50 +03:00
Harel M acaa350f0f Apply suggestion from @HarelM 2026-07-12 08:59:43 +03:00
HarelM 1a5c879c75 Improve tests. 2026-07-11 15:33:31 +03:00
HarelM b16776fed3 Merge branch 'main' into increase-coverage 2026-07-10 21:40:37 +03:00
HarelM d039dc73a5 Increase coverage to about 80% 2026-07-10 21:11:41 +03:00
HarelM 70a2db580f replace for ;; with while true. 2026-07-09 16:31:27 +03:00
HarelM b76d9cbe29 Remove circular dependency. 2026-07-09 15:38:41 +03:00
HarelM dd04c14d96 Remove maputnik assertable 2026-07-09 15:28:36 +03:00
HarelM 6c31add041 Reduce export surface 2026-07-09 15:22:41 +03:00
HarelM 60ed80651c Improve abstraction 2026-07-09 15:05:18 +03:00
HarelM c642ec5325 Remove comments 2026-07-09 15:05:18 +03:00
pre-commit-ci[bot] 0c98378243 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-09 11:44:08 +00:00
HarelM 95ba3c4428 Remove cypress related comments. 2026-07-09 14:43:58 +03:00
HarelM b112c6a2bf Split dirver and helper 2026-07-09 14:40:06 +03:00
HarelM a251faf8f7 improve abstraction 2026-07-09 14:27:33 +03:00
HarelM 8580499ec3 Fix incorrect quotes 2026-07-09 14:19:47 +03:00
HarelM 56a9840def Remove unused page 2026-07-09 14:19:23 +03:00
HarelM 3d1919738b Improve test readability 2026-07-09 14:16:12 +03:00
HarelM cc317c20a1 Move fill local storage to driver 2026-07-09 14:11:49 +03:00
HarelM a9c3da0f40 Remove hack from modal driver 2026-07-09 13:59:55 +03:00
HarelM dc5d6dd77d Remove unneeded comments. 2026-07-09 13:50:16 +03:00
HarelM 95d87ad7ef Remove export for a method that isn't used outside the file. 2026-07-09 13:41:51 +03:00
HarelM 09efbb5cd6 Fix utils path 2026-07-09 13:40:45 +03:00
HarelM 4f046cb83e Fix build 2026-07-09 13:38:54 +03:00
HarelM fb00dea285 Move playwrite stuff to utils folder 2026-07-09 13:33:29 +03:00
HarelM c00395ee11 Remove coverage file and have everything inside the fixtures.ts file. 2026-07-09 13:29:42 +03:00
pre-commit-ci[bot] 5092a924aa [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-09 10:27:14 +00:00
HarelM 7d80dccb81 Remote test related entries. 2026-07-09 13:26:24 +03:00
HarelM a93fe4d78b Fix test for regexp 2026-07-09 12:35:29 +03:00
Harel M 603a30cba8 Potential fix for pull request finding 'CodeQL / Incomplete regular expression for hostnames'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-07-09 12:19:45 +03:00
HarelM 6f55fda7d4 Remove docker coverage upload. 2026-07-09 11:47:40 +03:00
HarelM 8f0ee898ff Merge branch 'main' into replace-cypress-with-playwright 2026-07-09 11:43:28 +03:00
HarelM 3896c4c187 Merge branch 'relocate-e2e-tests' into replace-cypress-with-playwright 2026-07-08 22:44:19 +03:00
HarelM c0f1a72d80 Fix failing unit tests in CI 2026-07-08 22:43:34 +03:00
HarelM ac9186e7f8 test: instantiate MaputnikDriver once per describe block
Make the driver page-lazy (it resolves the running test's page on demand via
an auto fixture) so it can be created a single time at describe scope and
reused across the block's tests, matching the pre-migration ergonomics:

  const { given, get, when, then } = new MaputnikDriver();

instead of pulling `driver` out of a fixture and destructuring it in every
test. Coverage collection and dialog handling move into the auto fixture.

Also inject a bare invalid token ("zzz") in the json-editor parse-error test:
CodeMirror auto-closes brackets/quotes, so " {" no longer reliably breaks the
JSON.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 17:48:44 +03:00
Harel M 8c86607100 Add alias for 'it' as 'test' in layers list spec 2026-07-08 15:35:34 +03:00
HarelM 7c5e5358cb Merge branch 'relocate-e2e-tests' into replace-cypress-with-playwright 2026-07-08 15:17:09 +03:00
HarelM 18b34d3ecd Fix lint 2026-07-08 15:16:28 +03:00
HarelM 08ebca266c Merge branch 'relocate-e2e-tests' into replace-cypress-with-playwright 2026-07-08 15:15:39 +03:00
HarelM 8344a30f5d Move things back to where this will still work. 2026-07-08 15:05:35 +03:00
Harel M 4249e9beb9 Merge branch 'main' into relocate-e2e-tests 2026-07-08 14:32:25 +03:00
HarelM c3dd253737 test: migrate e2e to Playwright and component test to Vitest browser mode
Replace Cypress with Playwright for the end-to-end suite and drop
@shellygo/cypress-test-utils in favour of a hand-written MaputnikDriver
page object that keeps the fluent then(...).shouldX() assertion style
(now async). The InputAutocomplete component test moves to Vitest browser
mode using the Playwright provider.

- e2e/maputnik-driver.ts: driver + MaputnikAssertable over Playwright
- e2e/{fixtures,coverage,global-setup,global-teardown}.ts: test fixture,
  istanbul coverage collection, and nyc report generation
- playwright.config.ts / vitest.config.ts
- Code coverage preserved: dev server is istanbul-instrumented, per-test
  window.__coverage__ is merged via nyc into coverage/coverage-final.json
- CI: Cypress jobs replaced with Playwright; docker e2e runs against the
  container via E2E_NO_WEBSERVER
- Remove Cypress deps, config and support files; update docs and .nycrc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:42:32 +03:00
HarelM f7b48139a4 test: adopt Playwright test()/test.describe() naming in e2e specs
Mechanical rename of it() -> test() and describe() -> test.describe() so the
subsequent Playwright migration diff only touches test bodies, not the
suite/case wrappers.
2026-07-08 12:42:13 +03:00
HarelM 8af1cfd5f8 test: relocate Cypress e2e suite to e2e/ ahead of Playwright migration
Pure file moves (no content changes) so git records them as renames and
history/blame is preserved through the migration that follows:
  cypress/e2e/*.cy.ts        -> e2e/*.spec.ts
  cypress/e2e/*-driver.ts    -> e2e/*-driver.ts
  cypress/fixtures/          -> e2e/fixtures/
  cypress.config.ts          -> playwright.config.ts
  InputAutocomplete.cy.tsx   -> InputAutocomplete.browser.test.tsx

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:24:03 +03:00
105 changed files with 742 additions and 614 deletions
+11 -11
View File
@@ -21,9 +21,9 @@ jobs:
os: [ ubuntu-latest, windows-latest, macos-latest ]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- run: npm ci
@@ -41,9 +41,9 @@ jobs:
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- run: npm ci
@@ -56,7 +56,7 @@ jobs:
# Build and upload desktop CLI artifacts
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: ^1.23.x
cache-dependency-path: desktop/go.sum
@@ -90,9 +90,9 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- run: npm ci
@@ -111,9 +111,9 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- run: npm ci
@@ -139,9 +139,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- run: npm ci
+3 -3
View File
@@ -38,11 +38,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -67,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e0647621c2984b5ed2f768cb892365bf2a616ad1 # v4.37.2
uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
+2 -2
View File
@@ -16,13 +16,13 @@ jobs:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: main
- name: Use Node.js from nvmrc
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
+4 -4
View File
@@ -12,11 +12,11 @@ jobs:
contents: write
if: ${{ github.event_name == 'push' }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { persist-credentials: false }
- name: Use Node.js from nvmrc
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
@@ -45,11 +45,11 @@ jobs:
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- run: docker build -t ghcr.io/maplibre/maputnik:main .
- run: docker push ghcr.io/maplibre/maputnik:main
+5 -5
View File
@@ -15,14 +15,14 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: main
persist-credentials: false
- name: Use Node.js from nvmrc
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
@@ -42,19 +42,19 @@ jobs:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: main
- name: Use Node.js from nvmrc
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
registry-url: "https://registry.npmjs.org"
- name: Set up Go for desktop build
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: ^1.23.x
cache-dependency-path: desktop/go.sum
+1 -7
View File
@@ -110,13 +110,7 @@ export class MaputnikDriver {
},
chooseExampleFile: async () => {
await this.helper.when.openFileByFixture("example-style.json", "modal:open.dropzone");
await this.helper.when.wait(200);
},
/** Picks the example style through the browser's native file chooser. */
chooseExampleFileFromPicker: async () => {
await this.helper.when.chooseFileFromPicker("example-style.json", "modal:open.dropzone");
await this.helper.when.openFileByFixture("example-style.json", "modal:open.dropzone", "modal:open.file.input");
await this.helper.when.wait(200);
},
-10
View File
@@ -43,16 +43,6 @@ describe("modals", () => {
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude(get.responseBody("example-style.json"));
});
});
describe("without the File System Access API", () => {
test("upload via the file chooser", async () => {
await given.noFileSystemAccessApi();
await when.setStyle("");
await when.click("nav:open");
await when.chooseExampleFileFromPicker();
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude(get.fixture("example-style.json"));
});
});
});
describe("shortcuts", () => {
+16 -43
View File
@@ -218,18 +218,6 @@ export class PlaywrightHelper {
public then = <T>(target: T): Assertable<T> => new Assertable(target);
public given = {
/**
* Removes the File System Access API so the app falls back to a plain
* <input type="file">, the way Firefox and Safari behave. Must be called
* before the page under test is loaded.
*/
noFileSystemAccessApi: async () => {
await this.page.addInitScript(() => {
delete (window as any).showOpenFilePicker;
delete (window as any).showSaveFilePicker;
});
},
intercept: async (pattern: RegExp, alias: string, _method = "GET") => {
this.recordedRequests.set(alias, []);
await this.page.route(pattern, (route) => {
@@ -357,38 +345,23 @@ export class PlaywrightHelper {
await this.page.mouse.up();
},
/**
* Opens a fixture through the File System Access API, which raises no
* "filechooser" event and so has to be stubbed. For the <input type="file">
* fallback that browsers without the API use, see chooseFileFromPicker.
*/
openFileByFixture: async (fixture: string, buttonTestId: string) => {
openFileByFixture: async (fixture: string, buttonTestId: string, inputTestId: string) => {
const content = JSON.stringify(this.readFixture(fixture));
await this.page.evaluate((fileContent) => {
(window as any).showOpenFilePicker = async () => [
{ getFile: async () => ({ text: async () => fileContent }) },
];
}, content);
await this.testId(buttonTestId).click();
},
/**
* Clicks a control that opens the browser's native file chooser and answers
* it with a fixture. Only works on the <input type="file"> path — the File
* System Access API does not raise a "filechooser" event, so pair this with
* given.noFileSystemAccessApi().
*/
chooseFileFromPicker: async (fixture: string, triggerTestId: string) => {
const content = JSON.stringify(this.readFixture(fixture));
const [fileChooser] = await Promise.all([
this.page.waitForEvent("filechooser"),
this.testId(triggerTestId).click(),
]);
await fileChooser.setFiles({
name: fixture,
mimeType: "application/json",
buffer: Buffer.from(content),
});
const hasPicker = await this.page.evaluate(() => "showOpenFilePicker" in window);
if (hasPicker) {
await this.page.evaluate((fileContent) => {
(window as any).showOpenFilePicker = async () => [
{ getFile: async () => ({ text: async () => fileContent }) },
];
}, content);
await this.testId(buttonTestId).click();
} else {
await this.testId(inputTestId).setInputFiles({
name: fixture,
mimeType: "application/json",
buffer: Buffer.from(content),
});
}
},
dropFileByFixture: async (fixture: string, dropzoneTestId: string) => {
+1 -3
View File
@@ -34,9 +34,7 @@ export default defineConfig({
rules: {
"react-refresh/only-export-components": [
"warn",
// Many components are exported as withTranslation()(Component); without
// this the rule cannot tell the HOC's result is still a component.
{ allowConstantExport: true, extraHOCs: ["withTranslation"] }
{ allowConstantExport: true }
],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
+301 -210
View File
@@ -20,7 +20,7 @@
"@mapbox/mapbox-gl-rtl-text": "^0.4.0",
"@maplibre/maplibre-gl-geocoder": "^1.9.4",
"@maplibre/maplibre-gl-inspect": "^1.8.2",
"@maplibre/maplibre-gl-style-spec": "^26.2.1",
"@maplibre/maplibre-gl-style-spec": "^25.0.2",
"array-move": "^4.0.0",
"buffer": "^6.0.3",
"classnames": "^2.5.1",
@@ -30,7 +30,7 @@
"downshift": "^9.4.0",
"events": "^3.3.0",
"file-saver": "^2.0.5",
"i18next": "^26.3.6",
"i18next": "^26.3.4",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.1",
"json-stringify-pretty-compact": "^4.0.0",
@@ -48,14 +48,14 @@
"ol-mapbox-style": "^13.4.1",
"pmtiles": "^4.4.1",
"prop-types": "^15.8.1",
"react": "^19.2.8",
"react": "^19.2.7",
"react-accessible-accordion": "^5.0.1",
"react-aria-menubutton": "^8.0.0",
"react-aria-modal": "^5.0.2",
"react-collapse": "^5.1.1",
"react-color": "^2.19.3",
"react-dom": "^19.2.8",
"react-i18next": "^17.0.11",
"react-dom": "^19.2.7",
"react-i18next": "^17.0.8",
"react-icons": "^5.7.0",
"react-markdown": "^10.1.0",
"reconnecting-websocket": "^4.4.0",
@@ -89,25 +89,25 @@
"@types/react-dom": "^19.2.3",
"@types/string-hash": "^1.1.3",
"@types/wicg-file-system-access": "^2023.10.7",
"@vitejs/plugin-react": "6.0",
"@vitejs/plugin-react": "5.2",
"@vitest/coverage-v8": "^4.1.10",
"cors": "^2.8.6",
"eslint": "^10.7.0",
"eslint": "^10.6.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.3",
"i18next-cli": "^1.67.1",
"i18next-cli": "^1.65.0",
"istanbul": "^0.4.5",
"istanbul-lib-coverage": "^3.2.2",
"nyc": "^18.0.0",
"postcss": "^8.5.22",
"postcss": "^8.5.16",
"react-hot-loader": "^4.13.1",
"sass": "^1.101.7",
"stylelint": "^17.14.1",
"sass": "^1.101.0",
"stylelint": "^17.14.0",
"stylelint-config-recommended-scss": "^17.0.1",
"stylelint-scss": "^7.2.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.65.0",
"typescript-eslint": "^8.62.1",
"uuid": "^14.0.1",
"vite": "^7.3.2",
"vite-plugin-istanbul": "^9.0.1",
@@ -266,6 +266,16 @@
"@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
"integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
@@ -326,6 +336,38 @@
"node": ">=6.0.0"
}
},
"node_modules/@babel/plugin-transform-react-jsx-self": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
"integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-react-jsx-source": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
"integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/runtime": {
"version": "7.29.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
@@ -394,13 +436,13 @@
}
},
"node_modules/@cacheable/memory": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz",
"integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==",
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.9.tgz",
"integrity": "sha512-HdMx6DoGywB30vacDbBsITbIX4pgFqj1zsrV58jZBUw3klzkNoXhj7qOqAgledhxG7YZI5rBSJg7Zp8/VG0DuA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cacheable/utils": "^2.5.0",
"@cacheable/utils": "^2.4.1",
"@keyv/bigmap": "^1.3.1",
"hookified": "^1.15.1",
"keyv": "^5.6.0"
@@ -417,9 +459,9 @@
}
},
"node_modules/@cacheable/utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz",
"integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.1.tgz",
"integrity": "sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -605,9 +647,9 @@
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.7.tgz",
"integrity": "sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==",
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.5.tgz",
"integrity": "sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==",
"dev": true,
"funding": [
{
@@ -2137,9 +2179,9 @@
}
},
"node_modules/@maplibre/maplibre-gl-style-spec": {
"version": "26.2.1",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-26.2.1.tgz",
"integrity": "sha512-QFKCXkOeSzOr8jF75jm6kySOg+dUvOehPhRi68gcOYPHb7U5JloUq0dJW0Y5/fZV8ygfT0Vp2RWodvq+fyxFWA==",
"version": "25.0.2",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-25.0.2.tgz",
"integrity": "sha512-hTNlIVG1gaLKz6UvOV23PYcT8wVS69LLMK9jbGT2hDWzs6hlTbMejeMyQsAF0rebj9czVp77Vhp4KRaUHHUp9g==",
"license": "ISC",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.3",
@@ -2580,9 +2622,9 @@
}
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"version": "1.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
"integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
"dev": true,
"license": "MIT"
},
@@ -3303,6 +3345,20 @@
"@swc/counter": "^0.1.3"
}
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.20.7",
"@babel/types": "^7.20.7",
"@types/babel__generator": "*",
"@types/babel__template": "*",
"@types/babel__traverse": "*"
}
},
"node_modules/@types/babel__generator": {
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
@@ -3313,6 +3369,27 @@
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__template": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__traverse": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
"integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.2"
}
},
"node_modules/@types/chai": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
@@ -3664,17 +3741,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz",
"integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz",
"integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.65.0",
"@typescript-eslint/type-utils": "8.65.0",
"@typescript-eslint/utils": "8.65.0",
"@typescript-eslint/visitor-keys": "8.65.0",
"@typescript-eslint/scope-manager": "8.62.1",
"@typescript-eslint/type-utils": "8.62.1",
"@typescript-eslint/utils": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.5.0"
@@ -3687,15 +3764,15 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.65.0",
"@typescript-eslint/parser": "^8.62.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz",
"integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==",
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3703,16 +3780,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz",
"integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz",
"integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.65.0",
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/typescript-estree": "8.65.0",
"@typescript-eslint/visitor-keys": "8.65.0",
"@typescript-eslint/scope-manager": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3"
},
"engines": {
@@ -3728,14 +3805,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz",
"integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz",
"integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.65.0",
"@typescript-eslint/types": "^8.65.0",
"@typescript-eslint/tsconfig-utils": "^8.62.1",
"@typescript-eslint/types": "^8.62.1",
"debug": "^4.4.3"
},
"engines": {
@@ -3750,14 +3827,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz",
"integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz",
"integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/visitor-keys": "8.65.0"
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3768,9 +3845,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz",
"integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz",
"integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3785,15 +3862,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz",
"integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz",
"integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/typescript-estree": "8.65.0",
"@typescript-eslint/utils": "8.65.0",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1",
"@typescript-eslint/utils": "8.62.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
@@ -3810,9 +3887,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz",
"integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz",
"integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3824,16 +3901,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz",
"integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz",
"integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.65.0",
"@typescript-eslint/tsconfig-utils": "8.65.0",
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/visitor-keys": "8.65.0",
"@typescript-eslint/project-service": "8.62.1",
"@typescript-eslint/tsconfig-utils": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
@@ -3862,16 +3939,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
"integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
"integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
"node": "20 || >=22"
"node": "18 || 20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
@@ -3891,16 +3968,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz",
"integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz",
"integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.65.0",
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/typescript-estree": "8.65.0"
"@typescript-eslint/scope-manager": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3915,13 +3992,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz",
"integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz",
"integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.65.0",
"@typescript-eslint/types": "8.62.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@@ -3952,29 +4029,24 @@
"license": "ISC"
},
"node_modules/@vitejs/plugin-react": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.4.tgz",
"integrity": "sha512-XcCQz0TBpBgljhj0gMuuDj49i6Ytqh5q1osT/Gp5uAVJUCTWxyskk/l1jwYYiu2xcNHHipdMz40EGfM1VdamVg==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz",
"integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rolldown/pluginutils": "^1.0.1"
"@babel/core": "^7.29.0",
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
"@rolldown/pluginutils": "1.0.0-rc.3",
"@types/babel__core": "^7.20.5",
"react-refresh": "^0.18.0"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"peerDependencies": {
"@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
"babel-plugin-react-compiler": "^1.0.0",
"vite": "^8.0.0"
},
"peerDependenciesMeta": {
"@rolldown/plugin-babel": {
"optional": true
},
"babel-plugin-react-compiler": {
"optional": true
}
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@vitest/coverage-v8": {
@@ -4621,14 +4693,14 @@
}
},
"node_modules/cacheable": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz",
"integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==",
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.5.tgz",
"integrity": "sha512-EQfaKe09tl615iNvq/TBRWTFf1AKJNXYQSsMx0Z3EI0nA+pVsVPS8wJhnRlkbdacKPh1d0qVIhwTc2zsQNFEEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cacheable/memory": "^2.2.0",
"@cacheable/utils": "^2.5.0",
"@cacheable/memory": "^2.0.8",
"@cacheable/utils": "^2.4.1",
"hookified": "^1.15.0",
"keyv": "^5.6.0",
"qified": "^0.10.1"
@@ -5785,9 +5857,9 @@
}
},
"node_modules/eslint": {
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.7.0.tgz",
"integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==",
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.6.0.tgz",
"integrity": "sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -6210,9 +6282,9 @@
}
},
"node_modules/fast-uri": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"dev": true,
"funding": [
{
@@ -6795,9 +6867,9 @@
}
},
"node_modules/globby": {
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-16.2.2.tgz",
"integrity": "sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==",
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-16.2.0.tgz",
"integrity": "sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6816,15 +6888,41 @@
}
},
"node_modules/globby/node_modules/ignore": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz",
"integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==",
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/globby/node_modules/is-path-inside": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
"integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globby/node_modules/slash": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
"integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globjoin": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
@@ -7100,12 +7198,12 @@
"license": "MIT"
},
"node_modules/html-parse-stringify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-4.0.1.tgz",
"integrity": "sha512-0zHsZJrK7S3K2aucXWL6ycoYJ/iNtIcFHC/nYQgFklPtrv5LpJctIiSCroWZWeuoXvuyFdzp6KzjJQ+OT5MfFw==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"license": "MIT",
"funding": {
"url": "https://locize.com"
"dependencies": {
"void-elements": "3.1.0"
}
},
"node_modules/html-tags": {
@@ -7132,9 +7230,9 @@
}
},
"node_modules/i18next": {
"version": "26.3.6",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.6.tgz",
"integrity": "sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==",
"version": "26.3.4",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.4.tgz",
"integrity": "sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==",
"funding": [
{
"type": "individual",
@@ -7151,7 +7249,7 @@
],
"license": "MIT",
"peerDependencies": {
"typescript": "^5 || ^6 || ^7"
"typescript": "^5 || ^6"
},
"peerDependenciesMeta": {
"typescript": {
@@ -7169,9 +7267,9 @@
}
},
"node_modules/i18next-cli": {
"version": "1.67.1",
"resolved": "https://registry.npmjs.org/i18next-cli/-/i18next-cli-1.67.1.tgz",
"integrity": "sha512-X5Ev7R9XNUs932vroHAIJhDITE4mhvAcwoSu6fKTeRT2FREjbnfftSQkkMA0M+zLBdQHg+J4cjN0Mi25SmbQ6w==",
"version": "1.65.0",
"resolved": "https://registry.npmjs.org/i18next-cli/-/i18next-cli-1.65.0.tgz",
"integrity": "sha512-sak+2Ry4P7wtl7xMAZg2sWG2vup1lRHFBKA7h5IeEqFUog51QEgeYUhHxd2x85+MvS4BhVOZZs833clnd1WgYA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7505,9 +7603,9 @@
}
},
"node_modules/immutable": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
"integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
"integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
"dev": true,
"license": "MIT"
},
@@ -7946,19 +8044,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-path-inside": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
"integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-plain-obj": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -9641,9 +9726,9 @@
}
},
"node_modules/nanoid": {
"version": "3.3.16",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
"version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"dev": true,
"funding": [
{
@@ -10670,9 +10755,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.22",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz",
"integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==",
"version": "8.5.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
"integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
"dev": true,
"funding": [
{
@@ -10690,7 +10775,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.16",
"nanoid": "^3.3.12",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -10975,9 +11060,9 @@
}
},
"node_modules/react": {
"version": "19.2.8",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz",
"integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==",
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -11051,15 +11136,15 @@
}
},
"node_modules/react-dom": {
"version": "19.2.8",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz",
"integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==",
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"license": "MIT",
"dependencies": {
"scheduler": "^0.27.0"
},
"peerDependencies": {
"react": "^19.2.8"
"react": "^19.2.7"
}
},
"node_modules/react-hot-loader": {
@@ -11103,19 +11188,19 @@
}
},
"node_modules/react-i18next": {
"version": "17.0.11",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.11.tgz",
"integrity": "sha512-cDtkXgxjuFTWUH6V+aQn1Ve5vDiUztCNPWW5GtSHDccsgRXO1nE6QFWCEmc1KAutrb3OUv87wFShJL5RhUwPXg==",
"version": "17.0.8",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.8.tgz",
"integrity": "sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.29.2",
"html-parse-stringify": "^4.0.1",
"html-parse-stringify": "^3.0.1",
"use-sync-external-store": "^1.6.0"
},
"peerDependencies": {
"i18next": ">= 26.2.0",
"react": ">= 16.8.0",
"typescript": "^5 || ^6 || ^7"
"typescript": "^5 || ^6"
},
"peerDependenciesMeta": {
"react-dom": {
@@ -11178,6 +11263,16 @@
"react": ">=18"
}
},
"node_modules/react-refresh": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
"integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/reactcss": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
@@ -11643,9 +11738,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.101.7",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.101.7.tgz",
"integrity": "sha512-cDeUYU0dhwKVbpYg/ppsjyuoddxYhWlJOkRoI7+/iZsaSp7iowWDfm+tL2HcUafedWBDvbf/+hx0QRgKG4JSHA==",
"version": "1.101.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz",
"integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11854,19 +11949,6 @@
"dev": true,
"license": "ISC"
},
"node_modules/slash": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
"integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/slugify": {
"version": "1.6.9",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz",
@@ -12190,9 +12272,9 @@
}
},
"node_modules/stylelint": {
"version": "17.14.1",
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.14.1.tgz",
"integrity": "sha512-xVQwyiuxALUBNB2fBe0tmNemg9KqLtdj3T64mioFDar79B2cU8LIyz+3KL6LdiHs9NkeNfwxpKSaIVOY8f112g==",
"version": "17.14.0",
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.14.0.tgz",
"integrity": "sha512-8xkHPpdqYryeIsOgfsYTmr6cIeC4nLYWk5S8BPxpodq8mIuepggkMljsHewWfuAjj/+qpRKou2QerhjMH3iasg==",
"dev": true,
"funding": [
{
@@ -12208,7 +12290,7 @@
"dependencies": {
"@csstools/css-calc": "^3.2.1",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-syntax-patches-for-csstree": "^1.1.6",
"@csstools/css-syntax-patches-for-csstree": "^1.1.5",
"@csstools/css-tokenizer": "^4.0.0",
"@csstools/media-query-list-parser": "^5.0.0",
"@csstools/selector-resolve-nested": "^4.0.0",
@@ -12220,9 +12302,9 @@
"debug": "^4.4.3",
"fast-glob": "^3.3.3",
"fastest-levenshtein": "^1.0.16",
"file-entry-cache": "^11.1.5",
"file-entry-cache": "^11.1.3",
"global-modules": "^2.0.0",
"globby": "^16.2.1",
"globby": "^16.2.0",
"globjoin": "^0.1.4",
"html-tags": "^5.1.0",
"ignore": "^7.0.5",
@@ -12232,12 +12314,12 @@
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"picocolors": "^1.1.1",
"postcss": "^8.5.16",
"postcss": "^8.5.15",
"postcss-safe-parser": "^7.0.1",
"postcss-selector-parser": "^7.1.4",
"postcss-value-parser": "^4.2.0",
"string-width": "^8.2.1",
"supports-hyperlinks": "^4.5.0",
"supports-hyperlinks": "^4.4.0",
"svg-tags": "^1.0.0",
"table": "^6.9.0",
"write-file-atomic": "^7.0.1"
@@ -12336,23 +12418,23 @@
}
},
"node_modules/stylelint/node_modules/file-entry-cache": {
"version": "11.1.5",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz",
"integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==",
"version": "11.1.3",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.3.tgz",
"integrity": "sha512-oMbq0PD6VIiIwMF6LIa7MEwd/l9huKwmqRKXqmrkqIZv8CvRbfowL+L0ryAl8h//HfAS0zS+4SbYoRyAoA6BJA==",
"dev": true,
"license": "MIT",
"dependencies": {
"flat-cache": "^6.1.23"
"flat-cache": "^6.1.22"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
"version": "6.1.23",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz",
"integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==",
"version": "6.1.22",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.22.tgz",
"integrity": "sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug==",
"dev": true,
"license": "MIT",
"dependencies": {
"cacheable": "^2.5.0",
"cacheable": "^2.3.4",
"flatted": "^3.4.2",
"hookified": "^1.15.0"
}
@@ -12465,9 +12547,9 @@
}
},
"node_modules/supports-hyperlinks": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz",
"integrity": "sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.4.0.tgz",
"integrity": "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12903,16 +12985,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz",
"integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==",
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz",
"integrity": "sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.65.0",
"@typescript-eslint/parser": "8.65.0",
"@typescript-eslint/typescript-estree": "8.65.0",
"@typescript-eslint/utils": "8.65.0"
"@typescript-eslint/eslint-plugin": "8.62.1",
"@typescript-eslint/parser": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1",
"@typescript-eslint/utils": "8.62.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -13488,6 +13570,15 @@
}
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+12 -12
View File
@@ -37,7 +37,7 @@
"@mapbox/mapbox-gl-rtl-text": "^0.4.0",
"@maplibre/maplibre-gl-geocoder": "^1.9.4",
"@maplibre/maplibre-gl-inspect": "^1.8.2",
"@maplibre/maplibre-gl-style-spec": "^26.2.1",
"@maplibre/maplibre-gl-style-spec": "^25.0.2",
"array-move": "^4.0.0",
"buffer": "^6.0.3",
"classnames": "^2.5.1",
@@ -47,7 +47,7 @@
"downshift": "^9.4.0",
"events": "^3.3.0",
"file-saver": "^2.0.5",
"i18next": "^26.3.6",
"i18next": "^26.3.4",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.1",
"json-stringify-pretty-compact": "^4.0.0",
@@ -65,14 +65,14 @@
"ol-mapbox-style": "^13.4.1",
"pmtiles": "^4.4.1",
"prop-types": "^15.8.1",
"react": "^19.2.8",
"react": "^19.2.7",
"react-accessible-accordion": "^5.0.1",
"react-aria-menubutton": "^8.0.0",
"react-aria-modal": "^5.0.2",
"react-collapse": "^5.1.1",
"react-color": "^2.19.3",
"react-dom": "^19.2.8",
"react-i18next": "^17.0.11",
"react-dom": "^19.2.7",
"react-i18next": "^17.0.8",
"react-icons": "^5.7.0",
"react-markdown": "^10.1.0",
"reconnecting-websocket": "^4.4.0",
@@ -123,25 +123,25 @@
"@types/react-dom": "^19.2.3",
"@types/string-hash": "^1.1.3",
"@types/wicg-file-system-access": "^2023.10.7",
"@vitejs/plugin-react": "6.0",
"@vitejs/plugin-react": "5.2",
"@vitest/coverage-v8": "^4.1.10",
"cors": "^2.8.6",
"eslint": "^10.7.0",
"eslint": "^10.6.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.3",
"i18next-cli": "^1.67.1",
"i18next-cli": "^1.65.0",
"istanbul": "^0.4.5",
"istanbul-lib-coverage": "^3.2.2",
"nyc": "^18.0.0",
"postcss": "^8.5.22",
"postcss": "^8.5.16",
"react-hot-loader": "^4.13.1",
"sass": "^1.101.7",
"stylelint": "^17.14.1",
"sass": "^1.101.0",
"stylelint": "^17.14.0",
"stylelint-config-recommended-scss": "^17.0.1",
"stylelint-scss": "^7.2.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.65.0",
"typescript-eslint": "^8.62.1",
"uuid": "^14.0.1",
"vite": "^7.3.2",
"vite-plugin-istanbul": "^9.0.1",
+17 -17
View File
@@ -11,29 +11,29 @@ import {type Map, type LayerSpecification, type StyleSpecification, type Validat
import {validateStyleMin} from "@maplibre/maplibre-gl-style-spec";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { MapMaplibreGl } from "./MapMaplibreGl";
import { MapOpenLayers } from "./MapOpenLayers";
import { CodeEditor } from "./CodeEditor";
import { LayerList } from "./LayerList";
import { LayerEditor } from "./LayerEditor";
import { AppToolbar, type MapState } from "./AppToolbar";
import { AppLayout } from "./AppLayout";
import { AppMessagePanel as MessagePanel } from "./AppMessagePanel";
import MapMaplibreGl from "./MapMaplibreGl";
import MapOpenLayers from "./MapOpenLayers";
import CodeEditor from "./CodeEditor";
import LayerList from "./LayerList";
import LayerEditor from "./LayerEditor";
import AppToolbar, { type MapState } from "./AppToolbar";
import AppLayout from "./AppLayout";
import MessagePanel from "./AppMessagePanel";
import { ModalSettings } from "./modals/ModalSettings";
import { ModalExport } from "./modals/ModalExport";
import { ModalSources } from "./modals/ModalSources";
import { ModalOpen } from "./modals/ModalOpen";
import { ModalShortcuts } from "./modals/ModalShortcuts";
import { ModalDebug } from "./modals/ModalDebug";
import { ModalGlobalState } from "./modals/ModalGlobalState";
import ModalSettings from "./modals/ModalSettings";
import ModalExport from "./modals/ModalExport";
import ModalSources from "./modals/ModalSources";
import ModalOpen from "./modals/ModalOpen";
import ModalShortcuts from "./modals/ModalShortcuts";
import ModalDebug from "./modals/ModalDebug";
import ModalGlobalState from "./modals/ModalGlobalState";
import {downloadGlyphsMetadata, downloadSpriteMetadata} from "../libs/metadata";
import { emptyStyle, getAccessToken, replaceAccessTokens } from "../libs/style";
import { undoMessages, redoMessages } from "../libs/diffmessage";
import { createStyleStore, type IStyleStore } from "../libs/store/style-store-factory";
import { RevisionStore } from "../libs/revisions";
import { LayerWatcher } from "../libs/layerwatcher";
import LayerWatcher from "../libs/layerwatcher";
import tokens from "../config/tokens.json";
import isEqual from "lodash.isequal";
import { type MapOptions } from "maplibre-gl";
@@ -123,7 +123,7 @@ type AppState = {
fileHandle: FileSystemFileHandle | null
};
export class App extends React.Component<any, AppState> {
export default class App extends React.Component<any, AppState> {
revisionStore: RevisionStore;
styleStore: IStyleStore | null = null;
layerWatcher: LayerWatcher;
+3 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import { ScrollContainer } from "./ScrollContainer";
import ScrollContainer from "./ScrollContainer";
import { type WithTranslation, withTranslation } from "react-i18next";
import { IconContext } from "react-icons";
@@ -50,4 +50,5 @@ class AppLayoutInternal extends React.Component<AppLayoutInternalProps> {
}
}
export const AppLayout = withTranslation()(AppLayoutInternal);
const AppLayout = withTranslation()(AppLayoutInternal);
export default AppLayout;
+2 -1
View File
@@ -61,4 +61,5 @@ class AppMessagePanelInternal extends React.Component<AppMessagePanelInternalPro
}
}
export const AppMessagePanel = withTranslation()(AppMessagePanelInternal);
const AppMessagePanel = withTranslation()(AppMessagePanelInternal);
export default AppMessagePanel;
+2 -1
View File
@@ -306,4 +306,5 @@ class AppToolbarInternal extends React.Component<AppToolbarInternalProps> {
}
}
export const AppToolbar = withTranslation()(AppToolbarInternal);
const AppToolbar = withTranslation()(AppToolbarInternal);
export default AppToolbar;
+3 -3
View File
@@ -1,7 +1,7 @@
import React, {type CSSProperties, type PropsWithChildren, type SyntheticEvent} from "react";
import classnames from "classnames";
import { FieldDocLabel } from "./FieldDocLabel";
import { Doc } from "./Doc";
import FieldDocLabel from "./FieldDocLabel";
import Doc from "./Doc";
export type BlockProps = PropsWithChildren & {
"data-wd-key"?: string
@@ -19,7 +19,7 @@ type BlockState = {
};
/** Wrap a component with a label */
export class Block extends React.Component<BlockProps, BlockState> {
export default class Block extends React.Component<BlockProps, BlockState> {
_blockEl: HTMLDivElement | null = null;
constructor (props: BlockProps) {
+4 -2
View File
@@ -1,4 +1,4 @@
import { InputJson } from "./InputJson";
import InputJson from "./InputJson";
import React from "react";
import { withTranslation, type WithTranslation } from "react-i18next";
import { type StyleSpecification } from "maplibre-gl";
@@ -24,4 +24,6 @@ const CodeEditorInternal: React.FC<CodeEditorProps> = (props) => {
</>;
};
export const CodeEditor = withTranslation()(CodeEditorInternal);
const CodeEditor = withTranslation()(CodeEditorInternal);
export default CodeEditor;
+1 -1
View File
@@ -9,7 +9,7 @@ type CollapseProps = {
};
export class Collapse extends React.Component<CollapseProps> {
export default class Collapse extends React.Component<CollapseProps> {
static defaultProps = {
isActive: true
};
+1 -1
View File
@@ -6,7 +6,7 @@ type CollapserProps = {
style?: object
};
export class Collapser extends React.Component<CollapserProps> {
export default class Collapser extends React.Component<CollapserProps> {
render() {
const iconStyle = {
width: 20,
+1 -1
View File
@@ -23,7 +23,7 @@ type DocProps = {
}
};
export class Doc extends React.Component<DocProps> {
export default class Doc extends React.Component<DocProps> {
render () {
const {fieldSpec} = this.props;
+5 -3
View File
@@ -1,5 +1,5 @@
import { InputArray, type InputArrayProps } from "./InputArray";
import { Fieldset } from "./Fieldset";
import InputArray, { type InputArrayProps } from "./InputArray";
import Fieldset from "./Fieldset";
type FieldArrayProps = InputArrayProps & {
name?: string
@@ -8,10 +8,12 @@ type FieldArrayProps = InputArrayProps & {
}
};
export const FieldArray: React.FC<FieldArrayProps> = (props) => {
const FieldArray: React.FC<FieldArrayProps> = (props) => {
return (
<Fieldset label={props.label} fieldSpec={props.fieldSpec}>
<InputArray {...props} />
</Fieldset>
);
};
export default FieldArray;
+5 -3
View File
@@ -1,5 +1,5 @@
import { Block } from "./Block";
import { InputAutocomplete, type InputAutocompleteProps } from "./InputAutocomplete";
import Block from "./Block";
import InputAutocomplete, { type InputAutocompleteProps } from "./InputAutocomplete";
type FieldAutocompleteProps = InputAutocompleteProps & {
@@ -7,10 +7,12 @@ type FieldAutocompleteProps = InputAutocompleteProps & {
};
export const FieldAutocomplete: React.FC<FieldAutocompleteProps> = (props) => {
const FieldAutocomplete: React.FC<FieldAutocompleteProps> = (props) => {
return (
<Block label={props.label}>
<InputAutocomplete {...props} />
</Block>
);
};
export default FieldAutocomplete;
+5 -3
View File
@@ -1,5 +1,5 @@
import { Block } from "./Block";
import { InputCheckbox, type InputCheckboxProps } from "./InputCheckbox";
import Block from "./Block";
import InputCheckbox, {type InputCheckboxProps} from "./InputCheckbox";
type FieldCheckboxProps = InputCheckboxProps & {
@@ -7,10 +7,12 @@ type FieldCheckboxProps = InputCheckboxProps & {
};
export const FieldCheckbox: React.FC<FieldCheckboxProps> = (props) => {
const FieldCheckbox: React.FC<FieldCheckboxProps> = (props) => {
return (
<Block label={props.label}>
<InputCheckbox {...props} />
</Block>
);
};
export default FieldCheckbox;
+5 -3
View File
@@ -1,5 +1,5 @@
import { Block } from "./Block";
import { InputColor, type InputColorProps } from "./InputColor";
import Block from "./Block";
import InputColor, {type InputColorProps} from "./InputColor";
type FieldColorProps = InputColorProps & {
@@ -10,10 +10,12 @@ type FieldColorProps = InputColorProps & {
};
export const FieldColor: React.FC<FieldColorProps> = (props) => {
const FieldColor: React.FC<FieldColorProps> = (props) => {
return (
<Block label={props.label} fieldSpec={props.fieldSpec}>
<InputColor {...props} />
</Block>
);
};
export default FieldColor;
+4 -3
View File
@@ -1,7 +1,7 @@
import React from "react";
import { Block } from "./Block";
import { InputString } from "./InputString";
import Block from "./Block";
import InputString from "./InputString";
import { type WithTranslation, withTranslation } from "react-i18next";
type FieldCommentInternalProps = {
@@ -36,4 +36,5 @@ const FieldCommentInternal: React.FC<FieldCommentInternalProps> = (props) => {
);
};
export const FieldComment = withTranslation()(FieldCommentInternal);
const FieldComment = withTranslation()(FieldCommentInternal);
export default FieldComment;
+3 -1
View File
@@ -10,7 +10,7 @@ type FieldDocLabelProps = {
};
export const FieldDocLabel: React.FC<FieldDocLabelProps> = (props) => {
const FieldDocLabel: React.FC<FieldDocLabelProps> = (props) => {
const [open, setOpen] = React.useState(false);
const onToggleDoc = (state: boolean) => {
@@ -49,3 +49,5 @@ export const FieldDocLabel: React.FC<FieldDocLabelProps> = (props) => {
}
return <div />;
};
export default FieldDocLabel;
+6 -7
View File
@@ -1,17 +1,16 @@
import { InputDynamicArray, type InputDynamicArrayProps } from "./InputDynamicArray";
import { Fieldset } from "./Fieldset";
import InputDynamicArray, {type InputDynamicArrayProps} from "./InputDynamicArray";
import Fieldset from "./Fieldset";
type FieldDynamicArrayProps = InputDynamicArrayProps & {
name?: string;
fieldSpec?: {
value?: string;
}
name?: string
};
export const FieldDynamicArray: React.FC<FieldDynamicArrayProps> = (props) => {
const FieldDynamicArray: React.FC<FieldDynamicArrayProps> = (props) => {
return (
<Fieldset label={props.label}>
<InputDynamicArray {...props} />
</Fieldset>
);
};
export default FieldDynamicArray;
+5 -3
View File
@@ -1,5 +1,5 @@
import { InputEnum, type InputEnumProps } from "./InputEnum";
import { Fieldset } from "./Fieldset";
import InputEnum, {type InputEnumProps} from "./InputEnum";
import Fieldset from "./Fieldset";
type FieldEnumProps = InputEnumProps & {
@@ -10,10 +10,12 @@ type FieldEnumProps = InputEnumProps & {
};
export const FieldEnum: React.FC<FieldEnumProps> = (props) => {
const FieldEnum: React.FC<FieldEnumProps> = (props) => {
return (
<Fieldset label={props.label} fieldSpec={props.fieldSpec}>
<InputEnum {...props} />
</Fieldset>
);
};
export default FieldEnum;
+7 -5
View File
@@ -1,9 +1,9 @@
import React from "react";
import { SpecProperty } from "./SpecProperty";
import { DataProperty, type Stop } from "./DataProperty";
import { ZoomProperty } from "./ZoomProperty";
import { ExpressionProperty } from "./ExpressionProperty";
import SpecProperty from "./_SpecProperty";
import DataProperty, { type Stop } from "./_DataProperty";
import ZoomProperty from "./_ZoomProperty";
import ExpressionProperty from "./_ExpressionProperty";
import {function as styleFunction} from "@maplibre/maplibre-gl-style-spec";
import {findDefaultFromSpec} from "../libs/spec-helper";
import { type MappedLayerErrors } from "../libs/definitions";
@@ -128,7 +128,7 @@ type FieldFunctionProps = {
/** Supports displaying spec field for zoom function objects
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
*/
export const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
const [dataType, setDataType] = React.useState(
getDataType(props.value, props.fieldSpec)
);
@@ -402,3 +402,5 @@ export const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
</div>
);
};
export default FieldFunction;
+5 -3
View File
@@ -1,7 +1,7 @@
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { Block } from "./Block";
import { InputString } from "./InputString";
import Block from "./Block";
import InputString from "./InputString";
type FieldIdProps = {
value: string
@@ -10,7 +10,7 @@ type FieldIdProps = {
error?: {message: string}
};
export const FieldId: React.FC<FieldIdProps> = (props) => {
const FieldId: React.FC<FieldIdProps> = (props) => {
return (
<Block label="ID" fieldSpec={latest.layer.id}
data-wd-key={props.wdKey}
@@ -24,3 +24,5 @@ export const FieldId: React.FC<FieldIdProps> = (props) => {
</Block>
);
};
export default FieldId;
+4 -2
View File
@@ -1,9 +1,11 @@
import { InputJson, type InputJsonProps } from "./InputJson";
import InputJson, {type InputJsonProps} from "./InputJson";
type FieldJsonProps = InputJsonProps & {};
export const FieldJson: React.FC<FieldJsonProps> = (props) => {
const FieldJson: React.FC<FieldJsonProps> = (props) => {
return <InputJson {...props} />;
};
export default FieldJson;
+4 -3
View File
@@ -1,8 +1,8 @@
import React from "react";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { Block } from "./Block";
import { InputNumber } from "./InputNumber";
import Block from "./Block";
import InputNumber from "./InputNumber";
import { type WithTranslation, withTranslation } from "react-i18next";
type FieldMaxZoomInternalProps = {
@@ -31,4 +31,5 @@ const FieldMaxZoomInternal: React.FC<FieldMaxZoomInternalProps> = (props) => {
);
};
export const FieldMaxZoom = withTranslation()(FieldMaxZoomInternal);
const FieldMaxZoom = withTranslation()(FieldMaxZoomInternal);
export default FieldMaxZoom;
+4 -3
View File
@@ -1,8 +1,8 @@
import React from "react";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { Block } from "./Block";
import { InputNumber } from "./InputNumber";
import Block from "./Block";
import InputNumber from "./InputNumber";
import { type WithTranslation, withTranslation } from "react-i18next";
type FieldMinZoomInternalProps = {
@@ -31,4 +31,5 @@ const FieldMinZoomInternal: React.FC<FieldMinZoomInternalProps> = (props) => {
);
};
export const FieldMinZoom = withTranslation()(FieldMinZoomInternal);
const FieldMinZoom = withTranslation()(FieldMinZoomInternal);
export default FieldMinZoom;
+5 -3
View File
@@ -1,5 +1,5 @@
import { InputMultiInput, type InputMultiInputProps } from "./InputMultiInput";
import { Fieldset } from "./Fieldset";
import InputMultiInput, {type InputMultiInputProps} from "./InputMultiInput";
import Fieldset from "./Fieldset";
type FieldMultiInputProps = InputMultiInputProps & {
@@ -7,10 +7,12 @@ type FieldMultiInputProps = InputMultiInputProps & {
};
export const FieldMultiInput: React.FC<FieldMultiInputProps> = (props) => {
const FieldMultiInput: React.FC<FieldMultiInputProps> = (props) => {
return (
<Fieldset label={props.label}>
<InputMultiInput {...props} />
</Fieldset>
);
};
export default FieldMultiInput;
+5 -3
View File
@@ -1,5 +1,5 @@
import { InputNumber, type InputNumberProps } from "./InputNumber";
import { Block } from "./Block";
import InputNumber, {type InputNumberProps} from "./InputNumber";
import Block from "./Block";
type FieldNumberProps = InputNumberProps & {
@@ -10,10 +10,12 @@ type FieldNumberProps = InputNumberProps & {
};
export const FieldNumber: React.FC<FieldNumberProps> = (props) => {
const FieldNumber: React.FC<FieldNumberProps> = (props) => {
return (
<Block label={props.label} fieldSpec={props.fieldSpec}>
<InputNumber {...props} />
</Block>
);
};
export default FieldNumber;
+5 -3
View File
@@ -1,5 +1,5 @@
import { Block } from "./Block";
import { InputSelect, type InputSelectProps } from "./InputSelect";
import Block from "./Block";
import InputSelect, {type InputSelectProps} from "./InputSelect";
type FieldSelectProps = InputSelectProps & {
@@ -10,10 +10,12 @@ type FieldSelectProps = InputSelectProps & {
};
export const FieldSelect: React.FC<FieldSelectProps> = (props) => {
const FieldSelect: React.FC<FieldSelectProps> = (props) => {
return (
<Block label={props.label} fieldSpec={props.fieldSpec}>
<InputSelect {...props} />
</Block>
);
};
export default FieldSelect;
+4 -3
View File
@@ -1,8 +1,8 @@
import React from "react";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { Block } from "./Block";
import { InputAutocomplete } from "./InputAutocomplete";
import Block from "./Block";
import InputAutocomplete from "./InputAutocomplete";
import { type WithTranslation, withTranslation } from "react-i18next";
type FieldSourceInternalProps = {
@@ -38,4 +38,5 @@ const FieldSourceInternal: React.FC<FieldSourceInternalProps> = ({
};
export const FieldSource = withTranslation()(FieldSourceInternal);
const FieldSource = withTranslation()(FieldSourceInternal);
export default FieldSource;
+4 -3
View File
@@ -1,8 +1,8 @@
import React from "react";
import {latest} from "@maplibre/maplibre-gl-style-spec";
import { Block } from "./Block";
import { InputAutocomplete } from "./InputAutocomplete";
import Block from "./Block";
import InputAutocomplete from "./InputAutocomplete";
import { type WithTranslation, withTranslation } from "react-i18next";
type FieldSourceLayerInternalProps = {
@@ -35,4 +35,5 @@ const FieldSourceLayerInternal: React.FC<FieldSourceLayerInternalProps> = ({
);
};
export const FieldSourceLayer = withTranslation()(FieldSourceLayerInternal);
const FieldSourceLayer = withTranslation()(FieldSourceLayerInternal);
export default FieldSourceLayer;
+6 -4
View File
@@ -1,6 +1,6 @@
import { Block, type BlockProps } from "./Block";
import { InputSpec, type FieldSpecType, type InputSpecProps } from "./InputSpec";
import { Fieldset, type FieldsetProps } from "./Fieldset";
import Block, { type BlockProps } from "./Block";
import InputSpec, { type FieldSpecType, type InputSpecProps } from "./InputSpec";
import Fieldset, { type FieldsetProps } from "./Fieldset";
function getElementFromType(fieldSpec: { type?: FieldSpecType, values?: unknown[] }): typeof Fieldset | typeof Block {
switch(fieldSpec.type) {
@@ -36,7 +36,7 @@ function getElementFromType(fieldSpec: { type?: FieldSpecType, values?: unknown[
export type FieldSpecProps = InputSpecProps & BlockProps & FieldsetProps;
export const FieldSpec: React.FC<FieldSpecProps> = (props) => {
const FieldSpec: React.FC<FieldSpecProps> = (props) => {
const TypeBlock = getElementFromType(props.fieldSpec!);
return (
@@ -45,3 +45,5 @@ export const FieldSpec: React.FC<FieldSpecProps> = (props) => {
</TypeBlock>
);
};
export default FieldSpec;
+5 -3
View File
@@ -1,5 +1,5 @@
import { Block } from "./Block";
import { InputString, type InputStringProps } from "./InputString";
import Block from "./Block";
import InputString, {type InputStringProps} from "./InputString";
type FieldStringProps = InputStringProps & {
name?: string
@@ -9,10 +9,12 @@ type FieldStringProps = InputStringProps & {
}
};
export const FieldString: React.FC<FieldStringProps> = (props) => {
const FieldString: React.FC<FieldStringProps> = (props) => {
return (
<Block label={props.label} fieldSpec={props.fieldSpec}>
<InputString {...props} />
</Block>
);
};
export default FieldString;
+5 -4
View File
@@ -1,8 +1,8 @@
import React from "react";
import {v8} from "@maplibre/maplibre-gl-style-spec";
import { Block } from "./Block";
import { InputSelect } from "./InputSelect";
import { InputString } from "./InputString";
import Block from "./Block";
import InputSelect from "./InputSelect";
import InputString from "./InputString";
import { type WithTranslation, withTranslation } from "react-i18next";
import { startCase } from "lodash";
@@ -43,4 +43,5 @@ const FieldTypeInternal: React.FC<FieldTypeInternalProps> = ({
);
};
export const FieldType = withTranslation()(FieldTypeInternal);
const FieldType = withTranslation()(FieldTypeInternal);
export default FieldType;
+5 -3
View File
@@ -1,5 +1,5 @@
import { InputUrl, type FieldUrlProps as InputUrlProps } from "./InputUrl";
import { Block } from "./Block";
import InputUrl, {type FieldUrlProps as InputUrlProps} from "./InputUrl";
import Block from "./Block";
type FieldUrlProps = InputUrlProps & {
@@ -10,10 +10,12 @@ type FieldUrlProps = InputUrlProps & {
};
export const FieldUrl: React.FC<FieldUrlProps> = (props) => {
const FieldUrl: React.FC<FieldUrlProps> = (props) => {
return (
<Block label={props.label} fieldSpec={props.fieldSpec}>
<InputUrl {...props} />
</Block>
);
};
export default FieldUrl;
+6 -4
View File
@@ -1,8 +1,8 @@
import React, { type PropsWithChildren, type ReactElement } from "react";
import classnames from "classnames";
import { FieldDocLabel } from "./FieldDocLabel";
import { Doc } from "./Doc";
import { generateUniqueId } from "../libs/document-uid";
import FieldDocLabel from "./FieldDocLabel";
import Doc from "./Doc";
import generateUniqueId from "../libs/document-uid";
export type FieldsetProps = PropsWithChildren & {
label?: string,
@@ -12,7 +12,7 @@ export type FieldsetProps = PropsWithChildren & {
};
export const Fieldset: React.FC<FieldsetProps> = (props) => {
const Fieldset: React.FC<FieldsetProps> = (props) => {
const [showDoc, setShowDoc] = React.useState(false);
const labelId = React.useRef(generateUniqueId("fieldset_label_"));
@@ -49,3 +49,5 @@ export const Fieldset: React.FC<FieldsetProps> = (props) => {
</div>
);
};
export default Fieldset;
+9 -8
View File
@@ -7,13 +7,13 @@ import {migrate, convertFilter} from "@maplibre/maplibre-gl-style-spec";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import {combiningFilterOps} from "../libs/filterops";
import { InputSelect } from "./InputSelect";
import { Block } from "./Block";
import { SingleFilterEditor } from "./SingleFilterEditor";
import { FilterEditorBlock } from "./FilterEditorBlock";
import { InputButton } from "./InputButton";
import { Doc } from "./Doc";
import { ExpressionProperty } from "./ExpressionProperty";
import InputSelect from "./InputSelect";
import Block from "./Block";
import SingleFilterEditor from "./SingleFilterEditor";
import FilterEditorBlock from "./FilterEditorBlock";
import InputButton from "./InputButton";
import Doc from "./Doc";
import ExpressionProperty from "./_ExpressionProperty";
import { type WithTranslation, withTranslation } from "react-i18next";
import type { MappedLayerErrors, StyleSpecificationWithId } from "../libs/definitions";
@@ -318,4 +318,5 @@ class FilterEditorInternal extends React.Component<FilterEditorInternalProps, Fi
}
}
export const FilterEditor = withTranslation()(FilterEditorInternal);
const FilterEditor = withTranslation()(FilterEditorInternal);
export default FilterEditor;
+3 -2
View File
@@ -1,5 +1,5 @@
import React, { type PropsWithChildren } from "react";
import { InputButton } from "./InputButton";
import InputButton from "./InputButton";
import {MdDelete} from "react-icons/md";
import { type WithTranslation, withTranslation } from "react-i18next";
@@ -27,4 +27,5 @@ class FilterEditorBlockInternal extends React.Component<FilterEditorBlockInterna
}
}
export const FilterEditorBlock = withTranslation()(FilterEditorBlockInternal);
const FilterEditorBlock = withTranslation()(FilterEditorBlockInternal);
export default FilterEditorBlock;
+3 -1
View File
@@ -13,7 +13,7 @@ type IconLayerProps = {
className?: string
};
export const IconLayer: React.FC<IconLayerProps> = (props) => {
const IconLayer: React.FC<IconLayerProps> = (props) => {
const iconProps = { style: props.style };
switch(props.type) {
case "fill-extrusion": return <IoMdCube {...iconProps} />;
@@ -29,3 +29,5 @@ export const IconLayer: React.FC<IconLayerProps> = (props) => {
default: return <MdPriorityHigh {...iconProps} />;
}
};
export default IconLayer;
+3 -3
View File
@@ -1,6 +1,6 @@
import React from "react";
import { InputString } from "./InputString";
import { InputNumber } from "./InputNumber";
import InputString from "./InputString";
import InputNumber from "./InputNumber";
export type InputArrayProps = {
value: (string | number | undefined)[]
@@ -17,7 +17,7 @@ type InputArrayState = {
initialPropsValue: unknown[]
};
export class InputArray extends React.Component<InputArrayProps, InputArrayState> {
export default class InputArray extends React.Component<InputArrayProps, InputArrayState> {
static defaultProps = {
value: [],
default: [],
+1 -1
View File
@@ -11,7 +11,7 @@ export type InputAutocompleteProps = {
"aria-label"?: string
};
export function InputAutocomplete({
export default function InputAutocomplete({
value,
options = [],
onChange = () => {},
+1 -1
View File
@@ -14,7 +14,7 @@ type InputButtonProps = {
title?: string
};
export class InputButton extends React.Component<InputButtonProps> {
export default class InputButton extends React.Component<InputButtonProps> {
render() {
return <button
id={this.props.id}
+1 -1
View File
@@ -6,7 +6,7 @@ export type InputCheckboxProps = {
onChange(...args: unknown[]): unknown
};
export class InputCheckbox extends React.Component<InputCheckboxProps> {
export default class InputCheckbox extends React.Component<InputCheckboxProps> {
static defaultProps = {
value: false,
};
+1 -1
View File
@@ -20,7 +20,7 @@ export type InputColorProps = {
};
/*** Number fields with support for min, max and units and documentation*/
export class InputColor extends React.Component<InputColorProps> {
export default class InputColor extends React.Component<InputColorProps> {
state = {
pickerOpened: false
};
+10 -8
View File
@@ -3,13 +3,13 @@ import capitalize from "lodash.capitalize";
import {MdDelete} from "react-icons/md";
import { type WithTranslation, withTranslation } from "react-i18next";
import { InputString } from "./InputString";
import { InputNumber } from "./InputNumber";
import { InputButton } from "./InputButton";
import { FieldDocLabel } from "./FieldDocLabel";
import { InputEnum } from "./InputEnum";
import { InputUrl } from "./InputUrl";
import { InputColor } from "./InputColor";
import InputString from "./InputString";
import InputNumber from "./InputNumber";
import InputButton from "./InputButton";
import FieldDocLabel from "./FieldDocLabel";
import InputEnum from "./InputEnum";
import InputUrl from "./InputUrl";
import InputColor from "./InputColor";
export type InputDynamicArrayProps = {
@@ -141,7 +141,9 @@ class InputDynamicArrayInternal extends React.Component<InputDynamicArrayInterna
}
}
export const InputDynamicArray = withTranslation()(InputDynamicArrayInternal);
const InputDynamicArray = withTranslation()(InputDynamicArrayInternal);
export default InputDynamicArray;
type DeleteValueInputButtonProps = {
onClick?(...args: unknown[]): unknown
} & WithTranslation;
+3 -3
View File
@@ -1,6 +1,6 @@
import React from "react";
import { InputSelect } from "./InputSelect";
import { InputMultiInput } from "./InputMultiInput";
import InputSelect from "./InputSelect";
import InputMultiInput from "./InputMultiInput";
function optionsLabelLength(options: any[]) {
@@ -25,7 +25,7 @@ export type InputEnumProps = {
};
export class InputEnum extends React.Component<InputEnumProps> {
export default class InputEnum extends React.Component<InputEnumProps> {
render() {
const {options, value, onChange, name, label} = this.props;
+2 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import { InputAutocomplete } from "./InputAutocomplete";
import InputAutocomplete from "./InputAutocomplete";
export type InputFontProps = {
name: string
@@ -11,7 +11,7 @@ export type InputFontProps = {
"aria-label"?: string
};
export class InputFont extends React.Component<InputFontProps> {
export default class InputFont extends React.Component<InputFontProps> {
static defaultProps = {
fonts: []
};
+2 -1
View File
@@ -135,4 +135,5 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
}
}
export const InputJson = withTranslation()(InputJsonInternal);
const InputJson = withTranslation()(InputJsonInternal);
export default InputJson;
+1 -1
View File
@@ -9,7 +9,7 @@ export type InputMultiInputProps = {
"aria-label"?: string
};
export class InputMultiInput extends React.Component<InputMultiInputProps> {
export default class InputMultiInput extends React.Component<InputMultiInputProps> {
render() {
let options = this.props.options;
if(options.length > 0 && !Array.isArray(options[0])) {
+2 -2
View File
@@ -1,5 +1,5 @@
import React, { type BaseSyntheticEvent } from "react";
import { generateUniqueId } from "../libs/document-uid";
import generateUniqueId from "../libs/document-uid";
export type InputNumberProps = {
value?: number
@@ -25,7 +25,7 @@ type InputNumberState = {
dirtyValue?: number | string | undefined
};
export class InputNumber extends React.Component<InputNumberProps, InputNumberState> {
export default class InputNumber extends React.Component<InputNumberProps, InputNumberState> {
static defaultProps = {
rangeStep: 1
};
+1 -1
View File
@@ -10,7 +10,7 @@ export type InputSelectProps = {
"aria-label"?: string
};
export class InputSelect extends React.Component<InputSelectProps> {
export default class InputSelect extends React.Component<InputSelectProps> {
render() {
let options = this.props.options;
if(options.length > 0 && !Array.isArray(options[0])) {
+10 -10
View File
@@ -1,14 +1,14 @@
import React, { type ReactElement } from "react";
import { InputColor, type InputColorProps } from "./InputColor";
import { InputNumber, type InputNumberProps } from "./InputNumber";
import { InputCheckbox, type InputCheckboxProps } from "./InputCheckbox";
import { InputString, type InputStringProps } from "./InputString";
import { InputArray, type InputArrayProps } from "./InputArray";
import { InputDynamicArray, type InputDynamicArrayProps } from "./InputDynamicArray";
import { InputFont, type InputFontProps } from "./InputFont";
import { InputAutocomplete, type InputAutocompleteProps } from "./InputAutocomplete";
import { InputEnum, type InputEnumProps } from "./InputEnum";
import InputColor, { type InputColorProps } from "./InputColor";
import InputNumber, { type InputNumberProps } from "./InputNumber";
import InputCheckbox, { type InputCheckboxProps } from "./InputCheckbox";
import InputString, { type InputStringProps } from "./InputString";
import InputArray, { type InputArrayProps } from "./InputArray";
import InputDynamicArray, { type InputDynamicArrayProps } from "./InputDynamicArray";
import InputFont, { type InputFontProps } from "./InputFont";
import InputAutocomplete, { type InputAutocompleteProps } from "./InputAutocomplete";
import InputEnum, { type InputEnumProps } from "./InputEnum";
import capitalize from "lodash.capitalize";
const iconProperties = ["background-pattern", "fill-pattern", "line-pattern", "fill-extrusion-pattern", "icon-image"];
@@ -38,7 +38,7 @@ export type InputSpecProps = {
/** Display any field from the Maplibre GL style spec and
* choose the correct field component based on the @{fieldSpec}
* to display @{value}. */
export class InputSpec extends React.Component<InputSpecProps> {
export default class InputSpec extends React.Component<InputSpecProps> {
childNodes() {
const commonProps = {
+1 -1
View File
@@ -20,7 +20,7 @@ type InputStringState = {
value?: string
};
export class InputString extends React.Component<InputStringProps, InputStringState> {
export default class InputString extends React.Component<InputStringProps, InputStringState> {
static defaultProps = {
onInput: () => {},
};
+4 -3
View File
@@ -1,6 +1,6 @@
import React, { type JSX } from "react";
import { InputString } from "./InputString";
import { SmallError } from "./SmallError";
import InputString from "./InputString";
import SmallError from "./SmallError";
import { Trans, type WithTranslation, withTranslation } from "react-i18next";
import { type TFunction } from "i18next";
import { ErrorType, validate } from "../libs/urlopen";
@@ -91,4 +91,5 @@ class InputUrlInternal extends React.Component<InputUrlInternalProps, InputUrlSt
}
}
export const InputUrl = withTranslation()(InputUrlInternal);
const InputUrl = withTranslation()(InputUrlInternal);
export default InputUrl;
+17 -16
View File
@@ -6,17 +6,17 @@ import { IconContext } from "react-icons";
import { type BackgroundLayerSpecification, type LayerSpecification, type SourceSpecification } from "maplibre-gl";
import { v8 } from "@maplibre/maplibre-gl-style-spec";
import { FieldJson } from "./FieldJson";
import { FilterEditor } from "./FilterEditor";
import { PropertyGroup } from "./PropertyGroup";
import { LayerEditorGroup } from "./LayerEditorGroup";
import { FieldType } from "./FieldType";
import { FieldId } from "./FieldId";
import { FieldMinZoom } from "./FieldMinZoom";
import { FieldMaxZoom } from "./FieldMaxZoom";
import { FieldComment } from "./FieldComment";
import { FieldSource } from "./FieldSource";
import { FieldSourceLayer } from "./FieldSourceLayer";
import FieldJson from "./FieldJson";
import FilterEditor from "./FilterEditor";
import PropertyGroup from "./PropertyGroup";
import LayerEditorGroup from "./LayerEditorGroup";
import FieldType from "./FieldType";
import FieldId from "./FieldId";
import FieldMinZoom from "./FieldMinZoom";
import FieldMaxZoom from "./FieldMaxZoom";
import FieldComment from "./FieldComment";
import FieldSource from "./FieldSource";
import FieldSourceLayer from "./FieldSourceLayer";
import { changeType, changeProperty } from "../libs/layer";
import { formatLayerId } from "../libs/format";
import { type WithTranslation, withTranslation } from "react-i18next";
@@ -74,20 +74,20 @@ function getLayoutForType(type: LayerSpecification["type"], t: TFunction): Maput
return getLayoutForSymbolType(t);
}
const groups: MaputnikLayoutGroup[] = [];
if (Object.keys(v8["paint_" + type as keyof typeof v8]).length > 0) {
if (Object.keys(v8["paint_" + type]).length > 0) {
groups.push({
title: t("Paint properties"),
id: "Paint_properties",
type: "properties",
fields: Object.keys(v8["paint_" + type as keyof typeof v8]),
fields: Object.keys(v8["paint_" + type]),
});
}
if (Object.keys(v8["layout_" + type as keyof typeof v8]).length > 0) {
if (Object.keys(v8["layout_" + type]).length > 0) {
groups.push({
title: t("Layout properties"),
id: "Layout_properties",
type: "properties",
fields: Object.keys(v8["layout_" + type as keyof typeof v8])
fields: Object.keys(v8["layout_" + type])
});
}
return groups;
@@ -420,4 +420,5 @@ class LayerEditorInternal extends React.Component<LayerEditorInternalProps, Laye
}
}
export const LayerEditor = withTranslation()(LayerEditorInternal);
const LayerEditor = withTranslation()(LayerEditorInternal);
export default LayerEditor;
+1 -1
View File
@@ -18,7 +18,7 @@ type LayerEditorGroupProps = {
};
export class LayerEditorGroup extends React.Component<LayerEditorGroupProps> {
export default class LayerEditorGroup extends React.Component<LayerEditorGroupProps> {
render() {
return <AccordionItem uuid={this.props.id}>
<AccordionItemHeading className="maputnik-layer-editor-group"
+7 -5
View File
@@ -14,12 +14,12 @@ import {
verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { LayerListGroup } from "./LayerListGroup";
import { LayerListItem } from "./LayerListItem";
import { ModalAdd } from "./modals/ModalAdd";
import LayerListGroup from "./LayerListGroup";
import LayerListItem from "./LayerListItem";
import ModalAdd from "./modals/ModalAdd";
import type {LayerSpecification, SourceSpecification} from "maplibre-gl";
import { generateUniqueId } from "../libs/document-uid";
import generateUniqueId from "../libs/document-uid";
import { findClosestCommonPrefix, layerPrefix } from "../libs/layer";
import { type WithTranslation, withTranslation } from "react-i18next";
import { type MappedError, type OnMoveLayerCallback } from "../libs/definitions";
@@ -336,7 +336,7 @@ type LayerListProps = LayerListContainerProps & {
onMoveLayer: OnMoveLayerCallback
};
export const LayerList: React.FC<LayerListProps> = (props) => {
const LayerList: React.FC<LayerListProps> = (props) => {
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
const handleDragEnd = (event: DragEndEvent) => {
@@ -361,3 +361,5 @@ export const LayerList: React.FC<LayerListProps> = (props) => {
</DndContext>
);
};
export default LayerList;
+2 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import { Collapser } from "./Collapser";
import Collapser from "./Collapser";
type LayerListGroupProps = {
title: string
@@ -9,7 +9,7 @@ type LayerListGroupProps = {
"aria-controls"?: string
};
export class LayerListGroup extends React.Component<LayerListGroupProps> {
export default class LayerListGroup extends React.Component<LayerListGroupProps> {
render() {
return <li className="maputnik-layer-list-group">
<div className="maputnik-layer-list-group-header"
+4 -2
View File
@@ -5,7 +5,7 @@ import { IconContext } from "react-icons";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { IconLayer } from "./IconLayer";
import IconLayer from "./IconLayer";
import type { VisibilitySpecification } from "maplibre-gl";
@@ -87,7 +87,7 @@ type LayerListItemProps = {
onLayerVisibilityToggle?(...args: unknown[]): unknown
};
export const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>((props, ref) => {
const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>((props, ref) => {
const {
isSelected = false,
visibility = "visible",
@@ -162,3 +162,5 @@ export const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>
</li>
</IconContext.Provider>;
});
export default LayerListItem;
+5 -4
View File
@@ -3,10 +3,10 @@ import {createRoot} from "react-dom/client";
import MapLibreGl, {type LayerSpecification, type LngLat, type Map, type MapOptions, type SourceSpecification, type StyleSpecification} from "maplibre-gl";
import MaplibreInspect from "@maplibre/maplibre-gl-inspect";
import colors from "@maplibre/maplibre-gl-inspect/lib/colors";
import { FeatureLayerPopup as MapMaplibreGlLayerPopup } from "./MapMaplibreGlLayerPopup";
import { FeaturePropertyPopup as MapMaplibreGlFeaturePropertyPopup, type InspectFeature } from "./MapMaplibreGlFeaturePropertyPopup";
import MapMaplibreGlLayerPopup from "./MapMaplibreGlLayerPopup";
import MapMaplibreGlFeaturePropertyPopup, { type InspectFeature } from "./MapMaplibreGlFeaturePropertyPopup";
import Color from "color";
import { ZoomControl } from "../libs/zoomcontrol";
import ZoomControl from "../libs/zoomcontrol";
import { type HighlightedLayer, colorHighlightedLayer } from "../libs/highlight";
import "maplibre-gl/dist/maplibre-gl.css";
import "../maplibregl.css";
@@ -322,4 +322,5 @@ class MapMaplibreGlInternal extends React.Component<MapMaplibreGlInternalProps,
}
}
export const MapMaplibreGl = withTranslation()(MapMaplibreGlInternal);
const MapMaplibreGl = withTranslation()(MapMaplibreGlInternal);
export default MapMaplibreGl;
@@ -63,7 +63,7 @@ type FeaturePropertyPopupProps = {
features: InspectFeature[]
};
export class FeaturePropertyPopup extends React.Component<FeaturePropertyPopupProps> {
class FeaturePropertyPopup extends React.Component<FeaturePropertyPopupProps> {
render() {
const features = removeDuplicatedFeatures(this.props.features);
return <div className="maputnik-feature-property-popup" dir="ltr" data-wd-key="feature-property-popup">
@@ -75,3 +75,6 @@ export class FeaturePropertyPopup extends React.Component<FeaturePropertyPopupPr
</div>;
}
}
export default FeaturePropertyPopup;
+5 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import { IconLayer } from "./IconLayer";
import IconLayer from "./IconLayer";
import type {InspectFeature} from "./MapMaplibreGlFeaturePropertyPopup";
function groupFeaturesBySourceLayer(features: InspectFeature[]) {
@@ -32,7 +32,7 @@ type FeatureLayerPopupProps = {
zoom?: number
};
export class FeatureLayerPopup extends React.Component<FeatureLayerPopupProps> {
class FeatureLayerPopup extends React.Component<FeatureLayerPopupProps> {
_getFeatureColor(feature: InspectFeature, _zoom?: number) {
// Guard because openlayers won't have this
if (!feature.layer.paint) {
@@ -109,3 +109,6 @@ export class FeatureLayerPopup extends React.Component<FeatureLayerPopupProps> {
</div>;
}
}
export default FeatureLayerPopup;
+3 -2
View File
@@ -2,7 +2,7 @@ import React from "react";
import {throttle} from "lodash";
import { type WithTranslation, withTranslation } from "react-i18next";
import { FeatureLayerPopup as MapMaplibreGlLayerPopup } from "./MapMaplibreGlLayerPopup";
import MapMaplibreGlLayerPopup from "./MapMaplibreGlLayerPopup";
import "ol/ol.css";
//@ts-ignore
@@ -204,4 +204,5 @@ class MapOpenLayersInternal extends React.Component<MapOpenLayersInternalProps,
}
}
export const MapOpenLayers = withTranslation()(MapOpenLayersInternal);
const MapOpenLayers = withTranslation()(MapOpenLayersInternal);
export default MapOpenLayers;
+2 -2
View File
@@ -1,6 +1,6 @@
import React from "react";
import { FieldFunction } from "./FieldFunction";
import FieldFunction from "./FieldFunction";
import type {LayerSpecification} from "maplibre-gl";
import { type MappedLayerErrors } from "../libs/definitions";
@@ -40,7 +40,7 @@ type PropertyGroupProps = {
errors?: MappedLayerErrors
};
export class PropertyGroup extends React.Component<PropertyGroupProps> {
export default class PropertyGroup extends React.Component<PropertyGroupProps> {
onPropertyChange = (property: string, newValue: any) => {
const group = getGroupName(this.props.spec, this.props.layer.type, property);
this.props.onChange(group ,property, newValue);
+1 -1
View File
@@ -4,7 +4,7 @@ type ScrollContainerProps = {
children?: React.ReactNode
};
export class ScrollContainer extends React.Component<ScrollContainerProps> {
export default class ScrollContainer extends React.Component<ScrollContainerProps> {
render() {
return <div className="maputnik-scroll-container">
{this.props.children}
+4 -4
View File
@@ -1,9 +1,9 @@
import React from "react";
import {otherFilterOps} from "../libs/filterops";
import { InputString } from "./InputString";
import { InputAutocomplete } from "./InputAutocomplete";
import { InputSelect } from "./InputSelect";
import InputString from "./InputString";
import InputAutocomplete from "./InputAutocomplete";
import InputSelect from "./InputSelect";
function tryParseInt(v: string | number) {
if (v === "") return v;
@@ -40,7 +40,7 @@ type SingleFilterEditorProps = {
properties?: {[key: string]: string}
};
export class SingleFilterEditor extends React.Component<SingleFilterEditorProps> {
export default class SingleFilterEditor extends React.Component<SingleFilterEditorProps> {
static defaultProps = {
properties: {},
};
+2 -1
View File
@@ -18,4 +18,5 @@ class SmallErrorInternal extends React.Component<SmallErrorInternalProps> {
}
}
export const SmallError = withTranslation()(SmallErrorInternal);
const SmallError = withTranslation()(SmallErrorInternal);
export default SmallError;
@@ -3,19 +3,19 @@ import {PiListPlusBold} from "react-icons/pi";
import {TbMathFunction} from "react-icons/tb";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { InputButton } from "./InputButton";
import { InputSpec } from "./InputSpec";
import { InputNumber } from "./InputNumber";
import { InputString } from "./InputString";
import { InputSelect } from "./InputSelect";
import { Block } from "./Block";
import { generateUniqueId as docUid } from "../libs/document-uid";
import { sortNumerically } from "../libs/sort-numerically";
import InputButton from "./InputButton";
import InputSpec from "./InputSpec";
import InputNumber from "./InputNumber";
import InputString from "./InputString";
import InputSelect from "./InputSelect";
import Block from "./Block";
import docUid from "../libs/document-uid";
import sortNumerically from "../libs/sort-numerically";
import {findDefaultFromSpec} from "../libs/spec-helper";
import { type WithTranslation, withTranslation } from "react-i18next";
import { labelFromFieldName } from "../libs/label-from-field-name";
import { DeleteStopButton } from "./DeleteStopButton";
import labelFromFieldName from "../libs/label-from-field-name";
import DeleteStopButton from "./_DeleteStopButton";
import { type MappedLayerErrors } from "../libs/definitions";
@@ -385,4 +385,5 @@ class DataPropertyInternal extends React.Component<DataPropertyInternalProps, Da
}
}
export const DataProperty = withTranslation()(DataPropertyInternal);
const DataProperty = withTranslation()(DataPropertyInternal);
export default DataProperty;
@@ -1,6 +1,6 @@
import React from "react";
import { InputButton } from "./InputButton";
import InputButton from "./InputButton";
import {MdDelete} from "react-icons/md";
import { type WithTranslation, withTranslation } from "react-i18next";
@@ -23,4 +23,5 @@ class DeleteStopButtonInternal extends React.Component<DeleteStopButtonInternalP
}
}
export const DeleteStopButton = withTranslation()(DeleteStopButtonInternal);
const DeleteStopButton = withTranslation()(DeleteStopButtonInternal);
export default DeleteStopButton;
@@ -2,10 +2,10 @@ import React from "react";
import {MdDelete, MdUndo} from "react-icons/md";
import { type WithTranslation, withTranslation } from "react-i18next";
import { Block } from "./Block";
import { InputButton } from "./InputButton";
import { labelFromFieldName } from "../libs/label-from-field-name";
import { FieldJson } from "./FieldJson";
import Block from "./Block";
import InputButton from "./InputButton";
import labelFromFieldName from "../libs/label-from-field-name";
import FieldJson from "./FieldJson";
import type { StylePropertySpecification } from "maplibre-gl";
import { type MappedLayerErrors } from "../libs/definitions";
@@ -92,4 +92,5 @@ class ExpressionPropertyInternal extends React.Component<ExpressionPropertyInter
}
}
export const ExpressionProperty = withTranslation()(ExpressionPropertyInternal);
const ExpressionProperty = withTranslation()(ExpressionPropertyInternal);
export default ExpressionProperty;
@@ -1,6 +1,6 @@
import React from "react";
import { InputButton } from "./InputButton";
import InputButton from "./InputButton";
import {MdFunctions, MdInsertChart} from "react-icons/md";
import { TbMathFunction } from "react-icons/tb";
import { type WithTranslation, withTranslation } from "react-i18next";
@@ -67,4 +67,5 @@ class FunctionInputButtonsInternal extends React.Component<FunctionInputButtonsI
}
}
export const FunctionInputButtons = withTranslation()(FunctionInputButtonsInternal);
const FunctionInputButtons = withTranslation()(FunctionInputButtonsInternal);
export default FunctionInputButtons;
@@ -1,9 +1,9 @@
import React from "react";
import { FieldSpec, type FieldSpecProps } from "./FieldSpec";
import { FunctionInputButtons as FunctionButtons } from "./FunctionButtons";
import FieldSpec, {type FieldSpecProps} from "./FieldSpec";
import FunctionButtons from "./_FunctionButtons";
import { labelFromFieldName } from "../libs/label-from-field-name";
import labelFromFieldName from "../libs/label-from-field-name";
type SpecPropertyProps = FieldSpecProps & {
@@ -19,7 +19,7 @@ type SpecPropertyProps = FieldSpecProps & {
};
export class SpecProperty extends React.Component<SpecPropertyProps> {
export default class SpecProperty extends React.Component<SpecPropertyProps> {
static defaultProps = {
errors: {},
};
@@ -4,17 +4,17 @@ import { TbMathFunction } from "react-icons/tb";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { type WithTranslation, withTranslation } from "react-i18next";
import { InputButton } from "./InputButton";
import { InputSpec } from "./InputSpec";
import { InputNumber } from "./InputNumber";
import { InputSelect } from "./InputSelect";
import { Block } from "./Block";
import InputButton from "./InputButton";
import InputSpec from "./InputSpec";
import InputNumber from "./InputNumber";
import InputSelect from "./InputSelect";
import Block from "./Block";
import { DeleteStopButton } from "./DeleteStopButton";
import { labelFromFieldName } from "../libs/label-from-field-name";
import DeleteStopButton from "./_DeleteStopButton";
import labelFromFieldName from "../libs/label-from-field-name";
import { generateUniqueId as docUid } from "../libs/document-uid";
import { sortNumerically } from "../libs/sort-numerically";
import docUid from "../libs/document-uid";
import sortNumerically from "../libs/sort-numerically";
import { type MappedLayerErrors } from "../libs/definitions";
@@ -267,4 +267,5 @@ class ZoomPropertyInternal extends React.Component<ZoomPropertyInternalProps, Zo
}
}
export const ZoomProperty = withTranslation()(ZoomPropertyInternal);
const ZoomProperty = withTranslation()(ZoomPropertyInternal);
export default ZoomProperty;
+2 -1
View File
@@ -67,4 +67,5 @@ class ModalInternal extends React.Component<ModalInternalProps> {
}
}
export const Modal = withTranslation()(ModalInternal);
const Modal = withTranslation()(ModalInternal);
export default Modal;
+8 -7
View File
@@ -2,12 +2,12 @@ import React from "react";
import { type WithTranslation, withTranslation } from "react-i18next";
import type {LayerSpecification, SourceSpecification} from "maplibre-gl";
import { InputButton } from "../InputButton";
import { Modal } from "./Modal";
import { FieldType } from "../FieldType";
import { FieldId } from "../FieldId";
import { FieldSource } from "../FieldSource";
import { FieldSourceLayer } from "../FieldSourceLayer";
import InputButton from "../InputButton";
import Modal from "./Modal";
import FieldType from "../FieldType";
import FieldId from "../FieldId";
import FieldSource from "../FieldSource";
import FieldSourceLayer from "../FieldSourceLayer";
import { NON_SOURCE_LAYERS } from "../../libs/non-source-layers";
type ModalAddInternalProps = {
@@ -192,4 +192,5 @@ class ModalAddInternal extends React.Component<ModalAddInternalProps, ModalAddSt
}
}
export const ModalAdd = withTranslation()(ModalAddInternal);
const ModalAdd = withTranslation()(ModalAddInternal);
export default ModalAdd;
+3 -2
View File
@@ -1,7 +1,7 @@
import React from "react";
import { Trans, type WithTranslation, withTranslation } from "react-i18next";
import { Modal } from "./Modal";
import Modal from "./Modal";
type ModalDebugInternalProps = {
@@ -79,4 +79,5 @@ class ModalDebugInternal extends React.Component<ModalDebugInternalProps> {
}
}
export const ModalDebug = withTranslation()(ModalDebugInternal);
const ModalDebug = withTranslation()(ModalDebugInternal);
export default ModalDebug;
+7 -6
View File
@@ -6,11 +6,11 @@ import {format} from "@maplibre/maplibre-gl-style-spec";
import {MdMap, MdSave} from "react-icons/md";
import {type WithTranslation, withTranslation} from "react-i18next";
import { FieldString } from "../FieldString";
import { InputButton } from "../InputButton";
import { Modal } from "./Modal";
import { replaceAccessTokens, stripAccessTokens } from "../../libs/style";
import { spec as fieldSpecAdditional } from "../../libs/field-spec-additional";
import FieldString from "../FieldString";
import InputButton from "../InputButton";
import Modal from "./Modal";
import {replaceAccessTokens, stripAccessTokens} from "../../libs/style";
import fieldSpecAdditional from "../../libs/field-spec-additional";
import type {OnStyleChangedCallback, StyleSpecificationWithId} from "../../libs/definitions";
@@ -217,4 +217,5 @@ class ModalExportInternal extends React.Component<ModalExportInternalProps> {
}
}
export const ModalExport = withTranslation()(ModalExportInternal);
const ModalExport = withTranslation()(ModalExportInternal);
export default ModalExport;
+6 -5
View File
@@ -3,13 +3,13 @@ import { withTranslation, type WithTranslation } from "react-i18next";
import { MdDelete } from "react-icons/md";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import { Modal } from "./Modal";
import { FieldString } from "../FieldString";
import { InputButton } from "../InputButton";
import Modal from "./Modal";
import FieldString from "../FieldString";
import InputButton from "../InputButton";
import { PiListPlusBold } from "react-icons/pi";
import { type StyleSpecificationWithId } from "../../libs/definitions";
import { type SchemaSpecification } from "maplibre-gl";
import { Doc } from "../Doc";
import Doc from "../Doc";
type ModalGlobalStateInternalProps = {
mapStyle: StyleSpecificationWithId;
@@ -151,4 +151,5 @@ const ModalGlobalStateInternal: React.FC<ModalGlobalStateInternalProps> = (props
);
};
export const ModalGlobalState = withTranslation()(ModalGlobalStateInternal);
const ModalGlobalState = withTranslation()(ModalGlobalStateInternal);
export default ModalGlobalState;
+4 -3
View File
@@ -1,8 +1,8 @@
import React from "react";
import { type WithTranslation, withTranslation } from "react-i18next";
import { InputButton } from "../InputButton";
import { Modal } from "./Modal";
import InputButton from "../InputButton";
import Modal from "./Modal";
type ModalLoadingInternalProps = {
@@ -35,4 +35,5 @@ class ModalLoadingInternal extends React.Component<ModalLoadingInternalProps> {
}
}
export const ModalLoading = withTranslation()(ModalLoadingInternal);
const ModalLoading = withTranslation()(ModalLoadingInternal);
export default ModalLoading;
+6 -5
View File
@@ -3,10 +3,10 @@ import { MdFileUpload } from "react-icons/md";
import { MdAddCircleOutline } from "react-icons/md";
import { Trans, type WithTranslation, withTranslation } from "react-i18next";
import { ModalLoading } from "./ModalLoading";
import { Modal } from "./Modal";
import { InputButton } from "../InputButton";
import { InputUrl } from "../InputUrl";
import ModalLoading from "./ModalLoading";
import Modal from "./Modal";
import InputButton from "../InputButton";
import InputUrl from "../InputUrl";
import { ensureStyleValidity } from "../../libs/style";
import publicStyles from "../../config/styles.json";
@@ -364,4 +364,5 @@ class ModalOpenInternal extends React.Component<ModalOpenInternalProps, ModalOpe
}
}
export const ModalOpen = withTranslation()(ModalOpenInternal);
const ModalOpen = withTranslation()(ModalOpenInternal);
export default ModalOpen;
+13 -12
View File
@@ -3,17 +3,17 @@ import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import type {LightSpecification, ProjectionSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from "maplibre-gl";
import { type WithTranslation, withTranslation } from "react-i18next";
import { FieldArray } from "../FieldArray";
import { FieldNumber } from "../FieldNumber";
import { FieldString } from "../FieldString";
import { FieldUrl } from "../FieldUrl";
import { FieldSelect } from "../FieldSelect";
import { FieldEnum } from "../FieldEnum";
import { FieldColor } from "../FieldColor";
import { Modal } from "./Modal";
import { FieldJson } from "../FieldJson";
import { Block } from "../Block";
import { spec as fieldSpecAdditional } from "../../libs/field-spec-additional";
import FieldArray from "../FieldArray";
import FieldNumber from "../FieldNumber";
import FieldString from "../FieldString";
import FieldUrl from "../FieldUrl";
import FieldSelect from "../FieldSelect";
import FieldEnum from "../FieldEnum";
import FieldColor from "../FieldColor";
import Modal from "./Modal";
import FieldJson from "../FieldJson";
import Block from "../Block";
import fieldSpecAdditional from "../../libs/field-spec-additional";
import type {OnStyleChangedCallback, StyleSpecificationWithId} from "../../libs/definitions";
type ModalSettingsInternalProps = {
@@ -332,4 +332,5 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
}
}
export const ModalSettings = withTranslation()(ModalSettingsInternal);
const ModalSettings = withTranslation()(ModalSettingsInternal);
export default ModalSettings;
+3 -2
View File
@@ -1,7 +1,7 @@
import React from "react";
import { Trans, type WithTranslation, withTranslation } from "react-i18next";
import { Modal } from "./Modal";
import Modal from "./Modal";
type ModalShortcutsInternalProps = {
@@ -134,4 +134,5 @@ class ModalShortcutsInternal extends React.Component<ModalShortcutsInternalProps
}
}
export const ModalShortcuts = withTranslation()(ModalShortcutsInternal);
const ModalShortcuts = withTranslation()(ModalShortcutsInternal);
export default ModalShortcuts;
+7 -6
View File
@@ -4,11 +4,11 @@ import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import type {GeoJSONSourceSpecification, RasterDEMSourceSpecification, RasterSourceSpecification, SourceSpecification, VectorSourceSpecification} from "maplibre-gl";
import { type WithTranslation, withTranslation } from "react-i18next";
import { Modal } from "./Modal";
import { InputButton } from "../InputButton";
import { FieldString } from "../FieldString";
import { FieldSelect } from "../FieldSelect";
import { ModalSourcesTypeEditor, type EditorMode } from "./ModalSourcesTypeEditor";
import Modal from "./Modal";
import InputButton from "../InputButton";
import FieldString from "../FieldString";
import FieldSelect from "../FieldSelect";
import ModalSourcesTypeEditor, { type EditorMode } from "./ModalSourcesTypeEditor";
import { generateId } from "../../libs/style";
import { deleteSource, addSource, changeSource } from "../../libs/source";
@@ -343,4 +343,5 @@ class ModalSourcesInternal extends React.Component<ModalSourcesInternalProps> {
}
}
export const ModalSources = withTranslation()(ModalSourcesInternal);
const ModalSources = withTranslation()(ModalSourcesInternal);
export default ModalSources;
@@ -3,14 +3,14 @@ import {latest} from "@maplibre/maplibre-gl-style-spec";
import { type WithTranslation, withTranslation } from "react-i18next";
import { type TFunction } from "i18next";
import { Block } from "../Block";
import { FieldUrl } from "../FieldUrl";
import { FieldNumber } from "../FieldNumber";
import { FieldSelect } from "../FieldSelect";
import { FieldDynamicArray } from "../FieldDynamicArray";
import { FieldArray } from "../FieldArray";
import { FieldJson } from "../FieldJson";
import { FieldCheckbox } from "../FieldCheckbox";
import Block from "../Block";
import FieldUrl from "../FieldUrl";
import FieldNumber from "../FieldNumber";
import FieldSelect from "../FieldSelect";
import FieldDynamicArray from "../FieldDynamicArray";
import FieldArray from "../FieldArray";
import FieldJson from "../FieldJson";
import FieldCheckbox from "../FieldCheckbox";
export type EditorMode = "video" | "image" | "tilejson_vector" | "tile_raster" | "tilejson_raster" | "tilexyz_raster-dem" | "tilejson_raster-dem" | "pmtiles_vector" | "tile_vector" | "geojson_url" | "geojson_json" | null;
@@ -375,4 +375,5 @@ class ModalSourcesTypeEditorInternal extends React.Component<ModalSourcesTypeEdi
}
}
export const ModalSourcesTypeEditor = withTranslation()(ModalSourcesTypeEditorInternal);
const ModalSourcesTypeEditor = withTranslation()(ModalSourcesTypeEditorInternal);
export default ModalSourcesTypeEditor;
+1 -1
View File
@@ -42,4 +42,4 @@ i18n
}
});
export { i18n };
export default i18n;
+1 -1
View File
@@ -4,7 +4,7 @@ import { createRoot } from "react-dom/client";
import "./favicon.ico";
import "./styles/index.scss";
import "./i18n";
import { App } from "./components/App";
import App from "./components/App";
const root = createRoot(document.querySelector("#app"));
root.render(
+1 -1
View File
@@ -119,7 +119,7 @@ function createMaplibreExpressionLinter(spec?: StylePropertySpecification) {
const text = view.state.doc.toString();
const parsedJson = JSON.parse(text);
const ast = jsonToAst(text);
const out = expression.createExpression(parsedJson, "expression", spec);
const out = expression.createExpression(parsedJson, spec);
if (out?.result !== "error") {
return [];
}
+1 -1
View File
@@ -3,7 +3,7 @@
*/
let REF = 0;
export function generateUniqueId(prefix="") {
export default function generateUniqueId(prefix="") {
REF++;
return prefix+REF;
}
+3 -1
View File
@@ -1,6 +1,6 @@
import { type TFunction } from "i18next";
export const spec = (t: TFunction) => ({
const spec = (t: TFunction) => ({
maputnik: {
maptiler_access_token: {
label: t("MapTiler Access Token"),
@@ -32,3 +32,5 @@ export const spec = (t: TFunction) => ({
},
}
});
export default spec;
+1 -1
View File
@@ -1,6 +1,6 @@
import capitalize from "lodash.capitalize";
export function labelFromFieldName(fieldName: string) {
export default function labelFromFieldName(fieldName: string) {
let label;
const parts = fieldName.split("-");
if (parts.length > 1) {
+2 -2
View File
@@ -5,14 +5,14 @@ import { type LayerSpecification } from "maplibre-gl";
export function changeType(layer: LayerSpecification, newType: string): LayerSpecification {
const changedPaintProps: LayerSpecification["paint"] = { ...layer.paint };
Object.keys(changedPaintProps).forEach(propertyName => {
if(!(propertyName in ((latest["paint_" + newType as keyof typeof latest]) as string[]))) {
if(!(propertyName in latest["paint_" + newType])) {
delete changedPaintProps[propertyName as keyof LayerSpecification["paint"]];
}
});
const changedLayoutProps: LayerSpecification["layout"] = { ...layer.layout };
Object.keys(changedLayoutProps).forEach(propertyName => {
if(!(propertyName in ((latest["layout_" + newType as keyof typeof latest]) as string[]))) {
if(!(propertyName in latest["layout_" + newType])) {
delete changedLayoutProps[propertyName as keyof LayerSpecification["layout"]];
}
});
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, it, expect, vi } from "vitest";
import { LayerWatcher } from "./layerwatcher";
import type { Map } from "maplibre-gl";
import LayerWatcher from "./layerwatcher";
function mockMap(): Map {
return {
+1 -1
View File
@@ -9,7 +9,7 @@ export type LayerWatcherOptions = {
/** Listens to map events to build up a store of available vector
* layers contained in the tiles */
export class LayerWatcher {
export default class LayerWatcher {
onSourcesChange: (sources: { [sourceId: string]: string[] }) => void;
onVectorLayersChange: (vectorLayers: { [vectorLayerId: string]: { [propertyName: string]: { [propertyValue: string]: {} } } }) => void;
throttledAnalyzeVectorLayerFields: (map: any) => void;

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