@versatiles/svelte 2.0.0 → 2.0.1

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.
@@ -33,7 +33,17 @@
33
33
  <hr />
34
34
 
35
35
  <InputRow id="showStroke" label="Draw Outline">
36
- <input id="showStroke" type="checkbox" bind:checked={$strokeVisible} />
36
+ <input
37
+ id="showStroke"
38
+ type="checkbox"
39
+ bind:checked={
40
+ () => $strokeVisible,
41
+ (visible) => {
42
+ $strokeVisible = visible;
43
+ element.manager.state.log();
44
+ }
45
+ }
46
+ />
37
47
  </InputRow>
38
48
 
39
49
  {#if $strokeVisible}
@@ -10,11 +10,30 @@
10
10
  </script>
11
11
 
12
12
  <InputRow label="Color" id="color">
13
- <input id="color" type="color" bind:value={$color} />
13
+ <input
14
+ id="color"
15
+ type="color"
16
+ bind:value={
17
+ () => $color,
18
+ (v) => {
19
+ $color = v;
20
+ layer.manager.state.log();
21
+ }
22
+ }
23
+ />
14
24
  </InputRow>
15
25
 
16
26
  <InputRow label="Pattern" id="pattern">
17
- <select id="pattern" bind:value={$pattern}>
27
+ <select
28
+ id="pattern"
29
+ bind:value={
30
+ () => $pattern,
31
+ (v) => {
32
+ $pattern = v;
33
+ layer.manager.state.log();
34
+ }
35
+ }
36
+ >
18
37
  {#each fillPatterns as [index, fill] (index)}
19
38
  <option value={index}>{fill.name}</option>
20
39
  {/each}
@@ -22,5 +41,18 @@
22
41
  </InputRow>
23
42
 
24
43
  <InputRow label="Opacity" id="opacity">
25
- <input id="opacity" type="range" min="0" max="1" step="0.02" bind:value={$opacity} />
44
+ <input
45
+ id="opacity"
46
+ type="range"
47
+ min="0"
48
+ max="1"
49
+ step="0.02"
50
+ bind:value={
51
+ () => $opacity,
52
+ (v) => {
53
+ $opacity = v;
54
+ layer.manager.state.log();
55
+ }
56
+ }
57
+ />
26
58
  </InputRow>
@@ -10,11 +10,30 @@
10
10
  </script>
11
11
 
12
12
  <InputRow id="color" label="Color">
13
- <input id="color" type="color" bind:value={$color} />
13
+ <input
14
+ id="color"
15
+ type="color"
16
+ bind:value={
17
+ () => $color,
18
+ (v) => {
19
+ $color = v;
20
+ layer.manager.state.log();
21
+ }
22
+ }
23
+ />
14
24
  </InputRow>
15
25
 
16
26
  <InputRow id="dashed" label="Dashed">
17
- <select id="dashed" bind:value={$dashed}>
27
+ <select
28
+ id="dashed"
29
+ bind:value={
30
+ () => $dashed,
31
+ (v) => {
32
+ $dashed = v;
33
+ layer.manager.state.log();
34
+ }
35
+ }
36
+ >
18
37
  {#each dashArrays as [index, dash] (index)}
19
38
  <option value={index}>{dash.name}</option>
20
39
  {/each}
@@ -22,5 +41,18 @@
22
41
  </InputRow>
23
42
 
24
43
  <InputRow id="width" label="Width">
25
- <input id="width" type="range" min="0.5" max="5" step="0.5" bind:value={$width} />
44
+ <input
45
+ id="width"
46
+ type="range"
47
+ min="0.5"
48
+ max="5"
49
+ step="0.5"
50
+ bind:value={
51
+ () => $width,
52
+ (v) => {
53
+ $width = v;
54
+ layer.manager.state.log();
55
+ }
56
+ }
57
+ />
26
58
  </InputRow>
@@ -15,31 +15,108 @@
15
15
  </script>
16
16
 
17
17
  <InputRow id="label" label="Symbol">
18
- <SymbolSelector bind:symbolIndex={$symbolIndex} symbolLibrary={layer.manager.symbolLibrary} />
18
+ <SymbolSelector
19
+ bind:symbolIndex={
20
+ () => $symbolIndex,
21
+ (v) => {
22
+ $symbolIndex = v;
23
+ layer.manager.state.log();
24
+ }
25
+ }
26
+ symbolLibrary={layer.manager.symbolLibrary}
27
+ />
19
28
  </InputRow>
20
29
 
21
30
  <InputRow id="color" label="Color">
22
- <input id="color" type="color" bind:value={$color} />
31
+ <input
32
+ id="color"
33
+ type="color"
34
+ bind:value={
35
+ () => $color,
36
+ (v) => {
37
+ $color = v;
38
+ layer.manager.state.log();
39
+ }
40
+ }
41
+ />
23
42
  </InputRow>
24
43
 
25
44
  <InputRow id="size" label="Size">
26
- <input id="size" type="range" min="0.5" max="3" step="0.1" bind:value={$size} />
45
+ <input
46
+ id="size"
47
+ type="range"
48
+ min="0.5"
49
+ max="3"
50
+ step="0.1"
51
+ bind:value={
52
+ () => $size,
53
+ (v) => {
54
+ $size = v;
55
+ layer.manager.state.log();
56
+ }
57
+ }
58
+ />
27
59
  </InputRow>
28
60
 
29
61
  <InputRow id="rotate" label="Rotation">
30
- <input id="rotate" type="range" min="-180" max="180" step="15" bind:value={$rotate} />
62
+ <input
63
+ id="rotate"
64
+ type="range"
65
+ min="-180"
66
+ max="180"
67
+ step="15"
68
+ bind:value={
69
+ () => $rotate,
70
+ (v) => {
71
+ $rotate = v;
72
+ layer.manager.state.log();
73
+ }
74
+ }
75
+ />
31
76
  </InputRow>
32
77
 
33
78
  <InputRow id="halo" label="Halo">
34
- <input id="halo" type="range" min="0" max="3" step="0.5" bind:value={$halo} />
79
+ <input
80
+ id="halo"
81
+ type="range"
82
+ min="0"
83
+ max="3"
84
+ step="0.5"
85
+ bind:value={
86
+ () => $halo,
87
+ (v) => {
88
+ $halo = v;
89
+ layer.manager.state.log();
90
+ }
91
+ }
92
+ />
35
93
  </InputRow>
36
94
 
37
95
  <InputRow id="label" label="Label">
38
- <input id="label" type="label" bind:value={$label} />
96
+ <input
97
+ id="label"
98
+ type="label"
99
+ bind:value={
100
+ () => $label,
101
+ (v) => {
102
+ $label = v;
103
+ layer.manager.state.log();
104
+ }
105
+ }
106
+ />
39
107
  </InputRow>
40
108
 
41
109
  <InputRow id="labelAlign" label="Align Label">
42
- <select id="labelAlign" bind:value={$labelAlign}>
110
+ <select
111
+ id="labelAlign"
112
+ bind:value={
113
+ () => $labelAlign,
114
+ (v) => {
115
+ $labelAlign = v;
116
+ layer.manager.state.log();
117
+ }
118
+ }
119
+ >
43
120
  {#each labelPositions as { index, name } (index)}
44
121
  <option value={index}>{name}</option>
45
122
  {/each}
@@ -22,6 +22,7 @@
22
22
  if (!evt.target) return alert('Failed to read file.');
23
23
  const json = JSON.parse(evt.target.result as string);
24
24
  geometryManager.addGeoJSON(json);
25
+ geometryManager.state.log();
25
26
  } catch (error) {
26
27
  console.error(error);
27
28
  return alert('Failed to import GeoJSON. Please check the file format.');
@@ -97,15 +98,21 @@
97
98
  <Editor element={$activeElement} />
98
99
  <SidebarPanel title="Actions" disabled={!$activeElement}>
99
100
  <div class="flex flex-two">
100
- <button onclick={() => $activeElement!.delete()}>Delete</button>
101
+ <button
102
+ onclick={() => {
103
+ $activeElement!.delete();
104
+ geometryManager.state.log();
105
+ }}>Delete</button
106
+ >
101
107
  </div>
102
108
  </SidebarPanel>
103
- <SidebarPanel title="Help">
109
+ <SidebarPanel title="Help" open={false}>
110
+ Submit bugs and feature requests as
104
111
  <a
105
112
  id="github_link"
106
113
  href="https://github.com/versatiles-org/node-versatiles-svelte/issues"
107
114
  target="_blank"
108
- aria-label="Repository on GitHub">Report Bugs and Feature Requests as GitHub Issues</a
115
+ aria-label="Repository on GitHub">GitHub issues</a
109
116
  >
110
117
  </SidebarPanel>
111
118
  </div>
@@ -175,10 +182,6 @@
175
182
  }
176
183
 
177
184
  a {
178
- text-decoration: none;
179
185
  color: var(--fg-color);
180
- &:hover {
181
- text-decoration: underline;
182
- }
183
186
  }
184
187
  </style>
@@ -3,9 +3,9 @@
3
3
 
4
4
  let {
5
5
  children,
6
+ disabled = false,
6
7
  open = true,
7
- title,
8
- disabled = false
8
+ title
9
9
  }: { children: Snippet; disabled?: boolean; open?: boolean; title: string } = $props();
10
10
  </script>
11
11
 
@@ -40,9 +40,10 @@
40
40
  width: 100%;
41
41
 
42
42
  .title {
43
- text-transform: uppercase;
44
43
  opacity: 0.8;
44
+ text-transform: uppercase;
45
45
  }
46
+
46
47
  .chevron {
47
48
  box-sizing: border-box;
48
49
  display: block;
@@ -53,25 +54,30 @@
53
54
  right: 0.4em;
54
55
  top: 0;
55
56
  width: 1em;
57
+
56
58
  svg {
57
59
  fill: var(--color-fg);
58
- width: 100%;
59
60
  height: 100%;
60
61
  rotate: 0deg;
61
- transition: rotate 0.1s linear;
62
62
  transform-origin: 40% 50%;
63
+ transition: rotate 0.1s linear;
64
+ width: 100%;
63
65
  }
64
66
  }
65
67
  }
68
+
66
69
  .content {
70
+ box-sizing: border-box;
67
71
  height: 0;
72
+ margin: var(--gap) 0;
68
73
  overflow: hidden;
69
74
  padding: 0;
70
- box-sizing: border-box;
71
75
  }
72
76
  }
77
+
73
78
  .open {
74
79
  margin-bottom: 2em;
80
+
75
81
  .header {
76
82
  .chevron {
77
83
  svg {
@@ -79,12 +85,15 @@
79
85
  }
80
86
  }
81
87
  }
88
+
82
89
  .content {
83
90
  height: auto;
84
91
  }
85
92
  }
93
+
86
94
  .disabled {
87
95
  opacity: 0.3;
96
+
88
97
  .content {
89
98
  display: none;
90
99
  }
@@ -3,11 +3,11 @@ import type { GeometryManager } from '../geometry_manager.js';
3
3
  import type { StateElement } from '../state/types.js';
4
4
  export declare abstract class AbstractElement {
5
5
  protected readonly canvas: HTMLElement;
6
- protected readonly manager: GeometryManager;
7
6
  protected readonly map: maplibregl.Map;
8
7
  protected readonly source: maplibregl.GeoJSONSource;
9
8
  protected readonly slug: string;
10
9
  protected isSelected: boolean;
10
+ readonly manager: GeometryManager;
11
11
  readonly sourceId: string;
12
12
  constructor(manager: GeometryManager);
13
13
  select(value: boolean): void;
@@ -1,10 +1,10 @@
1
1
  export class AbstractElement {
2
2
  canvas;
3
- manager;
4
3
  map;
5
4
  source;
6
5
  slug = '_' + Math.random().toString(36).slice(2);
7
6
  isSelected = false;
7
+ manager;
8
8
  sourceId = 'source' + this.slug;
9
9
  constructor(manager) {
10
10
  this.manager = manager;
@@ -164,13 +164,11 @@ export class GeometryManager {
164
164
  }
165
165
  appendElement(element) {
166
166
  this.elements.update((elements) => [...elements, element]);
167
- this.state.log();
168
167
  }
169
168
  removeElement(element) {
170
169
  if (get(this.selectedElement) === element)
171
170
  this.selectElement(undefined);
172
171
  this.elements.update((elements) => elements.filter((e) => e !== element));
173
- this.state.log();
174
172
  }
175
173
  getGeoJSON() {
176
174
  const center = this.map.getCenter();
@@ -13,7 +13,6 @@ export declare abstract class MapLayer<T extends LayerSpec> {
13
13
  eventHandlers: Map<Events, MouseEventHandler[]>;
14
14
  isSelected: boolean;
15
15
  constructor(manager: GeometryManager, id: string);
16
- pushState(): void;
17
16
  addLayer(source: string, type: 'symbol' | 'line' | 'fill', layout: T['layout'], paint: T['paint']): void;
18
17
  on(event: Events, handler: MouseEventHandler): void;
19
18
  off(event: Events, handler: MouseEventHandler): void;
@@ -12,9 +12,6 @@ export class MapLayer {
12
12
  this.map = manager.map;
13
13
  this.id = id;
14
14
  }
15
- pushState() {
16
- this.manager.state.log();
17
- }
18
15
  addLayer(source, type, layout, paint) {
19
16
  layout = cloneClean(layout);
20
17
  paint = cloneClean(paint);
@@ -52,18 +52,9 @@ export class MapLayerFill extends MapLayer {
52
52
  this.map.addImage(name, { width: size, height: size, data });
53
53
  this.updatePaint('fill-pattern', name);
54
54
  };
55
- this.color.subscribe(() => {
56
- updatePattern();
57
- this.manager.state.log();
58
- });
59
- this.pattern.subscribe(() => {
60
- updatePattern();
61
- this.manager.state.log();
62
- });
63
- this.opacity.subscribe((value) => {
64
- this.updatePaint('fill-opacity', value);
65
- this.manager.state.log();
66
- });
55
+ this.color.subscribe(() => updatePattern());
56
+ this.pattern.subscribe(() => updatePattern());
57
+ this.opacity.subscribe((value) => this.updatePaint('fill-opacity', value));
67
58
  }
68
59
  getState() {
69
60
  return removeDefaultFields({
@@ -30,22 +30,10 @@ export class MapLayerLine extends MapLayer {
30
30
  'line-dasharray': get(this.dashArray),
31
31
  'line-width': get(this.width)
32
32
  });
33
- this.color.subscribe((v) => {
34
- this.updatePaint('line-color', Color.parse(v));
35
- this.manager.state.log();
36
- });
37
- this.dashArray.subscribe((v) => {
38
- this.updatePaint('line-dasharray', v);
39
- this.manager.state.log();
40
- });
41
- this.visible.subscribe((v) => {
42
- this.updateLayout('visibility', v ? 'visible' : 'none');
43
- this.manager.state.log();
44
- });
45
- this.width.subscribe((v) => {
46
- this.updatePaint('line-width', v);
47
- this.manager.state.log();
48
- });
33
+ this.color.subscribe((v) => this.updatePaint('line-color', Color.parse(v)));
34
+ this.dashArray.subscribe((v) => this.updatePaint('line-dasharray', v));
35
+ this.visible.subscribe((v) => this.updateLayout('visibility', v ? 'visible' : 'none'));
36
+ this.width.subscribe((v) => this.updatePaint('line-width', v));
49
37
  }
50
38
  getState() {
51
39
  return removeDefaultFields({
@@ -1,6 +1,7 @@
1
1
  import type { GeometryManager } from '../geometry_manager.js';
2
2
  export declare class StateManager {
3
3
  geometryManager: GeometryManager;
4
+ private disableLogging;
4
5
  constructor(geometryManager: GeometryManager);
5
6
  getHash(): string;
6
7
  setHash(hash: string): void;
@@ -4,6 +4,7 @@ import { StateWriter } from './writer.js';
4
4
  const MAXLENGTH = 100;
5
5
  export class StateManager {
6
6
  geometryManager;
7
+ disableLogging = false;
7
8
  constructor(geometryManager) {
8
9
  this.geometryManager = geometryManager;
9
10
  this.resetHistory();
@@ -18,8 +19,12 @@ export class StateManager {
18
19
  return;
19
20
  try {
20
21
  const state = StateReader.fromBase64(hash).readRoot();
22
+ this.disableLogging = true;
21
23
  this.geometryManager.setState(state);
22
- this.resetHistory();
24
+ this.disableLogging = false;
25
+ this.history = [{ ...state, map: undefined }];
26
+ this.historyIndex = 0;
27
+ this.updateButtons();
23
28
  }
24
29
  catch (error) {
25
30
  console.error(error);
@@ -40,6 +45,8 @@ export class StateManager {
40
45
  this.updateButtons();
41
46
  }
42
47
  log() {
48
+ if (this.disableLogging)
49
+ return;
43
50
  const state = this.geometryManager.getState();
44
51
  state.map = undefined; // Remove map state from history
45
52
  if (this.historyIndex > 0) {
@@ -57,7 +64,9 @@ export class StateManager {
57
64
  if (this.historyIndex < this.history.length - 1) {
58
65
  this.historyIndex++;
59
66
  const state = this.history[this.historyIndex];
67
+ this.disableLogging = true;
60
68
  this.geometryManager.setState(state);
69
+ this.disableLogging = false;
61
70
  this.updateButtons();
62
71
  }
63
72
  }
@@ -65,7 +74,9 @@ export class StateManager {
65
74
  if (this.historyIndex > 0) {
66
75
  this.historyIndex--;
67
76
  const state = this.history[this.historyIndex];
77
+ this.disableLogging = true;
68
78
  this.geometryManager.setState(state);
79
+ this.disableLogging = false;
69
80
  this.updateButtons();
70
81
  }
71
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/svelte",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",