Repository: MIERUNE/svelte-maplibre-gl Branch: main Commit: f031cbb0cbc5 Files: 294 Total size: 317.6 KB Directory structure: gitextract_qlcdzk6r/ ├── .changeset/ │ ├── README.md │ └── config.json ├── .github/ │ ├── dependabot.yml │ ├── pull_request_template.md │ └── workflows/ │ ├── lint.yml │ ├── preview.yml │ └── release.yml ├── .gitignore ├── .node-version ├── .npmrc ├── .prettierignore ├── .prettierrc ├── LICENSE-APACHE.txt ├── LICENSE-MIT.txt ├── README.md ├── components.json ├── e2e/ │ └── demo.test.ts ├── eslint.config.js ├── extensions/ │ ├── contour/ │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ └── lib/ │ │ │ ├── MapLibreContourSource.svelte │ │ │ └── index.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── deckgl/ │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ └── lib/ │ │ │ ├── DeckGLOverlay.svelte │ │ │ └── index.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── pmtiles/ │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ └── lib/ │ │ │ ├── PMTilesProtocol.svelte │ │ │ └── index.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── terradraw/ │ ├── CHANGELOG.md │ ├── package.json │ ├── src/ │ │ ├── app.d.ts │ │ ├── app.html │ │ └── lib/ │ │ ├── TerraDraw.svelte │ │ └── index.ts │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── package.json ├── playwright.config.ts ├── pnpm-workspace.yaml ├── src/ │ ├── app.css │ ├── app.d.ts │ ├── app.html │ ├── content/ │ │ ├── CodeBlock.svelte │ │ ├── components/ │ │ │ └── toc.ts │ │ ├── docs/ │ │ │ ├── quickstart/ │ │ │ │ ├── Marker.svelte │ │ │ │ ├── Simplest.svelte │ │ │ │ └── content.svelte.md │ │ │ └── toc.ts │ │ └── examples/ │ │ ├── 3d-buildings/ │ │ │ ├── Buildings3D.svelte │ │ │ └── content.svelte.md │ │ ├── 3d-extrusion-floorplan/ │ │ │ ├── Floorplan.svelte │ │ │ └── content.svelte.md │ │ ├── animate-images/ │ │ │ ├── AnimateImages.svelte │ │ │ └── content.svelte.md │ │ ├── basestyle/ │ │ │ ├── BaseStyle.svelte │ │ │ └── content.svelte.md │ │ ├── canvas-source/ │ │ │ ├── Canvas.svelte │ │ │ ├── Circle.ts │ │ │ └── content.svelte.md │ │ ├── clusters/ │ │ │ ├── Clusters.svelte │ │ │ └── content.svelte.md │ │ ├── color-relief/ │ │ │ ├── ColorRelief.svelte │ │ │ └── content.svelte.md │ │ ├── complex/ │ │ │ ├── Complex.svelte │ │ │ └── content.svelte.md │ │ ├── contour/ │ │ │ ├── Contour.svelte │ │ │ └── content.svelte.md │ │ ├── cursor/ │ │ │ ├── Cursor.svelte │ │ │ └── content.svelte.md │ │ ├── custom-control/ │ │ │ ├── CustomControl.svelte │ │ │ ├── MyControl.ts │ │ │ └── content.svelte.md │ │ ├── custom-layer/ │ │ │ ├── CustomLayer.svelte │ │ │ └── content.svelte.md │ │ ├── custom-protocol/ │ │ │ ├── CustomProtocol.svelte │ │ │ └── content.svelte.md │ │ ├── deckgl-overlay/ │ │ │ ├── DeckGL.svelte │ │ │ └── content.svelte.md │ │ ├── dynamic-image/ │ │ │ ├── DynamicImage.svelte │ │ │ └── content.svelte.md │ │ ├── fullscreen/ │ │ │ ├── Fullscreen.svelte │ │ │ └── content.svelte.md │ │ ├── geolocate/ │ │ │ ├── Geolocate.svelte │ │ │ └── content.svelte.md │ │ ├── global-state/ │ │ │ ├── Plain.svelte │ │ │ └── content.svelte.md │ │ ├── globe-atmosphere/ │ │ │ ├── Globe.svelte │ │ │ └── content.svelte.md │ │ ├── hover-styles/ │ │ │ ├── HoverStyles.svelte │ │ │ └── content.svelte.md │ │ ├── image-loader/ │ │ │ ├── Images.svelte │ │ │ └── content.svelte.md │ │ ├── limit-interaction/ │ │ │ ├── LimitInteraction.svelte │ │ │ └── content.svelte.md │ │ ├── marker-popup/ │ │ │ ├── MarkerAndPopup.svelte │ │ │ └── content.svelte.md │ │ ├── plain/ │ │ │ ├── Plain.svelte │ │ │ └── content.svelte.md │ │ ├── pmtiles/ │ │ │ ├── PMTiles.svelte │ │ │ └── content.svelte.md │ │ ├── query-features/ │ │ │ ├── Query.svelte │ │ │ └── content.svelte.md │ │ ├── side-by-side/ │ │ │ ├── SideBySide.svelte │ │ │ └── content.svelte.md │ │ ├── terradraw/ │ │ │ ├── TerraDraw.svelte │ │ │ └── content.svelte.md │ │ ├── terrain/ │ │ │ ├── Terrain.svelte │ │ │ └── content.svelte.md │ │ ├── threejs-model/ │ │ │ ├── CustomLayer.svelte │ │ │ └── content.svelte.md │ │ ├── toc.ts │ │ └── video-on-a-map/ │ │ ├── Video.svelte │ │ └── content.svelte.md │ ├── demo.spec.ts │ ├── lib/ │ │ ├── assets/ │ │ │ ├── fonts/ │ │ │ │ ├── LICENSE.txt │ │ │ │ └── geist.css │ │ │ └── icons/ │ │ │ └── GitHub.svelte │ │ ├── components/ │ │ │ ├── Index.svelte │ │ │ ├── types.ts │ │ │ └── ui/ │ │ │ ├── badge/ │ │ │ │ ├── badge.svelte │ │ │ │ └── index.ts │ │ │ ├── breadcrumb/ │ │ │ │ ├── breadcrumb-ellipsis.svelte │ │ │ │ ├── breadcrumb-item.svelte │ │ │ │ ├── breadcrumb-link.svelte │ │ │ │ ├── breadcrumb-list.svelte │ │ │ │ ├── breadcrumb-page.svelte │ │ │ │ ├── breadcrumb-separator.svelte │ │ │ │ ├── breadcrumb.svelte │ │ │ │ └── index.ts │ │ │ ├── button/ │ │ │ │ ├── button.svelte │ │ │ │ └── index.ts │ │ │ ├── checkbox/ │ │ │ │ ├── checkbox.svelte │ │ │ │ └── index.ts │ │ │ ├── dropdown-menu/ │ │ │ │ ├── dropdown-menu-checkbox-group.svelte │ │ │ │ ├── dropdown-menu-checkbox-item.svelte │ │ │ │ ├── dropdown-menu-content.svelte │ │ │ │ ├── dropdown-menu-group-heading.svelte │ │ │ │ ├── dropdown-menu-group.svelte │ │ │ │ ├── dropdown-menu-item.svelte │ │ │ │ ├── dropdown-menu-label.svelte │ │ │ │ ├── dropdown-menu-portal.svelte │ │ │ │ ├── dropdown-menu-radio-group.svelte │ │ │ │ ├── dropdown-menu-radio-item.svelte │ │ │ │ ├── dropdown-menu-separator.svelte │ │ │ │ ├── dropdown-menu-shortcut.svelte │ │ │ │ ├── dropdown-menu-sub-content.svelte │ │ │ │ ├── dropdown-menu-sub-trigger.svelte │ │ │ │ ├── dropdown-menu-sub.svelte │ │ │ │ ├── dropdown-menu-trigger.svelte │ │ │ │ ├── dropdown-menu.svelte │ │ │ │ └── index.ts │ │ │ ├── label/ │ │ │ │ ├── index.ts │ │ │ │ └── label.svelte │ │ │ ├── radio-group/ │ │ │ │ ├── index.ts │ │ │ │ ├── radio-group-item.svelte │ │ │ │ └── radio-group.svelte │ │ │ ├── select/ │ │ │ │ ├── index.ts │ │ │ │ ├── select-content.svelte │ │ │ │ ├── select-group-heading.svelte │ │ │ │ ├── select-group.svelte │ │ │ │ ├── select-item.svelte │ │ │ │ ├── select-label.svelte │ │ │ │ ├── select-portal.svelte │ │ │ │ ├── select-scroll-down-button.svelte │ │ │ │ ├── select-scroll-up-button.svelte │ │ │ │ ├── select-separator.svelte │ │ │ │ ├── select-trigger.svelte │ │ │ │ └── select.svelte │ │ │ ├── separator/ │ │ │ │ ├── index.ts │ │ │ │ └── separator.svelte │ │ │ ├── slider/ │ │ │ │ ├── index.ts │ │ │ │ └── slider.svelte │ │ │ ├── switch/ │ │ │ │ ├── index.ts │ │ │ │ └── switch.svelte │ │ │ ├── table/ │ │ │ │ ├── index.ts │ │ │ │ ├── table-body.svelte │ │ │ │ ├── table-caption.svelte │ │ │ │ ├── table-cell.svelte │ │ │ │ ├── table-footer.svelte │ │ │ │ ├── table-head.svelte │ │ │ │ ├── table-header.svelte │ │ │ │ ├── table-row.svelte │ │ │ │ └── table.svelte │ │ │ └── tabs/ │ │ │ ├── index.ts │ │ │ ├── tabs-content.svelte │ │ │ ├── tabs-list.svelte │ │ │ ├── tabs-trigger.svelte │ │ │ └── tabs.svelte │ │ └── utils.ts │ └── routes/ │ ├── +layout.server.ts │ ├── +layout.svelte │ ├── +page.svelte │ ├── DarkModeSelector.svelte │ ├── GlobalToc.svelte │ ├── Header.svelte │ ├── ViewTransition.svelte │ ├── docs/ │ │ ├── +layout.ts │ │ ├── +page.svelte │ │ ├── [slug]/ │ │ │ ├── +layout.svelte │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ └── components/ │ │ ├── +page.svelte │ │ ├── [slug]/ │ │ │ ├── _+layout.svelte_ │ │ │ ├── _+page.svelte_ │ │ │ ├── _+page.ts_ │ │ │ ├── _Prop.svelte_ │ │ │ └── _utils.ts_ │ │ └── components.json │ ├── examples/ │ │ ├── +layout.ts │ │ ├── +page.svelte │ │ └── [slug]/ │ │ ├── +layout.svelte │ │ ├── +page.svelte │ │ └── +page.ts │ └── sitemap.xml/ │ └── +server.ts ├── svelte-maplibre-gl/ │ ├── CHANGELOG.md │ ├── package.json │ ├── src/ │ │ ├── app.d.ts │ │ ├── app.html │ │ └── lib/ │ │ ├── contexts.svelte.ts │ │ ├── controls/ │ │ │ ├── AttributionControl.svelte │ │ │ ├── CustomControl.svelte │ │ │ ├── FullScreenControl.svelte │ │ │ ├── GeolocateControl.svelte │ │ │ ├── GlobeControl.svelte │ │ │ ├── Hash.svelte │ │ │ ├── LogoControl.svelte │ │ │ ├── NavigationControl.svelte │ │ │ ├── ScaleControl.svelte │ │ │ └── TerrainControl.svelte │ │ ├── global/ │ │ │ └── Protocol.svelte │ │ ├── index.ts │ │ ├── layers/ │ │ │ ├── BackgroundLayer.svelte │ │ │ ├── CircleLayer.svelte │ │ │ ├── ColorReliefLayer.svelte │ │ │ ├── CustomLayer.svelte │ │ │ ├── FillExtrusionLayer.svelte │ │ │ ├── FillLayer.svelte │ │ │ ├── HeatmapLayer.svelte │ │ │ ├── HillshadeLayer.svelte │ │ │ ├── LineLayer.svelte │ │ │ ├── RasterLayer.svelte │ │ │ ├── RawLayer.svelte │ │ │ ├── SymbolLayer.svelte │ │ │ └── common.ts │ │ ├── map/ │ │ │ ├── Image.svelte │ │ │ ├── Light.svelte │ │ │ ├── MapLibre.svelte │ │ │ ├── Projection.svelte │ │ │ ├── Sky.svelte │ │ │ ├── Sprite.svelte │ │ │ └── Terrain.svelte │ │ ├── markers/ │ │ │ ├── Marker.svelte │ │ │ └── Popup.svelte │ │ ├── sources/ │ │ │ ├── CanvasSource.svelte │ │ │ ├── FeatureState.svelte │ │ │ ├── GeoJSONSource.svelte │ │ │ ├── ImageSource.svelte │ │ │ ├── RasterDEMTileSource.svelte │ │ │ ├── RasterTileSource.svelte │ │ │ ├── RawSource.svelte │ │ │ ├── VectorTileSource.svelte │ │ │ └── VideoSource.svelte │ │ ├── types.ts │ │ ├── utilities/ │ │ │ ├── ImageLoader.svelte │ │ │ ├── QueryRenderedFeatures.svelte │ │ │ └── QuerySourceFeatures.svelte │ │ └── utils.ts │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── svelte.config.js ├── tailwind.config.ts ├── tsconfig.json ├── turbo.json ├── vite.config.ts └── wrangler.jsonc ================================================ FILE CONTENTS ================================================ ================================================ FILE: .changeset/README.md ================================================ # Changesets Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets) We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) ================================================ FILE: .changeset/config.json ================================================ { "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], "linked": [["svelte-maplibre-gl", "@svelte-maplibre-gl/*"]], "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": ["@svelte-maplibre-gl/docs"], "privatePackages": { "version": false, "tag": false } } ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: 'github-actions' directory: '/' schedule: interval: 'weekly' ================================================ FILE: .github/pull_request_template.md ================================================ Close #0 ### What I did - ### Notes None ================================================ FILE: .github/workflows/lint.yml ================================================ name: Lint on: push: branches: - main pull_request: jobs: lint: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v6 - run: npm i -g --force corepack && corepack enable - uses: actions/setup-node@v6 with: node-version: 22 cache: 'pnpm' - name: Install dependencies run: pnpm install - name: Svelte check run: pnpm run check:all - name: Lint run: pnpm run lint ================================================ FILE: .github/workflows/preview.yml ================================================ name: Preview Release on: pull_request: jobs: preview-release: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v6 - run: npm i -g --force corepack && corepack enable - uses: actions/setup-node@v6 with: node-version: 22 cache: 'pnpm' - name: Install dependencies run: pnpm install - name: Build packages run: pnpm build:packages - name: Publish packages preview with pkg-pr-new CLI run: | pnpx pkg-pr-new publish \ ./svelte-maplibre-gl \ ./extensions/contour \ ./extensions/deckgl \ ./extensions/pmtiles \ ./extensions/terradraw ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: branches: - main concurrency: ${{ github.workflow }}-${{ github.ref }} jobs: release: name: Release runs-on: ubuntu-latest permissions: contents: write pull-requests: write id-token: write steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Setup pnpm run: npm i -g --force corepack@latest && corepack enable - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 22 cache: 'pnpm' - name: Install Dependencies run: pnpm install - name: Create Release Pull Request or Publish to npm id: changesets uses: changesets/action@c48e67d110a68bc90ccf1098e9646092baacaa87 # v1.6.0 with: publish: pnpm run release version: pnpm run version env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # Generate preview releases for PRs - name: Publish Preview Packages if: steps.changesets.outputs.published != 'true' run: | pnpm build:packages pnpx pkg-pr-new publish \ ./svelte-maplibre-gl \ ./extensions/contour \ ./extensions/deckgl \ ./extensions/pmtiles \ ./extensions/terradraw ================================================ FILE: .gitignore ================================================ test-results node_modules # Output .output .vercel **/.svelte-kit/ **/dist/ /build .turbo # OS .DS_Store Thumbs.db # Env .env .env.* !.env.example !.env.test # Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* # ignore npm lockfile package-lock.json .wrangler ================================================ FILE: .node-version ================================================ 22.17 ================================================ FILE: .npmrc ================================================ engine-strict=true ================================================ FILE: .prettierignore ================================================ # Package Managers package-lock.json pnpm-lock.yaml yarn.lock **/dist/ **/.svelte-kit/ # shadcn-svelte src/lib/components/ui/** .github/*.md /README.md ================================================ FILE: .prettierrc ================================================ { "useTabs": true, "singleQuote": true, "trailingComma": "none", "printWidth": 120, "plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-svelte"], "overrides": [ { "files": "*.svelte", "options": { "parser": "svelte" } }, { "files": ["*.svx", "*.svelte.md", "*.md"], "options": { "parser": "markdown" } } ], "tailwindStylesheet": "./src/app.css" } ================================================ FILE: LICENSE-APACHE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSE-MIT.txt ================================================ MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Svelte MapLibre GL ![NPM Version](https://img.shields.io/npm/v/svelte-maplibre-gl) ![NPM License](https://img.shields.io/npm/l/svelte-maplibre-gl?color=96C902) :world_map: Build interactive web maps effortlessly with [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/) and [Svelte](https://svelte.dev/). :point_right: **Documentaion and Live Demos:** https://svelte-maplibre-gl.mierune.dev/examples/ **Features:** - The most declarative and reactive MapLibre GL JS experience, powered by Svelte 5 - A flexible, minimally opinionated API design that is suitable for both beginners and experienced MapLibre users - Freedom preserved — Traditional imperative MapLibre GL JS usage remains fully supported License: MIT or Apache 2.0 hero image ## Installation ```bash npm install --save-dev svelte-maplibre-gl ``` `svelte-maplibre-gl` only works with **Svelte 5** and above. ## License Licensed under the [MIT License](./LICENSE-MIT.txt) or the [Apache License 2.0](./LICENSE-APACHE.txt), at your option. ## Acknowledgements This project `svelte-maplibre-gl` is built from scratch, while drawing strong inspiration from the work of the following libraries: - [`dimfeld/svelte-maplibre`](https://github.com/dimfeld/svelte-maplibre) — A library offering idiomatic Svelte support for the MapLibre GL mapping software - [`visgl/react-map-gl`](https://visgl.github.io/react-map-gl/) and [`visgl/react-maplibre`](https://visgl.github.io/react-maplibre/) — React friendly API wrapper around Mapbox/MapLibre GL JS ## Contributing Everyone is welcome to contribute to this project! There are many ways to support it, such as: - Trying it out and reporting any issues or missing features - Expanding, improving, or suggesting new examples - Any other ideas you might have! Your contributions are greatly appreciated. ### Authors [All contributors](https://github.com/MIERUNE/svelte-maplibre-gl/graphs/contributors)! ================================================ FILE: components.json ================================================ { "$schema": "https://shadcn-svelte.com/schema.json", "tailwind": { "css": "src/app.css", "baseColor": "slate" }, "aliases": { "components": "$lib/components", "utils": "$lib/utils", "ui": "$lib/components/ui", "hooks": "$lib/hooks", "lib": "$lib" }, "typescript": true, "registry": "https://shadcn-svelte.com/registry" } ================================================ FILE: e2e/demo.test.ts ================================================ import { expect, test } from '@playwright/test'; test('home page has expected h1', async ({ page }) => { await page.goto('/'); await expect(page.locator('h1')).toBeVisible(); }); ================================================ FILE: eslint.config.js ================================================ import prettier from 'eslint-config-prettier'; import js from '@eslint/js'; import svelte from 'eslint-plugin-svelte'; import globals from 'globals'; import ts from 'typescript-eslint'; export default ts.config( js.configs.recommended, ...ts.configs.recommended, ...svelte.configs['flat/recommended'], prettier, ...svelte.configs['flat/prettier'], { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, { files: ['**/*.svelte', '**/*.svelte.ts'], rules: { // surpress "Expected an assignment or function call and instead saw an expression" '@typescript-eslint/no-unused-expressions': 'off' // 'svelte/require-each-key': 'off' }, languageOptions: { parserOptions: { parser: ts.parser } } }, { ignores: ['**/build/', '**/.svelte-kit/', '**/dist/'] } ); ================================================ FILE: extensions/contour/CHANGELOG.md ================================================ # @svelte-maplibre-gl/contour ## 1.0.3 ### Patch Changes - Updated dependencies [6b3cd54] - svelte-maplibre-gl@1.0.3 ## 1.0.2 ### Patch Changes - Updated dependencies [608c2b5] - svelte-maplibre-gl@1.0.2 ## 1.0.1 ### Patch Changes - Updated dependencies [a5cc3ef] - svelte-maplibre-gl@1.0.1 ================================================ FILE: extensions/contour/package.json ================================================ { "name": "@svelte-maplibre-gl/contour", "version": "1.0.3", "license": "(MIT OR Apache-2.0)", "description": "maplibre-contour extension for svelte-maplibre-gl", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "keywords": [ "map", "svelte", "maplibre", "maplibre-gl", "contour" ], "scripts": { "build": "vite build && npm run prepack", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", "prepack": "svelte-kit sync && svelte-package && publint", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check ." }, "files": [ "dist", "!dist/**/*.test.*", "!dist/**/*.spec.*" ], "sideEffects": false, "svelte": "./dist/index.js", "types": "./dist/index.d.ts", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js" } }, "peerDependencies": { "maplibre-contour": ">=0.1.0", "maplibre-gl": "^5.0.0 || ^4.0.0", "svelte": ">=5.0.0", "svelte-maplibre-gl": "workspace:*" }, "devDependencies": { "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "maplibre-contour": "catalog:", "maplibre-gl": "catalog:", "publint": "catalog:", "svelte": "catalog:", "svelte-check": "catalog:", "svelte-maplibre-gl": "workspace:*", "typescript": "catalog:", "vite": "catalog:" } } ================================================ FILE: extensions/contour/src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: extensions/contour/src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: extensions/contour/src/lib/MapLibreContourSource.svelte ================================================ {#if demSource} {@render children?.(demSource)} {/if} ================================================ FILE: extensions/contour/src/lib/index.ts ================================================ export { default as MapLibreContourSource } from './MapLibreContourSource.svelte'; ================================================ FILE: extensions/contour/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), kit: { // Since this is a library package, we don't need an adapter adapter: undefined } }; export default config; ================================================ FILE: extensions/contour/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler", "module": "ESNext", "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "types": ["svelte"] }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "exclude": ["node_modules", "dist"] } ================================================ FILE: extensions/contour/vite.config.ts ================================================ import { defineConfig } from 'vite'; import { svelte } from '@sveltejs/vite-plugin-svelte'; export default defineConfig({ plugins: [svelte()], build: { lib: { entry: './src/lib/index.ts', name: 'SvelteMaplibreContour', fileName: 'index' }, rollupOptions: { external: ['svelte', 'maplibre-gl', '@watergis/maplibre-gl-terradraw'], output: { globals: { svelte: 'Svelte', 'maplibre-gl': 'maplibregl', '@watergis/maplibre-gl-terradraw': 'MaplibreContour' } } } } }); ================================================ FILE: extensions/deckgl/CHANGELOG.md ================================================ # @svelte-maplibre-gl/deckgl ## 1.0.3 ### Patch Changes - Updated dependencies [6b3cd54] - svelte-maplibre-gl@1.0.3 ## 1.0.2 ### Patch Changes - Updated dependencies [608c2b5] - svelte-maplibre-gl@1.0.2 ## 1.0.1 ### Patch Changes - Updated dependencies [a5cc3ef] - svelte-maplibre-gl@1.0.1 ================================================ FILE: extensions/deckgl/package.json ================================================ { "name": "@svelte-maplibre-gl/deckgl", "version": "1.0.3", "license": "(MIT OR Apache-2.0)", "description": "DeckGL extension for svelte-maplibre-gl", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "keywords": [ "map", "svelte", "maplibre", "maplibre-gl", "deckgl" ], "scripts": { "build": "vite build && npm run prepack", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", "prepack": "svelte-kit sync && svelte-package && publint", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check ." }, "files": [ "dist", "!dist/**/*.test.*", "!dist/**/*.spec.*" ], "sideEffects": false, "svelte": "./dist/index.js", "types": "./dist/index.d.ts", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js" } }, "peerDependencies": { "@deck.gl/core": "^9.1.0", "@deck.gl/layers": "^9.1.0", "@deck.gl/mapbox": "^9.1.0", "maplibre-gl": "^5.0.0 || ^4.0.0", "svelte": ">=5.0.0", "svelte-maplibre-gl": "workspace:*" }, "devDependencies": { "@deck.gl/core": "catalog:", "@deck.gl/layers": "catalog:", "@deck.gl/mapbox": "catalog:", "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "maplibre-gl": "catalog:", "publint": "catalog:", "svelte": "catalog:", "svelte-check": "catalog:", "svelte-maplibre-gl": "workspace:*", "typescript": "catalog:", "vite": "catalog:" } } ================================================ FILE: extensions/deckgl/src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: extensions/deckgl/src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: extensions/deckgl/src/lib/DeckGLOverlay.svelte ================================================ ================================================ FILE: extensions/deckgl/src/lib/index.ts ================================================ export { default as DeckGLOverlay } from './DeckGLOverlay.svelte'; ================================================ FILE: extensions/deckgl/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), kit: { // Since this is a library package, we don't need an adapter adapter: undefined } }; export default config; ================================================ FILE: extensions/deckgl/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler", "module": "ESNext", "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "types": ["svelte"] }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "exclude": ["node_modules", "dist"] } ================================================ FILE: extensions/deckgl/vite.config.ts ================================================ import { defineConfig } from 'vite'; import { svelte } from '@sveltejs/vite-plugin-svelte'; export default defineConfig({ plugins: [svelte()], build: { lib: { entry: './src/lib/index.ts', name: 'SvelteMaplibreDeckGL', fileName: 'index' }, rollupOptions: { external: ['svelte', 'maplibre-gl', '@deck.gl/mapbox'], output: { globals: { svelte: 'Svelte', 'maplibre-gl': 'maplibregl', '@deck.gl/mapbox': 'DeckGLMapbox' } } } } }); ================================================ FILE: extensions/pmtiles/CHANGELOG.md ================================================ # @svelte-maplibre-gl/pmtiles ## 1.0.3 ### Patch Changes - Updated dependencies [6b3cd54] - svelte-maplibre-gl@1.0.3 ## 1.0.2 ### Patch Changes - Updated dependencies [608c2b5] - svelte-maplibre-gl@1.0.2 ## 1.0.1 ### Patch Changes - Updated dependencies [a5cc3ef] - svelte-maplibre-gl@1.0.1 ================================================ FILE: extensions/pmtiles/package.json ================================================ { "name": "@svelte-maplibre-gl/pmtiles", "version": "1.0.3", "license": "(MIT OR Apache-2.0)", "description": "PMTiles extension for svelte-maplibre-gl", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "keywords": [ "map", "svelte", "maplibre", "maplibre-gl", "pmtiles" ], "scripts": { "build": "vite build && npm run prepack", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", "prepack": "svelte-kit sync && svelte-package && publint", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check ." }, "files": [ "dist", "!dist/**/*.test.*", "!dist/**/*.spec.*" ], "sideEffects": false, "svelte": "./dist/index.js", "types": "./dist/index.d.ts", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js" } }, "peerDependencies": { "pmtiles": "^4.0.0", "maplibre-gl": "^5.0.0 || ^4.0.0", "svelte": ">=5.0.0", "svelte-maplibre-gl": "workspace:*" }, "devDependencies": { "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "maplibre-gl": "catalog:", "pmtiles": "catalog:", "publint": "catalog:", "svelte": "catalog:", "svelte-check": "catalog:", "svelte-maplibre-gl": "workspace:*", "typescript": "catalog:", "vite": "catalog:" } } ================================================ FILE: extensions/pmtiles/src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: extensions/pmtiles/src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: extensions/pmtiles/src/lib/PMTilesProtocol.svelte ================================================ ================================================ FILE: extensions/pmtiles/src/lib/index.ts ================================================ export { default as PMTilesProtocol } from './PMTilesProtocol.svelte'; ================================================ FILE: extensions/pmtiles/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), kit: { // Since this is a library package, we don't need an adapter adapter: undefined } }; export default config; ================================================ FILE: extensions/pmtiles/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler", "module": "ESNext", "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "types": ["svelte"] }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "exclude": ["node_modules", "dist"] } ================================================ FILE: extensions/pmtiles/vite.config.ts ================================================ import { defineConfig } from 'vite'; import { svelte } from '@sveltejs/vite-plugin-svelte'; export default defineConfig({ plugins: [svelte()], build: { lib: { entry: './src/lib/index.ts', name: 'SvelteMaplibrePMTiles', fileName: 'index' }, rollupOptions: { external: ['svelte', 'maplibre-gl', 'pmtiles', 'svelte-maplibre-gl'], output: { globals: { svelte: 'Svelte', 'maplibre-gl': 'maplibregl', pmtiles: 'pmtiles', 'svelte-maplibre-gl': 'SvelteMaplibreGL' } } } } }); ================================================ FILE: extensions/terradraw/CHANGELOG.md ================================================ # @svelte-maplibre-gl/terradraw ## 1.0.3 ### Patch Changes - Updated dependencies [6b3cd54] - svelte-maplibre-gl@1.0.3 ## 1.0.2 ### Patch Changes - Updated dependencies [608c2b5] - svelte-maplibre-gl@1.0.2 ## 1.0.1 ### Patch Changes - Updated dependencies [a5cc3ef] - svelte-maplibre-gl@1.0.1 ================================================ FILE: extensions/terradraw/package.json ================================================ { "name": "@svelte-maplibre-gl/terradraw", "version": "1.0.3", "license": "(MIT OR Apache-2.0)", "description": "TerraDraw extension for svelte-maplibre-gl", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "keywords": [ "map", "svelte", "maplibre", "maplibre-gl", "terradraw" ], "scripts": { "build": "vite build && npm run prepack", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", "prepack": "svelte-kit sync && svelte-package && publint", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check ." }, "files": [ "dist", "!dist/**/*.test.*", "!dist/**/*.spec.*" ], "sideEffects": false, "svelte": "./dist/index.js", "types": "./dist/index.d.ts", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js" } }, "peerDependencies": { "terra-draw": "^1.0.0", "terra-draw-maplibre-gl-adapter": "^1.0.3", "maplibre-gl": "^5.0.0 || ^4.0.0", "svelte": ">=5.0.0", "svelte-maplibre-gl": "workspace:*" }, "devDependencies": { "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "maplibre-gl": "catalog:", "publint": "catalog:", "svelte": "catalog:", "svelte-check": "catalog:", "svelte-maplibre-gl": "workspace:*", "terra-draw": "catalog:", "terra-draw-maplibre-gl-adapter": "catalog:", "typescript": "catalog:", "vite": "catalog:" } } ================================================ FILE: extensions/terradraw/src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: extensions/terradraw/src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: extensions/terradraw/src/lib/TerraDraw.svelte ================================================ ================================================ FILE: extensions/terradraw/src/lib/index.ts ================================================ export { default as TerraDraw } from './TerraDraw.svelte'; ================================================ FILE: extensions/terradraw/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), kit: { // Since this is a library package, we don't need an adapter adapter: undefined } }; export default config; ================================================ FILE: extensions/terradraw/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler", "module": "ESNext", "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "types": ["svelte"] }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "exclude": ["node_modules", "dist"] } ================================================ FILE: extensions/terradraw/vite.config.ts ================================================ import { defineConfig } from 'vite'; import { svelte } from '@sveltejs/vite-plugin-svelte'; export default defineConfig({ plugins: [svelte()], build: { lib: { entry: './src/lib/index.ts', name: 'SvelteMaplibreTerraDraw', fileName: 'index' }, rollupOptions: { external: ['svelte', 'maplibre-gl', 'terra-draw', 'terra-draw-maplibre-gl-adapter', 'svelte-maplibre-gl'], output: { globals: { svelte: 'Svelte', 'maplibre-gl': 'maplibregl', 'terra-draw': 'TerraDraw', 'terra-draw-maplibre-gl-adapter': 'TerraDrawMapLibreGLAdapter', 'svelte-maplibre-gl': 'SvelteMaplibreGL' } } } } }); ================================================ FILE: package.json ================================================ { "name": "@svelte-maplibre-gl/docs", "version": "1.0.0", "private": true, "type": "module", "license": "(MIT OR Apache-2.0)", "description": "Documentation site for svelte-maplibre-gl", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "scripts": { "dev": "vite dev", "build": "vite build", "build:all": "turbo run build", "build:packages": "turbo run build --filter='./svelte-maplibre-gl' --filter='./extensions/*'", "preview": "turbo run preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:all": "turbo run check", "check:watch": "turbo run check:watch --filter='./svelte-maplibre-gl' --filter='./extensions/*'", "format": "prettier --write .", "lint": "prettier --check . && eslint .", "test:unit": "vitest", "test": "npm run test:unit -- --run && npm run test:e2e", "test:e2e": "playwright test", "changeset": "changeset", "version": "changeset version", "release": "pnpm build:packages && changeset publish" }, "dependencies": { "@changesets/changelog-github": "^0.5.2", "@svelte-maplibre-gl/contour": "workspace:*", "@svelte-maplibre-gl/deckgl": "workspace:*", "@svelte-maplibre-gl/pmtiles": "workspace:*", "@svelte-maplibre-gl/terradraw": "workspace:*", "svelte-maplibre-gl": "workspace:*" }, "devDependencies": { "@changesets/cli": "^2.29.8", "@deck.gl/core": "catalog:", "@deck.gl/layers": "catalog:", "@deck.gl/mapbox": "catalog:", "@docsearch/css": "^3.9.0", "@docsearch/js": "^3.9.0", "@eslint/js": "^9.39.2", "@internationalized/date": "^3.10.1", "@lucide/svelte": "^0.541.0", "@playwright/test": "^1.58.0", "@sveltejs/adapter-cloudflare": "^7.2.6", "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.1.18", "@types/eslint": "^9.6.1", "@types/geojson": "catalog:", "@types/three": "^0.179.0", "bits-ui": "^2.15.4", "clsx": "^2.1.1", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", "eslint-plugin-svelte": "^3.14.0", "fast-png": "^7.0.1", "globals": "^17.2.0", "install": "^0.13.0", "maplibre-contour": "catalog:", "maplibre-gl": "catalog:", "mdsvex": "^0.12.6", "mode-watcher": "^1.1.0", "pathe": "^2.0.3", "pkg-pr-new": "^0.0.57", "pmtiles": "catalog:", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.4.1", "prettier-plugin-tailwindcss": "^0.6.14", "publint": "catalog:", "shiki": "^3.21.0", "superjson": "^2.2.6", "svelte": "catalog:", "svelte-check": "catalog:", "svelte2tsx": "0.7.34", "tailwind-merge": "^3.4.0", "tailwind-variants": "^3.2.2", "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", "terra-draw": "catalog:", "terra-draw-maplibre-gl-adapter": "catalog:", "three": "^0.179.1", "turbo": "^2.7.6", "typescript": "catalog:", "typescript-eslint": "^8.54.0", "vite": "catalog:", "vitest": "^3.2.4" }, "packageManager": "pnpm@10.15.0" } ================================================ FILE: playwright.config.ts ================================================ import { defineConfig } from '@playwright/test'; export default defineConfig({ webServer: { command: 'npm run build && npm run preview', port: 4173 }, testDir: 'e2e' }); ================================================ FILE: pnpm-workspace.yaml ================================================ packages: - svelte-maplibre-gl - extensions/* - . catalog: '@deck.gl/core': ^9.2.6 '@deck.gl/layers': ^9.2.6 '@deck.gl/mapbox': ^9.2.6 '@sveltejs/kit': ^2.50.1 '@sveltejs/package': ^2.5.7 '@sveltejs/vite-plugin-svelte': ^6.2.4 '@types/geojson': ^7946.0.16 maplibre-contour: ^0.1.0 maplibre-gl: 5.17.0 pmtiles: ^4.3.2 publint: ^0.3.17 svelte: ^5.48.5 svelte-check: ^4.3.5 terra-draw: ^1.23.1 terra-draw-maplibre-gl-adapter: ^1.2.3 typescript: ^5.9.3 vite: ^7.3.1 onlyBuiltDependencies: - esbuild - sharp - workerd ================================================ FILE: src/app.css ================================================ @import 'tailwindcss'; @custom-variant dark (&:where(.dark, .dark *)); @config '../tailwind.config.ts'; /* The default border color has changed to `currentColor` in Tailwind CSS v4, so we've added these compatibility styles to make sure everything still looks the same as it did with Tailwind CSS v3. If we ever want to remove these styles, we need to add an explicit border color utility to any element that depends on these defaults. */ @layer base { *, ::after, ::before, ::backdrop, ::file-selector-button { border-color: var(--color-gray-200, currentColor); } } @layer base { :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; --card: 0 0% 100%; --card-foreground: 222.2 84% 4.9%; --popover: 0 0% 100%; --popover-foreground: 222.2 84% 4.9%; --primary: 222.2 47.4% 11.2%; --primary-foreground: 210 40% 98%; --secondary: 210 40% 96.1%; --secondary-foreground: 222.2 47.4% 11.2%; --muted: 210 40% 96.1%; --muted-foreground: 215.4 16.3% 46.9%; --accent: 210 40% 96.1%; --accent-foreground: 222.2 47.4% 11.2%; --destructive: 0 72.22% 50.59%; --destructive-foreground: 210 40% 98%; --border: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%; --ring: 222.2 84% 4.9%; --radius: 0.5rem; } .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; --card: 222.2 84% 4.9%; --card-foreground: 210 40% 98%; --popover: 222.2 84% 4.9%; --popover-foreground: 210 40% 98%; --primary: 210 40% 98%; --primary-foreground: 222.2 47.4% 11.2%; --secondary: 217.2 32.6% 17.5%; --secondary-foreground: 210 40% 98%; --muted: 217.2 32.6% 17.5%; --muted-foreground: 215 20.2% 65.1%; --accent: 217.2 32.6% 17.5%; --accent-foreground: 210 40% 98%; --destructive: 0 62.8% 30.6%; --destructive-foreground: 210 40% 98%; --border: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%; --ring: 212.7 26.8% 83.9%; } :root { --docsearch-primary-color: #0e58c0; --docsearch-text-color: rgb(28, 30, 33); --docsearch-spacing: 12px; --docsearch-icon-stroke-width: 1.4; --docsearch-highlight-color: var(--docsearch-primary-color); --docsearch-muted-color: #666; --docsearch-container-background: rgba(101, 108, 133, 0.8); --docsearch-logo-color: rgba(84, 104, 255); /* modal */ --docsearch-modal-width: 560px; --docsearch-modal-height: 600px; --docsearch-modal-background: rgb(245, 246, 247); --docsearch-modal-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.5), 0 3px 8px 0 rgba(85, 90, 100, 1); /* searchbox */ --docsearch-searchbox-height: 56px; --docsearch-searchbox-background: transparent; --docsearch-searchbox-focus-background: #fff; --docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color); /* hit */ --docsearch-hit-height: 56px; --docsearch-hit-color: rgb(68, 73, 80); --docsearch-hit-active-color: #fff; --docsearch-hit-background: #fff; --docsearch-hit-shadow: 0 1px 3px 0 rgb(212, 217, 225); /* key */ --docsearch-key-gradient: linear-gradient(-225deg, rgb(213, 219, 228) 0%, rgb(248, 248, 248) 100%); --docsearch-key-shadow: inset 0 -2px 0 0 rgb(205, 205, 230), inset 0 0 1px 1px #fff, 0 1px 2px 1px rgba(30, 35, 90, 0.4); --docsearch-key-pressed-shadow: inset 0 -2px 0 0 #cdcde6, inset 0 0 1px 1px #fff, 0 1px 1px 0 rgba(30, 35, 90, 0.4); /* footer */ --docsearch-footer-height: 44px; --docsearch-footer-background: #fff; --docsearch-footer-shadow: 0 -1px 0 0 rgb(224, 227, 232), 0 -3px 6px 0 rgba(69, 98, 155, 0.12); } /* Darkmode */ html.dark { --docsearch-text-color: rgb(245, 246, 247); --docsearch-container-background: rgba(9, 10, 17, 0.8); --docsearch-modal-background: #151e2a; --docsearch-modal-shadow: inset 1px 1px 0 0 rgb(44, 46, 64), 0 3px 8px 0 rgb(0, 3, 9); --docsearch-searchbox-background: #000; --docsearch-searchbox-focus-background: #000; --docsearch-hit-color: rgb(190, 195, 201); --docsearch-hit-shadow: none; --docsearch-hit-background: rgb(9, 10, 17); --docsearch-key-gradient: linear-gradient(-26.5deg, #566272 0%, #31425b 100%); --docsearch-key-shadow: inset 0 -2px 0 0 rgb(40, 56, 85), inset 0 0 1px 1px rgb(81, 93, 125), 0 2px 2px 0 rgba(3, 5, 9, 0.3); --docsearch-key-pressed-shadow: inset 0 -2px 0 0 #283b55, inset 0 0 1px 1px #51617d, 0 1px 1px 0 #0305094d; --docsearch-footer-background: #1f2936; --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 86, 106, 0.5), 0 -4px 8px 0 rgba(0, 0, 0, 0.2); --docsearch-logo-color: rgb(255, 255, 255); --docsearch-muted-color: #aaa; } } @layer base { * { @apply border-border; } body { @apply bg-background text-foreground; } } ================================================ FILE: src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: src/content/CodeBlock.svelte ================================================
{@html shiki.codeToHtml(_content, { lang: 'svelte', theme: 'github-dark-default' })}
Our examples use Tailwind CSS and shadcn-svelte.
================================================ FILE: src/content/components/toc.ts ================================================ import type { Toc } from '$lib/components/types'; export const toc: Toc = [ { title: 'Map', items: { '/docs/components/MapLibre': 'MapLibre', '/docs/components/Image': 'Image', '/docs/components/Light': 'Light', '/docs/components/Projection': 'Projection', '/docs/components/Sky': 'Sky', '/docs/components/Sprite': 'Sprite', '/docs/components/Terrain': 'Terrain' } }, { title: 'Sources', items: { '/docs/components/CanvasSource': 'CanvasSource', '/docs/components/FeatureState': 'FeatureState', '/docs/components/GeoJSONSource': 'GeoJSONSource', '/docs/components/ImageSource': 'ImageSource', '/docs/components/RasterDEMTileSource': 'RasterDEMTileSource', '/docs/components/RasterTileSource': 'RasterTileSource', '/docs/components/RawSource': 'RawSource', '/docs/components/VectorTileSource': 'VectorTileSource', '/docs/components/VideoSource': 'VideoSource', '/docs/components/MapLibreContourSource': 'MapLibreContourSource (ext)' } }, { title: 'Layers', items: { '/docs/components/BackgroundLayer': 'BackgroundLayer', '/docs/components/CircleLayer': 'CircleLayer', '/docs/components/ColorReliefLayer': 'ColorReliefLayer', '/docs/components/CustomLayer': 'CustomLayer', '/docs/components/FillExtrusionLayer': 'FillExtrusionLayer', '/docs/components/HeatmapLayer': 'HeatmapLayer', '/docs/components/HillshadeLayer': 'HillshadeLayer', '/docs/components/LineLayer': 'LineLayer', '/docs/components/RasterLayer': 'RasterLayer', '/docs/components/RawLayer': 'RawLayer', '/docs/components/SymbolLayer': 'SymbolLayer' } }, { title: 'Global', items: { '/docs/components/Protocol': 'Protocol', '/docs/components/PMTilesProtocol': 'PMTilesProtocol (ext)' } }, { title: 'Marker', items: { '/docs/components/Marker': 'Marker', '/docs/components/Popup': 'Popup' } }, { title: 'Controls', items: { '/docs/components/AttributionControl': 'AttributionControl', '/docs/components/CustomControl': 'CustomControl', '/docs/components/FullScreenControl': 'FullScreenControl', '/docs/components/GeolocateControl': 'GeolocateControl', '/docs/components/GlobeControl': 'GlobeControl', '/docs/components/Hash': 'Hash', '/docs/components/LogoControl': 'LogoControl', '/docs/components/NavigationControl': 'NavigationControl', '/docs/components/ScaleControl': 'ScaleControl', '/docs/components/TerrainControl': 'TerrainControl', '/docs/components/DeckGLOverlay': 'DeckGLOverlay (ext)', '/docs/components/TerraDraw': 'TerraDraw (ext)' } }, { title: 'Utilities', items: { '/docs/components/ImageLoader': 'ImageLoader', '/docs/components/QueryRenderedFeatures': 'QueryRenderedFeatures', '/docs/components/QuerySourceFeatures': 'QuerySourceFeatures' } } ]; ================================================ FILE: src/content/docs/quickstart/Marker.svelte ================================================ ================================================ FILE: src/content/docs/quickstart/Simplest.svelte ================================================ ================================================ FILE: src/content/docs/quickstart/content.svelte.md ================================================ --- title: Quickstart description: Get started with svelte-maplibre-gl in just a few minutes. --- ## 1. Launch a SvelteKit Project Create a new SvelteKit project using the official [Svelte CLI](https://svelte.dev/docs/kit/creating-a-project). ```bash npx sv create myapp # Make sure to enable the Tailwind CSS add-on, # as our examples use it for styling. cd myapp npm install ``` ## 2. Install `svelte-maplibre-gl` ```bash npm install -D svelte-maplibre-gl ``` ## 3. Add the Simplest Map Now you can add the simplest MapLibre GL JS map to your `+page.svelte` file with just one line of code. ## 4. Put a Marker on the Map Let’s set an initial zoom and put a marker pin on the map. ================================================ FILE: src/content/docs/toc.ts ================================================ import type { Toc } from '$lib/components/types'; export const toc: Toc = [ { title: 'Overview', items: { '/docs/quickstart': 'Quickstart' // '/docs/Concept': 'Concept', } } ]; ================================================ FILE: src/content/examples/3d-buildings/Buildings3D.svelte ================================================ =', ['get', 'zoom'], 14], ['get', 'render_min_height'], 0] }} /> ================================================ FILE: src/content/examples/3d-buildings/content.svelte.md ================================================ --- title: 3D Buildings description: Use extrusions to display buildings' height in 3D. original: https://maplibre.org/maplibre-gl-js/docs/examples/3d-buildings/ --- ================================================ FILE: src/content/examples/3d-extrusion-floorplan/Floorplan.svelte ================================================ ================================================ FILE: src/content/examples/3d-extrusion-floorplan/content.svelte.md ================================================ --- title: 3D Floor Plan description: Create a 3D indoor map with the fill-extrude-height paint property. original: https://maplibre.org/maplibre-gl-js/docs/examples/3d-extrusion-floorplan/ --- ================================================ FILE: src/content/examples/animate-images/AnimateImages.svelte ================================================ ================================================ FILE: src/content/examples/animate-images/content.svelte.md ================================================ --- title: Animate a series of images description: Use a series of image sources to create an animation. orignal: https://maplibre.org/maplibre-gl-js/docs/examples/animate-images/ --- ================================================ FILE: src/content/examples/basestyle/BaseStyle.svelte ================================================
{#each STYLES as [name] (name)}
{/each}
{#if !globe} {/if} ================================================ FILE: src/content/examples/basestyle/content.svelte.md ================================================ --- title: Change Base Style description: This library efficiently preserves dynamic user contents even when the base style changes. --- ================================================ FILE: src/content/examples/canvas-source/Canvas.svelte ================================================ (animate = !animate)} > ================================================ FILE: src/content/examples/canvas-source/Circle.ts ================================================ export class Circle { constructor( public x: number, public y: number, public dx: number, public dy: number, public radius: number, public color: string ) {} draw(ctx: CanvasRenderingContext2D) { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); ctx.strokeStyle = this.color; ctx.stroke(); } update(ctx: CanvasRenderingContext2D) { if (this.x + this.radius > ctx.canvas.width || this.x - this.radius < 0) { this.dx = -this.dx; } if (this.y + this.radius > ctx.canvas.height || this.y - this.radius < 0) { this.dy = -this.dy; } this.x += this.dx; this.y += this.dy; this.draw(ctx); } } ================================================ FILE: src/content/examples/canvas-source/content.svelte.md ================================================ --- title: Canvas Source description: Add a canvas source to the map. original: https://maplibre.org/maplibre-gl-js/docs/examples/canvas-source/ --- ================================================ FILE: src/content/examples/clusters/Clusters.svelte ================================================
================================================ FILE: src/content/examples/clusters/content.svelte.md ================================================ --- title: Clusters description: Use MapLibre's built-in functions to visualize points as clusters. original: https://maplibre.org/maplibre-gl-js/docs/examples/cluster/ --- ================================================ FILE: src/content/examples/color-relief/ColorRelief.svelte ================================================
================================================ FILE: src/content/examples/color-relief/content.svelte.md ================================================ --- title: Color Relief description: Render hypsometric tints using DEM sources original: https://nathanmolson.github.io/color_relief/ --- ================================================ FILE: src/content/examples/complex/Complex.svelte ================================================
{`lat: ${center[1].toFixed(3)}, lng: ${center[0].toFixed(3)}, z: ${zoom.toFixed(1)}, pitch: ${pitch.toFixed(1)}, bearing: ${bearing.toFixed(1)}`}
marker: {`${markerLnglat.lat.toFixed(3)}, ${markerLnglat.lng.toFixed(3)}`}
{#if hash} {/if} {#if sky} {/if} {#if !globe} {/if} {#if hillshade} {/if} {#if showCities} {#if extrude} {:else} {/if} {/if} {#if heatmap} {:else} {/if} {#snippet content()} 🐸 {/snippet} {`${markerLnglat.lat.toFixed(3)}, ${markerLnglat.lng.toFixed(3)}`} ================================================ FILE: src/content/examples/complex/content.svelte.md ================================================ --- title: Complex description: A showcase of various reactive features. --- ================================================ FILE: src/content/examples/contour/Contour.svelte ================================================ {#snippet children(demSource)} ', ['get', 'level'], 0]} layout={{ 'symbol-placement': 'line', 'text-size': 12, 'text-field': ['number-format', ['get', 'ele'], {}] }} paint={{ 'text-halo-color': 'white', 'text-halo-width': 1 }} /> {/snippet} ================================================ FILE: src/content/examples/contour/content.svelte.md ================================================ --- title: Contour Lines description: Render contour lines from a raster DEM source using maplibre-contour original: https://maplibre.org/maplibre-gl-js/docs/examples/add-contour-lines/ --- ================================================ FILE: src/content/examples/cursor/Cursor.svelte ================================================ (cursor = e.features![0].properties.cursor)} onmouseleave={() => (cursor = undefined)} paint={{ 'circle-radius': 12, 'circle-color': '#007cbf', 'circle-stroke-color': '#fff', 'circle-stroke-width': 3 }} /> ================================================ FILE: src/content/examples/cursor/content.svelte.md ================================================ --- title: Change Cursor description: Change the cursor style on hover --- ================================================ FILE: src/content/examples/custom-control/CustomControl.svelte ================================================
Arbitrary HTML
({center.lat.toFixed(4)}, {center.lng.toFixed(4)})
{#if isTerrainVisible} {/if} {#if isHillshadeVisible} {/if}
================================================ FILE: src/content/examples/custom-control/MyControl.ts ================================================ interface MyControlConstructorOptions { toggleTerrain: () => boolean; toggleHillshade: () => boolean; } class MyControl implements maplibregl.IControl { private _container: HTMLElement | undefined; private _toggleTerrain: () => boolean; private _toggleHillshade: () => boolean; constructor(options: MyControlConstructorOptions) { this._toggleTerrain = options.toggleTerrain; this._toggleHillshade = options.toggleHillshade; } onAdd() { this._container = document.createElement('div'); this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group p-2 rounded flex w-[240px] gap-x-2'; const toggleTerrain = document.createElement('button'); toggleTerrain.textContent = 'Disable Terrain'; toggleTerrain.type = 'button'; toggleTerrain.style.backgroundColor = 'red'; toggleTerrain.style.color = 'white'; toggleTerrain.style.width = '50%'; toggleTerrain.style.height = '100%'; toggleTerrain.style.borderRadius = '0.25rem'; toggleTerrain.addEventListener('click', () => { const newState = this._toggleTerrain(); toggleTerrain.textContent = newState ? 'Disable Terrain' : 'Enable Terrain'; }); const toggleHillshade = document.createElement('button'); toggleHillshade.textContent = 'Disable Hillshade'; toggleHillshade.type = 'button'; toggleHillshade.style.backgroundColor = 'blue'; toggleHillshade.style.color = 'white'; toggleHillshade.style.height = '100%'; toggleHillshade.style.width = '50%'; toggleHillshade.style.borderRadius = '0.25rem'; toggleHillshade.addEventListener('click', () => { const newState = this._toggleHillshade(); toggleHillshade.textContent = newState ? 'Disable Hillshade' : 'Enable Hillshade'; }); this._container.appendChild(toggleTerrain); this._container.appendChild(toggleHillshade); return this._container!; } onRemove() { if (this._container && this._container.parentNode) { this._container.parentNode.removeChild(this._container); } } } export { MyControl }; ================================================ FILE: src/content/examples/custom-control/content.svelte.md ================================================ --- title: Custom Control description: Easily create user-defined controls with a native look and feel. --- ================================================ FILE: src/content/examples/custom-layer/CustomLayer.svelte ================================================ ================================================ FILE: src/content/examples/custom-layer/content.svelte.md ================================================ --- title: Custom Layer description: Use a custom layer to draw simple WebGL content on a globe. original: https://maplibre.org/maplibre-gl-js/docs/examples/globe-custom-simple/ --- ================================================ FILE: src/content/examples/custom-protocol/CustomProtocol.svelte ================================================ ================================================ FILE: src/content/examples/custom-protocol/content.svelte.md ================================================ --- title: Custom Protocols description: Add a custom resource loading function to handle a custom URL scheme. --- ================================================ FILE: src/content/examples/deckgl-overlay/DeckGL.svelte ================================================ d.source, getTargetPosition: (d) => d.target, getSourceColor: [0, 255, 100], getTargetColor: [0, 190, 255], getWidth: 5 }) ]} /> ================================================ FILE: src/content/examples/deckgl-overlay/content.svelte.md ================================================ --- title: deck.gl Overlay description: Interleaving deck.gl with MapLibre layers original: https://deck.gl/gallery/maplibre-overlay --- ================================================ FILE: src/content/examples/dynamic-image/DynamicImage.svelte ================================================ ================================================ FILE: src/content/examples/dynamic-image/content.svelte.md ================================================ --- title: Dynamic Image description: Add an icon to the map that was generated at runtime. original: https://maplibre.org/maplibre-gl-js/docs/examples/add-image-generated/ --- ================================================ FILE: src/content/examples/fullscreen/Fullscreen.svelte ================================================ ================================================ FILE: src/content/examples/fullscreen/content.svelte.md ================================================ --- title: Fullscreen description: View a fullscreen map original: https://maplibre.org/maplibre-gl-js/docs/examples/fullscreen/ --- ================================================ FILE: src/content/examples/geolocate/Geolocate.svelte ================================================
{logString}
log('trackuserlocationstart')} ontrackuserlocationend={() => log('trackuserlocationend')} ongeolocate={(ev) => log(`geolocate ${JSON.stringify(ev.coords, null, 2)}`)} />
================================================ FILE: src/content/examples/geolocate/content.svelte.md ================================================ --- title: Locate the User description: Locate the User original: https://maplibre.org/maplibre-gl-js/docs/examples/locate-user/ --- ================================================ FILE: src/content/examples/global-state/Plain.svelte ================================================
================================================ FILE: src/content/examples/global-state/content.svelte.md ================================================ --- title: Global State description: Filter a layer symbols based on user input using setGlobalStateProperty(). original: https://maplibre.org/maplibre-gl-js/docs/examples/filter-layer-symbols-using-global-state/ --- ================================================ FILE: src/content/examples/globe-atmosphere/Globe.svelte ================================================
================================================ FILE: src/content/examples/globe-atmosphere/content.svelte.md ================================================ --- title: Globe with an atmosphere description: Display a globe with an atmosphere. original: https://maplibre.org/maplibre-gl-js/docs/examples/globe-atmosphere/ --- ================================================ FILE: src/content/examples/hover-styles/HoverStyles.svelte ================================================ { // Listen to mousemove events to track the hovered feature hoveredFeature = ev.features?.[0]; lnglat = ev.lngLat; // cursor location }} onmouseleave={() => (hoveredFeature = undefined)} /> {#if hoveredFeature} {hoveredFeature.properties.STATE_NAME} {/if} ================================================ FILE: src/content/examples/hover-styles/content.svelte.md ================================================ --- title: Hover Styles description: Use events and feature states to create a per feature hover effect. original: https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/ --- ================================================ FILE: src/content/examples/image-loader/Images.svelte ================================================ ================================================ FILE: src/content/examples/image-loader/content.svelte.md ================================================ --- title: Load Images from URLs description: Utility for loading images from URLs original: https://maplibre.org/maplibre-gl-js/docs/examples/add-image-stretchable/ --- ================================================ FILE: src/content/examples/limit-interaction/LimitInteraction.svelte ================================================
================================================ FILE: src/content/examples/limit-interaction/content.svelte.md ================================================ --- title: Limit Map Interactions description: Set the zoom/pitch range and toggle UI handlers on the map. original: https://maplibre.org/maplibre-gl-js/docs/examples/toggle-interaction-handlers/ --- ================================================ FILE: src/content/examples/marker-popup/MarkerAndPopup.svelte ================================================
marker: {lngLatText}
{#snippet content()}
🐶
{lngLatText}
{/snippet} {lngLatText}
================================================ FILE: src/content/examples/marker-popup/content.svelte.md ================================================ --- title: Marker and Popup description: Control marker and popup states using Svelte’s reactivity. --- ================================================ FILE: src/content/examples/plain/Plain.svelte ================================================ ================================================ FILE: src/content/examples/plain/content.svelte.md ================================================ --- title: Plain Map description: A minimal example showing only the base map. --- ================================================ FILE: src/content/examples/pmtiles/PMTiles.svelte ================================================ ================================================ FILE: src/content/examples/pmtiles/content.svelte.md ================================================ --- title: PMTiles Protocol description: Uses the PMTiles plugin and the custom protocol to present a map. original: https://maplibre.org/maplibre-gl-js/docs/examples/pmtiles/ --- ================================================ FILE: src/content/examples/query-features/Query.svelte ================================================
{#if mode == 'source'} {#snippet children(feature: maplibregl.MapGeoJSONFeature)} {#if feature.geometry.type === 'Point'} {/if} {/snippet} {/if} {#if mode == 'rendered'} {#snippet children(feature: maplibregl.MapGeoJSONFeature)} {#if feature.geometry.type === 'Point'} {/if} {/snippet} {/if}
Source Rendered
    {#each features as feature (feature.id)}
  • {feature.properties.title}
  • {/each}
    {#each features as feature (feature.id)}
  • {feature.properties.title}
  • {/each}
================================================ FILE: src/content/examples/query-features/content.svelte.md ================================================ --- title: Query Features description: Query source and rendered features to place markers and display a list. --- ================================================ FILE: src/content/examples/side-by-side/SideBySide.svelte ================================================
{#each MODES as mode (mode)}
{/each}
(point = { x: ev.offsetX, y: ev.offsetY })} >
================================================ FILE: src/content/examples/side-by-side/content.svelte.md ================================================ --- title: Side by Side description: Synchronize two maps. original: https://visgl.github.io/react-maplibre/examples/side-by-side --- ================================================ FILE: src/content/examples/terradraw/TerraDraw.svelte ================================================ (selected = featureId)} ondeselect={() => (selected = null)} onfinish={() => (mode = 'select')} />
{#each modeNames as modeName (modeName)} {/each} {#if selected} {/if}
================================================ FILE: src/content/examples/terradraw/content.svelte.md ================================================ --- title: Terra Draw description: Use Terra Draw to draw a geometry in various forms such as point, line or polygon on your map. --- ================================================ FILE: src/content/examples/terrain/Terrain.svelte ================================================ {#if skyEnabled} {/if}
Terrain Sky
{#if hillshadeMethod === 'standard'}
{/if}
{#if !['standard', 'igor'].includes(hillshadeMethod)}
{/if}
================================================ FILE: src/content/examples/terrain/content.svelte.md ================================================ --- title: 3D Terrain and Sky description: Show elevation in actual 3D with the sky. original: https://maplibre.org/maplibre-gl-js/docs/examples/sky-with-fog-and-terrain/ --- ================================================ FILE: src/content/examples/threejs-model/CustomLayer.svelte ================================================ ================================================ FILE: src/content/examples/threejs-model/content.svelte.md ================================================ --- title: 3D model with three.js description: Use a custom style layer with three.js to add a 3D model to the map. original: https://maplibre.org/maplibre-gl-js/docs/examples/globe-3d-model/ --- ================================================ FILE: src/content/examples/toc.ts ================================================ import type { Toc } from '$lib/components/types'; export const toc: Toc = [ { title: 'Basic', items: { '/examples/plain': 'Plain Map', '/examples/complex': 'Complex', '/examples/marker-popup': 'Marker and Popup', '/examples/basestyle': 'Change Base Style', '/examples/hover-styles': 'Hover Styles', '/examples/clusters': 'Clusters', '/examples/limit-interaction': 'Limit Map Interactions', '/examples/animate-images': 'Animate a Series of Images', '/examples/video-on-a-map': 'Video on a Map', '/examples/fullscreen': 'Fullscreen', '/examples/geolocate': 'Locate the User', '/examples/cursor': 'Change Cursor' } }, { title: 'Styles', items: { '/examples/terrain': '3D Terrain and Sky', '/examples/color-relief': 'Color Relief', '/examples/globe-atmosphere': 'Globe with an Atmosphere', '/examples/3d-buildings': '3D Buildings', '/examples/global-state': 'Global State' } }, { title: 'Utilities', items: { '/examples/image-loader': 'Load Images from URLs', '/examples/query-features': 'Query Features' } }, { title: 'Techniques', items: { '/examples/side-by-side': 'Side by Side', '/examples/3d-extrusion-floorplan': '3D Floor Plan' } }, { title: 'Advanced', items: { '/examples/custom-control': 'Custom Control', '/examples/custom-protocol': 'Custom Protocols', '/examples/canvas-source': 'Canvas Source', '/examples/custom-layer': 'Custom Layer', '/examples/dynamic-image': 'Dynamic Image', '/examples/threejs-model': '3D model with three.js' } }, { title: 'Extensions', items: { '/examples/pmtiles': 'PMTiles Protocol', '/examples/deckgl-overlay': 'deck.gl Overlay', '/examples/contour': 'Contour Lines', '/examples/terradraw': 'Terra Draw' } } ]; ================================================ FILE: src/content/examples/video-on-a-map/Video.svelte ================================================ ================================================ FILE: src/content/examples/video-on-a-map/content.svelte.md ================================================ --- title: Video on a map description: Display a video. original: https://maplibre.org/maplibre-gl-js/docs/examples/video-on-a-map/ --- ================================================ FILE: src/demo.spec.ts ================================================ import { describe, it, expect } from 'vitest'; describe('sum test', () => { it('adds 1 + 2 to equal 3', () => { expect(1 + 2).toBe(3); }); }); ================================================ FILE: src/lib/assets/fonts/LICENSE.txt ================================================ Copyright (c) 2023 Vercel, in collaboration with basement.studio This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION AND CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. ================================================ FILE: src/lib/assets/fonts/geist.css ================================================ @font-face { font-family: 'Geist'; src: url('./geist.woff2') format('woff2'); font-display: swap; } @font-face { font-family: 'Geist Mono'; src: url('./geist-mono.woff2') format('woff2'); font-display: swap; } ================================================ FILE: src/lib/assets/icons/GitHub.svelte ================================================ ================================================ FILE: src/lib/components/Index.svelte ================================================ ================================================ FILE: src/lib/components/types.ts ================================================ export type Toc = { title: string; items: Record; }[]; ================================================ FILE: src/lib/components/ui/badge/badge.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/badge/index.ts ================================================ export { default as Badge } from "./badge.svelte"; export { badgeVariants, type BadgeVariant } from "./badge.svelte"; ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte ================================================ ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-item.svelte ================================================
  • {@render children?.()}
  • ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-link.svelte ================================================ {#if child} {@render child({ props: attrs })} {:else} {@render children?.()} {/if} ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-list.svelte ================================================
      {@render children?.()}
    ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-page.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte ================================================ ================================================ FILE: src/lib/components/ui/breadcrumb/breadcrumb.svelte ================================================ ================================================ FILE: src/lib/components/ui/breadcrumb/index.ts ================================================ import Root from "./breadcrumb.svelte"; import Ellipsis from "./breadcrumb-ellipsis.svelte"; import Item from "./breadcrumb-item.svelte"; import Separator from "./breadcrumb-separator.svelte"; import Link from "./breadcrumb-link.svelte"; import List from "./breadcrumb-list.svelte"; import Page from "./breadcrumb-page.svelte"; export { Root, Ellipsis, Item, Separator, Link, List, Page, // Root as Breadcrumb, Ellipsis as BreadcrumbEllipsis, Item as BreadcrumbItem, Separator as BreadcrumbSeparator, Link as BreadcrumbLink, List as BreadcrumbList, Page as BreadcrumbPage, }; ================================================ FILE: src/lib/components/ui/button/button.svelte ================================================ {#if href} {@render children?.()} {:else} {/if} ================================================ FILE: src/lib/components/ui/button/index.ts ================================================ import Root, { type ButtonProps, type ButtonSize, type ButtonVariant, buttonVariants, } from "./button.svelte"; export { Root, type ButtonProps as Props, // Root as Button, buttonVariants, type ButtonProps, type ButtonSize, type ButtonVariant, }; ================================================ FILE: src/lib/components/ui/checkbox/checkbox.svelte ================================================ {#snippet children({ checked, indeterminate })}
    {#if checked} {:else if indeterminate} {/if}
    {/snippet}
    ================================================ FILE: src/lib/components/ui/checkbox/index.ts ================================================ import Root from "./checkbox.svelte"; export { Root, // Root as Checkbox, }; ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte ================================================ {#snippet children({ checked, indeterminate })} {#if indeterminate} {:else} {/if} {@render childrenProp?.()} {/snippet} ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte ================================================
    {@render children?.()}
    ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte ================================================ {#snippet children({ checked })} {#if checked} {/if} {@render childrenProp?.({ checked })} {/snippet} ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/dropdown-menu.svelte ================================================ ================================================ FILE: src/lib/components/ui/dropdown-menu/index.ts ================================================ import Root from "./dropdown-menu.svelte"; import Sub from "./dropdown-menu-sub.svelte"; import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; import Content from "./dropdown-menu-content.svelte"; import Group from "./dropdown-menu-group.svelte"; import Item from "./dropdown-menu-item.svelte"; import Label from "./dropdown-menu-label.svelte"; import RadioGroup from "./dropdown-menu-radio-group.svelte"; import RadioItem from "./dropdown-menu-radio-item.svelte"; import Separator from "./dropdown-menu-separator.svelte"; import Shortcut from "./dropdown-menu-shortcut.svelte"; import Trigger from "./dropdown-menu-trigger.svelte"; import SubContent from "./dropdown-menu-sub-content.svelte"; import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; import GroupHeading from "./dropdown-menu-group-heading.svelte"; import Portal from "./dropdown-menu-portal.svelte"; export { CheckboxGroup, CheckboxItem, Content, Portal, Root as DropdownMenu, CheckboxGroup as DropdownMenuCheckboxGroup, CheckboxItem as DropdownMenuCheckboxItem, Content as DropdownMenuContent, Portal as DropdownMenuPortal, Group as DropdownMenuGroup, Item as DropdownMenuItem, Label as DropdownMenuLabel, RadioGroup as DropdownMenuRadioGroup, RadioItem as DropdownMenuRadioItem, Separator as DropdownMenuSeparator, Shortcut as DropdownMenuShortcut, Sub as DropdownMenuSub, SubContent as DropdownMenuSubContent, SubTrigger as DropdownMenuSubTrigger, Trigger as DropdownMenuTrigger, GroupHeading as DropdownMenuGroupHeading, Group, GroupHeading, Item, Label, RadioGroup, RadioItem, Root, Separator, Shortcut, Sub, SubContent, SubTrigger, Trigger, }; ================================================ FILE: src/lib/components/ui/label/index.ts ================================================ import Root from "./label.svelte"; export { Root, // Root as Label, }; ================================================ FILE: src/lib/components/ui/label/label.svelte ================================================ ================================================ FILE: src/lib/components/ui/radio-group/index.ts ================================================ import Root from "./radio-group.svelte"; import Item from "./radio-group-item.svelte"; export { Root, Item, // Root as RadioGroup, Item as RadioGroupItem, }; ================================================ FILE: src/lib/components/ui/radio-group/radio-group-item.svelte ================================================ {#snippet children({ checked })}
    {#if checked} {/if}
    {/snippet}
    ================================================ FILE: src/lib/components/ui/radio-group/radio-group.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/index.ts ================================================ import Root from "./select.svelte"; import Group from "./select-group.svelte"; import Label from "./select-label.svelte"; import Item from "./select-item.svelte"; import Content from "./select-content.svelte"; import Trigger from "./select-trigger.svelte"; import Separator from "./select-separator.svelte"; import ScrollDownButton from "./select-scroll-down-button.svelte"; import ScrollUpButton from "./select-scroll-up-button.svelte"; import GroupHeading from "./select-group-heading.svelte"; import Portal from "./select-portal.svelte"; export { Root, Group, Label, Item, Content, Trigger, Separator, ScrollDownButton, ScrollUpButton, GroupHeading, Portal, // Root as Select, Group as SelectGroup, Label as SelectLabel, Item as SelectItem, Content as SelectContent, Trigger as SelectTrigger, Separator as SelectSeparator, ScrollDownButton as SelectScrollDownButton, ScrollUpButton as SelectScrollUpButton, GroupHeading as SelectGroupHeading, Portal as SelectPortal, }; ================================================ FILE: src/lib/components/ui/select/select-content.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/select/select-group-heading.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/select/select-group.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/select-item.svelte ================================================ {#snippet children({ selected, highlighted })} {#if selected} {/if} {#if childrenProp} {@render childrenProp({ selected, highlighted })} {:else} {label || value} {/if} {/snippet} ================================================ FILE: src/lib/components/ui/select/select-label.svelte ================================================
    {@render children?.()}
    ================================================ FILE: src/lib/components/ui/select/select-portal.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/select-scroll-down-button.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/select-scroll-up-button.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/select-separator.svelte ================================================ ================================================ FILE: src/lib/components/ui/select/select-trigger.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/select/select.svelte ================================================ ================================================ FILE: src/lib/components/ui/separator/index.ts ================================================ import Root from "./separator.svelte"; export { Root, // Root as Separator, }; ================================================ FILE: src/lib/components/ui/separator/separator.svelte ================================================ ================================================ FILE: src/lib/components/ui/slider/index.ts ================================================ import Root from "./slider.svelte"; export { Root, // Root as Slider, }; ================================================ FILE: src/lib/components/ui/slider/slider.svelte ================================================ {#snippet children({ thumbs })} {#each thumbs as thumb (thumb)} {/each} {/snippet} ================================================ FILE: src/lib/components/ui/switch/index.ts ================================================ import Root from "./switch.svelte"; export { Root, // Root as Switch, }; ================================================ FILE: src/lib/components/ui/switch/switch.svelte ================================================ ================================================ FILE: src/lib/components/ui/table/index.ts ================================================ import Root from "./table.svelte"; import Body from "./table-body.svelte"; import Caption from "./table-caption.svelte"; import Cell from "./table-cell.svelte"; import Footer from "./table-footer.svelte"; import Head from "./table-head.svelte"; import Header from "./table-header.svelte"; import Row from "./table-row.svelte"; export { Root, Body, Caption, Cell, Footer, Head, Header, Row, // Root as Table, Body as TableBody, Caption as TableCaption, Cell as TableCell, Footer as TableFooter, Head as TableHead, Header as TableHeader, Row as TableRow, }; ================================================ FILE: src/lib/components/ui/table/table-body.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-caption.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-cell.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-footer.svelte ================================================ tr]:last:border-b-0", className)} {...restProps} > {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-head.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-header.svelte ================================================ {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table-row.svelte ================================================ svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", className )} {...restProps} > {@render children?.()} ================================================ FILE: src/lib/components/ui/table/table.svelte ================================================
    {@render children?.()}
    ================================================ FILE: src/lib/components/ui/tabs/index.ts ================================================ import Root from "./tabs.svelte"; import Content from "./tabs-content.svelte"; import List from "./tabs-list.svelte"; import Trigger from "./tabs-trigger.svelte"; export { Root, Content, List, Trigger, // Root as Tabs, Content as TabsContent, List as TabsList, Trigger as TabsTrigger, }; ================================================ FILE: src/lib/components/ui/tabs/tabs-content.svelte ================================================ ================================================ FILE: src/lib/components/ui/tabs/tabs-list.svelte ================================================ ================================================ FILE: src/lib/components/ui/tabs/tabs-trigger.svelte ================================================ ================================================ FILE: src/lib/components/ui/tabs/tabs.svelte ================================================ ================================================ FILE: src/lib/utils.ts ================================================ import { clsx, type ClassValue } from 'clsx'; import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } // eslint-disable-next-line @typescript-eslint/no-explicit-any export type WithoutChild = T extends { child?: any } ? Omit : T; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type WithoutChildren = T extends { children?: any } ? Omit : T; export type WithoutChildrenOrChild = WithoutChildren>; export type WithElementRef = T & { ref?: U | null }; ================================================ FILE: src/routes/+layout.server.ts ================================================ // export async function load({ setHeaders }) { // setHeaders({ 'Cache-Control': 'max-age=300, stale-while-revalidate=300' }); // } ================================================ FILE: src/routes/+layout.svelte ================================================
    {@render children()}

    © {currentYear} Svelte Maplibre GL contributors

    Svelte MapLibre GL ================================================ FILE: src/routes/+page.svelte ================================================

    Svelte MapLibre GL

    Svelte 5 wrapper for 🗺 MapLibre GL JS — Build interactive web maps effortlessly with Svelte’s reactive and declarative power 🚀

    Explore Examples

    hero

    Installation

    npm install --save-dev svelte-maplibre-gl

    Contents

    Features

    • The most declarative and reactive MapLibre GL JS experience, powered by Svelte 5
    • A flexible, minimally opinionated API design that is suitable for both beginners and experienced MapLibre users
    • Traditional imperative MapLibre GL JS usage remains fully supported
    Svelte MapLibre GL - Build interactive web maps effortlessly with MapLibre GL JS and Svelte ================================================ FILE: src/routes/DarkModeSelector.svelte ================================================ Toggle theme setMode('light')}>Light setMode('dark')}>Dark resetMode()}>System ================================================ FILE: src/routes/GlobalToc.svelte ================================================

    Svelte MapLibre GL

    ================================================ FILE: src/routes/Header.svelte ================================================

    ================================================ FILE: src/routes/ViewTransition.svelte ================================================ ================================================ FILE: src/routes/docs/+layout.ts ================================================ // export const prerender = true; ================================================ FILE: src/routes/docs/+page.svelte ================================================
    ================================================ FILE: src/routes/docs/[slug]/+layout.svelte ================================================
    {@render children()}
    ================================================ FILE: src/routes/docs/[slug]/+page.svelte ================================================
    Docs {data.meta.title}

    {data.meta.title}

    {data.meta.description}

    {data.meta.title} - Svelte MapLibre GL ================================================ FILE: src/routes/docs/[slug]/+page.ts ================================================ import { error } from '@sveltejs/kit'; import type { Component } from 'svelte'; import { browser } from '$app/environment'; import { createHighlighter, createJavaScriptRegexEngine, createOnigurumaEngine } from 'shiki'; import svelte from 'shiki/langs/svelte.mjs'; import dark from 'shiki/themes/github-dark-default.mjs'; const shiki = createHighlighter({ themes: [dark], langs: [svelte], engine: browser ? createOnigurumaEngine(import('shiki/wasm')) : createJavaScriptRegexEngine() }); export const load = async ({ params }) => { const { slug } = params; try { const post = (await import(`$content/docs/${slug}/content.svelte.md`)) as { default: Component; metadata: { title: string; description: string; }; }; return { Content: post.default, meta: { ...post.metadata, slug }, shiki: await shiki }; } catch { error(404, `Docs '${slug}' not found`); } }; ================================================ FILE: src/routes/docs/components/+page.svelte ================================================ ================================================ FILE: src/routes/docs/components/[slug]/_+layout.svelte_ ================================================
    {@render children()}
    ================================================ FILE: src/routes/docs/components/[slug]/_+page.svelte_ ================================================
    API Reference {data.title}

    {data.title}

    API Reference (beta) for {`<${data.targetComponent} />`}

    Property Type Description {#each requiredProps as [name, prop] (name)} {#if !prop.isOptional} {/if} {/each} {#each optionalProps as [name, prop] (name)} {#if prop.isOptional} {/if} {/each}
    {data.title} - Svelte MapLibre GL ================================================ FILE: src/routes/docs/components/[slug]/_+page.ts_ ================================================ import { error } from '@sveltejs/kit'; // import { parse } from 'svelte-docgen'; type ParsedComponent = ReturnType; const loaders: Record Promise<{ default: ParsedComponent }>> = Object.fromEntries([ ...Object.entries(import.meta.glob('$svmlgl/**/*.svelte', { query: '?docgen' })).map(([key, value]) => { const name = key.match(/\/([^/]+)\.svelte$/)?.[1]; return [name, value] as const; }), ...Object.entries(import.meta.glob('$svmlglext/**/*.svelte', { query: '?docgen' })).map(([key, value]) => { const name = key.match(/\/([^/]+)\.svelte$/)?.[1]; return [name, value] as const; }) ]); export const load = async ({ params }) => { const { slug } = params; const loader = loaders[slug](); if (!loader) { error(404, `Component '${slug}' not found`); } const doc = (await loader).default; return { title: slug, targetComponent: slug, doc }; }; ================================================ FILE: src/routes/docs/components/[slug]/_Prop.svelte_ ================================================ {name}
    {#if prop.isOptional} optional {:else} required {/if} {#if prop.isBindable} bindable {/if}
    {@html formatType(prop.type, types)}
    {#if prop.description} {formatDescription(prop.description)} {:else} - {/if}
    {#if !prop.isBindable && prop.default && typeof prop.default !== 'string' && prop.default.kind !== 'undefined'}
    default: {@html formatType(prop.default, types)}
    {/if}
    ================================================ FILE: src/routes/docs/components/[slug]/_utils.ts_ ================================================ import type { DisplayPart, TypeOrRef, Types } from 'svelte-docgen/doc'; export function formatType(type: TypeOrRef, types: Types): string { const visited = new Set(); const [res] = _format(type, types, visited, true); return res; } function _formatWrapper( type: TypeOrRef, types: Types, visited: Set, ignoreUndefined = false ): [string, boolean] { if (visited.has(type)) { return ['...', false]; } visited.add(type); const [formatted, needParens] = _format(type, types, visited, ignoreUndefined); visited.delete(type); return [formatted, needParens]; } function _format(type: TypeOrRef, types: Types, visited: Set, ignoreUndefined = false): [string, boolean] { if (typeof type === 'string') { return _formatWrapper(types.get(type)!, types, visited, ignoreUndefined); } if ('alias' in type && type.alias) { let name = formatQualifiedName(type.alias); if ( !type.alias.endsWith('Like') && (type.kind !== 'union' || type.types.some((t) => typeof t === 'string' || t.kind !== 'literal')) ) { if (type.aliasTypeArgs?.length) { name += formatTypeArgs(type.aliasTypeArgs, types, visited); } if (type.kind === 'function') { name += '()'; } return [name, false]; } } if (type.kind === 'array') { const [res, needParens] = _formatWrapper(type.element, types, visited); return needParens ? [`(${res})[]`, false] : [`${res}[]`, false]; } else if (type.kind === 'tuple') { const elements = type.elements.map((t) => _formatWrapper(t, types, visited)[0]).join(', '); return [`[${elements}]`, false]; } else if (type.kind === 'literal') { switch (type.subkind) { case 'string': return [`"${type.value}"`, false]; case 'number': return [`${type.value}`, false]; case 'boolean': return [`${type.value}`, false]; default: return [type.subkind, false]; } } else if (type.kind === 'constructible') { let name = formatQualifiedName(type.name, 'classes'); if (type.typeArgs?.length) { name += formatTypeArgs(type.typeArgs, types, visited); } return [name, false]; } else if (type.kind === 'function') { if (type.name === '"svelte".Snippet') { let name = 'Snippet'; if (type.typeArgs?.length) { name += formatTypeArgs(type.typeArgs, types, visited); } return [name, false]; } if (type.calls.length !== 1) { return ['function', false]; } const call = type.calls[0]; const params = call.parameters .map((p) => { const optional = p.isOptional ? '?' : ''; return `${p.name}${optional}: ${_formatWrapper(p.type, types, visited)[0]}`; }) .join(', '); return [`(${params}) => ${_formatWrapper(call.returns, types, visited)[0]}`, true]; } else if (type.kind === 'union') { const res = type.types .filter((t) => !ignoreUndefined || typeof t === 'string' || t.kind !== 'undefined') .map((t) => _formatWrapper(t, types, visited)[0]) .join(' | '); return [res, false]; } else if (type.kind === 'intersection') { const res = type.types.map((t) => _formatWrapper(t, types, visited)[0]).join(' | '); return [res, true]; } else if (type.kind === 'interface') { if (type.members.size === 0) { return ['{}', false]; } const members = type.members .entries() .map(([name, m]) => { const type = _formatWrapper(m.type, types, visited, m.isOptional)[0]; const optional = m.isOptional ? '?' : ''; return ` ${name}${optional}: ${type}`; }) .toArray() .join(',\n'); return [`{\n${members}\n}`, false]; } else if (type.kind === 'type-parameter') { return [formatQualifiedName(type.name), false]; } return [type.kind, false]; } function formatTypeArgs(typeArgs: TypeOrRef[], types: Types, visited: Set): string { const args = typeArgs.map((t) => _formatWrapper(t, types, visited)[0]).join(', '); return `<${args}>`; } const MDN_API = new Set([ 'CSSStyleDeclaration', 'GeolocateEvent', 'GeolocationPosition', 'GeolocationPositionError', 'HTMLCanvasElement', 'HTMLDivElement', 'HTMLElement', 'HTMLImageElement', 'ImageBitmap', 'ImageData', 'MouseEvent', 'TouchEvent', 'WebGLRenderingContext', 'WebGL2RenderingContext', 'WheelEvent' ]); const MDN_OBJECTS = new Set(['SharedArrayBuffer', 'ArrayBuffer', 'Uint8Array', 'Uint8ClampedArray']); function formatQualifiedName(name: string, link: string = 'type-aliases'): string { let alias = name; const lastDotIndex = name.lastIndexOf('.'); let prefix = ''; if (lastDotIndex !== -1) { prefix = name.slice(0, lastDotIndex); alias = name.slice(lastDotIndex + 1); } if (MDN_API.has(alias)) { return `${alias}`; } if (MDN_OBJECTS.has(alias)) { return `${alias}`; } if (alias === 'Map$1') { return `Map`; } if (prefix.includes('/maplibre-gl"')) { return `${alias}`; } return alias; } export function formatDescription(description: DisplayPart[]): string { return description .filter((p) => p.kind === 'text') .map((part) => part.text) .join(''); } ================================================ FILE: src/routes/docs/components/components.json ================================================ { "components": [ "AttributionControl", "BackgroundLayer", "CanvasSource", "CircleLayer", "ColorReliefLayer", "CustomControl", "CustomLayer", "FeatureState", "FillExtrusionLayer", "FillLayer", "FullScreenControl", "GeoJSONSource", "GeolocateControl", "GlobeControl", "Hash", "HeatmapLayer", "HillshadeLayer", "Image", "ImageLoader", "ImageSource", "Light", "LineLayer", "LogoControl", "MapLibre", "Marker", "NavigationControl", "Popup", "Projection", "Protocol", "QueryRenderedFeatures", "QuerySourceFeatures", "RasterDEMTileSource", "RasterLayer", "RasterTileSource", "RawLayer", "RawSource", "ScaleControl", "Sky", "Sprite", "SymbolLayer", "Terrain", "TerrainControl", "VectorTileSource", "VideoSource" ], "extensions": { "@svelte-maplibre-gl/contour": ["MapLibreContourSource"], "@svelte-maplibre-gl/deckgl": ["DeckGLOverlay"], "@svelte-maplibre-gl/pmtiles": ["PMTilesProtocol"], "@svelte-maplibre-gl/terradraw": ["TerraDraw"] } } ================================================ FILE: src/routes/examples/+layout.ts ================================================ export const prerender = true; ================================================ FILE: src/routes/examples/+page.svelte ================================================
    ================================================ FILE: src/routes/examples/[slug]/+layout.svelte ================================================
    {@render children()}
    ================================================ FILE: src/routes/examples/[slug]/+page.svelte ================================================
    Examples {data.meta.title}

    {data.meta.title}

    {data.meta.description}

    {#if data.meta.original}

    Based on: {data.meta.original}

    {/if}
    {data.meta.title} - Svelte MapLibre GL ================================================ FILE: src/routes/examples/[slug]/+page.ts ================================================ import { error } from '@sveltejs/kit'; import type { Component } from 'svelte'; import { browser } from '$app/environment'; import { createHighlighter, createJavaScriptRegexEngine, createOnigurumaEngine } from 'shiki'; import svelte from 'shiki/langs/svelte.mjs'; import dark from 'shiki/themes/github-dark-default.mjs'; const shiki = createHighlighter({ themes: [dark], langs: [svelte], engine: browser ? createOnigurumaEngine(import('shiki/wasm')) : createJavaScriptRegexEngine() }); export const load = async ({ params }) => { const { slug } = params; try { const post = (await import(`$content/examples/${slug}/content.svelte.md`)) as { default: Component; metadata: { title: string; description?: string; original?: string; }; }; return { Content: post.default, meta: { ...post.metadata, slug }, shiki: await shiki }; } catch { error(404, `Example '${slug}' not found`); } }; ================================================ FILE: src/routes/sitemap.xml/+server.ts ================================================ import { toc as docsToc } from '$content/docs/toc.js'; import { toc as exampleToc } from '$content/examples/toc.js'; // import { toc as componentToc } from '$content/components/toc.js'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async ({ request }) => { const urls: string[] = []; const origin = new URL(request.url).origin; urls.push(origin + '/'); urls.push(origin + '/examples/'); for (const section of exampleToc) { for (const [path] of Object.entries(section.items)) { urls.push(origin + path); } } // urls.push(origin + '/docs/components/'); // for (const section of componentToc) { // for (const [path] of Object.entries(section.items)) { // urls.push(origin + path); // } // } for (const section of docsToc) { for (const [path] of Object.entries(section.items)) { urls.push(origin + path); } } return new Response( ` ${urls.map((url) => `${url}`).join('\n')} `.trim(), { headers: { 'Content-Type': 'application/xml' } } ); }; ================================================ FILE: svelte-maplibre-gl/CHANGELOG.md ================================================ # svelte-maplibre-gl ## 1.0.3 ### Patch Changes - 6b3cd54: Handle feature.id being undefined in QueryRenderedFeatures.svelte ## 1.0.2 ### Patch Changes - 608c2b5: Fix: add missing source prop to CircleLayer ## 1.0.1 ### Patch Changes - a5cc3ef: Fix: GeolocationControl causes infinite $effect loop with latest Svelte ================================================ FILE: svelte-maplibre-gl/package.json ================================================ { "name": "svelte-maplibre-gl", "version": "1.0.3", "license": "(MIT OR Apache-2.0)", "description": "Build interactive web maps effortlessly with MapLibre GL JS and Svelte", "repository": { "url": "https://github.com/MIERUNE/svelte-maplibre-gl" }, "homepage": "https://svelte-maplibre-gl.mierune.dev/", "keywords": [ "map", "svelte", "maplibre", "maplibre-gl", "maplibre-gl-js", "geospatial", "mapping", "gis" ], "scripts": { "dev": "vite dev", "build": "vite build && npm run prepack", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", "prepack": "svelte-kit sync && svelte-package && publint", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --compiler-warnings 'state_referenced_locally:ignore'", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check ." }, "files": [ "dist", "!dist/**/*.test.*", "!dist/**/*.spec.*" ], "sideEffects": [ "**/*.css" ], "svelte": "./dist/index.js", "types": "./dist/index.d.ts", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js" } }, "peerDependencies": { "maplibre-gl": "^5.0.0 || ^4.0.0", "svelte": ">=5.0.0" }, "devDependencies": { "@sveltejs/kit": "catalog:", "@sveltejs/package": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "@types/geojson": "catalog:", "maplibre-gl": "catalog:", "publint": "catalog:", "svelte": "catalog:", "svelte-check": "catalog:", "typescript": "catalog:", "vite": "catalog:" } } ================================================ FILE: svelte-maplibre-gl/src/app.d.ts ================================================ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {}; ================================================ FILE: svelte-maplibre-gl/src/app.html ================================================ %sveltekit.head%
    %sveltekit.body%
    ================================================ FILE: svelte-maplibre-gl/src/lib/contexts.svelte.ts ================================================ import type { Map as MapLibre, Marker, AddLayerObject, SourceSpecification, CanvasSourceSpecification, StyleSpecification, SkySpecification, TerrainSpecification, ProjectionSpecification, LightSpecification } from 'maplibre-gl'; import { setContext, getContext } from 'svelte'; const MAP_CONTEXT_KEY = Symbol('MapLibre map context'); const SOURCE_CONTEXT_KEY = Symbol('MapLibre source context'); const LAYER_CONTEXT_KEY = Symbol('MapLibre layer context'); const MARKER_CONTEXT_KEY = Symbol('MapLibre marker context'); // https://svelte.dev/docs/svelte/$state#Classes class MapContext { /** Map instance */ _map: MapLibre | null = $state.raw(null); /** Callbacks to be called when the map style is loaded */ private _listener?: maplibregl.Listener = undefined; private _pending: ((map: maplibregl.Map) => void)[] = []; /** Names of layers dynamically added */ userLayers: Set = new Set(); /** Names of sources dynamically added */ userSources: Set = new Set(); /** Terrain specification of the current base style */ baseTerrain?: TerrainSpecification | undefined; /** Sky specification set by user */ userTerrain?: TerrainSpecification | undefined; /** Sky specification of the current base style */ baseSky?: SkySpecification | undefined; /** Sky specification set by user */ userSky?: SkySpecification | undefined; /** Light specification of the current base style */ baseLight?: LightSpecification | undefined; /** Light specification set by user */ userLight?: LightSpecification | undefined; /** Projection specification of the current base style */ baseProjection?: ProjectionSpecification | undefined; /** Projection specification set by user */ userProjection?: ProjectionSpecification | undefined; get map() { return this._map; } set map(value: maplibregl.Map | null) { if (this._listener) { this._map?.off('styledata', this._listener); this._listener = undefined; } this._map = value; if (this._map) { this._listener = this._onstyledata.bind(this); this._map.on('styledata', this._listener); } } addLayer(addLayerObject: AddLayerObject, beforeId?: string) { if (!this.map) throw new Error('Map is not initialized'); this.userLayers.add(addLayerObject.id); this.waitForStyleLoaded((map) => { map.addLayer(addLayerObject, beforeId); }); } removeLayer(id: string) { if (!this.map) throw new Error('Map is not initialized'); this.userLayers.delete(id); this.waitForStyleLoaded((map) => { map.removeLayer(id); }); } addSource(id: string, source: SourceSpecification | CanvasSourceSpecification) { this.userSources.add(id); this.waitForStyleLoaded((map) => { map.addSource(id, source); }); } removeSource(id: string) { this.userSources.delete(id); this.waitForStyleLoaded((map) => { map.removeSource(id); }); } /** Wait for the style to be loaded before calling the function */ waitForStyleLoaded(func: (map: maplibregl.Map) => void) { if (!this.map) { return; } if (this.map.style._loaded) { // style is already loaded func(this.map); } else { // we need to wait the style to be loaded this._pending.push(func); } } private _onstyledata(ev: maplibregl.MapStyleDataEvent) { const map = ev.target; if (map?.style._loaded) { for (const func of this._pending) { // call pending tasks func(map); } this._pending = []; } } setStyle(style: string | StyleSpecification | null) { const { userSources: addedSources, userLayers: addedLayers } = this; if (!style) { this.map?.setStyle(null); return; } this.map?.setStyle($state.snapshot(style) as string | StyleSpecification, { // Preserves user styles when the base style changes transformStyle: (previous, next) => { this.baseLight = next.light; this.baseProjection = next.projection; this.baseSky = next.sky; this.baseTerrain = next.terrain; if (!previous) { return next; } const sources = next.sources; for (const [key, value] of Object.entries(previous.sources!)) { if (addedSources.has(key)) { sources[key] = value; } } const userLayers = previous.layers!.filter((layer) => addedLayers.has(layer.id)); const layers = [...next.layers!, ...userLayers]; return { ...next, light: this.userLight || this.baseLight, projection: this.userProjection || this.baseProjection, sky: this.userSky || this.baseSky, terrain: this.userTerrain || this.baseTerrain, sources, layers }; } }); } } export function prepareMapContext(): MapContext { const mapCtx = new MapContext(); setContext(MAP_CONTEXT_KEY, mapCtx); return mapCtx; } export function getMapContext(): MapContext { const mapCtx = getContext(MAP_CONTEXT_KEY); if (!mapCtx) throw new Error('Map context not found'); return mapCtx; } // https://svelte.dev/docs/svelte/$state#Classes class SourceContext { /** sourceId */ id: string = $state(''); } export function prepareSourceContext(): SourceContext { const sourceCtx = new SourceContext(); setContext(SOURCE_CONTEXT_KEY, sourceCtx); return sourceCtx; } export function getSourceContext(): SourceContext { const sourceCtx = getContext(SOURCE_CONTEXT_KEY); if (!sourceCtx || !sourceCtx.id) throw new Error('Source context not found'); return sourceCtx; } class LayerContext { id: string = $state(''); } export function prepareLayerContext(): LayerContext { const layerCtx = new LayerContext(); setContext(LAYER_CONTEXT_KEY, layerCtx); return layerCtx; } export function getLayerContext(): LayerContext | null { const layerCtx = getContext(LAYER_CONTEXT_KEY); if (!layerCtx || !layerCtx.id) throw new Error('Layer context not found'); return layerCtx; } class MarkerContext { marker: Marker | null = $state.raw(null); } export function prepareMarkerContext(): MarkerContext { const markerCtx = new MarkerContext(); setContext(MARKER_CONTEXT_KEY, markerCtx); return markerCtx; } export function getMarkerContext(): MarkerContext | null { const markerCtx = getContext(MARKER_CONTEXT_KEY); if (!markerCtx) { return null; } return markerCtx; } ================================================ FILE: svelte-maplibre-gl/src/lib/controls/AttributionControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/CustomControl.svelte ================================================ {#if !givenControl}
    {@render children?.()}
    {/if} ================================================ FILE: svelte-maplibre-gl/src/lib/controls/FullScreenControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/GeolocateControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/GlobeControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/Hash.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/LogoControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/NavigationControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/ScaleControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/controls/TerrainControl.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/global/Protocol.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/index.ts ================================================ // Reexport your entry components here // global export { default as Protocol } from './global/Protocol.svelte'; // map export { default as MapLibre } from './map/MapLibre.svelte'; export { default as Map } from './map/MapLibre.svelte'; // alias export { default as Sky } from './map/Sky.svelte'; export { default as Light } from './map/Light.svelte'; export { default as Projection } from './map/Projection.svelte'; export { default as Terrain } from './map/Terrain.svelte'; export { default as Image } from './map/Image.svelte'; export { default as Sprite } from './map/Sprite.svelte'; // sources export { default as VectorTileSource } from './sources/VectorTileSource.svelte'; export { default as RasterTileSource } from './sources/RasterTileSource.svelte'; export { default as RasterDEMTileSource } from './sources/RasterDEMTileSource.svelte'; export { default as GeoJSONSource } from './sources/GeoJSONSource.svelte'; export { default as ImageSource } from './sources/ImageSource.svelte'; export { default as VideoSource } from './sources/VideoSource.svelte'; export { default as CanvasSource } from './sources/CanvasSource.svelte'; export { default as RawSource } from './sources/RawSource.svelte'; export { default as FeatureState } from './sources/FeatureState.svelte'; // layers export { default as FillLayer } from './layers/FillLayer.svelte'; export { default as LineLayer } from './layers/LineLayer.svelte'; export { default as CircleLayer } from './layers/CircleLayer.svelte'; export { default as FillExtrusionLayer } from './layers/FillExtrusionLayer.svelte'; export { default as SymbolLayer } from './layers/SymbolLayer.svelte'; export { default as HeatmapLayer } from './layers/HeatmapLayer.svelte'; export { default as RasterLayer } from './layers/RasterLayer.svelte'; export { default as HillshadeLayer } from './layers/HillshadeLayer.svelte'; export { default as ColorReliefLayer } from './layers/ColorReliefLayer.svelte'; export { default as BackgroundLayer } from './layers/BackgroundLayer.svelte'; export { default as RawLayer } from './layers/RawLayer.svelte'; export { default as CustomLayer } from './layers/CustomLayer.svelte'; // markers export { default as Marker } from './markers/Marker.svelte'; export { default as Popup } from './markers/Popup.svelte'; // controls export { default as AttributionControl } from './controls/AttributionControl.svelte'; export { default as GeolocateControl } from './controls/GeolocateControl.svelte'; export { default as GlobeControl } from './controls/GlobeControl.svelte'; export { default as NavigationControl } from './controls/NavigationControl.svelte'; export { default as FullScreenControl } from './controls/FullScreenControl.svelte'; export { default as TerrainControl } from './controls/TerrainControl.svelte'; export { default as ScaleControl } from './controls/ScaleControl.svelte'; export { default as LogoControl } from './controls/LogoControl.svelte'; export { default as CustomControl } from './controls/CustomControl.svelte'; export { default as Hash } from './controls/Hash.svelte'; // utilities export { default as ImageLoader } from './utilities/ImageLoader.svelte'; export { default as QuerySourceFeatures } from './utilities/QuerySourceFeatures.svelte'; export { default as QueryRenderedFeatures } from './utilities/QueryRenderedFeatures.svelte'; // contexts export { getMapContext, getSourceContext, getMarkerContext } from './contexts.svelte.js'; ================================================ FILE: svelte-maplibre-gl/src/lib/layers/BackgroundLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/CircleLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/ColorReliefLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/CustomLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/FillExtrusionLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/FillLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/HeatmapLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/HillshadeLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/LineLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/RasterLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/RawLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/SymbolLayer.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/layers/common.ts ================================================ import maplibregl from 'maplibre-gl'; export type MapLayerEventProps = { [K in keyof maplibregl.MapLayerEventType as `on${K}`]?: (ev: maplibregl.MapLayerEventType[K]) => void; }; ================================================ FILE: svelte-maplibre-gl/src/lib/map/Image.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/map/Light.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/map/MapLibre.svelte ================================================
    {#if map} {@render children?.(map)} {/if}
    ================================================ FILE: svelte-maplibre-gl/src/lib/map/Projection.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/map/Sky.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/map/Sprite.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/map/Terrain.svelte ================================================ ================================================ FILE: svelte-maplibre-gl/src/lib/markers/Marker.svelte ================================================ {#if content}
    {@render content()}
    {/if} {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/markers/Popup.svelte ================================================
    {@render children?.()}
    ================================================ FILE: svelte-maplibre-gl/src/lib/sources/CanvasSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/FeatureState.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/GeoJSONSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/ImageSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/RasterDEMTileSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/RasterTileSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/RawSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/VectorTileSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/sources/VideoSource.svelte ================================================ {@render children?.()} ================================================ FILE: svelte-maplibre-gl/src/lib/types.ts ================================================ export type Listener = (event: T) => void; export type Event = { type: N; target: T; }; ================================================ FILE: svelte-maplibre-gl/src/lib/utilities/ImageLoader.svelte ================================================ {#if initialLoaded} {@render children?.()} {/if} ================================================ FILE: svelte-maplibre-gl/src/lib/utilities/QueryRenderedFeatures.svelte ================================================ {#if children}{#each features as feature (feature.id)}{@render children(feature)}{/each}{/if} ================================================ FILE: svelte-maplibre-gl/src/lib/utilities/QuerySourceFeatures.svelte ================================================ {#if children}{#each features as feature (feature.id)}{@render children(feature)}{/each}{/if} ================================================ FILE: svelte-maplibre-gl/src/lib/utils.ts ================================================ import maplibregl from 'maplibre-gl'; let layerIdCounter = 0; let sourceIdCounter = 0; export function generateLayerID() { return `svmlgl-layer-${layerIdCounter++}`; } export function generateSourceID() { return `svmlgl-source-${sourceIdCounter++}`; } /** * Set an event listener on an Evented object, and return a function that will remove the listener. * * Intended to be used within the $effect rune. */ export function resetEventListener( evented: maplibregl.Evented | null | undefined, type: string, listener: maplibregl.Listener | undefined ) { if (listener) { evented?.on(type, listener); } const prevListener = listener; return () => { if (prevListener) { evented?.off(type, prevListener); } }; } /** * Set a Layer event listener on the Map object, and return a function that will remove the listener. * * Intended to be used within the $effect rune. */ export function resetLayerEventListener( map: maplibregl.Map | null, type: keyof maplibregl.MapLayerEventType, layer: string, listener: maplibregl.Listener | undefined ) { if (listener) { map?.on(type, layer, listener); } const prevListener = listener; return () => { if (prevListener) { map?.off(type, layer, prevListener); } }; } export function formatLngLat(target: maplibregl.LngLatLike, lnglat: maplibregl.LngLat): maplibregl.LngLatLike { if (Array.isArray(target)) { return [lnglat.lng, lnglat.lat]; } else if ('lon' in target) { return { lon: lnglat.lng, lat: lnglat.lat }; } else { return { lng: lnglat.lng, lat: lnglat.lat }; } } ================================================ FILE: svelte-maplibre-gl/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: vitePreprocess(), kit: { // No adapter needed for library packages } }; export default config; ================================================ FILE: svelte-maplibre-gl/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler" } } ================================================ FILE: svelte-maplibre-gl/vite.config.ts ================================================ import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [sveltekit()] }); ================================================ FILE: svelte.config.js ================================================ // mdsvex import { mdsvex, escapeSvelte } from 'mdsvex'; import { createHighlighter } from 'shiki'; const theme = 'github-dark-default'; const highlighter = await createHighlighter({ themes: [theme], langs: ['javascript', 'typescript', 'svelte', 'bash'] }); /** @type {import('mdsvex').MdsvexOptions} */ const mdsvexOptions = { highlight: { highlighter: async (code, lang = 'text') => { const html = escapeSvelte(highlighter.codeToHtml(code, { lang, theme })); return `{@html \`${html}\` }`; } }, extensions: ['.svelte.md', '.svx'] }; // SvelteKit import adapter from '@sveltejs/adapter-cloudflare'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: [vitePreprocess(), mdsvex(mdsvexOptions)], kit: { // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), alias: { $content: 'src/content', $svmlgl: 'svelte-maplibre-gl/src/lib', $svmlglext: 'extensions/' } }, extensions: ['.svelte', '.svx', '.svelte.md'] }; export default config; ================================================ FILE: tailwind.config.ts ================================================ import defaultTheme from 'tailwindcss/defaultTheme'; import type { Config } from 'tailwindcss'; import tailwindcssAnimate from 'tailwindcss-animate'; import tailwindcssTypography from '@tailwindcss/typography'; const config: Config = { content: ['./src/**/*.{html,js,svelte,ts}'], theme: { container: { center: true, padding: '2rem', screens: { '2xl': '1400px' } }, extend: { colors: { border: 'hsl(var(--border) / )', input: 'hsl(var(--input) / )', ring: 'hsl(var(--ring) / )', background: 'hsl(var(--background) / )', foreground: 'hsl(var(--foreground) / )', primary: { DEFAULT: 'hsl(var(--primary) / )', foreground: 'hsl(var(--primary-foreground) / )' }, secondary: { DEFAULT: 'hsl(var(--secondary) / )', foreground: 'hsl(var(--secondary-foreground) / )' }, destructive: { DEFAULT: 'hsl(var(--destructive) / )', foreground: 'hsl(var(--destructive-foreground) / )' }, muted: { DEFAULT: 'hsl(var(--muted) / )', foreground: 'hsl(var(--muted-foreground) / )' }, accent: { DEFAULT: 'hsl(var(--accent) / )', foreground: 'hsl(var(--accent-foreground) / )' }, popover: { DEFAULT: 'hsl(var(--popover) / )', foreground: 'hsl(var(--popover-foreground) / )' }, card: { DEFAULT: 'hsl(var(--card) / )', foreground: 'hsl(var(--card-foreground) / )' }, sidebar: { DEFAULT: 'hsl(var(--sidebar-background))', foreground: 'hsl(var(--sidebar-foreground))', primary: 'hsl(var(--sidebar-primary))', 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))', accent: 'hsl(var(--sidebar-accent))', 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))', border: 'hsl(var(--sidebar-border))', ring: 'hsl(var(--sidebar-ring))' } }, borderRadius: { xl: 'calc(var(--radius) + 4px)', lg: 'var(--radius)', md: 'calc(var(--radius) - 2px)', sm: 'calc(var(--radius) - 4px)' }, fontFamily: { sans: ['Geist', ...defaultTheme.fontFamily.sans], mono: ['Geist Mono', ...defaultTheme.fontFamily.mono] }, keyframes: { 'accordion-down': { from: { height: '0' }, to: { height: 'var(--radix-accordion-content-height)' } }, 'accordion-up': { from: { height: 'var(--radix-accordion-content-height)' }, to: { height: '0' } }, 'caret-blink': { '0%,70%,100%': { opacity: '1' }, '20%,50%': { opacity: '0' } } }, animation: { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', 'caret-blink': 'caret-blink 1.25s ease-out infinite' } } }, plugins: [tailwindcssTypography, tailwindcssAnimate] }; export default config; ================================================ FILE: tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, // "module": "NodeNext", "moduleResolution": "bundler" // "types": ["vite-plugin-svelte-docgen"] }, "exclude": ["node_modules", "dist", "**/dist", "extensions/*/dist", "svelte-maplibre-gl/dist"] } ================================================ FILE: turbo.json ================================================ { "$schema": "https://turbo.build/schema.json", "ui": "tui", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".svelte-kit/**"], "cache": true }, "prepack": { "dependsOn": ["^prepack"], "outputs": ["dist/**"], "cache": true }, "check": { "dependsOn": ["^build", "^check"] }, "check:watch": {}, "lint": {}, "test": {}, "test:e2e": {}, "preview": {} } } ================================================ FILE: vite.config.ts ================================================ import { sveltekit } from '@sveltejs/kit/vite'; import tailwindcss from '@tailwindcss/vite'; import { searchForWorkspaceRoot } from 'vite'; // import svelteDocgenPlugin from 'vite-plugin-svelte-docgen'; import { defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [ //svelteDocgenPlugin(), tailwindcss(), sveltekit() ], server: { fs: { allow: [searchForWorkspaceRoot(process.cwd())] } }, resolve: { alias: { path: 'pathe' } }, test: { include: ['src/**/*.{test,spec}.{js,ts}'] } }); ================================================ FILE: wrangler.jsonc ================================================ { "name": "svelte-maplibre-gl", "main": ".svelte-kit/cloudflare/_worker.js", "compatibility_date": "2025-05-30", "assets": { "binding": "ASSETS", "directory": ".svelte-kit/cloudflare" } }