@jupytergis/base 0.14.1 → 0.16.0-alpha.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 (397) hide show
  1. package/lib/commands/BaseCommandIDs.d.ts +6 -0
  2. package/lib/commands/BaseCommandIDs.js +6 -0
  3. package/lib/commands/index.js +245 -55
  4. package/lib/commands/operationCommands.js +2 -2
  5. package/lib/constants.js +6 -1
  6. package/lib/{panelview/annotationPanel.js → features/annotations/AnnotationsPanel.js} +1 -1
  7. package/lib/{annotations → features/annotations}/index.d.ts +1 -0
  8. package/lib/{annotations → features/annotations}/index.js +1 -0
  9. package/lib/{console → features/console}/consoleview.js +1 -1
  10. package/lib/{panelview/filter-panel → features/filter}/Filter.js +4 -4
  11. package/lib/{panelview/filter-panel → features/filter}/FilterRow.d.ts +3 -2
  12. package/lib/{panelview/filter-panel → features/filter}/FilterRow.js +2 -1
  13. package/lib/{panelview/identify-panel → features/identify}/IdentifyPanel.d.ts +2 -0
  14. package/lib/features/identify/IdentifyPanel.js +102 -0
  15. package/lib/features/identify/components/FeatureCard.d.ts +17 -0
  16. package/lib/features/identify/components/FeatureCard.js +26 -0
  17. package/lib/features/identify/components/FeatureCardHeader.d.ts +11 -0
  18. package/lib/features/identify/components/FeatureCardHeader.js +30 -0
  19. package/lib/features/identify/components/FeatureFloater.d.ts +7 -0
  20. package/lib/features/identify/components/FeatureFloater.js +19 -0
  21. package/lib/features/identify/components/FeaturePropertyList.d.ts +11 -0
  22. package/lib/features/identify/components/FeaturePropertyList.js +18 -0
  23. package/lib/features/identify/components/FeatureRow.d.ts +13 -0
  24. package/lib/features/identify/components/FeatureRow.js +25 -0
  25. package/lib/features/identify/components/PropertyEditors.d.ts +44 -0
  26. package/lib/features/identify/components/PropertyEditors.js +56 -0
  27. package/lib/features/identify/hooks/useIdentifyPropertyEditor.d.ts +11 -0
  28. package/lib/features/identify/hooks/useIdentifyPropertyEditor.js +132 -0
  29. package/lib/features/identify/types/editorTypes.d.ts +21 -0
  30. package/lib/features/identify/utils/getFeatureIdentifier.d.ts +5 -0
  31. package/lib/features/identify/utils/getFeatureIdentifier.js +14 -0
  32. package/lib/features/identify/utils/highlightLayer.d.ts +11 -0
  33. package/lib/features/identify/utils/highlightLayer.js +57 -0
  34. package/lib/features/identify/utils/highlightStyle.d.ts +7 -0
  35. package/lib/features/identify/utils/highlightStyle.js +40 -0
  36. package/lib/{dialogs/layerBrowserDialog.js → features/layer-browser/index.js} +2 -2
  37. package/lib/features/layers/forms/layer/geoTiffLayerForm.d.ts +3 -0
  38. package/lib/{formbuilder/objectform/layer/webGlLayerForm.js → features/layers/forms/layer/geoTiffLayerForm.js} +5 -5
  39. package/lib/{formbuilder/objectform → features/layers/forms}/layer/heatmapLayerForm.js +4 -4
  40. package/lib/{formbuilder/objectform → features/layers/forms}/layer/hillshadeLayerForm.js +4 -4
  41. package/lib/{formbuilder/objectform → features/layers/forms}/layer/index.d.ts +1 -1
  42. package/lib/{formbuilder/objectform → features/layers/forms}/layer/index.js +1 -1
  43. package/lib/{formbuilder/objectform → features/layers/forms}/layer/layerform.d.ts +1 -1
  44. package/lib/{formbuilder/objectform → features/layers/forms}/layer/layerform.js +4 -4
  45. package/lib/features/layers/forms/layer/storySegmentLayerForm.js +150 -0
  46. package/lib/{formbuilder/objectform → features/layers/forms}/layer/vectorlayerform.js +4 -4
  47. package/lib/{formbuilder/objectform → features/layers/forms}/source/geojsonsource.js +5 -5
  48. package/lib/features/layers/forms/source/geopackagesource.d.ts +3 -0
  49. package/lib/features/layers/forms/source/geopackagesource.js +93 -0
  50. package/lib/{formbuilder/objectform → features/layers/forms}/source/geotiffsource.js +5 -5
  51. package/lib/{formbuilder/objectform → features/layers/forms}/source/index.d.ts +2 -0
  52. package/lib/{formbuilder/objectform → features/layers/forms}/source/index.js +2 -0
  53. package/lib/{formbuilder/objectform → features/layers/forms}/source/pathbasedsource.js +5 -5
  54. package/lib/{formbuilder/objectform → features/layers/forms}/source/sourceform.d.ts +1 -1
  55. package/lib/{formbuilder/objectform → features/layers/forms}/source/sourceform.js +4 -4
  56. package/lib/{formbuilder/objectform → features/layers/forms}/source/tilesourceform.js +4 -4
  57. package/lib/features/layers/forms/source/wmsTileSource.d.ts +4 -0
  58. package/lib/features/layers/forms/source/wmsTileSource.js +78 -0
  59. package/lib/{dialogs → features/layers}/layerCreationFormDialog.d.ts +1 -1
  60. package/lib/{dialogs → features/layers}/layerCreationFormDialog.js +1 -1
  61. package/lib/features/layers/symbology/Grammar.d.ts +11 -0
  62. package/lib/features/layers/symbology/Grammar.js +235 -0
  63. package/lib/{dialogs/symbology/vector_layer/types → features/layers/symbology}/Heatmap.d.ts +1 -1
  64. package/lib/{dialogs/symbology/vector_layer/types → features/layers/symbology}/Heatmap.js +30 -10
  65. package/lib/{dialogs → features/layers}/symbology/classificationModes.d.ts +6 -6
  66. package/lib/{dialogs → features/layers}/symbology/classificationModes.js +57 -57
  67. package/lib/features/layers/symbology/colorRampUtils.d.ts +65 -0
  68. package/lib/features/layers/symbology/colorRampUtils.js +242 -0
  69. package/lib/features/layers/symbology/components/MappingRow.d.ts +40 -0
  70. package/lib/features/layers/symbology/components/MappingRow.js +516 -0
  71. package/lib/features/layers/symbology/components/NumericInput.d.ts +20 -0
  72. package/lib/features/layers/symbology/components/NumericInput.js +44 -0
  73. package/lib/features/layers/symbology/components/ScaleEditor.d.ts +33 -0
  74. package/lib/features/layers/symbology/components/ScaleEditor.js +221 -0
  75. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampControls.d.ts +1 -1
  76. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampControls.js +3 -2
  77. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampSelector.d.ts +2 -1
  78. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampSelector.js +12 -15
  79. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampSelectorEntry.d.ts +2 -2
  80. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ColorRampSelectorEntry.js +3 -11
  81. package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ModeSelectRow.d.ts +1 -1
  82. package/lib/features/layers/symbology/components/color_ramp/RgbaColorPicker.d.ts +13 -0
  83. package/lib/features/layers/symbology/components/color_ramp/RgbaColorPicker.js +128 -0
  84. package/lib/{dialogs → features/layers}/symbology/components/color_stops/StopContainer.js +3 -1
  85. package/lib/{dialogs → features/layers}/symbology/components/color_stops/StopRow.d.ts +2 -2
  86. package/lib/{dialogs → features/layers}/symbology/components/color_stops/StopRow.js +12 -7
  87. package/lib/features/layers/symbology/grammarToOLLayer.d.ts +27 -0
  88. package/lib/features/layers/symbology/grammarToOLLayer.js +145 -0
  89. package/lib/features/layers/symbology/grammarToOLStyle.d.ts +32 -0
  90. package/lib/features/layers/symbology/grammarToOLStyle.js +467 -0
  91. package/lib/{dialogs → features/layers}/symbology/hooks/useGetBandInfo.d.ts +1 -1
  92. package/lib/{dialogs → features/layers}/symbology/hooks/useGetBandInfo.js +1 -1
  93. package/lib/{dialogs → features/layers}/symbology/hooks/useGetProperties.js +1 -1
  94. package/lib/{dialogs → features/layers}/symbology/hooks/useGetSymbology.js +4 -2
  95. package/lib/features/layers/symbology/styleBuilder.d.ts +21 -0
  96. package/lib/features/layers/symbology/styleBuilder.js +145 -0
  97. package/lib/{dialogs → features/layers}/symbology/symbologyDialog.d.ts +3 -2
  98. package/lib/{dialogs → features/layers}/symbology/symbologyDialog.js +12 -12
  99. package/lib/features/layers/symbology/symbologyUtils.d.ts +41 -0
  100. package/lib/features/layers/symbology/symbologyUtils.js +114 -0
  101. package/lib/{panelview/objectproperties.d.ts → features/objectproperties/index.d.ts} +1 -1
  102. package/lib/{panelview/objectproperties.js → features/objectproperties/index.js} +5 -10
  103. package/lib/{dialogs → features/processing}/ProcessingFormDialog.d.ts +1 -1
  104. package/lib/{dialogs → features/processing}/ProcessingFormDialog.js +28 -14
  105. package/lib/features/processing/forms/MapExtentToggle.d.ts +13 -0
  106. package/lib/features/processing/forms/MapExtentToggle.js +20 -0
  107. package/lib/features/processing/forms/clipRasterByExtentForm.d.ts +10 -0
  108. package/lib/features/processing/forms/clipRasterByExtentForm.js +99 -0
  109. package/lib/{formbuilder/objectform/process → features/processing/forms}/dissolveProcessForm.js +5 -5
  110. package/lib/{formbuilder/objectform → features/processing/forms}/processingForm.d.ts +1 -1
  111. package/lib/{formbuilder/objectform → features/processing/forms}/processingForm.js +6 -6
  112. package/lib/features/processing/forms/rasterizeForm.d.ts +10 -0
  113. package/lib/features/processing/forms/rasterizeForm.js +75 -0
  114. package/lib/features/processing/forms/useMapExtent.d.ts +22 -0
  115. package/lib/features/processing/forms/useMapExtent.js +57 -0
  116. package/lib/{processing → features/processing}/index.d.ts +19 -2
  117. package/lib/features/processing/index.js +1246 -0
  118. package/lib/{processing → features/processing}/processingCommands.d.ts +1 -1
  119. package/lib/features/processing/processingCommands.js +168 -0
  120. package/lib/features/processing/serverProcessing.d.ts +51 -0
  121. package/lib/features/processing/serverProcessing.js +99 -0
  122. package/lib/{stacBrowser → features/stac-browser}/components/StacPanel.js +2 -2
  123. package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/QueryableComboBox.js +64 -21
  124. package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/QueryableRow.js +1 -1
  125. package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/StacFilterExtensionPanel.js +2 -2
  126. package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/StacQueryableFilters.js +1 -1
  127. package/lib/{stacBrowser → features/stac-browser}/components/geodes/StacFilterSection.js +3 -3
  128. package/lib/{stacBrowser → features/stac-browser}/components/shared/StacPanelResults.js +3 -3
  129. package/lib/{stacBrowser → features/stac-browser}/components/shared/StacSpatialExtent.js +1 -1
  130. package/lib/{stacBrowser → features/stac-browser}/components/shared/StacTemporalExtent.js +1 -1
  131. package/lib/{stacBrowser → features/stac-browser}/context/StacResultsContext.js +2 -2
  132. package/lib/{stacBrowser → features/stac-browser}/hooks/useGeodesSearch.js +2 -2
  133. package/lib/{stacBrowser → features/stac-browser}/hooks/useStacFilterExtension.d.ts +1 -1
  134. package/lib/{stacBrowser → features/stac-browser}/hooks/useStacFilterExtension.js +198 -114
  135. package/lib/{stacBrowser → features/stac-browser}/hooks/useStacSearch.d.ts +1 -0
  136. package/lib/{stacBrowser → features/stac-browser}/hooks/useStacSearch.js +19 -11
  137. package/lib/features/stac-browser/types/types.js +1 -0
  138. package/lib/{panelview/story-maps → features/story}/SpectaPanel.d.ts +4 -1
  139. package/lib/{panelview/story-maps → features/story}/SpectaPanel.js +3 -4
  140. package/lib/{panelview/story-maps → features/story}/StoryEditorPanel.js +1 -1
  141. package/lib/{panelview/story-maps → features/story}/StoryViewerPanel.d.ts +12 -11
  142. package/lib/features/story/StoryViewerPanel.js +64 -0
  143. package/lib/features/story/__tests__/fixtures/listStoryTestItems.d.ts +9 -0
  144. package/lib/features/story/__tests__/fixtures/listStoryTestItems.js +21 -0
  145. package/lib/features/story/components/ListStoryMapOverlayPanel.d.ts +10 -0
  146. package/lib/features/story/components/ListStoryMapOverlayPanel.js +11 -0
  147. package/lib/features/story/components/ListStoryMarkdownMeasurePane.d.ts +11 -0
  148. package/lib/features/story/components/ListStoryMarkdownMeasurePane.js +55 -0
  149. package/lib/features/story/components/ListStoryOverlayMarkdown.d.ts +15 -0
  150. package/lib/features/story/components/ListStoryOverlayMarkdown.js +93 -0
  151. package/lib/features/story/components/ListStoryStageOverlay.d.ts +12 -0
  152. package/lib/features/story/components/ListStoryStageOverlay.js +132 -0
  153. package/lib/features/story/components/ListStoryVirtualScrollTrack.d.ts +6 -0
  154. package/lib/features/story/components/ListStoryVirtualScrollTrack.js +7 -0
  155. package/lib/{panelview/story-maps → features/story}/components/SpectaDesktopView.d.ts +4 -2
  156. package/lib/features/story/components/SpectaDesktopView.js +67 -0
  157. package/lib/{panelview/story-maps → features/story}/components/SpectaMobileView.d.ts +2 -4
  158. package/lib/{panelview/story-maps → features/story}/components/SpectaMobileView.js +3 -3
  159. package/lib/features/story/components/SpectaSingleModeContent.d.ts +18 -0
  160. package/lib/features/story/components/SpectaSingleModeContent.js +8 -0
  161. package/lib/features/story/context/ListStoryScrollTrackContext.d.ts +15 -0
  162. package/lib/features/story/context/ListStoryScrollTrackContext.js +142 -0
  163. package/lib/features/story/hooks/useCurrentSegmentIndex.d.ts +3 -0
  164. package/lib/features/story/hooks/useCurrentSegmentIndex.js +17 -0
  165. package/lib/features/story/hooks/useListStoryScroll.d.ts +15 -0
  166. package/lib/features/story/hooks/useListStoryScroll.js +107 -0
  167. package/lib/features/story/hooks/useQueuedMarkdownHeightMeasure.d.ts +19 -0
  168. package/lib/features/story/hooks/useQueuedMarkdownHeightMeasure.js +56 -0
  169. package/lib/features/story/hooks/useStoryImagePreload.d.ts +1 -0
  170. package/lib/features/story/hooks/useStoryImagePreload.js +24 -0
  171. package/lib/{panelview/story-maps → features/story}/hooks/useStoryMap.d.ts +2 -7
  172. package/lib/{panelview/story-maps → features/story}/hooks/useStoryMap.js +20 -44
  173. package/lib/features/story/hooks/useStoryScrollState.d.ts +21 -0
  174. package/lib/features/story/hooks/useStoryScrollState.js +39 -0
  175. package/lib/features/story/hooks/useStorySegmentSync.d.ts +8 -0
  176. package/lib/features/story/hooks/useStorySegmentSync.js +51 -0
  177. package/lib/features/story/types/types.d.ts +38 -0
  178. package/lib/features/story/types/types.js +1 -0
  179. package/lib/features/story/utils/computeListStoryScrollState.d.ts +12 -0
  180. package/lib/features/story/utils/computeListStoryScrollState.js +70 -0
  181. package/lib/features/story/utils/listStoryMeasureQueue.d.ts +11 -0
  182. package/lib/features/story/utils/listStoryMeasureQueue.js +14 -0
  183. package/lib/features/story/utils/listStoryScrollTrack.d.ts +17 -0
  184. package/lib/features/story/utils/listStoryScrollTrack.js +72 -0
  185. package/lib/features/story/utils/spectaPresentation.d.ts +9 -0
  186. package/lib/features/story/utils/spectaPresentation.js +37 -0
  187. package/lib/features/story/utils/storySegmentViewItems.d.ts +5 -0
  188. package/lib/features/story/utils/storySegmentViewItems.js +30 -0
  189. package/lib/index.d.ts +11 -9
  190. package/lib/index.js +11 -9
  191. package/lib/keybindings.json +5 -0
  192. package/lib/mainview/OpenEOTileLayer.d.ts +49 -0
  193. package/lib/mainview/OpenEOTileLayer.js +179 -0
  194. package/lib/mainview/TemporalSlider.js +11 -9
  195. package/lib/mainview/geoJsonFeaturePatch.d.ts +9 -0
  196. package/lib/mainview/geoJsonFeaturePatch.js +43 -0
  197. package/lib/mainview/mainView.d.ts +93 -8
  198. package/lib/mainview/mainView.js +1286 -529
  199. package/lib/mainview/mainviewwidget.d.ts +5 -1
  200. package/lib/mainview/mainviewwidget.js +4 -2
  201. package/lib/shared/components/Button.d.ts +1 -1
  202. package/lib/shared/components/DropdownMenu.d.ts +1 -0
  203. package/lib/shared/components/DropdownMenu.js +3 -2
  204. package/lib/shared/components/NativeSelect.d.ts +8 -0
  205. package/lib/shared/components/NativeSelect.js +29 -0
  206. package/lib/shared/components/Tabs.d.ts +3 -3
  207. package/lib/shared/components/Tabs.js +5 -5
  208. package/lib/{formbuilder → shared/formbuilder}/creationform.js +71 -4
  209. package/lib/{formbuilder → shared/formbuilder}/editform.js +1 -1
  210. package/lib/{formbuilder → shared/formbuilder}/formselectors.d.ts +2 -2
  211. package/lib/{formbuilder → shared/formbuilder}/formselectors.js +13 -4
  212. package/lib/shared/formbuilder/index.d.ts +4 -0
  213. package/lib/shared/formbuilder/index.js +4 -0
  214. package/lib/{formbuilder → shared/formbuilder}/objectform/SchemaForm.d.ts +1 -1
  215. package/lib/{formbuilder → shared/formbuilder}/objectform/StoryEditorForm.d.ts +1 -1
  216. package/lib/{formbuilder → shared/formbuilder}/objectform/StoryEditorForm.js +1 -1
  217. package/lib/{formbuilder → shared/formbuilder}/objectform/components/LayerSelect.js +1 -1
  218. package/lib/{formbuilder → shared/formbuilder}/objectform/components/SegmentFormSymbology.js +4 -4
  219. package/lib/{formbuilder → shared/formbuilder}/objectform/components/SourcePropertiesField.js +1 -1
  220. package/lib/{formbuilder → shared/formbuilder}/objectform/components/StorySegmentReset.js +1 -1
  221. package/lib/shared/formbuilder/objectform/components/WmsTileSourceUrlInput.d.ts +3 -0
  222. package/lib/shared/formbuilder/objectform/components/WmsTileSourceUrlInput.js +84 -0
  223. package/lib/{formbuilder → shared/formbuilder}/objectform/fileselectorwidget.js +8 -1
  224. package/lib/{formbuilder → shared/formbuilder}/objectform/schemaUtils.d.ts +3 -1
  225. package/lib/{formbuilder → shared/formbuilder}/objectform/schemaUtils.js +11 -0
  226. package/lib/{formbuilder → shared/formbuilder}/objectform/useSchemaFormState.d.ts +2 -2
  227. package/lib/{formbuilder → shared/formbuilder}/objectform/useSchemaFormState.js +1 -1
  228. package/lib/{icons.d.ts → shared/icons.d.ts} +2 -0
  229. package/lib/{icons.js → shared/icons.js} +28 -18
  230. package/lib/tools.d.ts +3 -1
  231. package/lib/tools.js +140 -6
  232. package/lib/types.d.ts +12 -1
  233. package/lib/types.js +6 -1
  234. package/lib/{menus.js → workspace/menus.js} +14 -2
  235. package/lib/workspace/panels/components/TabbedPanel.d.ts +17 -0
  236. package/lib/workspace/panels/components/TabbedPanel.js +19 -0
  237. package/lib/{panelview → workspace/panels}/components/layers.js +82 -20
  238. package/lib/workspace/panels/components/legendItem.js +680 -0
  239. package/lib/workspace/panels/hooks/useLayerTree.d.ts +19 -0
  240. package/lib/workspace/panels/hooks/useLayerTree.js +103 -0
  241. package/lib/workspace/panels/hooks/useRightPanelOptions.d.ts +27 -0
  242. package/lib/workspace/panels/hooks/useRightPanelOptions.js +72 -0
  243. package/lib/workspace/panels/hooks/useUIState.d.ts +2 -0
  244. package/lib/workspace/panels/hooks/useUIState.js +25 -0
  245. package/lib/{panelview → workspace/panels}/index.d.ts +1 -1
  246. package/lib/{panelview → workspace/panels}/index.js +1 -1
  247. package/lib/{panelview → workspace/panels}/leftpanel.d.ts +1 -1
  248. package/lib/workspace/panels/leftpanel.js +70 -0
  249. package/lib/{panelview/rightpanel.d.ts → workspace/panels/mergedpanel.d.ts} +6 -5
  250. package/lib/workspace/panels/mergedpanel.js +166 -0
  251. package/lib/workspace/panels/rightpanel.d.ts +25 -0
  252. package/lib/{panelview → workspace/panels}/rightpanel.js +53 -63
  253. package/lib/{statusbar → workspace/statusbar}/StatusBar.js +5 -4
  254. package/lib/{toolbar → workspace/toolbar}/widget.d.ts +2 -0
  255. package/lib/{toolbar → workspace/toolbar}/widget.js +33 -5
  256. package/lib/{widget.d.ts → workspace/widget.d.ts} +7 -5
  257. package/lib/{widget.js → workspace/widget.js} +16 -7
  258. package/package.json +19 -4
  259. package/style/base.css +109 -1
  260. package/style/icons/geopackage.svg +95 -0
  261. package/style/icons/pencil_solid.svg +7 -0
  262. package/style/identify.css +95 -0
  263. package/style/layerBrowser.css +28 -0
  264. package/style/leftPanel.css +25 -0
  265. package/style/shared/button.css +12 -0
  266. package/style/shared/dropdownMenu.css +9 -0
  267. package/style/shared/nativeSelect.css +75 -0
  268. package/style/shared/tabs.css +3 -3
  269. package/style/spectaProgressBar.css +0 -1
  270. package/style/storyPanel.css +142 -9
  271. package/style/storySpectaArticleOverlay.css +129 -0
  272. package/style/symbologyDialog.css +330 -28
  273. package/lib/dialogs/symbology/colorRampUtils.d.ts +0 -20
  274. package/lib/dialogs/symbology/colorRampUtils.js +0 -132
  275. package/lib/dialogs/symbology/symbologyUtils.d.ts +0 -33
  276. package/lib/dialogs/symbology/symbologyUtils.js +0 -180
  277. package/lib/dialogs/symbology/tiff_layer/TiffRendering.d.ts +0 -4
  278. package/lib/dialogs/symbology/tiff_layer/TiffRendering.js +0 -42
  279. package/lib/dialogs/symbology/tiff_layer/components/BandRow.d.ts +0 -23
  280. package/lib/dialogs/symbology/tiff_layer/components/BandRow.js +0 -59
  281. package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.d.ts +0 -4
  282. package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +0 -92
  283. package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.d.ts +0 -5
  284. package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +0 -301
  285. package/lib/dialogs/symbology/vector_layer/VectorRendering.d.ts +0 -4
  286. package/lib/dialogs/symbology/vector_layer/VectorRendering.js +0 -112
  287. package/lib/dialogs/symbology/vector_layer/components/ValueSelect.d.ts +0 -8
  288. package/lib/dialogs/symbology/vector_layer/components/ValueSelect.js +0 -9
  289. package/lib/dialogs/symbology/vector_layer/types/Canonical.d.ts +0 -4
  290. package/lib/dialogs/symbology/vector_layer/types/Canonical.js +0 -65
  291. package/lib/dialogs/symbology/vector_layer/types/Categorized.d.ts +0 -4
  292. package/lib/dialogs/symbology/vector_layer/types/Categorized.js +0 -196
  293. package/lib/dialogs/symbology/vector_layer/types/Graduated.d.ts +0 -4
  294. package/lib/dialogs/symbology/vector_layer/types/Graduated.js +0 -250
  295. package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.d.ts +0 -4
  296. package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.js +0 -105
  297. package/lib/formbuilder/index.d.ts +0 -4
  298. package/lib/formbuilder/index.js +0 -4
  299. package/lib/formbuilder/objectform/layer/storySegmentLayerForm.js +0 -95
  300. package/lib/formbuilder/objectform/layer/webGlLayerForm.d.ts +0 -3
  301. package/lib/formbuilder/objectform/process/index.d.ts +0 -1
  302. package/lib/formbuilder/objectform/process/index.js +0 -1
  303. package/lib/panelview/components/legendItem.js +0 -200
  304. package/lib/panelview/identify-panel/IdentifyPanel.js +0 -102
  305. package/lib/panelview/leftpanel.js +0 -139
  306. package/lib/panelview/story-maps/StoryViewerPanel.js +0 -116
  307. package/lib/panelview/story-maps/components/SpectaDesktopView.js +0 -49
  308. package/lib/processing/index.js +0 -200
  309. package/lib/processing/processingCommands.js +0 -67
  310. /package/lib/{panelview/annotationPanel.d.ts → features/annotations/AnnotationsPanel.d.ts} +0 -0
  311. /package/lib/{annotations → features/annotations}/components/Annotation.d.ts +0 -0
  312. /package/lib/{annotations → features/annotations}/components/Annotation.js +0 -0
  313. /package/lib/{annotations → features/annotations}/components/AnnotationFloater.d.ts +0 -0
  314. /package/lib/{annotations → features/annotations}/components/AnnotationFloater.js +0 -0
  315. /package/lib/{annotations → features/annotations}/components/Message.d.ts +0 -0
  316. /package/lib/{annotations → features/annotations}/components/Message.js +0 -0
  317. /package/lib/{annotations → features/annotations}/model.d.ts +0 -0
  318. /package/lib/{annotations → features/annotations}/model.js +0 -0
  319. /package/lib/{console → features/console}/consoleview.d.ts +0 -0
  320. /package/lib/{console → features/console}/index.d.ts +0 -0
  321. /package/lib/{console → features/console}/index.js +0 -0
  322. /package/lib/{panelview/filter-panel → features/filter}/Filter.d.ts +0 -0
  323. /package/lib/{stacBrowser/types/types.js → features/identify/types/editorTypes.js} +0 -0
  324. /package/lib/{dialogs/layerBrowserDialog.d.ts → features/layer-browser/index.d.ts} +0 -0
  325. /package/lib/{formbuilder/objectform → features/layers/forms}/layer/heatmapLayerForm.d.ts +0 -0
  326. /package/lib/{formbuilder/objectform → features/layers/forms}/layer/hillshadeLayerForm.d.ts +0 -0
  327. /package/lib/{formbuilder/objectform → features/layers/forms}/layer/storySegmentLayerForm.d.ts +0 -0
  328. /package/lib/{formbuilder/objectform → features/layers/forms}/layer/vectorlayerform.d.ts +0 -0
  329. /package/lib/{formbuilder/objectform → features/layers/forms}/source/geojsonsource.d.ts +0 -0
  330. /package/lib/{formbuilder/objectform → features/layers/forms}/source/geotiffsource.d.ts +0 -0
  331. /package/lib/{formbuilder/objectform → features/layers/forms}/source/pathbasedsource.d.ts +0 -0
  332. /package/lib/{formbuilder/objectform → features/layers/forms}/source/tilesourceform.d.ts +0 -0
  333. /package/lib/{dialogs → features/layers}/symbology/components/color_ramp/ModeSelectRow.js +0 -0
  334. /package/lib/{dialogs → features/layers}/symbology/components/color_ramp/cmocean.json +0 -0
  335. /package/lib/{dialogs → features/layers}/symbology/components/color_stops/StopContainer.d.ts +0 -0
  336. /package/lib/{dialogs → features/layers}/symbology/hooks/useEffectiveSymbologyParams.d.ts +0 -0
  337. /package/lib/{dialogs → features/layers}/symbology/hooks/useEffectiveSymbologyParams.js +0 -0
  338. /package/lib/{dialogs → features/layers}/symbology/hooks/useGetProperties.d.ts +0 -0
  339. /package/lib/{dialogs → features/layers}/symbology/hooks/useGetSymbology.d.ts +0 -0
  340. /package/lib/{dialogs → features/layers}/symbology/hooks/useOkSignal.d.ts +0 -0
  341. /package/lib/{dialogs → features/layers}/symbology/hooks/useOkSignal.js +0 -0
  342. /package/lib/{formbuilder/objectform/process → features/processing/forms}/dissolveProcessForm.d.ts +0 -0
  343. /package/lib/{processing → features/processing}/processingFormToParam.d.ts +0 -0
  344. /package/lib/{processing → features/processing}/processingFormToParam.js +0 -0
  345. /package/lib/{stacBrowser → features/stac-browser}/components/StacPanel.d.ts +0 -0
  346. /package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/QueryableComboBox.d.ts +0 -0
  347. /package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/QueryableRow.d.ts +0 -0
  348. /package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/StacFilterExtensionPanel.d.ts +0 -0
  349. /package/lib/{stacBrowser → features/stac-browser}/components/filter-extension/StacQueryableFilters.d.ts +0 -0
  350. /package/lib/{stacBrowser → features/stac-browser}/components/geodes/StacFilterSection.d.ts +0 -0
  351. /package/lib/{stacBrowser → features/stac-browser}/components/geodes/StacGeodesFilterPanel.d.ts +0 -0
  352. /package/lib/{stacBrowser → features/stac-browser}/components/geodes/StacGeodesFilterPanel.js +0 -0
  353. /package/lib/{stacBrowser → features/stac-browser}/components/shared/StacPanelResults.d.ts +0 -0
  354. /package/lib/{stacBrowser → features/stac-browser}/components/shared/StacSpatialExtent.d.ts +0 -0
  355. /package/lib/{stacBrowser → features/stac-browser}/components/shared/StacTemporalExtent.d.ts +0 -0
  356. /package/lib/{stacBrowser → features/stac-browser}/constants.d.ts +0 -0
  357. /package/lib/{stacBrowser → features/stac-browser}/constants.js +0 -0
  358. /package/lib/{stacBrowser → features/stac-browser}/context/StacResultsContext.d.ts +0 -0
  359. /package/lib/{stacBrowser → features/stac-browser}/hooks/useGeodesSearch.d.ts +0 -0
  360. /package/lib/{stacBrowser → features/stac-browser}/index.d.ts +0 -0
  361. /package/lib/{stacBrowser → features/stac-browser}/index.js +0 -0
  362. /package/lib/{stacBrowser → features/stac-browser}/types/types.d.ts +0 -0
  363. /package/lib/{panelview/story-maps → features/story}/StoryEditorPanel.d.ts +0 -0
  364. /package/lib/{panelview/story-maps → features/story}/components/PreviewModeSwitch.d.ts +0 -0
  365. /package/lib/{panelview/story-maps → features/story}/components/PreviewModeSwitch.js +0 -0
  366. /package/lib/{panelview/story-maps → features/story}/components/StoryContentSection.d.ts +0 -0
  367. /package/lib/{panelview/story-maps → features/story}/components/StoryContentSection.js +0 -0
  368. /package/lib/{panelview/story-maps → features/story}/components/StoryImageSection.d.ts +0 -0
  369. /package/lib/{panelview/story-maps → features/story}/components/StoryImageSection.js +0 -0
  370. /package/lib/{panelview/story-maps → features/story}/components/StoryNavBar.d.ts +0 -0
  371. /package/lib/{panelview/story-maps → features/story}/components/StoryNavBar.js +0 -0
  372. /package/lib/{panelview/story-maps → features/story}/components/StorySubtitleSection.d.ts +0 -0
  373. /package/lib/{panelview/story-maps → features/story}/components/StorySubtitleSection.js +0 -0
  374. /package/lib/{panelview/story-maps → features/story}/components/StoryTitleSection.d.ts +0 -0
  375. /package/lib/{panelview/story-maps → features/story}/components/StoryTitleSection.js +0 -0
  376. /package/lib/{formbuilder → shared/formbuilder}/creationform.d.ts +0 -0
  377. /package/lib/{formbuilder → shared/formbuilder}/editform.d.ts +0 -0
  378. /package/lib/{formbuilder → shared/formbuilder}/objectform/SchemaForm.js +0 -0
  379. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/LayerSelect.d.ts +0 -0
  380. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/OpacitySlider.d.ts +0 -0
  381. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/OpacitySlider.js +0 -0
  382. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/SegmentFormSymbology.d.ts +0 -0
  383. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/SourcePropertiesField.d.ts +0 -0
  384. /package/lib/{formbuilder → shared/formbuilder}/objectform/components/StorySegmentReset.d.ts +0 -0
  385. /package/lib/{formbuilder → shared/formbuilder}/objectform/fileselectorwidget.d.ts +0 -0
  386. /package/lib/{store.d.ts → shared/store.d.ts} +0 -0
  387. /package/lib/{store.js → shared/store.js} +0 -0
  388. /package/lib/{menus.d.ts → workspace/menus.d.ts} +0 -0
  389. /package/lib/{panelview → workspace/panels}/components/layers.d.ts +0 -0
  390. /package/lib/{panelview → workspace/panels}/components/legendItem.d.ts +0 -0
  391. /package/lib/{panelview → workspace/panels}/header.d.ts +0 -0
  392. /package/lib/{panelview → workspace/panels}/header.js +0 -0
  393. /package/lib/{statusbar → workspace/statusbar}/SpectaPresentationProgressBar.d.ts +0 -0
  394. /package/lib/{statusbar → workspace/statusbar}/SpectaPresentationProgressBar.js +0 -0
  395. /package/lib/{statusbar → workspace/statusbar}/StatusBar.d.ts +0 -0
  396. /package/lib/{toolbar → workspace/toolbar}/index.d.ts +0 -0
  397. /package/lib/{toolbar → workspace/toolbar}/index.js +0 -0
@@ -0,0 +1,680 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { getColorMap, } from "../../../features/layers/symbology/colorRampUtils";
3
+ import { useGetSymbology } from "../../../features/layers/symbology/hooks/useGetSymbology";
4
+ // ---------------------------------------------------------------------------
5
+ // Colour helpers
6
+ // ---------------------------------------------------------------------------
7
+ function rgbaToString([r, g, b, a]) {
8
+ return `rgba(${r},${g},${b},${a})`;
9
+ }
10
+ function rampColors(name, n = 7) {
11
+ const map = getColorMap(name);
12
+ if (!map || !map.colors.length) {
13
+ return ['#000', '#fff'];
14
+ }
15
+ const colors = map.colors;
16
+ if (colors.length <= n) {
17
+ return colors;
18
+ }
19
+ // Sample n evenly-spaced colours from the full ramp.
20
+ const step = (colors.length - 1) / (n - 1);
21
+ return Array.from({ length: n }, (_, i) => colors[Math.round(i * step)]);
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // Value formatting
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Format a numeric tick value using at most `sigDigits` significant digits.
28
+ * Uses exponential notation for very large or very small values.
29
+ */
30
+ function formatTickValue(v, sigDigits) {
31
+ if (v === 0) {
32
+ return '0';
33
+ }
34
+ const abs = Math.abs(v);
35
+ if (abs >= 0.01 && abs < 1e6) {
36
+ return parseFloat(v.toPrecision(sigDigits)).toString();
37
+ }
38
+ return v.toExponential(sigDigits - 1);
39
+ }
40
+ /** Linearly interpolate a scalar mapping's output at a given stop value. */
41
+ function interpolateScalar(scalarStops, value) {
42
+ if (scalarStops.length === 0) {
43
+ return 1;
44
+ }
45
+ if (value <= scalarStops[0].stop) {
46
+ return scalarStops[0].output;
47
+ }
48
+ if (value >= scalarStops[scalarStops.length - 1].stop) {
49
+ return scalarStops[scalarStops.length - 1].output;
50
+ }
51
+ for (let i = 0; i < scalarStops.length - 1; i++) {
52
+ const lo = scalarStops[i];
53
+ const hi = scalarStops[i + 1];
54
+ if (value >= lo.stop && value <= hi.stop) {
55
+ const t = (value - lo.stop) / (hi.stop - lo.stop);
56
+ return lo.output + t * (hi.output - lo.output);
57
+ }
58
+ }
59
+ return 1;
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Channel label helpers
63
+ // ---------------------------------------------------------------------------
64
+ /**
65
+ * Derive a single human-readable label for a set of output channels.
66
+ * Multiple channels often cover the same logical property for different
67
+ * geometry types (e.g. fill-color + circle-fill-color → "Fill color").
68
+ */
69
+ function deriveChannelLabel(channels) {
70
+ var _a;
71
+ const set = new Set(channels);
72
+ // Colour channels — combine geometry variants where both are present.
73
+ const hasFillPoly = set.has('fill-color');
74
+ const hasFillCircle = set.has('circle-fill-color');
75
+ const hasStrokeColorLine = set.has('stroke-color');
76
+ const hasStrokeColorCircle = set.has('circle-stroke-color');
77
+ const hasFill = hasFillPoly || hasFillCircle;
78
+ const hasStrokeColor = hasStrokeColorLine || hasStrokeColorCircle;
79
+ if (hasFill && hasStrokeColor) {
80
+ return 'Fill & stroke color';
81
+ }
82
+ if (hasFill) {
83
+ if (hasFillPoly && hasFillCircle) {
84
+ return 'Fill color';
85
+ }
86
+ return hasFillPoly ? 'Fill color (polygon)' : 'Fill color (circle)';
87
+ }
88
+ if (hasStrokeColor) {
89
+ if (hasStrokeColorLine && hasStrokeColorCircle) {
90
+ return 'Stroke color';
91
+ }
92
+ return hasStrokeColorLine ? 'Stroke color (line)' : 'Stroke color (circle)';
93
+ }
94
+ // Width channels.
95
+ const hasWidthLine = set.has('stroke-width');
96
+ const hasWidthCircle = set.has('circle-stroke-width');
97
+ if (hasWidthLine && hasWidthCircle) {
98
+ return 'Stroke width';
99
+ }
100
+ if (hasWidthLine) {
101
+ return 'Stroke width (line)';
102
+ }
103
+ if (hasWidthCircle) {
104
+ return 'Stroke width (circle)';
105
+ }
106
+ if (set.has('circle-radius')) {
107
+ return 'Radius';
108
+ }
109
+ // Pixel channels (raster / KDE).
110
+ if (set.has('pixel-color')) {
111
+ return 'pixel-rgba';
112
+ }
113
+ if (set.has('pixel-rgb')) {
114
+ return 'pixel-rgb';
115
+ }
116
+ if (set.has('pixel-red')) {
117
+ return 'pixel-red';
118
+ }
119
+ if (set.has('pixel-green')) {
120
+ return 'pixel-green';
121
+ }
122
+ if (set.has('pixel-blue')) {
123
+ return 'pixel-blue';
124
+ }
125
+ if (set.has('pixel-alpha')) {
126
+ return 'pixel-alpha';
127
+ }
128
+ return (_a = channels[0]) !== null && _a !== void 0 ? _a : '';
129
+ }
130
+ /** Format a single predicate into a short human-readable string. */
131
+ function formatPredicate(p) {
132
+ switch (p.type) {
133
+ case 'geometryType':
134
+ return p.value;
135
+ case 'hasField':
136
+ return `has ${p.field}`;
137
+ case 'fieldEquals':
138
+ return `${p.field} = ${p.value}`;
139
+ case 'fieldCompare':
140
+ return `${p.field} ${p.op} ${p.value}`;
141
+ case 'between':
142
+ return `${p.field} between ${p.min} and ${p.max}`;
143
+ }
144
+ }
145
+ /** Format a when clause (AND-ed predicates) into a single string. */
146
+ function formatWhen(when) {
147
+ if (!when || when.length === 0) {
148
+ return undefined;
149
+ }
150
+ return when.map(formatPredicate).join(' & ');
151
+ }
152
+ // ---------------------------------------------------------------------------
153
+ // Grammar → LegendEntry[]
154
+ // ---------------------------------------------------------------------------
155
+ const COLOR_CHANNELS = new Set([
156
+ 'fill-color',
157
+ 'circle-fill-color',
158
+ 'stroke-color',
159
+ 'circle-stroke-color',
160
+ 'pixel-color', // full RGBA (shown as "pixel-rgba" in the UI)
161
+ 'pixel-rgb', // virtual: fans out to pixel-red/green/blue
162
+ 'pixel-red',
163
+ 'pixel-green',
164
+ 'pixel-blue',
165
+ 'pixel-alpha',
166
+ ]);
167
+ const SIZE_CHANNELS = new Set(['circle-radius']);
168
+ const STROKE_WIDTH_CHANNELS = new Set(['stroke-width', 'circle-stroke-width']);
169
+ function kdeToLegendEntries(grammarLayer, kdeTransform) {
170
+ const entries = [];
171
+ // "Normalized density" or "Normalized density (weight: <field>)" as the input descriptor.
172
+ const densityLabel = kdeTransform.weightField
173
+ ? `Normalized density (weight: ${kdeTransform.weightField})`
174
+ : 'Normalized density';
175
+ for (const rule of grammarLayer.rules) {
176
+ for (const mapping of rule.mappings) {
177
+ const isPixelChannel = mapping.channels.some(ch => ch === 'pixel-color' || ch.startsWith('pixel-'));
178
+ if (!isPixelChannel || mapping.scale.scheme !== 'colorRamp') {
179
+ continue;
180
+ }
181
+ const p = mapping.scale.params;
182
+ if (p.colorStops && p.colorStops.length >= 2) {
183
+ const colorStrs = p.colorStops.map(s => rgbaToString(s.color));
184
+ entries.push({
185
+ type: 'gradient',
186
+ field: densityLabel,
187
+ channel: 'Heatmap color',
188
+ colors: colorStrs,
189
+ stops: p.colorStops.map((s, i) => ({
190
+ value: s.stop,
191
+ color: colorStrs[i],
192
+ })),
193
+ tickMode: 'value',
194
+ });
195
+ }
196
+ else {
197
+ // No stops yet — OL normalizes density to [0, 1].
198
+ const colors = rampColors(p.name);
199
+ const ramp = p.reverse ? [...colors].reverse() : colors;
200
+ entries.push({
201
+ type: 'gradient',
202
+ field: densityLabel,
203
+ channel: 'Heatmap color',
204
+ colors: ramp,
205
+ stops: [
206
+ { value: 0, color: ramp[0] },
207
+ { value: 1, color: ramp[ramp.length - 1] },
208
+ ],
209
+ });
210
+ }
211
+ }
212
+ }
213
+ // Fallback when no colorRamp rule is found.
214
+ if (entries.length === 0) {
215
+ const colors = ['#00f', '#0ff', '#0f0', '#ff0', '#f00'];
216
+ entries.push({
217
+ type: 'gradient',
218
+ field: densityLabel,
219
+ channel: 'Heatmap color',
220
+ colors,
221
+ stops: [
222
+ { value: 0, color: colors[0] },
223
+ { value: 1, color: colors[colors.length - 1] },
224
+ ],
225
+ });
226
+ }
227
+ return entries;
228
+ }
229
+ function grammarToLegendEntries(state) {
230
+ var _a, _b, _c, _d, _e, _f, _g, _h;
231
+ const entries = [];
232
+ for (const grammarLayer of (_a = state.layers) !== null && _a !== void 0 ? _a : []) {
233
+ const kdeTransform = (_b = grammarLayer.preprocess) === null || _b === void 0 ? void 0 : _b.find((t) => t.type === 'kde');
234
+ if (kdeTransform) {
235
+ entries.push(...kdeToLegendEntries(grammarLayer, kdeTransform));
236
+ continue;
237
+ }
238
+ // Look for a pixel-alpha scalar mapping anywhere in this grammar layer.
239
+ // It is often in a separate rule from the color mapping (e.g. COG layers).
240
+ const layerAlphaMapping = grammarLayer.rules
241
+ .flatMap(r => r.mappings)
242
+ .find(m => {
243
+ var _a, _b, _c;
244
+ return m.channels.includes('pixel-alpha') &&
245
+ m.scale.scheme === 'scalar' &&
246
+ ((_c = (_b = (_a = m.scale.params) === null || _a === void 0 ? void 0 : _a.scalarStops) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) >= 2;
247
+ });
248
+ const layerAlphaScalarStops = (_e = (_d = (_c = layerAlphaMapping === null || layerAlphaMapping === void 0 ? void 0 : layerAlphaMapping.scale) === null || _c === void 0 ? void 0 : _c.params) === null || _d === void 0 ? void 0 : _d.scalarStops) !== null && _e !== void 0 ? _e : [];
249
+ const layerWhen = (_f = grammarLayer.when) !== null && _f !== void 0 ? _f : [];
250
+ for (const rule of grammarLayer.rules) {
251
+ const field = (_g = rule.fields) === null || _g === void 0 ? void 0 : _g[0];
252
+ const allWhen = [...layerWhen, ...((_h = rule.when) !== null && _h !== void 0 ? _h : [])];
253
+ const whenLbl = formatWhen(allWhen.length > 0 ? allWhen : undefined);
254
+ for (const mapping of rule.mappings) {
255
+ const { scale, channels } = mapping;
256
+ // Determine which logical channel family this mapping targets.
257
+ const isColor = channels.some(ch => COLOR_CHANNELS.has(ch));
258
+ const isSize = channels.some(ch => SIZE_CHANNELS.has(ch));
259
+ const isStrokeWidth = channels.some(ch => STROKE_WIDTH_CHANNELS.has(ch));
260
+ // Skip the alpha mapping itself — it's shown implicitly via withAlpha.
261
+ if (channels.includes('pixel-alpha')) {
262
+ continue;
263
+ }
264
+ const channelLbl = deriveChannelLabel(channels);
265
+ const isPixelChannel = channels.some(ch => ch === 'pixel-color' || ch.startsWith('pixel-'));
266
+ const withAlpha = isPixelChannel && layerAlphaScalarStops.length >= 2;
267
+ if (isColor) {
268
+ switch (scale.scheme) {
269
+ case 'colorRamp': {
270
+ const p = scale.params;
271
+ if (p.colorStops && p.colorStops.length >= 2) {
272
+ // When alpha is driven by a companion scalar, clip the displayed
273
+ // gradient and ticks to the scalar's effective domain — beyond
274
+ // it alpha is either 0 (invisible) or constant (fully opaque),
275
+ // so the meaningful field range is [alphaMin, alphaMax].
276
+ let displayStops = p.colorStops;
277
+ if (withAlpha && layerAlphaScalarStops.length >= 2) {
278
+ const alphaMin = layerAlphaScalarStops[0].stop;
279
+ const alphaMax = layerAlphaScalarStops[layerAlphaScalarStops.length - 1]
280
+ .stop;
281
+ const clipped = p.colorStops.filter(s => s.stop >= alphaMin && s.stop <= alphaMax);
282
+ if (clipped.length >= 2) {
283
+ displayStops = clipped;
284
+ }
285
+ }
286
+ const colorStrs = displayStops.map(s => {
287
+ const [r, g, b] = s.color;
288
+ const a = withAlpha
289
+ ? interpolateScalar(layerAlphaScalarStops, s.stop)
290
+ : s.color[3];
291
+ return `rgba(${r},${g},${b},${a})`;
292
+ });
293
+ entries.push({
294
+ type: 'gradient',
295
+ field,
296
+ channel: channelLbl,
297
+ when: whenLbl,
298
+ colors: colorStrs,
299
+ stops: displayStops.map((s, i) => ({
300
+ value: s.stop,
301
+ color: colorStrs[i],
302
+ })),
303
+ withAlpha,
304
+ });
305
+ }
306
+ else {
307
+ // No colorStops yet — show a preview gradient from the ramp name.
308
+ const colors = rampColors(p.name);
309
+ const preview = {
310
+ type: 'gradient',
311
+ field,
312
+ channel: channelLbl,
313
+ when: whenLbl,
314
+ colors,
315
+ withAlpha,
316
+ };
317
+ if (p.domain) {
318
+ // Domain is known: show min/max ticks.
319
+ preview.stops = [
320
+ { value: p.domain[0], color: colors[0] },
321
+ { value: p.domain[1], color: colors[colors.length - 1] },
322
+ ];
323
+ }
324
+ else {
325
+ // No domain yet: label the ends so users know the scale exists.
326
+ preview.endLabels = ['min', 'max'];
327
+ }
328
+ entries.push(preview);
329
+ }
330
+ break;
331
+ }
332
+ case 'categorical': {
333
+ const p = scale.params;
334
+ if (p.colorStops && p.colorStops.length > 0) {
335
+ entries.push({
336
+ type: 'categorical',
337
+ field,
338
+ channel: channelLbl,
339
+ when: whenLbl,
340
+ stops: p.colorStops.map(s => ({
341
+ label: String(s.stop),
342
+ color: rgbaToString(s.color),
343
+ })),
344
+ });
345
+ }
346
+ // No colorStops → skip (categories not yet loaded).
347
+ break;
348
+ }
349
+ case 'constant_rgba': {
350
+ const color = rgbaToString(scale.params.value);
351
+ entries.push({
352
+ type: 'swatch',
353
+ label: channelLbl,
354
+ color,
355
+ when: whenLbl,
356
+ });
357
+ break;
358
+ }
359
+ case 'identity': {
360
+ // Field value is used as-is for the channel color.
361
+ // No fixed range to display — show a rainbow swatch indicating
362
+ // the channel is data-driven.
363
+ entries.push({
364
+ type: 'swatch',
365
+ field,
366
+ label: channelLbl,
367
+ color: 'linear-gradient(to right,#f66,#fa0,#ff0,#6c6,#08f,#94f)',
368
+ when: whenLbl,
369
+ });
370
+ break;
371
+ }
372
+ // expression / constant_num on color channel: skip.
373
+ default:
374
+ break;
375
+ }
376
+ }
377
+ else if (isSize && scale.scheme === 'scalar') {
378
+ const p = scale.params;
379
+ entries.push({
380
+ type: 'size',
381
+ field,
382
+ channel: channelLbl,
383
+ when: whenLbl,
384
+ minSize: p.range[0],
385
+ maxSize: p.range[1],
386
+ domain: p.domain,
387
+ });
388
+ }
389
+ else if (isStrokeWidth && scale.scheme === 'scalar') {
390
+ const p = scale.params;
391
+ entries.push({
392
+ type: 'stroke-width',
393
+ field,
394
+ channel: channelLbl,
395
+ when: whenLbl,
396
+ minWidth: p.range[0],
397
+ maxWidth: p.range[1],
398
+ domain: p.domain,
399
+ });
400
+ }
401
+ }
402
+ }
403
+ }
404
+ return entries;
405
+ }
406
+ // ---------------------------------------------------------------------------
407
+ // Individual legend entry renderers
408
+ // ---------------------------------------------------------------------------
409
+ /**
410
+ * Shared header shown above every data-driven legend entry.
411
+ *
412
+ * best_age_top ← input field (bold)
413
+ * → Stroke width ← output channel (muted)
414
+ * if: Polygon ← when clause (muted, only when present)
415
+ */
416
+ const EntryHeader = ({ field, channel, when }) => {
417
+ if (!field && !channel && !when) {
418
+ return null;
419
+ }
420
+ return (React.createElement("div", { style: {
421
+ display: 'flex',
422
+ flexWrap: 'wrap',
423
+ alignItems: 'baseline',
424
+ gap: '0 4px',
425
+ marginBottom: 6,
426
+ fontSize: '0.78em',
427
+ } },
428
+ field && React.createElement("span", { style: { fontWeight: 'bold' } }, field),
429
+ channel && React.createElement("span", { style: { opacity: 0.7 } },
430
+ "\u2192 ",
431
+ channel),
432
+ when && React.createElement("span", { style: { opacity: 0.6 } },
433
+ "\u00B7 if: ",
434
+ when)));
435
+ };
436
+ const CHECKERBOARD = {
437
+ position: 'absolute',
438
+ inset: 0,
439
+ borderRadius: 3,
440
+ backgroundImage: 'repeating-conic-gradient(#bbb 0% 25%, #fff 0% 50%)',
441
+ backgroundSize: '8px 8px',
442
+ };
443
+ /** Small square swatch with checkerboard backing to reveal alpha. */
444
+ const ColorSwatch = ({ color, size = 14, }) => (React.createElement("span", { style: {
445
+ position: 'relative',
446
+ display: 'inline-block',
447
+ flexShrink: 0,
448
+ width: size,
449
+ height: size,
450
+ borderRadius: 2,
451
+ border: '1px solid #000',
452
+ overflow: 'hidden',
453
+ } },
454
+ React.createElement("span", { style: CHECKERBOARD }),
455
+ React.createElement("span", { style: { position: 'absolute', inset: 0, background: color } })));
456
+ const GradientLegend = ({ field, channel, when, colors, stops, tickMode = 'index', sigDigits = 2, endLabels, withAlpha, }) => {
457
+ const barRef = useRef(null);
458
+ const [barWidth, setBarWidth] = useState(0);
459
+ useEffect(() => {
460
+ const el = barRef.current;
461
+ if (!el) {
462
+ return;
463
+ }
464
+ const ro = new ResizeObserver(entries => {
465
+ setBarWidth(entries[0].contentRect.width);
466
+ });
467
+ ro.observe(el);
468
+ return () => ro.disconnect();
469
+ }, []);
470
+ const gradient = `linear-gradient(to right, ${colors.join(', ')})`;
471
+ // Determine which stops are visible as ticks.
472
+ let visibleStops = stops !== null && stops !== void 0 ? stops : [];
473
+ if (stops && stops.length >= 2 && tickMode === 'value' && barWidth > 0) {
474
+ // Estimate the width of the widest label and subsample to avoid overlap.
475
+ const charPx = 6;
476
+ const minGapPx = 4;
477
+ const maxLabelPx = Math.max(...stops.map(s => formatTickValue(s.value, sigDigits).length)) *
478
+ charPx +
479
+ minGapPx;
480
+ const maxTicks = Math.max(2, Math.floor(barWidth / maxLabelPx));
481
+ if (stops.length > maxTicks) {
482
+ visibleStops = Array.from({ length: maxTicks }, (_, i) => stops[Math.round((i * (stops.length - 1)) / (maxTicks - 1))]);
483
+ }
484
+ }
485
+ const min = visibleStops.length >= 2 ? visibleStops[0].value : 0;
486
+ const max = visibleStops.length >= 2 ? visibleStops[visibleStops.length - 1].value : 1;
487
+ const valueRange = max - min || 1;
488
+ return (React.createElement("div", { style: { padding: '6px 6px 10px' } },
489
+ React.createElement(EntryHeader, { field: field, channel: channel, when: when }),
490
+ React.createElement("div", { ref: barRef, style: { marginBottom: 4 } },
491
+ React.createElement("div", { style: { position: 'relative', height: 12 } },
492
+ withAlpha && React.createElement("div", { style: CHECKERBOARD }),
493
+ React.createElement("div", { style: {
494
+ position: 'absolute',
495
+ inset: 0,
496
+ background: gradient,
497
+ border: '1px solid #ccc',
498
+ borderRadius: 3,
499
+ } })),
500
+ visibleStops.length >= 2 && (React.createElement("div", { style: { position: 'relative', height: 18, marginTop: 2 } }, visibleStops.map((s, i) => {
501
+ const pct = tickMode === 'value'
502
+ ? ((s.value - min) / valueRange) * 100
503
+ : (i / (visibleStops.length - 1)) * 100;
504
+ const isFirst = i === 0;
505
+ const isLast = i === visibleStops.length - 1;
506
+ return (React.createElement("div", { key: i, style: {
507
+ position: 'absolute',
508
+ left: `${pct}%`,
509
+ transform: isFirst
510
+ ? 'none'
511
+ : isLast
512
+ ? 'translateX(-100%)'
513
+ : 'translateX(-50%)',
514
+ display: 'flex',
515
+ flexDirection: 'column',
516
+ alignItems: isFirst
517
+ ? 'flex-start'
518
+ : isLast
519
+ ? 'flex-end'
520
+ : 'center',
521
+ } },
522
+ React.createElement("div", { style: { width: 1, height: 4, background: '#888' } }),
523
+ React.createElement("div", { style: { fontSize: '0.7em', whiteSpace: 'nowrap' } }, formatTickValue(s.value, sigDigits))));
524
+ }))),
525
+ endLabels && !visibleStops.length && (React.createElement("div", { style: {
526
+ display: 'flex',
527
+ justifyContent: 'space-between',
528
+ fontSize: '0.7em',
529
+ marginTop: 2,
530
+ } },
531
+ React.createElement("span", null, endLabels[0]),
532
+ React.createElement("span", null, endLabels[1]))))));
533
+ };
534
+ const CategoricalLegend = ({ field, channel, when, stops, }) => (React.createElement("div", { style: { padding: 6 } },
535
+ React.createElement(EntryHeader, { field: field, channel: channel, when: when }),
536
+ React.createElement("div", { style: {
537
+ display: 'grid',
538
+ gap: 4,
539
+ maxHeight: 180,
540
+ overflowY: 'auto',
541
+ paddingRight: 4,
542
+ } }, stops.map((s, i) => (React.createElement("div", { key: i, style: { display: 'flex', alignItems: 'center', gap: 8 } },
543
+ React.createElement(ColorSwatch, { color: s.color || '#ccc' }),
544
+ React.createElement("span", { style: {
545
+ fontSize: '0.75em',
546
+ overflow: 'hidden',
547
+ textOverflow: 'ellipsis',
548
+ } }, s.label)))))));
549
+ const SwatchLegend = ({ field, label, color, when }) => (React.createElement("div", { style: { padding: '4px 6px' } },
550
+ React.createElement(EntryHeader, { field: field, channel: label, when: when }),
551
+ React.createElement(ColorSwatch, { color: color })));
552
+ const SizeLegend = ({ field, channel, when, minSize, maxSize, domain, }) => (React.createElement("div", { style: { padding: 6 } },
553
+ React.createElement(EntryHeader, { field: field, channel: channel, when: when }),
554
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 10 } },
555
+ React.createElement("div", { style: {
556
+ display: 'flex',
557
+ flexDirection: 'column',
558
+ alignItems: 'center',
559
+ gap: 2,
560
+ } },
561
+ React.createElement("span", { style: {
562
+ width: minSize * 2,
563
+ height: minSize * 2,
564
+ borderRadius: '50%',
565
+ background: '#888',
566
+ border: '1px solid #333',
567
+ } }),
568
+ React.createElement("span", { style: { fontSize: '0.7em' } }, domain[0] % 1 === 0 ? domain[0] : domain[0].toFixed(1))),
569
+ React.createElement("div", { style: {
570
+ display: 'flex',
571
+ flexDirection: 'column',
572
+ alignItems: 'center',
573
+ gap: 2,
574
+ } },
575
+ React.createElement("span", { style: {
576
+ width: maxSize * 2,
577
+ height: maxSize * 2,
578
+ borderRadius: '50%',
579
+ background: '#888',
580
+ border: '1px solid #333',
581
+ } }),
582
+ React.createElement("span", { style: { fontSize: '0.7em' } }, domain[1] % 1 === 0 ? domain[1] : domain[1].toFixed(1))))));
583
+ const StrokeWidthLegend = ({ field, channel, when, minWidth, maxWidth, domain, }) => (React.createElement("div", { style: { padding: 6 } },
584
+ React.createElement(EntryHeader, { field: field, channel: channel, when: when }),
585
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 10 } }, [
586
+ { w: minWidth, v: domain[0] },
587
+ { w: maxWidth, v: domain[1] },
588
+ ].map(({ w, v }, i) => (React.createElement("div", { key: i, style: {
589
+ display: 'flex',
590
+ flexDirection: 'column',
591
+ alignItems: 'center',
592
+ gap: 4,
593
+ } },
594
+ React.createElement("div", { style: {
595
+ width: 28,
596
+ height: Math.max(1, w),
597
+ background: '#888',
598
+ border: '1px solid #333',
599
+ } }),
600
+ React.createElement("span", { style: { fontSize: '0.7em' } }, v % 1 === 0 ? v : v.toFixed(1))))))));
601
+ // ---------------------------------------------------------------------------
602
+ // Heatmap legend
603
+ // ---------------------------------------------------------------------------
604
+ const HeatmapLegend = ({ gradient, reversed, }) => {
605
+ const bg = `linear-gradient(to right, ${gradient.join(', ')})`;
606
+ return (React.createElement("div", { style: { padding: 6, width: '90%' } },
607
+ React.createElement("div", { style: { fontSize: '0.78em', fontWeight: 'bold', marginBottom: 8 } }, "Density"),
608
+ React.createElement("div", { style: {
609
+ height: 12,
610
+ background: bg,
611
+ border: '1px solid #ccc',
612
+ borderRadius: 3,
613
+ marginBottom: 4,
614
+ } }),
615
+ React.createElement("div", { style: {
616
+ display: 'flex',
617
+ justifyContent: 'space-between',
618
+ fontSize: '0.75em',
619
+ } },
620
+ React.createElement("span", null, reversed ? 'High' : 'Low'),
621
+ React.createElement("span", null, reversed ? 'Low' : 'High'))));
622
+ };
623
+ // ---------------------------------------------------------------------------
624
+ // Main LegendItem component
625
+ // ---------------------------------------------------------------------------
626
+ export const LegendItem = ({ layerId, model }) => {
627
+ const { symbology, isLoading, error } = useGetSymbology({ layerId, model });
628
+ const [entries, setEntries] = useState([]);
629
+ const [heatmapColors, setHeatmapColors] = useState(null);
630
+ const [heatmapReversed, setHeatmapReversed] = useState(false);
631
+ useEffect(() => {
632
+ setEntries([]);
633
+ setHeatmapColors(null);
634
+ if (isLoading || error || !symbology) {
635
+ return;
636
+ }
637
+ const state = symbology.symbologyState;
638
+ if (!state) {
639
+ return;
640
+ }
641
+ // Heatmap layers have their own renderType and gradient config.
642
+ if (state.renderType === 'Heatmap') {
643
+ const colors = Array.isArray(state.gradient) ? state.gradient : [];
644
+ if (colors.length) {
645
+ setHeatmapColors(colors);
646
+ setHeatmapReversed(!!state.reverseRamp);
647
+ }
648
+ return;
649
+ }
650
+ if (Array.isArray(state.layers)) {
651
+ setEntries(grammarToLegendEntries(state));
652
+ }
653
+ }, [symbology, isLoading, error]);
654
+ if (isLoading) {
655
+ return React.createElement("p", { style: { fontSize: '0.8em', padding: 6 } }, "Loading\u2026");
656
+ }
657
+ if (error) {
658
+ return (React.createElement("p", { style: { color: 'red', fontSize: '0.8em', padding: 6 } }, error.message));
659
+ }
660
+ if (heatmapColors) {
661
+ return (React.createElement(HeatmapLegend, { gradient: heatmapColors, reversed: heatmapReversed }));
662
+ }
663
+ if (entries.length === 0) {
664
+ return null;
665
+ }
666
+ return (React.createElement("div", null, entries.map((entry, i) => {
667
+ switch (entry.type) {
668
+ case 'gradient':
669
+ return React.createElement(GradientLegend, Object.assign({ key: i }, entry));
670
+ case 'categorical':
671
+ return React.createElement(CategoricalLegend, Object.assign({ key: i }, entry));
672
+ case 'swatch':
673
+ return React.createElement(SwatchLegend, Object.assign({ key: i }, entry));
674
+ case 'size':
675
+ return React.createElement(SizeLegend, Object.assign({ key: i }, entry));
676
+ case 'stroke-width':
677
+ return React.createElement(StrokeWidthLegend, Object.assign({ key: i }, entry));
678
+ }
679
+ })));
680
+ };