Skip to content

Commit 86cc34a

Browse files
authored
Merge pull request #69 from communitiesuk/table-gds-styling
Table gds styling
2 parents a61dce7 + 8c8a1e7 commit 86cc34a

File tree

9 files changed

+210
-144
lines changed

9 files changed

+210
-144
lines changed

src/app.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/>
1313
<meta name="theme-color" content="#0b0c0c" />
1414
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
15-
<!-- <link rel="stylesheet" href="%sveltekit.assets%/css/govuk-frontend.min.css"> -->
15+
<link rel="stylesheet" href="%sveltekit.assets%/css/govuk-frontend.min.css">
1616
%sveltekit.head%
1717
</head>
1818

@@ -24,6 +24,7 @@
2424
? " govuk-frontend-supported"
2525
: "");
2626
</script>
27+
2728
<div>%sveltekit.body%</div>
2829
</body>
2930
</html>
Lines changed: 73 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<script>
2+
import Button from "$lib/components/ui/Button.svelte";
3+
24
let {
35
componentNameProp = undefined,
46
data = undefined,
57
metaData = undefined,
8+
caption = undefined,
9+
colourScale = undefined,
610
} = $props();
711
812
let localCopyOfData = $state([...data]);
@@ -87,67 +91,79 @@
8791
{/snippet}
8892

8993
<div class="p-4">
90-
<h4>{componentNameProp} component</h4>
91-
92-
<div class="legend">
93-
<div>Colour key:</div>
94-
{#each colorKey as key}
95-
<div class="good" style="background-color: {normToColor(key[1])}">
96-
{key[0]}
97-
</div>
98-
{/each}
99-
</div>
94+
{#if colourScale === "On"}
95+
<div class="legend">
96+
<div>Colour key:</div>
97+
{#each colorKey as key}
98+
<div class="color-keys" style="background-color: {normToColor(key[1])}">
99+
{key[0]}
100+
</div>
101+
{/each}
102+
</div>
103+
{/if}
100104

101105
<div class="table-container">
102-
<table class="my-table">
103-
<caption></caption>
104-
<thead
105-
><tr>
106-
<th class="col-one-header">Area</th>
106+
<table class="govuk-table" data-module="moj-sortable-table">
107+
<caption class="govuk-table__caption">{caption}</caption>
108+
<thead class="govuk-table__head"
109+
><tr class="govuk-table__row">
110+
<th scope="col" class="govuk-table__header" aria-sort="ascending"
111+
>Area</th
112+
>
107113
{#each metrics as metric}
108-
<th title={metaData[metric].explainer}>
114+
<th
115+
scope="col"
116+
class="govuk-table__header govuk-table__header--numeric"
117+
title={metaData[metric].explainer}
118+
aria-sort="none"
119+
>
109120
<div class="header">
110-
<div class="header-top">
111-
<div class="metric">{metaData[metric].label}</div>
112-
<div class="sorting-button">
113-
<button
114-
onclick={() => {
115-
updateSortState(metric, "ascending");
116-
sortFunction();
117-
}}>▲</button
118-
>
119-
<button
120-
onclick={() => {
121-
updateSortState(metric, "descending");
122-
sortFunction();
123-
}}>▼</button
124-
>
125-
</div>
126-
</div>
127-
<div class="metric-explainer">
128-
{metaData[metric].explainer}
129-
</div>
130-
</div>
131-
</th>
121+
<Button
122+
textContent={metaData[metric].shortLabel}
123+
buttonType={"table header"}
124+
onClickFunction={() => {
125+
const newDirection =
126+
sortState.column === metric &&
127+
sortState.order === "ascending"
128+
? "descending"
129+
: "ascending";
130+
131+
updateSortState(metric, newDirection);
132+
sortFunction();
133+
}}
134+
></Button>
135+
</div></th
136+
>
132137
{/each}
133138
</tr></thead
134139
>
135-
<tbody>
140+
<tbody class="govuk-table__body">
136141
{#each localCopyOfData as row}
137-
<tr>
138-
<td class="areas">{row["areaName"]}</td>
142+
<tr class="govuk-table__row">
143+
<td class="govuk-table__cell">{row["areaName"]}</td>
139144
{#each metrics as metric}
140-
{#if metaData[metric].direction === "Higher is better"}
141-
<td
142-
style="background-color: {normToColor(
143-
row[metric + '__normalised'],
144-
)}">{row[metric]}</td
145-
>
145+
{#if colourScale === "On"}
146+
{#if metaData[metric].direction === "Higher is better"}
147+
<td
148+
class="govuk-table__cell govuk-table__cell--numeric"
149+
style="background-color: {normToColor(
150+
row[metric + '__normalised'],
151+
)}"
152+
data-sort-value="42">{row[metric]}</td
153+
>
154+
{:else}
155+
<td
156+
class="govuk-table__cell govuk-table__cell--numeric"
157+
style="background-color: {normToColorReverse(
158+
row[metric + '__normalised'],
159+
)}"
160+
data-sort-value="42">{row[metric]}</td
161+
>
162+
{/if}
146163
{:else}
147164
<td
148-
style="background-color: {normToColorReverse(
149-
row[metric + '__normalised'],
150-
)}">{row[metric]}</td
165+
class="govuk-table__cell govuk-table__cell--numeric"
166+
data-sort-value="42">{row[metric]}</td
151167
>
152168
{/if}
153169
{/each}
@@ -159,101 +175,26 @@
159175
</div>
160176

161177
<style>
162-
* {
163-
margin: 0px;
164-
padding: 0px;
165-
}
166-
167178
.table-container {
168-
max-height: 85vh;
179+
max-height: 80vh;
169180
overflow-y: auto;
170-
border: 1px solid black;
171-
border-radius: 1%;
172181
}
173182
174-
.ascending {
175-
background-color: #ff7f7f;
176-
}
177-
.descending {
178-
background-color: #add8e6;
179-
}
180-
.buttons-container {
181-
display: flex;
182-
gap: 20px;
183+
th {
184+
position: sticky;
185+
top: 0;
186+
z-index: 1;
187+
background-color: white;
183188
}
184189
185-
.metric-explainer {
186-
font-size: 13px;
187-
font-style: italic;
188-
font-weight: 400;
189-
}
190190
.legend {
191191
display: flex;
192192
justify-content: center;
193193
gap: 20px;
194194
margin: 10px;
195195
}
196-
197-
.legend > * {
196+
.color-keys {
198197
border-radius: 10%;
199198
padding: 6px;
200199
}
201-
202-
td {
203-
padding: 0.5rem 0.5rem;
204-
}
205-
206-
th {
207-
text-align: left;
208-
font-size: medium;
209-
vertical-align: top;
210-
}
211-
212-
td {
213-
text-align: right;
214-
}
215-
.areas {
216-
font-size: medium;
217-
}
218-
.my-table {
219-
table-layout: fixed;
220-
width: 100%;
221-
}
222-
223-
.my-table th:first-child,
224-
.my-table td:first-child {
225-
width: 25%;
226-
}
227-
228-
.my-table th:nth-child(n + 2),
229-
.my-table td:nth-child(n + 2) {
230-
width: 25%;
231-
}
232-
233-
.header {
234-
display: flex;
235-
flex-direction: column;
236-
padding: 5px;
237-
justify-content: flex-start;
238-
}
239-
240-
.header-top {
241-
display: flex;
242-
gap: 0px;
243-
}
244-
245-
.sorting-button {
246-
display: flex;
247-
flex-direction: column;
248-
font-size: 0.8em;
249-
line-height: 1; /* removes extra space between lines */
250-
gap: 3px;
251-
justify-content: center;
252-
background-color: lightgray;
253-
border-radius: 20%;
254-
}
255-
.col-one-header {
256-
text-align: right;
257-
padding: 5px;
258-
}
259200
</style>

src/lib/components/ui/Button.svelte

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
textContent = undefined,
44
buttonType,
55
componentNameProp = undefined,
6-
buttonFunction,
6+
onClickFunction = undefined,
77
} = $props();
88
99
let buttonClass = $derived(
@@ -20,16 +20,14 @@
2020
</script>
2121

2222
<div class="p-4">
23-
<h4>{componentNameProp} component</h4>
24-
<br />
2523
{#if buttonType === "start"}
2624
<a
2725
href="#"
2826
role="button"
2927
draggable="false"
3028
class="govuk-button govuk-button--start"
3129
data-module="govuk-button"
32-
onclick={buttonFunction}
30+
onclick={onClickFunction}
3331
>
3432
{textContent}
3533
<svg
@@ -51,12 +49,12 @@
5149
aria-disabled="true"
5250
class="govuk-button"
5351
data-module="govuk-button"
54-
onclick={buttonFunction}
52+
onclick={onClickFunction}
5553
>
5654
{textContent}
5755
</button>
5856
{:else if buttonType === "table header"}
59-
<button type="button" class="text-header">
57+
<button type="button" class="text-header" onclick={onClickFunction}>
6058
{textContent}
6159
<svg
6260
width="22"
@@ -83,7 +81,7 @@
8381
type="submit"
8482
class={buttonClass}
8583
data-module="govuk-button"
86-
onclick={buttonFunction}
84+
onclick={onClickFunction}
8785
>
8886
{textContent}
8987
</button>

src/wrappers/components/data-vis/table/TableWrapper.svelte

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,28 @@
174174
visible: false,
175175
value: data.metaData,
176176
},
177+
{
178+
name: "caption",
179+
category: "Input props",
180+
value: `This is the table caption`,
181+
description: {
182+
markdown: true,
183+
arr: [`This is the caption of the table. It sits above the table.`],
184+
},
185+
rows: 2,
186+
},
187+
{
188+
name: "colourScale",
189+
category: "Input props",
190+
propType: "radio",
191+
options: ["Off", "On"],
192+
description: {
193+
markdown: true,
194+
arr: [
195+
`Turn the colour scale on if you want to more easily gauge the magnitude of the value relative to highest and lowest values of that metric.`,
196+
],
197+
},
198+
},
177199
]),
178200
);
179201

src/wrappers/components/ui/ButtonWrapper.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@
198198
rows: 5,
199199
},
200200
{
201-
name: "buttonFunction",
201+
name: "onClickFunction",
202202
category: "Input props",
203203
value: function () {
204204
window.alert(`The button function has been triggered.`);

0 commit comments

Comments
 (0)