@versatiles/svelte 1.1.1 → 2.0.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 (53) hide show
  1. package/dist/components/BBoxMap/AutoComplete.svelte +0 -1
  2. package/dist/components/BBoxMap/BBoxMap.svelte +1 -2
  3. package/dist/{utils/draw → components/BBoxMap/lib}/bbox.d.ts +1 -2
  4. package/dist/components/BasicMap/BasicMap.svelte +7 -9
  5. package/dist/components/BasicMap/BasicMap.svelte.d.ts +5 -4
  6. package/dist/components/LocatorMap/LocatorMap.svelte +0 -2
  7. package/dist/components/MapEditor/MapEditor.svelte +16 -3
  8. package/dist/components/MapEditor/components/Editor.svelte +46 -39
  9. package/dist/components/MapEditor/components/Editor.svelte.d.ts +1 -1
  10. package/dist/components/MapEditor/components/EditorFill.svelte +7 -9
  11. package/dist/components/MapEditor/components/EditorStroke.svelte +9 -11
  12. package/dist/components/MapEditor/components/EditorSymbol.svelte +23 -19
  13. package/dist/components/MapEditor/components/InputRow.svelte +34 -0
  14. package/dist/components/MapEditor/components/InputRow.svelte.d.ts +9 -0
  15. package/dist/components/MapEditor/components/Sidebar.svelte +116 -111
  16. package/dist/components/MapEditor/components/SidebarPanel.svelte +92 -0
  17. package/dist/components/MapEditor/components/SidebarPanel.svelte.d.ts +10 -0
  18. package/dist/components/MapEditor/components/SymbolSelector.svelte +7 -15
  19. package/dist/components/MapEditor/lib/element/abstract.d.ts +3 -3
  20. package/dist/components/MapEditor/lib/element/abstract.js +1 -1
  21. package/dist/components/MapEditor/lib/element/line.d.ts +3 -4
  22. package/dist/components/MapEditor/lib/element/line.js +0 -1
  23. package/dist/components/MapEditor/lib/element/marker.d.ts +4 -4
  24. package/dist/components/MapEditor/lib/element/polygon.d.ts +3 -3
  25. package/dist/components/MapEditor/lib/geometry_manager.d.ts +20 -10
  26. package/dist/components/MapEditor/lib/geometry_manager.js +46 -52
  27. package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +4 -3
  28. package/dist/components/MapEditor/lib/map_layer/abstract.js +30 -12
  29. package/dist/components/MapEditor/lib/map_layer/fill.d.ts +4 -3
  30. package/dist/components/MapEditor/lib/map_layer/fill.js +9 -8
  31. package/dist/components/MapEditor/lib/map_layer/line.d.ts +4 -3
  32. package/dist/components/MapEditor/lib/map_layer/line.js +15 -14
  33. package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +21 -10
  34. package/dist/components/MapEditor/lib/map_layer/symbol.js +72 -31
  35. package/dist/components/MapEditor/lib/state/constants.d.ts +4 -0
  36. package/dist/components/MapEditor/lib/state/constants.js +22 -0
  37. package/dist/components/MapEditor/lib/state/manager.d.ts +16 -0
  38. package/dist/components/MapEditor/lib/state/manager.js +76 -0
  39. package/dist/components/MapEditor/lib/state/reader.d.ts +21 -14
  40. package/dist/components/MapEditor/lib/state/reader.js +259 -139
  41. package/dist/components/MapEditor/lib/state/types.d.ts +28 -12
  42. package/dist/components/MapEditor/lib/state/writer.d.ts +18 -14
  43. package/dist/components/MapEditor/lib/state/writer.js +183 -156
  44. package/dist/components/MapEditor/lib/utils.d.ts +2 -5
  45. package/dist/components/MapEditor/lib/utils.js +0 -19
  46. package/package.json +28 -27
  47. package/dist/components/MapEditor/lib/__mocks__/cursor.d.ts +0 -5
  48. package/dist/components/MapEditor/lib/__mocks__/cursor.js +0 -6
  49. package/dist/components/MapEditor/lib/__mocks__/geometry_manager.d.ts +0 -22
  50. package/dist/components/MapEditor/lib/__mocks__/geometry_manager.js +0 -21
  51. package/dist/components/MapEditor/lib/__mocks__/map.d.ts +0 -36
  52. package/dist/components/MapEditor/lib/__mocks__/map.js +0 -26
  53. /package/dist/{utils/draw → components/BBoxMap/lib}/bbox.js +0 -0
@@ -1,4 +1,3 @@
1
- <!-- AutoComplete.svelte -->
2
1
  <script lang="ts" generics="T">
3
2
  import { isDarkMode } from '../../utils/map_style.js';
4
3
  /* eslint svelte/no-at-html-tags: off */
@@ -1,4 +1,3 @@
1
- <!-- BBoxMap.svelte -->
2
1
  <script lang="ts">
3
2
  import type { CameraOptions, Map as MaplibreMapType } from 'maplibre-gl';
4
3
  import AutoComplete from './AutoComplete.svelte';
@@ -7,7 +6,7 @@
7
6
  import { isDarkMode } from '../../utils/map_style.js';
8
7
  import type { BBox } from 'geojson';
9
8
  import { loadBBoxes } from './BBoxMap.js';
10
- import { BBoxDrawer } from '../../utils/draw/bbox.js';
9
+ import { BBoxDrawer } from './lib/bbox.js';
11
10
 
12
11
  let { selectedBBox = $bindable() }: { selectedBBox?: BBox } = $props();
13
12
  const startTime = Date.now();
@@ -1,7 +1,7 @@
1
1
  import type geojson from 'geojson';
2
2
  import { type Writable } from 'svelte/store';
3
3
  import maplibregl from 'maplibre-gl';
4
- type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
4
+ export type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
5
5
  export declare const DragPointMap: Map<DragPoint, {
6
6
  cursor: string;
7
7
  flipH: DragPoint;
@@ -27,4 +27,3 @@ export declare class BBoxDrawer {
27
27
  private getCursor;
28
28
  private doDrag;
29
29
  }
30
- export {};
@@ -1,10 +1,8 @@
1
- <!-- BasicMap.svelte -->
2
1
  <script lang="ts">
3
- import type { Map as MaplibreMapType, MapOptions } from 'maplibre-gl';
4
2
  import 'maplibre-gl/dist/maplibre-gl.css';
5
3
  import { getMapStyle, isDarkMode } from '../../utils/map_style.js';
6
4
  import maplibre from 'maplibre-gl';
7
- const { Map } = maplibre;
5
+ import type { MapOptions } from 'maplibre-gl';
8
6
 
9
7
  // Props
10
8
  let {
@@ -18,9 +16,9 @@
18
16
  style?: string;
19
17
  styleOptions?: Parameters<typeof getMapStyle>[1];
20
18
  mapOptions?: Partial<MapOptions>;
21
- map?: MaplibreMapType;
22
- onMapInit?: (map: MaplibreMapType) => void;
23
- onMapLoad?: (map: MaplibreMapType) => void;
19
+ map?: maplibre.Map;
20
+ onMapInit?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
21
+ onMapLoad?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
24
22
  } = $props();
25
23
 
26
24
  let container: HTMLDivElement;
@@ -40,7 +38,7 @@
40
38
 
41
39
  const style = getMapStyle(darkMode, styleOptions);
42
40
  style.transition = { duration: 0, delay: 0 };
43
- map = new Map({
41
+ map = new maplibre.Map({
44
42
  container,
45
43
  style,
46
44
  renderWorldCopies: false,
@@ -50,10 +48,10 @@
50
48
  ...mapOptions
51
49
  });
52
50
 
53
- if (onMapInit) onMapInit(map);
51
+ if (onMapInit) onMapInit(map, maplibre);
54
52
 
55
53
  map.on('load', () => {
56
- if (onMapLoad) onMapLoad(map!);
54
+ if (onMapLoad) onMapLoad(map!, maplibre);
57
55
  });
58
56
  }
59
57
  </script>
@@ -1,13 +1,14 @@
1
- import type { Map as MaplibreMapType, MapOptions } from 'maplibre-gl';
2
1
  import 'maplibre-gl/dist/maplibre-gl.css';
3
2
  import { getMapStyle } from '../../utils/map_style.js';
3
+ import maplibre from 'maplibre-gl';
4
+ import type { MapOptions } from 'maplibre-gl';
4
5
  type $$ComponentProps = {
5
6
  style?: string;
6
7
  styleOptions?: Parameters<typeof getMapStyle>[1];
7
8
  mapOptions?: Partial<MapOptions>;
8
- map?: MaplibreMapType;
9
- onMapInit?: (map: MaplibreMapType) => void;
10
- onMapLoad?: (map: MaplibreMapType) => void;
9
+ map?: maplibre.Map;
10
+ onMapInit?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
11
+ onMapLoad?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
11
12
  };
12
13
  declare const BasicMap: import("svelte").Component<$$ComponentProps, {}, "map">;
13
14
  type BasicMap = ReturnType<typeof BasicMap>;
@@ -1,4 +1,3 @@
1
- <!-- LocatorMap.svelte -->
2
1
  <script lang="ts">
3
2
  import type { Map as MaplibreMapType, GeoJSONSource } from 'maplibre-gl';
4
3
  import BasicMap from '../BasicMap/BasicMap.svelte';
@@ -10,7 +9,6 @@
10
9
  let coordinates: [number, number] = [0, 0];
11
10
  const initialHash = parseHash();
12
11
  if (initialHash) {
13
- console.log('initialHash', initialHash);
14
12
  coordinates = [initialHash[1], initialHash[2]];
15
13
  map.setZoom(initialHash[0]);
16
14
  map.setCenter(coordinates);
@@ -15,25 +15,34 @@
15
15
  let map: MaplibreMapType | undefined = $state();
16
16
  let geometryManager: GeometryManager | undefined = $state();
17
17
 
18
- function onMapInit(_map: MaplibreMapType) {
18
+ function onMapInit(_map: MaplibreMapType, maplibre: typeof import('maplibre-gl')) {
19
19
  map = _map;
20
+ map.addControl(new maplibre.AttributionControl({ compact: true }), 'bottom-left');
21
+
20
22
  map.on('load', async () => {
21
23
  const { GeometryManager } = await import('./lib/geometry_manager.js');
22
24
  geometryManager = new GeometryManager(map!);
25
+ const hash = location.hash.slice(1);
26
+ if (hash) geometryManager.state.setHash(hash);
27
+ addEventListener('hashchange', () => geometryManager!.state.setHash(location.hash.slice(1)));
23
28
  });
24
29
  }
25
30
  </script>
26
31
 
27
32
  <div class="page">
28
33
  <div class="container">
29
- <BasicMap {onMapInit} styleOptions={{ disableDarkMode: true }}></BasicMap>
34
+ <BasicMap
35
+ {onMapInit}
36
+ styleOptions={{ disableDarkMode: true }}
37
+ mapOptions={{ attributionControl: false }}
38
+ ></BasicMap>
30
39
  </div>
31
40
  {#if showSidebar && geometryManager}
32
41
  <Sidebar {geometryManager} width={200} />
33
42
 
34
43
  <style>
35
44
  .page .container {
36
- width: calc(100% - 200px);
45
+ width: 100%;
37
46
  position: absolute;
38
47
  top: 0;
39
48
  left: 0;
@@ -50,4 +59,8 @@
50
59
  position: relative;
51
60
  min-height: 6em;
52
61
  }
62
+ :global(.maplibregl-ctrl-attrib) {
63
+ display: flex;
64
+ align-items: center;
65
+ }
53
66
  </style>
@@ -6,48 +6,55 @@
6
6
  import { LineElement } from '../lib/element/line.js';
7
7
  import { MarkerElement } from '../lib/element/marker.js';
8
8
  import { PolygonElement } from '../lib/element/polygon.js';
9
+ import InputRow from './InputRow.svelte';
10
+ import SidebarPanel from './SidebarPanel.svelte';
11
+ import { writable } from 'svelte/store';
9
12
 
10
- const { element }: { element: AbstractElement } = $props();
11
- let strokeVisible = $state(false);
13
+ const { element }: { element: AbstractElement | undefined } = $props();
12
14
 
13
- if (element instanceof PolygonElement) {
14
- element.strokeLayer.visible.subscribe((value) => (strokeVisible = value));
15
- }
15
+ const noElement = $derived(!element);
16
+ const strokeVisible = $derived.by(() => {
17
+ if (element instanceof PolygonElement) return element.strokeLayer.visible;
18
+ return writable(false);
19
+ });
16
20
  </script>
17
21
 
18
- {#if element instanceof MarkerElement}
19
- <h2>Marker</h2>
20
- <EditorSymbol layer={element.layer} />
21
- {/if}
22
- {#if element instanceof LineElement}
23
- <h2>Line Stroke</h2>
24
- <EditorStroke layer={element.layer} />
25
- {/if}
26
- {#if element instanceof PolygonElement}
27
- <h2>Polygon Fill</h2>
28
- <EditorFill layer={element.fillLayer} />
29
- <h2>Polygon Stroke</h2>
22
+ {#key element}
23
+ <SidebarPanel title="Style" disabled={noElement}>
24
+ <div class="style-editor">
25
+ {#if element instanceof MarkerElement}
26
+ <EditorSymbol layer={element.layer} />
27
+ {/if}
28
+ {#if element instanceof LineElement}
29
+ <EditorStroke layer={element.layer} />
30
+ {/if}
31
+ {#if element instanceof PolygonElement}
32
+ <EditorFill layer={element.fillLayer} />
33
+ <hr />
34
+
35
+ <InputRow id="showStroke" label="Draw Outline">
36
+ <input id="showStroke" type="checkbox" bind:checked={$strokeVisible} />
37
+ </InputRow>
30
38
 
31
- <div class="row-input">
32
- <label for="showStroke">Outline:</label>
33
- <input
34
- id="showStroke"
35
- type="checkbox"
36
- bind:checked={
37
- () => strokeVisible, (v) => (element as PolygonElement).strokeLayer.visible.set(v)
38
- }
39
- />
40
- </div>
39
+ {#if $strokeVisible}
40
+ <EditorStroke layer={element.strokeLayer} />
41
+ {/if}
42
+ {/if}
43
+ {#if element instanceof PolygonElement || element instanceof LineElement}
44
+ <hr />
45
+ <p>
46
+ Drag points to move.<br />Drag a midpoint to add.<br />Shift-click to delete a point.
47
+ </p>
48
+ {/if}
49
+ </div>
50
+ </SidebarPanel>
51
+ {/key}
41
52
 
42
- {#if strokeVisible}
43
- <EditorStroke layer={element.strokeLayer} />
44
- {/if}
45
- {/if}
46
- {#if element instanceof PolygonElement || element instanceof LineElement}
47
- <h2>Shape</h2>
48
- <p>
49
- Drag points to move.<br />Drag a midpoint to add.<br />Shift-click to delete a point.
50
- </p>
51
- {/if}
52
- <h2>Actions</h2>
53
- <input type="button" value="Delete" onclick={() => element!.delete()} />
53
+ <style>
54
+ .style-editor {
55
+ :global(p) {
56
+ opacity: 0.5;
57
+ margin: 0.5em 0 1em;
58
+ }
59
+ }
60
+ </style>
@@ -1,6 +1,6 @@
1
1
  import type { AbstractElement } from '../lib/element/abstract.js';
2
2
  type $$ComponentProps = {
3
- element: AbstractElement;
3
+ element: AbstractElement | undefined;
4
4
  };
5
5
  declare const Editor: import("svelte").Component<$$ComponentProps, {}, "">;
6
6
  type Editor = ReturnType<typeof Editor>;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { fillPatterns, type MapLayerFill } from '../lib/map_layer/fill.js';
3
+ import InputRow from './InputRow.svelte';
3
4
 
4
5
  const { layer }: { layer: MapLayerFill } = $props();
5
6
 
@@ -8,21 +9,18 @@
8
9
  let opacity = $state(layer.opacity);
9
10
  </script>
10
11
 
11
- <div class="row-input">
12
- <label for="color">Color:</label>
12
+ <InputRow label="Color" id="color">
13
13
  <input id="color" type="color" bind:value={$color} />
14
- </div>
14
+ </InputRow>
15
15
 
16
- <div class="row-input">
17
- <label for="pattern">Pattern:</label>
16
+ <InputRow label="Pattern" id="pattern">
18
17
  <select id="pattern" bind:value={$pattern}>
19
18
  {#each fillPatterns as [index, fill] (index)}
20
19
  <option value={index}>{fill.name}</option>
21
20
  {/each}
22
21
  </select>
23
- </div>
22
+ </InputRow>
24
23
 
25
- <div class="row-input">
26
- <label for="opacity">Opacity:</label>
24
+ <InputRow label="Opacity" id="opacity">
27
25
  <input id="opacity" type="range" min="0" max="1" step="0.02" bind:value={$opacity} />
28
- </div>
26
+ </InputRow>
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { dashArrays, MapLayerLine } from '../lib/map_layer/line.js';
3
+ import InputRow from './InputRow.svelte';
3
4
 
4
5
  const { layer }: { layer: MapLayerLine } = $props();
5
6
 
@@ -8,21 +9,18 @@
8
9
  let dashed = $state(layer.dashed);
9
10
  </script>
10
11
 
11
- <div class="row-input">
12
- <label for="dashed">Dashed:</label>
12
+ <InputRow id="color" label="Color">
13
+ <input id="color" type="color" bind:value={$color} />
14
+ </InputRow>
15
+
16
+ <InputRow id="dashed" label="Dashed">
13
17
  <select id="dashed" bind:value={$dashed}>
14
18
  {#each dashArrays as [index, dash] (index)}
15
19
  <option value={index}>{dash.name}</option>
16
20
  {/each}
17
21
  </select>
18
- </div>
19
-
20
- <div class="row-input">
21
- <label for="color">Color:</label>
22
- <input id="color" type="color" bind:value={$color} />
23
- </div>
22
+ </InputRow>
24
23
 
25
- <div class="row-input">
26
- <label for="width">Width:</label>
24
+ <InputRow id="width" label="Width">
27
25
  <input id="width" type="range" min="0.5" max="5" step="0.5" bind:value={$width} />
28
- </div>
26
+ </InputRow>
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
- import { MapLayerSymbol } from '../lib/map_layer/symbol.js';
2
+ import { labelPositions, MapLayerSymbol } from '../lib/map_layer/symbol.js';
3
+ import InputRow from './InputRow.svelte';
3
4
  import SymbolSelector from './SymbolSelector.svelte';
4
5
 
5
6
  const { layer }: { layer: MapLayerSymbol } = $props();
@@ -9,35 +10,38 @@
9
10
  let rotate = $state(layer.rotate);
10
11
  let halo = $state(layer.halo);
11
12
  let label = $state(layer.label);
13
+ let labelAlign = $state(layer.labelAlign);
12
14
  let size = $state(layer.size);
13
15
  </script>
14
16
 
15
- <div class="row-input">
16
- <div class="label">Symbol:</div>
17
+ <InputRow id="label" label="Symbol">
17
18
  <SymbolSelector bind:symbolIndex={$symbolIndex} symbolLibrary={layer.manager.symbolLibrary} />
18
- </div>
19
+ </InputRow>
19
20
 
20
- <div class="row-input">
21
- <label for="color">Color:</label>
21
+ <InputRow id="color" label="Color">
22
22
  <input id="color" type="color" bind:value={$color} />
23
- </div>
23
+ </InputRow>
24
24
 
25
- <div class="row-input">
26
- <label for="size">Size:</label>
25
+ <InputRow id="size" label="Size">
27
26
  <input id="size" type="range" min="0.5" max="3" step="0.1" bind:value={$size} />
28
- </div>
27
+ </InputRow>
29
28
 
30
- <div class="row-input">
31
- <label for="rotate">Rotation:</label>
29
+ <InputRow id="rotate" label="Rotation">
32
30
  <input id="rotate" type="range" min="-180" max="180" step="15" bind:value={$rotate} />
33
- </div>
31
+ </InputRow>
34
32
 
35
- <div class="row-input">
36
- <label for="halo">Halo:</label>
33
+ <InputRow id="halo" label="Halo">
37
34
  <input id="halo" type="range" min="0" max="3" step="0.5" bind:value={$halo} />
38
- </div>
35
+ </InputRow>
39
36
 
40
- <div class="row-input">
41
- <label for="label">Label:</label>
37
+ <InputRow id="label" label="Label">
42
38
  <input id="label" type="label" bind:value={$label} />
43
- </div>
39
+ </InputRow>
40
+
41
+ <InputRow id="labelAlign" label="Align Label">
42
+ <select id="labelAlign" bind:value={$labelAlign}>
43
+ {#each labelPositions as { index, name } (index)}
44
+ <option value={index}>{name}</option>
45
+ {/each}
46
+ </select>
47
+ </InputRow>
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ const { children, label, id }: { children: Snippet; label: string; id: string } = $props();
5
+ </script>
6
+
7
+ <div class="row">
8
+ <label for={id}>{label}</label>
9
+ {@render children()}
10
+ </div>
11
+
12
+ <style>
13
+ .row {
14
+ margin: var(--gap) 0 var(--gap);
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ color: var(--fg-color);
19
+ & > :global(label) {
20
+ flex-grow: 0;
21
+ opacity: 0.5;
22
+ }
23
+ & > :global(button),
24
+ & > :global(input),
25
+ & > :global(select) {
26
+ box-sizing: border-box;
27
+ width: 60%;
28
+ flex-grow: 0;
29
+ }
30
+ & > :global(input[type='checkbox']) {
31
+ width: auto;
32
+ }
33
+ }
34
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ children: Snippet;
4
+ label: string;
5
+ id: string;
6
+ };
7
+ declare const InputRow: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type InputRow = ReturnType<typeof InputRow>;
9
+ export default InputRow;