@nika-js/onlymap 0.2.0 → 0.2.2

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.
@@ -36,6 +36,11 @@
36
36
  " <!-- Built-in legend — reads label/color from each <om-layer> -->",
37
37
  " <om-widget type=\"legend\" title=\"Layers\" position=\"top-right\"></om-widget>",
38
38
  "",
39
+ " <!-- Shown only where scripts never run (chat-app/email file previews) — hidden once the map boots -->",
40
+ " <om-fallback>",
41
+ " <p>This interactive map requires JavaScript.<br />Open this file in a web browser such as Chrome, Safari, or Firefox.</p>",
42
+ " </om-fallback>",
43
+ "",
39
44
  " </om-map>",
40
45
  "",
41
46
  "</body>",
@@ -78,6 +83,11 @@
78
83
  "",
79
84
  " $0",
80
85
  "",
86
+ " <!-- Shown only where scripts never run (chat-app/email file previews) -->",
87
+ " <om-fallback>",
88
+ " <p>This interactive map requires JavaScript — open this file in a web browser.</p>",
89
+ " </om-fallback>",
90
+ "",
81
91
  "</om-map>"
82
92
  ]
83
93
  },
@@ -157,6 +167,19 @@
157
167
  ]
158
168
  },
159
169
 
170
+ "!fallback": {
171
+ "scope": "html",
172
+ "prefix": "!fallback",
173
+ "description": "<om-fallback> — no-JS fallback for shared/previewed files (hidden once the map boots)",
174
+ "body": [
175
+ "<!-- Shown only where scripts never run (chat-app/email file previews, iOS QuickLook) -->",
176
+ "<om-fallback>",
177
+ " <p>${1:This interactive map requires JavaScript.}<br />",
178
+ " ${2:Open this file in a web browser such as Chrome, Safari, or Firefox.}</p>",
179
+ "</om-fallback>$0"
180
+ ]
181
+ },
182
+
160
183
  "!inline-data": {
161
184
  "scope": "html",
162
185
  "prefix": "!inline-data",
package/README.md CHANGED
@@ -44,22 +44,23 @@ Or with no build step at all, straight from a CDN:
44
44
  <script type="module" src="https://esm.sh/@nika-js/onlymap"></script>
45
45
  ```
46
46
 
47
- Then `npx @nika-js/onlymap init` wires up VS Code IntelliSense and `!`-prefixed manifest snippets for your project. The library ships with 254 unit/behavioral tests and 12 Playwright GPU tests.
47
+ Then `npx @nika-js/onlymap init` wires up VS Code IntelliSense and `!`-prefixed manifest snippets for your project. The library ships with 297 unit/behavioral tests and 19 Playwright GPU tests.
48
48
 
49
49
  The [examples](https://github.com/NikaGeospatial/onlymapjs/tree/main/examples) are the best tour: widgets, behaviors & overlays, basemaps, columnar/Arrow data, manual drawing, 3D models, a live WebSocket ship feed, and a polled driver fleet.
50
50
 
51
51
  ## The manifest
52
52
 
53
- Five elements, one rule: **attributes are kebab-case versions of deck.gl props** (`radius-units` → `radiusUnits`), and `get-*` attributes are data-driven accessors.
53
+ A handful of elements, one rule: **attributes are kebab-case versions of deck.gl props** (`radius-units` → `radiusUnits`), and `get-*` attributes are data-driven accessors.
54
54
 
55
55
  | Element | Role |
56
56
  |---|---|
57
- | `<om-map>` | The map. `center`, `zoom`, `pitch`, `bearing`; `basemap="maplibre"` (default style or any style URL no token) or `"none"` (standalone canvas); `validate` for a live on-page error panel. |
57
+ | `<om-map>` | The map. `center`, `zoom`, `pitch`, `bearing`; `basemap` takes a free preset (`positron`, `liberty`, `dark-matter`, `osm`, ), a style URL, or `"none"` (standalone canvas) — and switches **live**; `validate` for a live on-page error panel. |
58
58
  | `<om-layer>` | Any of **33 layer types** by name — all of deck.gl's core, geo, aggregation, and mesh layers (Scatterplot, GeoJson, Arc, Path, Heatmap, Hexagon, Trips, Tile, Tile3D, Scenegraph, …) plus the built-in `PopupLayer` for WebGL badges/labels at scale. `id` required; `label`/`color` feed the legend. |
59
- | `<om-widget>` | UI panels. Built-ins: `legend`, `layer-switcher`, `zoom-controls`, `scale-bar`, `attribution`, `filter`, `draw`, `vega-lite` (live charts). Or write your own inline with HTML + a `<script type="om/widget">`. |
59
+ | `<om-widget>` | UI panels. Built-ins: `legend`, `layer-switcher`, `basemap-switcher`, `zoom-controls`, `scale-bar`, `attribution`, `filter`, `draw`, `vega-lite` (live charts). Or write your own inline with HTML + a `<script type="om/widget">`. |
60
60
  | `<om-overlay>` | Rich HTML anchored to a map location — a static `anchor="[lng, lat]"`, the current selection, or a feature's own geometry via `anchor-layer`/`anchor-feature-id`. `{{field}}` interpolates the picked feature, HTML-escaped by default. |
61
61
  | `<om-behavior>` | Declarative interactions: `on="click|hover|drag|load|data-loaded"` → a named action. |
62
62
  | `<om-story>` | A storyboard: `<om-step>` children fire actions on a timeline. Controlled by the `player` widget, behaviors, or `storyEl.play()/pause()/seek()`. |
63
+ | `<om-fallback>` | What shows where scripts never run — chat-app/email file previews (iOS QuickLook renders HTML attachments with JS off), file managers, sandboxed webviews. A direct child of `<om-map>`, hidden automatically the moment the map boots; pages without one get a text-only default banner from the stylesheet. Good practice on any page that may travel as a file. The gate is pure CSS (`om-map:not(:defined)`), so `onlymapjs.css` must load without JS — a real `<link>`, a bundler-emitted sheet, or an inlined `<style>`. |
63
64
 
64
65
  ### Accessors without JavaScript
65
66
 
@@ -93,7 +94,9 @@ Private endpoints: `OmMap.configureData({ headers, credentials, fetch })` — ap
93
94
 
94
95
  ### Interaction
95
96
 
96
- Ten built-in actions wire to picks, widget buttons (`data-emit`), or script (`ctx.emit`) with one shared payload contract: `show-overlay`, `hide-overlay`, `show-tooltip`, `hide-tooltip`, `toggle-layer`, `highlight-feature`, `zoom-to-feature`, `filter-layer`, `zoom-in`, `zoom-out` — plus `OmMap.registerAction` for your own.
97
+ Built-in actions wire to picks, widget buttons (`data-emit`), or script (`ctx.emit`) with one shared payload contract: `show-overlay`, `hide-overlay`, `show-tooltip`, `hide-tooltip`, `toggle-layer`, `highlight-feature`, `zoom-to-feature`, `filter-layer`, `set-basemap`, `zoom-in`, `zoom-out` — plus `OmMap.registerAction` for your own.
98
+
99
+ **Basemaps:** free presets out of the box — OpenFreeMap `liberty`/`bright`/`positron` (no key, no limits), CARTO `dark-matter`/`voyager`, classic `osm` raster, and keyed `maptiler-*` presets (MapTiler's style editor is the visual way to customize basemap JSON; keys are publishable, via `basemap-key` or `OmMap.configureBasemap`). The `basemap` attribute switches **live** — camera and layers survive — from a hand edit, the `set-basemap` action, or `<om-widget type="basemap-switcher">`. Add your own with `OmMap.registerBasemap(name, { style })`; required attribution renders automatically. Guide: [docs/basemaps.md](docs/basemaps.md).
97
100
 
98
101
  **Animation:** camera moves accept a duration — `map.flyTo(coords, zoom, { duration: 1200, curve: true })`, or the `fly-to` action (`center`/`zoom`/`pitch`/`bearing`/`duration`) from any behavior or button; `prefers-reduced-motion` is honored (moves become instant, final state identical). Per-prop GPU transitions via the `transition` attribute: `transition="get-fill-color 800ms"` fades color changes; on a streaming layer, `transition="get-position 300ms"` makes entities glide between updates.
99
102
 
@@ -190,7 +193,7 @@ Plus `OmMap.snapshotIR(html)` to lock down what a manifest *means* in a snapshot
190
193
 
191
194
  ## Programmatic surface
192
195
 
193
- - **`OmMap.*`** — `validate`, `snapshotIR`, `registerLayer`, `registerWidget`, `registerAction`, `registerSource`, `registerFormat`, `configureData`, `getLayerSchema`
196
+ - **`OmMap.*`** — `validate`, `snapshotIR`, `registerLayer`, `registerWidget`, `registerAction`, `registerSource`, `registerFormat`, `registerBasemap`, `configureBasemap`, `configureData`, `getLayerSchema`
194
197
  - **On a `<om-map>` element** — `ready` (promise), `flyTo(coords, zoom?)`, `setLayerVisible(id, bool)`, `getLayers()`, `emit(action, payload)`; `document.querySelector("om-map")` is fully typed
195
198
  - **`MapController`** — the framework-grade programmatic front-end (typed `LayerDescriptor`s → the same reconcile core, no DOM manifest): `setLayers`, `watch`, `emit`, camera methods, `injectPick`, `ready`. The React adapter rides it; usable directly from vanilla TS or other frameworks
196
199
  - **Testing** — `mountForTest`, and imports are SSR-safe (importing in Node/jsdom never touches browser globals)
@@ -203,6 +206,6 @@ Mapbox GL basemaps, depth-interleaved 3D compositing, globe projection, SSE tran
203
206
 
204
207
  | | |
205
208
  |---|---|
206
- | [docs/react.md](docs/react.md) · [docs/testing.md](docs/testing.md) · [docs/live-data.md](docs/live-data.md) · [docs/3d-assets.md](docs/3d-assets.md) · [docs/stories.md](docs/stories.md) | Consumer guides |
209
+ | [docs/react.md](docs/react.md) · [docs/basemaps.md](docs/basemaps.md) · [docs/testing.md](docs/testing.md) · [docs/live-data.md](docs/live-data.md) · [docs/3d-assets.md](docs/3d-assets.md) · [docs/stories.md](docs/stories.md) | Consumer guides |
207
210
  | [llms.txt](llms.txt) | The agent-facing quick reference |
208
211
  | `skills/onlymapjs` | Installable LLM skill for OnlyMapJS authoring |