├── .env.example
├── .github
├── dependabot.yml
└── workflows
│ └── pnpm-test.yml
├── .gitignore
├── .husky
├── .gitignore
└── pre-commit
├── .npmrc
├── .nvmrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs
└── how-to-use-a-proxy.md
├── index.html
├── package.json
├── pitsby.config.js
├── pnpm-lock.yaml
├── src
├── components
│ ├── address-autocomplete
│ │ ├── address-autocomplete.doc.js
│ │ ├── index.ts
│ │ ├── main.test.ts
│ │ └── styles.scss
│ ├── my-map
│ │ ├── controls.ts
│ │ ├── docs
│ │ │ ├── my-map-basic.doc.js
│ │ │ ├── my-map-draw.doc.js
│ │ │ ├── my-map-features.doc.js
│ │ │ ├── my-map-geojson.doc.js
│ │ │ └── my-map-proxy.doc.js
│ │ ├── drawing.ts
│ │ ├── icons
│ │ │ ├── README.md
│ │ │ ├── north-arrow-n.svg
│ │ │ ├── poi-alt.svg
│ │ │ ├── printer.svg
│ │ │ └── trash-can.svg
│ │ ├── index.ts
│ │ ├── layers.test.ts
│ │ ├── layers.ts
│ │ ├── main.test.ts
│ │ ├── os-features.ts
│ │ ├── pin.svg
│ │ ├── projections.ts
│ │ ├── snapping.ts
│ │ ├── styles.scss
│ │ └── utils.ts
│ └── postcode-search
│ │ ├── index.ts
│ │ ├── main.test.ts
│ │ ├── postcode-search.doc.js
│ │ └── styles.scss
├── index.ts
├── lib
│ ├── ordnanceSurvey.test.ts
│ └── ordnanceSurvey.ts
├── test-utils.ts
└── vite-env.d.ts
├── tsconfig.json
└── vite.config.ts
/.env.example:
--------------------------------------------------------------------------------
1 | VITE_APP_OS_API_KEY=👻
2 | VITE_APP_MAPBOX_ACCESS_TOKEN=👻
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm" # use this yaml value when package manager is 'pnpm'
4 | directory: "/"
5 | schedule:
6 | interval: "monthly"
7 | reviewers:
8 | - "theopensystemslab/planx"
9 | ignore:
10 | - dependency-name: "ol"
11 | update-types: ["version-update:semver-major"]
12 | - dependency-name: "happy-dom"
13 | update-types: ["version-update:semver-major"]
14 |
15 | - package-ecosystem: "github-actions"
16 | directory: "/"
17 | schedule:
18 | interval: "monthly"
19 | reviewers:
20 | - "theopensystemslab/planx"
21 |
--------------------------------------------------------------------------------
/.github/workflows/pnpm-test.yml:
--------------------------------------------------------------------------------
1 | name: Run tests
2 | on:
3 | pull_request:
4 | types: [opened, synchronize]
5 | branches:
6 | - main
7 |
8 | env:
9 | PNPM_VERSION: 8.6.6
10 | NODE_VERSION: 18.16.1
11 |
12 | jobs:
13 | vitest:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - uses: pnpm/action-setup@v4.1.0
18 | with:
19 | version: ${{ env.PNPM_VERSION }}
20 | - uses: actions/setup-node@v4
21 | with:
22 | node-version: ${{ env.NODE_VERSION }}
23 | cache: "pnpm"
24 | cache-dependency-path: "**/pnpm-lock.yaml"
25 | - run: pnpm install --no-frozen-lockfile
26 | - run: pnpm test
27 | env:
28 | VITE_APP_OS_API_KEY: ${{ secrets.OS_API_KEY }}
29 | VITE_APP_MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | pitsby
5 | types
6 | *.local
7 | *.log
8 | /.vscode
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | auto-install-peers=true
2 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v18.16.1
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | **Note:** Version 0 of Semantic Versioning is handled differently from version 1 and above.
9 | The minor version will be incremented upon a breaking change and the patch version will be
10 | incremented for features.
11 |
12 | ### [1.0.0-alpha.5] - 2025-03-11
13 |
14 | ### Fixed
15 | - chore: ensured Vite environment variables are not bundled in build files ([#533](https://github.com/theopensystemslab/map/pull/533))
16 |
17 | ### Changed
18 | - deps: now on OpenLayers v10 ! ([#535](https://github.com/theopensystemslab/map/pull/535))
19 | - deps: a number of other package updates via Dependabot
20 | - docs: deployment instructions now added for releases & pre-releases ([#511](https://github.com/theopensystemslab/map/pull/511))
21 |
22 | ### [1.0.0-alpha.4] - 2024-10-23
23 |
24 | ### Added
25 | - feat: new boolean prop `hideDrawLabels` allows default labels to be hidden when `drawMany` is enabled ([#508](https://github.com/theopensystemslab/map/pull/508))
26 |
27 | ### Changed
28 | - style: increased visual constrast of drawing points by applying colored stroke rather fill and bumping overall size ([#507](https://github.com/theopensystemslab/map/pull/507), [#509](https://github.com/theopensystemslab/map/pull/509))
29 |
30 | ### [1.0.0-alpha.3] - 2024-09-06
31 |
32 | ### Fixed
33 | - fix: ensure labels are incremental when drawing many features ([#495](https://github.com/theopensystemslab/map/pull/495))
34 |
35 | ### Changed
36 | - style: switch direction of reset icon ([#498](https://github.com/theopensystemslab/map/pull/498))
37 |
38 | ### Added
39 | - feat: add boolean prop `resetViewOnly` to prevent reset control from clearing drawing data and only reset viewport ([#496](https://github.com/theopensystemslab/map/pull/496))
40 |
41 | ### [1.0.0-alpha.2] - 2024-09-02
42 |
43 | ### Fixed
44 | - fix: maintain existing drawing labels when modifying features ([#493](https://github.com/theopensystemslab/map/pull/493))
45 | - fix: `drawGeojsonData` accepts individual "Feature" or "FeatureCollection" to work correctly with `drawMany` ([#491](https://github.com/theopensystemslab/map/pull/491))
46 |
47 | ### Added
48 | - feat: `drawGeojsonData` will read from GeoJSON property "color" if set, or else fallback to the `drawColor` prop which allows individual features to use different styles when `drawMany` ([#492](https://github.com/theopensystemslab/map/pull/492))
49 |
50 | ### [1.0.0-alpha.1] - 2024-08-29
51 |
52 | ### Changed
53 | - fix: ensure `showCentreMarker` and `geojsonData` layers are correctly ordered on top of basemap when using "MapboxSatellite" ([#481](https://github.com/theopensystemslab/map/pull/481))
54 | - fix: ensure point features displayed via `geojsonData` have an associated style ([#482](https://github.com/theopensystemslab/map/pull/482))
55 | - fix: increased `drawMany` label font size and default point size for `drawType="Point"` ([#483](https://github.com/theopensystemslab/map/pull/483))
56 |
57 | ### Added
58 | - feat: adds prop `dataTestId` to set a `data-testid` on the map's shadow root ([#484](https://github.com/theopensystemslab/map/pull/484))
59 |
60 | ### [1.0.0-alpha.0] - 2024-08-24
61 |
62 | We're starting to work towards a v1.0.0 stable release!
63 |
64 | ### Breaking
65 | A number of props and dispatched events have been deprecated and condensed:
66 | - `osVectorTilesApiKey`, `osFeaturesApiKey` and `osPlacesApiKey` are deprecated in favor of a single `osApiKey` prop ([#476](https://github.com/theopensystemslab/map/pull/476))
67 | - `disableVectorTiles` is deprecated in favor of a _new_ `basemap` prop with enum values `"OSVectorTile" | "OSRaster" | "MapboxSatellite" | "OSM"`. The default is still `"OSVectorTile"` and we'll still fallback to OpenStreetMap if any of the API-dependent basemaps can't be initialised ([#476](https://github.com/theopensystemslab/map/pull/476))
68 | - `drawPointColor`, `drawFillColor` and `featureBorderNone` props are deprecated and rolled into existing style props ([#473](https://github.com/theopensystemslab/map/pull/473))
69 | - The `areaChange` event dispatched in `drawMode` has been deprecated and rolled into existing `geojsonChange` event. If your `drawType="Polygon"`, you'll now simply find an `area` property on the dispatched geojson feature ([#466-discussion](https://github.com/theopensystemslab/map/pull/466#discussion_r1703872391))
70 | - Similarly, the `featuresAreaChange` event dispatched by `clickFeatures` has been deprecated and rolled into `featuresGeojsonChange` event ([#479](https://github.com/theopensystemslab/map/pull/479))
71 | - `areaUnit` prop has been deprecated and you'll find the calculated area in _both_ `squareMetres` and `hectares` by default now in `geojsonChange` event data above ([#479](https://github.com/theopensystemslab/map/pull/479))
72 |
73 | We think the above deprecations will mean simpler, _more_ flexible configurations and subscriptions for end-users, but if you were relying on any of the deprecated props, cannot achieve feature parity with the alternatives, or find a regression we've overlooked, please open an [Issue](https://github.com/theopensystemslab/map/issues)!
74 |
75 | ### Changed
76 | - fix: `osCopyright` prop no longer has a default license number, please add your own! ([#476](https://github.com/theopensystemslab/map/pull/476))
77 | - deps: various dependency updates via Dependabot
78 |
79 | ### Added
80 | - feat: new `basemap` option `"MapboxSatellite"` displays aerial imagery; see README "Bring your own API keys" for configuring a Mapbox access token ([#475](https://github.com/theopensystemslab/map/pull/475))
81 | - feat: `drawMany` prop allows more than one feature to be drawn and will display labels (simple incremental index for now, _not_ customisable). The label and area (if `drawType="Polygon"`) will be included in the `properties` of each feature dispatched via the `geojsonChange` event ([#466](https://github.com/theopensystemslab/map/pull/466))
82 | - feat: `drawType` prop adds supported value `"Circle"` for drawing & modifying circles; please note this type is still quite experimental and does _not_ yet dispatch a `geojsonChange` event ("circles" are not a natively supported type in geojson and we'll need to transform to polygons first) ([#465](https://github.com/theopensystemslab/map/pull/465))
83 |
84 | ### [0.8.3] - 2024-06-28
85 |
86 | ### Fixed
87 | - fix(a11y): adds a `role` to the map container div of either `application` if interactive or `presentation` if implemented in static mode ([#454](https://github.com/theopensystemslab/map/pull/454))
88 |
89 | ### Changed
90 | - deps: various dependency updates via Dependabot
91 |
92 | ### [0.8.2] - 2024-05-09
93 |
94 | ### Added
95 | - feat(a11y): adds optional prop `ariaLabelOlFixedOverlay` which sets an `aria-label` on the outermost `canvas` element rendered in the shadow root ([#445](https://github.com/theopensystemslab/map/pull/445))
96 | - fix(a11y): sets `aria-controls` on the OL Attribution control button rendered when `collapseAttributions` is true, and a corresponding `id` on the attribution list ([#446](https://github.com/theopensystemslab/map/pull/446))
97 |
98 | ### [0.8.1] - 2024-04-05
99 |
100 | ### Changed
101 | - fix: usability improvements such as stronger focus color contrast and improved keyboard navigation based on recent accessibility audit ([#442](https://github.com/theopensystemslab/map/pull/442))
102 | - deps: upgraded to Vite v5, in addition to a number of other Dependabot updates ([#441](https://github.com/theopensystemslab/map/pull/441))
103 |
104 | ### [0.8.0] - 2024-01-25
105 |
106 | ### Breaking
107 | - feat: adds new boolean prop `showGeojsonDataMarkers` to display point features passed via the `geojsonData` prop; renames existing `showMarker` boolean prop to `showCentreMarker` for clarity ([#429](https://github.com/theopensystemslab/map/pull/429))
108 |
109 | ### [0.7.9] - 2024-01-02
110 |
111 | ### Added
112 | - feat: new props `drawGeojsonDataCopyright`, `geojsonDataCopyright`, and `collapseAttributes` allow multiple attributions to be set and styled on the map ([#424](https://github.com/theopensystemslab/map/pull/424))
113 |
114 | ### Changed
115 | - deps: various dependency updates via Dependabot
116 |
117 | ### [0.7.8] - 2023-12-13
118 |
119 | ### Changed
120 | - fix: now displays vertices for polygons as well as multipolygons that are passed into `drawGeojsonData` prop ([#417](https://github.com/theopensystemslab/map/pull/417))
121 |
122 | ### [0.7.7] - 2023-09-01
123 |
124 | ### Added
125 | - feat: ability to set a custom border color _per_ feature when passing a `FeatureCollection` into `geojsonData` by reading from the feature's `properties.color` attribute. If `properties.color` is not defined, `geojsonColor` will be used to style each feature. ([#381](https://github.com/theopensystemslab/map/pull/381))
126 |
127 | ### [0.7.6] - 2023-08-30
128 |
129 | ### Added
130 | - feat: add `drawColor` & `drawFillColor` props to customise the drawing color. It still defaults to red for the canonical example of location plans. ([#379](https://github.com/theopensystemslab/map/pull/379))
131 |
132 | ### [0.7.5] - 2023-08-14
133 |
134 | ### Added
135 | - feat: add `clipGeojsonData` prop to disable panning/zooming/navigating the map's viewport beyond a given geojson extent. ([#363](https://github.com/theopensystemslab/map/pull/363))
136 |
137 | ### Changed
138 | - deps: various dependency updates via Dependabot
139 |
140 | ### [0.7.4] - 2023-03-17
141 |
142 | ### Changed
143 | - fix: ensure autocomplete selected address formatting always matches option, completing #275 below. ([#277](https://github.com/theopensystemslab/map/pull/277))
144 |
145 | ### [0.7.3] - 2023-03-17
146 |
147 | ### Changed
148 | - fix: split single line addresses on last occurance of council name, not first, in address-autocomplete dropdown options. Our previous string formatting method failed on postcode ME7 1NH ([#275](https://github.com/theopensystemslab/map/pull/275))
149 |
150 | ### [0.7.2] - 2023-02-24
151 |
152 | ### Added
153 | - feat: Printing ([#263](https://github.com/theopensystemslab/map/pull/263))
154 |
155 | ### Changed
156 | - chore: Update `@testing-library/dom` and `vitest` dependencies to latests ([#265](https://github.com/theopensystemslab/map/pull/265))
157 |
158 | ### [0.7.1] - 2023-02-07
159 |
160 | ### Changed
161 | - fix: correctly project coordinates to EPSG:27700 on GeoJSON change events (coordinates in EPSG:3857 are and were ok!) ([#261](https://github.com/theopensystemslab/map/pull/261))
162 |
163 | ### [0.7.0] - 2023-01-20
164 |
165 | ### Changed
166 | - **BREAKING**: GeoJSON change events are now dispatched in _two_ projections: EPSG:3857 (prior default) and EPSG:27700. If you are subscribed to these events, please update your code to reflect the new data format ([#255](https://github.com/theopensystemslab/map/pull/255))
167 | - fix: display scale bar correctly ([#252](https://github.com/theopensystemslab/map/pull/252))
168 | - fix: debug `drawGeojsonData` examples in Pitsy Component Docs ([#249](https://github.com/theopensystemslab/map/pull/249))
169 |
170 | ### [0.6.3] - 2022-12-21
171 |
172 | ### Added
173 | - feat: add `osProxyEndpoint` prop to support optionally calling the Ordnance Survey APIs via a proxy in public applications to avoid exposing your API keys ([#241](https://github.com/theopensystemslab/map/pull/241))
174 |
175 | ### Changed
176 | - build: update vitest dependencies
177 |
178 | ### [0.6.2] - 2022-12-09
179 |
180 | ### Added
181 | - feat: add `drawingType` prop to specify "Polygon" (default) or "Point" to enable drawing a single point ([#232](https://github.com/theopensystemslab/map/pull/232))
182 |
183 | ### Changed
184 | - chore: update styling of default scale line ([#230](https://github.com/theopensystemslab/map/pull/230))
185 | - chore: swap out north arrow icon and remove unused `resetControlImage` icons ([#233](https://github.com/theopensystemslab/map/pull/233))
186 | - build: update vite and vitest-related dependencies
187 |
188 | ### [0.6.1] - 2022-10-17
189 |
190 | ### Added
191 | - feat: `resetControlImage` prop can be used to specify a custom icon for the reset control button. This is likely a temporary prop while user research testing is conducted, then we will refactor to use a single standard icon ([#209](https://github.com/theopensystemslab/map/pull/209))
192 |
193 | ### [0.6.0] - 2022-10-10
194 |
195 | ### Added
196 | - feat: `showNorthArrow` boolean prop will show a static North arrow icon in the upper right of the map for official reference ([#198]https://github.com/theopensystemslab/map/pull/198)
197 |
198 | ### [0.5.9] - 2022-08-26
199 |
200 | ### Changed
201 | - fix: Ensure snap points load on the map's `loadend` event ([#193](https://github.com/theopensystemslab/map/pull/193))
202 | - test: Added basic suite of OL tests for snap loading, exposing an `olMap` instance on the global window for testing
203 |
204 | ### [0.5.8] - 2022-08-19
205 |
206 | ### Added
207 | - feat: Added map property `projection` to specify which system you are supplying coordinates in. Supported values are `EPSG:4326` (default), `EPSG:27700`, and `EPSG:3857` ([#168](https://github.com/theopensystemslab/map/pull/168))
208 | - feat: Added Vitest framework for unit testing our web components and a Github Action workflow to run tests on all pull requests ([#139](https://github.com/theopensystemslab/map/pull/139), [#191](https://github.com/theopensystemslab/map/pull/191))
209 | - feat: Added Pitsby interactive documentation for our web components, available at [oslmap.netlify.app](https://oslmap.netlify.app/) ([#61](https://github.com/theopensystemslab/map/pull/61))
210 |
211 | ### Changed
212 | - docs: Updated README to reflect scope of all components and new local dev instructions ([#181](https://github.com/theopensystemslab/map/pull/181))
213 | - build: Upgraded multiple project dependencies
214 |
215 | ### [0.5.7] - 2022-07-28
216 |
217 | ### Added
218 | - feat: `markerImage` property added to specify a circle (default) or pin icon ([#165](https://github.com/theopensystemslab/map/pull/165))
219 |
220 | ### Changed
221 | - build: Upgrade development dependency Vite to v3 ([#167](https://github.com/theopensystemslab/map/pull/167))
222 |
223 | ### [0.5.6] - 2022-07-05
224 |
225 | ### Added
226 | - feat: `showMarker` property added to display a point on the map (defaults to latitude & longitude used to center the map, custom coordinates can be provided using `markerLatitude`, `markerLongitude`) ([#159](https://github.com/theopensystemslab/map/pull/159))
227 |
228 | ### Changed
229 | - fix: Ability to remove border style using boolean property `featureBorderNone` when in `showFeaturesAtPoint` mode ([#159](https://github.com/theopensystemslab/map/pull/159))
230 |
231 | ### [0.5.5] - 2022-05-09
232 |
233 | ### Changed
234 | - fix: Update map focus to Gov.UK yellow, adding a black border on map element for sufficient contrast ([#147](https://github.com/theopensystemslab/map/pull/147))
235 |
236 | ## [0.5.4] - 2022-03-29
237 |
238 | ### Changed
239 | - fix: Ensure error container is always in DOM (autocomplete) ([#136](https://github.com/theopensystemslab/map/pull/136))
240 |
241 | ## [0.5.3] - 2022-03-28
242 |
243 | ### Changed
244 | - fix: Re-enable `labelStyle` property ([#133](https://github.com/theopensystemslab/map/pull/133))
245 |
246 | ## [0.5.2] - 2022-03-28
247 |
248 | ### Added
249 | - feat: `labelStyle` property added to autocomplete ([#130](https://github.com/theopensystemslab/map/pull/130))
250 |
251 | ### Changed
252 | - fix: Accessibility fixes flagged by auditors ([#131](https://github.com/theopensystemslab/map/pull/131))
253 |
254 | ## [0.5.1] - 2022-03-24
255 |
256 | ### Added
257 | - feat: `arrowStyle` property added to autocomplete ([#128](https://github.com/theopensystemslab/map/pull/128))
258 |
259 | ### Changed
260 | - fix: Improve style of autocomplete ([#128](https://github.com/theopensystemslab/map/pull/128))
261 |
262 | ## [0.5.0] - 2022-03-23
263 |
264 | ### Changed
265 | - fix: autocomplete shouldn't have a tabindex on its' container, only the input ([#126](https://github.com/theopensystemslab/map/pull/126))
266 |
267 | ## [0.4.9] - 2022-03-23
268 |
269 | ### Added
270 | - feat: allow autocomplete to be styled from the parent ([#124](https://github.com/theopensystemslab/map/pull/124))
271 |
272 | ### Changed
273 | - fix: autocomplete & search should set `tabindex="0"` to ensure they're keyboard accessible ([#122](https://github.com/theopensystemslab/map/pull/122))
274 |
275 | ## [0.4.8] - 2022-03-22
276 |
277 | ### Added
278 | - feat: address-autocomplete supports a default value using the `initialAddress` property ([#120](https://github.com/theopensystemslab/map/pull/120))
279 |
280 | ## [0.4.7] - 2022-03-22
281 |
282 | ### Added
283 | - feat: two new components ([#93](https://github.com/theopensystemslab/map/pull/93))! file structure & build config are adjusted to reflect a library of components, but no breaking changes to the original map. New components:
284 | 1. `` is a GOV.UK-styled input that validates UK postcodes using [these utility methods](https://www.npmjs.com/package/postcode). When a postcode is validated, an event is dispatched containing the sanitized string.
285 | 2. `` fetches addresses in a given UK postcode using the [OS Places API](https://developer.ordnancesurvey.co.uk/os-places-api) and displays them using GOV.UK's [accessible-autocomplete](https://github.com/alphagov/accessible-autocomplete) component. When you select an address, an event is dispatched with the full OS record for that address. Set the `osPlacesApiKey` property to start using this component.
286 |
287 | ## [0.4.6] - 2022-02-04
288 |
289 | ### Changed
290 | - fix: make snap points visible on the first render before any interactions if other conditions are met (`drawMode` is enabled, `zoom` is greater than or equal to 20). Previosly, we'd only render snaps after a map move ([#112](https://github.com/theopensystemslab/map/pull/112))
291 |
292 | ## [0.4.5] - 2022-01-14
293 |
294 | ### Added
295 | - feat: string property `id` now allows users to set a custom id on the custom element ``. it still defaults to `id="map"` as before ([#110](https://github.com/theopensystemslab/map/pull/110))
296 |
297 | ### Changed
298 | - fix: `featureSource` and `drawingSource` are now cleared upfront when their respective interaction modes (eg `showFeaturesAtPoint`, `drawMode`) are enabled. This doesn't change anything on the first map render, but should help clear up scenarios where the map has been redrawn with new props but the layer still holds prior data features ([#110](https://github.com/theopensystemslab/map/pull/110))
299 |
300 | ## [0.4.4] - 2022-01-11
301 |
302 | ### Changed
303 | - fix: when in `drawMode`, "reset" control button now dispatches two events to reset area to 0 and empty geojson. Previously, the area and geojson continued to reflect the last drawn polygon ([#102](https://github.com/theopensystemslab/map/pull/102))
304 | - bump rambda and @types/node dependencies ([#107](https://github.com/theopensystemslab/map/pull/107) & [#108](https://github.com/theopensystemslab/map/pull/108))
305 |
306 | ## [0.4.3] - 2021-12-14
307 |
308 | ### Changed
309 | - fix: control buttons are an accessible size ([#95](https://github.com/theopensystemslab/map/pull/95))
310 | - fix: add Lit lifecycle method to unmount map ([#97](https://github.com/theopensystemslab/map/pull/97))
311 |
312 | ## [0.4.2] - 2021-11-26
313 |
314 | ### Changed
315 | - upgrade openlayers ([#89](https://github.com/theopensystemslab/map/pull/89))
316 |
317 | ## [0.4.1] - 2021-11-25
318 |
319 | ### Changed
320 | - feat: string property `osCopyright` now allows users to set the map attribution for OS layers based on their own API keys. The default copyright text is updated to reflect our new data agreement with DHLUC ([#88](https://github.com/theopensystemslab/map/pull/88))
321 |
322 | ## [0.4.0] - 2021-11-24
323 |
324 | ### Changed
325 | - **BREAKING**: removed `ariaLabel` property based on accessibility audit recommendation, as aria-label attributes shouldn't be used on div elements ([#86](https://github.com/theopensystemslab/map/pull/86))
326 |
327 | ## [0.3.7] - 2021-11-19
328 |
329 | ### Added
330 | - feat: string property `drawPointer` to set the drawing cursor style, defaults to "crosshair" or can be set to "dot" ([#84](https://github.com/theopensystemslab/map/pull/84))
331 |
332 | ### Changed
333 | - fix: keep snapping behavior while modifying drawn polygon ([#83](https://github.com/theopensystemslab/map/pull/83))
334 |
335 | ## [0.3.6] - 2021-11-12
336 |
337 | ### Added
338 | - feat: `drawMode` now derives snap-able points from the OS Vector Tiles basemap and displays them by default when the zoom level > 20. The drawing pointer also changed from a red dot to a simple crosshair. ([#75](https://github.com/theopensystemslab/map/pull/75))
339 |
340 | ### Changed
341 | - fix: updated control button color for more accessible level of contrast ([#77](https://github.com/theopensystemslab/map/pull/77))
342 | - fix: ensure prettier is run on precommit hook ([#78](https://github.com/theopensystemslab/map/pull/78))
343 | - fix: typo in Readme ([#73](https://github.com/theopensystemslab/map/pull/73))
344 |
345 | ## [0.3.5] - 2021-10-27
346 |
347 | ### Added
348 | - feat: ability to display a geojson polygon in the initial drawing layer when in `drawMode`, using new object property `drawGeojsonData` and number property `drawGeojsonBuffer` ([#70](https://github.com/theopensystemslab/map/pull/70))
349 | - feat: dispatch events `featuresAreaChange`, `featuresGeojsonChange` and `geojsonDataArea`, so that show/click features mode and loading static data has parity with existing event dispatching used in draw mode ([#69](https://github.com/theopensystemslab/map/pull/69))
350 |
351 | ## [0.3.4] - 2021-10-01
352 |
353 | ### Added
354 | - feat: boolean property `featureFill` to style the fill color of OS Features polygon as the specified stroke color with 20% opacity, disabled/false by default. Same idea as below, my oversight for not combining them into the same release! ([#66](https://github.com/theopensystemslab/map/pull/66))
355 |
356 | ## [0.3.3] - 2021-10-01
357 |
358 | ### Added
359 | - feat: boolean property `geojsonFill` to style the fill color of a static geojson polygon as the specified stroke color with 20% opacity, disabled/false by default ([#64](https://github.com/theopensystemslab/map/pull/64))
360 |
361 | ## [0.3.2] - 2021-09-22
362 |
363 | ### Added
364 | - feat: show vertices of the drawn polygon, similar in design to MapInfo Professional which will hopefully help guide users in modifying existing vertices or adding new ones when drawing a site boundary ([#57](https://github.com/theopensystemslab/map/pull/57))
365 | - feat: accessibilty improvements, including string property `ariaLabel` to add custom text to describe the component and the ability to access the main map div and control buttons by tabbing ([#58](https://github.com/theopensystemslab/map/pull/58))
366 | - feat: boolean properties `showScale` and `useScaleBarStyle` to display a scale bar on the map ([#60](https://github.com/theopensystemslab/map/pull/60))
367 |
368 | ## [0.3.1] - 2021-08-27
369 |
370 | ### Changed
371 | - fix: any prior drawings are cleared upon enabling `drawMode`, resolving an edge case that could occur in PlanX 'back' button behavior ([#50](https://github.com/theopensystemslab/map/pull/50))
372 |
373 | ### Added
374 | - feat: string property `areaUnit` to specify "m2" for metres squared (default) or "ha" for hectares when returning the total area of a feature ([#51](https://github.com/theopensystemslab/map/pull/51))
375 | - feat: boolean property `clickFeatures` to extend the `showFeaturesAtPoint` mode, by allowing a user to click to select or de-select features ([#48](https://github.com/theopensystemslab/map/pull/48))
376 |
377 | ## [0.3.0] - 2021-08-17
378 |
379 | ### Changed
380 | - **BREAKING**: `renderVectorTiles` is renamed to `disableVectorTiles` and disabled by default, a convention we'll follow for all boolean property types going forward ([#40](https://github.com/theopensystemslab/map/pull/40))
381 | - fix: reset control erases drawing when `geojsonData` is also displayed ([#42](https://github.com/theopensystemslab/map/pull/42))
382 | - fix: total area doesn't return html tags if units are configured to square metres ([#43](https://github.com/theopensystemslab/map/pull/43))
383 |
384 | ### Added
385 | - feat: boolean properties `hideResetControl` and `staticMode` to configure visibility of control buttons and allowed user interactions like zooming/dragging ([#41](https://github.com/theopensystemslab/map/pull/41))
386 |
387 | ## [0.2.0] - 2021-08-12
388 |
389 | ### Changed
390 | - **BREAKING**: Ordnance Survey API keys are now provided client-side as optional properties `osVectorTilesApiKey`, `osFeaturesApiKey` ([#29](https://github.com/theopensystemslab/map/pull/29))
391 | - fix: `geojsonData` now handles `{ "type": "Feature" }` in addition to "FeatureCollection" ([#34](https://github.com/theopensystemslab/map/pull/34))
392 |
393 | ### Added
394 | - docs: basic examples + gif ([#33](https://github.com/theopensystemslab/map/pull/33), [#35](https://github.com/theopensystemslab/map/pull/35))
395 |
396 | ## [0.1.0] - 2021-08-10
397 |
398 | ### Changed
399 |
400 | - **BREAKING**: [`drawMode` is now disabled by default](https://github.com/theopensystemslab/map/pull/24#discussion_r685808355)
401 | - upgrade from lit-element > lit ([#27](https://github.com/theopensystemslab/map/pull/27))
402 |
403 | ### Added
404 |
405 | - feat: query & display features that intersect with lon,lat ([#24](https://github.com/theopensystemslab/map/pull/24))
406 | - feat: display a static polygon if geojson provided ([#19](https://github.com/theopensystemslab/map/pull/19))
407 | - docs: ([update npm badge link](https://github.com/theopensystemslab/map/commit/5e95993869bc6bd04761fdfb02a7e208e82aade6))
408 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The Mozilla Public License (MPL) Version 2
2 |
3 | Copyright (c) 2023
4 |
5 | This source code is licensed under the Mozilla Public License v2.0. To view this license, visit https://mozilla.org/MPL/2.0/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Place components
2 |
3 | [](http://npm.im/@opensystemslab/map)
4 |
5 | A library of [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) for tasks related to addresses and planning permission in the UK built with [Lit](https://lit.dev/), [Vite](https://vitejs.dev/), and [Ordnance Survey APIs](https://developer.ordnancesurvey.co.uk/).
6 |
7 | ***Web map***
8 |
9 | `` is an [OpenLayers](https://openlayers.org/)-powered map to support drawing and modifying red-line boundaries. Other supported modes include: highlighting an OS Feature that intersects with a given address point; clicking to select and merge multiple OS Features into a single boundary; and displaying static point or polygon data. Events are dispatched with the calculated area and geojson representation when you change your drawing.
10 |
11 | 
12 |
13 | ***Postcode search***
14 |
15 | `` is a [GOV.UK-styled](https://frontend.design-system.service.gov.uk/) input that validates UK postcodes using these [utility methods](https://www.npmjs.com/package/postcode). When a postcode is validated, an event is dispatched containing the sanitized string.
16 |
17 | ***Address autocomplete***
18 |
19 | `` fetches addresses in a given UK postcode using the [OS Places API](https://developer.ordnancesurvey.co.uk/os-places-api) and displays them using GOV.UK's [accessible-autocomplete](https://github.com/alphagov/accessible-autocomplete) component. An event is dispatched with the OS record when you select an address.
20 |
21 | These web components can be used independently or together following GOV.UK's [Address lookup](https://design-system.service.gov.uk/patterns/addresses/) design pattern.
22 |
23 | 
24 |
25 | ## Documentation & examples
26 |
27 | - Interactive web component docs [oslmap.netlify.app](https://oslmap.netlify.app)
28 | - [CodeSandbox](https://codesandbox.io/s/confident-benz-rr0s9?file=/index.html) (note: update the CDN script with a version number for new features)
29 |
30 | Find these components in the wild, including what we're learning through public beta user-testing, at [https://www.ripa.digital/](https://www.ripa.digital/).
31 |
32 | ## Bring your own API keys
33 |
34 | Different features rely on different APIs - namely from Ordnance Survey and Mapbox.
35 |
36 | You can set keys directly as props (eg `osApiKey`) on the applicable web components or [use a proxy](https://github.com/theopensystemslab/map/blob/main/docs/how-to-use-a-proxy.md) to mask these secrets.
37 |
38 | Address autocomplete utilises the OS Places API.
39 |
40 | For the map:
41 | - The `basemap` prop defaults to `"OSVectorTile"` which requires the OS Vector Tiles API
42 | - Basemap `"OSRaster"` uses the OS Maps API
43 | - Basemap `"MapboxSatellite"` requires a Mapbox Access Token with with scope `style:read`
44 | - The `"OSM"` (OpenStreetMap) basemap is available for users without any keys, and as a fallback if any of the above basemaps fail to build
45 | - `clickFeatures` requires the OS Features API
46 |
47 | When using Ordnance Survey APIs:
48 | - Update the `osCopyright` attribution prop with your license number
49 | - Configure an optional `osProxyEndpoint` to avoid exposing your keys (set this instead of `osApiKey`)
50 | - ** We are not currently supporting a similar proxy for Mapbox because access tokens can be restricted to specific URLs via your account
51 |
52 | ## Running locally
53 |
54 | - Rename `.env.example` to `.env.local` and replace the values - or simply provide your API keys as props
55 | - Install [pnpm](https://pnpm.io) globally if you don't have it already `npm i pnpm -g`
56 | - Install dependencies `pnpm i`
57 | - Start development server `pnpm dev`
58 |
59 | ### Tests
60 |
61 | Unit tests are written with [Vitest](https://vitest.dev/), [Happy Dom](https://www.npmjs.com/package/happy-dom), and [@testing-library/user-event](https://testing-library.com/docs/user-event/intro/). Each component has a `main.test.ts` file.
62 |
63 | - `pnpm test` starts `vitest` in watch mode
64 | - `pnpm test:ui` opens Vitest's UI in the browser to interactively explore logs https://vitest.dev/guide/ui.html
65 |
66 | ### Docs
67 |
68 | We use [Pitsby](https://pitsby.com/) for documenting our web components. It's simple to configure (`pitsby.config.js` plus a `*.doc.js` per component), has good support for vanilla web components, and an interactive playground.
69 |
70 | - `pnpm run docs` starts Pitsby in watch mode for local development
71 | - `pnpm run docsPublish` builds the site so Netlify can serve it from `pitsby/`
72 |
73 | ### Deployments
74 |
75 | We publish this package via [NPM](https://www.npmjs.com/package/@opensystemslab/map).
76 |
77 | To create a new release:
78 | 1. Open a new PR against `main` which bumps the package.json "version" & creates a CHANGELOG.md entry, request code review & merge on approval
79 | 1. Run `npm publish` or `npm publish --tag next` if making a pre-release (requires permissions to OSL team in NPM & access to 2-factor auth method)
80 | 1. [Draft a new release](https://github.com/theopensystemslab/map/releases) via GitHub web: tag should match version, automatically generate changenotes and link above PR, then "Publish" and set as latest version (or set as pre-release if you used `--tag next` in above command)
81 |
82 | ## License
83 |
84 | This repository is licensed under the [Open Government License v3](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).
85 |
--------------------------------------------------------------------------------
/docs/how-to-use-a-proxy.md:
--------------------------------------------------------------------------------
1 | # How to: Use a MyMap & AddressAutocomplete with a proxy
2 |
3 | ## Context
4 | Both `MyMap` and `AddressAutocomplete` can call the Ordnance Survey API directly, or via a proxy.
5 |
6 | Calling the API directly may be suitable for internal use, where exposure of API keys is not a concern, whilst calling a proxy may be more suitable for public use.
7 |
8 | A proxy endpoint can be supplied via the `osProxyEndpoint` property on these components.
9 |
10 | Proxies are required to complete the following actions in order to work successfully -
11 |
12 | - Append a valid OS API key as a search parameter to incoming requests
13 | - Modify outgoing response with suitable CORS / CORP headers to allow the originating site access to the returned assets
14 |
15 | ## Diagram
16 | ```mermaid
17 | sequenceDiagram
18 | autonumber
19 | participant WC as Web Component
20 | participant P as Proxy
21 | participant OS as Ordnance Survey API
22 |
23 | WC ->>+ P: Request
24 | P -->> P: Validate Request
25 | P ->>+ OS: Request + API key
26 | OS ->>- P: Response
27 | P ->>- WC: Response + CORP/CORS headers
28 | ```
29 |
30 | ## Examples
31 | Please see the sample code below for how a proxy could be implemented -
32 |
33 | ### Express
34 | Below is an annotated example of a simple proxy using [Express](https://github.com/expressjs/express) & [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware).
35 |
36 | **index.js**
37 | ```js
38 | import express from "express";
39 | import { useOrdnanceSurveyProxy } from "proxy";
40 |
41 | const app = express()
42 | const port = 3000
43 |
44 | app.use('/proxy/ordnance-survey', useOrdnanceSurveyProxy)
45 |
46 | app.listen(port)
47 | ```
48 |
49 | **proxy.js**
50 | ```js
51 | import { createProxyMiddleware } from "http-proxy-middleware";
52 |
53 | const OS_DOMAIN = "https://api.os.uk";
54 |
55 | export const useOrdnanceSurveyProxy = async (req, res, next) => {
56 | if (!isValid(req)) return next({
57 | status: 401,
58 | message: "Unauthorised"
59 | })
60 |
61 | return createProxyMiddleware({
62 | target: OS_DOMAIN,
63 | changeOrigin: true,
64 | onProxyRes: (proxyRes) => setCORPHeaders(proxyRes),
65 | pathRewrite: (fullPath, req) => appendAPIKey(fullPath, req)
66 | onError: (_err, _req, res) => {
67 | res.json({
68 | status: 500,
69 | message: "Something went wrong",
70 | });
71 | },
72 | })(req, res, next);
73 | };
74 |
75 | const isValid = (req) => {
76 | // Your validation logic here, for example checking req.header.referer against an allowlist of domains
77 | }
78 |
79 | // Ensure that returned tiles can be embedded cross-site
80 | // May not be required if "same-site" policy works for your setup
81 | const setCORPHeaders = (proxyRes: IncomingMessage): void => {
82 | proxyRes.headers["Cross-Origin-Resource-Policy"] = "cross-origin"
83 | }
84 |
85 | export const appendAPIKey = (fullPath, req) => {
86 | const [path, params] = fullPath.split("?");
87 | // Append API key
88 | const updatedParams = new URLSearchParams(params);
89 | updatedParams.set("key", process.env.ORDNANCE_SURVEY_API_KEY);
90 | // Remove our API baseUrl (/proxy/ordnance-survey)
91 | const updatedPath = path.replace(req.baseUrl, "");
92 | // Construct and return rewritten path
93 | const resultPath = [updatedPath, updatedParams.toString()].join("?");
94 | return resultPath;
95 | };
96 | ```
97 | > A working and more fleshed out example (in TypeScript) can be seen [here in the PlanX API](https://github.com/theopensystemslab/planx-new/blob/production/api.planx.uk/proxy/ordnanceSurvey.ts).
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |