@mailwoman/react 10.0.0 → 10.2.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 (389) hide show
  1. package/README.md +18 -16
  2. package/fonts.css +97 -22
  3. package/lib/common/About.tsx +10 -10
  4. package/lib/common/ClientOnly.tsx +2 -14
  5. package/lib/common/CopyButton.tsx +9 -3
  6. package/lib/common/LoadingIndicator.tsx +13 -5
  7. package/lib/common/PresetChips.tsx +11 -8
  8. package/lib/common/confidence-tiers.ts +8 -7
  9. package/lib/common/cx.ts +3 -1
  10. package/lib/common/text-tokens.ts +10 -13
  11. package/lib/common/useBuildInfo.ts +54 -0
  12. package/lib/common/useClipboard.ts +2 -11
  13. package/lib/common.ts +22 -0
  14. package/lib/index.ts +27 -18
  15. package/lib/map/AppIdentity.tsx +89 -0
  16. package/lib/map/CompareToggle.tsx +8 -31
  17. package/lib/map/DebugInfo.tsx +75 -0
  18. package/lib/map/Geocoder.tsx +65 -50
  19. package/lib/map/GeocoderControls.tsx +425 -141
  20. package/lib/map/GraticuleLayer.tsx +56 -0
  21. package/lib/map/MapCanvas.tsx +26 -13
  22. package/lib/map/MapChipRow.tsx +4 -8
  23. package/lib/map/MapCompass.tsx +18 -25
  24. package/lib/map/MapControlStack.tsx +11 -10
  25. package/lib/map/MapFooter.tsx +5 -17
  26. package/lib/map/MapProgressBar.tsx +10 -13
  27. package/lib/map/MapSearchBar.tsx +31 -17
  28. package/lib/map/MapSheet.tsx +24 -15
  29. package/lib/map/OverlayLayers.tsx +14 -3
  30. package/lib/map/PlaceAutocomplete.tsx +12 -21
  31. package/lib/map/PlaceMarker.tsx +10 -4
  32. package/lib/map/ResolvedPlaceLayers.tsx +14 -15
  33. package/lib/map/ResultCamera.tsx +10 -31
  34. package/lib/map/ResultOverlay.tsx +14 -16
  35. package/lib/map/ResultPanel.tsx +1 -20
  36. package/lib/map/VersionPicker.tsx +10 -19
  37. package/lib/map/fake-runtime.ts +46 -19
  38. package/lib/map/geometry.ts +14 -47
  39. package/lib/map/graticule.ts +80 -0
  40. package/lib/map/map-debug.ts +4 -2
  41. package/lib/map/place-render.ts +30 -62
  42. package/lib/map/types.ts +57 -116
  43. package/lib/map/useCompareState.ts +5 -4
  44. package/lib/map/useGeocode.ts +7 -5
  45. package/lib/map/useMapBearing.ts +13 -13
  46. package/lib/map/useMapLabelPick.ts +21 -30
  47. package/lib/map/useMapPlaceRender.ts +3 -7
  48. package/lib/map/usePlaceAutocomplete.ts +44 -50
  49. package/lib/map.ts +92 -0
  50. package/lib/pipeline/CandidatePicker.tsx +13 -5
  51. package/lib/pipeline/ConfidenceCell.tsx +2 -2
  52. package/lib/pipeline/FailureDiagnostic.tsx +8 -2
  53. package/lib/pipeline/PipelineExplorer.tsx +6 -3
  54. package/lib/pipeline/QueryForm.tsx +5 -2
  55. package/lib/pipeline/ResolvedPlace.tsx +2 -2
  56. package/lib/pipeline/SpanHighlight.tsx +7 -5
  57. package/lib/pipeline/TimingPanel.tsx +1 -1
  58. package/lib/pipeline/TreeView.tsx +2 -2
  59. package/lib/pipeline/copy.ts +22 -25
  60. package/lib/pipeline/presets.ts +15 -13
  61. package/lib/pipeline/types.ts +20 -17
  62. package/lib/pipeline/useParsePipeline.ts +16 -13
  63. package/lib/pipeline.ts +36 -0
  64. package/lib/poi/AbstainPanel.tsx +1 -1
  65. package/lib/poi/LiveResultsBlock.tsx +2 -1
  66. package/lib/poi/POIExplorer.tsx +29 -17
  67. package/lib/poi/QueryInput.tsx +1 -1
  68. package/lib/poi/SubjectPanel.tsx +4 -3
  69. package/lib/poi/runtime.ts +14 -16
  70. package/lib/poi/types.ts +58 -47
  71. package/lib/poi/usePOISearch.ts +91 -82
  72. package/lib/poi.ts +40 -0
  73. package/lib/runtime/useReleaseRuntime.ts +122 -90
  74. package/lib/search/SearchModal.tsx +478 -0
  75. package/lib/search/search.css +282 -0
  76. package/lib/search/types.ts +68 -0
  77. package/lib/search.ts +11 -0
  78. package/out/common/About.d.ts +6 -6
  79. package/out/common/About.d.ts.map +1 -1
  80. package/out/common/About.js +1 -1
  81. package/out/common/About.js.map +1 -1
  82. package/out/common/ClientOnly.d.ts +2 -11
  83. package/out/common/ClientOnly.d.ts.map +1 -1
  84. package/out/common/ClientOnly.js +1 -13
  85. package/out/common/ClientOnly.js.map +1 -1
  86. package/out/common/CopyButton.d.ts +9 -3
  87. package/out/common/CopyButton.d.ts.map +1 -1
  88. package/out/common/CopyButton.js.map +1 -1
  89. package/out/common/LoadingIndicator.d.ts +13 -5
  90. package/out/common/LoadingIndicator.d.ts.map +1 -1
  91. package/out/common/LoadingIndicator.js.map +1 -1
  92. package/out/common/PresetChips.d.ts +11 -8
  93. package/out/common/PresetChips.d.ts.map +1 -1
  94. package/out/common/PresetChips.js.map +1 -1
  95. package/out/common/confidence-tiers.d.ts +8 -7
  96. package/out/common/confidence-tiers.d.ts.map +1 -1
  97. package/out/common/confidence-tiers.js +7 -6
  98. package/out/common/confidence-tiers.js.map +1 -1
  99. package/out/common/cx.d.ts +3 -1
  100. package/out/common/cx.d.ts.map +1 -1
  101. package/out/common/cx.js +3 -1
  102. package/out/common/cx.js.map +1 -1
  103. package/out/common/text-tokens.d.ts +6 -11
  104. package/out/common/text-tokens.d.ts.map +1 -1
  105. package/out/common/text-tokens.js +6 -3
  106. package/out/common/text-tokens.js.map +1 -1
  107. package/out/common/useBuildInfo.d.ts +27 -0
  108. package/out/common/useBuildInfo.d.ts.map +1 -0
  109. package/out/common/useBuildInfo.js +32 -0
  110. package/out/common/useBuildInfo.js.map +1 -0
  111. package/out/common/useClipboard.d.ts +1 -3
  112. package/out/common/useClipboard.d.ts.map +1 -1
  113. package/out/common/useClipboard.js +2 -11
  114. package/out/common/useClipboard.js.map +1 -1
  115. package/out/common.d.ts +22 -0
  116. package/out/common.d.ts.map +1 -0
  117. package/out/common.js +15 -0
  118. package/out/common.js.map +1 -0
  119. package/out/index.d.ts +26 -16
  120. package/out/index.d.ts.map +1 -1
  121. package/out/index.js +21 -15
  122. package/out/index.js.map +1 -1
  123. package/out/map/AppIdentity.d.ts +46 -0
  124. package/out/map/AppIdentity.d.ts.map +1 -0
  125. package/out/map/AppIdentity.js +16 -0
  126. package/out/map/AppIdentity.js.map +1 -0
  127. package/out/map/CompareToggle.d.ts +8 -31
  128. package/out/map/CompareToggle.d.ts.map +1 -1
  129. package/out/map/CompareToggle.js +4 -1
  130. package/out/map/CompareToggle.js.map +1 -1
  131. package/out/map/DebugInfo.d.ts +27 -0
  132. package/out/map/DebugInfo.d.ts.map +1 -0
  133. package/out/map/DebugInfo.js +36 -0
  134. package/out/map/DebugInfo.js.map +1 -0
  135. package/out/map/Geocoder.d.ts +41 -30
  136. package/out/map/Geocoder.d.ts.map +1 -1
  137. package/out/map/Geocoder.js +23 -37
  138. package/out/map/Geocoder.js.map +1 -1
  139. package/out/map/GeocoderControls.d.ts +15 -44
  140. package/out/map/GeocoderControls.d.ts.map +1 -1
  141. package/out/map/GeocoderControls.js +250 -39
  142. package/out/map/GeocoderControls.js.map +1 -1
  143. package/out/map/GraticuleLayer.d.ts +30 -0
  144. package/out/map/GraticuleLayer.d.ts.map +1 -0
  145. package/out/map/GraticuleLayer.js +25 -0
  146. package/out/map/GraticuleLayer.js.map +1 -0
  147. package/out/map/MapCanvas.d.ts +26 -13
  148. package/out/map/MapCanvas.d.ts.map +1 -1
  149. package/out/map/MapCanvas.js +5 -2
  150. package/out/map/MapCanvas.js.map +1 -1
  151. package/out/map/MapChipRow.d.ts +4 -8
  152. package/out/map/MapChipRow.d.ts.map +1 -1
  153. package/out/map/MapChipRow.js.map +1 -1
  154. package/out/map/MapCompass.d.ts +14 -21
  155. package/out/map/MapCompass.d.ts.map +1 -1
  156. package/out/map/MapCompass.js +5 -1
  157. package/out/map/MapCompass.js.map +1 -1
  158. package/out/map/MapControlStack.d.ts +11 -10
  159. package/out/map/MapControlStack.d.ts.map +1 -1
  160. package/out/map/MapControlStack.js +4 -1
  161. package/out/map/MapControlStack.js.map +1 -1
  162. package/out/map/MapFooter.d.ts +5 -16
  163. package/out/map/MapFooter.d.ts.map +1 -1
  164. package/out/map/MapFooter.js +0 -14
  165. package/out/map/MapFooter.js.map +1 -1
  166. package/out/map/MapProgressBar.d.ts +10 -13
  167. package/out/map/MapProgressBar.d.ts.map +1 -1
  168. package/out/map/MapProgressBar.js.map +1 -1
  169. package/out/map/MapSearchBar.d.ts +16 -17
  170. package/out/map/MapSearchBar.d.ts.map +1 -1
  171. package/out/map/MapSearchBar.js +6 -0
  172. package/out/map/MapSearchBar.js.map +1 -1
  173. package/out/map/MapSheet.d.ts +15 -12
  174. package/out/map/MapSheet.d.ts.map +1 -1
  175. package/out/map/MapSheet.js +8 -12
  176. package/out/map/MapSheet.js.map +1 -1
  177. package/out/map/OverlayLayers.d.ts +8 -2
  178. package/out/map/OverlayLayers.d.ts.map +1 -1
  179. package/out/map/OverlayLayers.js +3 -3
  180. package/out/map/OverlayLayers.js.map +1 -1
  181. package/out/map/PlaceAutocomplete.d.ts +12 -21
  182. package/out/map/PlaceAutocomplete.d.ts.map +1 -1
  183. package/out/map/PlaceAutocomplete.js +2 -1
  184. package/out/map/PlaceAutocomplete.js.map +1 -1
  185. package/out/map/PlaceMarker.d.ts +10 -4
  186. package/out/map/PlaceMarker.d.ts.map +1 -1
  187. package/out/map/PlaceMarker.js +3 -1
  188. package/out/map/PlaceMarker.js.map +1 -1
  189. package/out/map/ResolvedPlaceLayers.d.ts +14 -15
  190. package/out/map/ResolvedPlaceLayers.d.ts.map +1 -1
  191. package/out/map/ResolvedPlaceLayers.js +1 -1
  192. package/out/map/ResolvedPlaceLayers.js.map +1 -1
  193. package/out/map/ResultCamera.d.ts +10 -31
  194. package/out/map/ResultCamera.d.ts.map +1 -1
  195. package/out/map/ResultCamera.js +3 -28
  196. package/out/map/ResultCamera.js.map +1 -1
  197. package/out/map/ResultOverlay.d.ts +14 -16
  198. package/out/map/ResultOverlay.d.ts.map +1 -1
  199. package/out/map/ResultOverlay.js +1 -2
  200. package/out/map/ResultOverlay.js.map +1 -1
  201. package/out/map/ResultPanel.d.ts +1 -20
  202. package/out/map/ResultPanel.d.ts.map +1 -1
  203. package/out/map/ResultPanel.js.map +1 -1
  204. package/out/map/VersionPicker.d.ts +7 -19
  205. package/out/map/VersionPicker.d.ts.map +1 -1
  206. package/out/map/VersionPicker.js +5 -2
  207. package/out/map/VersionPicker.js.map +1 -1
  208. package/out/map/fake-runtime.d.ts +9 -11
  209. package/out/map/fake-runtime.d.ts.map +1 -1
  210. package/out/map/fake-runtime.js +45 -19
  211. package/out/map/fake-runtime.js.map +1 -1
  212. package/out/map/geometry.d.ts +13 -34
  213. package/out/map/geometry.d.ts.map +1 -1
  214. package/out/map/geometry.js +9 -34
  215. package/out/map/geometry.js.map +1 -1
  216. package/out/map/graticule.d.ts +17 -0
  217. package/out/map/graticule.d.ts.map +1 -0
  218. package/out/map/graticule.js +67 -0
  219. package/out/map/graticule.js.map +1 -0
  220. package/out/map/map-debug.d.ts +4 -2
  221. package/out/map/map-debug.d.ts.map +1 -1
  222. package/out/map/map-debug.js +1 -1
  223. package/out/map/map-debug.js.map +1 -1
  224. package/out/map/place-render.d.ts +25 -45
  225. package/out/map/place-render.d.ts.map +1 -1
  226. package/out/map/place-render.js +4 -39
  227. package/out/map/place-render.js.map +1 -1
  228. package/out/map/types.d.ts +57 -113
  229. package/out/map/types.d.ts.map +1 -1
  230. package/out/map/types.js +1 -10
  231. package/out/map/types.js.map +1 -1
  232. package/out/map/useCompareState.d.ts +5 -4
  233. package/out/map/useCompareState.d.ts.map +1 -1
  234. package/out/map/useCompareState.js +3 -3
  235. package/out/map/useCompareState.js.map +1 -1
  236. package/out/map/useGeocode.d.ts +5 -3
  237. package/out/map/useGeocode.d.ts.map +1 -1
  238. package/out/map/useGeocode.js +4 -4
  239. package/out/map/useGeocode.js.map +1 -1
  240. package/out/map/useMapBearing.d.ts +11 -11
  241. package/out/map/useMapBearing.d.ts.map +1 -1
  242. package/out/map/useMapBearing.js +6 -11
  243. package/out/map/useMapBearing.js.map +1 -1
  244. package/out/map/useMapLabelPick.d.ts +4 -14
  245. package/out/map/useMapLabelPick.d.ts.map +1 -1
  246. package/out/map/useMapLabelPick.js +21 -30
  247. package/out/map/useMapLabelPick.js.map +1 -1
  248. package/out/map/useMapPlaceRender.d.ts +3 -7
  249. package/out/map/useMapPlaceRender.d.ts.map +1 -1
  250. package/out/map/useMapPlaceRender.js +2 -6
  251. package/out/map/useMapPlaceRender.js.map +1 -1
  252. package/out/map/usePlaceAutocomplete.d.ts +30 -28
  253. package/out/map/usePlaceAutocomplete.d.ts.map +1 -1
  254. package/out/map/usePlaceAutocomplete.js +6 -33
  255. package/out/map/usePlaceAutocomplete.js.map +1 -1
  256. package/out/map.d.ts +67 -0
  257. package/out/map.d.ts.map +1 -0
  258. package/out/map.js +45 -0
  259. package/out/map.js.map +1 -0
  260. package/out/pipeline/CandidatePicker.d.ts +12 -2
  261. package/out/pipeline/CandidatePicker.d.ts.map +1 -1
  262. package/out/pipeline/CandidatePicker.js +1 -1
  263. package/out/pipeline/CandidatePicker.js.map +1 -1
  264. package/out/pipeline/ConfidenceCell.d.ts +2 -2
  265. package/out/pipeline/ConfidenceCell.d.ts.map +1 -1
  266. package/out/pipeline/ConfidenceCell.js +1 -1
  267. package/out/pipeline/FailureDiagnostic.d.ts +8 -2
  268. package/out/pipeline/FailureDiagnostic.d.ts.map +1 -1
  269. package/out/pipeline/FailureDiagnostic.js +3 -0
  270. package/out/pipeline/FailureDiagnostic.js.map +1 -1
  271. package/out/pipeline/PipelineExplorer.d.ts +6 -2
  272. package/out/pipeline/PipelineExplorer.d.ts.map +1 -1
  273. package/out/pipeline/PipelineExplorer.js +1 -1
  274. package/out/pipeline/PipelineExplorer.js.map +1 -1
  275. package/out/pipeline/QueryForm.d.ts +5 -2
  276. package/out/pipeline/QueryForm.d.ts.map +1 -1
  277. package/out/pipeline/QueryForm.js.map +1 -1
  278. package/out/pipeline/ResolvedPlace.d.ts +1 -1
  279. package/out/pipeline/ResolvedPlace.d.ts.map +1 -1
  280. package/out/pipeline/SpanHighlight.d.ts +4 -3
  281. package/out/pipeline/SpanHighlight.d.ts.map +1 -1
  282. package/out/pipeline/SpanHighlight.js +3 -2
  283. package/out/pipeline/SpanHighlight.js.map +1 -1
  284. package/out/pipeline/TimingPanel.d.ts +1 -1
  285. package/out/pipeline/TreeView.d.ts +1 -1
  286. package/out/pipeline/TreeView.js.map +1 -1
  287. package/out/pipeline/copy.d.ts +1 -1
  288. package/out/pipeline/copy.d.ts.map +1 -1
  289. package/out/pipeline/copy.js +4 -3
  290. package/out/pipeline/copy.js.map +1 -1
  291. package/out/pipeline/presets.d.ts +5 -4
  292. package/out/pipeline/presets.d.ts.map +1 -1
  293. package/out/pipeline/presets.js +15 -13
  294. package/out/pipeline/presets.js.map +1 -1
  295. package/out/pipeline/types.d.ts +20 -17
  296. package/out/pipeline/types.d.ts.map +1 -1
  297. package/out/pipeline/types.js +2 -4
  298. package/out/pipeline/types.js.map +1 -1
  299. package/out/pipeline/useParsePipeline.d.ts +14 -9
  300. package/out/pipeline/useParsePipeline.d.ts.map +1 -1
  301. package/out/pipeline/useParsePipeline.js +7 -8
  302. package/out/pipeline/useParsePipeline.js.map +1 -1
  303. package/out/pipeline.d.ts +33 -0
  304. package/out/pipeline.d.ts.map +1 -0
  305. package/out/pipeline.js +21 -0
  306. package/out/pipeline.js.map +1 -0
  307. package/out/poi/AbstainPanel.d.ts +1 -1
  308. package/out/poi/LiveResultsBlock.d.ts +2 -1
  309. package/out/poi/LiveResultsBlock.d.ts.map +1 -1
  310. package/out/poi/LiveResultsBlock.js.map +1 -1
  311. package/out/poi/POIExplorer.d.ts +22 -12
  312. package/out/poi/POIExplorer.d.ts.map +1 -1
  313. package/out/poi/POIExplorer.js +11 -10
  314. package/out/poi/POIExplorer.js.map +1 -1
  315. package/out/poi/QueryInput.d.ts +1 -1
  316. package/out/poi/SubjectPanel.d.ts +2 -2
  317. package/out/poi/SubjectPanel.d.ts.map +1 -1
  318. package/out/poi/SubjectPanel.js +2 -1
  319. package/out/poi/SubjectPanel.js.map +1 -1
  320. package/out/poi/runtime.d.ts +5 -14
  321. package/out/poi/runtime.d.ts.map +1 -1
  322. package/out/poi/runtime.js +14 -16
  323. package/out/poi/runtime.js.map +1 -1
  324. package/out/poi/types.d.ts +53 -45
  325. package/out/poi/types.d.ts.map +1 -1
  326. package/out/poi/types.js +2 -4
  327. package/out/poi/types.js.map +1 -1
  328. package/out/poi/usePOISearch.d.ts +30 -17
  329. package/out/poi/usePOISearch.d.ts.map +1 -1
  330. package/out/poi/usePOISearch.js +48 -64
  331. package/out/poi/usePOISearch.js.map +1 -1
  332. package/out/poi.d.ts +23 -0
  333. package/out/poi.d.ts.map +1 -0
  334. package/out/poi.js +15 -0
  335. package/out/poi.js.map +1 -0
  336. package/out/runtime/useReleaseRuntime.d.ts +63 -74
  337. package/out/runtime/useReleaseRuntime.d.ts.map +1 -1
  338. package/out/runtime/useReleaseRuntime.js +31 -32
  339. package/out/runtime/useReleaseRuntime.js.map +1 -1
  340. package/out/{runtime/index.d.ts → runtime.d.ts} +1 -1
  341. package/out/runtime.d.ts.map +1 -0
  342. package/out/{runtime/index.js → runtime.js} +1 -1
  343. package/out/runtime.js.map +1 -0
  344. package/out/search/SearchModal.d.ts +40 -0
  345. package/out/search/SearchModal.d.ts.map +1 -0
  346. package/out/search/SearchModal.js +255 -0
  347. package/out/search/SearchModal.js.map +1 -0
  348. package/out/search/types.d.ts +65 -0
  349. package/out/search/types.d.ts.map +1 -0
  350. package/out/search/types.js +13 -0
  351. package/out/search/types.js.map +1 -0
  352. package/out/search.d.ts +11 -0
  353. package/out/search.d.ts.map +1 -0
  354. package/out/search.js +9 -0
  355. package/out/search.js.map +1 -0
  356. package/package.json +73 -165
  357. package/styles.css +482 -266
  358. package/tokens/index.css +24 -6
  359. package/tokens/tokens.json +114 -6
  360. package/lib/common/index.ts +0 -22
  361. package/lib/map/BackendControl.tsx +0 -51
  362. package/lib/map/index.ts +0 -95
  363. package/lib/pipeline/index.ts +0 -36
  364. package/lib/poi/index.ts +0 -39
  365. package/out/common/index.d.ts +0 -22
  366. package/out/common/index.d.ts.map +0 -1
  367. package/out/common/index.js +0 -15
  368. package/out/common/index.js.map +0 -1
  369. package/out/map/BackendControl.d.ts +0 -32
  370. package/out/map/BackendControl.d.ts.map +0 -1
  371. package/out/map/BackendControl.js +0 -8
  372. package/out/map/BackendControl.js.map +0 -1
  373. package/out/map/index.d.ts +0 -69
  374. package/out/map/index.d.ts.map +0 -1
  375. package/out/map/index.js +0 -46
  376. package/out/map/index.js.map +0 -1
  377. package/out/pipeline/index.d.ts +0 -33
  378. package/out/pipeline/index.d.ts.map +0 -1
  379. package/out/pipeline/index.js +0 -21
  380. package/out/pipeline/index.js.map +0 -1
  381. package/out/poi/index.d.ts +0 -23
  382. package/out/poi/index.d.ts.map +0 -1
  383. package/out/poi/index.js +0 -15
  384. package/out/poi/index.js.map +0 -1
  385. package/out/runtime/index.d.ts.map +0 -1
  386. package/out/runtime/index.js.map +0 -1
  387. package/styleframe.config.ts +0 -329
  388. package/vitest.node.config.ts +0 -20
  389. /package/lib/{runtime/index.ts → runtime.ts} +0 -0
@@ -2,93 +2,78 @@
2
2
  * @copyright Sister Software
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
- *
6
- * `computeMapPlaceRenderSpec` — the PURE core that replaces the docs demo's ~100-line imperative
7
- * marker/bbox/camera redraw effect (`_app.tsx:601-705`). It takes an ALREADY-RESOLVED place (the async
8
- * polygon-DB fetch is a host/runtime concern — a later phase — so a crisp polygon arrives pre-fetched
9
- * as `place.geometry`) and returns a declarative render spec: the marker position(s), the outline
10
- * geometry to draw, and the camera target. No map instance, no DOM, no `react-map-gl` — so it is
11
- * node-testable (see `place-render.node.test.ts`). The declarative components in this folder render
12
- * the spec; a controlled-viewport consumer applies the camera.
13
- *
14
- * The decision cascade is a faithful, side-effect-free transcription of the imperative effect:
15
- * 1. street tier (situs / interp) → exact-radius circle, fly to a tight zoom
16
- * 2. crisp admin polygon (pre-fetched) → draw the polygon, fit its bounds
17
- * 3. anchor-centroid postcode (no bbox) → ~3 km "around here" circle, fly to zoom 11
18
- * 4. bbox with real extent → bbox-sized approximate circle, fit the bbox
19
- * 5. bare point → no outline, fly to zoom 12
20
5
  */
21
6
 
22
7
  import type { ResolvedPlaceView } from "@mailwoman/core/pipeline/client-result"
8
+ import type { LatLonBounds } from "@mailwoman/spatial"
23
9
 
24
10
  import { approxCircleGeometry, bboxToBounds, geomBounds, radiusCircleGeometry } from "#map/geometry"
25
- import type { BoundsTuple, PlaceBBox, PlaceGeometry } from "#map/geometry"
11
+ import type { BoundsTuple, PlaceGeometry } from "#map/geometry"
26
12
 
27
13
  /**
28
- * `[longitude, latitude]`.
14
+ * A coordinate pair as `[longitude, latitude]`.
29
15
  */
30
16
  export type LngLat = [number, number]
31
17
 
32
18
  /**
33
- * The street-level resolution tier (#377): `address_point` = exact building; `interpolated` = TIGER estimate.
19
+ * How a street-level result was located: `address_point` is an exact building point
20
+ * and `interpolated` an estimate from a TIGER address range.
34
21
  */
35
22
  export type PlaceTier = "address_point" | "interpolated"
36
23
 
37
24
  /**
38
- * The resolved-place shape the map render consumes — the pipeline {@link ResolvedPlaceView} plus the map-only extras the
39
- * demo's `ResolvedHit` carries (bbox, street tier + uncertainty), and an optional PRE-FETCHED crisp polygon. Extending
40
- * `ResolvedPlaceView` keeps the map render aligned with the shared parse result; the extras are additive.
25
+ * A resolved place with the extra fields the map uses to draw it.
41
26
  */
42
27
  export interface ResolvedMapPlace extends ResolvedPlaceView {
43
28
  /**
44
- * The place's bounding box, when the gazetteer carries one (admin places). Absent for anchor-centroid postcodes.
29
+ * The place's bounding box.
30
+ * Postcodes located by an anchor centroid have none.
45
31
  */
46
- bbox?: PlaceBBox
32
+ bbox: LatLonBounds | null
33
+
47
34
  /**
48
- * Street-level tier, when this hit came from the situs/interp tier rather than the WOF admin cascade.
35
+ * The street-level tier, set only for results from address points or interpolation.
49
36
  */
50
- tier?: PlaceTier
37
+ tier: PlaceTier | null
38
+
51
39
  /**
52
- * Honest uncertainty radius in meters for a street-level tier (10 m situs floor; calibrated interp).
40
+ * The uncertainty radius in meters of a street-level result, drawn as a circle when `tier` is set.
53
41
  */
54
- uncertaintyM?: number
42
+ uncertaintyM: number | null
43
+
55
44
  /**
56
- * The crisp admin polygon, when the host has ALREADY fetched it from the sibling polygon DB. Its presence drives the
57
- * polygon path; the async fetch itself stays out of this pure function (a runtime concern in a later phase).
45
+ * The admin polygon, if the host has already fetched it.
46
+ * When present the outline and camera follow it.
58
47
  */
59
48
  geometry?: PlaceGeometry
60
49
  }
61
50
 
62
51
  /**
63
- * The camera target the render computes. `center` (fly to a point at a zoom) HAS a declarative equivalent — a consumer
64
- * can feed it to a controlled `viewState` (see {@link cameraToViewState}). `bounds` (fit a box with pixel padding) does
65
- * NOT — `fitBounds` needs the map's pixel dimensions, so it is applied imperatively by `<ResultCamera>`.
52
+ * Only a `center` target can be applied declaratively through {@link cameraToViewState};
53
+ * fitting bounds needs the map's pixel size, so `<ResultCamera>` applies it imperatively.
66
54
  */
67
55
  export type MapCameraTarget =
68
56
  | { kind: "center"; center: LngLat; zoom: number }
69
57
  | { kind: "bounds"; bounds: BoundsTuple; padding: number }
70
58
 
71
59
  /**
72
- * The declarative render spec for one resolved place — the pure output of {@link computeMapPlaceRenderSpec}.
60
+ * The markers, outline and camera target for one resolved place, as returned
61
+ * by {@link computeMapPlaceRenderSpec}.
73
62
  */
74
63
  export interface MapPlaceRenderSpec {
75
64
  /**
76
- * Marker position(s) as `[lon, lat]`. Single-element today; an array leaves room for multi-marker later.
65
+ * The marker positions as `[lon, lat]`; there is always exactly one marker.
77
66
  */
78
67
  markers: LngLat[]
68
+
79
69
  /**
80
- * The outline geometry (polygon / circle) to draw, or `null` when the place renders as a bare point.
70
+ * The polygon or circle outline to draw, or `null` when the place renders as a bare point.
81
71
  */
82
72
  outline: PlaceGeometry | null
83
- /**
84
- * The camera target — animate or fit to this.
85
- */
73
+
86
74
  camera: MapCameraTarget
87
75
  }
88
76
 
89
- /**
90
- * Zoom levels the imperative effect flew to, kept named so the cascade reads as intent, not magic numbers.
91
- */
92
77
  const ZOOM = {
93
78
  addressPoint: 17,
94
79
  interpolated: 15,
@@ -96,26 +81,17 @@ const ZOOM = {
96
81
  point: 12,
97
82
  } as const
98
83
 
99
- /**
100
- * Padding (px) `fitBounds` insets a fitted box by, matching the ported effect.
101
- */
102
84
  const FIT_PADDING = 40
103
85
 
104
- /**
105
- * The minimum lat/lon span (degrees) a bbox must exceed to be treated as a real extent rather than a point.
106
- */
107
86
  const MIN_EXTENT_DEG = 0.001
108
87
 
109
88
  /**
110
- * Map a resolved place to its declarative render spec. Pure — same input, same output, no side effects. The `place`
111
- * arrives fully resolved (crisp polygon pre-fetched into `place.geometry` when available), so this is the honest
112
- * inverse of the old redraw effect with the imperative map mutation and the async DB load removed.
89
+ * Computes the markers, outline and camera target for a resolved place without loading data,
90
+ * so the caller must put any fetched polygon in `place.geometry` first.
113
91
  */
114
92
  export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRenderSpec {
115
93
  const markers: LngLat[] = [[place.lon, place.lat]]
116
94
 
117
- // 1. Street tier (#377): the honest uncertainty circle (exact meter radius) + a tight zoom. Takes precedence over
118
- // the admin polygon/bbox paths — a precise point gets no admin boundary.
119
95
  if (place.tier && place.uncertaintyM != null) {
120
96
  return {
121
97
  markers,
@@ -128,7 +104,6 @@ export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRend
128
104
  }
129
105
  }
130
106
 
131
- // 2. Crisp admin polygon (host pre-fetched it from the polygon DB) — draw the real boundary and fit it.
132
107
  if (place.geometry) {
133
108
  return {
134
109
  markers,
@@ -137,8 +112,6 @@ export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRend
137
112
  }
138
113
  }
139
114
 
140
- // 3. Anchor-centroid postcode: no bbox, no polygon — a default ~3 km circle says "approximately here" without
141
- // inventing a boundary.
142
115
  if (!place.bbox && place.placetype === "postcode") {
143
116
  return {
144
117
  markers,
@@ -147,8 +120,6 @@ export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRend
147
120
  }
148
121
  }
149
122
 
150
- // 4. A bbox with real extent — draw an approximate CIRCLE sized from the bbox (a rectangle would read as a wrong,
151
- // real boundary) and fit the bbox.
152
123
  const bbox = place.bbox
153
124
 
154
125
  if (bbox && Math.max(bbox.maxLat - bbox.minLat, bbox.maxLon - bbox.minLon) > MIN_EXTENT_DEG) {
@@ -159,7 +130,6 @@ export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRend
159
130
  }
160
131
  }
161
132
 
162
- // 5. A bare point (no tier, no polygon, no meaningful bbox) — just a marker and a mid zoom.
163
133
  return {
164
134
  markers,
165
135
  outline: null,
@@ -168,10 +138,8 @@ export function computeMapPlaceRenderSpec(place: ResolvedMapPlace): MapPlaceRend
168
138
  }
169
139
 
170
140
  /**
171
- * The DECLARATIVE camera path: reshape a `center` target into a `viewState` patch a controlled `<MapCanvas viewState>`
172
- * can apply directly (a hard jump, no animation). Returns `null` for a `bounds` target — fitting a box to the viewport
173
- * needs the map's pixel dimensions, which only the live map has, so that case is applied imperatively by
174
- * `<ResultCamera>`. Pure + node-testable.
141
+ * Converts a `center` camera target into a `viewState` patch for a controlled `<MapCanvas>`,
142
+ * returning `null` for a `bounds` target that `<ResultCamera>` must fit imperatively.
175
143
  */
176
144
  export function cameraToViewState(
177
145
  camera: MapCameraTarget
package/lib/map/types.ts CHANGED
@@ -3,16 +3,7 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * Types for the geocoder map surface. Mirrors the pipeline boundary: the package owns the UI state
7
- * machine + the declarative map, while the host injects a {@link GeocoderRuntime} that owns ONNX / httpvfs
8
- * / R2 and the composed map style. {@link GeocoderRuntime} EXTENDS {@link PipelineRuntime} so the shared
9
- * `runParse` / `parseStageLabels` / `loading` contract is reused, and adds the map-specific surface
10
- * (style, overlays, initial center, viewport bias, backend/version selection). Phase 4 adds the
11
- * `resolveMapPlace` enricher, the {@link GeocoderPanels} injection bag, and the {@link CompareContext}.
12
- *
13
- * The map-spec types are imported type-only from `react-map-gl/maplibre`; nothing here loads maplibre at
14
- * runtime, so this module stays node-safe (its concrete-value CONSUMERS — `MapCanvas`, `Geocoder` —
15
- * are the ones behind the `@mailwoman/react/map` subpath).
6
+ * Types for the geocoder map surface. Its `react-map-gl/maplibre` imports are type-only, so the module stays node-safe.
16
7
  */
17
8
 
18
9
  import type { ParseResult, ResolvedPlaceView } from "@mailwoman/core/pipeline/client-result"
@@ -25,9 +16,10 @@ import type { PipelineRuntime } from "#pipeline/types"
25
16
  import type { MapCanvasStyle } from "./MapCanvas.tsx"
26
17
 
27
18
  /**
28
- * `[longitude, latitude]`.
19
+ * An alias for {@link LngLat}.
29
20
  *
30
- * @deprecated Alias kept for existing imports — {@link LngLat} (from `@mailwoman/react/map`) is the canonical name.
21
+ * @deprecated Alias kept for existing imports — {@link LngLat}
22
+ * (from `@mailwoman/react/map`) is the canonical name.
31
23
  */
32
24
  export type LngLatTuple = LngLat
33
25
 
@@ -35,40 +27,24 @@ export type LngLatTuple = LngLat
35
27
  * A viewport bias handed to `runParse` — the map's current center (and optionally zoom) as a soft prior.
36
28
  */
37
29
  export interface MapBias {
38
- /**
39
- * Map center as `[lon, lat]`, typically read from `map.getCenter()`.
40
- */
41
30
  center: LngLat
42
- /**
43
- * Current zoom, if the host wants distance-aware biasing.
44
- */
45
31
  zoom?: number
46
32
  }
47
33
 
48
34
  /**
49
- * A host-supplied overlay: one map `<Source>` plus one or more `<Layer>`s laid over the basemap (coverage "fog of war",
50
- * race-dots, …). The host composes the specs; the package renders them declaratively in a later phase.
35
+ * A host-supplied overlay: one map `<Source>` plus one or more `<Layer>`s laid over the basemap.
51
36
  */
52
37
  export interface OverlaySpec {
53
38
  /**
54
39
  * Stable id — used as the `<Source>` id and the layer-id prefix.
55
40
  */
56
41
  id: string
57
- /**
58
- * The map source spec (vector/geojson/raster).
59
- */
60
42
  source: SourceSpecification
61
- /**
62
- * The layers drawn from that source.
63
- */
64
43
  layers: LayerSpecification[]
65
44
  /**
66
- * Whether the overlay is visible initially. @default true
45
+ * @defaultValue `true`
67
46
  */
68
47
  visible?: boolean
69
- /**
70
- * Human label for a layer-toggle control.
71
- */
72
48
  label?: string
73
49
  }
74
50
 
@@ -95,50 +71,38 @@ export interface Suggestion {
95
71
  */
96
72
  export interface VersionOption {
97
73
  /**
98
- * The version tag (e.g. a git tag or model-card version).
74
+ * The version tag, such as a git tag or model-card version.
99
75
  */
100
76
  version: string
101
77
  /**
102
- * Display label; falls back to `version`.
78
+ * Display label.
79
+ * The picker falls back to `version`.
103
80
  */
104
81
  label?: string
105
82
  }
106
83
 
107
84
  /**
108
- * Which neural backend the geocoder is currently running on.
109
- */
110
- export type InferenceBackend = "webgpu" | "wasm"
111
-
112
- /**
113
- * The injected geocoder runtime. Extends {@link PipelineRuntime} (shared `runParse` / `parseStageLabels` / `loading` /
114
- * `ready`) with the map + version/backend surface the geocoder needs. The host composes `mapStyle` (via cartographer's
115
- * `StyleSpecificationComposer` + the tile-worker TileJSON), supplies the overlay specs, the initial center (from
116
- * geolocation), the FST autocomplete, and the calibrator — nothing in the package imports `@mailwoman/cartographer`,
117
- * `@mailwoman/neural`'s web loader, httpvfs, or Docusaurus.
85
+ * The injected geocoder runtime extends {@link PipelineRuntime} with the map.
86
+ * It also supplies version and backend controls.
87
+ *
88
+ * The package imports no `@mailwoman/cartographer`, `@mailwoman/neural` web loader, httpvfs, or Docusaurus.
118
89
  */
119
90
  export interface GeocoderRuntime extends PipelineRuntime {
120
- // ── Map ────────────────────────────────────────────────────────────────
121
91
  /**
122
92
  * The composed basemap style (URL or `StyleSpecification`).
123
93
  */
124
94
  mapStyle: MapCanvasStyle
125
- /**
126
- * Host-supplied overlays (coverage, race-dots, …).
127
- */
128
95
  overlays?: OverlaySpec[]
129
96
  /**
130
- * Initial map center as `[lon, lat]` (the host's browser-geolocation result).
97
+ * Initial map center as `[lon, lat]`.
131
98
  */
132
99
  initialCenter: LngLat
133
- /**
134
- * Initial zoom for the first camera.
135
- */
136
100
  initialZoom?: number
137
101
 
138
- // ── Parse extras layered over PipelineRuntime.runParse ──────────────────
139
102
  /**
140
- * A bias-aware parse. The geocoder feeds the current viewport center as a soft prior; when absent the host falls back
141
- * to the base {@link PipelineRuntime.runParse}. Kept separate so the shared `runParse` contract is unchanged.
103
+ * A bias-aware parse that feeds the current viewport center as a soft prior.
104
+ *
105
+ * Absent, the host falls back to {@link PipelineRuntime.runParse}.
142
106
  */
143
107
  runParseWithBias?: (
144
108
  input: string,
@@ -154,11 +118,17 @@ export interface GeocoderRuntime extends PipelineRuntime {
154
118
  */
155
119
  calibrator?: (raw: number) => number | null
156
120
  /**
157
- * Enrich the selected candidate into the richer {@link ResolvedMapPlace} the declarative map render consumes (bbox,
158
- * street tier + uncertainty, a pre-fetched crisp polygon) — the fields that live on the host's `ResolvedHit` but not
159
- * on the shared {@link ResolvedPlaceView}. The host owns this because those extras (and the async polygon fetch in the
160
- * real runtime) are host/gazetteer concerns; the package keeps {@link ParseResult} unpolluted. Absent → the candidate
161
- * renders as a bare point (marker + a mid-zoom fly-to). Returning `null` also renders nothing.
121
+ * Enrich the selected candidate into the richer {@link ResolvedMapPlace} the declarative
122
+ * map render consumes (bbox, street tier + uncertainty, a pre-fetched crisp polygon) —
123
+ * the fields that live on the host's `ResolvedHit` but not on the shared {@link ResolvedPlaceView}.
124
+ *
125
+ * The host owns this because those extras (and the async polygon fetch in the real runtime)
126
+ * are host/gazetteer concerns.
127
+ * The package keeps {@link ParseResult} unpolluted.
128
+ *
129
+ * Absent → the candidate renders as a bare point (marker + a mid-zoom fly-to).
130
+ *
131
+ * A `null` result also renders no overlay.
162
132
  */
163
133
  resolveMapPlace?: (candidate: ResolvedPlaceView, result: ParseResult) => ResolvedMapPlace | null
164
134
 
@@ -167,40 +137,26 @@ export interface GeocoderRuntime extends PipelineRuntime {
167
137
  * The selectable model bundles the version picker offers.
168
138
  */
169
139
  availableVersions?: VersionOption[]
170
- /**
171
- * The currently-selected model version.
172
- */
173
140
  selectedVersion?: string
174
141
  /**
175
142
  * Switch the active model bundle (re-loads weights/tokenizer/gazetteer).
176
143
  */
177
144
  selectVersion?: (version: string) => void
178
145
  /**
179
- * The backend the neural runtime resolved to (e.g. `webgpu (28 MB int8)`); free-form for the label.
146
+ * The neural runtime's backend and model size (e.g. `wasm (28 MB int8)`); free-form for the label.
180
147
  */
181
148
  activeBackend?: string
182
- /**
183
- * Whether the CPU/WASM backend is currently forced (the controlled value for the backend toggle).
184
- */
185
- forceWASM?: boolean
186
- /**
187
- * Force the WASM backend (opt out of WebGPU), for the backend toggle.
188
- */
189
- setForceWASM?: (forceWASM: boolean) => void
190
149
  }
191
150
 
192
151
  /**
193
- * The compare-mode state a {@link GeocoderPanels.compare} render-prop receives (the second parse itself stays
194
- * host-side).
152
+ * The compare-mode state a {@link GeocoderPanels.compare} render-prop receives.
153
+ * the second parse itself stays host-side.
195
154
  */
196
155
  export interface CompareContext {
197
156
  /**
198
157
  * The current primary parse result, or `null` before the first submit.
199
158
  */
200
159
  result: ParseResult | null
201
- /**
202
- * Whether the compare toggle is on.
203
- */
204
160
  compareMode: boolean
205
161
  /**
206
162
  * The version selected to compare against, or `null` when none is chosen.
@@ -209,39 +165,29 @@ export interface CompareContext {
209
165
  }
210
166
 
211
167
  /**
212
- * The state a {@link GeocoderPanels.result} render-prop receives, so a host can render its OWN result block (a
213
- * `<ResultPanel>` with its span-highlight / timing / hierarchy / precision detail) in place of the package's default
214
- * {@link ResultPanel}. Everything the default panel needs is passed through; the candidate-selection state stays owned
215
- * by the package (`useGeocode`).
168
+ * The state a {@link GeocoderPanels.result} render-prop receives, so a host can render its own result block.
169
+ *
170
+ * The candidate-selection state stays owned by the package (`useGeocode`).
216
171
  */
217
172
  export interface ResultContext {
218
- /**
219
- * The current parse+resolve result.
220
- */
221
173
  result: ParseResult
222
174
  /**
223
175
  * The selected candidate (falls back to the first), enriched for the resolved-place detail.
224
176
  */
225
177
  selectedCandidate: ResolvedPlaceView | null
226
- /**
227
- * The selected candidate index, for the picker's active state.
228
- */
229
178
  selectedCandidateIndex: number
230
- /**
231
- * Fired when a candidate in the picker is chosen.
232
- */
233
179
  onSelectCandidate: (index: number) => void
234
180
  }
235
181
 
236
182
  /**
237
- * Host-injected panels for {@link Geocoder}, the map analogue of `PipelinePanels`. Each is an already-rendered
238
- * `ReactNode` (or a thunk of the parse result / compare state) so the package needs neither the heavy host visualizers
239
- * (ModelVisualizer, VersionCompare, About, PermalinkButton) nor their data types. Every field is optional — the
240
- * fake-runtime Storybook stories pass none and still render the whole geocoder.
183
+ * Host-injected panels for {@link Geocoder}, the map analogue of `PipelinePanels`.
184
+ *
185
+ * Each is an already-rendered `ReactNode` or a thunk.
186
+ * Every field is optional.
241
187
  */
242
188
  export interface GeocoderPanels {
243
189
  /**
244
- * Rendered at the top of the control panel (e.g. the host's "About this geocoder").
190
+ * Rendered at the top of the control panel, such as the host's "About this geocoder".
245
191
  */
246
192
  header?: ReactNode
247
193
  /**
@@ -249,13 +195,13 @@ export interface GeocoderPanels {
249
195
  */
250
196
  releaseInfo?: ReactNode
251
197
  /**
252
- * Rendered at the bottom of the control panel (e.g. a guided tour).
198
+ * Rendered at the bottom of the control panel, such as a guided tour.
253
199
  */
254
200
  footer?: ReactNode
255
201
  /**
256
- * A device-location / proximity-bias control, rendered between the query form and the autocomplete list (the "📍 Use
257
- * my location" row). Host-owned so the geolocation permission + the bias it feeds into the host's
258
- * {@link GeocoderRuntime.runParseWithBias} stay a host concern.
202
+ * A device-location / proximity-bias control, rendered between the query form and the autocomplete list.
203
+ *
204
+ * Host-owned because the geolocation permission feeds {@link GeocoderRuntime.runParseWithBias}.
259
205
  */
260
206
  bias?: ReactNode
261
207
  /**
@@ -263,26 +209,25 @@ export interface GeocoderPanels {
263
209
  */
264
210
  extras?: (result: ParseResult) => ReactNode
265
211
  /**
266
- * Rendered just above the result block (present or empty), for content that reads on THIS answer.
267
- *
268
- * A control that reads on the model rather than on an address belongs in {@link developerExtras}: above the result it
269
- * is the first thing a visitor meets, and on a phone it pushes the answer below the fold.
212
+ * Rendered just above the result block for content that reads on this answer. a
213
+ * control that reads on the model belongs in {@link developerExtras}.
270
214
  */
271
215
  aboveResult?: (context: { result: ParseResult | null }) => ReactNode
272
216
  /**
273
- * Host controls appended to the Developer sheet — the opt-in display toggles, whose state and the renderers they
274
- * drive both belong to the host.
217
+ * Host controls appended to the Developer sheet.
218
+ * The host owns their state and renderers.
275
219
  */
276
220
  developerExtras?: ReactNode
277
221
  /**
278
- * Replace the package's default {@link ResultPanel} entirely. When provided, the host renders its own result block
279
- * (span highlight, timing, hierarchy, precision detail, calibrated confidences) from the {@link ResultContext}. Absent
280
- * → the built-in panel renders.
222
+ * Replaces the package's default {@link ResultPanel}.
223
+ *
224
+ * When absent, the built-in panel renders.
225
+ * When provided, the host renders from {@link ResultContext}.
281
226
  */
282
227
  result?: (context: ResultContext) => ReactNode
283
228
  /**
284
- * Rendered in place of the resolved-place panel when nothing resolved (host's FailureDiagnostic). Ignored when
285
- * {@link result} is set.
229
+ * Rendered in place of the resolved-place panel when no place resolved. ignored
230
+ * when {@link result} is set.
286
231
  */
287
232
  failure?: (result: ParseResult) => ReactNode
288
233
  /**
@@ -290,9 +235,8 @@ export interface GeocoderPanels {
290
235
  */
291
236
  compare?: (context: CompareContext) => ReactNode
292
237
  /**
293
- * The model-visualizer / debug drawer, mounted beside the map (host's ModelVisualizer). A render-prop so the host can
294
- * trace the CURRENT result (its input) — the package passes the live parse result; the host decides on its own
295
- * dev-mode state and returns `null` when the drawer is closed.
238
+ * The model-visualizer / debug drawer mounted beside the map, as a render-prop
239
+ * receiving the live result and returning `null` when closed.
296
240
  */
297
241
  debugDrawer?: (context: { result: ParseResult | null }) => ReactNode
298
242
  /**
@@ -300,11 +244,8 @@ export interface GeocoderPanels {
300
244
  */
301
245
  mapControls?: ReactNode
302
246
  /**
303
- * A layer control, rendered in the chrome's top column under the example chips rather than in a MapLibre corner.
304
- *
305
- * A render-prop taking the live map handle, because a layer control reads `getStyle().layers` and writes
306
- * `setLayoutProperty` — it cannot be a static node. The handle is `null` until the map instantiates, so the host
307
- * returns `null` for that first frame rather than rendering an empty control.
247
+ * A layer control rendered in the chrome's top column, as a render-prop over the
248
+ * live map handle (null until the map instantiates).
308
249
  */
309
250
  layers?: (context: { map: MapInstance | null }) => ReactNode
310
251
  /**
@@ -4,9 +4,9 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
6
  * `useCompareState` — the small headless state machine behind the demo's compare toggle
7
- * (`_app.tsx:142-143, 1238-1305`): whether compare mode is on, and which version to compare against.
8
- * Turning compare off clears the chosen version; selecting a compare version equal to the primary is
9
- * rejected (the picker filters it out, this guards the programmatic path). The SECOND parse itself is a
7
+ * (`_app.tsx:142-143, 1238-1305`): whether compare mode is on and which version to compare against.
8
+ * The off state clears the chosen version. A selected compare version equal to the primary is
9
+ * rejected (the picker filters it out, this guards the programmatic path). The second parse itself is a
10
10
  * host concern surfaced through `panels.compare` — this hook owns only the toggle + selection.
11
11
  */
12
12
 
@@ -22,7 +22,8 @@ export interface UseCompareState {
22
22
  */
23
23
  compareVersion: string | null
24
24
  /**
25
- * Flip compare mode; turning it off clears the chosen version.
25
+ * Flip compare mode.
26
+ * The off state clears the chosen version.
26
27
  */
27
28
  setCompareMode: (compareMode: boolean) => void
28
29
  /**
@@ -3,12 +3,12 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * `useGeocode` — the parse+resolve state machine for the geocoder map. It REUSES the pipeline's
6
+ * `useGeocode` — the parse+resolve state machine for the geocoder map. It reuses the pipeline's
7
7
  * `useParsePipeline` (text / busy / stage / result / candidate selection) and layers on the two map-only
8
8
  * concerns the geocoder adds over the base explorer:
9
9
  *
10
10
  * 1. Viewport bias — when the runtime exposes `runParseWithBias`, the current map center (read through
11
- * an injected `getBias`, itself reading the `MapRef`) rides along as a soft proximity prior. The
11
+ * an injected `getBias`, itself reading the `MapRef`) supplies a soft proximity prior. The
12
12
  * bias is injected by deriving a `runParse` that binds it, so `useParsePipeline` is reused verbatim.
13
13
  * 2. The map render place — the selected candidate, enriched by the host's `resolveMapPlace` into the
14
14
  * richer {@link ResolvedMapPlace} the declarative overlays consume (bbox / tier / polygon). Absent
@@ -35,7 +35,9 @@ export interface UseGeocodeOptions {
35
35
  */
36
36
  defaultText: string
37
37
  /**
38
- * Read the current viewport bias (the map center) at submit time. Absent → no bias.
38
+ * Read the current viewport bias (the map center) at submit time.
39
+ *
40
+ * Absent → no bias.
39
41
  */
40
42
  getBias?: () => MapBias | null
41
43
  }
@@ -48,8 +50,8 @@ export interface UseGeocode extends UseParsePipeline {
48
50
  }
49
51
 
50
52
  export function useGeocode({ runtime, defaultText, getBias }: UseGeocodeOptions): UseGeocode {
51
- // Bind the viewport bias into a derived `runParse` so `useParsePipeline` is reused unchanged. When the runtime has no
52
- // bias-aware parse, pass it straight through.
53
+ // Bind the viewport bias into a derived `runParse` so `useParsePipeline` is reused unchanged.
54
+ // When the runtime has no bias-aware parse, pass it straight through.
53
55
  const geoRuntime = useMemo<PipelineRuntime>(() => {
54
56
  const withBias = runtime.runParseWithBias
55
57
 
@@ -3,31 +3,31 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * `useMapBearing` — the map's rotation as React state, for a compass that appears off north and fades back.
7
- *
8
- * The map is an external store, so it is read through `useSyncExternalStore` rather than mirrored into state by an
9
- * effect: the bearing is a number, which makes a stable snapshot, and React tears nothing during a concurrent
10
- * render.
11
- *
12
- * It listens on `rotate` rather than `rotateend`, because the needle has to track the gesture rather than snap once
13
- * the gesture is over. `move` is subscribed too: a `flyTo` or an `easeTo` carrying a bearing rotates the map without
14
- * firing a rotate event, and a compass that misses those stays pointing north over a turned map.
6
+ * The map's rotation as React state, read through `useSyncExternalStore` and subscribed to `move` as well as `rotate`, since a `flyTo` or `easeTo` carrying a direction fires no rotate event.
15
7
  */
16
8
 
17
9
  import { useCallback, useSyncExternalStore } from "react"
18
10
  import type { MapInstance } from "react-map-gl/maplibre"
19
11
 
12
+ /**
13
+ * The map's bearing and a callback that returns the map to north.
14
+ */
20
15
  export interface UseMapBearing {
21
16
  /**
22
- * Degrees off north, as MapLibre reports it. Zero while there is no map.
17
+ * Degrees off north, as MapLibre reports it.
18
+ * Zero while there is no map.
23
19
  */
24
20
  bearing: number
25
21
  /**
26
- * Rotate the map back to north. A no-op while there is no map.
22
+ * Rotate the map back to north.
23
+ * A no-op while there is no map.
27
24
  */
28
25
  resetNorth: () => void
29
26
  }
30
27
 
28
+ /**
29
+ * Reads the live map bearing and exposes `resetNorth`.
30
+ */
31
31
  export function useMapBearing(map: MapInstance | null): UseMapBearing {
32
32
  const subscribe = useCallback(
33
33
  (onChange: () => void) => {
@@ -44,8 +44,8 @@ export function useMapBearing(map: MapInstance | null): UseMapBearing {
44
44
  [map]
45
45
  )
46
46
 
47
- // The server snapshot is the same reading: there is no map during a server render, and north is what a compass
48
- // shows when it has nothing to report.
47
+ // The server snapshot is the same reading: the server renders no map.
48
+ // and north is what a compass shows with no bearing to report.
49
49
  const readBearing = useCallback(() => map?.getBearing() ?? 0, [map])
50
50
 
51
51
  const bearing = useSyncExternalStore(subscribe, readBearing, () => 0)