Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy-map-icon-sprite.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Build and deploy map icons'
name: 'deploy map icons'
on:
workflow_dispatch:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-sophora-components.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Deploy sophora-components'
name: 'deploy sophora-components'
on:
workflow_dispatch:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-storybook.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Deploy Storybook'
name: 'deploy storybook'
on:
workflow_dispatch:
push:
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: e2e tests
on:
workflow_dispatch:
push:
paths:
- 'components/**'
- 'mock-sveltekit/**'
branches:
- main
pull_request:
paths:
- 'components/**'
- 'mock-sveltekit/**'
types: [opened, synchronize]

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: lts/*
- run: npm ci --workspace=components --include=dev
- run: npm run sync --workspace=components
- run: npm ci --workspace=mock-sveltekit
- run: npm run sync --workspace=mock-sveltekit
- run: npm run build --workspace=mock-sveltekit
- run: npx playwright install --with-deps chromium
- run: cd mock-sveltekit && npx playwright test
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Release to NPM
name: release

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-storybook.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Run Storybook Tests'
name: component tests
on:
workflow_dispatch:
push:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ Svelte/kit component library for [SWR Data Lab](https://www.swr.de/home/swr-data

### Project structure

1. `/components`: Central repository for reusable components, utility scripts, and other reusable assets. We use [Storybook](https://storybook.js.org/) for previewing and component-level testing.
2. `/mock-sveltekit`: Sample [SvelteKit](https://kit.svelte.dev/) application used to test our components and develop the configuration needed to build our applications for SWR.de, the SWR Aktuell native app and wherever else they need to go.
1. `/components`: Central repository for components, utility scripts, and other reusable assets. We use [Storybook](https://storybook.js.org/) for previewing and component testing.
2. `/mock-sveltekit`: Sample [SvelteKit](https://kit.svelte.dev/) application for e2e testing and developing the configuration needed to deploy our apps to SWR.de and the SWR Aktuell native app.
3. `/mock-sophora`: Testing environment designed to mimic the SWR.de environment, featuring [`defunkt/jquery-pjax`](https://github.com/defunkt/jquery-pjax) navigation, global styles and server-side includes.
4. `/sophora-components`: Experimental components that are intended to be used directly within SWR.de articles and pages via the "Datenjournalismus" module in the Sophora CMS.

### Release workflow

- We use [semantic-release](https://github.com/semantic-release/) to create releases and publish to the [NPM registry](https://www.npmjs.com/package/@swr-data-lab/components) on commit to `main`.
- We use [semantic-release](https://github.com/semantic-release/) to create releases and publish to [npm](https://www.npmjs.com/package/@swr-data-lab/components) on commit to `main`.
- Only [conventional commits](https://www.conventionalcommits.org/) trigger new releases. Prefix your commit message with `fix: ` for a patch, `feat: ` for a minor and `!: ` for a major version bump. See also [semantic-release docs](https://semantic-release.gitbook.io/semantic-release/support/faq).
14 changes: 7 additions & 7 deletions components/src/maplibre/Maplibre.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ This example initialises a map using the SWRDataLabLight style, adds an addition
<VectorTileSource
id='ev-infra-source'
url='https://static.datenhub.net/data/p108_e_auto_check/ev_infra_merged.versatiles?{z}/{x}/{y}'>
<VectorLayer
sourceId='ev-infra-source'
sourceLayer='coverage'
id='ev-infra-outline'
type='line'
paint={{'line-width': 1, 'line-color': 'red'}}>
</VectorLayer>
</VectorTileSource>
<VectorLayer
sourceId='ev-infra-source'
sourceLayer='coverage'
id='ev-infra-outline'
type='line'
paint={{'line-width': 1, 'line-color': 'red'}}>
</VectorLayer>
<AttributionControl />
</Map>
</div>
Expand Down
51 changes: 16 additions & 35 deletions components/src/maplibre/Source/MapSource.svelte
Original file line number Diff line number Diff line change
@@ -1,70 +1,51 @@
<script lang="ts">
import { onDestroy, type Snippet } from 'svelte';
import { onDestroy, onMount, type Snippet } from 'svelte';
import { type Map, type SourceSpecification } from 'maplibre-gl';
import { getMapContext, createSourceContext, SourceContext } from '../context.svelte.js';

type Source = maplibregl.VectorTileSource | maplibregl.GeoJSONSource;
import { getMapContext } from '../context.svelte.js';

interface MapSourceProps {
id: string;
source?: maplibregl.VectorTileSource | maplibregl.GeoJSONSource;
sourceSpec: SourceSpecification;
source?: Source;
onLoad?: (map: Map, url?: string, data?: string) => undefined;
children?: Snippet;
}

let { id, sourceSpec, source = $bindable(), children }: MapSourceProps = $props();

const ctx = getMapContext();
let firstRun = $state(true);

// Get map context
const { map, styleLoaded } = $derived(getMapContext());

// Create source context
const sourceContext = createSourceContext();

// 1. Add the source to the map using the spec, then get the
// actual source object back from the map instance
$effect(() => {
if (map && styleLoaded && firstRun) {
map.addSource(id, $state.snapshot(sourceSpec));
source = map.getSource(id);
firstRun = false;
}
ctx.waitForStyleLoaded(() => {
ctx.addSource(id, sourceSpec);
});
firstRun = false;
});

$effect(() => {
if (source && sourceSpec.type === 'geojson') {
if (firstRun === false) {
source.setData(sourceSpec.data);
}
if (!firstRun && source && source.type === 'geojson') {
source.setData(sourceSpec.data);
}
});

$effect(() => {
if (!firstRun && source.setTiles) {
if (!firstRun && source && source.type === 'vector') {
source.setTiles(sourceSpec.tiles);
}
});

$effect(() => {
if (!firstRun && source.setUrl) {
if (!firstRun && source) {
source.setUrl(sourceSpec.url);
}
});

onDestroy(() => {
if (map && styleLoaded) {
const layers = map?.getStyle().layers;
layers
.filter((l) => l.type !== 'background' && l.source == id)
.forEach((l) => {
map?.removeLayer(l.id);
});
map.removeSource(id);
source = undefined;
}
ctx.removeSource(id);
});
</script>

{@render children?.()}
{#if !firstRun}
{@render children?.()}
{/if}
89 changes: 49 additions & 40 deletions components/src/maplibre/Tooltip/Tooltip.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,46 +36,55 @@
tiles={[
`https://static.datenhub.net/data/p108_e_auto_check/ev_infra_merged.versatiles?{z}/{x}/{y}`
]}
/>
<VectorLayer
sourceId="ev-infra-source"
type="fill"
id="coverage-fill"
sourceLayer="coverage"
onmousemove={(e) => {
hovered = e.features?.[0];
hoverCoords = e.lngLat;
}}
onmouseleave={() => (hovered = undefined)}
paint={{
'fill-color': ['step', ['get', 'coverage_2025'], 'white', 1, '#ffcfcc', 1.3, '#FF4D20']
}}
/>
<VectorLayer
{hovered}
sourceId="ev-infra-source"
sourceLayer="coverage"
id="ev-infra-outline"
type="line"
layout={{
'line-join': 'round'
}}
paint={{
'line-width': [
'case',
['any', ['boolean', ['feature-state', 'hovered'], false]],
1.5,
0.5
],
'line-color': [
'case',
['any', ['boolean', ['feature-state', 'hovered'], false]],
'#000',
'#555'
],
'line-opacity': 1
}}
/>
>
<VectorLayer
sourceId="ev-infra-source"
type="fill"
id="coverage-fill"
sourceLayer="coverage"
onmousemove={(e) => {
hovered = e.features?.[0];
hoverCoords = e.lngLat;
}}
onmouseleave={() => (hovered = undefined)}
paint={{
'fill-color': [
'step',
['get', 'coverage_2025'],
'white',
1,
'#ffcfcc',
1.3,
'#FF4D20'
]
}}
/>
<VectorLayer
{hovered}
sourceId="ev-infra-source"
sourceLayer="coverage"
id="ev-infra-outline"
type="line"
layout={{
'line-join': 'round'
}}
paint={{
'line-width': [
'case',
['any', ['boolean', ['feature-state', 'hovered'], false]],
1.5,
0.5
],
'line-color': [
'case',
['any', ['boolean', ['feature-state', 'hovered'], false]],
'#000',
'#555'
],
'line-opacity': 1
}}
/>
</VectorTileSource>

{#if hovered}
<Tooltip
Expand Down
Loading
Loading