@fieldia/map 0.0.0-stage → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -2
  3. package/package.json +37 -3
  4. package/src/index.d.mts +6 -0
  5. package/src/index.d.ts +6 -0
  6. package/src/index.js +22 -0
  7. package/src/index.js.map +1 -0
  8. package/src/index.mjs +6 -0
  9. package/src/index.mjs.map +1 -0
  10. package/src/lib/area.d.mts +3 -0
  11. package/src/lib/area.d.ts +3 -0
  12. package/src/lib/area.js +591 -0
  13. package/src/lib/area.js.map +1 -0
  14. package/src/lib/area.mjs +588 -0
  15. package/src/lib/area.mjs.map +1 -0
  16. package/src/lib/geo.d.mts +72 -0
  17. package/src/lib/geo.d.ts +72 -0
  18. package/src/lib/geo.js +149 -0
  19. package/src/lib/geo.js.map +1 -0
  20. package/src/lib/geo.mjs +134 -0
  21. package/src/lib/geo.mjs.map +1 -0
  22. package/src/lib/kinds.d.mts +35 -0
  23. package/src/lib/kinds.d.ts +35 -0
  24. package/src/lib/kinds.js +127 -0
  25. package/src/lib/kinds.js.map +1 -0
  26. package/src/lib/kinds.mjs +124 -0
  27. package/src/lib/kinds.mjs.map +1 -0
  28. package/src/lib/labels.d.mts +58 -0
  29. package/src/lib/labels.d.ts +58 -0
  30. package/src/lib/labels.js +214 -0
  31. package/src/lib/labels.js.map +1 -0
  32. package/src/lib/labels.mjs +209 -0
  33. package/src/lib/labels.mjs.map +1 -0
  34. package/src/lib/leaflet-css.d.mts +2 -0
  35. package/src/lib/leaflet-css.d.ts +2 -0
  36. package/src/lib/leaflet-css.js +34 -0
  37. package/src/lib/leaflet-css.js.map +1 -0
  38. package/src/lib/leaflet-css.mjs +31 -0
  39. package/src/lib/leaflet-css.mjs.map +1 -0
  40. package/src/lib/leaflet.d.mts +15 -0
  41. package/src/lib/leaflet.d.ts +15 -0
  42. package/src/lib/leaflet.js +76 -0
  43. package/src/lib/leaflet.js.map +1 -0
  44. package/src/lib/leaflet.mjs +72 -0
  45. package/src/lib/leaflet.mjs.map +1 -0
  46. package/src/lib/map-core.d.mts +47 -0
  47. package/src/lib/map-core.d.ts +47 -0
  48. package/src/lib/map-core.js +300 -0
  49. package/src/lib/map-core.js.map +1 -0
  50. package/src/lib/map-core.mjs +297 -0
  51. package/src/lib/map-core.mjs.map +1 -0
  52. package/src/lib/place.d.mts +3 -0
  53. package/src/lib/place.d.ts +3 -0
  54. package/src/lib/place.js +323 -0
  55. package/src/lib/place.js.map +1 -0
  56. package/src/lib/place.mjs +320 -0
  57. package/src/lib/place.mjs.map +1 -0
  58. package/src/lib/providers.d.mts +131 -0
  59. package/src/lib/providers.d.ts +131 -0
  60. package/src/lib/providers.js +224 -0
  61. package/src/lib/providers.js.map +1 -0
  62. package/src/lib/providers.mjs +217 -0
  63. package/src/lib/providers.mjs.map +1 -0
  64. package/src/lib/search-box.d.mts +28 -0
  65. package/src/lib/search-box.d.ts +28 -0
  66. package/src/lib/search-box.js +141 -0
  67. package/src/lib/search-box.js.map +1 -0
  68. package/src/lib/search-box.mjs +138 -0
  69. package/src/lib/search-box.mjs.map +1 -0
  70. package/src/lib/settings.d.mts +19 -0
  71. package/src/lib/settings.d.ts +19 -0
  72. package/src/lib/settings.js +3 -0
  73. package/src/lib/settings.js.map +1 -0
  74. package/src/lib/settings.mjs +2 -0
  75. package/src/lib/settings.mjs.map +1 -0
  76. package/src/lib/styles.d.mts +11 -0
  77. package/src/lib/styles.d.ts +11 -0
  78. package/src/lib/styles.js +127 -0
  79. package/src/lib/styles.js.map +1 -0
  80. package/src/lib/styles.mjs +122 -0
  81. package/src/lib/styles.mjs.map +1 -0
  82. package/src/lib/widgets.d.mts +14 -0
  83. package/src/lib/widgets.d.ts +14 -0
  84. package/src/lib/widgets.js +21 -0
  85. package/src/lib/widgets.js.map +1 -0
  86. package/src/lib/widgets.mjs +18 -0
  87. package/src/lib/widgets.mjs.map +1 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * The maps in Fieldia's colours: every colour a token, so a theme, a host's
3
+ * tokens and the dark scheme reach the map's buttons, search, shapes and
4
+ * grips. Fixed on purpose: the veil over the map that asks for two fingers
5
+ * or Ctrl (white words on a dark veil, as an image's caption has them).
6
+ */
7
+ export const MAP_CSS = `
8
+ .fd-map-field { display: grid; gap: 8px; min-width: 0; }
9
+ .fd-map-tools { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-width: 0; }
10
+ .fd-map-tools .fd-button { min-height: 32px; padding-inline: 10px; }
11
+ .fd-map-tools .fd-button[aria-pressed="true"] { background: var(--fd-accent-soft); border-color: var(--fd-accent); color: var(--fd-accent); }
12
+ .fd-map-tools .fd-button svg { width: 16px; height: 16px; flex: none; }
13
+ .fd-map-search { position: relative; flex: 1 1 220px; min-width: 0; }
14
+ .fd-map-results {
15
+ position: absolute; inset-inline: 0; top: calc(100% + 4px); z-index: 1100; margin: 0; padding: 4px; list-style: none;
16
+ background: var(--fd-surface); color: var(--fd-text); border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius);
17
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16); max-height: 240px; overflow: auto;
18
+ }
19
+ .fd-map-results [role="option"] { padding: 6px 8px; border-radius: 4px; cursor: pointer; line-height: 1.35; }
20
+ .fd-map-results [role="option"][aria-selected="true"], .fd-map-results [role="option"]:hover { background: var(--fd-accent-soft); }
21
+ .fd-map-results .fd-map-results-note { padding: 6px 8px; color: var(--fd-muted); cursor: default; }
22
+ .fd-map-box {
23
+ position: relative; height: var(--fd-map-height, 280px); min-height: 160px; overflow: hidden; isolation: isolate;
24
+ border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); background: var(--fd-fill);
25
+ }
26
+ .fd-map-box.leaflet-container:focus { outline: none; }
27
+ .fd-map-box.leaflet-container[data-keys]:focus { outline: 2px solid var(--fd-focus); outline-offset: 1px; }
28
+ .fd-map-box.leaflet-container { font: inherit; background: var(--fd-fill); }
29
+ .fd-map-zoom { position: absolute; top: 8px; z-index: 1000; display: grid; gap: 4px; }
30
+ .fd-map-zoom[data-side="right"] { right: 8px; }
31
+ .fd-map-zoom[data-side="left"] { left: 8px; }
32
+ .fd-map-zoom button {
33
+ width: 32px; height: 32px; display: grid; place-items: center; padding: 0; cursor: pointer; font: 600 18px/1 system-ui, sans-serif;
34
+ background: var(--fd-surface); color: var(--fd-text); border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius);
35
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
36
+ }
37
+ .fd-map-zoom button:hover { color: var(--fd-accent); border-color: var(--fd-accent); }
38
+ .fd-map-zoom button:focus-visible, .fd-map-hint button:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 1px; }
39
+ .fd-map-credits {
40
+ position: absolute; right: 0; bottom: 0; z-index: 1000; max-width: 72%; padding: 1px 6px; font-size: 11px; line-height: 1.5;
41
+ background: color-mix(in srgb, var(--fd-surface) 88%, transparent); color: var(--fd-text); border-top-left-radius: 4px;
42
+ }
43
+ .fd-map-credits a { color: inherit; }
44
+ .fd-map-logo { position: absolute; left: 6px; bottom: 4px; z-index: 1000; display: inline-flex; align-items: center; text-decoration: none; }
45
+ .fd-map-logo img { height: 18px; width: auto; display: block; }
46
+ .fd-map-logo span {
47
+ font: 700 12px/1.4 system-ui, sans-serif; padding: 0 5px; border-radius: 3px;
48
+ background: color-mix(in srgb, var(--fd-surface) 88%, transparent); color: var(--fd-text);
49
+ }
50
+ .fd-map-veil {
51
+ position: absolute; inset: 0; z-index: 1001; display: grid; place-items: center; padding: 16px; text-align: center;
52
+ background: rgba(0, 0, 0, 0.5); color: #fff; font-weight: 600; opacity: 0; pointer-events: none; transition: opacity 0.2s;
53
+ }
54
+ .fd-map-veil[data-show] { opacity: 1; }
55
+ .fd-map-crosshair { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; z-index: 900; pointer-events: none; display: none; }
56
+ .fd-map-crosshair::before, .fd-map-crosshair::after { content: ""; position: absolute; background: var(--fd-accent); box-shadow: 0 0 0 1px var(--fd-surface); }
57
+ .fd-map-crosshair::before { left: 10px; top: 0; width: 2px; height: 22px; }
58
+ .fd-map-crosshair::after { top: 10px; left: 0; height: 2px; width: 22px; }
59
+ .fd-map-box[data-keys]:focus .fd-map-crosshair { display: block; }
60
+ .fd-map-hint {
61
+ position: absolute; top: 8px; left: 8px; right: 52px; z-index: 1000; display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center;
62
+ padding: 6px 10px; font-size: 13px; line-height: 1.4; background: var(--fd-surface); color: var(--fd-text);
63
+ border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.14);
64
+ }
65
+ .fd-map-box[data-side="left"] .fd-map-hint { left: 52px; right: 8px; }
66
+ .fd-map-hint p { margin: 0; flex: 1 1 180px; min-width: 0; }
67
+ .fd-map-hint .fd-button { min-height: 28px; padding: 2px 10px; }
68
+ .fd-map-coords { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
69
+ .fd-map-coords label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--fd-muted); }
70
+ .fd-map-coords .fd-input { width: 12ch; font-variant-numeric: tabular-nums; }
71
+ .fd-map-coords .fd-input[aria-invalid="true"] { border-color: var(--fd-error); }
72
+ .fd-map-note { margin: 0; font-size: 12.5px; color: var(--fd-muted); }
73
+ .fd-map-note[data-tone="error"] { color: var(--fd-error); }
74
+ .fd-map-pin { width: 28px; height: 40px; }
75
+ .fd-map-pin svg { display: block; width: 28px; height: 40px; filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.3)); }
76
+ .fd-map-pin .fd-map-pin-body { fill: var(--fd-accent); stroke: var(--fd-surface); stroke-width: 1.5; }
77
+ .fd-map-pin .fd-map-pin-dot { fill: var(--fd-surface); }
78
+ .fd-map-pin:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; border-radius: 4px; }
79
+ path.fd-map-shape { stroke: var(--fd-accent); fill: var(--fd-accent); stroke-width: 2; fill-opacity: 0.16; }
80
+ path.fd-map-shape.fd-map-movable { cursor: move; }
81
+ path.fd-map-trace { stroke: var(--fd-accent); fill: var(--fd-accent); stroke-width: 2; fill-opacity: 0.08; stroke-dasharray: 6 5; pointer-events: none; }
82
+ .fd-map-grip { width: 24px; height: 24px; display: grid; place-items: center; cursor: grab; }
83
+ .fd-map-grip::after {
84
+ content: ""; width: 12px; height: 12px; border-radius: 50%; box-sizing: border-box;
85
+ background: var(--fd-surface); border: 2px solid var(--fd-accent); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
86
+ }
87
+ .fd-map-grip[data-closes]::after { width: 18px; height: 18px; background: var(--fd-accent); border-color: var(--fd-surface); }
88
+ .fd-map-grip:focus-visible { outline: none; }
89
+ .fd-map-grip:focus-visible::after { box-shadow: 0 0 0 3px var(--fd-focus); }
90
+ .fd-map-field select.fd-input { width: auto; max-width: 100%; }
91
+ /* One finger scrolls the page past a map, as on any page; two move it. While a shape is drawn, the map takes every touch. */
92
+ .fd-map-box.leaflet-container, .fd-map-box.leaflet-touch-drag.leaflet-touch-zoom { touch-action: pan-x pan-y; }
93
+ .fd-map-box.leaflet-container[data-drawing] { touch-action: none; }
94
+ .fd-map-box .leaflet-marker-draggable { touch-action: none; }
95
+ .fd-map-grip-add::after { width: 10px; height: 10px; opacity: 0.7; }
96
+ /* Each image overlaps the next by a pixel (leaflet.ts): drawn plainly over it, not added to it as Leaflet's own seam fix adds light. */
97
+ .fd-map-box.leaflet-container img.leaflet-tile { mix-blend-mode: normal; }
98
+ `;
99
+ /** The maps' own stylesheet, once per document: the tools, the search and the box are drawn before Leaflet has loaded. */
100
+ export function installMapStyles(doc) {
101
+ if (doc.getElementById('fieldia-map-styles'))
102
+ return;
103
+ const own = doc.createElement('style');
104
+ own.id = 'fieldia-map-styles';
105
+ own.textContent = MAP_CSS;
106
+ // Before the page's own styles, so an app's rule for a map wins over these.
107
+ doc.head.prepend(own);
108
+ }
109
+ /** Leaflet's stylesheet, once per document, before the maps' own (which add to it): it comes with Leaflet. */
110
+ export function installLeafletStyles(doc, css) {
111
+ if (doc.getElementById('fieldia-leaflet-styles'))
112
+ return;
113
+ const leaflet = doc.createElement('style');
114
+ leaflet.id = 'fieldia-leaflet-styles';
115
+ leaflet.textContent = css;
116
+ const own = doc.getElementById('fieldia-map-styles');
117
+ if (own)
118
+ own.before(leaflet);
119
+ else
120
+ doc.head.prepend(leaflet);
121
+ }
122
+ //# sourceMappingURL=styles.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/styles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FtB,CAAC;AAEF,0HAA0H;AAC1H,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,IAAI,GAAG,CAAC,cAAc,CAAC,oBAAoB,CAAC;QAAE,OAAO;IACrD,MAAM,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,GAAG,oBAAoB,CAAC;IAC9B,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,oBAAoB,CAAC,GAAa,EAAE,GAAW;IAC7D,IAAI,GAAG,CAAC,cAAc,CAAC,wBAAwB,CAAC;QAAE,OAAO;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,GAAG,wBAAwB,CAAC;IACtC,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC;IAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;IACrD,IAAI,GAAG;QAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;;QACxB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { WidgetFactory } from '@fieldia/widgets';
2
+ import type { MapSettings } from './settings.mjs';
3
+ /**
4
+ * The maps' widgets, for the viewer's (and the designer's) `widgets`:
5
+ *
6
+ * - `"widget": "place"` on a json field keeps a GeoJSON Point; on a float
7
+ * field, its latitude, with `options.longitudeField` naming the field for
8
+ * its longitude.
9
+ * - `"widget": "area"` on a json field keeps a GeoJSON Feature: a polygon,
10
+ * a box or a circle.
11
+ *
12
+ * Every map shares the settings given here: its provider above all.
13
+ */
14
+ export declare function mapWidgets(settings: MapSettings): Record<string, WidgetFactory>;
@@ -0,0 +1,14 @@
1
+ import type { WidgetFactory } from '@fieldia/widgets';
2
+ import type { MapSettings } from './settings';
3
+ /**
4
+ * The maps' widgets, for the viewer's (and the designer's) `widgets`:
5
+ *
6
+ * - `"widget": "place"` on a json field keeps a GeoJSON Point; on a float
7
+ * field, its latitude, with `options.longitudeField` naming the field for
8
+ * its longitude.
9
+ * - `"widget": "area"` on a json field keeps a GeoJSON Feature: a polygon,
10
+ * a box or a circle.
11
+ *
12
+ * Every map shares the settings given here: its provider above all.
13
+ */
14
+ export declare function mapWidgets(settings: MapSettings): Record<string, WidgetFactory>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapWidgets = mapWidgets;
4
+ const area_1 = require("./area");
5
+ const place_1 = require("./place");
6
+ /**
7
+ * The maps' widgets, for the viewer's (and the designer's) `widgets`:
8
+ *
9
+ * - `"widget": "place"` on a json field keeps a GeoJSON Point; on a float
10
+ * field, its latitude, with `options.longitudeField` naming the field for
11
+ * its longitude.
12
+ * - `"widget": "area"` on a json field keeps a GeoJSON Feature: a polygon,
13
+ * a box or a circle.
14
+ *
15
+ * Every map shares the settings given here: its provider above all.
16
+ */
17
+ function mapWidgets(settings) {
18
+ const place = (0, place_1.placeWidget)(settings);
19
+ return { 'json.place': place, 'float.place': place, 'json.area': (0, area_1.areaWidget)(settings) };
20
+ }
21
+ //# sourceMappingURL=widgets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgets.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/widgets.ts"],"names":[],"mappings":";;AAgBA,gCAGC;AAlBD,iCAAoC;AACpC,mCAAsC;AAGtC;;;;;;;;;;GAUG;AACH,SAAgB,UAAU,CAAC,QAAqB;IAC9C,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,IAAA,iBAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { areaWidget } from './area.mjs';
2
+ import { placeWidget } from './place.mjs';
3
+ /**
4
+ * The maps' widgets, for the viewer's (and the designer's) `widgets`:
5
+ *
6
+ * - `"widget": "place"` on a json field keeps a GeoJSON Point; on a float
7
+ * field, its latitude, with `options.longitudeField` naming the field for
8
+ * its longitude.
9
+ * - `"widget": "area"` on a json field keeps a GeoJSON Feature: a polygon,
10
+ * a box or a circle.
11
+ *
12
+ * Every map shares the settings given here: its provider above all.
13
+ */
14
+ export function mapWidgets(settings) {
15
+ const place = placeWidget(settings);
16
+ return { 'json.place': place, 'float.place': place, 'json.area': areaWidget(settings) };
17
+ }
18
+ //# sourceMappingURL=widgets.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgets.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/widgets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,QAAqB;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC1F,CAAC"}