From 6cb8472d4a10d55620e1840e4d2e4cf8823fa2c1 Mon Sep 17 00:00:00 2001 From: galela Date: Mon, 3 Jun 2024 17:36:34 +0200 Subject: [PATCH 1/7] feat: Adding React map sample --- package-lock.json | 49 ++++++++ package.json | 4 +- samples/react-map-with-localities/index.njk | 6 + samples/react-map-with-localities/index.tsx | 119 ++++++++++++++++++ .../react-map-with-localities.json | 19 +++ samples/react-map-with-localities/style.scss | 6 + src/engines/typescript/sample-jsx.js | 8 +- 7 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 samples/react-map-with-localities/index.njk create mode 100644 samples/react-map-with-localities/index.tsx create mode 100644 samples/react-map-with-localities/react-map-with-localities.json create mode 100644 samples/react-map-with-localities/style.scss diff --git a/package-lock.json b/package-lock.json index 4794abe7..5b3a3d51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "name": "@woosmap/js-samples", "version": "1.30.0", "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", "supercluster": "^7.1.3" }, "devDependencies": { @@ -4403,6 +4405,11 @@ "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", "dev": true }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4614,6 +4621,17 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -6100,6 +6118,29 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -6518,6 +6559,14 @@ "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", "dev": true }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", diff --git a/package.json b/package.json index abd162ec..02e59ee5 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,8 @@ "yaml": "^2.3.4" }, "dependencies": { - "supercluster": "^7.1.3" + "supercluster": "^7.1.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" } } diff --git a/samples/react-map-with-localities/index.njk b/samples/react-map-with-localities/index.njk new file mode 100644 index 00000000..4376e938 --- /dev/null +++ b/samples/react-map-with-localities/index.njk @@ -0,0 +1,6 @@ +{% extends '../../src/_includes/layout.njk' %} +{% block api %} +{% endblock %} +{% block html %} +
+{% endblock %} \ No newline at end of file diff --git a/samples/react-map-with-localities/index.tsx b/samples/react-map-with-localities/index.tsx new file mode 100644 index 00000000..fb0bbf5e --- /dev/null +++ b/samples/react-map-with-localities/index.tsx @@ -0,0 +1,119 @@ +// [START woosmap_react_map_with_localities] +import { createRoot } from "react-dom/client"; + +import React, { + createContext, + useContext, + useEffect, + useRef, + useState, +} from "react"; + +// Define the types for the position and the Woosmap object +type Position = { lat: number; lng: number }; +declare const woosmap: any; + +// Custom hook to load the Woosmap JavaScript API +function useWoosmap(apiKey: string) { + const [isLoaded, setIsLoaded] = useState(false); + + useEffect(() => { + const script = document.createElement("script"); + script.src = `https://sdk.woosmap.com/map/map.js?key=${apiKey}`; + script.onload = () => setIsLoaded(true); + document.body.appendChild(script); + }, [apiKey]); + + return isLoaded; +} + +const MapContext = createContext(null); +const MapInstanceContext = createContext(null); + +interface APIProviderProps { + apiKey: string; + children: React.ReactNode; +} + +function APIProvider({ apiKey, children }: APIProviderProps) { + const isLoaded = useWoosmap(apiKey); + + if (!isLoaded) { + return null; + } + + return {children}; +} + +interface MapProps extends woosmap.map.MapOptions { + children: React.ReactNode; +} + +function Map({ center, zoom, children }: MapProps) { + const mapRef = useRef(null); + const woosmap = useContext(MapContext); + const [mapInstance, setMapInstance] = useState(null); + + useEffect(() => { + if (mapRef.current) { + const map = new woosmap.map.Map(mapRef.current, { + zoom, + center, + }); + setMapInstance(map); + } + }, [woosmap, zoom, center]); + + return ( + +
+ {children} +
+
+ ); +} + +function Marker({ position }: woosmap.map.MarkerOptions) { + const woosmap = useContext(MapContext); + const mapInstance = useContext(MapInstanceContext); + + useEffect(() => { + if (mapInstance) { + const marker = new woosmap.map.Marker({ + position, + icon: { + url: "https://images.woosmap.com/marker.png", + scaledSize: { + height: 50, + width: 32, + }, + }, + }); + marker.setMap(mapInstance); + } + }, [woosmap, position, mapInstance]); + + return null; +} + +function App() { + const position: Position = { lat: 61.2176, lng: -149.8997 }; + + return ( + + + + + + ); +} + +window.addEventListener("DOMContentLoaded", () => { + const root = createRoot(document.getElementById("root")!); + root.render(); +}); + +// [END woosmap_react_map_with_localities] +let PRESERVE_COMMENT_ABOVE; // force tsc to maintain the comment above eslint-disable-line + +export {}; diff --git a/samples/react-map-with-localities/react-map-with-localities.json b/samples/react-map-with-localities/react-map-with-localities.json new file mode 100644 index 00000000..0a2de532 --- /dev/null +++ b/samples/react-map-with-localities/react-map-with-localities.json @@ -0,0 +1,19 @@ +{ + "title": "React Map with Localities", + "description": "A basic Woosmap Map sample using React JS Framework", + "callback": "initMap", + "category": "Map Basics", + "tsx": true, + "tag": "react_map_with_localities", + "name": "react-map-with-localities", + "pagination": { + "data": "mode", + "size": 1, + "alias": "mode" + }, + "permalink": "samples/{{ page.fileSlug }}/{{mode}}/{% if mode == 'jsfiddle' %}demo{% else %}index{% endif %}.{{ page.outputFileExtension }}", + "dependencies": [ + "react", + "react-dom" + ] +} diff --git a/samples/react-map-with-localities/style.scss b/samples/react-map-with-localities/style.scss new file mode 100644 index 00000000..2d9df9c4 --- /dev/null +++ b/samples/react-map-with-localities/style.scss @@ -0,0 +1,6 @@ +@use 'sass:meta'; // To enable @use via meta.load-css and keep comments in order + +/* [START react_map_with_localities] */ +@include meta.load-css("../../shared/scss/_default.scss"); + +/* [END react_map_with_localities] */ diff --git a/src/engines/typescript/sample-jsx.js b/src/engines/typescript/sample-jsx.js index ceb0c220..cb8444cd 100644 --- a/src/engines/typescript/sample-jsx.js +++ b/src/engines/typescript/sample-jsx.js @@ -12,7 +12,13 @@ module.exports = { "utf8", ), ), - file: ["docs.jsx", "app.tsx", "jsfiddle.jsx", "highlight.jsx"], + file: [ + "docs.jsx", + "app.tsx", + "jsfiddle.jsx", + "highlight.tsx", + "highlight.jsx", + ], pagination: { data: "file", alias: "file", From a75d043be38d114b1cc93749e71d0722bf217ceb Mon Sep 17 00:00:00 2001 From: galela Date: Mon, 3 Jun 2024 17:55:02 +0200 Subject: [PATCH 2/7] fix: fix React Map Typings --- samples/react-map-with-localities/index.tsx | 27 ++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/samples/react-map-with-localities/index.tsx b/samples/react-map-with-localities/index.tsx index fb0bbf5e..be644fa2 100644 --- a/samples/react-map-with-localities/index.tsx +++ b/samples/react-map-with-localities/index.tsx @@ -9,8 +9,7 @@ import React, { useState, } from "react"; -// Define the types for the position and the Woosmap object -type Position = { lat: number; lng: number }; +// Define the types for the Woosmap object declare const woosmap: any; // Custom hook to load the Woosmap JavaScript API @@ -35,7 +34,7 @@ interface APIProviderProps { children: React.ReactNode; } -function APIProvider({ apiKey, children }: APIProviderProps) { +const APIProvider: React.FC = ({ apiKey, children }) => { const isLoaded = useWoosmap(apiKey); if (!isLoaded) { @@ -43,16 +42,16 @@ function APIProvider({ apiKey, children }: APIProviderProps) { } return {children}; -} +}; interface MapProps extends woosmap.map.MapOptions { children: React.ReactNode; } -function Map({ center, zoom, children }: MapProps) { +const WoosmapMap: React.FC = ({ center, zoom, children }) => { const mapRef = useRef(null); const woosmap = useContext(MapContext); - const [mapInstance, setMapInstance] = useState(null); + const [mapInstance, setMapInstance] = useState(null); useEffect(() => { if (mapRef.current) { @@ -71,9 +70,9 @@ function Map({ center, zoom, children }: MapProps) { ); -} +}; -function Marker({ position }: woosmap.map.MarkerOptions) { +const Marker: React.FC = ({ position }) => { const woosmap = useContext(MapContext); const mapInstance = useContext(MapInstanceContext); @@ -94,19 +93,19 @@ function Marker({ position }: woosmap.map.MarkerOptions) { }, [woosmap, position, mapInstance]); return null; -} +}; -function App() { - const position: Position = { lat: 61.2176, lng: -149.8997 }; +const App: React.VFC = () => { + const position: woosmap.map.LatLngLiteral = { lat: 61.2176, lng: -149.8997 }; return ( - + - + ); -} +}; window.addEventListener("DOMContentLoaded", () => { const root = createRoot(document.getElementById("root")!); From 108f23476ca513b1edcc0cbb6f65174a9fe55e6b Mon Sep 17 00:00:00 2001 From: galela Date: Tue, 4 Jun 2024 14:29:45 +0200 Subject: [PATCH 3/7] feat: Added react map properly and deploy pr --- .github/workflows/pr-to-s3.yml | 33 ++++++ samples/highlight.html.njk | 39 ++++--- samples/react-map-with-localities/index.tsx | 116 +++++++++++++++++-- samples/react-map-with-localities/style.scss | 2 + shared/scss/_autocomplete_list.scss | 4 + tsconfig.json | 6 +- 6 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/pr-to-s3.yml diff --git a/.github/workflows/pr-to-s3.yml b/.github/workflows/pr-to-s3.yml new file mode 100644 index 00000000..6fa56410 --- /dev/null +++ b/.github/workflows/pr-to-s3.yml @@ -0,0 +1,33 @@ +name: PR Deploy +on: + pull_request: + branches: [ master ] + workflow_dispatch: + +jobs: + push-to-s3: + if: "!contains(github.event.head_commit.message, 'skip ci')" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v3 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node + - run: npm ci + - run: npm run build + - name: include ignored files + run: | + rm -rf dist/samples/**/node_modules + rm -rf dist/samples/**/package-lock.json + rm -rf dist/samples/**/app/.gitignore + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-central-1 + - name: Deploy static site to S3 bucket + run: aws s3 sync dist s3://demo.woosmap.com/misc/js-samples-pr-deploy/pr-${{ github.event.pull_request.number }}/ --acl public-read diff --git a/samples/highlight.html.njk b/samples/highlight.html.njk index a1faeffe..f43f0c6d 100644 --- a/samples/highlight.html.njk +++ b/samples/highlight.html.njk @@ -5,18 +5,31 @@ pagination: size: 1 permalink: /samples/{{ sample.fileSlug }}/highlight/highlight.html --- +{% if sample.data.tsx %} + {% set ts_extension = 'tsx' %} + {% set ts_highlight = 'tsx' %} + {% set js_extension = 'jsx' %} + {% set js_highlight = 'jsx' %} +{% else %} + {% set ts_extension = 'ts' %} + {% set ts_highlight = 'typescript' %} + {% set js_extension = 'js' %} + {% set js_highlight = 'javascript' %} +{% endif %} Highlight