├── .github
└── CODEOWNERS
├── packages
├── website
│ ├── .eslintrc.json
│ ├── styles
│ │ └── globals.css
│ ├── public
│ │ ├── icon.png
│ │ ├── favicon.ico
│ │ └── vercel.svg
│ ├── pages
│ │ ├── examples
│ │ │ ├── meta.en-US.json
│ │ │ ├── advanced
│ │ │ │ ├── meta.en-US.json
│ │ │ │ ├── retina.en-US.mdx
│ │ │ │ ├── dynamic-points.en-US.mdx
│ │ │ │ ├── declaratively-move-view.en-US.mdx
│ │ │ │ ├── dynamic-styles.en-US.mdx
│ │ │ │ ├── performance.en-US.mdx
│ │ │ │ └── kitchen-sink.en-US.mdx
│ │ │ └── openlayers
│ │ │ │ ├── simple.en-US.mdx
│ │ │ │ ├── meta.en-US.json
│ │ │ │ ├── preload.en-US.mdx
│ │ │ │ ├── reprojection-wgs84.en-US.mdx
│ │ │ │ ├── xyz.en-US.mdx
│ │ │ │ ├── wms-tiled.en-US.mdx
│ │ │ │ ├── static-image.en-US.mdx
│ │ │ │ ├── accessible.en-US.mdx
│ │ │ │ ├── xyz-retina.en-US.mdx
│ │ │ │ ├── bing-maps.en-US.mdx
│ │ │ │ ├── zoomify.en-US.mdx
│ │ │ │ ├── reprojection-image.en-US.mdx
│ │ │ │ ├── turf.en-US.mdx
│ │ │ │ ├── dynamic-data.en-US.mdx
│ │ │ │ ├── popup.en-US.mdx
│ │ │ │ ├── draw-and-modify-features.en-US.mdx
│ │ │ │ ├── icon.en-US.mdx
│ │ │ │ ├── cluster.en-US.mdx
│ │ │ │ ├── draw-shapes.en-US.mdx
│ │ │ │ ├── select-features.en-US.mdx
│ │ │ │ ├── image-filter.en-US.mdx
│ │ │ │ ├── geojson.en-US.mdx
│ │ │ │ └── mapbox-vector-tiles.en-US.mdx
│ │ ├── _middleware.tsx
│ │ ├── docs
│ │ │ ├── meta.en-US.json
│ │ │ ├── imperative-fallback.en-US.mdx
│ │ │ ├── hooks.en-US.mdx
│ │ │ ├── getting-started.en-US.mdx
│ │ │ ├── components.en-US.mdx
│ │ │ └── props.en-US.mdx
│ │ ├── _app.tsx
│ │ ├── meta.en-US.json
│ │ └── index.en-US.mdx
│ ├── postcss.config.js
│ ├── next-env.d.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── package.json
│ ├── theme.config.js
│ ├── next.config.js
│ └── README.md
└── react-openlayers-fiber
│ ├── src
│ ├── test
│ │ ├── setup.ts
│ │ └── utils.tsx
│ ├── __snapshots__
│ │ ├── test-rig.vitest.tsx.snap
│ │ └── test-rig.test.tsx.snap
│ ├── context.tsx
│ ├── index.ts
│ ├── test-rig.test.tsx
│ ├── test-rig.vitest.tsx
│ ├── map.tsx
│ ├── events.ts
│ ├── types.ts
│ └── catalogue.ts
│ ├── babel.config.cjs
│ ├── vitest.config.ts
│ ├── cjs.swcrc
│ ├── esm.swcrc
│ ├── jest.config.js
│ ├── next.config.js
│ ├── jest.config.swc.js
│ ├── package.json
│ └── README.md
├── .gitattributes
├── .yarnrc.yml
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── package.json
├── tsconfig.json
├── .gitignore
├── LICENSE
└── readme.md
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @crubier
2 |
--------------------------------------------------------------------------------
/packages/website/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/test/setup.ts:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom'
2 |
--------------------------------------------------------------------------------
/packages/website/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/packages/website/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crubier/react-openlayers-fiber/HEAD/packages/website/public/icon.png
--------------------------------------------------------------------------------
/packages/website/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crubier/react-openlayers-fiber/HEAD/packages/website/public/favicon.ico
--------------------------------------------------------------------------------
/packages/website/pages/examples/meta.en-US.json:
--------------------------------------------------------------------------------
1 | {
2 | "openlayers": "OpenLayers examples",
3 | "advanced": "Advanced examples"
4 | }
5 |
--------------------------------------------------------------------------------
/packages/website/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/packages/website/pages/_middleware.tsx:
--------------------------------------------------------------------------------
1 |
2 | // @ts-ignore
3 | import { locales } from "nextra/locales";
4 |
5 | export const middleware = locales;
--------------------------------------------------------------------------------
/packages/website/pages/docs/meta.en-US.json:
--------------------------------------------------------------------------------
1 | {
2 | "getting-started": "Getting Started",
3 | "components": "Components",
4 | "props": "Props",
5 | "hooks": "Hooks",
6 | "imperative-fallback": "Imperative Fallback"
7 | }
8 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/__snapshots__/test-rig.vitest.tsx.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1
2 |
3 | exports[`Test setup > can run dom snapshot test 1`] = `
4 |
9 | `;
10 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | defaultSemverRangePrefix: ""
2 |
3 | logFilters:
4 | - code: YN0002
5 | level: error
6 | - code: YN0060
7 | level: warning
8 |
9 | nodeLinker: node-modules
10 |
11 | yarnPath: .yarn/releases/yarn-3.2.0.cjs
12 |
--------------------------------------------------------------------------------
/packages/website/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "esbenp.prettier-vscode",
5 | ],
6 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
7 | "unwantedRecommendations": []
8 | }
9 |
--------------------------------------------------------------------------------
/packages/website/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import 'nextra-theme-docs/style.css'
3 |
4 | import type { AppProps } from 'next/app'
5 |
6 | function MyApp({ Component, pageProps }: AppProps) {
7 | return
8 | }
9 |
10 | export default MyApp
11 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/advanced/meta.en-US.json:
--------------------------------------------------------------------------------
1 | {
2 | "declaratively-move-view": "Declaratively move view",
3 | "dynamic-styles": "Dynamic styles",
4 | "dynamic-points": "Dynamic points",
5 | "retina": "Retina",
6 | "performance": "Performance",
7 | "kitchen-sink": "Kitchen Sink"
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@react-ol/root",
3 | "version": "1.0.0",
4 | "repository": "git@github.com:crubier/crubier/react-openlayers-fiber.git",
5 | "engines": {
6 | "node": ">=14.0.0",
7 | "yarn": ">=1.0.0"
8 | },
9 | "workspaces": [
10 | "packages/*"
11 | ],
12 | "packageManager": "yarn@3.2.0"
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/pages/meta.en-US.json:
--------------------------------------------------------------------------------
1 | {
2 | "index": {
3 | "title": "Introduction",
4 | "type": "page",
5 | "theme": {
6 | "sidebar": false
7 | }
8 | },
9 | "docs": {
10 | "title": "Docs",
11 | "type": "page"
12 | },
13 | "examples": {
14 | "title": "Examples",
15 | "type": "page"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/website/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [
3 | "./pages/**/*.{js,ts,jsx,tsx,md,mdx}",
4 | "./components/**/*.{js,ts,jsx,tsx,md,mdx}",
5 | "./theme.config.js",
6 | "./styles.css",
7 | ],
8 | theme: {
9 | extend: {},
10 | },
11 | plugins: [
12 | require('@tailwindcss/forms')
13 | ],
14 | }
15 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/context.tsx:
--------------------------------------------------------------------------------
1 | import { createContext, useContext } from "react";
2 | import { Map as OlMap } from "ol";
3 |
4 | export const MapContext = createContext(null);
5 |
6 | export const useMap = () => useContext(MapContext);
7 | export const MapConsumer = MapContext.Consumer;
8 | export const MapProvider = MapContext.Provider;
9 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/babel.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "presets": [
3 | // [
4 | // "@babel/preset-typescript",
5 | // {
6 | // "isTSX": true,
7 | // "allExtensions": true
8 | // }
9 | // ],
10 | ["@babel/preset-react", {}],
11 | ["@babel/preset-env", { "targets": { "node": "current" } }]
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/__snapshots__/test-rig.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Test setup > can run dom snapshot test 1`] = `
4 |
9 | `;
10 |
11 | exports[`Test setup can run dom snapshot test 1`] = `
12 |
17 | `;
18 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitest/config'
2 | import react from '@vitejs/plugin-react'
3 |
4 | export default defineConfig({
5 | plugins: [react()],
6 | test: {
7 | globals: true,
8 | environment: 'jsdom',
9 | include: ['**/*.vitest.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
10 | setupFiles: './src/test/setup.ts',
11 | },
12 | })
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/cjs.swcrc:
--------------------------------------------------------------------------------
1 | {
2 | "module": {
3 | "type": "commonjs",
4 | "strict": false,
5 | "strictMode": true,
6 | "lazy": false,
7 | "noInterop": false
8 | },
9 | "jsc": {
10 | "parser": {
11 | "syntax": "typescript",
12 | "tsx": true,
13 | "decorators": true,
14 | "dynamicImport": true
15 | },
16 | "target": "es5"
17 | },
18 | "minify": false
19 | }
20 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/esm.swcrc:
--------------------------------------------------------------------------------
1 | {
2 | "module": {
3 | "type": "es6",
4 | "strict": false,
5 | "strictMode": true,
6 | "lazy": false,
7 | "noInterop": false
8 | },
9 | "jsc": {
10 | "parser": {
11 | "syntax": "typescript",
12 | "tsx": true,
13 | "decorators": true,
14 | "dynamicImport": true
15 | },
16 | "target": "es2016"
17 | },
18 | "minify": false
19 | }
20 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Catalogue as CatalogueBase,
3 | CatalogueKey as CatalogueKeyBase,
4 | Kind as KindBase,
5 | } from "./catalogue";
6 |
7 | export { catalogue, extend } from "./catalogue";
8 |
9 | export type Catalogue = CatalogueBase;
10 |
11 | export type CatalogueKey = CatalogueKeyBase;
12 | export type Kind = KindBase;
13 |
14 | export { MapContext, MapProvider, MapConsumer, useMap } from "./context";
15 |
16 | export { Map } from "./map";
17 |
18 | export * from "./types";
19 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/test/utils.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/export */
2 | import { render } from '@testing-library/react'
3 |
4 | const customRender = (ui: React.ReactElement, options = {}) =>
5 | render(ui, {
6 | // wrap provider(s) here if needed
7 | wrapper: ({ children }) => children,
8 | ...options,
9 | })
10 |
11 | export * from '@testing-library/react'
12 | export { default as userEvent } from '@testing-library/user-event'
13 | // override render export
14 | export { customRender as render }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "esModuleInterop": true,
10 | "module": "commonjs",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react",
15 | "incremental": true
16 | },
17 | "include": ["**/*.ts", "**/*.tsx"]
18 | // "exclude": ["**/node_modules", "**/dist"]
19 | }
20 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": [
3 | {
4 | "type": "node",
5 | "name": "vscode-jest-tests",
6 | "request": "launch",
7 | "console": "integratedTerminal",
8 | "internalConsoleOptions": "neverOpen",
9 | "disableOptimisticBPs": true,
10 | "cwd": "${workspaceFolder}",
11 | "runtimeExecutable": "yarn",
12 | "args": ["test", "--runInBand", "--watchAll=false"],
13 | "outFiles": [
14 | "${workspaceFolder}/packages/*/src/**/*.ts?(x)",
15 | "!**/node_modules/**"
16 | ]
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/jest.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * For a detailed explanation regarding each configuration property and type check, visit:
3 | * https://jestjs.io/docs/configuration
4 | */
5 |
6 | export default {
7 | preset: 'ts-jest',
8 | testEnvironment: "jsdom",
9 | transform: { "^.+\\.(js|jsx|ts|tsx|mjs)$": "babel-jest" },
10 | transformIgnorePatterns: [
11 | '^.+\\.module\\.(css|sass|scss)$',
12 | // '^.*/node_modules/(?!(ol/|labelgun/|@mapbox/mapbox-gl-style-spec/|mapbox-to-ol-style/|ol-mapbox-style/|geotiff/|fetch-blob/)).*$'
13 | '/node_modules/(?!(ol/))'
14 | ],
15 | };
16 |
--------------------------------------------------------------------------------
/packages/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true
17 | },
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19 | "exclude": ["node_modules", ".next"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/website/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env.local
30 | .env.development.local
31 | .env.test.local
32 | .env.production.local
33 |
34 | # vercel
35 | .vercel
36 |
37 | # typescript
38 | *.tsbuildinfo
39 |
40 | .env
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | experimental: {
4 | // Prefer loading of ES Modules over CommonJS
5 | // @link {https://nextjs.org/blog/next-11-1#es-modules-support|Blog 11.1.0}
6 | // @link {https://github.com/vercel/next.js/discussions/27876|Discussion}
7 | esmExternals: true,
8 | // Experimental monorepo support
9 | // @link {https://github.com/vercel/next.js/pull/22867|Original PR}
10 | // @link {https://github.com/vercel/next.js/discussions/26420|Discussion}
11 | externalDir: true,
12 | },
13 | reactStrictMode: true,
14 | }
15 |
16 | export default nextConfig;
17 |
--------------------------------------------------------------------------------
/packages/website/pages/docs/imperative-fallback.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Imperative Fallback
2 |
3 | The [`ref` prop](/docs/props#ref-prop) allows to access the underlying OpenLayers object imperatively.
4 |
5 | For example, to access the `ol.View` OpenLayers object instance, you can use the `` prop:
6 |
7 | ```tsx
8 | export const AccessibleMap = () => {
9 | const viewRef = useRef();
10 | return (
11 |
12 |
19 |
25 |
26 | );
27 | };
28 | ```
29 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/simple.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Simple Map
2 |
3 | See https://openlayers.org/en/latest/examples/simple.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExampleSimple = () => (
10 |
16 | );
17 |
18 |
19 |
20 | ```tsx
21 | import React from "react";
22 | import "ol/ol.css";
23 | import { Map } from "@react-ol/fiber";
24 |
25 | export const ExampleSimple = () => (
26 |
32 | );
33 | ```
34 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/meta.en-US.json:
--------------------------------------------------------------------------------
1 | {
2 | "accessible": "Accessible Map",
3 | "bing-maps": "Bing Maps",
4 | "cluster": "Clustered Features",
5 | "draw-and-modify-features": "Draw and Modify Features",
6 | "draw-shapes": "Draw Shapes",
7 | "dynamic-data": "Dynamic Data",
8 | "geojson": "GeoJSON",
9 | "icon": "Icon Symbolizer",
10 | "image-filter": "Image Filters",
11 | "mapbox-vector-tiles": "Mapbox Vector Tiles",
12 | "popup": "Popup",
13 | "preload": "Preload Tiles",
14 | "reprojection-image": "Image Reprojection",
15 | "reprojection-wgs84": "OpenStreetMap Reprojection",
16 | "select-features": "Select Features",
17 | "simple": "Simple Map",
18 | "static-image": "Static Image",
19 | "turf": "turf.js",
20 | "wms-tiled": "Tiled WMS",
21 | "xyz-retina": "XYZ Retina Tiles",
22 | "xyz": "XYZ",
23 | "zoomify": "Zoomify"
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/preload.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Preload Tiles
2 |
3 | See https://openlayers.org/en/latest/examples/preload.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExamplePreload = () => (
10 |
16 | );
17 |
18 |
19 |
20 | ```tsx
21 | import React from "react";
22 | import "ol/ol.css";
23 | import { Map } from "@react-ol/fiber";
24 |
25 | export const ExamplePreload = () => (
26 |
32 | );
33 | ```
34 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/test-rig.test.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render } from "@testing-library/react";
3 | import { Map } from "ol";
4 |
5 |
6 | describe("Test setup", () => {
7 | it("can run basic test", () => {
8 | expect(1).toBe(1);
9 | });
10 | it("can run inline snapshot test", () => {
11 | expect(1).toMatchInlineSnapshot(`1`);
12 | });
13 | it("can run dom snapshot test", () => {
14 | const { container } = render(ok
);
15 | expect(container).toMatchSnapshot();
16 | });
17 | it("can run react testing library test", () => {
18 | const { getByText } = render(ok
);
19 | const heading = getByText(/ok/i);
20 | console.log(heading);
21 | expect(heading).toMatchInlineSnapshot(`
22 |
23 | ok
24 |
25 | `);
26 | });
27 | it("can run ol tests", () => {
28 | const map = new Map({});
29 | expect(map.getAllLayers().length).toBe(0);
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/packages/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@react-ol/website",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@react-ol/fiber": "workspace:*",
13 | "@tailwindcss/forms": "0.5.0",
14 | "@turf/turf": "6.5.0",
15 | "next": "12.1.1",
16 | "nextra": "2.0.0-alpha.34",
17 | "nextra-theme-docs": "2.0.0-alpha.34",
18 | "ol": "6.13.0",
19 | "proj4": "2.8.0",
20 | "react": "latest",
21 | "react-dom": "latest",
22 | "react-use": "17.3.2"
23 | },
24 | "devDependencies": {
25 | "@types/node": "17.0.21",
26 | "@types/react": "17.0.40",
27 | "autoprefixer": "10.4.2",
28 | "eslint": "8.11.0",
29 | "eslint-config-next": "12.1.0",
30 | "postcss": "8.4.8",
31 | "tailwindcss": "3.0.23",
32 | "typescript": "4.6.2",
33 | "webpack": "5.70.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/website/pages/docs/hooks.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Hooks
2 |
3 | ## The `useMap` hook
4 |
5 | The `useMap` hook allows to access the `Map` instance. Remember that this can work only inside a component that is child of a `` component.
6 |
7 | ```tsx
8 | import React from "react";
9 | import { Map, useMap } from "@react-ol/fiber";
10 | import "ol/ol.css";
11 |
12 | export const Inner = () => {
13 | const map = useMap();
14 | function centerOnFeatures(extent) {
15 | const view = map.getView();
16 | view.fit(extent);
17 | }
18 | return (
19 |
20 | centerOnFeatures(e.target.getExtent())}>
21 |
22 |
23 |
24 |
25 |
26 | );
27 | };
28 |
29 | export const Parent = () => {
30 | // WARNING: you can't use useOL() here
31 | return (
32 |
35 | );
36 | };
37 | ```
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Diagnostic reports (https://nodejs.org/api/report.html)
6 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 | *.lcov
20 |
21 | # node-waf configuration
22 | .lock-wscript
23 |
24 | # Dependency directories
25 | node_modules/
26 | jspm_packages/
27 |
28 | # TypeScript cache
29 | *.tsbuildinfo
30 |
31 | # Optional npm cache directory
32 | .npm
33 |
34 | # Optional eslint cache
35 | .eslintcache
36 |
37 | # Optional REPL history
38 | .node_repl_history
39 |
40 | # Output of 'npm pack'
41 | *.tgz
42 |
43 | # Yarn Integrity file
44 | .yarn-integrity
45 |
46 | # MacOS
47 | .DS_Store
48 |
49 | # vercel
50 | .vercel
51 |
52 | # next.js
53 | .next
54 | out
55 |
56 | .yarn/*
57 | !.yarn/patches
58 | !.yarn/plugins
59 | !.yarn/releases
60 | !.yarn/sdks
61 | !.yarn/versions
62 |
63 | dist
--------------------------------------------------------------------------------
/packages/website/theme.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | projectLink: 'https://github.com/crubier/react-openlayers-fiber', // GitHub link in the navbar
3 | docsRepositoryBase: 'https://github.com/crubier/react-openlayers-fiber/blob/master/packages/website/pages', // base URL for the docs repository
4 | titleSuffix: ' – React Openlayers Fiber',
5 | nextLinks: true,
6 | prevLinks: true,
7 | search: true,
8 | customSearch: null, // customizable, you can use algolia for example
9 | darkMode: true,
10 | footer: true,
11 | footerText: `MIT ${new Date().getFullYear()} © Vincent Lecrubier.`,
12 | footerEditLink: `Edit this page on GitHub`,
13 | unstable_flexsearch: true,
14 | floatTOC: true,
15 | logo: (
16 | <>
17 | React OpenLayers Fiber
18 | >
19 | ),
20 | head: (
21 | <>
22 |
23 |
24 |
25 | >
26 | ),
27 | }
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/reprojection-wgs84.en-US.mdx:
--------------------------------------------------------------------------------
1 | # OpenStreetMap Reprojection
2 |
3 | See hhttps://openlayers.org/en/latest/examples/reprojection-wgs84.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExampleReprojectionWGS84 = () => (
10 |
20 | );
21 |
22 |
23 |
24 | ```tsx
25 | import React from "react";
26 | import "ol/ol.css";
27 | import { Map } from "@react-ol/fiber";
28 |
29 | export const ExampleReprojectionWGS84 = () => (
30 |
40 | );
41 | ```
42 |
--------------------------------------------------------------------------------
/packages/website/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[typescript]": {
3 | "editor.formatOnSave": false,
4 | "editor.codeActionsOnSave": {
5 | "source.fixAll.eslint": true
6 | }
7 | },
8 | "[typescriptreact]": {
9 | "editor.formatOnSave": false,
10 | "editor.codeActionsOnSave": {
11 | "source.fixAll.eslint": true
12 | }
13 | },
14 | "eslint.workingDirectories": [{ "mode": "auto" }],
15 | "cSpell.words": [
16 | "Heatmap",
17 | "Mapbox",
18 | "WMTS",
19 | "Zoomify",
20 | "openlayers",
21 | "upsert"
22 | ],
23 | "jest.jestCommandLine": "yarn test",
24 | "gitlens.views.commits.files.layout": "tree",
25 | "gitlens.views.repositories.files.layout": "tree",
26 | "gitlens.views.fileHistory.files.layout": "tree",
27 | "gitlens.views.branches.files.layout": "tree",
28 | "gitlens.views.remotes.files.layout": "tree",
29 | "gitlens.views.stashes.files.layout": "tree",
30 | "gitlens.views.tags.files.layout": "tree",
31 | "gitlens.views.worktrees.files.layout": "tree",
32 | "gitlens.views.contributors.files.layout": "tree",
33 | "gitlens.views.searchAndCompare.files.layout": "tree"
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020-present Vincent Lecrubier
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/website/pages/docs/getting-started.en-US.mdx:
--------------------------------------------------------------------------------
1 | import Callout from "nextra-theme-docs/callout";
2 | import Bleed from "nextra-theme-docs/bleed";
3 |
4 | # Getting Started
5 |
6 | ## Install
7 |
8 | Install with your favorite package manager:
9 |
10 | ```sh
11 | yarn add @react-ol/fiber
12 | ```
13 |
14 | ```sh
15 | npm install @react-ol/fiber
16 | ```
17 |
18 | ```sh
19 | pnpm add @react-ol/fiber
20 | ```
21 |
22 | ## Usage
23 |
24 | Use the `Map` component as the root. Children of the `Map` component should be OpenLayers objects that will be rendered on the map.
25 |
26 | ```tsx
27 | import { Map } from "@react-ol/fiber";
28 |
29 | function MyMap() {
30 | return (
31 |
37 | );
38 | }
39 | ```
40 |
41 | ## Examples
42 |
43 | Examples are visible on the [example section](/examples/openlayers/simple) of this website.
44 |
45 | Most of the examples are simply ported from [openlayers examples section](https://openlayers.org/en/latest/examples/).
46 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/advanced/retina.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Retina
2 |
3 | This example shows how to use display maps that looks good on retina screens
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExampleRetina = () => (
10 |
21 | );
22 |
23 |
24 |
25 | ```tsx
26 | import React from "react";
27 | import "ol/ol.css";
28 | import { Map } from "@react-ol/fiber";
29 |
30 | export const ExampleRetina = () => (
31 |
42 | );
43 | ```
44 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/xyz.en-US.mdx:
--------------------------------------------------------------------------------
1 | # XYZ
2 |
3 | See https://openlayers.org/en/latest/examples/xyz.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const key = process.env.NEXT_PUBLIC_THUNDERFOREST_KEY;
10 |
11 | export const ExampleXYZ = () => {
12 | return (
13 |
25 | );
26 | };
27 |
28 |
29 |
30 | ```tsx
31 | import React from "react";
32 | import "ol/ol.css";
33 | import { Map } from "@react-ol/fiber";
34 |
35 | export const key = process.env.NEXT_PUBLIC_THUNDERFOREST_KEY;
36 |
37 | export const ExampleXYZ = () => {
38 | return (
39 |
51 | );
52 | };
53 | ```
54 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/test-rig.vitest.tsx:
--------------------------------------------------------------------------------
1 | import { render,screen, userEvent } from "./test/utils";
2 | import { Map } from "ol";
3 | import React from "react";
4 | import { describe, expect, it } from 'vitest'
5 |
6 |
7 |
8 | // describe('Simple working test', () => {
9 | // it('the title is visible', () => {
10 | // render()
11 | // expect(screen.getByText(/Hello Vite \+ React!/i)).toBeInTheDocument()
12 | // })
13 |
14 | // it('should increment count on click', async() => {
15 | // render()
16 | // userEvent.click(screen.getByRole('button'))
17 | // expect(await screen.findByText(/count is: 1/i)).toBeInTheDocument()
18 | // })
19 | // })
20 |
21 |
22 |
23 | describe("Test setup", () => {
24 | it("can run basic test", () => {
25 | expect(1).toBe(1);
26 | });
27 | it("can run inline snapshot test", () => {
28 | expect(1).toMatchInlineSnapshot(`1`);
29 | });
30 | it("can run dom snapshot test", () => {
31 | const { container } = render(ok
);
32 | expect(container).toMatchSnapshot();
33 | });
34 | it("can run react testing library test", () => {
35 | const { getByText } = render(ok
);
36 | const heading = getByText(/ok/i);
37 | expect(heading).toMatchInlineSnapshot(`
38 |
39 | ok
40 |
41 | `);
42 | });
43 | it("can run ol tests", () => {
44 | const map = new Map({});
45 | expect(map.getAllLayers().length).toBe(0);
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/packages/website/next.config.js:
--------------------------------------------------------------------------------
1 | const createWithNextra = require('nextra');
2 |
3 | const withNextra = createWithNextra({
4 | theme: 'nextra-theme-docs',
5 | themeConfig: './theme.config.js',
6 | unstable_flexsearch: true,
7 | unstable_staticImage: true,
8 | })
9 |
10 | /** @type {import('next').NextConfig} */
11 | const nextConfig = withNextra({
12 | i18n: {
13 | locales: ["en-US"],
14 | defaultLocale: "en-US",
15 | },
16 | experimental: {
17 | // Prefer loading of ES Modules over CommonJS
18 | // @link {https://nextjs.org/blog/next-11-1#es-modules-support|Blog 11.1.0}
19 | // @link {https://github.com/vercel/next.js/discussions/27876|Discussion}
20 | esmExternals: true,
21 | // Experimental monorepo support
22 | // @link {https://github.com/vercel/next.js/pull/22867|Original PR}
23 | // @link {https://github.com/vercel/next.js/discussions/26420|Discussion}
24 | externalDir: true,
25 | },
26 | reactStrictMode: true,
27 | redirects: () => {
28 | return [
29 | {
30 | source: "/docs",
31 | destination: "/docs/getting-started",
32 | statusCode: 302,
33 | },
34 | {
35 | source: "/examples/openlayers",
36 | destination: "/examples/openlayers/simple",
37 | statusCode: 302,
38 | },
39 | {
40 | source: "/examples",
41 | destination: "/examples/openlayers/simple",
42 | statusCode: 302,
43 | },
44 | ]
45 | }
46 | })
47 |
48 | module.exports = nextConfig
49 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/wms-tiled.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Tiled WMS
2 |
3 | See https://openlayers.org/en/latest/examples/wms-tiled.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExampleTiledWMS = () => {
10 | return (
11 |
25 | );
26 | };
27 |
28 |
29 |
30 | ```tsx
31 | import React from "react";
32 | import "ol/ol.css";
33 | import { Map } from "@react-ol/fiber";
34 |
35 | export const ExampleTiledWMS = () => {
36 | return (
37 |
51 | );
52 | };
53 | ```
54 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/jest.config.swc.js:
--------------------------------------------------------------------------------
1 | // jest.config.js
2 | import nextJest from 'next/jest.js';
3 |
4 | const createJestConfig = nextJest({
5 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
6 | dir: '.',
7 | })
8 |
9 | // Add any custom config to be passed to Jest
10 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
11 | const customJestConfig = {
12 | // preset: 'ts-jest',
13 | // Add more setup options before each test is run
14 | // setupFilesAfterEnv: ['/jest.setup.js'],
15 | // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
16 | // moduleDirectories: ['node_modules', '/'],
17 | testEnvironment: 'jest-environment-jsdom',
18 | }
19 |
20 | const jestConfig = async () => {
21 | const nextJestConfig = await createJestConfig(customJestConfig)();
22 | // See https://github.com/vercel/next.js/issues/35634#issuecomment-1080942525
23 | const veryCustomJestConfig = {
24 | ...nextJestConfig,
25 | transformIgnorePatterns: [
26 | '^.+\\.module\\.(css|sass|scss)$',
27 | // '/node_modules/(?!(ol/|labelgun/|@mapbox/mapbox-gl-style-spec/|mapbox-to-ol-style/|ol-mapbox-style/|geotiff/|fetch-blob/))'
28 | '/node_modules/(?!(ol/))'
29 | ]
30 | };
31 | return veryCustomJestConfig;
32 | };
33 |
34 |
35 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
36 | export default jestConfig;
--------------------------------------------------------------------------------
/packages/website/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/static-image.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Static Image
2 |
3 | See https://openlayers.org/en/latest/examples/static-image.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 | import { getCenter } from "ol/extent";
9 | import Projection from "ol/proj/Projection";
10 |
11 | export const extent = [0, 0, 1024, 968];
12 | export const attributions = '© xkcd';
13 | export const projection = new Projection({
14 | code: "xkcd-image",
15 | units: "pixels",
16 | extent,
17 | });
18 |
19 | export const ExampleStaticImage = () => (
20 |
36 | );
37 |
38 |
39 |
40 | ```tsx
41 | import React from "react";
42 | import "ol/ol.css";
43 | import { Map } from "@react-ol/fiber";
44 | import { getCenter } from "ol/extent";
45 | import Projection from "ol/proj/Projection";
46 |
47 | export const extent = [0, 0, 1024, 968];
48 | export const attributions = '© xkcd';
49 | export const projection = new Projection({
50 | code: "xkcd-image",
51 | units: "pixels",
52 | extent,
53 | });
54 |
55 | export const ExampleStaticImage = () => (
56 |
72 | );
73 | ```
74 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@react-ol/fiber",
3 | "version": "1.0.0-beta.1",
4 | "sideEffects": false,
5 | "description": "React OpenLayers bindings using react fiber",
6 | "license": "MIT",
7 | "author": "Vincent Lecrubier ",
8 | "main": "./src/index.ts",
9 | "module": "./src/index.ts",
10 | "types": "./src/index.ts",
11 | "type": "module",
12 | "publishConfig": {
13 | "access": "public",
14 | "main": "./dist/cjs/index.js",
15 | "module": "./dist/esm/index.js",
16 | "types": "./dist/ts/index.d.ts"
17 | },
18 | "files": [
19 | "dist/**/*",
20 | "src/**/*"
21 | ],
22 | "scripts": {
23 | "type-check": "tsc",
24 | "vitest": "vitest",
25 | "jest": "jest",
26 | "jestswc": "jest --config jest.config.swc.js",
27 | "build": "swc ./src --out-dir ./dist/esm --config-file ./esm.swcrc && swc ./src --out-dir ./dist/cjs --config-file ./cjs.swcrc && tsc -d --declarationDir dist/ts --declarationMap --emitDeclarationOnly"
28 | },
29 | "dependencies": {
30 | "lodash": "4.17.21",
31 | "react-reconciler": "0.25.1",
32 | "scheduler": "0.20.1"
33 | },
34 | "peerDependencies": {
35 | "ol": "*",
36 | "react": "*",
37 | "react-dom": "*"
38 | },
39 | "devDependencies": {
40 | "@babel/core": "7.17.8",
41 | "@babel/preset-env": "7.16.11",
42 | "@babel/preset-react": "7.16.7",
43 | "@babel/preset-typescript": "7.16.7",
44 | "@swc/cli": "0.1.56",
45 | "@swc/core": "1.2.159",
46 | "@testing-library/jest-dom": "5.16.3",
47 | "@testing-library/react": "12.1.4",
48 | "@testing-library/user-event": "14.0.2",
49 | "@types/jest": "24.0.13",
50 | "@types/lodash": "4.14.154",
51 | "@types/proj4": "2.5.0",
52 | "@types/react": "17.0.0",
53 | "@types/react-dom": "17.0.0",
54 | "@types/react-reconciler": "0.26.1",
55 | "@vitejs/plugin-react": "1.3.0",
56 | "babel-jest": "27.5.1",
57 | "jest": "27.5.1",
58 | "next": "12.1.1",
59 | "ol": "6.13.0",
60 | "react": "latest",
61 | "react-dom": "latest",
62 | "ts-jest": "27.1.4",
63 | "tsc": "2.0.4",
64 | "typescript": "4.3.5",
65 | "vitest": "0.8.1"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/accessible.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Accessible Map
2 |
3 | See https://openlayers.org/en/latest/examples/accessible.html
4 |
5 | import React, { useRef } from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 |
9 | export const ExampleAccessible = () => {
10 | const viewRef = useRef();
11 | return (
12 | <>
13 |
21 |
29 |
35 | >
36 | );
37 | };
38 |
39 |
40 |
41 | ```tsx
42 | import React, { useRef } from "react";
43 | import "ol/ol.css";
44 | import { Map } from "@react-ol/fiber";
45 |
46 | export const ExampleAccessible = () => {
47 | const viewRef = useRef();
48 | return (
49 | <>
50 |
57 |
64 |
70 | >
71 | );
72 | };
73 | ```
74 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/openlayers/xyz-retina.en-US.mdx:
--------------------------------------------------------------------------------
1 | # XYZ Retina Tiles
2 |
3 | See https://openlayers.org/en/latest/examples/xyz-retina.html
4 |
5 | import React from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 | import { transform } from "ol/proj";
9 |
10 | export const key = process.env.NEXT_PUBLIC_MAPTILER_KEY;
11 | export const attributions =
12 | '© MapTiler ' +
13 | '© OpenStreetMap contributors';
14 |
15 | export const ExampleXYZRetina = () => {
16 | return (
17 |
38 | );
39 | };
40 |
41 |
42 |
43 | ```tsx
44 | import React from "react";
45 | import "ol/ol.css";
46 | import { Map } from "@react-ol/fiber";
47 | import { transform } from "ol/proj";
48 |
49 | export const key = process.env.NEXT_PUBLIC_MAPTILER_KEY;
50 | export const attributions =
51 | '© MapTiler ' +
52 | '© OpenStreetMap contributors';
53 |
54 | export const ExampleXYZRetina = () => {
55 | return (
56 |
77 | );
78 | };
79 | ```
80 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/src/map.tsx:
--------------------------------------------------------------------------------
1 | import React, {
2 | MutableRefObject,
3 | useRef,
4 | useEffect,
5 | useState,
6 | forwardRef,
7 | } from "react";
8 | import { Map as OlMap } from "ol";
9 | import { isNull, isFunction, isNil } from "lodash/fp";
10 | import { render } from "./renderer";
11 |
12 | import { MapProvider } from "./context";
13 |
14 | import { ReactOlFiber } from "./types";
15 |
16 | const defaultArgs = [{}] as [ConstructorParameters[0]];
17 | const defaultStyle = { width: "100%", height: "400px" };
18 |
19 | export type Props = ReactOlFiber.IntrinsicElements["olMap"] & {
20 | style?: React.CSSProperties;
21 | containerRef?: React.Ref;
22 | };
23 |
24 | export const Map = forwardRef(
25 | (
26 | {
27 | children,
28 | args = defaultArgs,
29 | style = defaultStyle,
30 | className,
31 | containerRef,
32 | ...mapProps
33 | }: Props,
34 | ref
35 | ): React.ReactElement => {
36 | const mapContainerRef = useRef(null);
37 | const [map, setMap] = useState(null);
38 |
39 | useEffect(() => {
40 | if (mapContainerRef.current) {
41 | const wrapped = (
42 |
48 | {isNull(map) ? null : (
49 | {children}
50 | )}
51 |
52 | );
53 | const returnedMap = render(wrapped, mapContainerRef.current) as OlMap;
54 |
55 | if (isNull(map) && !isNull(returnedMap)) {
56 | setMap((oldMap) => (isNull(oldMap) ? returnedMap : oldMap));
57 | }
58 | }
59 | }, [children, mapContainerRef.current, map]);
60 |
61 | const setRef = (value: HTMLDivElement): void => {
62 | if (isNil(value)) {
63 | return;
64 | }
65 | if (isFunction(containerRef)) {
66 | containerRef(value);
67 | } else if (!isNil(containerRef)) {
68 | // eslint-disable-next-line no-param-reassign
69 | (containerRef as MutableRefObject).current = value;
70 | }
71 | if (isFunction(mapContainerRef)) {
72 | mapContainerRef(value);
73 | } else if (!isNil(mapContainerRef)) {
74 | // eslint-disable-next-line no-param-reassign
75 | (mapContainerRef as MutableRefObject).current = value;
76 | }
77 | };
78 |
79 | return ;
80 | }
81 | );
82 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # React OpenLayers Fiber
2 |
3 | `@react-ol/fiber` is a react renderer for OpenLayers https://openlayers.org/ .
4 |
5 | It is based on the same concept as what `@react-three/fiber` does for Three.js.
6 |
7 | Visit https://react-openlayers-fiber.vercel.app
8 |
9 | ## What does it look like?
10 |
11 | ```tsx
12 | import React from "react";
13 | import "ol/ol.css";
14 | import { Map } from "@react-ol/fiber";
15 |
16 | export const Example = () => (
17 |
23 | );
24 | ```
25 |
26 | ## Why?
27 |
28 | Build your maps declaratively with re-usable, self-contained components that react to state, are readily interactive and can tap into React's ecosystem.
29 |
30 | ### Does it have limitations?
31 |
32 | None. Everything that works in OpenLayers will work here without exception.
33 |
34 | ### Can it keep up with frequent updates to OpenLayers?
35 |
36 | Yes. There is no hard dependency on a particular OpenLayers version, it does not wrap or duplicate a single OpenLayers class. It merely expresses OpenLayers in JSX: `` becomes `new ol.View()`, and that happens dynamically.
37 |
38 | ### Is it slower than plain OpenLayers?
39 |
40 | No. There is no additional overhead. Components participate in a unified renderloop outside of React. It outperforms OpenLayers at scale due to React's scheduling abilities.
41 |
42 | ## Fundamentals
43 |
44 | You need to be versed in both React and OpenLayers before rushing into this. If you are unsure about React consult the official React docs, especially the section about hooks. As for OpenLayers, make sure you at least glance over the following links:
45 |
46 | - Make sure you have a [basic grasp of OpenLayers](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). Keep that site open.
47 | - When you know what a `map` is, a `view`, `layer`, `source`, `geometry`, fork the [demo](/#what-does-it-look-like) above.
48 | - [Look up](https://openlayers.org/en/latest/apidoc/module-ol_layer_Layer-Layer.html) the JSX elements that you see (`layer`, `source`, etc), all OpenLayers exports are native to `@react-ol/fiber`.
49 | - Try changing some values, scroll through our API to see what the various settings and hooks do.
50 |
51 | ## Ecosystem
52 |
53 | - [`@react-three/fiber`](https://github.com/pmndrs/react-three-fiber) – a similar library, targeting Three.js
54 | - [`zustand`](https://github.com/pmndrs/zustand) – state management
55 | - [`react-spring`](https://github.com/pmndrs/react-spring) – a spring-physics-based animation library
56 |
--------------------------------------------------------------------------------
/packages/react-openlayers-fiber/README.md:
--------------------------------------------------------------------------------
1 | # React OpenLayers Fiber
2 |
3 | `@react-ol/fiber` is a react renderer for OpenLayers https://openlayers.org/ .
4 |
5 | It is based on the same concept as what `@react-three/fiber` does for Three.js.
6 |
7 | Visit https://react-openlayers-fiber.vercel.app
8 |
9 | ## What does it look like?
10 |
11 | ```tsx
12 | import React from "react";
13 | import "ol/ol.css";
14 | import { Map } from "@react-ol/fiber";
15 |
16 | export const Example = () => (
17 |
23 | );
24 | ```
25 |
26 | ## Why?
27 |
28 | Build your maps declaratively with re-usable, self-contained components that react to state, are readily interactive and can tap into React's ecosystem.
29 |
30 | ### Does it have limitations?
31 |
32 | None. Everything that works in OpenLayers will work here without exception.
33 |
34 | ### Can it keep up with frequent updates to OpenLayers?
35 |
36 | Yes. There is no hard dependency on a particular OpenLayers version, it does not wrap or duplicate a single OpenLayers class. It merely expresses OpenLayers in JSX: `` becomes `new ol.View()`, and that happens dynamically.
37 |
38 | ### Is it slower than plain OpenLayers?
39 |
40 | No. There is no additional overhead. Components participate in a unified renderloop outside of React. It outperforms OpenLayers at scale due to React's scheduling abilities.
41 |
42 | ## Fundamentals
43 |
44 | You need to be versed in both React and OpenLayers before rushing into this. If you are unsure about React consult the official React docs, especially the section about hooks. As for OpenLayers, make sure you at least glance over the following links:
45 |
46 | - Make sure you have a [basic grasp of OpenLayers](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). Keep that site open.
47 | - When you know what a `map` is, a `view`, `layer`, `source`, `geometry`, fork the [demo](/#what-does-it-look-like) above.
48 | - [Look up](https://openlayers.org/en/latest/apidoc/module-ol_layer_Layer-Layer.html) the JSX elements that you see (`layer`, `source`, etc), all OpenLayers exports are native to `@react-ol/fiber`.
49 | - Try changing some values, scroll through our API to see what the various settings and hooks do.
50 |
51 | ## Ecosystem
52 |
53 | - [`@react-three/fiber`](https://github.com/pmndrs/react-three-fiber) – a similar library, targeting Three.js
54 | - [`zustand`](https://github.com/pmndrs/zustand) – state management
55 | - [`react-spring`](https://github.com/pmndrs/react-spring) – a spring-physics-based animation library
56 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/advanced/dynamic-points.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Dynamic points
2 |
3 | In this example we declaratively update points at 30FPS.
4 |
5 | import React, { useState } from "react";
6 | import "ol/ol.css";
7 | import { Map } from "@react-ol/fiber";
8 | import { useInterval } from "react-use";
9 | import { Fill, Stroke, Style, RegularShape } from "ol/style";
10 |
11 | export const stroke = new Stroke({ color: "black", width: 2 });
12 | export const fill = new Fill({ color: "red" });
13 | export const pointStyle = new Style({
14 | image: new RegularShape({
15 | fill,
16 | stroke,
17 | points: 4,
18 | radius: 10,
19 | angle: Math.PI / 4,
20 | }),
21 | });
22 |
23 | export const ExampleDynamicPoints = () => {
24 | const [location, setLocation] = useState([0, 6000000]);
25 | useInterval(() => {
26 | setLocation([100000 * Math.random(), 6000000 + 100000 * Math.random()]);
27 | }, 1000 / 30);
28 | return (
29 |
42 | );
43 | };
44 |
45 |
46 |
47 | ```tsx
48 | import React, { useState } from "react";
49 | import "ol/ol.css";
50 | import { Map } from "@react-ol/fiber";
51 | import { useInterval } from "react-use";
52 | import { Fill, Stroke, Style, RegularShape } from "ol/style";
53 |
54 | export const stroke = new Stroke({ color: "black", width: 2 });
55 | export const fill = new Fill({ color: "red" });
56 | export const pointStyle = new Style({
57 | image: new RegularShape({
58 | fill,
59 | stroke,
60 | points: 4,
61 | radius: 10,
62 | angle: Math.PI / 4,
63 | }),
64 | });
65 |
66 | export const ExampleDynamicPoints = () => {
67 | const [location, setLocation] = useState([0, 6000000]);
68 | useInterval(() => {
69 | setLocation([100000 * Math.random(), 6000000 + 100000 * Math.random()]);
70 | }, 1000 / 30);
71 | return (
72 |
85 | );
86 | };
87 | ```
88 |
--------------------------------------------------------------------------------
/packages/website/pages/examples/advanced/declaratively-move-view.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Declaratively move view
2 |
3 | In this example we only provide props for the view, so it should load with default values
4 | and go a bit north every second, forcing the view to recenter every second
5 |
6 | import React, { useState } from "react";
7 | import "ol/ol.css";
8 | import { Map } from "@react-ol/fiber";
9 | import { useInterval } from "react-use";
10 |
11 | export const ExampleDeclarativelyMoveView = () => {
12 | const [latitude, setLatitude] = useState(6000000);
13 | useInterval(() => {
14 | setLatitude(latitude + 10000);
15 | }, 1000);
16 | return (
17 |
23 | );
24 | };
25 |
26 |
27 |
28 | ```tsx
29 | import React, { useState } from "react";
30 | import "ol/ol.css";
31 | import { Map } from "@react-ol/fiber";
32 | import { useInterval } from "react-use";
33 |
34 | export const ExampleDeclarativelyMoveView = () => {
35 | const [latitude, setLatitude] = useState(6000000);
36 | useInterval(() => {
37 | setLatitude(latitude + 10000);
38 | }, 1000);
39 | return (
40 |
46 | );
47 | };
48 | ```
49 |
50 | In this second example we provide props and initial props for the view, so it should behave like the Basic Props example values.
51 | It loads with the initial values and immediatly the position get changed with the position from props
52 |
53 | export const ExampleInitialProps = () => {
54 | const [latitude, setLatitude] = useState(6000000);
55 | useInterval(() => {
56 | setLatitude(latitude + 10000);
57 | }, 1000);
58 | return (
59 |
69 | );
70 | };
71 |
72 |
73 |
74 | ```tsx
75 | export const ExampleInitialProps = () => {
76 | const [latitude, setLatitude] = useState(6000000);
77 | useInterval(() => {
78 | setLatitude(latitude + 10000);
79 | }, 1000);
80 | return (
81 |
91 | );
92 | };
93 | ```
94 |
--------------------------------------------------------------------------------
/packages/website/pages/docs/components.en-US.mdx:
--------------------------------------------------------------------------------
1 | # Components
2 |
3 | ## OpenLayers-derived components
4 |
5 | All OpenLayers classes are available as React Component through the automatic API.
6 |
7 | The naming scheme is using the camel-cased fully qualified names of the classes.
8 |
9 | Examples:
10 |
11 | | OpenLayers Class | React OpenLayers Fiber component |
12 | | -------------------------------------------------------------------------------------------------- | -------------------------------- |
13 | | [`ol/View`](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html) | `` |
14 | | [`ol/geom/Polygon`](https://openlayers.org/en/latest/apidoc/module-ol_geom_Polygon-Polygon.html) | `` |
15 | | [`ol/layer/Heatmap`](https://openlayers.org/en/latest/apidoc/module-ol_layer_Heatmap-Heatmap.html) | `` |
16 |
17 | ```tsx
18 | import { Map } from "@react-ol/fiber";
19 |
20 | export const Example = () => (
21 |
27 | );
28 | ```
29 |
30 | ## The `Map` component
31 |
32 | The `