@element-editor/ui 0.0.0-stage → 0.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 (244) hide show
  1. package/AGENTS.md +65 -0
  2. package/LICENSE +21 -0
  3. package/README.md +46 -2
  4. package/dist/BooleanOperations-WXcmW9Vy.cjs +1 -0
  5. package/dist/BooleanOperations-oF0WybQP.js +111 -0
  6. package/dist/DataTable-CNfB01y2.cjs +2 -0
  7. package/dist/DataTable-DNmjUwka.js +510 -0
  8. package/dist/DataTablePanel-BknCxC1K.cjs +1 -0
  9. package/dist/DataTablePanel-rWdaQubk.js +208 -0
  10. package/dist/EditToolbarBtn-SZIsnIn3.js +378 -0
  11. package/dist/EditToolbarBtn-dpCmKnzk.cjs +3 -0
  12. package/dist/FeatureEditModal-BF-fGhVD.js +77 -0
  13. package/dist/FeatureEditModal-CM6BObUO.cjs +1 -0
  14. package/dist/FeatureList-CQb2kTrV.js +520 -0
  15. package/dist/FeatureList-Csr-anLA.cjs +1 -0
  16. package/dist/FeatureRowContextMenu-BLt7VlUU.js +130 -0
  17. package/dist/FeatureRowContextMenu-Gwq3OMEA.cjs +1 -0
  18. package/dist/GeoJSONModal-BPFWeaLZ.js +886 -0
  19. package/dist/GeoJSONModal-iwUcvrg7.cjs +9 -0
  20. package/dist/SchemaEditor-BEsKUe2p.js +293 -0
  21. package/dist/SchemaEditor-qkoYMg0C.cjs +1 -0
  22. package/dist/SchemaModal-9nNrgorr.js +95 -0
  23. package/dist/SchemaModal-GrtgA7cH.cjs +1 -0
  24. package/dist/SettingsModal-6_qmRyCi.cjs +1 -0
  25. package/dist/SettingsModal-DTP0Xx_Z.js +237 -0
  26. package/dist/ShortcutsModal-CdyQlrqK.cjs +1 -0
  27. package/dist/ShortcutsModal-DwxZu71W.js +299 -0
  28. package/dist/components/ActiveDrawingToolbar.d.cts +1 -0
  29. package/dist/components/ActiveDrawingToolbar.d.ts +1 -0
  30. package/dist/components/BasemapPicker.d.cts +26 -0
  31. package/dist/components/BasemapPicker.d.ts +26 -0
  32. package/dist/components/BooleanOperations.d.cts +1 -0
  33. package/dist/components/BooleanOperations.d.ts +1 -0
  34. package/dist/components/BufferPanel.d.cts +1 -0
  35. package/dist/components/BufferPanel.d.ts +1 -0
  36. package/dist/components/DataTable.d.cts +9 -0
  37. package/dist/components/DataTable.d.ts +9 -0
  38. package/dist/components/DataTablePanel.d.cts +10 -0
  39. package/dist/components/DataTablePanel.d.ts +10 -0
  40. package/dist/components/EditingToolbar.d.cts +1 -0
  41. package/dist/components/EditingToolbar.d.ts +1 -0
  42. package/dist/components/ElementEditorErrorBoundary.d.cts +28 -0
  43. package/dist/components/ElementEditorErrorBoundary.d.ts +28 -0
  44. package/dist/components/ElementEditorUIProvider.d.cts +50 -0
  45. package/dist/components/ElementEditorUIProvider.d.ts +50 -0
  46. package/dist/components/FeatureMapContextMenu.d.cts +23 -0
  47. package/dist/components/FeatureMapContextMenu.d.ts +23 -0
  48. package/dist/components/FitBoundsButton.d.cts +6 -0
  49. package/dist/components/FitBoundsButton.d.ts +6 -0
  50. package/dist/components/FloatingToolbar.d.cts +3 -0
  51. package/dist/components/FloatingToolbar.d.ts +3 -0
  52. package/dist/components/LocateButton.d.cts +11 -0
  53. package/dist/components/LocateButton.d.ts +11 -0
  54. package/dist/components/ReadonlyBanner.d.cts +1 -0
  55. package/dist/components/ReadonlyBanner.d.ts +1 -0
  56. package/dist/components/ShortcutsModal.d.cts +1 -0
  57. package/dist/components/ShortcutsModal.d.ts +1 -0
  58. package/dist/components/SimplifyPanel.d.cts +1 -0
  59. package/dist/components/SimplifyPanel.d.ts +1 -0
  60. package/dist/components/SmoothPanel.d.cts +1 -0
  61. package/dist/components/SmoothPanel.d.ts +1 -0
  62. package/dist/components/UndoRedoToolbar.d.cts +20 -0
  63. package/dist/components/UndoRedoToolbar.d.ts +20 -0
  64. package/dist/components/VertexSelectionBar.d.cts +12 -0
  65. package/dist/components/VertexSelectionBar.d.ts +12 -0
  66. package/dist/components/ZoomIndicator.d.cts +15 -0
  67. package/dist/components/ZoomIndicator.d.ts +15 -0
  68. package/dist/components/dialogs/DynamicFieldRenderer.d.cts +11 -0
  69. package/dist/components/dialogs/DynamicFieldRenderer.d.ts +11 -0
  70. package/dist/components/dialogs/SettingsModal.d.cts +1 -0
  71. package/dist/components/dialogs/SettingsModal.d.ts +1 -0
  72. package/dist/components/lazyParts.d.cts +12 -0
  73. package/dist/components/lazyParts.d.ts +12 -0
  74. package/dist/components/sidebar/FeatureEditModal.d.cts +6 -0
  75. package/dist/components/sidebar/FeatureEditModal.d.ts +6 -0
  76. package/dist/components/sidebar/FeatureList.d.cts +4 -0
  77. package/dist/components/sidebar/FeatureList.d.ts +4 -0
  78. package/dist/components/sidebar/FeatureRow.d.cts +38 -0
  79. package/dist/components/sidebar/FeatureRow.d.ts +38 -0
  80. package/dist/components/sidebar/FeatureRowContextMenu.d.cts +12 -0
  81. package/dist/components/sidebar/FeatureRowContextMenu.d.ts +12 -0
  82. package/dist/components/sidebar/FeatureSidePanel.d.cts +8 -0
  83. package/dist/components/sidebar/FeatureSidePanel.d.ts +8 -0
  84. package/dist/components/sidebar/GeoJSONModal.d.cts +5 -0
  85. package/dist/components/sidebar/GeoJSONModal.d.ts +5 -0
  86. package/dist/components/sidebar/GroupRow.d.cts +21 -0
  87. package/dist/components/sidebar/GroupRow.d.ts +21 -0
  88. package/dist/components/sidebar/HideLayersToggle.d.cts +2 -0
  89. package/dist/components/sidebar/HideLayersToggle.d.ts +2 -0
  90. package/dist/components/sidebar/LayersPanel.d.cts +5 -0
  91. package/dist/components/sidebar/LayersPanel.d.ts +5 -0
  92. package/dist/components/sidebar/PartSubRow.d.cts +9 -0
  93. package/dist/components/sidebar/PartSubRow.d.ts +9 -0
  94. package/dist/components/sidebar/SchemaEditor.d.cts +4 -0
  95. package/dist/components/sidebar/SchemaEditor.d.ts +4 -0
  96. package/dist/components/sidebar/SchemaModal.d.cts +5 -0
  97. package/dist/components/sidebar/SchemaModal.d.ts +5 -0
  98. package/dist/components/sidebar/codeDock.d.cts +21 -0
  99. package/dist/components/sidebar/codeDock.d.ts +21 -0
  100. package/dist/components/ui/Button.d.cts +9 -0
  101. package/dist/components/ui/Button.d.ts +9 -0
  102. package/dist/components/ui/CloseButton.d.cts +6 -0
  103. package/dist/components/ui/CloseButton.d.ts +6 -0
  104. package/dist/components/ui/ContextMenu.d.cts +28 -0
  105. package/dist/components/ui/ContextMenu.d.ts +28 -0
  106. package/dist/components/ui/EditToolbarBtn.d.cts +13 -0
  107. package/dist/components/ui/EditToolbarBtn.d.ts +13 -0
  108. package/dist/components/ui/ElementToaster.d.cts +3 -0
  109. package/dist/components/ui/ElementToaster.d.ts +3 -0
  110. package/dist/components/ui/GeometryTypeIcon.d.cts +7 -0
  111. package/dist/components/ui/GeometryTypeIcon.d.ts +7 -0
  112. package/dist/components/ui/IconButton.d.cts +28 -0
  113. package/dist/components/ui/IconButton.d.ts +28 -0
  114. package/dist/components/ui/Input.d.cts +14 -0
  115. package/dist/components/ui/Input.d.ts +14 -0
  116. package/dist/components/ui/JsonCode.d.cts +4 -0
  117. package/dist/components/ui/JsonCode.d.ts +4 -0
  118. package/dist/components/ui/Kbd.d.cts +16 -0
  119. package/dist/components/ui/Kbd.d.ts +16 -0
  120. package/dist/components/ui/NoFeaturesEmptyState.d.cts +1 -0
  121. package/dist/components/ui/NoFeaturesEmptyState.d.ts +1 -0
  122. package/dist/components/ui/SearchDropdown.d.cts +28 -0
  123. package/dist/components/ui/SearchDropdown.d.ts +28 -0
  124. package/dist/components/ui/ToolButton.d.cts +19 -0
  125. package/dist/components/ui/ToolButton.d.ts +19 -0
  126. package/dist/components/ui/Tooltip.d.cts +12 -0
  127. package/dist/components/ui/Tooltip.d.ts +12 -0
  128. package/dist/components/ui/panelHeader.d.cts +2 -0
  129. package/dist/components/ui/panelHeader.d.ts +2 -0
  130. package/dist/components/ui/resizeEdge.d.cts +4 -0
  131. package/dist/components/ui/resizeEdge.d.ts +4 -0
  132. package/dist/contexts/ElementEditorConfigContext.d.cts +351 -0
  133. package/dist/contexts/ElementEditorConfigContext.d.ts +351 -0
  134. package/dist/contexts/EventContext.d.cts +69 -0
  135. package/dist/contexts/EventContext.d.ts +69 -0
  136. package/dist/contexts/MapControllerContext.d.cts +24 -0
  137. package/dist/contexts/MapControllerContext.d.ts +24 -0
  138. package/dist/contexts/ShortcutConfigContext.d.cts +16 -0
  139. package/dist/contexts/ShortcutConfigContext.d.ts +16 -0
  140. package/dist/contexts/ThemeContext.d.cts +12 -0
  141. package/dist/contexts/ThemeContext.d.ts +12 -0
  142. package/dist/element-editor-ui.cjs +1 -0
  143. package/dist/element-editor-ui.es.js +102 -0
  144. package/dist/geometryWorker-CCwg4tNC.cjs +1 -0
  145. package/dist/geometryWorker-DgQCFSmD.js +25 -0
  146. package/dist/hooks/dragShield.d.cts +7 -0
  147. package/dist/hooks/dragShield.d.ts +7 -0
  148. package/dist/hooks/themeInputs.d.cts +14 -0
  149. package/dist/hooks/themeInputs.d.ts +14 -0
  150. package/dist/hooks/useAccentPalette.d.cts +15 -0
  151. package/dist/hooks/useAccentPalette.d.ts +15 -0
  152. package/dist/hooks/useAccentStyle.d.cts +39 -0
  153. package/dist/hooks/useAccentStyle.d.ts +39 -0
  154. package/dist/hooks/useAdapterControls.d.cts +280 -0
  155. package/dist/hooks/useAdapterControls.d.ts +280 -0
  156. package/dist/hooks/useBalancedWrap.d.cts +8 -0
  157. package/dist/hooks/useBalancedWrap.d.ts +8 -0
  158. package/dist/hooks/useContextMenu.d.cts +11 -0
  159. package/dist/hooks/useContextMenu.d.ts +11 -0
  160. package/dist/hooks/useDataChangeSubscription.d.cts +9 -0
  161. package/dist/hooks/useDataChangeSubscription.d.ts +9 -0
  162. package/dist/hooks/useDragWindow.d.cts +9 -0
  163. package/dist/hooks/useDragWindow.d.ts +9 -0
  164. package/dist/hooks/useFocusTrap.d.cts +7 -0
  165. package/dist/hooks/useFocusTrap.d.ts +7 -0
  166. package/dist/hooks/useGeoJSONDrop.d.cts +40 -0
  167. package/dist/hooks/useGeoJSONDrop.d.ts +40 -0
  168. package/dist/hooks/useGeoJSONExport.d.cts +69 -0
  169. package/dist/hooks/useGeoJSONExport.d.ts +69 -0
  170. package/dist/hooks/useGeoJSONFileImport.d.cts +24 -0
  171. package/dist/hooks/useGeoJSONFileImport.d.ts +24 -0
  172. package/dist/hooks/useInlineRename.d.cts +26 -0
  173. package/dist/hooks/useInlineRename.d.ts +26 -0
  174. package/dist/hooks/useJumpToFeature.d.cts +3 -0
  175. package/dist/hooks/useJumpToFeature.d.ts +3 -0
  176. package/dist/hooks/useKeyboardShortcuts.d.cts +9 -0
  177. package/dist/hooks/useKeyboardShortcuts.d.ts +9 -0
  178. package/dist/hooks/useNominatim.d.cts +24 -0
  179. package/dist/hooks/useNominatim.d.ts +24 -0
  180. package/dist/hooks/usePanelOffset.d.cts +14 -0
  181. package/dist/hooks/usePanelOffset.d.ts +14 -0
  182. package/dist/hooks/useResizablePanel.d.cts +4 -0
  183. package/dist/hooks/useResizablePanel.d.ts +4 -0
  184. package/dist/hooks/useRootTokens.d.cts +27 -0
  185. package/dist/hooks/useRootTokens.d.ts +27 -0
  186. package/dist/hooks/useSearchState.d.cts +23 -0
  187. package/dist/hooks/useSearchState.d.ts +23 -0
  188. package/dist/hooks/useServiceAttribution.d.cts +13 -0
  189. package/dist/hooks/useServiceAttribution.d.ts +13 -0
  190. package/dist/hooks/useWindowEscape.d.cts +25 -0
  191. package/dist/hooks/useWindowEscape.d.ts +25 -0
  192. package/dist/hooks/useWindowFocus.d.cts +4 -0
  193. package/dist/hooks/useWindowFocus.d.ts +4 -0
  194. package/dist/hooks/useWorkerGeometryPreview.d.cts +22 -0
  195. package/dist/hooks/useWorkerGeometryPreview.d.ts +22 -0
  196. package/dist/index-BKdDZ4Y9.cjs +1 -0
  197. package/dist/index-CtZterPc.js +3165 -0
  198. package/dist/index.d.cts +89 -0
  199. package/dist/index.d.ts +89 -0
  200. package/dist/internal.cjs +1 -0
  201. package/dist/internal.d.cts +16 -0
  202. package/dist/internal.d.ts +16 -0
  203. package/dist/internal.es.js +42 -0
  204. package/dist/primitives.cjs +1 -0
  205. package/dist/primitives.d.cts +19 -0
  206. package/dist/primitives.d.ts +19 -0
  207. package/dist/primitives.es.js +17 -0
  208. package/dist/store/StoreContext.d.cts +17 -0
  209. package/dist/store/StoreContext.d.ts +17 -0
  210. package/dist/types/events.d.cts +95 -0
  211. package/dist/types/events.d.ts +95 -0
  212. package/dist/useAccentStyle-CPo2XqAn.js +412 -0
  213. package/dist/useAccentStyle-hsGvyHZc.cjs +1 -0
  214. package/dist/useAdapterControls-BBObhzVX.cjs +1 -0
  215. package/dist/useAdapterControls-DVjkwRZ_.js +691 -0
  216. package/dist/useContextMenu-DJ2Cti85.js +10 -0
  217. package/dist/useContextMenu-DbxMvb1s.cjs +1 -0
  218. package/dist/useFocusTrap-BBjPCfDR.cjs +1 -0
  219. package/dist/useFocusTrap-CKxKT8De.js +25 -0
  220. package/dist/useJumpToFeature-Bdz2hqOC.js +16 -0
  221. package/dist/useJumpToFeature-LwjxGzfy.cjs +1 -0
  222. package/dist/useWindowFocus-D-_yEm_V.cjs +1 -0
  223. package/dist/useWindowFocus-DGAWA1au.js +80 -0
  224. package/dist/utils/booleanValue.d.cts +4 -0
  225. package/dist/utils/booleanValue.d.ts +4 -0
  226. package/dist/utils/clipboardError.d.cts +3 -0
  227. package/dist/utils/clipboardError.d.ts +3 -0
  228. package/dist/utils/download.d.cts +42 -0
  229. package/dist/utils/download.d.ts +42 -0
  230. package/dist/utils/geojsonDocument.d.cts +168 -0
  231. package/dist/utils/geojsonDocument.d.ts +168 -0
  232. package/dist/utils/geometryWorkerClient.d.cts +6 -0
  233. package/dist/utils/geometryWorkerClient.d.ts +6 -0
  234. package/dist/utils/layerOrder.d.cts +9 -0
  235. package/dist/utils/layerOrder.d.ts +9 -0
  236. package/dist/utils/lazyWithPreload.d.cts +24 -0
  237. package/dist/utils/lazyWithPreload.d.ts +24 -0
  238. package/dist/utils/lineSmooth.d.cts +7 -0
  239. package/dist/utils/lineSmooth.d.ts +7 -0
  240. package/dist/utils/platform.d.cts +2 -0
  241. package/dist/utils/platform.d.ts +2 -0
  242. package/dist/workers/geometryWorker.d.cts +1 -0
  243. package/dist/workers/geometryWorker.d.ts +1 -0
  244. package/package.json +133 -3
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Runs `fn` (a layout change) with editor transitions off until it has been
3
+ * painted, so everything it moves jumps in the same frame instead of some
4
+ * parts sliding 200 ms after others.
5
+ */
6
+ export declare function withoutTransitions(fn: () => void): void;
7
+ export declare function startDragShield(cursor: string, handle?: HTMLElement): () => void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Runs `fn` (a layout change) with editor transitions off until it has been
3
+ * painted, so everything it moves jumps in the same frame instead of some
4
+ * parts sliding 200 ms after others.
5
+ */
6
+ export declare function withoutTransitions(fn: () => void): void;
7
+ export declare function startDragShield(cursor: string, handle?: HTMLElement): () => void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Watch everything that can change the CSS variables resolved on an editor root:
3
+ * the root's `style` / `class` / `data-elm-theme`, `<html>`'s `style` / `class`,
4
+ * stylesheets added to, removed from or edited in `<head>`, and `<link>` loads.
5
+ * Calls `onChange` (the caller batches it). Shared by `useAccentPalette` and
6
+ * `useRootTokens`.
7
+ *
8
+ * ponytail: CSSOM edits (insertRule, adoptedStyleSheets, constructable sheets)
9
+ * and <style> outside <head> fire no event; re-set a token on the root to nudge it.
10
+ */
11
+ /** The root's theme-relevant inputs as one string: class, mode and inline style minus layout vars. */
12
+ export declare const themeInputs: (root: Element | null) => string;
13
+ /** Start watching; returns the cleanup. `onChange` may fire several times per frame: batch it. */
14
+ export declare function watchThemeInputs(root: Element | null, onChange: () => void): () => void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Watch everything that can change the CSS variables resolved on an editor root:
3
+ * the root's `style` / `class` / `data-elm-theme`, `<html>`'s `style` / `class`,
4
+ * stylesheets added to, removed from or edited in `<head>`, and `<link>` loads.
5
+ * Calls `onChange` (the caller batches it). Shared by `useAccentPalette` and
6
+ * `useRootTokens`.
7
+ *
8
+ * ponytail: CSSOM edits (insertRule, adoptedStyleSheets, constructable sheets)
9
+ * and <style> outside <head> fire no event; re-set a token on the root to nudge it.
10
+ */
11
+ /** The root's theme-relevant inputs as one string: class, mode and inline style minus layout vars. */
12
+ export declare const themeInputs: (root: Element | null) => string;
13
+ /** Start watching; returns the cleanup. `onChange` may fire several times per frame: batch it. */
14
+ export declare function watchThemeInputs(root: Element | null, onChange: () => void): () => void;
@@ -0,0 +1,15 @@
1
+ import { AccentPalette } from '@element-editor/core';
2
+ /**
3
+ * The palette in effect for `el`, as the CSS resolves it (accent and any
4
+ * `--elm-primary-N` override), for map renderers that need concrete colours
5
+ * (Leaflet SVG attributes, MapLibre paint). Re-reads, once per frame at most,
6
+ * when the `style`/`class` of the nearest `[data-elm-theme]` ancestor or
7
+ * `<html>` changes, when `<head>` gains/loses/edits a stylesheet, or when a
8
+ * `<link>` finishes loading. Returns the same object while nothing changed.
9
+ * HTML (divIcons, marker elements) can use `var(--color-primary-N)` directly.
10
+ *
11
+ * ponytail: CSSOM edits (insertRule, adoptedStyleSheets, constructable sheets)
12
+ * and <style> outside <head> fire no event; re-set the accent on the root to
13
+ * nudge it if a host does that.
14
+ */
15
+ export declare function useAccentPalette(el: HTMLElement | null): AccentPalette;
@@ -0,0 +1,15 @@
1
+ import { AccentPalette } from '@element-editor/core';
2
+ /**
3
+ * The palette in effect for `el`, as the CSS resolves it (accent and any
4
+ * `--elm-primary-N` override), for map renderers that need concrete colours
5
+ * (Leaflet SVG attributes, MapLibre paint). Re-reads, once per frame at most,
6
+ * when the `style`/`class` of the nearest `[data-elm-theme]` ancestor or
7
+ * `<html>` changes, when `<head>` gains/loses/edits a stylesheet, or when a
8
+ * `<link>` finishes loading. Returns the same object while nothing changed.
9
+ * HTML (divIcons, marker elements) can use `var(--color-primary-N)` directly.
10
+ *
11
+ * ponytail: CSSOM edits (insertRule, adoptedStyleSheets, constructable sheets)
12
+ * and <style> outside <head> fire no event; re-set the accent on the root to
13
+ * nudge it if a host does that.
14
+ */
15
+ export declare function useAccentPalette(el: HTMLElement | null): AccentPalette;
@@ -0,0 +1,39 @@
1
+ import { CSSProperties } from 'react';
2
+ /**
3
+ * CSS custom properties the host set on the editor root (`<ElementEditor style>`), e.g.
4
+ * `--elm-accent` or a single `--elm-primary-N` shade. Body-level portals don't inherit
5
+ * them, so `useAccentStyle()` copies them onto each portal root. `<ElementEditor>`
6
+ * provides it; adapter users style their own root (see `useAccentStyle`).
7
+ */
8
+ export declare const RootCssVarsContext: import('react').Context<CSSProperties | undefined>;
9
+ /** Inline style that sets `--elm-accent`; undefined when no accent is configured (CSS default blue). */
10
+ export declare function accentStyle(accent: string | undefined): CSSProperties | undefined;
11
+ /**
12
+ * The editor root's theme for Element's body-level portals (modals, menus,
13
+ * tooltips, drag clones, toasts): `--elm-accent` and every design token
14
+ * (`--elm-surface`, `--elm-radius`, …) the integrator set. Portals sit outside
15
+ * the editor root and don't inherit its CSS variables, so each portal root
16
+ * spreads this into its `style`. The root must also carry `data-elm-theme`
17
+ * (or `data-elm-portal`): the shared.css blocks that hold the token defaults
18
+ * and derive `--color-primary-*` from `--elm-accent` are declared on those
19
+ * selectors, and a var only re-resolves where it's declared.
20
+ *
21
+ * Merges, later winning: `config.accentColor`; the tokens resolved on the
22
+ * editor root (RootTokensContext, so a stylesheet rule on the root such as
23
+ * `.my-editor[data-elm-theme="dark"] { --elm-surface: … }` reaches portals too);
24
+ * the CSS variables of `<ElementEditor style>` (RootCssVarsContext).
25
+ */
26
+ export declare function useAccentStyle(): CSSProperties | undefined;
27
+ /**
28
+ * Apply `config.accentColor` to the editor root for adapter users, whose
29
+ * themed root (`[data-elm-theme]`) is their own element, not one we render.
30
+ * `ElementEditorUIProvider` renders no DOM, so the provider can't style it; the
31
+ * adapters' `ElementEditorControls` call this with `map.getContainer()` instead,
32
+ * and the var goes on the nearest `[data-elm-theme]` ancestor (else the
33
+ * container). This finds the root wherever it sits in the host's tree.
34
+ *
35
+ * Skips when the root already has that exact inline value, e.g. `<ElementEditor>`
36
+ * sets it through React's `style`, so React keeps owning it there. Cleanup
37
+ * only removes a value this hook wrote.
38
+ */
39
+ export declare function useApplyAccentToRoot(container: HTMLElement | null | undefined): void;
@@ -0,0 +1,39 @@
1
+ import { CSSProperties } from 'react';
2
+ /**
3
+ * CSS custom properties the host set on the editor root (`<ElementEditor style>`), e.g.
4
+ * `--elm-accent` or a single `--elm-primary-N` shade. Body-level portals don't inherit
5
+ * them, so `useAccentStyle()` copies them onto each portal root. `<ElementEditor>`
6
+ * provides it; adapter users style their own root (see `useAccentStyle`).
7
+ */
8
+ export declare const RootCssVarsContext: import('react').Context<CSSProperties | undefined>;
9
+ /** Inline style that sets `--elm-accent`; undefined when no accent is configured (CSS default blue). */
10
+ export declare function accentStyle(accent: string | undefined): CSSProperties | undefined;
11
+ /**
12
+ * The editor root's theme for Element's body-level portals (modals, menus,
13
+ * tooltips, drag clones, toasts): `--elm-accent` and every design token
14
+ * (`--elm-surface`, `--elm-radius`, …) the integrator set. Portals sit outside
15
+ * the editor root and don't inherit its CSS variables, so each portal root
16
+ * spreads this into its `style`. The root must also carry `data-elm-theme`
17
+ * (or `data-elm-portal`): the shared.css blocks that hold the token defaults
18
+ * and derive `--color-primary-*` from `--elm-accent` are declared on those
19
+ * selectors, and a var only re-resolves where it's declared.
20
+ *
21
+ * Merges, later winning: `config.accentColor`; the tokens resolved on the
22
+ * editor root (RootTokensContext, so a stylesheet rule on the root such as
23
+ * `.my-editor[data-elm-theme="dark"] { --elm-surface: … }` reaches portals too);
24
+ * the CSS variables of `<ElementEditor style>` (RootCssVarsContext).
25
+ */
26
+ export declare function useAccentStyle(): CSSProperties | undefined;
27
+ /**
28
+ * Apply `config.accentColor` to the editor root for adapter users, whose
29
+ * themed root (`[data-elm-theme]`) is their own element, not one we render.
30
+ * `ElementEditorUIProvider` renders no DOM, so the provider can't style it; the
31
+ * adapters' `ElementEditorControls` call this with `map.getContainer()` instead,
32
+ * and the var goes on the nearest `[data-elm-theme]` ancestor (else the
33
+ * container). This finds the root wherever it sits in the host's tree.
34
+ *
35
+ * Skips when the root already has that exact inline value, e.g. `<ElementEditor>`
36
+ * sets it through React's `style`, so React keeps owning it there. Cleanup
37
+ * only removes a value this hook wrote.
38
+ */
39
+ export declare function useApplyAccentToRoot(container: HTMLElement | null | undefined): void;
@@ -0,0 +1,280 @@
1
+ import { FeatureCollection, FeatureCollectionInput, FeaturePatch, FlyToOptions, GeoJSONFeature, GeoJSONFeatureInput, Schema } from '@element-editor/core';
2
+ import { DrawTool } from '../contexts/ElementEditorConfigContext.cjs';
3
+ /**
4
+ * `useAdapterControls` — single source of truth for the editor-shell wiring
5
+ * shared by `@element-editor/adapter-leaflet`, `@element-editor/adapter-maplibre`, and
6
+ * `@element-editor/react`.
7
+ *
8
+ * Owns:
9
+ * - prop → store sync (readonly / tools / maxFeatures / layout; network-disabled tools)
10
+ * - one-time mounts (initialData, schema)
11
+ * - data-change subscription (onChange / per-feature callbacks / selection)
12
+ * - onZoomChange + onFeatureSelect subscriptions
13
+ * - the FC-shaped imperative API (return value — caller wires it through
14
+ * `useImperativeHandle`)
15
+ *
16
+ * Caller still owns: bounds / maxBounds (different APIs across map libs),
17
+ * the map-bridge wiring, the layer tree, and any wrapper-only concerns
18
+ * (slots, tile layer, theme persistence, dev affordances).
19
+ */
20
+ export interface ImportResult {
21
+ /** Features skipped due to unsupported geometry type. */
22
+ skipped: number;
23
+ /** Features skipped because their id collided with an existing feature. */
24
+ duplicates: number;
25
+ /** True if the import was capped by `maxFeatures` / internal safety limits. */
26
+ truncated: boolean;
27
+ }
28
+ /**
29
+ * Options of the ref's data-changing methods (`addFeature`, `updateFeature(s)`, `removeFeatures`).
30
+ */
31
+ export interface MutationOptions {
32
+ /**
33
+ * Default `true`: the change is one undo step, like the same edit made by the user.
34
+ * `false` (e.g. applying a change from your server): no undo step, and the change is also
35
+ * applied to every undo/redo snapshot, so undoing an earlier user edit doesn't revert it.
36
+ */
37
+ undoable?: boolean;
38
+ }
39
+ /** Options of `ref.setFeatureCollection`. */
40
+ export interface SetFeatureCollectionOptions {
41
+ /**
42
+ * Default `false`: the load fires `onChange` (and `onFeatureAdd` / `onFeatureUpdate` /
43
+ * `onFeatureDelete`) like any other change. `true`: those callbacks don't fire for this load,
44
+ * so data you just fetched from your backend isn't saved straight back. `onSelectionChange`
45
+ * still fires when the load clears a selection.
46
+ */
47
+ silent?: boolean;
48
+ /**
49
+ * Default `true`: the load is one undo step (undo restores the previous data). `false`: no undo
50
+ * step, and the undo/redo history is cleared, so the user can't undo back past the loaded data
51
+ * (what `initialData` does).
52
+ */
53
+ undoable?: boolean;
54
+ }
55
+ /** What `ref.validate()` returns. */
56
+ export interface ValidationReport {
57
+ /** `true` when no feature has a validation error. */
58
+ valid: boolean;
59
+ /**
60
+ * Error messages per feature id, only for features that have errors (e.g.
61
+ * `'Missing required property: Owner'`): the same object `onValidationError` receives.
62
+ */
63
+ errors: Record<string, string[]>;
64
+ }
65
+ /**
66
+ * Imperative handle of `<ElementEditor ref>` and both adapters' `<ElementEditorControls ref>`.
67
+ * Coordinates are GeoJSON order, `[lng, lat]`, unless a method says otherwise.
68
+ * Map methods (`flyTo`, `setZoom`, `fitBounds`, `select`'s `fit`) do nothing until the map has mounted.
69
+ *
70
+ * Data-changing methods go through the same store actions as the UI: `maxFeatures`, schema
71
+ * validation, undo and the `onChange` / `onFeature*` / `onSelectionChange` callbacks behave as
72
+ * for the user's own edits (callbacks fire synchronously, before the method returns). They work
73
+ * in `readonly` mode too (the host app is in charge); only `setTool` is refused there.
74
+ *
75
+ * `TMap` is the engine's map type: `maplibregl.Map` on `@element-editor/react` and
76
+ * `@element-editor/adapter-maplibre`, `L.Map` on `@element-editor/react/leaflet` and
77
+ * `@element-editor/adapter-leaflet`.
78
+ */
79
+ export interface ElementEditorImperativeAPI<TMap = unknown> {
80
+ /**
81
+ * Snapshot of the current data as a FeatureCollection: every feature (hidden ones included,
82
+ * internal validation state stripped) plus `metadata.schemas` / `metadata.groups`.
83
+ */
84
+ getFeatureCollection: () => FeatureCollection;
85
+ /**
86
+ * One feature by id, as `getFeatureCollection()` would return it (hidden features included), or
87
+ * `null` for an unknown id.
88
+ */
89
+ getFeature: (id: string) => GeoJSONFeature | null;
90
+ /**
91
+ * Replaces all data with `data` (like `importGeoJSON(data, 'replace')`). Plain GeoJSON is fine:
92
+ * missing ids get UUIDs, no `metadata` means the default schema. Features without a usable
93
+ * geometry (`geometry: null`, unknown types) are skipped and reported through `onError` /
94
+ * the `error` event.
95
+ *
96
+ * By default this fires `onChange` (and `onFeatureAdd` / `onFeatureDelete`) like any change and is
97
+ * one undo step. When you load data from your backend and save it in `onChange`, pass
98
+ * `{ silent: true }` so the load isn't saved straight back (see `SetFeatureCollectionOptions`).
99
+ *
100
+ * ```ts
101
+ * const fc = await (await fetch('/api/map')).json()
102
+ * ref.current?.setFeatureCollection(fc, { silent: true, undoable: false })
103
+ * ```
104
+ */
105
+ setFeatureCollection: (data: FeatureCollectionInput, options?: SetFeatureCollectionOptions) => void;
106
+ /** The current data serialised as a GeoJSON string (what "Export" downloads). */
107
+ exportGeoJSON: () => string;
108
+ /** Triggers a browser download of the current data. Only `'geojson'` is supported. */
109
+ exportAs: (format: 'geojson') => void;
110
+ /**
111
+ * Imports a FeatureCollection (or anything parseable as one). `'replace'` (default) swaps the
112
+ * data, `'merge'` appends. It is one undo step (undo restores the previous features, schemas and
113
+ * groups; no file backup). Returns counts of skipped (unsupported
114
+ * geometry) / duplicate (repeated id) features and whether the import was truncated
115
+ * (`maxFeatures` or the internal 50,000-feature limit).
116
+ */
117
+ importGeoJSON: (raw: FeatureCollectionInput | unknown, mode?: 'replace' | 'merge') => ImportResult;
118
+ /**
119
+ * Updates many features in one commit: one store update, one `onChange`, and `onFeatureUpdate`
120
+ * once per feature whose geometry or properties changed. Each `patch` may set `properties`
121
+ * (replaces the whole object), `geometry`, `schemaId` or `hidden`; features are re-validated
122
+ * against their schema. The batch is one undo step (see `MutationOptions.undoable`). Unknown ids
123
+ * and malformed patches are skipped (with a development warning).
124
+ *
125
+ * ```ts
126
+ * ref.current.updateFeatures(ids.map((id) => ({ id, patch: { properties: { ...props(id), status: 'done' } } })))
127
+ * ```
128
+ */
129
+ updateFeatures: (updates: ReadonlyArray<{
130
+ id: string;
131
+ patch: FeaturePatch;
132
+ }>, options?: MutationOptions) => void;
133
+ /**
134
+ * Adds a feature and returns it as stored (with its `id`; a missing id gets a UUID), or `null`
135
+ * when nothing was added: the geometry isn't valid GeoJSON, the id is already used (both warn
136
+ * in development), or `maxFeatures` is reached (reported like a user add). The feature goes on
137
+ * top of the layer list; the selection is left alone. `groupId` is kept only if that group exists.
138
+ * Fires `onFeatureAdd` and `onChange`.
139
+ */
140
+ addFeature: (feature: GeoJSONFeatureInput, options?: MutationOptions) => GeoJSONFeature | null;
141
+ /**
142
+ * Updates one feature. `patch` may set `properties` (replaces the whole object), `geometry`,
143
+ * `schemaId` or `hidden`; other keys are ignored. The feature is re-validated against its schema
144
+ * (schema errors don't block the write). Returns `false`, changing nothing, for an unknown id or
145
+ * a malformed patch (both warn in development). Fires `onFeatureUpdate` and `onChange`.
146
+ */
147
+ updateFeature: (id: string, patch: FeaturePatch, options?: MutationOptions) => boolean;
148
+ /**
149
+ * Removes the features with these ids in one undo step and returns how many were removed
150
+ * (unknown ids are skipped, with a development warning). Removed ids leave the selection.
151
+ * Fires `onFeatureDelete` per feature and `onChange` once.
152
+ */
153
+ removeFeatures: (ids: string[], options?: MutationOptions) => number;
154
+ /** Ids of the selected features (a copy). */
155
+ getSelection: () => string[];
156
+ /**
157
+ * Replaces the selection with these features (`[]` clears it) and fires `onSelectionChange`.
158
+ * Unknown ids, group ids and hidden features (or features in a hidden group) are left out, with a
159
+ * development warning. `fit: true` also fits the map to the selected features.
160
+ */
161
+ select: (ids: string[], options?: {
162
+ fit?: boolean;
163
+ }) => void;
164
+ /**
165
+ * Turns a drawing tool on, as its toolbar button does (an unfinished shape of another tool is
166
+ * discarded); `null` turns the active tool off. Returns `false`, changing nothing, when the tool
167
+ * isn't available: unknown or `'search'`, left out by `tools`, `maxFeatures` reached (tools that
168
+ * add features), or `readonly` (every tool but `'measure'`, which the readonly toolbar keeps).
169
+ */
170
+ setTool: (tool: DrawTool | null) => boolean;
171
+ /**
172
+ * The drawing tool that is on (as `setTool` takes it), or `null` when none is. Shape operations
173
+ * (cut, slice, simplify, smooth, buffer) aren't tools: `null` while they run.
174
+ */
175
+ getTool: () => DrawTool | null;
176
+ /** `true` when `undo()` would change something (there is an edit to undo). */
177
+ canUndo: () => boolean;
178
+ /** `true` when `redo()` would change something (there is an undone edit to redo). */
179
+ canRedo: () => boolean;
180
+ /**
181
+ * Validates every feature against its schema (required fields, number `min` / `max`) and its
182
+ * geometry (zero-area polygons), and returns the result. Changes nothing and calls no callback:
183
+ * use it to check before your own save, or to show errors. `submit()` runs the same check.
184
+ *
185
+ * ```ts
186
+ * const { valid, errors } = ref.current!.validate()
187
+ * if (!valid) ref.current!.select(Object.keys(errors), { fit: true })
188
+ * ```
189
+ */
190
+ validate: () => ValidationReport;
191
+ /**
192
+ * The underlying map: `maplibregl.Map` or `L.Map` (see `TMap`), or `null` until the map has
193
+ * mounted (the MapLibre drop-in creates it once its basemap style has loaded).
194
+ *
195
+ * On a MapLibre map, switch basemaps with the `basemap` prop or `setBasemap`: they keep your
196
+ * layers. After your own `map.setStyle()` Element restores its own layers; re-add yours on `style.load`.
197
+ */
198
+ getMap: () => TMap | null;
199
+ /**
200
+ * Animates the map to a centre and zoom.
201
+ *
202
+ * - `flyTo({ center: [lng, lat], zoom? })` — preferred; GeoJSON order. Zoom defaults to 15.
203
+ * - `flyTo([lat, lng], zoom?)` — deprecated `[lat, lng]` tuple form; still works, warns once
204
+ * in development.
205
+ */
206
+ flyTo: {
207
+ (options: FlyToOptions): void;
208
+ /** @deprecated `[lat, lng]` order. Use `flyTo({ center: [lng, lat], zoom })`. */
209
+ (latlng: [number, number], zoom?: number): void;
210
+ };
211
+ /**
212
+ * Sets the zoom immediately (no animation), clamped to the map's min/max zoom.
213
+ * Returns `false` when the map is not mounted yet (nothing happened), `true` otherwise.
214
+ */
215
+ setZoom: (zoom: number) => boolean;
216
+ /**
217
+ * Animates the map to fit a box, with padding, never zooming in past 16. Accepts:
218
+ *
219
+ * - a GeoJSON bbox `[minLng, minLat, maxLng, maxLat]` (= `[west, south, east, north]`), or
220
+ * - an array of `[lng, lat]` points (fits their bounding box).
221
+ *
222
+ * Empty input or input without finite coordinates is ignored.
223
+ */
224
+ fitBounds: (target: [number, number][] | [number, number, number, number]) => void;
225
+ /**
226
+ * Validates every feature (as `validate()` does), then submits. Returns `false` if any feature
227
+ * has validation errors: `onValidationError` is called with them (keyed by feature id) and
228
+ * `onSubmit` is not. Returns `true` when the data is valid: `onSubmit` (if set) is called
229
+ * with the current FeatureCollection.
230
+ */
231
+ submit: () => boolean;
232
+ /** Undoes the last edit (no-op when there is nothing to undo; see `canUndo`). */
233
+ undo: () => void;
234
+ /** Redoes the last undone edit (no-op when there is nothing to redo; see `canRedo`). */
235
+ redo: () => void;
236
+ /** Deselects all features. */
237
+ clearSelection: () => void;
238
+ }
239
+ export interface UseAdapterControlsOptions {
240
+ /**
241
+ * Plain GeoJSON is fine (see `FeatureCollectionInput`); a single Feature is wrapped in a collection.
242
+ * Applied on mount. A value that arrives later (`null` / `undefined` → data, e.g. after a fetch) is
243
+ * applied once too, if the editor is still empty and unedited; any other change is ignored, with a
244
+ * development warning.
245
+ */
246
+ initialData?: FeatureCollectionInput | GeoJSONFeatureInput | null;
247
+ schema?: Schema;
248
+ layout?: 'panel' | 'minimal' | 'split';
249
+ readonly?: boolean;
250
+ tools?: DrawTool[] | null;
251
+ maxFeatures?: number;
252
+ /**
253
+ * The map engine; the adapters pass it. With it, the tools `config.network` turns off are
254
+ * synced to `uiStore.unavailableTools` (the Picker needs Overpass only on Leaflet).
255
+ */
256
+ engine?: 'leaflet' | 'maplibre';
257
+ onChange?: (data: FeatureCollection) => void;
258
+ onSubmit?: (data: FeatureCollection) => void;
259
+ onValidationError?: (errors: Record<string, string[]>) => void;
260
+ onFeatureAdd?: (feature: GeoJSONFeature) => void;
261
+ onFeatureUpdate?: (id: string, feature: GeoJSONFeature) => void;
262
+ onFeatureDelete?: (id: string) => void;
263
+ onSelectionChange?: (ids: string[]) => void;
264
+ onFeatureSelect?: (feature: GeoJSONFeature | null) => void;
265
+ onZoomChange?: (zoom: number) => void;
266
+ /** Called with the tool that turned on (as `ref.getTool()` reports it), or `null` when it turned off. */
267
+ onToolChange?: (tool: DrawTool | null) => void;
268
+ /**
269
+ * @internal Called after `initialData` was applied: `late` is true for data that arrived after
270
+ * mount. The drop-in uses it to fit the late data.
271
+ */
272
+ onInitialDataApplied?: (data: FeatureCollectionInput, late: boolean) => void;
273
+ }
274
+ /** The tools `network` turns off: no routing → Route, no geocoder → search, no Overpass → Picker on Leaflet (MapLibre still picks from the vector tiles). */
275
+ export declare function networkUnavailableTools(network: {
276
+ routing?: unknown;
277
+ nominatim?: unknown;
278
+ overpass?: unknown;
279
+ }, engine: 'leaflet' | 'maplibre'): string[];
280
+ export declare function useAdapterControls<TMap = unknown>(opts: UseAdapterControlsOptions): ElementEditorImperativeAPI<TMap>;