@elaraai/east-ui 1.0.13 → 1.0.15

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 (40) hide show
  1. package/dist/src/collections/index.d.ts +1 -0
  2. package/dist/src/collections/index.d.ts.map +1 -1
  3. package/dist/src/collections/index.js +1 -0
  4. package/dist/src/collections/index.js.map +1 -1
  5. package/dist/src/collections/map/index.d.ts +1180 -0
  6. package/dist/src/collections/map/index.d.ts.map +1 -0
  7. package/dist/src/collections/map/index.js +802 -0
  8. package/dist/src/collections/map/index.js.map +1 -0
  9. package/dist/src/collections/map/types.d.ts +586 -0
  10. package/dist/src/collections/map/types.d.ts.map +1 -0
  11. package/dist/src/collections/map/types.js +315 -0
  12. package/dist/src/collections/map/types.js.map +1 -0
  13. package/dist/src/component.d.ts +225 -0
  14. package/dist/src/component.d.ts.map +1 -1
  15. package/dist/src/component.js +36 -0
  16. package/dist/src/component.js.map +1 -1
  17. package/dist/src/index.d.ts +1 -1
  18. package/dist/src/index.d.ts.map +1 -1
  19. package/dist/src/index.js +1 -1
  20. package/dist/src/index.js.map +1 -1
  21. package/dist/src/internal.d.ts +1 -1
  22. package/dist/src/internal.d.ts.map +1 -1
  23. package/dist/src/internal.js +1 -1
  24. package/dist/src/internal.js.map +1 -1
  25. package/dist/src/runtime/collections/index.d.ts +1 -0
  26. package/dist/src/runtime/collections/index.d.ts.map +1 -1
  27. package/dist/src/runtime/collections/index.js +1 -0
  28. package/dist/src/runtime/collections/index.js.map +1 -1
  29. package/dist/src/runtime/collections/map.d.ts +74 -0
  30. package/dist/src/runtime/collections/map.d.ts.map +1 -0
  31. package/dist/src/runtime/collections/map.js +70 -0
  32. package/dist/src/runtime/collections/map.js.map +1 -0
  33. package/dist/test/collections/map.examples.d.ts +8 -0
  34. package/dist/test/collections/map.examples.d.ts.map +1 -0
  35. package/dist/test/collections/map.examples.js +150 -0
  36. package/dist/test/collections/map.examples.js.map +1 -0
  37. package/dist/test/collections/schematic.examples.d.ts.map +1 -1
  38. package/dist/test/collections/schematic.examples.js +30 -2
  39. package/dist/test/collections/schematic.examples.js.map +1 -1
  40. package/package.json +3 -3
@@ -0,0 +1,802 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * `Map` — an interactive geographic basemap (CARTO / OSM raster tiles) with
7
+ * H3 hex and filled-area overlays, connector lines, pins, standalone labels,
8
+ * and a generalised overlay slot that hosts arbitrary East `UIComponent`
9
+ * children (a HUD, a legend, a back button) positioned over the canvas.
10
+ * **Read-only / selection-only**: click an area (returns its key), zoom, and
11
+ * fly to; any writes ride in through ordinary `Button` children in the
12
+ * overlay slot. Colour stays theme-owned — data selects a `tone` / `status`
13
+ * and the renderer's recipe maps each to a token.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+ import { East, Expr, variant, some, none, ArrayType, BooleanType, FloatType, FunctionType, IntegerType, NullType, OptionType, StringType, StructType, } from "@elaraai/east";
18
+ import { UIComponentType } from "../../component.js";
19
+ import { AlignType } from "../../style/content.js";
20
+ import {} from "../../style/interaction.js";
21
+ import {} from "../../display/icon/types.js";
22
+ import { MapLatLngType, MapToneType, MapCartoStyleType, MapTileType, MapFocusType, MapAreaShapeType, MapAreaType, MapHexLayerType, MapMarkerType, MapLineStyleType, MapLineType, MapLabelType, } from "./types.js";
23
+ // Re-export types
24
+ export { MapLatLngType, MapToneType, MapCartoStyleType, MapTileType, MapFocusType, MapAreaShapeType, MapAreaType, MapHexLayerType, MapMarkerType, MapLineStyleType, MapLineType, MapLabelType, } from "./types.js";
25
+ function toneValue(tone) {
26
+ return tone !== undefined ? some(variant(tone, null)) : none;
27
+ }
28
+ /** Wrap a `tone` override into its option — accepts a string literal shorthand
29
+ * (`"brand"`) or an East tone expression / value. */
30
+ function toneOption(tone) {
31
+ if (tone === undefined)
32
+ return none;
33
+ return typeof tone === "string" ? some(variant(tone, null)) : some(tone);
34
+ }
35
+ function buildAlign(a) {
36
+ return typeof a === "string" ? East.value(variant(a, null), AlignType) : a;
37
+ }
38
+ // ============================================================================
39
+ // Geometry + style sub-builders
40
+ // ============================================================================
41
+ /**
42
+ * Builds a geographic point value.
43
+ *
44
+ * @param lat - Latitude in degrees
45
+ * @param lng - Longitude in degrees
46
+ * @returns A `MapLatLngType` value
47
+ */
48
+ function at(lat, lng) {
49
+ return East.value({ lat, lng }, MapLatLngType);
50
+ }
51
+ /**
52
+ * Builds a CARTO raster basemap.
53
+ *
54
+ * @param style - The CARTO preset (default `positron`)
55
+ * @returns A `MapTileType` value
56
+ */
57
+ function carto(style = "positron") {
58
+ return East.value(variant("carto", { style: variant(style, null) }), MapTileType);
59
+ }
60
+ /**
61
+ * Builds an OpenStreetMap raster basemap.
62
+ *
63
+ * @returns A `MapTileType` value
64
+ */
65
+ function osm() {
66
+ return East.value(variant("osm", null), MapTileType);
67
+ }
68
+ /**
69
+ * Builds a raw XYZ basemap with explicit attribution.
70
+ *
71
+ * @param config - The tile URL, attribution, and optional `subdomains` / `maxZoom` / `detectRetina`
72
+ * @returns A `MapTileType` value
73
+ */
74
+ function tile(config) {
75
+ return East.value(variant("custom", {
76
+ url: config.url,
77
+ attribution: config.attribution,
78
+ subdomains: config.subdomains !== undefined ? some(config.subdomains) : none,
79
+ maxZoom: config.maxZoom !== undefined ? some(config.maxZoom) : none,
80
+ detectRetina: config.detectRetina !== undefined ? some(config.detectRetina) : none,
81
+ }), MapTileType);
82
+ }
83
+ /**
84
+ * Builds an `hexDisk` area shape — a `gridDisk(origin, k)` blob at a resolution.
85
+ *
86
+ * @param center - The disk origin
87
+ * @param k - Ring count around the origin
88
+ * @param resolution - H3 resolution
89
+ * @returns A `MapAreaShapeType` value
90
+ */
91
+ function hexDisk(center, k, resolution) {
92
+ return East.value(variant("hexDisk", { center, k, resolution }), MapAreaShapeType);
93
+ }
94
+ /**
95
+ * Builds a `cells` area shape — an explicit set of H3 cell ids.
96
+ *
97
+ * @param ids - The H3 cell ids
98
+ * @returns A `MapAreaShapeType` value
99
+ */
100
+ function cells(ids) {
101
+ return East.value(variant("cells", ids), MapAreaShapeType);
102
+ }
103
+ /**
104
+ * Builds a `polygon` area shape — an explicit ring of points (an irregular
105
+ * region boundary). Two polygons that share an edge abut exactly, so adjacent
106
+ * regions running up against each other are authored by reusing the shared
107
+ * boundary points in both.
108
+ *
109
+ * @param points - The boundary points, in order (auto-closed; `Map.at(...)`)
110
+ * @returns A `MapAreaShapeType` value
111
+ */
112
+ function polygon(points) {
113
+ return East.value(variant("polygon", points), MapAreaShapeType);
114
+ }
115
+ /**
116
+ * Builds a `point` camera target — centre on a point at a zoom level.
117
+ *
118
+ * @param center - The centre
119
+ * @param zoom - The zoom level to settle at
120
+ * @returns A `MapFocusType` value
121
+ */
122
+ function point(center, zoom) {
123
+ return East.value(variant("point", { center, zoom }), MapFocusType);
124
+ }
125
+ /**
126
+ * Builds a `bounds` camera target — frame a south-west / north-east box.
127
+ *
128
+ * @param sw - South-west corner
129
+ * @param ne - North-east corner
130
+ * @returns A `MapFocusType` value
131
+ */
132
+ function bounds(sw, ne) {
133
+ return East.value(variant("bounds", { sw, ne }), MapFocusType);
134
+ }
135
+ /**
136
+ * Builds a `solid` line style.
137
+ *
138
+ * @param config - Optional stroke configuration (`tone`, `weight`)
139
+ * @returns A `MapLineStyleType` value
140
+ */
141
+ function solid(config) {
142
+ return East.value(variant("solid", {
143
+ tone: toneValue(config?.tone),
144
+ weight: config?.weight !== undefined ? some(config.weight) : none,
145
+ }), MapLineStyleType);
146
+ }
147
+ /**
148
+ * Builds a `dashed` line style.
149
+ *
150
+ * @param config - Optional stroke configuration (`tone`, `weight`)
151
+ * @returns A `MapLineStyleType` value
152
+ */
153
+ function dashed(config) {
154
+ return East.value(variant("dashed", {
155
+ tone: toneValue(config?.tone),
156
+ weight: config?.weight !== undefined ? some(config.weight) : none,
157
+ }), MapLineStyleType);
158
+ }
159
+ /**
160
+ * Builds the hex layer — a faint background lattice plus optional per-cell
161
+ * detail revealed at LOD.
162
+ *
163
+ * @param config - Optional `lattice`, `cells`, `tone`, and `interactive`
164
+ * @returns A `MapHexLayerType` value
165
+ */
166
+ function hex(config) {
167
+ return East.value({
168
+ lattice: config?.lattice !== undefined
169
+ ? some(East.value({ center: config.lattice.center, k: config.lattice.k, resolution: config.lattice.resolution }, StructType({ center: MapLatLngType, k: IntegerType, resolution: IntegerType })))
170
+ : none,
171
+ cells: (config?.cells ?? []).map(c => ({
172
+ id: c.id,
173
+ status: c.status !== undefined ? c.status : none,
174
+ fillOpacity: c.fillOpacity !== undefined ? some(c.fillOpacity) : none,
175
+ detail: c.detail !== undefined ? some(c.detail) : none,
176
+ })),
177
+ tone: toneOption(config?.tone),
178
+ interactive: config?.interactive !== undefined ? some(config.interactive) : none,
179
+ }, MapHexLayerType);
180
+ }
181
+ // ============================================================================
182
+ // Overlay slot
183
+ // ============================================================================
184
+ /**
185
+ * The generalised overlay slot value — an East `UIComponent` positioned over
186
+ * the map, either screen-anchored (`align` / `verticalAlign`) or pinned to a
187
+ * coordinate (`geoAnchor`).
188
+ *
189
+ * @property content - The East child tree rendered over the canvas
190
+ * @property align - Horizontal screen anchor
191
+ * @property verticalAlign - Vertical screen anchor
192
+ * @property key - Optional stable child storage-key segment
193
+ * @property geoAnchor - Optional coordinate the overlay follows on pan / zoom
194
+ * @property offset - Optional px nudge from the anchor
195
+ * @property interactive - Optional pointer-events flag (default true)
196
+ */
197
+ export const MapOverlayType = StructType({
198
+ /** The East child tree rendered over the canvas */
199
+ content: UIComponentType,
200
+ /** Horizontal screen anchor */
201
+ align: AlignType,
202
+ /** Vertical screen anchor */
203
+ verticalAlign: AlignType,
204
+ /** Optional stable child storage-key segment */
205
+ key: OptionType(StringType),
206
+ /** Optional coordinate the overlay follows on pan / zoom */
207
+ geoAnchor: OptionType(MapLatLngType),
208
+ /** Optional px nudge from the anchor */
209
+ offset: OptionType(StructType({ x: FloatType, y: FloatType })),
210
+ /** Optional pointer-events flag (default true; false ⇒ click-through) */
211
+ interactive: OptionType(BooleanType),
212
+ });
213
+ /**
214
+ * Builds a positioned overlay child for the `overlays` slot.
215
+ *
216
+ * @param content - The East child tree (a HUD, legend, back button)
217
+ * @param options - Anchor / offset / interactivity options
218
+ * @returns A `MapOverlayType` value
219
+ */
220
+ function overlay(content, options) {
221
+ return East.value({
222
+ content,
223
+ align: buildAlign(options?.align ?? "start"),
224
+ verticalAlign: buildAlign(options?.verticalAlign ?? "start"),
225
+ key: options?.key !== undefined ? some(options.key) : none,
226
+ geoAnchor: options?.geoAnchor !== undefined ? some(options.geoAnchor) : none,
227
+ offset: options?.offset !== undefined
228
+ ? some(East.value({ x: options.offset.x, y: options.offset.y }, StructType({ x: FloatType, y: FloatType })))
229
+ : none,
230
+ interactive: options?.interactive !== undefined ? some(options.interactive) : none,
231
+ }, MapOverlayType);
232
+ }
233
+ /**
234
+ * Builds a resolved marker value.
235
+ *
236
+ * @param fields - The marker fields ({@link MapMarkerFields})
237
+ * @returns A `MapMarkerType` value
238
+ */
239
+ function marker(fields) {
240
+ return East.value({
241
+ key: fields.key,
242
+ at: at(fields.lat, fields.lng),
243
+ label: fields.label !== undefined ? some(fields.label) : none,
244
+ icon: fields.icon !== undefined ? some(fields.icon) : none,
245
+ tone: toneOption(fields.tone),
246
+ minZoom: fields.minZoom !== undefined ? some(fields.minZoom) : none,
247
+ interactive: fields.interactive !== undefined ? some(fields.interactive) : none,
248
+ }, MapMarkerType);
249
+ }
250
+ /**
251
+ * Builds a resolved area value.
252
+ *
253
+ * @param fields - The area fields ({@link MapAreaFields})
254
+ * @returns A `MapAreaType` value
255
+ */
256
+ function area(fields) {
257
+ return East.value({
258
+ key: fields.key,
259
+ shape: fields.shape,
260
+ label: fields.label !== undefined ? some(fields.label) : none,
261
+ detailLabel: fields.detailLabel !== undefined ? some(fields.detailLabel) : none,
262
+ status: fields.status !== undefined ? fields.status : none,
263
+ tone: toneOption(fields.tone),
264
+ color: fields.color !== undefined ? some(fields.color) : none,
265
+ fillOpacity: fields.fillOpacity !== undefined ? some(fields.fillOpacity) : none,
266
+ weight: fields.weight !== undefined ? some(fields.weight) : none,
267
+ pulse: fields.pulse !== undefined ? some(fields.pulse) : none,
268
+ flyTo: fields.flyTo !== undefined ? some(fields.flyTo) : none,
269
+ }, MapAreaType);
270
+ }
271
+ /**
272
+ * Builds a resolved line value.
273
+ *
274
+ * @param fields - The line fields ({@link MapLineFields})
275
+ * @returns A `MapLineType` value
276
+ */
277
+ function line(fields) {
278
+ return East.value({
279
+ key: fields.key,
280
+ points: East.value(fields.points, ArrayType(MapLatLngType)),
281
+ style: fields.style !== undefined ? fields.style : solid(),
282
+ flow: fields.flow !== undefined ? some(fields.flow) : none,
283
+ arrow: fields.arrow !== undefined ? some(fields.arrow) : none,
284
+ }, MapLineType);
285
+ }
286
+ function label(fields) {
287
+ return East.value({ key: fields.key, at: at(fields.lat, fields.lng), text: fields.text }, MapLabelType);
288
+ }
289
+ // ============================================================================
290
+ // Root type + factory
291
+ // ============================================================================
292
+ /**
293
+ * East StructType for the Map component.
294
+ *
295
+ * @remarks
296
+ * The `overlays` slot and (via `content`) any child trees are recursive
297
+ * `UIComponentType` values; the registration in `component.ts` spells the
298
+ * same shape with the recursion `node`.
299
+ *
300
+ * @property tiles - Basemap source
301
+ * @property center - Initial centre
302
+ * @property zoom - Initial zoom
303
+ * @property minZoom - Optional minimum zoom clamp
304
+ * @property maxZoom - Optional maximum zoom clamp
305
+ * @property lodZoom - Optional detail-LOD threshold
306
+ * @property fitBounds - Optional camera framing (alternative to center / zoom)
307
+ * @property areas - Filled boundaries
308
+ * @property hexes - Optional H3 lattice + per-cell detail
309
+ * @property markers - Pins
310
+ * @property lines - Connectors / move arrows
311
+ * @property labels - Standalone labels
312
+ * @property overlays - Positioned East children (HUD / legend / back)
313
+ * @property scrollWheelZoom - Optional scroll-wheel zoom (default true)
314
+ * @property attributionPrefix - Optional Leaflet prefix toggle (default false)
315
+ * @property height - Optional fixed panel height
316
+ * @property onAreaClick - Optional area-click callback (receives the area key)
317
+ * @property onMarkerClick - Optional marker-click callback (receives the marker key)
318
+ * @property onZoom - Optional zoom-end callback (receives the zoom level)
319
+ * @property onSelect - Optional hex / marker selection callback (receives the key)
320
+ */
321
+ export const MapRootType = StructType({
322
+ tiles: MapTileType,
323
+ center: MapLatLngType,
324
+ zoom: IntegerType,
325
+ minZoom: OptionType(IntegerType),
326
+ maxZoom: OptionType(IntegerType),
327
+ lodZoom: OptionType(IntegerType),
328
+ fitBounds: OptionType(MapFocusType),
329
+ areas: ArrayType(MapAreaType),
330
+ hexes: OptionType(MapHexLayerType),
331
+ markers: ArrayType(MapMarkerType),
332
+ lines: ArrayType(MapLineType),
333
+ labels: ArrayType(MapLabelType),
334
+ overlays: ArrayType(MapOverlayType),
335
+ scrollWheelZoom: OptionType(BooleanType),
336
+ attributionPrefix: OptionType(BooleanType),
337
+ height: OptionType(StringType),
338
+ onAreaClick: OptionType(FunctionType([StringType], NullType)),
339
+ onMarkerClick: OptionType(FunctionType([StringType], NullType)),
340
+ onZoom: OptionType(FunctionType([IntegerType], NullType)),
341
+ onSelect: OptionType(FunctionType([StringType], NullType)),
342
+ });
343
+ function buildRoot(markers, config) {
344
+ const markerMapper = config.marker;
345
+ const resolvedMarkers = markerMapper === undefined
346
+ ? East.value(markers, ArrayType(MapMarkerType))
347
+ : East.value(markers).map((_$, row) => {
348
+ const r = markerMapper(row);
349
+ if (r instanceof Expr)
350
+ return East.value(r, MapMarkerType);
351
+ return marker(r);
352
+ });
353
+ const areaMapper = config.area;
354
+ const resolvedAreas = config.areas === undefined
355
+ ? East.value([], ArrayType(MapAreaType))
356
+ : areaMapper === undefined
357
+ ? East.value(config.areas, ArrayType(MapAreaType))
358
+ : East.value(config.areas).map((_$, row) => {
359
+ const r = areaMapper(row);
360
+ if (r instanceof Expr)
361
+ return East.value(r, MapAreaType);
362
+ return area(r);
363
+ });
364
+ const labelMapper = config.label;
365
+ const resolvedLabels = config.labels === undefined
366
+ ? East.value([], ArrayType(MapLabelType))
367
+ : labelMapper === undefined
368
+ ? East.value(config.labels, ArrayType(MapLabelType))
369
+ : East.value(config.labels).map((_$, row) => {
370
+ const r = labelMapper(row);
371
+ if (r instanceof Expr)
372
+ return East.value(r, MapLabelType);
373
+ return label(r);
374
+ });
375
+ const lineMapper = config.line;
376
+ const resolvedLines = config.lines === undefined
377
+ ? East.value([], ArrayType(MapLineType))
378
+ : lineMapper === undefined
379
+ ? East.value(config.lines, ArrayType(MapLineType))
380
+ : East.value(config.lines).map((_$, row) => {
381
+ const r = lineMapper(row);
382
+ if (r instanceof Expr)
383
+ return East.value(r, MapLineType);
384
+ return line(r);
385
+ });
386
+ return East.value(variant("Map", {
387
+ tiles: config.tiles !== undefined ? config.tiles : carto("positron"),
388
+ center: config.center,
389
+ zoom: config.zoom,
390
+ minZoom: config.minZoom !== undefined ? some(config.minZoom) : none,
391
+ maxZoom: config.maxZoom !== undefined ? some(config.maxZoom) : none,
392
+ lodZoom: config.lodZoom !== undefined ? some(config.lodZoom) : none,
393
+ fitBounds: config.fitBounds !== undefined ? some(config.fitBounds) : none,
394
+ areas: resolvedAreas,
395
+ hexes: config.hexes !== undefined ? some(config.hexes) : none,
396
+ markers: resolvedMarkers,
397
+ lines: resolvedLines,
398
+ labels: resolvedLabels,
399
+ overlays: config.overlays !== undefined
400
+ ? East.value([...config.overlays], ArrayType(MapOverlayType))
401
+ : East.value([], ArrayType(MapOverlayType)),
402
+ scrollWheelZoom: config.scrollWheelZoom !== undefined ? some(config.scrollWheelZoom) : none,
403
+ attributionPrefix: config.attributionPrefix !== undefined ? some(config.attributionPrefix) : none,
404
+ height: config.height !== undefined ? some(config.height) : none,
405
+ onAreaClick: config.onAreaClick !== undefined ? some(config.onAreaClick) : none,
406
+ onMarkerClick: config.onMarkerClick !== undefined ? some(config.onMarkerClick) : none,
407
+ onZoom: config.onZoom !== undefined ? some(config.onZoom) : none,
408
+ onSelect: config.onSelect !== undefined ? some(config.onSelect) : none,
409
+ }), UIComponentType);
410
+ }
411
+ /**
412
+ * Creates a Map — an interactive geographic basemap with H3 / area overlays
413
+ * and a generalised East-child overlay slot.
414
+ *
415
+ * @typeParam M - The markers-table input
416
+ * @typeParam A - The areas-table input
417
+ * @typeParam La - The labels-table input
418
+ * @typeParam L - The lines-table input
419
+ * @param markers - The pin rows (the required first table)
420
+ * @param config - The Map configuration ({@link MapConfig})
421
+ * @returns An East expression of `UIComponentType`
422
+ *
423
+ * @example
424
+ * ```ts
425
+ * import { East } from "@elaraai/east";
426
+ * import { Map, UIComponentType } from "@elaraai/east-ui";
427
+ *
428
+ * const example = East.function([], UIComponentType, _$ =>
429
+ * Map.Root(
430
+ * [{ id: "okafor", lat: -34.842, lng: 138.598, name: "J. Okafor" }],
431
+ * {
432
+ * center: Map.at(-34.881, 138.6), zoom: 12n,
433
+ * marker: m => ({ key: m.id, lat: m.lat, lng: m.lng, label: m.name }),
434
+ * },
435
+ * ),
436
+ * );
437
+ * ```
438
+ */
439
+ function createMap(markers, config) {
440
+ return buildRoot(markers, config);
441
+ }
442
+ // ============================================================================
443
+ // Namespace export
444
+ // ============================================================================
445
+ /**
446
+ * Map component namespace.
447
+ *
448
+ * @remarks
449
+ * `Map.Root(markers, config)` builds the basemap from flat tables (markers,
450
+ * areas, labels, lines) plus the `hexes` layer and the `overlays` slot;
451
+ * closed-set fields in data (`status`, `tone`, `style`) are typed variant
452
+ * values (`Map.Types.*`).
453
+ */
454
+ export const Map = {
455
+ /**
456
+ * Creates a Map — an interactive geographic basemap with H3 / area
457
+ * overlays and a generalised East-child overlay slot.
458
+ *
459
+ * @typeParam M - The markers-table input
460
+ * @typeParam A - The areas-table input
461
+ * @typeParam La - The labels-table input
462
+ * @typeParam L - The lines-table input
463
+ * @param markers - The pin rows (the required first table)
464
+ * @param config - The Map configuration ({@link MapConfig})
465
+ * @returns An East expression of `UIComponentType`
466
+ *
467
+ * @example
468
+ * ```ts
469
+ * import { East } from "@elaraai/east";
470
+ * import { Map, UIComponentType } from "@elaraai/east-ui";
471
+ *
472
+ * const example = East.function([], UIComponentType, _$ =>
473
+ * Map.Root(
474
+ * [{ id: "okafor", lat: -34.842, lng: 138.598, name: "J. Okafor" }],
475
+ * {
476
+ * center: Map.at(-34.881, 138.6), zoom: 12n,
477
+ * marker: m => ({ key: m.id, lat: m.lat, lng: m.lng, label: m.name }),
478
+ * },
479
+ * ),
480
+ * );
481
+ * ```
482
+ */
483
+ Root: createMap,
484
+ /**
485
+ * Builds a geographic point value.
486
+ *
487
+ * @param lat - Latitude in degrees
488
+ * @param lng - Longitude in degrees
489
+ * @returns A `MapLatLngType` value
490
+ *
491
+ * @example
492
+ * ```ts
493
+ * Map.at(-34.881, 138.6)
494
+ * ```
495
+ */
496
+ at,
497
+ /**
498
+ * Builds a CARTO raster basemap.
499
+ *
500
+ * @param style - The CARTO preset (default `positron`)
501
+ * @returns A `MapTileType` value
502
+ *
503
+ * @example
504
+ * ```ts
505
+ * Map.carto("voyager")
506
+ * ```
507
+ */
508
+ carto,
509
+ /**
510
+ * Builds an OpenStreetMap raster basemap.
511
+ *
512
+ * @returns A `MapTileType` value
513
+ *
514
+ * @example
515
+ * ```ts
516
+ * Map.osm()
517
+ * ```
518
+ */
519
+ osm,
520
+ /**
521
+ * Builds a raw XYZ basemap with explicit attribution.
522
+ *
523
+ * @param config - The tile URL, attribution, and optional layer options
524
+ * @returns A `MapTileType` value
525
+ *
526
+ * @example
527
+ * ```ts
528
+ * Map.tile({ url: "https://{s}.tiles.example/{z}/{x}/{y}.png", attribution: "© Example" })
529
+ * ```
530
+ */
531
+ tile,
532
+ /**
533
+ * Builds an `hexDisk` area shape — a `gridDisk(origin, k)` blob.
534
+ *
535
+ * @param center - The disk origin
536
+ * @param k - Ring count around the origin
537
+ * @param resolution - H3 resolution
538
+ * @returns A `MapAreaShapeType` value
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * Map.hexDisk(Map.at(-34.9258, 138.5994), 1n, 8n)
543
+ * ```
544
+ */
545
+ hexDisk,
546
+ /**
547
+ * Builds a `cells` area shape — an explicit set of H3 cell ids.
548
+ *
549
+ * @param ids - The H3 cell ids
550
+ * @returns A `MapAreaShapeType` value
551
+ *
552
+ * @example
553
+ * ```ts
554
+ * Map.cells(["882830829bfffff"])
555
+ * ```
556
+ */
557
+ cells,
558
+ /**
559
+ * Builds a `polygon` area shape — an explicit ring of points (an irregular
560
+ * region boundary). Two polygons sharing an edge abut exactly.
561
+ *
562
+ * @param points - The boundary points, in order (auto-closed; `Map.at(...)`)
563
+ * @returns A `MapAreaShapeType` value
564
+ */
565
+ polygon,
566
+ /**
567
+ * Builds the hex layer — a faint background lattice plus optional per-cell
568
+ * detail revealed at LOD.
569
+ *
570
+ * @param config - Optional `lattice`, `cells`, `tone`, and `interactive`
571
+ * @returns A `MapHexLayerType` value
572
+ *
573
+ * @example
574
+ * ```ts
575
+ * Map.hex({ lattice: { center: Map.at(-34.881, 138.6), k: 11n, resolution: 8n }, tone: "muted" })
576
+ * ```
577
+ */
578
+ hex,
579
+ /**
580
+ * Builds a resolved marker value.
581
+ *
582
+ * @param fields - The marker fields ({@link MapMarkerFields})
583
+ * @returns A `MapMarkerType` value
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * Map.marker({ key: "okafor", lat: -34.842, lng: 138.598, label: "J. Okafor", icon: "house" })
588
+ * ```
589
+ */
590
+ marker,
591
+ /**
592
+ * Builds a resolved area value.
593
+ *
594
+ * @param fields - The area fields ({@link MapAreaFields})
595
+ * @returns A `MapAreaType` value
596
+ *
597
+ * @example
598
+ * ```ts
599
+ * Map.area({ key: "5000", shape: Map.hexDisk(Map.at(-34.9258, 138.5994), 1n, 8n), label: "5000 · CBD" })
600
+ * ```
601
+ */
602
+ area,
603
+ /**
604
+ * Builds a resolved line value.
605
+ *
606
+ * @param fields - The line fields ({@link MapLineFields})
607
+ * @returns A `MapLineType` value
608
+ *
609
+ * @example
610
+ * ```ts
611
+ * Map.line({ key: "move", points: [Map.at(-34.905, 138.6), Map.at(-34.852, 138.6)], style: Map.dashed({ tone: "brand" }), arrow: true })
612
+ * ```
613
+ */
614
+ line,
615
+ /**
616
+ * Builds a `solid` line style.
617
+ *
618
+ * @param config - Optional stroke configuration (`tone`, `weight`)
619
+ * @returns A `MapLineStyleType` value
620
+ *
621
+ * @example
622
+ * ```ts
623
+ * Map.solid({ tone: "brand" })
624
+ * ```
625
+ */
626
+ solid,
627
+ /**
628
+ * Builds a `dashed` line style.
629
+ *
630
+ * @param config - Optional stroke configuration (`tone`, `weight`)
631
+ * @returns A `MapLineStyleType` value
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * Map.dashed({ tone: "brand" })
636
+ * ```
637
+ */
638
+ dashed,
639
+ /**
640
+ * Builds a `point` camera target.
641
+ *
642
+ * @param center - The centre
643
+ * @param zoom - The zoom level to settle at
644
+ * @returns A `MapFocusType` value
645
+ *
646
+ * @example
647
+ * ```ts
648
+ * Map.point(Map.at(-34.9258, 138.5994), 14n)
649
+ * ```
650
+ */
651
+ point,
652
+ /**
653
+ * Builds a `bounds` camera target.
654
+ *
655
+ * @param sw - South-west corner
656
+ * @param ne - North-east corner
657
+ * @returns A `MapFocusType` value
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * Map.bounds(Map.at(-34.95, 138.55), Map.at(-34.80, 138.65))
662
+ * ```
663
+ */
664
+ bounds,
665
+ /**
666
+ * Builds a positioned overlay child for the `overlays` slot.
667
+ *
668
+ * @param content - The East child tree (a HUD, legend, back button)
669
+ * @param options - Anchor / offset / interactivity options
670
+ * @returns A `MapOverlayType` value
671
+ *
672
+ * @example
673
+ * ```ts
674
+ * Map.overlay(Text.Root("ELARA"), { align: "start", verticalAlign: "start", key: "hud" })
675
+ * ```
676
+ */
677
+ overlay,
678
+ Types: {
679
+ /**
680
+ * East StructType for the Map component.
681
+ *
682
+ * @remarks
683
+ * See {@link MapRootType} for per-field docs.
684
+ *
685
+ * @property tiles - Basemap source
686
+ * @property center - Initial centre
687
+ * @property zoom - Initial zoom
688
+ * @property areas - Filled boundaries
689
+ * @property markers - Pins
690
+ * @property overlays - Positioned East children
691
+ */
692
+ Map: MapRootType,
693
+ /**
694
+ * A geographic point.
695
+ *
696
+ * @property lat - Latitude in degrees
697
+ * @property lng - Longitude in degrees
698
+ */
699
+ LatLng: MapLatLngType,
700
+ /**
701
+ * Theme tone for areas / hexes / markers / lines.
702
+ *
703
+ * @property brand - Brand teal
704
+ * @property ink - Foreground ink
705
+ * @property muted - Muted foreground
706
+ * @property success - Status ok
707
+ * @property warning - Status warn
708
+ * @property danger - Status bad
709
+ */
710
+ Tone: MapToneType,
711
+ /**
712
+ * CARTO basemap preset.
713
+ *
714
+ * @property positron - Light base
715
+ * @property darkMatter - Dark base
716
+ * @property voyager - Colour base
717
+ */
718
+ CartoStyle: MapCartoStyleType,
719
+ /**
720
+ * Basemap source (`carto` / `osm` / `custom`).
721
+ *
722
+ * @property carto - A CARTO raster preset
723
+ * @property osm - OpenStreetMap raster tiles
724
+ * @property custom - A raw XYZ template with attribution
725
+ */
726
+ Tile: MapTileType,
727
+ /**
728
+ * Camera target (`point` / `bounds`).
729
+ *
730
+ * @property point - Centre on a point at a zoom level
731
+ * @property bounds - Frame a south-west / north-east box
732
+ */
733
+ Focus: MapFocusType,
734
+ /**
735
+ * Area boundary (`hexDisk` / `polygon` / `cells`).
736
+ *
737
+ * @property hexDisk - A `gridDisk(origin, k)` blob
738
+ * @property polygon - An explicit ring of points
739
+ * @property cells - Explicit H3 cell ids
740
+ */
741
+ AreaShape: MapAreaShapeType,
742
+ /**
743
+ * A resolved area.
744
+ *
745
+ * @property key - Area identity
746
+ * @property shape - The boundary
747
+ * @property status - Optional status (drives colour + pulse)
748
+ * @property flyTo - Optional click camera target
749
+ */
750
+ Area: MapAreaType,
751
+ /**
752
+ * The hex layer (lattice + per-cell detail).
753
+ *
754
+ * @property lattice - Optional faint background lattice
755
+ * @property cells - Per-cell detail
756
+ * @property tone - Optional lattice stroke tone
757
+ */
758
+ Hex: MapHexLayerType,
759
+ /**
760
+ * A resolved marker.
761
+ *
762
+ * @property key - Marker identity
763
+ * @property at - The pin location
764
+ * @property minZoom - Optional LOD gate
765
+ */
766
+ Marker: MapMarkerType,
767
+ /**
768
+ * Line render style (`solid` / `dashed`).
769
+ *
770
+ * @property solid - A solid connector
771
+ * @property dashed - A dashed / routing connector
772
+ */
773
+ LineStyle: MapLineStyleType,
774
+ /**
775
+ * A resolved line.
776
+ *
777
+ * @property key - Line identity
778
+ * @property points - The polyline points
779
+ * @property style - Render style
780
+ * @property flow - Optional animated dash-offset
781
+ */
782
+ Line: MapLineType,
783
+ /**
784
+ * A resolved standalone label.
785
+ *
786
+ * @property key - Label identity
787
+ * @property at - The anchor
788
+ * @property text - The text
789
+ */
790
+ Label: MapLabelType,
791
+ /**
792
+ * The overlay slot value.
793
+ *
794
+ * @property content - The East child tree
795
+ * @property align - Horizontal screen anchor
796
+ * @property verticalAlign - Vertical screen anchor
797
+ * @property geoAnchor - Optional coordinate anchor
798
+ */
799
+ Overlay: MapOverlayType,
800
+ },
801
+ };
802
+ //# sourceMappingURL=index.js.map