Skip to content

Commit 0479f98

Browse files
authored
Merge pull request #3 from terrestris/upgrade-svelte
chore: upgrade libs and imporve typings
2 parents 5d165e3 + 86173f8 commit 0479f98

15 files changed

+129
-117
lines changed

bun.lockb

-2 KB
Binary file not shown.

package.json

+26-23
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
11
{
22
"name": "svelte-app",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"dev": "vite",
87
"build": "vite build",
9-
"preview": "vite preview",
10-
"check": "svelte-check --tsconfig ./tsconfig.json"
8+
"check": "svelte-check --tsconfig ./tsconfig.json",
9+
"dev": "vite",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@terrestris/ol-util": "^20.0",
14+
"echarts": "^5.5.1",
15+
"marked": "^14.1.3",
16+
"ol": "^10",
17+
"sass": "^1.80.3",
18+
"sirv-cli": "^3.0.0",
19+
"vite": "^5.4.9",
20+
"yaml": "^2.6.0"
1121
},
1222
"devDependencies": {
13-
"@sveltejs/vite-plugin-svelte": "^2.4.5",
14-
"@tsconfig/svelte": "^3.0.0",
15-
"d3-array": "latest",
16-
"d3-scale": "latest",
17-
"svelte": "^3.55.0",
18-
"svelte-check": "^3.0.0",
19-
"svelte-preprocess": "^5.1.3",
20-
"tslib": "^2.5.0",
21-
"typescript": "^4.9.0"
23+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
24+
"@tsconfig/svelte": "^5.0.4",
25+
"d3-array": "^3.2.4",
26+
"d3-scale": "^4.0.2",
27+
"svelte": "^5.0.3",
28+
"svelte-check": "^4.0.5",
29+
"svelte-preprocess": "^6.0.3",
30+
"tslib": "^2.8.0",
31+
"typescript": "^5.6.3"
2232
},
23-
"dependencies": {
24-
"@terrestris/ol-util": "^12.0.1",
25-
"echarts": "^5.5.0",
26-
"marked": "^12.0.1",
27-
"ol": "^7",
28-
"sass": "^1.72.0",
29-
"sirv-cli": "^2.0.0",
30-
"vite": "^4.4.9",
31-
"yaml": "^2.3.2"
32-
}
33+
"trustedDependencies": [
34+
"svelte-preprocess"
35+
]
3336
}

src/App.svelte

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<script lang="ts">
2-
import { parse as parseYaml } from "yaml";
3-
import Scrolly from "./components/Scrolly.svelte";
4-
import Map from "./components/Map.svelte";
52
import Chart from "./components/Chart.svelte";
6-
import { step } from "./store/step";
7-
import { marked } from "marked";
83
import Header from "./components/Header.svelte";
9-
4+
import Map from "./components/Map.svelte";
5+
import Scrolly from "./components/Scrolly.svelte";
106
import type { Config } from "./types";
11-
7+
import { marked } from "marked";
8+
import { parse as parseYaml } from "yaml";
9+
import { step } from "./store/step";
1210
1311
/* By Connor Rothschild https://twitter.com/CL_Rothschild
1412
Scrollytelling component from Russell Goldenberg https://twitter.com/codenberg/status/1432774653139984387
@@ -20,14 +18,18 @@
2018
const path = url.searchParams.get("config");
2119
if (!path) {
2220
console.error("No config path defined.");
21+
return;
2322
}
2423
return path;
2524
};
2625
const path = getConfig();
27-
const promise = fetch(path)
28-
.then((response) => response.text())
29-
.then((text) => parseYaml(text) as Config)
30-
// TODO error handling
26+
let promise: any;
27+
if (path) {
28+
promise = fetch(path)
29+
.then((response) => response.text())
30+
.then((text) => parseYaml(text) as Config)
31+
// TODO error handling
32+
}
3133
3234
const basePath = location.origin + location.pathname;
3335
</script>
@@ -64,7 +66,7 @@
6466
<span class="attribution">{@html s.attribution}</span>
6567
{/if}
6668
</div>
67-
<p />
69+
<p></p>
6870
</div>
6971
{/each}
7072
<!-- <div class="spacer" /> -->

src/components/Chart.svelte

+22-9
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@
2121
CanvasRenderer,
2222
]);
2323
24-
export let config;
24+
// Define type for the config prop
25+
interface Config {
26+
title: string;
27+
xAxisData: Array<any>; // Define a more specific type if you know the structure
28+
series: Array<any>; // Define a more specific type if you know the structure
29+
}
30+
31+
export let config: Config;
2532
26-
let option;
33+
// TODO use echart types here
34+
let option: any = { ...echartOption }; // Use EChartsOption to type the option
2735
28-
let chartId: string;
36+
let chartId: string = "";
2937
3038
$: {
3139
if (config) {
@@ -36,29 +44,34 @@
3644
const setupChart = (node: HTMLElement) => {
3745
if (config) {
3846
// create chart config
39-
option = echartOption;
40-
option.title.text = config.title;
47+
option = { ...echartOption }; // Ensure a new instance is created
48+
option.title = { text: config.title }; // Ensure the title is typed correctly
49+
option.xAxis = []; // Ensure the xAxis is reset before pushing data
50+
4151
config.xAxisData.forEach(data => {
42-
option.xAxis.push(data);
52+
option.xAxis?.push(data);
4353
});
54+
55+
option.series = []; // Reset the series before adding data
4456
config.series.forEach((serie) => {
45-
option.series.push({
57+
option.series?.push({
4658
...serie,
4759
type: "bar",
4860
emphasis: {
4961
focus: "series",
5062
},
5163
});
5264
});
65+
5366
// init chart
5467
const echart = echarts.init(node);
5568
// apply chart option
5669
echart && option && echart.setOption(option);
5770
}
58-
}
71+
};
5972
</script>
6073

61-
<div id={chartId} class="chart" use:setupChart >chart</div>
74+
<div id={chartId} class="chart" use:setupChart>chart</div>
6275

6376
<style>
6477
.chart {

src/components/Map.svelte

+17-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// OpenLayers
55
import Map from "ol/Map";
66
import View from "ol/View";
7+
import Layer from "ol/layer/Layer";
78
// Utils
89
import { initTopicLayer, updateTopicLayer } from "../util/topicLayer";
910
import {
@@ -21,15 +22,15 @@
2122
export let steps: StepConfigList;
2223
2324
// Local state
24-
let map = null;
25-
let baseLayer;
26-
let topicLayer;
27-
let highlightLayer;
28-
let dataLayer;
25+
let map: Map | null = null;
26+
let baseLayer: Layer | undefined;
27+
let topicLayer: Layer | undefined;
28+
let highlightLayer: Layer | undefined;
29+
let dataLayer: Layer | undefined;
2930
3031
// Functions
3132
const setupMap = (node: HTMLElement) => {
32-
baseLayer = getBaseLayerByName("osm");
33+
baseLayer = getBaseLayerByName("osm") as Layer;
3334
map = new Map({
3435
controls: [
3536
new Attribution({
@@ -47,7 +48,7 @@
4748
return {
4849
destroy() {
4950
if (map) {
50-
map.setTarget(null);
51+
map.setTarget(undefined);
5152
map = null;
5253
}
5354
},
@@ -74,6 +75,7 @@
7475
}
7576
}
7677
}
78+
7779
// apply and render step config
7880
step.subscribe((stepValue) => {
7981
if (stepValue >= 0 && map && steps) {
@@ -84,33 +86,33 @@
8486
// apply baselayer
8587
if (
8688
currentConfig.baseLayer &&
87-
currentConfig.baseLayer !== baseLayer.get("name")
89+
currentConfig.baseLayer !== baseLayer?.get("name")
8890
) {
8991
const newSource = getBaseLayerByName(
90-
currentConfig.baseLayer,
92+
currentConfig.baseLayer as string,
9193
)?.getSource();
9294
const mapLayer = map
9395
.getAllLayers()
94-
.filter((l) => l.get("id") === "baseLayer")[0];
96+
.filter((l) => l.get("id") === "baseLayer")[0] as Layer;
9597
mapLayer?.setSource(newSource);
9698
mapLayer.set("name", currentConfig.baseLayer);
9799
}
98100
// apply topicLayer
99-
if (currentConfig.topicLayer) {
101+
if (currentConfig.topicLayer && topicLayer) {
100102
updateTopicLayer(currentConfig.topicLayer, topicLayer);
101103
topicLayer.setVisible(true);
102-
} else {
104+
} else if (topicLayer) {
103105
topicLayer.setVisible(false);
104106
}
105107
// apply dataLayer
106-
if (currentConfig.dataLayer) {
108+
if (currentConfig.dataLayer && dataLayer) {
107109
updateDataLayer(currentConfig, dataLayer);
108110
dataLayer.setVisible(true);
109111
} else if (dataLayer) {
110112
dataLayer.setVisible(false);
111113
}
112114
// apply highlighting
113-
if (currentConfig.highlight) {
115+
if (currentConfig.highlight && highlightLayer) {
114116
updateHighlightLayer(currentConfig.highlight, highlightLayer);
115117
highlightLayer.setVisible(true);
116118
} else if (highlightLayer) {
@@ -122,7 +124,7 @@
122124
});
123125
</script>
124126

125-
<div id={mapId} class="map" use:setupMap />
127+
<div id={mapId} class="map" use:setupMap> </div>
126128

127129
<style>
128130
.map {

src/components/Scrolly.svelte

+30-39
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,31 @@
1-
<script>
2-
/**
3-
Scrollytelling component from Russell Goldenberg
4-
https://svelte.dev/repl/3d3736e634c9404ea8ec2ef7b87e2053?version=3.42.4
5-
6-
* This component manages which item is most in view for scroll triggering
7-
* example:
8-
* <Scroll
9-
* bind:value={scrollIndex}
10-
* >
11-
* **items here**
12-
* </Scroll>
13-
*
14-
* optional params with defaults
15-
* <Scroll root={null} top={0} bottom={0} increments={100}>
16-
*/
1+
<script lang="ts">
172
import { onMount } from "svelte";
18-
export let root = null;
19-
export let top = 0;
20-
export let bottom = 0;
21-
export let increments = 100;
22-
export let value = 0;
3+
4+
// Define prop types
5+
export let root: HTMLElement | null = null;
6+
export let top: number = 0;
7+
export let bottom: number = 0;
8+
export let increments: number = 100;
9+
export let value: number = 0;
2310
24-
const steps = [];
25-
const threshold = [];
26-
27-
let nodes = [];
28-
let intersectionObservers = [];
29-
let container;
11+
// Local variables with specific types
12+
const steps: number[] = [];
13+
const threshold: number[] = [];
14+
let nodes: NodeListOf<HTMLElement> = document.querySelectorAll('.dummySelector'); // Initialize with an empty NodeList
15+
let intersectionObservers: IntersectionObserver[] = [];
16+
let container!: HTMLElement; // "!" asserts that container will be initialized later
3017
18+
// Watch for changes in 'top' or 'bottom' and trigger update
3119
$: top, bottom, update();
3220
33-
const update = () => {
21+
// Update function to create observers for each node
22+
const update = (): void => {
3423
if (!nodes.length) return;
35-
nodes.forEach(createObserver);
24+
nodes.forEach((node, index) => createObserver(node, index));
3625
};
3726
38-
const mostInView = () => {
27+
// Function to determine which item is most in view
28+
const mostInView = (): void => {
3929
let maxRatio = 0;
4030
let maxIndex = 0;
4131
for (let i = 0; i < steps.length; i++) {
@@ -45,22 +35,21 @@
4535
}
4636
}
4737
48-
if (maxRatio > 0) value = maxIndex;
49-
else value = 0;
38+
value = maxRatio > 0 ? maxIndex : 0;
5039
};
5140
52-
const createObserver = (node, index) => {
53-
const handleIntersect = (e) => {
54-
const intersecting = e[0].isIntersecting;
55-
const ratio = e[0].intersectionRatio;
41+
// Function to create an observer for a node
42+
const createObserver = (node: HTMLElement, index: number): void => {
43+
const handleIntersect = (entries: IntersectionObserverEntry[]): void => {
44+
const ratio = entries[0].intersectionRatio;
5645
steps[index] = ratio;
5746
mostInView();
5847
};
5948
6049
const marginTop = top ? top * -1 : 0;
6150
const marginBottom = bottom ? bottom * -1 : 0;
6251
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
63-
const options = { root, rootMargin, threshold };
52+
const options: IntersectionObserverInit = { root, rootMargin, threshold };
6453
6554
if (intersectionObservers[index]) intersectionObservers[index].disconnect();
6655
@@ -69,11 +58,13 @@
6958
intersectionObservers[index] = io;
7059
};
7160
72-
onMount(() => {
61+
// onMount to set up the component after it mounts
62+
onMount((): void => {
7363
for (let i = 0; i < increments + 1; i++) {
7464
threshold.push(i / increments);
7565
}
76-
nodes = container.querySelectorAll(":scope > *");
66+
// Query all child elements
67+
nodes = container.querySelectorAll(":scope > *") as NodeListOf<HTMLElement>;
7768
update();
7869
});
7970
</script>

src/global.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
/// <reference types="svelte" />
1+
/// <reference types="svelte" />

src/index.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
declare module 'configParser';
2-

src/main.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { mount } from 'svelte';
2+
13
import App from './App.svelte';
24

3-
var app = new App({
4-
target: document.body
5-
});
5+
const app = mount(App, { target: document.body });
66

7-
export default app;
7+
export default app;

0 commit comments

Comments
 (0)