@nika-js/onlymap 0.4.0 → 0.4.1
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.
- package/README.md +2 -2
- package/dist/{LercDecode.es-CWLcQT4F.js → LercDecode.es-B35eeLUh.js} +1 -1
- package/dist/{basemap-CZupn0P2.js → basemap--znNIrJq.js} +1 -1
- package/dist/elements/om-map.d.ts +30 -0
- package/dist/elements/om-widget.d.ts +15 -0
- package/dist/{index-BoxZ3Mec.js → index-BKiyX-jQ.js} +9453 -9266
- package/dist/{index-SWWESFOk.js → index-C8twrrDP.js} +2 -2
- package/dist/{index-Vw-Top85.js → index-CHmCCmPV.js} +1 -1
- package/dist/{index-CC4aVelb.js → index-ClqgDar6.js} +1 -1
- package/dist/{index-C8uDiJN4.js → index-_K3U-Ww1.js} +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/{lerc-CSc9BX_F.js → lerc-filCwJiM.js} +2 -2
- package/dist/onlymap.standalone.js +14204 -14017
- package/dist/onlymapjs.js +57 -49
- package/dist/{raster-DDi9gXqf.js → raster-xUPg8Z-C.js} +2 -2
- package/dist/react/context.d.ts +5 -3
- package/dist/react/om-map.d.ts +2 -0
- package/dist/react/om-widget.d.ts +4 -1
- package/dist/react.js +194 -199
- package/dist/version.d.ts +1 -1
- package/dist/widget-layout.d.ts +62 -0
- package/llms.txt +1 -1
- package/onlymapjs.html-data.json +36 -1
- package/package.json +2 -1
- package/skills/onlymapjs/SKILL.md +1 -1
- package/skills/onlymapjs/references/react.md +2 -2
- package/skills/onlymapjs/references/syntax.md +1 -1
package/dist/react.js
CHANGED
|
@@ -1,151 +1,143 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { jsxs as
|
|
5
|
-
import { createContext as
|
|
6
|
-
import { MapController as
|
|
7
|
-
import { createPortal as
|
|
8
|
-
const
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
12
|
-
return
|
|
1
|
+
var X = Object.defineProperty;
|
|
2
|
+
var Z = (t, e, n) => e in t ? X(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
|
|
3
|
+
var B = (t, e, n) => Z(t, typeof e != "symbol" ? e + "" : e, n);
|
|
4
|
+
import { jsxs as ee, jsx as O } from "react/jsx-runtime";
|
|
5
|
+
import { createContext as te, useContext as re, forwardRef as ne, useRef as g, useState as N, useCallback as se, useMemo as x, useLayoutEffect as oe, useEffect as w, useImperativeHandle as ie, useSyncExternalStore as H } from "react";
|
|
6
|
+
import { MANAGED_SLOTS as ae, slotContainerStyle as ce, MapController as le, parseWidgetStyle as ue, resolveSlot as fe, isStoreToken as de } from "@nika-js/onlymap";
|
|
7
|
+
import { createPortal as J } from "react-dom";
|
|
8
|
+
const Y = te(null);
|
|
9
|
+
function $(t) {
|
|
10
|
+
const e = re(Y);
|
|
11
|
+
if (!e) throw new Error(`[onlymapjs] ${t} must be rendered inside <OmMap>.`);
|
|
12
|
+
return e;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
15
|
-
if (
|
|
16
|
-
const
|
|
17
|
-
return
|
|
14
|
+
function V(t, e) {
|
|
15
|
+
if (t === e) return !0;
|
|
16
|
+
const n = Object.keys(t ?? {}), r = Object.keys(e ?? {});
|
|
17
|
+
return n.length !== r.length ? !1 : n.every((l) => t[l] === e[l]);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
const { props:
|
|
21
|
-
return
|
|
19
|
+
function ye(t, e) {
|
|
20
|
+
const { props: n, updateTriggers: r, ...l } = t, { props: f, updateTriggers: c, ...s } = e;
|
|
21
|
+
return V(l, s) && V(n, f) && V(r, c);
|
|
22
22
|
}
|
|
23
|
-
class
|
|
24
|
-
constructor(
|
|
25
|
-
|
|
26
|
-
this.controller =
|
|
23
|
+
class me {
|
|
24
|
+
constructor(e) {
|
|
25
|
+
B(this, "descriptors", /* @__PURE__ */ new Map());
|
|
26
|
+
this.controller = e;
|
|
27
27
|
}
|
|
28
|
-
upsert(
|
|
29
|
-
const
|
|
30
|
-
|
|
28
|
+
upsert(e) {
|
|
29
|
+
const n = this.descriptors.get(e.id);
|
|
30
|
+
n && ye(n, e) || (this.descriptors.set(e.id, e), this.controller.setLayers([...this.descriptors.values()]));
|
|
31
31
|
}
|
|
32
|
-
remove(
|
|
33
|
-
this.descriptors.delete(
|
|
32
|
+
remove(e) {
|
|
33
|
+
this.descriptors.delete(e) && this.controller.setLayers([...this.descriptors.values()]);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
const
|
|
37
|
-
function
|
|
38
|
-
return
|
|
39
|
-
position: "absolute",
|
|
40
|
-
[e.startsWith("top") ? "top" : "bottom"]: 10,
|
|
41
|
-
[e.endsWith("left") ? "left" : "right"]: 10,
|
|
42
|
-
display: "flex",
|
|
43
|
-
flexDirection: "column",
|
|
44
|
-
gap: 8,
|
|
45
|
-
alignItems: e.endsWith("left") ? "flex-start" : "flex-end",
|
|
46
|
-
zIndex: 20,
|
|
47
|
-
// The container never intercepts the map's pointer events; each
|
|
48
|
-
// <OmWidget> shell re-enables its own.
|
|
49
|
-
pointerEvents: "none"
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function ue(e, t) {
|
|
53
|
-
return Object.entries(t).some(([s, r]) => r !== void 0 && e[s] !== r);
|
|
36
|
+
const I = ae, ge = Object.fromEntries(I.map((t) => [t, ce(t)]));
|
|
37
|
+
function he(t, e) {
|
|
38
|
+
return Object.entries(e).some(([n, r]) => r !== void 0 && t[n] !== r);
|
|
54
39
|
}
|
|
55
|
-
const
|
|
56
|
-
const { center: r, zoom:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}), R = re((i) => {
|
|
62
|
-
C((y) => y === i ? y : i);
|
|
63
|
-
}, []), j = T(
|
|
40
|
+
const Re = ne(function(e, n) {
|
|
41
|
+
const { center: r, zoom: l, pitch: f, bearing: c, basemap: s, basemapKey: a, attribution: d, headless: u, widgetStyle: p, className: z, style: h, children: b } = e, y = g(null), [o, v] = N(null), [S, T] = N(null), [E, R] = N(
|
|
42
|
+
() => Object.fromEntries(I.map((i) => [i, null]))
|
|
43
|
+
), k = se((i) => {
|
|
44
|
+
T((m) => m === i ? m : i);
|
|
45
|
+
}, []), j = x(
|
|
64
46
|
() => Object.fromEntries(
|
|
65
|
-
|
|
47
|
+
I.map((i) => [
|
|
66
48
|
i,
|
|
67
|
-
(
|
|
68
|
-
|
|
49
|
+
(m) => {
|
|
50
|
+
R((M) => M[i] === m ? M : { ...M, [i]: m });
|
|
69
51
|
}
|
|
70
52
|
])
|
|
71
53
|
),
|
|
72
54
|
[]
|
|
73
|
-
),
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const F =
|
|
80
|
-
F.current =
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
if (!
|
|
86
|
-
const i =
|
|
87
|
-
|
|
88
|
-
const
|
|
55
|
+
), L = g({ center: r, zoom: l, pitch: f, bearing: c });
|
|
56
|
+
L.current = { center: r, zoom: l, pitch: f, bearing: c };
|
|
57
|
+
const P = g(e.onReady);
|
|
58
|
+
P.current = e.onReady;
|
|
59
|
+
const C = g(e.onViewStateChange);
|
|
60
|
+
C.current = e.onViewStateChange;
|
|
61
|
+
const F = g(e.onRuntimeError);
|
|
62
|
+
F.current = e.onRuntimeError;
|
|
63
|
+
const _ = g(s);
|
|
64
|
+
_.current = s;
|
|
65
|
+
const A = g(void 0), Q = u ? JSON.stringify(u) : "";
|
|
66
|
+
oe(() => {
|
|
67
|
+
if (!y.current) return;
|
|
68
|
+
const i = L.current;
|
|
69
|
+
A.current = _.current;
|
|
70
|
+
const m = new le(y.current, {
|
|
89
71
|
center: i.center,
|
|
90
72
|
zoom: i.zoom,
|
|
91
73
|
pitch: i.pitch,
|
|
92
74
|
bearing: i.bearing,
|
|
93
|
-
basemap:
|
|
94
|
-
basemapKey:
|
|
75
|
+
basemap: _.current,
|
|
76
|
+
basemapKey: a,
|
|
95
77
|
attribution: d,
|
|
96
|
-
headless:
|
|
97
|
-
onRuntimeError: (
|
|
98
|
-
var
|
|
99
|
-
return (
|
|
78
|
+
headless: u ? u === !0 ? {} : u : void 0,
|
|
79
|
+
onRuntimeError: (K) => {
|
|
80
|
+
var q;
|
|
81
|
+
return (q = F.current) == null ? void 0 : q.call(F, K);
|
|
100
82
|
}
|
|
101
83
|
});
|
|
102
|
-
|
|
84
|
+
v(m);
|
|
103
85
|
let M = !0;
|
|
104
|
-
return
|
|
105
|
-
var
|
|
106
|
-
M && ((
|
|
86
|
+
return m.ready.then(() => {
|
|
87
|
+
var K;
|
|
88
|
+
M && ((K = P.current) == null || K.call(P));
|
|
107
89
|
}), () => {
|
|
108
|
-
M = !1,
|
|
90
|
+
M = !1, v(null), m.destroy();
|
|
109
91
|
};
|
|
110
|
-
}, [Q]),
|
|
111
|
-
!
|
|
112
|
-
}, [
|
|
113
|
-
if (!
|
|
114
|
-
const i = { longitude: r == null ? void 0 : r[0], latitude: r == null ? void 0 : r[1], zoom:
|
|
115
|
-
|
|
116
|
-
}, [
|
|
92
|
+
}, [Q]), w(() => {
|
|
93
|
+
!o || A.current === s || (A.current = s, o.setBasemap(s ?? null));
|
|
94
|
+
}, [o, s]), ie(n, () => o, [o]), w(() => {
|
|
95
|
+
if (!o) return;
|
|
96
|
+
const i = { longitude: r == null ? void 0 : r[0], latitude: r == null ? void 0 : r[1], zoom: l, pitch: f, bearing: c };
|
|
97
|
+
he(o.getViewState(), i) && o.setView(i);
|
|
98
|
+
}, [o, r == null ? void 0 : r[0], r == null ? void 0 : r[1], l, f, c]), w(() => {
|
|
117
99
|
var i;
|
|
118
|
-
if (
|
|
119
|
-
return (i =
|
|
120
|
-
var
|
|
121
|
-
return (
|
|
100
|
+
if (o)
|
|
101
|
+
return (i = C.current) == null || i.call(C, o.getViewState()), o.getStore("viewport").subscribe(() => {
|
|
102
|
+
var m;
|
|
103
|
+
return (m = C.current) == null ? void 0 : m.call(C, o.getViewState());
|
|
122
104
|
});
|
|
123
|
-
}, [
|
|
124
|
-
const
|
|
125
|
-
() =>
|
|
126
|
-
|
|
105
|
+
}, [o]);
|
|
106
|
+
const U = x(
|
|
107
|
+
() => ({
|
|
108
|
+
position: "absolute",
|
|
109
|
+
inset: 0,
|
|
110
|
+
zIndex: 20,
|
|
111
|
+
pointerEvents: "none",
|
|
112
|
+
opacity: "var(--om-widget-opacity, 1)",
|
|
113
|
+
...p ? ue(p).properties : void 0
|
|
114
|
+
}),
|
|
115
|
+
[p]
|
|
116
|
+
), D = x(() => o ? new me(o) : null, [o]), W = x(
|
|
117
|
+
() => o && D && S ? { controller: o, layers: D, overlayPane: S, corners: E } : null,
|
|
118
|
+
[o, D, S, E]
|
|
127
119
|
);
|
|
128
|
-
return /* @__PURE__ */
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
-
/* @__PURE__ */
|
|
120
|
+
return /* @__PURE__ */ ee("div", { className: z, style: { position: "relative", overflow: "hidden", ...h }, children: [
|
|
121
|
+
/* @__PURE__ */ O("div", { ref: y, style: { position: "absolute", inset: 0 } }),
|
|
122
|
+
/* @__PURE__ */ O(
|
|
131
123
|
"div",
|
|
132
124
|
{
|
|
133
|
-
ref:
|
|
125
|
+
ref: k,
|
|
134
126
|
style: { position: "absolute", top: 0, left: 0, zIndex: 10, pointerEvents: "none" }
|
|
135
127
|
}
|
|
136
128
|
),
|
|
137
|
-
|
|
129
|
+
/* @__PURE__ */ O("div", { "data-om-widget-layer": "", style: U, children: I.map((i) => /* @__PURE__ */ O(
|
|
138
130
|
"div",
|
|
139
131
|
{
|
|
140
|
-
"data-om-widget-
|
|
132
|
+
"data-om-widget-slot": i,
|
|
141
133
|
ref: j[i],
|
|
142
|
-
style:
|
|
134
|
+
style: ge[i]
|
|
143
135
|
},
|
|
144
136
|
i
|
|
145
|
-
)),
|
|
146
|
-
|
|
137
|
+
)) }),
|
|
138
|
+
W && /* @__PURE__ */ O(Y.Provider, { value: W, children: b })
|
|
147
139
|
] });
|
|
148
|
-
}),
|
|
140
|
+
}), be = /* @__PURE__ */ new Set([
|
|
149
141
|
"id",
|
|
150
142
|
"type",
|
|
151
143
|
"data",
|
|
@@ -165,58 +157,61 @@ const ve = te(function(t, s) {
|
|
|
165
157
|
"onClick",
|
|
166
158
|
"onHover"
|
|
167
159
|
]);
|
|
168
|
-
function
|
|
169
|
-
const { controller:
|
|
170
|
-
for (const [
|
|
171
|
-
!
|
|
172
|
-
const
|
|
160
|
+
function Ce(t) {
|
|
161
|
+
const { controller: e, layers: n } = $("OmLayer"), { id: r } = t, l = {};
|
|
162
|
+
for (const [a, d] of Object.entries(t))
|
|
163
|
+
!be.has(a) && d !== void 0 && (l[a] = d);
|
|
164
|
+
const f = {
|
|
173
165
|
id: r,
|
|
174
|
-
type:
|
|
175
|
-
data:
|
|
176
|
-
label:
|
|
177
|
-
color:
|
|
178
|
-
filterField:
|
|
179
|
-
filterRange:
|
|
180
|
-
filterSoftRange:
|
|
181
|
-
filterCategoryField:
|
|
182
|
-
filterCategories:
|
|
183
|
-
source:
|
|
184
|
-
key:
|
|
185
|
-
flush:
|
|
186
|
-
refresh:
|
|
187
|
-
terrain:
|
|
188
|
-
updateTriggers:
|
|
189
|
-
props:
|
|
166
|
+
type: t.type,
|
|
167
|
+
data: t.data,
|
|
168
|
+
label: t.label,
|
|
169
|
+
color: t.color,
|
|
170
|
+
filterField: t.filterField,
|
|
171
|
+
filterRange: t.filterRange,
|
|
172
|
+
filterSoftRange: t.filterSoftRange,
|
|
173
|
+
filterCategoryField: t.filterCategoryField,
|
|
174
|
+
filterCategories: t.filterCategories,
|
|
175
|
+
source: t.source,
|
|
176
|
+
key: t.streamKey,
|
|
177
|
+
flush: t.flush,
|
|
178
|
+
refresh: t.refresh,
|
|
179
|
+
terrain: t.terrain,
|
|
180
|
+
updateTriggers: t.updateTriggers,
|
|
181
|
+
props: l
|
|
190
182
|
};
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}),
|
|
194
|
-
const c =
|
|
195
|
-
c.current =
|
|
196
|
-
const
|
|
197
|
-
return
|
|
198
|
-
() =>
|
|
199
|
-
var d,
|
|
200
|
-
if (
|
|
201
|
-
(d =
|
|
183
|
+
w(() => {
|
|
184
|
+
n.upsert(f);
|
|
185
|
+
}), w(() => () => n.remove(r), [n, r]);
|
|
186
|
+
const c = g(t.onClick);
|
|
187
|
+
c.current = t.onClick;
|
|
188
|
+
const s = g(t.onHover);
|
|
189
|
+
return s.current = t.onHover, w(
|
|
190
|
+
() => e.watchPicks((a) => {
|
|
191
|
+
var d, u, p;
|
|
192
|
+
if (a === null) {
|
|
193
|
+
(d = s.current) == null || d.call(s, null);
|
|
202
194
|
return;
|
|
203
195
|
}
|
|
204
|
-
|
|
196
|
+
a.layerId === r && (a.type === "click" ? (u = c.current) == null || u.call(c, a) : (p = s.current) == null || p.call(s, a));
|
|
205
197
|
}),
|
|
206
|
-
[
|
|
198
|
+
[e, r]
|
|
207
199
|
), null;
|
|
208
200
|
}
|
|
209
|
-
function
|
|
210
|
-
const { corners:
|
|
211
|
-
|
|
212
|
-
/* @__PURE__ */
|
|
213
|
-
|
|
201
|
+
function xe({ position: t = "top-start", order: e, className: n, style: r, children: l }) {
|
|
202
|
+
const { corners: f } = $("OmWidget"), c = fe(t) ?? "top-start";
|
|
203
|
+
if (c === "manual")
|
|
204
|
+
return /* @__PURE__ */ O("div", { className: n, style: { pointerEvents: "auto", ...r }, children: l });
|
|
205
|
+
const s = f[c];
|
|
206
|
+
return s ? J(
|
|
207
|
+
/* @__PURE__ */ O("div", { className: n, style: { pointerEvents: "auto", ...e !== void 0 ? { order: e } : void 0, ...r }, children: l }),
|
|
208
|
+
s
|
|
214
209
|
) : null;
|
|
215
210
|
}
|
|
216
|
-
function
|
|
217
|
-
return !
|
|
211
|
+
function G(t, e) {
|
|
212
|
+
return !e || (t == null ? void 0 : t.layerId) === e;
|
|
218
213
|
}
|
|
219
|
-
const
|
|
214
|
+
const ve = {
|
|
220
215
|
"top-left": "translate(0, 0)",
|
|
221
216
|
"top-center": "translate(-50%, 0)",
|
|
222
217
|
"top-right": "translate(-100%, 0)",
|
|
@@ -227,48 +222,48 @@ const de = {
|
|
|
227
222
|
"bottom-center": "translate(-50%, -100%)",
|
|
228
223
|
"bottom-right": "translate(-100%, -100%)"
|
|
229
224
|
};
|
|
230
|
-
function
|
|
231
|
-
const { controller:
|
|
232
|
-
|
|
233
|
-
const c =
|
|
234
|
-
const
|
|
235
|
-
let
|
|
225
|
+
function Te(t) {
|
|
226
|
+
const { controller: e, overlayPane: n } = $("OmOverlay"), r = g(null), l = g(void 0), f = g(t);
|
|
227
|
+
f.current = t;
|
|
228
|
+
const c = x(() => {
|
|
229
|
+
const h = e.getStore("selection");
|
|
230
|
+
let b, y, o = null;
|
|
236
231
|
return {
|
|
237
|
-
subscribe:
|
|
232
|
+
subscribe: h.subscribe,
|
|
238
233
|
getSnapshot: () => {
|
|
239
|
-
const
|
|
240
|
-
return (
|
|
234
|
+
const v = h.getSnapshot(), { anchorFrom: S, layer: T } = f.current, E = `${S ?? ""}|${T ?? ""}`;
|
|
235
|
+
return (v !== b || E !== y) && (b = v, y = E, S === "selection" && G(v, T) && (o = v)), o;
|
|
241
236
|
}
|
|
242
237
|
};
|
|
243
|
-
}, [
|
|
238
|
+
}, [e]), s = H(
|
|
244
239
|
c.subscribe,
|
|
245
240
|
c.getSnapshot,
|
|
246
241
|
c.getSnapshot
|
|
247
242
|
);
|
|
248
|
-
|
|
249
|
-
() =>
|
|
250
|
-
const
|
|
251
|
-
if (!
|
|
252
|
-
const { anchor:
|
|
243
|
+
w(
|
|
244
|
+
() => e.registerOverlay((h, b) => {
|
|
245
|
+
const y = r.current;
|
|
246
|
+
if (!y) return;
|
|
247
|
+
const { anchor: o, anchorFrom: v, layer: S, visible: T = !0, anchorOffset: E } = f.current;
|
|
253
248
|
let R;
|
|
254
|
-
if (
|
|
255
|
-
|
|
249
|
+
if (v === "selection" ? (G(b, S) && (l.current = (b == null ? void 0 : b.coordinate) ?? void 0), R = l.current) : R = o, !T || !R || !h) {
|
|
250
|
+
y.style.visibility = "hidden";
|
|
256
251
|
return;
|
|
257
252
|
}
|
|
258
|
-
const [
|
|
259
|
-
if (!(
|
|
260
|
-
|
|
253
|
+
const [k, j, L] = h.project([R[0], R[1], 0]);
|
|
254
|
+
if (!(k >= 0 && k <= h.width && j >= 0 && j <= h.height) || L !== void 0 && L < 0) {
|
|
255
|
+
y.style.visibility = "hidden";
|
|
261
256
|
return;
|
|
262
257
|
}
|
|
263
|
-
|
|
258
|
+
y.style.visibility = "visible", y.style.transform = `translate(${k}px, ${j}px) ${ve[E ?? "bottom-center"]}`;
|
|
264
259
|
}),
|
|
265
|
-
[
|
|
266
|
-
),
|
|
267
|
-
|
|
260
|
+
[e]
|
|
261
|
+
), w(() => {
|
|
262
|
+
e.refreshOverlays();
|
|
268
263
|
});
|
|
269
|
-
const { children:
|
|
270
|
-
return
|
|
271
|
-
/* @__PURE__ */
|
|
264
|
+
const { children: a, className: d, style: u, interactive: p = !0 } = t, z = typeof a == "function" ? a(s) : a;
|
|
265
|
+
return J(
|
|
266
|
+
/* @__PURE__ */ O(
|
|
272
267
|
"div",
|
|
273
268
|
{
|
|
274
269
|
ref: r,
|
|
@@ -280,38 +275,38 @@ function Oe(e) {
|
|
|
280
275
|
visibility: "hidden",
|
|
281
276
|
// hidden until the first flush positions it — never flashes at the origin
|
|
282
277
|
willChange: "transform",
|
|
283
|
-
pointerEvents:
|
|
284
|
-
...
|
|
278
|
+
pointerEvents: p ? "auto" : "none",
|
|
279
|
+
...u
|
|
285
280
|
},
|
|
286
|
-
children:
|
|
281
|
+
children: z
|
|
287
282
|
}
|
|
288
283
|
),
|
|
289
|
-
|
|
284
|
+
n
|
|
290
285
|
);
|
|
291
286
|
}
|
|
292
|
-
function
|
|
293
|
-
const { controller:
|
|
294
|
-
const c = (
|
|
295
|
-
let
|
|
287
|
+
function Me(t = []) {
|
|
288
|
+
const { controller: e } = $("useOmMap"), n = t.join(" "), r = x(() => {
|
|
289
|
+
const c = (n ? n.split(" ") : []).flatMap((a) => de(a) ? [e.getStore(a)] : (console.warn(`[onlymapjs] useOmMap: "${a}" is not a watch token on the React front-end — expected viewport, selection, layers, or data:<layerId>.`), []));
|
|
290
|
+
let s;
|
|
296
291
|
return {
|
|
297
|
-
subscribe: (
|
|
298
|
-
const d = c.map((
|
|
292
|
+
subscribe: (a) => {
|
|
293
|
+
const d = c.map((u) => u.subscribe(a));
|
|
299
294
|
return () => {
|
|
300
|
-
for (const
|
|
295
|
+
for (const u of d) u();
|
|
301
296
|
};
|
|
302
297
|
},
|
|
303
298
|
getSnapshot: () => {
|
|
304
|
-
const
|
|
305
|
-
return (!
|
|
299
|
+
const a = c.map((d) => d.getSnapshot());
|
|
300
|
+
return (!s || a.some((d, u) => d !== s[u])) && (s = a), s;
|
|
306
301
|
}
|
|
307
302
|
};
|
|
308
|
-
}, [
|
|
309
|
-
return
|
|
303
|
+
}, [e, n]), l = H(r.subscribe, r.getSnapshot, r.getSnapshot);
|
|
304
|
+
return x(() => e.buildCtx(), [e, l]);
|
|
310
305
|
}
|
|
311
306
|
export {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
307
|
+
Ce as OmLayer,
|
|
308
|
+
Re as OmMap,
|
|
309
|
+
Te as OmOverlay,
|
|
310
|
+
xe as OmWidget,
|
|
311
|
+
Me as useOmMap
|
|
317
312
|
};
|
package/dist/version.d.ts
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget layout vocabulary (spec: "Widget Layout Manager") — the shared,
|
|
3
|
+
* framework-free half of the slot system: slot names, legacy-corner
|
|
4
|
+
* aliasing, per-slot flex layout parameters, and the `widget-style` token
|
|
5
|
+
* sugar parser. Both front-ends derive their containers from THIS table
|
|
6
|
+
* (the HTML lane as cssText, the React lane as CSSProperties) so the two
|
|
7
|
+
* lanes cannot drift on placement semantics.
|
|
8
|
+
*
|
|
9
|
+
* Names are LOGICAL and RTL-aware: `-start`/`-end` map to CSS
|
|
10
|
+
* `inset-inline-*` and flex alignment, so an RTL document mirrors the
|
|
11
|
+
* whole chrome without any per-widget work. Legacy corner names stay as
|
|
12
|
+
* aliases mapped logically (`top-left` → `top-start`), which means legacy
|
|
13
|
+
* manifests mirror correctly under RTL too — physical-corner fidelity is
|
|
14
|
+
* deliberately NOT preserved there.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MANAGED_SLOTS: readonly ["top-start", "top-center", "top-end", "center-start", "center-end", "bottom-start", "bottom-center", "bottom-end"];
|
|
17
|
+
export type ManagedSlot = (typeof MANAGED_SLOTS)[number];
|
|
18
|
+
/** A widget's resolved placement: a managed slot, or the author-styled manual tier. */
|
|
19
|
+
export type WidgetSlot = ManagedSlot | "manual";
|
|
20
|
+
/** Legacy 4-corner vocabulary (pre-0.4.1) — accepted forever, mapped LOGICALLY. */
|
|
21
|
+
export declare const LEGACY_POSITION_ALIASES: Readonly<Record<string, ManagedSlot>>;
|
|
22
|
+
/** Every accepted `position` value (validation + html-data). */
|
|
23
|
+
export declare const ALL_POSITION_VALUES: readonly string[];
|
|
24
|
+
/**
|
|
25
|
+
* `position` attribute/prop → slot. Absent/empty → the default `top-start`
|
|
26
|
+
* (today's `top-left` default, aliased). Unknown values → null; callers
|
|
27
|
+
* warn and fall back to the default (validation carries the loud version).
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveSlot(raw: string | null | undefined): WidgetSlot | null;
|
|
30
|
+
export interface SlotLayout {
|
|
31
|
+
/** Stack axis: edge-center slots run ALONG their edge (row); everything else stacks as a column. */
|
|
32
|
+
axis: "column" | "row";
|
|
33
|
+
block: "top" | "center" | "bottom";
|
|
34
|
+
inline: "start" | "center" | "end";
|
|
35
|
+
}
|
|
36
|
+
export declare function slotLayout(slot: ManagedSlot): SlotLayout;
|
|
37
|
+
/**
|
|
38
|
+
* The slot container's styles as a camelCase style object — ONE builder for
|
|
39
|
+
* both front-ends (the React lane spreads it as CSSProperties; the HTML
|
|
40
|
+
* lane serializes it to cssText), so the lanes cannot drift on placement.
|
|
41
|
+
* Insets/gaps read the layout tokens with the pre-0.4.1 constants as
|
|
42
|
+
* fallbacks (12px inset, 8px gap), so a single-widget legacy corner renders
|
|
43
|
+
* pixel-identically. Containers never intercept the map's pointer events;
|
|
44
|
+
* each widget re-enables its own.
|
|
45
|
+
*/
|
|
46
|
+
export declare function slotContainerStyle(slot: ManagedSlot): Record<string, string | number>;
|
|
47
|
+
/** The HTML lane's serialization of slotContainerStyle. */
|
|
48
|
+
export declare function slotContainerCssText(slot: ManagedSlot): string;
|
|
49
|
+
export declare const WIDGET_STYLE_KEY_NAMES: readonly string[];
|
|
50
|
+
export interface WidgetStyleParse {
|
|
51
|
+
/** Custom property → CSS value, ready for style.setProperty. */
|
|
52
|
+
properties: Record<string, string>;
|
|
53
|
+
/** Unparseable entries (unknown key / non-numeric value) — validation's loud half; the live path skips them. */
|
|
54
|
+
errors: string[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* `widget-style="gap:10 opacity:0.9 inset-x:16"` → custom properties — the
|
|
58
|
+
* no-CSS token surface for agents/authors. Space-separated `key:value`
|
|
59
|
+
* pairs; numbers get `px` except opacity. One parser serves the live path
|
|
60
|
+
* (om-map attr → host properties) and validation.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseWidgetStyle(raw: string): WidgetStyleParse;
|
package/llms.txt
CHANGED
|
@@ -26,7 +26,7 @@ OnlyMapJS is NOT raw deck.gl and NOT generic HTML/JSX. The rules below are the d
|
|
|
26
26
|
|
|
27
27
|
- `<om-map center="[lng, lat]" zoom="11" pitch="55" bearing="20" basemap="positron">` — the root. `basemap` accepts a free preset (`liberty`, `bright`, `positron`, `dark-matter`, `voyager`, `osm` — no keys; or `maptiler-streets`/`maptiler-dataviz`/`maptiler-satellite` with `basemap-key="…"` or `OmMap.configureBasemap({ maptilerKey })`), `maplibre` (bare demo style), a style URL (e.g. a MapTiler-customized style; any scheme fetch supports, including desktop asset protocols like Tauri's, query strings fine), or `none` (standalone canvas). The attribute is LIVE — writing it switches the basemap in place (camera + layers survive); the `set-basemap {basemap}` action and `<om-widget type="basemap-switcher" options="positron dark-matter osm">` do the same. Register more via `OmMap.registerBasemap(name, { style })`. Required provider attribution renders automatically (`attribution="false"` opts out). `pitch`/`bearing` tilt the initial camera (use for 3D content). Terrain: `terrain="terrarium"` (keyless AWS DEM; also `maptiler-terrain` with a key, a raw `{z}/{x}/{y}` DEM URL + `terrain-decoder="terrarium|mapbox-rgb|<JSON>"`, or `off`) raises a 3D surface — geographic layers DRAPE onto it automatically (per-layer `terrain="drape|offset|off"` overrides; 3D-model layers sit ON it), `terrain-exaggeration` scales relief, `terrain-texture` drapes imagery; terrain REPLACES an active basemap while on (restored when off); `set-terrain` action, `terrain` watch token, `OmMap.registerTerrain(name, {...})` for more sources. Scene lighting for 3D content: `lighting="daylight|studio|flat|custom"` (absent = deck defaults) with `lighting-ambient`/`lighting-sun`/`lighting-sun-azimuth`/`lighting-sun-elevation`/`lighting-camera` overrides and `lighting-sun-date` (ISO/epoch — solar-position sun computed at the map center, wins over azimuth/elevation); attribute-backed (undoable, live-editable), story-steppable via the `set-lighting {lighting, sunAzimuth, ...}` action (`lighting="default"` removes the attribute set; a bare preset is a clean reset — stale overrides clear), native UI via `<om-widget type="lighting">` (preset radios + tuning sliders), widget watch token `lighting`. GeoJsonLayer extrudes polygons declaratively: `extruded get-elevation="$height"` (+ `wireframe`). `validate` attribute enables live validation + on-page error panel. Include a `map-id="<random UUID>"` on complete pages (identifies the map artifact for usage telemetry — not a visitor id; the page author deletes it to opt out); `telemetry="off"` disables usage telemetry + library-error reporting for the map (global: `OmMap.configureTelemetry({ disabled: true })`; schema: docs/telemetry.md). Free plan limits: 5 layers, 25k rows per layer — layers past a limit don't render and validation says why; a `license-key="om_live_…"` attribute (publishable, origin-restricted) or `OmMap.configureLicense(key)` lifts limits and removes the corner badge. When a user's map exceeds free limits, say so and point at the validation message rather than silently restructuring their data. Events on the element: `om-map-ready` (boot complete; `await mapEl.ready` is the promise twin), `om-validation-error`, `om-view-changed` (camera settled after a move, debounced; `detail = {longitude, latitude, zoom, pitch, bearing, origin}` where `origin` is `"user"` for gesture bursts vs `"programmatic"` for API/story moves — the camera-persistence hook, and the echo-suppression signal when syncing camera state to an app store). `await mapEl.snapshot()` returns a canvas-only PNG dataURL of the scene (basemap + layers at device pixels; `{as:"blob"}` for files) — DOM widgets/overlays/attribution are NOT captured, so exports must render provider credits themselves.
|
|
28
28
|
- `<om-layer id="..." type="ScatterplotLayer" data="./points.json">` — any deck.gl layer class by `type` (all 33 bundled, plus the native `COGLayer` raster type), plus `PopupLayer` (WebGL badges/labels at scale: `layout="badge|pin-label|card"`, `min-zoom`/`max-zoom`). Every type's full attribute list ships in the package's `onlymapjs.html-data.json` — consult it instead of guessing attribute names or reading the minified dist. TextLayer's default font atlas covers ASCII only: set `character-set` when label text carries other glyphs (`—`, `·`, accents) or deck warns and renders them blank. External layer classes register via `OmMap.registerLayer({type, deckClass, props})` — build them on `@nika-js/onlymap/deck` (the bundled `CompositeLayer`/`TileLayer`/… re-exports), never a separately-installed deck.gl (different class hierarchy, breaks in the renderer); function-valued props ride the subclass's `static defaultProps`; register at module top level BEFORE the manifest mounts (see docs/custom-layers.md). Data: `data` URL (JSON, GeoJSON, CSV/TSV `.csv` — parsed to typed columns — Shapefile `.shp` (+`.dbf` attributes) and KML `.kml` as GeoJSON features, or Arrow IPC `.arrow`/`.feather` — large point datasets stay columnar, GeoArrow line/polygon geometry becomes GeoJSON features, zstd-compressed IPC is handled; other formats plug in via `OmMap.registerFormat({match, parse})`; data URLs accept any scheme the runtime's fetch supports — desktop webviews (Tauri, Electron) pass asset-protocol URLs straight in), inline `<script type="application/json">` (row arrays or column-oriented `{"columns": {"lon": [...], "lat": [...]}}`; must be a DIRECT child of the `<om-layer>`, and when present it wins — omit the `data` attribute), or `wss://` streaming (`key="mmsi"` upserts entities in place, `flush="250ms"` coalesces bursts, `source="name"` selects a `OmMap.registerSource` decoder plugin), or a polled REST snapshot (`refresh="5s"` re-fetches and replaces — for live endpoints that return the full current state). Authenticated endpoints: call `OmMap.configureData({ headers: {...} })` in a script — never put tokens in attributes. `$field` accessors work identically on all of them — never write column-index code yourself. One columnar restriction: the `js` full-JS opt-in is not allowed on Arrow/columnar layers (validation will tell you; use `$field` accessors instead). For 3D models use `type="ScenegraphLayer"` with `scenegraph="./model.glb"` (required) and `get-orientation="[0, $heading, 90]"` — the roll of 90 stands Y-up glTF models upright; see docs/3d-assets.md. GeoTIFF/COG rasters use `type="COGLayer"` with `src="./dem.tif"` (NOT `data` — rasters stream tiles by Range request, they are not parsed rows): `min`/`max` set the rescale window (default 0–255; ALWAYS set them for float/16-bit data like DEMs), `colormap` picks a bundled ramp for single-band sources (gray, viridis, plasma, inferno, magma, cividis, rdylgn, rdbu, spectral, terrain, jet, turbo), `nodata` overrides the source sentinel (renders transparent); plain 8-bit RGB COGs need no styling attributes; restretch/recolor are GPU uniforms (no refetch) and the legend ramp derives from colormap+min/max automatically. Sources must be Cloud-Optimized (`gdal_translate -of COG` otherwise).
|
|
29
|
-
- `<om-widget type="legend|layer-switcher|basemap-switcher|lighting|zoom-controls|undo-redo|scale-bar|attribution|filter|vega-lite" position="bottom-
|
|
29
|
+
- `<om-widget type="legend|layer-switcher|basemap-switcher|lighting|zoom-controls|undo-redo|scale-bar|attribution|filter|vega-lite" position="bottom-end">` — static UI panels. `position` takes one of 8 managed slots (logical, RTL-aware: `top-start|top-center|top-end|center-start|center-end|bottom-start|bottom-center|bottom-end`; legacy corners `top-left` etc. alias) — same-slot widgets stack with flush edges and a shared gap (never overlap); `order="1"` orders within a slot; `position="manual"` renders a plain block you place with your own CSS (even outside the map). Layout tokens on `<om-map>`: `widget-style="gap:10 opacity:0.9 inset:16"` (keys inset/gap/inset-x/-y/gap-x/-y/opacity/radius/size, px except opacity) or the `--om-widget-inset-x/-y/-gap-x/-y/-opacity/-radius` custom properties. Built-ins are themeable from page CSS via custom properties (they inherit through the shadow root): `om-map { --om-widget-bg: #111827; --om-widget-fg: #f9fafb; }` — full set: `--om-widget-bg/-fg/-muted/-border/-hover-bg/-accent`; scope to a single widget with an `om-widget[type=legend]` selector instead. No `type` + HTML + `<script type="om/widget">` = custom widget with `ctx` (`ctx.layers`, `ctx.data(id)`, `ctx.dataInViewport(id)`, `ctx.stats(id, field)`, `ctx.viewport`, `ctx.selection`, `ctx.emit(action, payload)`), `this.watch = ['data:<layerId>', 'viewport', 'selection', 'layers', 'history', 'basemap']` (`layers` also fires on visibility/filter changes; `basemap` on basemap switches; `history` on undo/redo availability), `this.$(sel)`, `vegaEmbed`/`d3` as globals.
|
|
30
30
|
- `<om-overlay id="..." anchor-from="selection">` — rich geo-anchored HTML (≤ ~20 per map). Anchors: `anchor="[lng, lat]"` (static), `anchor-from="selection"` (follows picks), or `anchor-layer="regions" anchor-feature-id="mission"` (anchored to a feature's own geometry — bbox center — no coordinates in markup; `{{field}}` interpolates that feature's attributes). `{{field}}` interpolates the picked feature HTML-escaped; `{{{field}}}` is raw (avoid). For labels on many features use `PopupLayer`, not overlays.
|
|
31
31
|
- `<om-behavior on="click|hover|drag|load|data-loaded" layer="..." action="...">` — declarative interaction. Built-in actions: `show-overlay`, `hide-overlay`, `show-tooltip`, `hide-tooltip`, `toggle-layer`, `filter-layer`, `highlight-feature`, `zoom-to-feature`, `set-basemap`, `undo`, `redo`. One payload contract everywhere: `{ layer, target, feature, featureId, coordinate }`.
|
|
32
32
|
- Undo/redo is built in: user-facing manifest changes (layer toggles, filter changes, basemap switches, element add/remove, drawn sketches) are recorded automatically — the manifest is the state. `<om-widget type="undo-redo">` renders the buttons; Cmd/Ctrl-Z, Shift-Cmd/Ctrl-Z, and Ctrl-Y work on any map (text inputs keep their native undo). Camera moves, hover effects, and story playback are deliberately NOT undo steps. Widget scripts: `ctx.history.canUndo/canRedo` with watch token `history`; `ctx.emit("undo")`/`ctx.emit("redo")`.
|