@mailwoman/react 7.5.0 → 7.7.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 (128) hide show
  1. package/common/PresetChips.tsx +4 -1
  2. package/index.ts +28 -0
  3. package/map/BackendControl.tsx +39 -0
  4. package/map/CompareToggle.tsx +81 -0
  5. package/map/DemoControls.tsx +173 -0
  6. package/map/DemoMap.tsx +98 -0
  7. package/map/GeocoderDemo.tsx +178 -0
  8. package/map/OverlayLayers.tsx +46 -0
  9. package/map/PlaceAutocomplete.tsx +69 -0
  10. package/map/PlaceMarker.tsx +40 -0
  11. package/map/ResolvedPlaceLayers.tsx +63 -0
  12. package/map/ResultCamera.tsx +60 -0
  13. package/map/ResultOverlay.tsx +61 -0
  14. package/map/ResultPanel.tsx +84 -0
  15. package/map/VersionPicker.tsx +62 -0
  16. package/map/geometry.ts +135 -0
  17. package/map/index.ts +73 -0
  18. package/map/place-render.ts +157 -0
  19. package/map/types.ts +207 -0
  20. package/map/useCompareState.ts +45 -0
  21. package/map/useDemoGeocode.ts +67 -0
  22. package/map/useMapPlaceRender.ts +21 -0
  23. package/map/usePlaceAutocomplete.ts +195 -0
  24. package/out/common/PresetChips.d.ts +3 -1
  25. package/out/common/PresetChips.d.ts.map +1 -1
  26. package/out/common/PresetChips.js +2 -2
  27. package/out/common/PresetChips.js.map +1 -1
  28. package/out/index.d.ts +3 -0
  29. package/out/index.d.ts.map +1 -1
  30. package/out/index.js +2 -0
  31. package/out/index.js.map +1 -1
  32. package/out/map/BackendControl.d.ts +24 -0
  33. package/out/map/BackendControl.d.ts.map +1 -0
  34. package/out/map/BackendControl.js +6 -0
  35. package/out/map/BackendControl.js.map +1 -0
  36. package/out/map/CompareToggle.d.ts +35 -0
  37. package/out/map/CompareToggle.d.ts.map +1 -0
  38. package/out/map/CompareToggle.js +9 -0
  39. package/out/map/CompareToggle.js.map +1 -0
  40. package/out/map/DemoControls.d.ts +44 -0
  41. package/out/map/DemoControls.d.ts.map +1 -0
  42. package/out/map/DemoControls.js +28 -0
  43. package/out/map/DemoControls.js.map +1 -0
  44. package/out/map/DemoMap.d.ts +59 -0
  45. package/out/map/DemoMap.d.ts.map +1 -0
  46. package/out/map/DemoMap.js +12 -0
  47. package/out/map/DemoMap.js.map +1 -0
  48. package/out/map/GeocoderDemo.d.ts +47 -0
  49. package/out/map/GeocoderDemo.d.ts.map +1 -0
  50. package/out/map/GeocoderDemo.js +73 -0
  51. package/out/map/GeocoderDemo.js.map +1 -0
  52. package/out/map/OverlayLayers.d.ts +23 -0
  53. package/out/map/OverlayLayers.d.ts.map +1 -0
  54. package/out/map/OverlayLayers.js +27 -0
  55. package/out/map/OverlayLayers.js.map +1 -0
  56. package/out/map/PlaceAutocomplete.d.ts +34 -0
  57. package/out/map/PlaceAutocomplete.d.ts.map +1 -0
  58. package/out/map/PlaceAutocomplete.js +9 -0
  59. package/out/map/PlaceAutocomplete.js.map +1 -0
  60. package/out/map/PlaceMarker.d.ts +27 -0
  61. package/out/map/PlaceMarker.d.ts.map +1 -0
  62. package/out/map/PlaceMarker.js +9 -0
  63. package/out/map/PlaceMarker.js.map +1 -0
  64. package/out/map/ResolvedPlaceLayers.d.ts +34 -0
  65. package/out/map/ResolvedPlaceLayers.d.ts.map +1 -0
  66. package/out/map/ResolvedPlaceLayers.js +11 -0
  67. package/out/map/ResolvedPlaceLayers.js.map +1 -0
  68. package/out/map/ResultCamera.d.ts +34 -0
  69. package/out/map/ResultCamera.d.ts.map +1 -0
  70. package/out/map/ResultCamera.js +43 -0
  71. package/out/map/ResultCamera.js.map +1 -0
  72. package/out/map/ResultOverlay.d.ts +34 -0
  73. package/out/map/ResultOverlay.d.ts.map +1 -0
  74. package/out/map/ResultOverlay.js +18 -0
  75. package/out/map/ResultOverlay.js.map +1 -0
  76. package/out/map/ResultPanel.d.ts +34 -0
  77. package/out/map/ResultPanel.d.ts.map +1 -0
  78. package/out/map/ResultPanel.js +12 -0
  79. package/out/map/ResultPanel.js.map +1 -0
  80. package/out/map/VersionPicker.d.ts +30 -0
  81. package/out/map/VersionPicker.d.ts.map +1 -0
  82. package/out/map/VersionPicker.js +8 -0
  83. package/out/map/VersionPicker.js.map +1 -0
  84. package/out/map/geometry.d.ts +55 -0
  85. package/out/map/geometry.d.ts.map +1 -0
  86. package/out/map/geometry.js +99 -0
  87. package/out/map/geometry.js.map +1 -0
  88. package/out/map/index.d.ts +52 -0
  89. package/out/map/index.d.ts.map +1 -0
  90. package/out/map/index.js +36 -0
  91. package/out/map/index.js.map +1 -0
  92. package/out/map/place-render.d.ts +85 -0
  93. package/out/map/place-render.d.ts.map +1 -0
  94. package/out/map/place-render.js +98 -0
  95. package/out/map/place-render.js.map +1 -0
  96. package/out/map/types.d.ts +193 -0
  97. package/out/map/types.d.ts.map +1 -0
  98. package/out/map/types.js +18 -0
  99. package/out/map/types.js.map +1 -0
  100. package/out/map/useCompareState.d.ts +25 -0
  101. package/out/map/useCompareState.d.ts.map +1 -0
  102. package/out/map/useCompareState.js +27 -0
  103. package/out/map/useCompareState.js.map +1 -0
  104. package/out/map/useDemoGeocode.d.ts +36 -0
  105. package/out/map/useDemoGeocode.d.ts.map +1 -0
  106. package/out/map/useDemoGeocode.js +44 -0
  107. package/out/map/useDemoGeocode.js.map +1 -0
  108. package/out/map/useMapPlaceRender.d.ts +15 -0
  109. package/out/map/useMapPlaceRender.d.ts.map +1 -0
  110. package/out/map/useMapPlaceRender.js +18 -0
  111. package/out/map/useMapPlaceRender.js.map +1 -0
  112. package/out/map/usePlaceAutocomplete.d.ts +61 -0
  113. package/out/map/usePlaceAutocomplete.d.ts.map +1 -0
  114. package/out/map/usePlaceAutocomplete.js +122 -0
  115. package/out/map/usePlaceAutocomplete.js.map +1 -0
  116. package/out/pipeline/QueryForm.d.ts +6 -2
  117. package/out/pipeline/QueryForm.d.ts.map +1 -1
  118. package/out/pipeline/QueryForm.js +2 -2
  119. package/out/pipeline/QueryForm.js.map +1 -1
  120. package/out/runtime/useDemoRuntime.d.ts +113 -0
  121. package/out/runtime/useDemoRuntime.d.ts.map +1 -0
  122. package/out/runtime/useDemoRuntime.js +135 -0
  123. package/out/runtime/useDemoRuntime.js.map +1 -0
  124. package/package.json +27 -6
  125. package/pipeline/QueryForm.tsx +17 -2
  126. package/runtime/useDemoRuntime.ts +245 -0
  127. package/styles.css +145 -0
  128. package/vitest.node.config.ts +20 -0
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `<GeocoderDemo>` — the WHOLE geocoder demo, composed. It is the map analogue of `PipelineExplorer`
8
+ * and takes the SAME DI seam shape: an injected {@link DemoRuntime} (the host owns ONNX / httpvfs / R2 /
9
+ * the composed map style) plus a {@link DemoPanels} bag (the host's ModelVisualizer / VersionCompare /
10
+ * About / Permalink). Everything here is composition + a `ClientOnly` boundary:
11
+ *
12
+ * - the floating {@link DemoControls} panel (version / compare / backend / query+autocomplete / result),
13
+ * - the declarative {@link DemoMap} with the phase-2 overlays ({@link OverlayLayers}) and the
14
+ * resolved-place marker/outline/camera ({@link ResolvedPlaceLayers}) driven by the parse state,
15
+ * - the hooks that wire them: {@link useDemoGeocode} (parse + viewport bias + map place),
16
+ * {@link usePlaceAutocomplete}, {@link useCompareState}.
17
+ *
18
+ * Because it pulls {@link DemoMap} (→ `react-map-gl` → `maplibre-gl`, WebGL + DOM at import), it lives on
19
+ * the `@mailwoman/react/map` subpath ONLY — never the package root. The whole thing renders in Storybook
20
+ * over a fake runtime (offline stub style + canned geocode) with no network, no ONNX, no gazetteer.
21
+ */
22
+ import { useCallback, useRef } from "react";
23
+ import { ClientOnly } from "../common/ClientOnly.js";
24
+ import {} from "../common/PresetChips.js";
25
+ import { DemoControls } from "./DemoControls.js";
26
+ import { DemoMap } from "./DemoMap.js";
27
+ import { OverlayLayers } from "./OverlayLayers.js";
28
+ import { ResolvedPlaceLayers } from "./ResolvedPlaceLayers.js";
29
+ import { useCompareState } from "./useCompareState.js";
30
+ import { useDemoGeocode } from "./useDemoGeocode.js";
31
+ import { useMapPlaceRender } from "./useMapPlaceRender.js";
32
+ import { usePlaceAutocomplete } from "./usePlaceAutocomplete.js";
33
+ function GeocoderDemoInner({ runtime, panels, defaultAddress, presets, minBiasZoom, applyResultCamera, }) {
34
+ const mapRef = useRef(null);
35
+ // Read the viewport bias at submit time — through the map handle, never a threaded state value, so granting/zooming
36
+ // mid-session doesn't re-create the parse callback. Below the min-bias zoom, a whole-globe center is noise → null.
37
+ const getBias = useCallback(() => {
38
+ const map = mapRef.current?.getMap();
39
+ if (!map)
40
+ return null;
41
+ const zoom = map.getZoom();
42
+ if (zoom < minBiasZoom)
43
+ return null;
44
+ const center = map.getCenter();
45
+ return { center: [center.lng, center.lat], zoom };
46
+ }, [minBiasZoom]);
47
+ const geocode = useDemoGeocode({ runtime, defaultText: defaultAddress, getBias });
48
+ const compare = useCompareState();
49
+ const autocomplete = usePlaceAutocomplete({
50
+ text: geocode.text,
51
+ setText: geocode.setText,
52
+ autocomplete: runtime.autocomplete,
53
+ });
54
+ const spec = useMapPlaceRender(geocode.mapPlace);
55
+ const onSelectVersion = useCallback((version) => {
56
+ runtime.selectVersion?.(version);
57
+ compare.clearIfPrimary(version);
58
+ }, [runtime, compare]);
59
+ const onForceWASMChange = useCallback((forceWASM) => runtime.setForceWASM?.(forceWASM), [runtime]);
60
+ return (_jsxs("div", { className: "mw-geocoder-demo", children: [_jsx("div", { className: "mw-geocoder-demo__map", children: _jsxs(DemoMap, { mapStyle: runtime.mapStyle, mapRef: mapRef, initialViewState: {
61
+ longitude: runtime.initialCenter[0],
62
+ latitude: runtime.initialCenter[1],
63
+ zoom: runtime.initialZoom ?? 3,
64
+ }, style: { width: "100%", height: "100%" },
65
+ // Match the live demo's chrome: one compact attribution pill (the map's own default is a wide, always-open
66
+ // "MapLibre | © …" bar), no maplibre wordmark logo.
67
+ mapProps: { attributionControl: { compact: true }, maplibreLogo: false }, children: [_jsx(OverlayLayers, { overlays: runtime.overlays }), _jsx(ResolvedPlaceLayers, { spec: spec, applyCamera: applyResultCamera }), panels.mapControls] }) }), _jsx(DemoControls, { runtime: runtime, geocode: geocode, autocomplete: autocomplete, compare: compare, panels: panels, presets: presets, placeholder: defaultAddress, onSelectVersion: onSelectVersion, onForceWASMChange: onForceWASMChange }), panels.debugDrawer ? panels.debugDrawer({ result: geocode.result }) : null] }));
68
+ }
69
+ /** The composed geocoder demo, behind a `ClientOnly` SSR boundary (the map is intrinsically a client component). */
70
+ export function GeocoderDemo({ runtime, panels = {}, defaultAddress = "", presets = [], minBiasZoom = 4, applyResultCamera = true, }) {
71
+ return (_jsx(ClientOnly, { fallback: _jsx("div", { className: "mw-geocoder-demo", children: _jsx("p", { children: "Loading demo\u2026" }) }), children: () => (_jsx(GeocoderDemoInner, { runtime: runtime, panels: panels, defaultAddress: defaultAddress, presets: presets, minBiasZoom: minBiasZoom, applyResultCamera: applyResultCamera })) }));
72
+ }
73
+ //# sourceMappingURL=GeocoderDemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeocoderDemo.js","sourceRoot":"","sources":["../../map/GeocoderDemo.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<OverlayLayers>` — renders the host-supplied {@link OverlaySpec}s (coverage "fog of war",
7
+ * race-dots, …) as declarative `<Source>` + `<Layer>`s. This replaces the demo's imperative
8
+ * `map.addSource` / `map.addLayer` overlay loops (and their `isStyleLoaded()` / `styledata` gates):
9
+ * the host composes the specs, the package renders them, react-map-gl owns the add/remove lifecycle.
10
+ *
11
+ * Each overlay's `visible` flag flips the layers' `visibility` layout property — the declarative seam a
12
+ * layer-toggle control drives in a later phase. NODE-IMPORT SAFETY: imports `react-map-gl/maplibre` —
13
+ * reachable only via `@mailwoman/react/map`.
14
+ */
15
+ import { type ReactNode } from "react";
16
+ import type { OverlaySpec } from "./types.ts";
17
+ export interface OverlayLayersProps {
18
+ /** The overlays to render, in draw order (first is drawn first / lowest). */
19
+ overlays?: OverlaySpec[];
20
+ }
21
+ /** Render each overlay as one `<Source>` and its `<Layer>`s, honoring the `visible` flag via `visibility`. */
22
+ export declare function OverlayLayers({ overlays }: OverlayLayersProps): ReactNode;
23
+ //# sourceMappingURL=OverlayLayers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayLayers.d.ts","sourceRoot":"","sources":["../../map/OverlayLayers.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,WAAW,kBAAkB;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CACxB;AAED,8GAA8G;AAC9G,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,GAAG,SAAS,CAmBzE"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `<OverlayLayers>` — renders the host-supplied {@link OverlaySpec}s (coverage "fog of war",
8
+ * race-dots, …) as declarative `<Source>` + `<Layer>`s. This replaces the demo's imperative
9
+ * `map.addSource` / `map.addLayer` overlay loops (and their `isStyleLoaded()` / `styledata` gates):
10
+ * the host composes the specs, the package renders them, react-map-gl owns the add/remove lifecycle.
11
+ *
12
+ * Each overlay's `visible` flag flips the layers' `visibility` layout property — the declarative seam a
13
+ * layer-toggle control drives in a later phase. NODE-IMPORT SAFETY: imports `react-map-gl/maplibre` —
14
+ * reachable only via `@mailwoman/react/map`.
15
+ */
16
+ import { Fragment } from "react";
17
+ import { Layer, Source } from "react-map-gl/maplibre";
18
+ /** Render each overlay as one `<Source>` and its `<Layer>`s, honoring the `visible` flag via `visibility`. */
19
+ export function OverlayLayers({ overlays }) {
20
+ if (!overlays || overlays.length === 0)
21
+ return null;
22
+ return (_jsx(_Fragment, { children: overlays.map((overlay) => {
23
+ const visibility = overlay.visible === false ? "none" : "visible";
24
+ return (_jsxs(Fragment, { children: [_jsx(Source, { id: overlay.id, ...overlay.source }), overlay.layers.map((layer) => (_jsx(Layer, { ...layer, layout: { ...layer.layout, visibility } }, layer.id)))] }, overlay.id));
25
+ }) }));
26
+ }
27
+ //# sourceMappingURL=OverlayLayers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayLayers.js","sourceRoot":"","sources":["../../map/OverlayLayers.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AASrD,8GAA8G;AAC9G,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAsB;IAC7D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnD,OAAO,CACN,4BACE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACzB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;YAEjE,OAAO,CACN,MAAC,QAAQ,eACR,KAAC,MAAM,IAAC,EAAE,EAAE,OAAO,CAAC,EAAE,KAAM,OAAO,CAAC,MAAM,GAAI,EAC7C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC9B,KAAC,KAAK,OAAoB,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAA5D,KAAK,CAAC,EAAE,CAAwD,CAC5E,CAAC,KAJY,OAAO,CAAC,EAAE,CAKd,CACX,CAAA;QACF,CAAC,CAAC,GACA,CACH,CAAA;AACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<PlaceAutocomplete>` — the "Did you mean" suggestion listbox from the demo (`_app.tsx:1394-1418`), as
7
+ * a dumb presentational unit. It renders the current suggestions with the keyboard-highlighted active
8
+ * descendant; the state + keyboard nav live in {@link usePlaceAutocomplete}. Renders `null` when there
9
+ * is nothing to suggest, so the row only appears when useful. Wire the ids from the hook so the input's
10
+ * `aria-controls` / `aria-activedescendant` match this listbox.
11
+ *
12
+ * NODE-SAFE: pure React, no maplibre.
13
+ */
14
+ import type { ReactNode } from "react";
15
+ import type { Suggestion } from "./types.ts";
16
+ export interface PlaceAutocompleteProps {
17
+ /** The suggestions to render (from {@link usePlaceAutocomplete}). */
18
+ suggestions: Suggestion[];
19
+ /** The keyboard-highlighted index; `-1` for none. */
20
+ activeIndex: number;
21
+ /** Fired (with the suggestion `value`) when one is clicked. */
22
+ onPick: (value: string) => void;
23
+ /** Fired with the index a pointer entered, so hover matches keyboard highlight. */
24
+ onHover?: (index: number) => void;
25
+ /** The listbox element id — pass `listboxId` from the hook (matches the input's `aria-controls`). */
26
+ listboxId: string;
27
+ /** Build the option element id — pass `optionId` from the hook. */
28
+ optionId: (index: number) => string;
29
+ /** Leading label. @default "Did you mean:" */
30
+ caption?: string;
31
+ }
32
+ /** The suggestion listbox. */
33
+ export declare function PlaceAutocomplete({ suggestions, activeIndex, onPick, onHover, listboxId, optionId, caption, }: PlaceAutocompleteProps): ReactNode;
34
+ //# sourceMappingURL=PlaceAutocomplete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaceAutocomplete.d.ts","sourceRoot":"","sources":["../../map/PlaceAutocomplete.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,sBAAsB;IACtC,qEAAqE;IACrE,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,+DAA+D;IAC/D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,mFAAmF;IACnF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,qGAAqG;IACrG,SAAS,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACnC,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,8BAA8B;AAC9B,wBAAgB,iBAAiB,CAAC,EACjC,WAAW,EACX,WAAW,EACX,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,OAAyB,GACzB,EAAE,sBAAsB,GAAG,SAAS,CAuBpC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from "../common/cx.js";
3
+ /** The suggestion listbox. */
4
+ export function PlaceAutocomplete({ suggestions, activeIndex, onPick, onHover, listboxId, optionId, caption = "Did you mean:", }) {
5
+ if (suggestions.length === 0)
6
+ return null;
7
+ return (_jsxs("div", { className: "mw-demo-suggest", id: listboxId, role: "listbox", "aria-label": "Place suggestions", children: [_jsx("span", { className: "mw-demo-suggest__label", children: caption }), suggestions.map((s, i) => (_jsx("button", { id: optionId(i), type: "button", role: "option", "aria-selected": i === activeIndex, className: cx("mw-chip", { "mw-chip--active": i === activeIndex }), onMouseEnter: () => onHover?.(i), onClick: () => onPick(s.value), title: s.placetype, children: s.label ?? s.value }, `${s.value}-${i}`)))] }));
8
+ }
9
+ //# sourceMappingURL=PlaceAutocomplete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaceAutocomplete.js","sourceRoot":"","sources":["../../map/PlaceAutocomplete.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAoBpC,8BAA8B;AAC9B,MAAM,UAAU,iBAAiB,CAAC,EACjC,WAAW,EACX,WAAW,EACX,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,OAAO,GAAG,eAAe,GACD;IACxB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEzC,OAAO,CACN,eAAK,SAAS,EAAC,iBAAiB,EAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAC,SAAS,gBAAY,mBAAmB,aAC5F,eAAM,SAAS,EAAC,wBAAwB,YAAE,OAAO,GAAQ,EACxD,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,iBAEC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EACf,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,mBACE,CAAC,KAAK,WAAW,EAChC,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,iBAAiB,EAAE,CAAC,KAAK,WAAW,EAAE,CAAC,EAClE,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAChC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAC9B,KAAK,EAAE,CAAC,CAAC,SAAS,YAEjB,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAVd,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAWd,CACT,CAAC,IACG,CACN,CAAA;AACF,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<PlaceMarker>` — the resolved-place pin, as a declarative `react-map-gl/maplibre` `<Marker>`. This
7
+ * replaces the old imperative `new maplibre.Marker(...).setLngLat(...).addTo(map)` (+ the manual
8
+ * `markerRef.current.remove()` teardown) from the demo's redraw effect: mounting/unmounting the marker
9
+ * is now React's job, keyed on the resolved candidate. Renders as a child of `<DemoMap>`.
10
+ *
11
+ * NODE-IMPORT SAFETY: imports `react-map-gl/maplibre` at module scope, so it is reachable ONLY through
12
+ * the `@mailwoman/react/map` subpath, never the package root.
13
+ */
14
+ import type { ReactNode } from "react";
15
+ export interface PlaceMarkerProps {
16
+ /** Marker longitude. */
17
+ longitude: number;
18
+ /** Marker latitude. */
19
+ latitude: number;
20
+ /** Pin color. @default the house pink. */
21
+ color?: string;
22
+ /** Which part of the marker sits on the coordinate. @default "center" (a symmetric dot). */
23
+ anchor?: "center" | "top" | "bottom" | "left" | "right";
24
+ }
25
+ /** A single resolved-place marker. Wraps `react-map-gl`'s `<Marker>` with the demo's default color. */
26
+ export declare function PlaceMarker({ longitude, latitude, color, anchor, }: PlaceMarkerProps): ReactNode;
27
+ //# sourceMappingURL=PlaceMarker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaceMarker.d.ts","sourceRoot":"","sources":["../../map/PlaceMarker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,WAAW,gBAAgB;IAChC,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4FAA4F;IAC5F,MAAM,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;CACvD;AAED,uGAAuG;AACvG,wBAAgB,WAAW,CAAC,EAC3B,SAAS,EACT,QAAQ,EACR,KAAoB,EACpB,MAAiB,GACjB,EAAE,gBAAgB,GAAG,SAAS,CAE9B"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Marker } from "react-map-gl/maplibre";
3
+ /** The house pink the demo has always drawn the resolved-place marker in. */
4
+ const MARKER_COLOR = "#e0367c";
5
+ /** A single resolved-place marker. Wraps `react-map-gl`'s `<Marker>` with the demo's default color. */
6
+ export function PlaceMarker({ longitude, latitude, color = MARKER_COLOR, anchor = "center", }) {
7
+ return _jsx(Marker, { longitude: longitude, latitude: latitude, color: color, anchor: anchor });
8
+ }
9
+ //# sourceMappingURL=PlaceMarker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaceMarker.js","sourceRoot":"","sources":["../../map/PlaceMarker.tsx"],"names":[],"mappings":";AAeA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,6EAA6E;AAC7E,MAAM,YAAY,GAAG,SAAS,CAAA;AAa9B,uGAAuG;AACvG,MAAM,UAAU,WAAW,CAAC,EAC3B,SAAS,EACT,QAAQ,EACR,KAAK,GAAG,YAAY,EACpB,MAAM,GAAG,QAAQ,GACC;IAClB,OAAO,KAAC,MAAM,IAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAI,CAAA;AAC1F,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<ResolvedPlaceLayers>` — the drop-in that renders a whole {@link MapPlaceRenderSpec} as `<DemoMap>`
7
+ * children: the marker(s), the outline, and (optionally) the camera move. This is the declarative
8
+ * replacement for the demo's imperative marker/bbox/camera redraw effect — a consumer computes the spec
9
+ * with `useMapPlaceRender(place)` and drops `<ResolvedPlaceLayers spec={spec} />` inside `<DemoMap>`.
10
+ *
11
+ * `spec = null` (no result / no candidate) renders nothing, which also unmounts the previous marker +
12
+ * outline — the teardown the old effect did by hand (`markerRef.remove()`, `clearBbox`) is now just
13
+ * React unmounting. NODE-IMPORT SAFETY: pulls the map components — `@mailwoman/react/map` only.
14
+ */
15
+ import type { ReactNode } from "react";
16
+ import type { MapPlaceRenderSpec } from "./place-render.ts";
17
+ export interface ResolvedPlaceLayersProps {
18
+ /** The render spec (from {@link useMapPlaceRender}); `null` renders nothing. */
19
+ spec: MapPlaceRenderSpec | null;
20
+ /**
21
+ * Apply the computed camera target via {@link ResultCamera}. @default true. Set false when the consumer drives the
22
+ * camera itself (e.g. a controlled `<DemoMap viewState>` fed by {@link cameraToViewState}).
23
+ */
24
+ applyCamera?: boolean;
25
+ /** Animate the camera move. Forwarded to {@link ResultCamera}. @default true */
26
+ animateCamera?: boolean;
27
+ /** Source/layer id prefix for the outline. @default "mw-result" */
28
+ outlineId?: string;
29
+ /** Marker color. @default the house pink. */
30
+ markerColor?: string;
31
+ }
32
+ /** Render the marker(s), outline, and (optional) camera move for one resolved place. */
33
+ export declare function ResolvedPlaceLayers({ spec, applyCamera, animateCamera, outlineId, markerColor, }: ResolvedPlaceLayersProps): ReactNode;
34
+ //# sourceMappingURL=ResolvedPlaceLayers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResolvedPlaceLayers.d.ts","sourceRoot":"","sources":["../../map/ResolvedPlaceLayers.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAK3D,MAAM,WAAW,wBAAwB;IACxC,gFAAgF;IAChF,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAC/B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,EACnC,IAAI,EACJ,WAAkB,EAClB,aAAoB,EACpB,SAAS,EACT,WAAW,GACX,EAAE,wBAAwB,GAAG,SAAS,CAiBtC"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { PlaceMarker } from "./PlaceMarker.js";
3
+ import { ResultCamera } from "./ResultCamera.js";
4
+ import { ResultOverlay } from "./ResultOverlay.js";
5
+ /** Render the marker(s), outline, and (optional) camera move for one resolved place. */
6
+ export function ResolvedPlaceLayers({ spec, applyCamera = true, animateCamera = true, outlineId, markerColor, }) {
7
+ if (!spec)
8
+ return null;
9
+ return (_jsxs(_Fragment, { children: [spec.markers.map(([longitude, latitude], index) => (_jsx(PlaceMarker, { longitude: longitude, latitude: latitude, color: markerColor }, `${longitude},${latitude},${index}`))), _jsx(ResultOverlay, { outline: spec.outline, id: outlineId, color: markerColor }), applyCamera ? _jsx(ResultCamera, { target: spec.camera, animate: animateCamera }) : null] }));
10
+ }
11
+ //# sourceMappingURL=ResolvedPlaceLayers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResolvedPlaceLayers.js","sourceRoot":"","sources":["../../map/ResolvedPlaceLayers.tsx"],"names":[],"mappings":";AAkBA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAqB,CAAA;AAkBnD,wFAAwF;AACxF,MAAM,UAAU,mBAAmB,CAAC,EACnC,IAAI,EACJ,WAAW,GAAG,IAAI,EAClB,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,WAAW,GACe;IAC1B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IAEtB,OAAO,CACN,8BACE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CACnD,KAAC,WAAW,IAEX,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,WAAW,IAHb,GAAG,SAAS,IAAI,QAAQ,IAAI,KAAK,EAAE,CAIvC,CACF,CAAC,EACF,KAAC,aAAa,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,GAAI,EAC1E,WAAW,CAAC,CAAC,CAAC,KAAC,YAAY,IAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,GAAI,CAAC,CAAC,CAAC,IAAI,IACjF,CACH,CAAA;AACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<ResultCamera>` — applies the {@link MapCameraTarget} a {@link MapPlaceRenderSpec} computes, by
7
+ * animating the live map to it. This is the ONE deliberately-imperative touch in the phase-2 overlays,
8
+ * and it is justified: maplibre exposes animated camera moves (`flyTo`) and viewport-fitting
9
+ * (`fitBounds`, which needs the map's PIXEL dimensions + padding) ONLY imperatively — react-map-gl has
10
+ * no declarative prop for "animate to these bounds". It is applied the v8-idiomatic way, through
11
+ * `useMap()` (exactly as `DashboardMap`/`GeoJSONClipboardLayer` reach the map), never a threaded handle.
12
+ *
13
+ * A consumer that prefers a hard, declarative jump can instead feed the target through
14
+ * {@link cameraToViewState} into a controlled `<DemoMap viewState>` and skip this component — the
15
+ * `center` case has that declarative path; only `bounds` strictly requires this. Renders nothing.
16
+ *
17
+ * `target` is expected to be the STABLE, memoized `camera` off a `useMapPlaceRender` spec, so listing it
18
+ * as the effect dependency re-runs the camera move exactly when the resolved place changes — no
19
+ * value-key dance, no dependency-lint suppression.
20
+ */
21
+ import { type ReactNode } from "react";
22
+ import type { MapCameraTarget } from "./place-render.ts";
23
+ export interface ResultCameraProps {
24
+ /** The camera target to animate to. `null` leaves the camera untouched (no result yet). */
25
+ target: MapCameraTarget | null;
26
+ /**
27
+ * Animate (`flyTo`/`fitBounds`) vs jump. @default true. When false, a `center` target jumps with `jumpTo`; a `bounds`
28
+ * target still uses `fitBounds` (no instantaneous fit exists) but with `duration: 0`.
29
+ */
30
+ animate?: boolean;
31
+ }
32
+ /** Drive the live map to `target`. No DOM of its own — it is a behavior mounted as a `<Map>` child. */
33
+ export declare function ResultCamera({ target, animate }: ResultCameraProps): ReactNode;
34
+ //# sourceMappingURL=ResultCamera.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultCamera.d.ts","sourceRoot":"","sources":["../../map/ResultCamera.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,OAAO,CAAA;AAGjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,MAAM,WAAW,iBAAiB;IACjC,2FAA2F;IAC3F,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAc,EAAE,EAAE,iBAAiB,GAAG,SAAS,CAsBrF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<ResultCamera>` — applies the {@link MapCameraTarget} a {@link MapPlaceRenderSpec} computes, by
7
+ * animating the live map to it. This is the ONE deliberately-imperative touch in the phase-2 overlays,
8
+ * and it is justified: maplibre exposes animated camera moves (`flyTo`) and viewport-fitting
9
+ * (`fitBounds`, which needs the map's PIXEL dimensions + padding) ONLY imperatively — react-map-gl has
10
+ * no declarative prop for "animate to these bounds". It is applied the v8-idiomatic way, through
11
+ * `useMap()` (exactly as `DashboardMap`/`GeoJSONClipboardLayer` reach the map), never a threaded handle.
12
+ *
13
+ * A consumer that prefers a hard, declarative jump can instead feed the target through
14
+ * {@link cameraToViewState} into a controlled `<DemoMap viewState>` and skip this component — the
15
+ * `center` case has that declarative path; only `bounds` strictly requires this. Renders nothing.
16
+ *
17
+ * `target` is expected to be the STABLE, memoized `camera` off a `useMapPlaceRender` spec, so listing it
18
+ * as the effect dependency re-runs the camera move exactly when the resolved place changes — no
19
+ * value-key dance, no dependency-lint suppression.
20
+ */
21
+ import { useEffect } from "react";
22
+ import { useMap } from "react-map-gl/maplibre";
23
+ /** Drive the live map to `target`. No DOM of its own — it is a behavior mounted as a `<Map>` child. */
24
+ export function ResultCamera({ target, animate = true }) {
25
+ const map = useMap();
26
+ useEffect(() => {
27
+ const instance = map.current?.getMap();
28
+ if (!instance || !target)
29
+ return;
30
+ if (target.kind === "center") {
31
+ if (animate) {
32
+ instance.flyTo({ center: target.center, zoom: target.zoom });
33
+ }
34
+ else {
35
+ instance.jumpTo({ center: target.center, zoom: target.zoom });
36
+ }
37
+ return;
38
+ }
39
+ instance.fitBounds(target.bounds, { padding: target.padding, duration: animate ? undefined : 0 });
40
+ }, [map, target, animate]);
41
+ return null;
42
+ }
43
+ //# sourceMappingURL=ResultCamera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultCamera.js","sourceRoot":"","sources":["../../map/ResultCamera.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAkB,SAAS,EAAE,MAAM,OAAO,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAc9C,uGAAuG;AACvG,MAAM,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,EAAqB;IACzE,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IAEpB,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAA;QAEtC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM;YAAE,OAAM;QAEhC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;YAC7D,CAAC;iBAAM,CAAC;gBACP,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9D,CAAC;YAED,OAAM;QACP,CAAC;QAED,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAClG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAE1B,OAAO,IAAI,CAAA;AACZ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<ResultOverlay>` — the resolved-place outline (crisp admin polygon, or an approximate/exact-radius
7
+ * circle) as a declarative `<Source>` + fill/line `<Layer>`s. This replaces the demo's imperative
8
+ * `setPlaceOutline` / `drawApproxCircle` / `drawPlaceGeometry` / `clearBbox` helpers and their
9
+ * `whenStyleReady` gate: react-map-gl owns the "add source/layer once the style is loaded, remove on
10
+ * unmount" lifecycle, so the hand-rolled `isStyleLoaded()` / `styledata` races disappear.
11
+ *
12
+ * Pass the `outline` straight from a {@link MapPlaceRenderSpec}; a `null` outline renders nothing (the
13
+ * bare-point case). NODE-IMPORT SAFETY: imports `react-map-gl/maplibre` — `@mailwoman/react/map` only.
14
+ */
15
+ import type { ReactNode } from "react";
16
+ import type { PlaceGeometry } from "./geometry.ts";
17
+ export interface ResultOverlayProps {
18
+ /** The outline geometry to draw, or `null` to draw nothing (the bare-point result). */
19
+ outline: PlaceGeometry | null;
20
+ /** Source/layer id prefix — override to render more than one outline on a map. @default "mw-result" */
21
+ id?: string;
22
+ /** Fill color. @default the house pink. */
23
+ color?: string;
24
+ /** Fill opacity. @default 0.12 */
25
+ fillOpacity?: number;
26
+ /** Outline stroke width (px). @default 2 */
27
+ lineWidth?: number;
28
+ }
29
+ /**
30
+ * Render the resolved-place outline. One geojson `<Source>` feeds a translucent fill `<Layer>` and a solid line
31
+ * `<Layer>` — the same two layers the imperative `setPlaceOutline` created, now declarative and self-cleaning.
32
+ */
33
+ export declare function ResultOverlay({ outline, id, color, fillOpacity, lineWidth, }: ResultOverlayProps): ReactNode;
34
+ //# sourceMappingURL=ResultOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultOverlay.d.ts","sourceRoot":"","sources":["../../map/ResultOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAKlD,MAAM,WAAW,kBAAkB;IAClC,uFAAuF;IACvF,OAAO,EAAE,aAAa,GAAG,IAAI,CAAA;IAC7B,uGAAuG;IACvG,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC7B,OAAO,EACP,EAAgB,EAChB,KAAqB,EACrB,WAAkB,EAClB,SAAa,GACb,EAAE,kBAAkB,GAAG,SAAS,CAchC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Layer, Source } from "react-map-gl/maplibre";
3
+ /** The house pink, matched to {@link PlaceMarker}. */
4
+ const OUTLINE_COLOR = "#e0367c";
5
+ /**
6
+ * Render the resolved-place outline. One geojson `<Source>` feeds a translucent fill `<Layer>` and a solid line
7
+ * `<Layer>` — the same two layers the imperative `setPlaceOutline` created, now declarative and self-cleaning.
8
+ */
9
+ export function ResultOverlay({ outline, id = "mw-result", color = OUTLINE_COLOR, fillOpacity = 0.12, lineWidth = 2, }) {
10
+ if (!outline)
11
+ return null;
12
+ const data = {
13
+ type: "FeatureCollection",
14
+ features: [{ type: "Feature", geometry: outline, properties: {} }],
15
+ };
16
+ return (_jsxs(Source, { id: id, type: "geojson", data: data, children: [_jsx(Layer, { id: `${id}-fill`, type: "fill", paint: { "fill-color": color, "fill-opacity": fillOpacity } }), _jsx(Layer, { id: `${id}-line`, type: "line", paint: { "line-color": color, "line-width": lineWidth } })] }));
17
+ }
18
+ //# sourceMappingURL=ResultOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultOverlay.js","sourceRoot":"","sources":["../../map/ResultOverlay.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAIrD,sDAAsD;AACtD,MAAM,aAAa,GAAG,SAAS,CAAA;AAe/B;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAC7B,OAAO,EACP,EAAE,GAAG,WAAW,EAChB,KAAK,GAAG,aAAa,EACrB,WAAW,GAAG,IAAI,EAClB,SAAS,GAAG,CAAC,GACO;IACpB,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAEzB,MAAM,IAAI,GAAG;QACZ,IAAI,EAAE,mBAA4B;QAClC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;KAC3E,CAAA;IAED,OAAO,CACN,MAAC,MAAM,IAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAC,SAAS,EAAC,IAAI,EAAE,IAAI,aACxC,KAAC,KAAK,IAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,GAAI,EACpG,KAAC,KAAK,IAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,GAAI,IACxF,CACT,CAAA;AACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<ResultPanel>` — the demo's parse+resolve result block, assembled from the SHARED pipeline
7
+ * presentational units (it does not re-implement any of them): `KindBadge`, `ComponentTable`,
8
+ * `ResolvedPlace`, `CandidatePicker`, plus the `CopyButton` + `buildParsePayload` copy affordance. This
9
+ * is the standalone, story-testable unit the demo's floating panel renders (the map analogue of the
10
+ * result block PipelineExplorer inlines), so `GeocoderDemo` composes ONE panel instead of duplicating
11
+ * the marker/table/candidate glue. Heavy host visualizers (span highlight, tree, timing) slot in via
12
+ * `extras`; the no-resolve diagnostic via `failure`.
13
+ *
14
+ * NODE-SAFE: pure React + the shared units, no maplibre.
15
+ */
16
+ import type { ReactNode } from "react";
17
+ import type { ParseResult, ResolvedPlaceView } from "../pipeline/types.ts";
18
+ export interface ResultPanelProps {
19
+ /** The parse+resolve result to render. */
20
+ result: ParseResult;
21
+ /** The selected candidate (falls back to the first), used for the resolved-place detail + copy payload. */
22
+ selectedCandidate: ResolvedPlaceView | null;
23
+ /** The selected candidate index, for the picker's active state. */
24
+ selectedCandidateIndex: number;
25
+ /** Fired when a candidate in the picker is chosen. */
26
+ onSelectCandidate: (index: number) => void;
27
+ /** Host-injected heavy visualizers (span highlight, tree, timing, …), rendered from the result. */
28
+ extras?: (result: ParseResult) => ReactNode;
29
+ /** Host-injected no-resolve diagnostic, rendered when nothing resolved. */
30
+ failure?: (result: ParseResult) => ReactNode;
31
+ }
32
+ /** The composed result block for the geocoder demo. */
33
+ export declare function ResultPanel({ result, selectedCandidate, selectedCandidateIndex, onSelectCandidate, extras, failure, }: ResultPanelProps): ReactNode;
34
+ //# sourceMappingURL=ResultPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultPanel.d.ts","sourceRoot":"","sources":["../../map/ResultPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE1E,MAAM,WAAW,gBAAgB;IAChC,0CAA0C;IAC1C,MAAM,EAAE,WAAW,CAAA;IACnB,2GAA2G;IAC3G,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC3C,mEAAmE;IACnE,sBAAsB,EAAE,MAAM,CAAA;IAC9B,sDAAsD;IACtD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,mGAAmG;IACnG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAA;IAC3C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAA;CAC5C;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,EAC3B,MAAM,EACN,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,OAAO,GACP,EAAE,gBAAgB,GAAG,SAAS,CAkC9B"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { CopyButton } from "../common/CopyButton.js";
3
+ import { KindBadge } from "../common/KindBadge.js";
4
+ import { CandidatePicker } from "../pipeline/CandidatePicker.js";
5
+ import { ComponentTable } from "../pipeline/ComponentTable.js";
6
+ import { buildParsePayload } from "../pipeline/copy.js";
7
+ import { ResolvedPlace } from "../pipeline/ResolvedPlace.js";
8
+ /** The composed result block for the geocoder demo. */
9
+ export function ResultPanel({ result, selectedCandidate, selectedCandidateIndex, onSelectCandidate, extras, failure, }) {
10
+ return (_jsxs("div", { className: "mw-result", children: [_jsxs("div", { className: "mw-result__header", children: [_jsx("h2", { children: "Parsed components" }), _jsx(CopyButton, { value: () => buildParsePayload(result, selectedCandidate), label: "Copy JSON", copiedLabel: "\u2713 Copied" })] }), result.kindResult ? _jsx(KindBadge, { kindResult: result.kindResult }) : null, extras ? extras(result) : null, _jsx(ComponentTable, { nodes: result.nodes }), selectedCandidate ? (_jsxs(_Fragment, { children: [_jsx(ResolvedPlace, { place: selectedCandidate, dualRoles: result.dualRoles }), result.candidates.length > 1 ? (_jsx(CandidatePicker, { candidates: result.candidates, selectedIndex: selectedCandidateIndex, onSelect: onSelectCandidate })) : null] })) : failure ? (failure(result)) : null] }));
11
+ }
12
+ //# sourceMappingURL=ResultPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultPanel.js","sourceRoot":"","sources":["../../map/ResultPanel.tsx"],"names":[],"mappings":";AAkBA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAA0B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAyB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAiC,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAAgC,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA+B,CAAA;AAkB7D,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,EAC3B,MAAM,EACN,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,OAAO,GACW;IAClB,OAAO,CACN,eAAK,SAAS,EAAC,WAAW,aACzB,eAAK,SAAS,EAAC,mBAAmB,aACjC,6CAA0B,EAC1B,KAAC,UAAU,IACV,KAAK,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACzD,KAAK,EAAC,WAAW,EACjB,WAAW,EAAC,eAAU,GACrB,IACG,EAEL,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,UAAU,EAAE,MAAM,CAAC,UAAU,GAAI,CAAC,CAAC,CAAC,IAAI,EAEvE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAE/B,KAAC,cAAc,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAI,EAEtC,iBAAiB,CAAC,CAAC,CAAC,CACpB,8BACC,KAAC,aAAa,IAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,GAAI,EACvE,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC/B,KAAC,eAAe,IACf,UAAU,EAAE,MAAM,CAAC,UAAU,EAC7B,aAAa,EAAE,sBAAsB,EACrC,QAAQ,EAAE,iBAAiB,GAC1B,CACF,CAAC,CAAC,CAAC,IAAI,IACN,CACH,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACb,OAAO,CAAC,MAAM,CAAC,CACf,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAA;AACF,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `<VersionPicker>` — the model-version `<select>` from the demo's control panel (`_app.tsx:1230-1254`),
7
+ * as a dumb presentational unit: the available bundles + current selection come in as props, the choice
8
+ * goes out through `onSelect`. No load state, no manifest fetch — the host (via `useDemoRuntime`) owns
9
+ * that. Renders nothing when there is fewer than two versions to choose between.
10
+ *
11
+ * NODE-SAFE: pure React + a `<select>`, no maplibre. It rides the `@mailwoman/react/map` subpath only
12
+ * because it is a demo-specific control, not because it needs WebGL.
13
+ */
14
+ import type { ReactNode } from "react";
15
+ import type { DemoVersionOption } from "./types.ts";
16
+ export interface VersionPickerProps {
17
+ /** The selectable model bundles. */
18
+ versions: ReadonlyArray<DemoVersionOption>;
19
+ /** The currently-selected version tag. */
20
+ selected: string | null;
21
+ /** Fired with the chosen version tag. */
22
+ onSelect: (version: string) => void;
23
+ /** Disable the control (e.g. while a parse is running). */
24
+ disabled?: boolean;
25
+ /** Field label. @default "Model version" */
26
+ label?: string;
27
+ }
28
+ /** The model-version selector. Renders `null` when there is nothing meaningful to pick. */
29
+ export declare function VersionPicker({ versions, selected, onSelect, disabled, label, }: VersionPickerProps): ReactNode;
30
+ //# sourceMappingURL=VersionPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionPicker.d.ts","sourceRoot":"","sources":["../../map/VersionPicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,WAAW,kBAAkB;IAClC,oCAAoC;IACpC,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAA;IAC1C,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,yCAAyC;IACzC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,EAC7B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,KAAuB,GACvB,EAAE,kBAAkB,GAAG,SAAS,CAuBhC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** The model-version selector. Renders `null` when there is nothing meaningful to pick. */
3
+ export function VersionPicker({ versions, selected, onSelect, disabled, label = "Model version", }) {
4
+ if (versions.length < 2)
5
+ return null;
6
+ return (_jsxs("div", { className: "mw-demo-control", children: [_jsx("label", { className: "mw-demo-control__label", htmlFor: "mw-demo-version", children: label }), _jsx("select", { id: "mw-demo-version", className: "mw-demo-control__select", value: selected ?? "", onChange: (e) => onSelect(e.target.value), disabled: disabled, children: versions.map((v) => (_jsx("option", { value: v.version, children: v.label ?? v.version }, v.version))) })] }));
7
+ }
8
+ //# sourceMappingURL=VersionPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionPicker.js","sourceRoot":"","sources":["../../map/VersionPicker.tsx"],"names":[],"mappings":";AA+BA,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,EAC7B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,KAAK,GAAG,eAAe,GACH;IACpB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEpC,OAAO,CACN,eAAK,SAAS,EAAC,iBAAiB,aAC/B,gBAAO,SAAS,EAAC,wBAAwB,EAAC,OAAO,EAAC,iBAAiB,YACjE,KAAK,GACC,EACR,iBACC,EAAE,EAAC,iBAAiB,EACpB,SAAS,EAAC,yBAAyB,EACnC,KAAK,EAAE,QAAQ,IAAI,EAAE,EACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,QAAQ,EAAE,QAAQ,YAEjB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACpB,iBAAwB,KAAK,EAAE,CAAC,CAAC,OAAO,YACtC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,IADT,CAAC,CAAC,OAAO,CAEb,CACT,CAAC,GACM,IACJ,CACN,CAAA;AACF,CAAC"}