doxa-maps/plugin-designs/template-bundle/README.md
doxa-maps-88655c70 9dc4dda8cf
Some checks are pending
build-gate / build (push) Waiting to run
consolidate docs into documentation/ and deployment shells into deployment/
Driver 2026-09-21: 'a folder called deployment which will store the capacitor
folder, wordpress folder and tauri folder', and 'a folder called documentation
to store the contributing folder so docs are in one place'.

docs/ + contributing/ + CONTRIBUTING.md -> documentation/ (three doc homes into
one). capacitor/ + wordpress/ + src-tauri/ -> deployment/.

The public/ -> dist/ rename the Driver asked about is NOT here: after seeing the
measured blast radius (855 tracked files, 54 source refs, and public/ is the
served web-root four consumers point at) the Driver withdrew it - 'keep the
public folder the same'.

Path references were rewritten mechanically (258 across 87 files), but three
classes needed hand fixes because a prefix regex cannot see them:
  - join(ROOT,'docs',...) in 10 internal scripts - a quoted SEGMENT, not a prefix
  - tauri frontendDist '../public' -> '../../public', since src-tauri is now one
    level deeper; check:tauri caught this exactly as the card predicted
  - the WordPress contract test's dirname(__DIR__,2) -> 3, same reason

Also reverted one over-reach: the rewrite renamed a FINDING-CATEGORY label
'docs' in public-hygiene-check.mjs, which is a rule name in its own header, not
a path.

Verified: full build ALL GUARDS PASS, SRI consistent; check:tauri, check:mobile
(cap sync + webDir OK), check:wp-embed, quoted-scripts, capability-citations,
capability-exemplars, library-index, public-hygiene, parse and drop all pass.
2026-09-21 23:23:23 +00:00

6.1 KiB

template-bundle — copy this to start a new plugin

This folder is the STARTER. Copy it to make a new plugin. That's the whole idea.

Your starting point. Copy this folder, then build your map inside the copy — don't start from blank. It's a tiny working bundle (two trivial profiles that render a colored box, no Mapbox, no data) plus a src/ sandbox laid out for your real code.

In plain English (read this first)

If you've never touched this repo, here are the only 4 words you need:

Word Plain-English meaning
plugin / bundle One folder = one plugin. It compiles into a single .js file you can paste onto any web page. "Bundle" and "plugin" mean the same thing here — the folder you copy.
profile One .vue file inside the folder = one screen (one map). A bundle can hold one profile or many. You pick which screen shows at embed time with a profile name.
root.vue Each profile IS a normal Vue component — it's the "root" (the top of the tree) for that one screen. The filename (minus .vue) is the profile's name. Everything that screen draws hangs off this one file.
src/ Your private sandbox — your own colors, components, and helpers. Nothing in here can affect another plugin. Shared building blocks live in library/ (imported as @map/…) and you never edit those.

Make a new plugin in 2 moves:

# 1. copy this starter to a new name
cp -r plugin-designs/template-bundle plugin-designs/my-plugin

# 2. build (the ONE command)
bun run build      # → public/doxa-maps/my-plugin/my-plugin.js  (your paste-anywhere plugin)

Then rename the tag + profile strings (the "exactly four things" list below) so your copy has its own name, and rebuild. That's it — the build auto-detects your new folder, compiles it to one .js custom element, and lists it in the gallery.

Proven: a copy of this folder (cp -r + rename the 4 strings) runs bun run build and emits a working <my-plugin> custom element .js bundle that passes every build guard. If it builds for the starter, it builds for your copy.

Two zones — know which one a file is in

Zone What Edit it?
library/ (imported as @map/…) shared, reusable building blocks — map, legends, toolbars, composables, color + API registries No — reuse only. A change here can break every other map.
plugin-designs/<your-map>/src/ your private sandbox — screens, colors, API wiring, components, utils Yes — build anything. Nothing here leaks to another map.

Rule of thumb: local by default. Code only moves into library/ once a second map genuinely needs it — an expert move, not a first move. To see everything library/ offers, read ../../documentation/reference.md (that's the menu you pick from).

Build a new map — the steps

  1. Copy this folder → plugin-designs/<your-map>/, then change exactly four things:
    • the folder name (= bundle name = output file <your-map>.js),
    • the tag in index.js (customElements.define('<your-map>', …)),
    • the tag + profile strings in index.html (the staging page must mount your tag),
    • the .vue filenames — rename template-map-a.vue to your screen's name and delete template-map-b.vue if you only want one screen (filename = the profile name). Nothing else. Check it: bun run dev → your map renders at http://localhost:5173/plugin-designs/<your-map>/index.html.
  2. List what your map needs — data, colors, controls (legend, search, share, fullscreen…).
  3. Pick pieces from ../../documentation/reference.md and import them by reference (@map/…) — never copy library code into your folder.
  4. Put your own code in src/ — screens, components, hooks, helpers.
  5. Set colors in src/colors/colors.json (plain hex, no code). For color that varies by data, use a strategy .js in src/colors/ (copy example-mode.js).
  6. Build — bun run build (or just this one: BUNDLE=<your-map> bun run build:bundle).

What's in this folder

template-bundle/
├── index.js              ← bundle entry: registers <template-bundle>, globs ./*.vue
├── index.html            ← dev staging page (the build needs it to find the bundle)
├── template-map-a.vue    ← profile "template-map-a"   ← FLAT at the bundle root
├── template-map-b.vue    ← profile "template-map-b"   ← FLAT at the bundle root
└── src/                  ← YOUR SANDBOX (each subfolder has its own README)
    ├── api/  colors/  components/  composables/  utils/

The flat rule: profile .vue files sit directly in the bundle folder — there is no profiles/ subfolder, because the entry discovers them with a flat glob (import.meta.glob('./*.vue')). A .vue inside a profiles/ subfolder would NOT be found. Keep your profile screens flat; the small pieces they're built from live in src/.

Everything builds into one file: public/doxa-maps/template-bundle/template-bundle.js.

The two ways you import

  • Reuse from the library → the @map/… alias: import { useMapInstance } from '@map/composables/useMapInstance.js'
  • Your own sandbox code → a relative path: import colors from './src/colors/colors.json'

There's no alias for your sandbox — your code is always relative. That boundary keeps it private.

Embed it

<script src="/doxa-maps/template-bundle/template-bundle.js"></script>
<template-bundle profile-config='{"profile":"template-map-a"}'></template-bundle>
<template-bundle profile-config='{"profile":"template-map-b"}'></template-bundle>

(profile must match a .vue filename in this folder, without .vue. Add a third profile by dropping another flat .vue next to these and rebuilding — no config to edit.)

See also

  • src/README.md — sandbox layout · ../README.md — the plugin-designs authoring guide
  • ../../documentation/tutorial.md — 3 zones + 3 rules in one page · ../../documentation/reference.md — the @map/… menu
  • ../doxa-simple-map/index.js — a fuller, real-map reference entry