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
28 changes: 16 additions & 12 deletions components/src/ChartList/ChartList.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ import * as ChartListStories from './ChartList.stories.svelte';

**Development-only** utility component for displaying a list of charts with associated embed, typically at the `/` route of your Svelte project.

- `charts` is a list of `ChartSpec` objects of the following shape:

```ts
interface ChartSpec {
title: string;
slug: string;
}
```

- `project` is a string of the shape `<Project Number>: <Project Title>`.

## Usage

In your `+page.svelte`:
Expand All @@ -41,6 +30,21 @@ In your `+page.svelte`:
</DesignTokens>
```

<Stories />
### Props

- `charts` is a list of `ChartSpec` objects of the following shape:

```ts
interface ChartSpec {
title: string;
slug: string;
group?: string;
}
```

- `project` is a string of the shape `<Project Number>: <Project Title>`.
- `group` is an optional group name (useful for grouping charts by bundesland)

<Story of={ChartListStories.GroupedCharts} />

<Controls />
15 changes: 15 additions & 0 deletions components/src/ChartList/ChartList.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@
</DesignTokens>
</Story>

<Story name="Grouped charts" asChild>
<DesignTokens>
<ChartList
baseUrl="https://static.datenhub.net/apps/p110_wald-klimawandel/main"
charts={[
{ group: 'BW', title: 'Baden-Württemberg Loosers', slug: 'bw-loosers' },
{ group: 'BW', title: 'Baden-Württemberg Winners', slug: 'bw-winners' },
{ group: 'RP', title: 'Rheinland-Pfalz Loosers', slug: 'rp-loosers' },
{ title: 'Rheinland-Pfalz Winners', slug: 'rp-winners' }
]}
project="p110: Wie sieht der Wald von morgen aus?"
/>
</DesignTokens>
</Story>

<Story
name="Default base path (omitting basePath)"
asChild
Expand Down
85 changes: 35 additions & 50 deletions components/src/ChartList/ChartList.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
<script lang="ts">
import { dev } from '$app/environment';
import Row from './Row.svelte';

type ProjectPrefix = 'p' | 't';
type ProjectIdentifier = `${ProjectPrefix}${number}: ${string}`;

interface ChartSpec {
title: string;
slug: string;
group?: string;
}
interface ChartListProps {
project?: ProjectIdentifier;
charts?: ChartSpec[];
baseUrl?: string;
}
let { project, charts, baseUrl }: ChartListProps = $props();
let { project, charts = [], baseUrl }: ChartListProps = $props();

const groups: string[] = $derived(
Array.from(new Set(charts.map((c) => c.group).filter((c) => typeof c === 'string')))
);

const groupedCharts = $derived.by(() => {
let res: { [key: string]: ChartSpec[] } = {};
groups.forEach((g) => (res[g] = charts.filter((el) => el.group === g)));
return res;
});

const ungroupedCharts = $derived(charts.filter((el) => !el.group));
</script>

<main>
Expand All @@ -23,23 +37,27 @@
<table>
<thead>
<tr>
{#if groups.length > 0}
<th>Group</th>
{/if}
<th>Title</th>
<th>Embed URL</th>
</tr>
</thead>
<tbody>
{#each charts as chart}
{@const route = `/${chart.slug}`}
<tr>
<td>
<a rel="external" href={dev ? route : `./${chart.slug}.html`}>
{chart.title}
</a>
</td>
<td>
<input type="text" value={`${baseUrl ?? ''}${route}.html`} />
</td>
</tr>
{#each Object.values(groupedCharts) as charts}
{#each charts as chart, i}
<Row {chart} group={i === 0} rowspan={groupedCharts[chart.group].length} {baseUrl}
></Row>
{/each}
{/each}
{#each ungroupedCharts as chart, i}
<Row
{chart}
{baseUrl}
group={groups.length > 0 && i === 0}
rowspan={ungroupedCharts.length === 1 ? 1 : 0}
></Row>
{/each}
</tbody>
</table>
Expand Down Expand Up @@ -81,55 +99,22 @@
}
}
table {
border: 1px solid var(--color-surfaceBorder);
border-collapse: collapse;
border-spacing: 0;
width: 100%;
border: 1px solid var(--color-surfaceBorder);
}
a {
display: block;
color: inherit;
text-decoration: none;
}
th,
td {
padding: 0 0.4em;
text-align: left;
border-right: 1px solid var(--color-surfaceBorder);
&:last-child {
border-right: 0;
}
}

th {
text-align: left;
padding: 0.2em 0.4em;
border-right: 1px solid var(--color-textSecondary);
border-bottom: 1px solid var(--color-textSecondary);
}
tr {
border-bottom: 1px solid var(--color-surfaceBorder);
&:last-child {
border-bottom: 0;
border-right: 0;
}
}

input {
display: block;
font-family: monospace;
width: 100%;
padding: 0.35em 0;
font-size: 0.9rem;
background: var(--color-pageFill);
color: var(--color-textSecondary);
border: 0;
}

a:hover,
a:focus-visible {
text-decoration: underline;
}
a:last-child {
border-bottom: 0;
}
.notes {
margin-top: 0.5em;
color: var(--color-textSecondary);
Expand Down
64 changes: 64 additions & 0 deletions components/src/ChartList/Row.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script>
import { dev } from '$app/environment';
const { chart, group = false, rowspan = 0, baseUrl } = $props();

const route = $derived(`/${chart.slug}`);
</script>

<tr>
{#if group}
<td {rowspan}>{chart.group}</td>
{/if}
<td>
<a rel="external" href={dev ? route : `./${chart.slug}.html`}>
{chart.title}
</a>
</td>
<td>
<input type="text" value={`${baseUrl ?? ''}${route}.html`} />
</td>
</tr>

<style>
td {
padding: 0.15em 0.4em;
padding-bottom: 0;
line-height: 1.5;
text-align: left;
vertical-align: top;
border-right: 1px solid var(--color-surfaceBorder);
&:last-child {
border-right: 0;
}
}
tr {
border-bottom: 1px solid var(--color-surfaceBorder);
&:last-child {
border-bottom: 0;
}
}
a {
display: block;
color: inherit;
text-decoration: none;
}

input {
display: block;
font-family: monospace;
width: 100%;
padding: 0.35em 0;
font-size: 0.9rem;
background: var(--color-pageFill);
color: var(--color-textSecondary);
border: 0;
}

a:hover,
a:focus-visible {
text-decoration: underline;
}
a:last-child {
border-bottom: 0;
}
</style>