@versatiles/svelte 1.1.2 → 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.
- package/dist/components/BasicMap/BasicMap.svelte +4 -4
- package/dist/components/BasicMap/BasicMap.svelte.d.ts +2 -2
- package/dist/components/MapEditor/MapEditor.svelte +16 -3
- package/dist/components/MapEditor/components/Editor.svelte +46 -40
- package/dist/components/MapEditor/components/Editor.svelte.d.ts +1 -1
- package/dist/components/MapEditor/components/EditorFill.svelte +7 -9
- package/dist/components/MapEditor/components/EditorStroke.svelte +9 -11
- package/dist/components/MapEditor/components/EditorSymbol.svelte +15 -21
- package/dist/components/MapEditor/components/InputRow.svelte +34 -0
- package/dist/components/MapEditor/components/InputRow.svelte.d.ts +9 -0
- package/dist/components/MapEditor/components/Sidebar.svelte +115 -108
- package/dist/components/MapEditor/components/SidebarPanel.svelte +92 -0
- package/dist/components/MapEditor/components/SidebarPanel.svelte.d.ts +10 -0
- package/dist/components/MapEditor/components/SymbolSelector.svelte +7 -15
- package/dist/components/MapEditor/lib/element/abstract.d.ts +3 -3
- package/dist/components/MapEditor/lib/element/abstract.js +1 -1
- package/dist/components/MapEditor/lib/element/line.d.ts +3 -4
- package/dist/components/MapEditor/lib/element/line.js +0 -1
- package/dist/components/MapEditor/lib/element/marker.d.ts +4 -4
- package/dist/components/MapEditor/lib/element/polygon.d.ts +3 -3
- package/dist/components/MapEditor/lib/geometry_manager.d.ts +20 -10
- package/dist/components/MapEditor/lib/geometry_manager.js +44 -52
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +3 -2
- package/dist/components/MapEditor/lib/map_layer/abstract.js +3 -0
- package/dist/components/MapEditor/lib/map_layer/fill.d.ts +4 -3
- package/dist/components/MapEditor/lib/map_layer/fill.js +9 -8
- package/dist/components/MapEditor/lib/map_layer/line.d.ts +4 -3
- package/dist/components/MapEditor/lib/map_layer/line.js +15 -14
- package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +5 -4
- package/dist/components/MapEditor/lib/map_layer/symbol.js +28 -46
- package/dist/components/MapEditor/lib/state/constants.d.ts +4 -0
- package/dist/components/MapEditor/lib/state/constants.js +22 -0
- package/dist/components/MapEditor/lib/state/manager.d.ts +16 -0
- package/dist/components/MapEditor/lib/state/manager.js +76 -0
- package/dist/components/MapEditor/lib/state/reader.d.ts +21 -14
- package/dist/components/MapEditor/lib/state/reader.js +259 -142
- package/dist/components/MapEditor/lib/state/types.d.ts +27 -12
- package/dist/components/MapEditor/lib/state/writer.d.ts +18 -14
- package/dist/components/MapEditor/lib/state/writer.js +182 -169
- package/dist/components/MapEditor/lib/utils.d.ts +2 -5
- package/dist/components/MapEditor/lib/utils.js +0 -19
- package/package.json +19 -19
@@ -17,8 +17,8 @@
|
|
17
17
|
styleOptions?: Parameters<typeof getMapStyle>[1];
|
18
18
|
mapOptions?: Partial<MapOptions>;
|
19
19
|
map?: maplibre.Map;
|
20
|
-
onMapInit?: (map: maplibre.Map) => void;
|
21
|
-
onMapLoad?: (map: maplibre.Map) => void;
|
20
|
+
onMapInit?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
|
21
|
+
onMapLoad?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
|
22
22
|
} = $props();
|
23
23
|
|
24
24
|
let container: HTMLDivElement;
|
@@ -48,10 +48,10 @@
|
|
48
48
|
...mapOptions
|
49
49
|
});
|
50
50
|
|
51
|
-
if (onMapInit) onMapInit(map);
|
51
|
+
if (onMapInit) onMapInit(map, maplibre);
|
52
52
|
|
53
53
|
map.on('load', () => {
|
54
|
-
if (onMapLoad) onMapLoad(map
|
54
|
+
if (onMapLoad) onMapLoad(map!, maplibre);
|
55
55
|
});
|
56
56
|
}
|
57
57
|
</script>
|
@@ -7,8 +7,8 @@ type $$ComponentProps = {
|
|
7
7
|
styleOptions?: Parameters<typeof getMapStyle>[1];
|
8
8
|
mapOptions?: Partial<MapOptions>;
|
9
9
|
map?: maplibre.Map;
|
10
|
-
onMapInit?: (map: maplibre.Map) => void;
|
11
|
-
onMapLoad?: (map: maplibre.Map) => void;
|
10
|
+
onMapInit?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
|
11
|
+
onMapLoad?: (map: maplibre.Map, maplibre: typeof import('maplibre-gl')) => void;
|
12
12
|
};
|
13
13
|
declare const BasicMap: import("svelte").Component<$$ComponentProps, {}, "map">;
|
14
14
|
type BasicMap = ReturnType<typeof BasicMap>;
|
@@ -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
|
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:
|
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,49 +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();
|
13
|
+
const { element }: { element: AbstractElement | undefined } = $props();
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
15
|
+
const noElement = $derived(!element);
|
16
|
+
const strokeVisible = $derived.by(() => {
|
17
|
+
if (element instanceof PolygonElement) return element.strokeLayer.visible;
|
18
|
+
return writable(false);
|
19
|
+
});
|
17
20
|
</script>
|
18
21
|
|
19
|
-
{#
|
20
|
-
<
|
21
|
-
|
22
|
-
{
|
23
|
-
{
|
24
|
-
|
25
|
-
|
26
|
-
{
|
27
|
-
{
|
28
|
-
|
29
|
-
|
30
|
-
|
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 />
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
id="showStroke"
|
36
|
-
type="checkbox"
|
37
|
-
bind:checked={
|
38
|
-
() => strokeVisible, (v) => (element as PolygonElement).strokeLayer.visible.set(v)
|
39
|
-
}
|
40
|
-
/>
|
41
|
-
</div>
|
35
|
+
<InputRow id="showStroke" label="Draw Outline">
|
36
|
+
<input id="showStroke" type="checkbox" bind:checked={$strokeVisible} />
|
37
|
+
</InputRow>
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
{/if}
|
47
|
-
{#if element instanceof PolygonElement || element instanceof LineElement}
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
{/if}
|
53
|
-
|
54
|
-
|
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}
|
52
|
+
|
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
|
-
<
|
12
|
-
<label for="color">Color:</label>
|
12
|
+
<InputRow label="Color" id="color">
|
13
13
|
<input id="color" type="color" bind:value={$color} />
|
14
|
-
</
|
14
|
+
</InputRow>
|
15
15
|
|
16
|
-
<
|
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
|
-
</
|
22
|
+
</InputRow>
|
24
23
|
|
25
|
-
<
|
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
|
-
</
|
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
|
-
<
|
12
|
-
<
|
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
|
-
</
|
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
|
-
<
|
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
|
-
</
|
26
|
+
</InputRow>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<script lang="ts">
|
2
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();
|
@@ -13,41 +14,34 @@
|
|
13
14
|
let size = $state(layer.size);
|
14
15
|
</script>
|
15
16
|
|
16
|
-
<
|
17
|
-
<div class="label">Symbol:</div>
|
17
|
+
<InputRow id="label" label="Symbol">
|
18
18
|
<SymbolSelector bind:symbolIndex={$symbolIndex} symbolLibrary={layer.manager.symbolLibrary} />
|
19
|
-
</
|
19
|
+
</InputRow>
|
20
20
|
|
21
|
-
<
|
22
|
-
<label for="color">Color:</label>
|
21
|
+
<InputRow id="color" label="Color">
|
23
22
|
<input id="color" type="color" bind:value={$color} />
|
24
|
-
</
|
23
|
+
</InputRow>
|
25
24
|
|
26
|
-
<
|
27
|
-
<label for="size">Size:</label>
|
25
|
+
<InputRow id="size" label="Size">
|
28
26
|
<input id="size" type="range" min="0.5" max="3" step="0.1" bind:value={$size} />
|
29
|
-
</
|
27
|
+
</InputRow>
|
30
28
|
|
31
|
-
<
|
32
|
-
<label for="rotate">Rotation:</label>
|
29
|
+
<InputRow id="rotate" label="Rotation">
|
33
30
|
<input id="rotate" type="range" min="-180" max="180" step="15" bind:value={$rotate} />
|
34
|
-
</
|
31
|
+
</InputRow>
|
35
32
|
|
36
|
-
<
|
37
|
-
<label for="halo">Halo:</label>
|
33
|
+
<InputRow id="halo" label="Halo">
|
38
34
|
<input id="halo" type="range" min="0" max="3" step="0.5" bind:value={$halo} />
|
39
|
-
</
|
35
|
+
</InputRow>
|
40
36
|
|
41
|
-
<
|
42
|
-
<label for="label">Label:</label>
|
37
|
+
<InputRow id="label" label="Label">
|
43
38
|
<input id="label" type="label" bind:value={$label} />
|
44
|
-
</
|
39
|
+
</InputRow>
|
45
40
|
|
46
|
-
<
|
47
|
-
<label for="labelAlign">Align Label:</label>
|
41
|
+
<InputRow id="labelAlign" label="Align Label">
|
48
42
|
<select id="labelAlign" bind:value={$labelAlign}>
|
49
43
|
{#each labelPositions as { index, name } (index)}
|
50
44
|
<option value={index}>{name}</option>
|
51
45
|
{/each}
|
52
46
|
</select>
|
53
|
-
</
|
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;
|
@@ -1,9 +1,13 @@
|
|
1
1
|
<script lang="ts">
|
2
2
|
import Editor from './Editor.svelte';
|
3
3
|
import type { GeometryManager } from '../lib/geometry_manager.js';
|
4
|
+
import SidebarPanel from './SidebarPanel.svelte';
|
4
5
|
|
5
6
|
const { geometryManager, width }: { geometryManager: GeometryManager; width: number } = $props();
|
6
7
|
|
8
|
+
let history = geometryManager.state;
|
9
|
+
let undoEnabled = $state(geometryManager.state.undoEnabled);
|
10
|
+
let redoEnabled = $state(geometryManager.state.redoEnabled);
|
7
11
|
let activeElement = geometryManager.selectedElement;
|
8
12
|
|
9
13
|
function importGeoJSON() {
|
@@ -41,137 +45,140 @@
|
|
41
45
|
a.click();
|
42
46
|
URL.revokeObjectURL(url);
|
43
47
|
}
|
48
|
+
|
49
|
+
function getLink() {
|
50
|
+
const url = new URL(window.location.href);
|
51
|
+
url.hash = geometryManager.state.getHash();
|
52
|
+
return url.href;
|
53
|
+
}
|
54
|
+
|
55
|
+
function copyLink() {
|
56
|
+
navigator.clipboard.writeText(getLink()).then(
|
57
|
+
() => alert('Link copied to clipboard!'),
|
58
|
+
() => alert('Failed to copy link. Please try again.')
|
59
|
+
);
|
60
|
+
}
|
61
|
+
|
62
|
+
function copyEmbedCode() {
|
63
|
+
const html = `<iframe style="width:100%; height:60vh" src="${getLink()}"></iframe>`;
|
64
|
+
navigator.clipboard.writeText(html).then(
|
65
|
+
() => alert('Embed code copied to clipboard!'),
|
66
|
+
() => alert('Failed to copy embed code. Please try again.')
|
67
|
+
);
|
68
|
+
}
|
44
69
|
</script>
|
45
70
|
|
46
|
-
<div class="sidebar" style="
|
47
|
-
<div style="
|
48
|
-
<div class="
|
49
|
-
|
50
|
-
<
|
51
|
-
<input type="button" value="Export" onclick={exportGeoJSON} />
|
52
|
-
</div>
|
53
|
-
<hr />
|
54
|
-
<div class="label">Add new:</div>
|
55
|
-
<div class="row-flex">
|
56
|
-
<input
|
57
|
-
type="button"
|
58
|
-
value="Marker"
|
59
|
-
onclick={() => activeElement.set(geometryManager.addNewMarker())}
|
60
|
-
/>
|
61
|
-
<input
|
62
|
-
type="button"
|
63
|
-
value="Line"
|
64
|
-
onclick={() => activeElement.set(geometryManager.addNewLine())}
|
65
|
-
/>
|
66
|
-
<input
|
67
|
-
type="button"
|
68
|
-
value="Polygon"
|
69
|
-
onclick={() => activeElement.set(geometryManager.addNewPolygon())}
|
70
|
-
/>
|
71
|
+
<div class="sidebar" style="width: {width}px;">
|
72
|
+
<div style="margin-bottom: 36px;">
|
73
|
+
<div class="flex flex-two">
|
74
|
+
<button onclick={() => history.undo()} disabled={!$undoEnabled}>Undo</button>
|
75
|
+
<button onclick={() => history.redo()} disabled={!$redoEnabled}>Redo</button>
|
71
76
|
</div>
|
72
|
-
|
73
|
-
<
|
74
|
-
|
75
|
-
<
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
<SidebarPanel title="Share map" open={false}>
|
78
|
+
<div class="flex flex-one">
|
79
|
+
<button value="Link" onclick={copyLink}>Link</button>
|
80
|
+
<button onclick={copyEmbedCode}>Embed Code</button>
|
81
|
+
</div>
|
82
|
+
</SidebarPanel>
|
83
|
+
<SidebarPanel title="Import/Export" open={false}>
|
84
|
+
<div class="flex flex-one">
|
85
|
+
<button onclick={importGeoJSON}>Import GeoJSON</button>
|
86
|
+
<button onclick={exportGeoJSON}>Export GeoJSON</button>
|
87
|
+
</div>
|
88
|
+
</SidebarPanel>
|
89
|
+
<SidebarPanel title="Add new">
|
90
|
+
<div class="flex flex-two">
|
91
|
+
<button onclick={() => activeElement.set(geometryManager.addNewMarker())}>Marker</button>
|
92
|
+
<button onclick={() => activeElement.set(geometryManager.addNewLine())}>Line</button>
|
93
|
+
<button onclick={() => activeElement.set(geometryManager.addNewPolygon())}>Polygon</button>
|
94
|
+
<button disabled>Circle</button>
|
95
|
+
</div>
|
96
|
+
</SidebarPanel>
|
97
|
+
<Editor element={$activeElement} />
|
98
|
+
<SidebarPanel title="Actions" disabled={!$activeElement}>
|
99
|
+
<div class="flex flex-two">
|
100
|
+
<button onclick={() => $activeElement!.delete()}>Delete</button>
|
101
|
+
</div>
|
102
|
+
</SidebarPanel>
|
103
|
+
<SidebarPanel title="Help">
|
104
|
+
<a
|
105
|
+
id="github_link"
|
106
|
+
href="https://github.com/versatiles-org/node-versatiles-svelte/issues"
|
107
|
+
target="_blank"
|
108
|
+
aria-label="Repository on GitHub">Report Bugs and Feature Requests as GitHub Issues</a
|
109
|
+
>
|
110
|
+
</SidebarPanel>
|
83
111
|
</div>
|
84
112
|
</div>
|
85
113
|
|
86
114
|
<style>
|
87
115
|
.sidebar {
|
88
|
-
|
116
|
+
--color-btn: #336680;
|
117
|
+
--color-bg: #ffffff;
|
118
|
+
--color-text: #000000;
|
119
|
+
--gap: 10px;
|
120
|
+
|
121
|
+
background-color: rgb(from var(--color-bg) r g b/ 0.7);
|
122
|
+
backdrop-filter: blur(10px);
|
123
|
+
box-sizing: border-box;
|
124
|
+
color: var(--color-text);
|
125
|
+
font-size: 0.8em;
|
89
126
|
height: 100%;
|
127
|
+
overflow-y: scroll;
|
128
|
+
padding: var(--gap);
|
90
129
|
position: absolute;
|
91
|
-
top: 0;
|
92
130
|
right: 0;
|
93
|
-
|
94
|
-
|
95
|
-
box-sizing: border-box;
|
96
|
-
padding: 0.5em var(--gap) 0;
|
97
|
-
border-left: 0.5px solid rgba(0, 0, 0, 0.5);
|
98
|
-
|
99
|
-
hr {
|
100
|
-
border: none;
|
101
|
-
border-top: 0.5px solid rgba(0, 0, 0, 1);
|
102
|
-
margin: var(--gap) 0 var(--gap);
|
103
|
-
}
|
104
|
-
|
105
|
-
:global(h2) {
|
106
|
-
font-size: 0.9em;
|
107
|
-
font-weight: normal;
|
108
|
-
opacity: 0.5;
|
109
|
-
padding-top: var(--gap);
|
110
|
-
border-top: 0.5px solid rgba(0, 0, 0, 1);
|
111
|
-
margin: var(--gap) 0 var(--gap);
|
112
|
-
text-align: center;
|
113
|
-
}
|
131
|
+
top: 0;
|
132
|
+
width: 200px;
|
114
133
|
|
115
|
-
|
116
|
-
|
134
|
+
.flex {
|
135
|
+
--gap: 5px;
|
136
|
+
align-items: center;
|
117
137
|
display: flex;
|
138
|
+
flex-wrap: wrap;
|
139
|
+
gap: var(--gap);
|
118
140
|
justify-content: space-between;
|
119
|
-
column-gap: var(--gap);
|
120
|
-
:global(input) {
|
121
|
-
flex-grow: 0;
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
:global(.row-input) {
|
126
141
|
margin: var(--gap) 0 var(--gap);
|
127
|
-
|
128
|
-
justify-content: space-between;
|
129
|
-
align-items: center;
|
130
|
-
& > :global(label) {
|
131
|
-
flex-grow: 0;
|
132
|
-
}
|
133
|
-
& > :global(button),
|
134
|
-
& > :global(input),
|
135
|
-
& > :global(select) {
|
136
|
-
width: 60%;
|
137
|
-
flex-grow: 0;
|
138
|
-
}
|
139
|
-
& > :global(input[type='checkbox']) {
|
140
|
-
width: auto;
|
141
|
-
}
|
142
|
+
width: 100%;
|
142
143
|
}
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
font-size: 0.8em;
|
144
|
+
.flex-two button {
|
145
|
+
flex-grow: 1;
|
146
|
+
flex-basis: 0;
|
147
|
+
width: 40%;
|
148
148
|
}
|
149
149
|
|
150
|
-
|
151
|
-
:global(input),
|
152
|
-
:global(select) {
|
150
|
+
.flex-one button {
|
153
151
|
width: 100%;
|
154
|
-
box-sizing: border-box;
|
155
|
-
margin: 0;
|
156
152
|
}
|
157
153
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
154
|
+
button {
|
155
|
+
background-color: var(--color-btn);
|
156
|
+
border: 2px solid var(--color-btn);
|
157
|
+
border-radius: 0.2em;
|
158
|
+
color: var(--color-bg);
|
159
|
+
cursor: pointer;
|
160
|
+
font-weight: 600;
|
161
|
+
padding: 0.4em 1em;
|
162
|
+
transition:
|
163
|
+
background-color 0.1s ease-in-out,
|
164
|
+
color 0.1s ease-in-out;
|
165
|
+
|
166
|
+
&:not([disabled]):hover {
|
167
|
+
background-color: var(--color-bg);
|
168
|
+
color: var(--color-btn);
|
169
|
+
}
|
170
|
+
&:disabled {
|
171
|
+
cursor: not-allowed;
|
172
|
+
opacity: 0.5;
|
173
|
+
}
|
162
174
|
}
|
175
|
+
}
|
163
176
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
text-decoration: none;
|
170
|
-
opacity: 0.3;
|
171
|
-
&:hover {
|
172
|
-
opacity: 1;
|
173
|
-
}
|
174
|
-
}
|
177
|
+
a {
|
178
|
+
text-decoration: none;
|
179
|
+
color: var(--fg-color);
|
180
|
+
&:hover {
|
181
|
+
text-decoration: underline;
|
175
182
|
}
|
176
183
|
}
|
177
184
|
</style>
|