@communitiesuk/svelte-component-library 0.1.19-beta.3 → 0.1.19-beta.33
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/README.md +7 -0
- package/dist/components/content/Tag.svelte +32 -0
- package/dist/components/content/Tag.svelte.d.ts +13 -0
- package/dist/components/data-vis/Histogram.svelte +302 -0
- package/dist/components/data-vis/Histogram.svelte.d.ts +75 -0
- package/dist/components/data-vis/axis/Axis.svelte +217 -34
- package/dist/components/data-vis/axis/Axis.svelte.d.ts +38 -30
- package/dist/components/data-vis/axis/Ticks.svelte +142 -78
- package/dist/components/data-vis/axis/Ticks.svelte.d.ts +28 -31
- package/dist/components/data-vis/line-chart/LineChart.svelte +51 -21
- package/dist/components/data-vis/line-chart/LineChart.svelte.d.ts +14 -6
- package/dist/components/data-vis/line-chart/ValueLabel.svelte +2 -1
- package/dist/components/data-vis/line-chart/ValueLabel.svelte.d.ts +2 -0
- package/dist/components/data-vis/position-chart/PositionChart.svelte +278 -122
- package/dist/components/data-vis/position-chart/PositionChart.svelte.d.ts +37 -5
- package/dist/components/data-vis/position-chart/PositionChartAxis.svelte +59 -48
- package/dist/components/data-vis/position-chart/PositionChartAxis.svelte.d.ts +4 -4
- package/dist/components/layout/Footer.svelte +9 -0
- package/dist/components/layout/Footer.svelte.d.ts +1 -0
- package/dist/components/layout/PhaseBanner.svelte +10 -1
- package/dist/components/layout/PhaseBanner.svelte.d.ts +1 -0
- package/dist/components/layout/ServiceNavigation.svelte +19 -1
- package/dist/components/layout/ServiceNavigation.svelte.d.ts +2 -0
- package/dist/components/ui/BasicMultiSelect.svelte +716 -0
- package/dist/components/ui/BasicMultiSelect.svelte.d.ts +18 -0
- package/dist/components/ui/Button.svelte +1 -0
- package/dist/components/ui/Card.svelte +48 -60
- package/dist/components/ui/Card.svelte.d.ts +26 -12
- package/dist/components/ui/CardHeader.svelte +46 -0
- package/dist/components/ui/CardHeader.svelte.d.ts +21 -0
- package/dist/components/ui/ChartExporter.svelte +142 -0
- package/dist/components/ui/ChartExporter.svelte.d.ts +16 -0
- package/dist/components/ui/CheckBox.svelte +1 -0
- package/dist/components/ui/Details.svelte +47 -8
- package/dist/components/ui/Details.svelte.d.ts +8 -10
- package/dist/components/ui/Masthead.svelte +44 -6
- package/dist/components/ui/Masthead.svelte.d.ts +6 -0
- package/dist/components/ui/RelatedContent.svelte +4 -1
- package/dist/components/ui/RelatedContent.svelte.d.ts +1 -0
- package/dist/components/ui/SearchAutocomplete.svelte +69 -44
- package/dist/components/ui/SearchAutocomplete.svelte.d.ts +1 -0
- package/dist/components/ui/Select.svelte +18 -7
- package/dist/components/ui/Tabs.svelte +192 -18
- package/dist/components/ui/Tabs.svelte.d.ts +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/package.json +4 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type Option = {
|
|
2
|
+
id: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
};
|
|
5
|
+
type $$ComponentProps = {
|
|
6
|
+
options?: Option[];
|
|
7
|
+
selected?: (string | number)[];
|
|
8
|
+
colorArray?: string[];
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
hint?: string;
|
|
12
|
+
enableColors?: boolean;
|
|
13
|
+
startsWithSearch?: boolean;
|
|
14
|
+
resetButton?: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare const BasicMultiSelect: import("svelte").Component<$$ComponentProps, {}, "selected">;
|
|
17
|
+
type BasicMultiSelect = ReturnType<typeof BasicMultiSelect>;
|
|
18
|
+
export default BasicMultiSelect;
|
|
@@ -1,101 +1,89 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import CardHeader from "./CardHeader.svelte";
|
|
3
|
+
|
|
2
4
|
let {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
headerIsLink = true,
|
|
6
|
+
headerText = "Card header",
|
|
7
|
+
headerTextSize = "1.5rem",
|
|
8
|
+
headerTextColor = "#1D70B8",
|
|
9
|
+
headerBackgroundColor = "white",
|
|
6
10
|
href = undefined,
|
|
7
|
-
|
|
8
|
-
bodyText =
|
|
11
|
+
onlyTextInBody = true,
|
|
12
|
+
bodyText = "Text in the body of the card",
|
|
13
|
+
headerSnippet = undefined,
|
|
14
|
+
bodySnippet = undefined,
|
|
15
|
+
children = undefined,
|
|
9
16
|
bodyTextColor = "#0B0C0C",
|
|
10
17
|
bodyBackgroundColor = "#FBFCFD",
|
|
11
18
|
bodyTopBorderColor = "#F4F8FB",
|
|
12
19
|
bodyBottomBorderColor = "#c3d9e9",
|
|
13
20
|
selectedValue = $bindable(),
|
|
14
|
-
|
|
21
|
+
display = "flex",
|
|
22
|
+
gridPosition = undefined,
|
|
23
|
+
subtitle = undefined,
|
|
15
24
|
} = $props();
|
|
16
25
|
</script>
|
|
17
26
|
|
|
18
|
-
<div class="card">
|
|
27
|
+
<div class="card" style="display: {display}">
|
|
19
28
|
<div
|
|
20
|
-
class="
|
|
21
|
-
style="background-color: {
|
|
29
|
+
class="header-div"
|
|
30
|
+
style="background-color: {headerBackgroundColor}; grid-row: {gridPosition?.[0]
|
|
31
|
+
?.row ?? null}; grid-column: {gridPosition?.[0]?.col ?? null};"
|
|
22
32
|
>
|
|
23
|
-
{#if
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
-
width="10"
|
|
34
|
-
height="17"
|
|
35
|
-
viewBox="0 0 10 17"
|
|
36
|
-
fill="none"
|
|
37
|
-
>
|
|
38
|
-
<path
|
|
39
|
-
d="M6.21622 8.5L0 2.36667L1.89189 0.5L10 8.5L1.89189 16.5L0 14.6333L6.21622 8.5Z"
|
|
40
|
-
fill={linkTextColor}
|
|
41
|
-
></path>
|
|
42
|
-
</svg>
|
|
43
|
-
</a>
|
|
33
|
+
{#if headerIsLink}
|
|
34
|
+
<CardHeader
|
|
35
|
+
text={headerText}
|
|
36
|
+
textSize={headerTextSize}
|
|
37
|
+
textColor={headerTextColor}
|
|
38
|
+
backgroundColor={headerBackgroundColor}
|
|
39
|
+
{href}
|
|
40
|
+
{subtitle}
|
|
41
|
+
></CardHeader>
|
|
44
42
|
{:else}
|
|
45
|
-
{@render
|
|
43
|
+
{@render headerSnippet?.()}
|
|
46
44
|
{/if}
|
|
47
45
|
</div>
|
|
48
46
|
|
|
49
47
|
<div
|
|
50
48
|
class="body-div"
|
|
51
|
-
style="--body-bg-color: {bodyBackgroundColor}; --body-bottom-border-color: {bodyBottomBorderColor}; --body-top-border-color: {bodyTopBorderColor};
|
|
49
|
+
style="--body-bg-color: {bodyBackgroundColor}; --body-bottom-border-color: {bodyBottomBorderColor}; --body-top-border-color: {bodyTopBorderColor}; grid-row: {gridPosition?.[1]
|
|
50
|
+
?.row ?? null}; grid-column: {gridPosition?.[1]?.col ?? null};"
|
|
52
51
|
>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
{#if onlyTextInBody}
|
|
53
|
+
<p
|
|
54
|
+
class="govuk-body body-text"
|
|
55
|
+
style="--body-text-color: {bodyTextColor};"
|
|
56
|
+
>
|
|
57
|
+
{bodyText}
|
|
58
|
+
</p>
|
|
59
|
+
{:else if children}
|
|
60
|
+
{@render children?.()}
|
|
61
|
+
{:else}
|
|
62
|
+
{@render bodySnippet?.()}
|
|
63
|
+
{/if}
|
|
56
64
|
</div>
|
|
57
65
|
</div>
|
|
58
66
|
|
|
59
67
|
<style>
|
|
60
68
|
.card {
|
|
61
|
-
display: flex;
|
|
62
69
|
flex-direction: column;
|
|
70
|
+
min-width: 0;
|
|
63
71
|
}
|
|
64
72
|
|
|
65
|
-
.
|
|
66
|
-
padding:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.link {
|
|
70
|
-
display: flex;
|
|
71
|
-
align-items: center;
|
|
72
|
-
justify-content: space-between;
|
|
73
|
-
width: 100%;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.link-heading {
|
|
77
|
-
color: var(--link-text-color);
|
|
73
|
+
.header-div {
|
|
74
|
+
padding: 20px;
|
|
75
|
+
flex: 1;
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
.body-div {
|
|
81
79
|
background-color: var(--body-bg-color);
|
|
82
80
|
border-bottom: 1px solid var(--body-bottom-border-color);
|
|
83
81
|
border-top: 1px solid var(--body-top-border-color);
|
|
84
|
-
padding:
|
|
82
|
+
padding: 15px 1%;
|
|
85
83
|
flex: 1;
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
.body-text {
|
|
89
87
|
color: var(--body-text-color);
|
|
90
88
|
}
|
|
91
|
-
|
|
92
|
-
.govuk-heading-m {
|
|
93
|
-
/* overwriting margin and line-height to make link centered vertically */
|
|
94
|
-
margin: 0;
|
|
95
|
-
line-height: 1;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
a {
|
|
99
|
-
color: #1d70b8;
|
|
100
|
-
}
|
|
101
89
|
</style>
|
|
@@ -4,30 +4,44 @@ type Card = {
|
|
|
4
4
|
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
5
|
};
|
|
6
6
|
declare const Card: import("svelte").Component<{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
headerIsLink?: boolean;
|
|
8
|
+
headerText?: string;
|
|
9
|
+
headerTextSize?: string;
|
|
10
|
+
headerTextColor?: string;
|
|
11
|
+
headerBackgroundColor?: string;
|
|
10
12
|
href?: any;
|
|
11
|
-
|
|
12
|
-
bodyText?:
|
|
13
|
+
onlyTextInBody?: boolean;
|
|
14
|
+
bodyText?: string;
|
|
15
|
+
headerSnippet?: any;
|
|
16
|
+
bodySnippet?: any;
|
|
17
|
+
children?: any;
|
|
13
18
|
bodyTextColor?: string;
|
|
14
19
|
bodyBackgroundColor?: string;
|
|
15
20
|
bodyTopBorderColor?: string;
|
|
16
21
|
bodyBottomBorderColor?: string;
|
|
17
22
|
selectedValue?: any;
|
|
18
|
-
|
|
23
|
+
display?: string;
|
|
24
|
+
gridPosition?: any;
|
|
25
|
+
subtitle?: any;
|
|
19
26
|
}, {}, "selectedValue">;
|
|
20
27
|
type $$ComponentProps = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
headerIsLink?: boolean;
|
|
29
|
+
headerText?: string;
|
|
30
|
+
headerTextSize?: string;
|
|
31
|
+
headerTextColor?: string;
|
|
32
|
+
headerBackgroundColor?: string;
|
|
24
33
|
href?: any;
|
|
25
|
-
|
|
26
|
-
bodyText?:
|
|
34
|
+
onlyTextInBody?: boolean;
|
|
35
|
+
bodyText?: string;
|
|
36
|
+
headerSnippet?: any;
|
|
37
|
+
bodySnippet?: any;
|
|
38
|
+
children?: any;
|
|
27
39
|
bodyTextColor?: string;
|
|
28
40
|
bodyBackgroundColor?: string;
|
|
29
41
|
bodyTopBorderColor?: string;
|
|
30
42
|
bodyBottomBorderColor?: string;
|
|
31
43
|
selectedValue?: any;
|
|
32
|
-
|
|
44
|
+
display?: string;
|
|
45
|
+
gridPosition?: any;
|
|
46
|
+
subtitle?: any;
|
|
33
47
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let {
|
|
3
|
+
text = "Card header",
|
|
4
|
+
textSize = "1.5rem",
|
|
5
|
+
textColor = "#1D70B8",
|
|
6
|
+
backgroundColor = "white",
|
|
7
|
+
href = undefined,
|
|
8
|
+
subtitle = undefined,
|
|
9
|
+
} = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<a
|
|
13
|
+
class="link govuk-heading-m"
|
|
14
|
+
{href}
|
|
15
|
+
style="font-size: {textSize}; color: {textColor}; background-color: {backgroundColor}; margin: {subtitle ??
|
|
16
|
+
0}"
|
|
17
|
+
>
|
|
18
|
+
{text}
|
|
19
|
+
<svg
|
|
20
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
21
|
+
width="1em"
|
|
22
|
+
height="1em"
|
|
23
|
+
viewBox="0 0 10 17"
|
|
24
|
+
aria-hidden="true"
|
|
25
|
+
>
|
|
26
|
+
<path
|
|
27
|
+
d="M6.21622 8.5L0 2.36667L1.89189 0.5L10 8.5L1.89189 16.5L0 14.6333L6.21622 8.5Z"
|
|
28
|
+
fill="currentColor"
|
|
29
|
+
></path>
|
|
30
|
+
</svg>
|
|
31
|
+
</a>
|
|
32
|
+
{#if subtitle !== undefined}
|
|
33
|
+
<p>{subtitle}</p>{/if}
|
|
34
|
+
|
|
35
|
+
<style>
|
|
36
|
+
.link {
|
|
37
|
+
display: flex;
|
|
38
|
+
justify-content: space-between;
|
|
39
|
+
align-items: center;
|
|
40
|
+
width: 100%;
|
|
41
|
+
gap: 0.5rem;
|
|
42
|
+
}
|
|
43
|
+
p {
|
|
44
|
+
color: #666;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default CardHeader;
|
|
2
|
+
type CardHeader = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const CardHeader: import("svelte").Component<{
|
|
7
|
+
text?: string;
|
|
8
|
+
textSize?: string;
|
|
9
|
+
textColor?: string;
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
href?: any;
|
|
12
|
+
subtitle?: any;
|
|
13
|
+
}, {}, "">;
|
|
14
|
+
type $$ComponentProps = {
|
|
15
|
+
text?: string;
|
|
16
|
+
textSize?: string;
|
|
17
|
+
textColor?: string;
|
|
18
|
+
backgroundColor?: string;
|
|
19
|
+
href?: any;
|
|
20
|
+
subtitle?: any;
|
|
21
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// src/lib/utils/exportChartPNG.ts
|
|
3
|
+
export async function exportChartPNG(
|
|
4
|
+
node: HTMLElement,
|
|
5
|
+
{
|
|
6
|
+
fileName = "chart.png",
|
|
7
|
+
margin = 16,
|
|
8
|
+
backgroundColor = "#ffffff",
|
|
9
|
+
pixelRatio = Math.max(2, window.devicePixelRatio || 1),
|
|
10
|
+
filter,
|
|
11
|
+
}: {
|
|
12
|
+
fileName?: string;
|
|
13
|
+
margin?: number; // padding applied during export to avoid edges clipping
|
|
14
|
+
backgroundColor?: string;
|
|
15
|
+
pixelRatio?: number;
|
|
16
|
+
filter?: (node: Element) => boolean;
|
|
17
|
+
},
|
|
18
|
+
): Promise<string> {
|
|
19
|
+
const { toPng } = await import("html-to-image");
|
|
20
|
+
|
|
21
|
+
// Wait for web fonts to settle (prevents text reflow/misalignment)
|
|
22
|
+
if ((document as any).fonts?.ready) {
|
|
23
|
+
try {
|
|
24
|
+
await (document as any).fonts.ready;
|
|
25
|
+
} catch {
|
|
26
|
+
/* ignore */
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Measure the true content size (includes overflow)
|
|
31
|
+
const exportWidth = Math.ceil(node.scrollWidth + margin * 2);
|
|
32
|
+
const exportHeight = Math.ceil(node.scrollHeight + margin * 2);
|
|
33
|
+
|
|
34
|
+
const dataUrl = await toPng(node, {
|
|
35
|
+
cacheBust: false,
|
|
36
|
+
backgroundColor,
|
|
37
|
+
pixelRatio,
|
|
38
|
+
width: exportWidth,
|
|
39
|
+
height: exportHeight,
|
|
40
|
+
style: {
|
|
41
|
+
// Apply padding inside the cloned element
|
|
42
|
+
padding: `${margin}px`,
|
|
43
|
+
boxSizing: "border-box",
|
|
44
|
+
// Ensure no clipping
|
|
45
|
+
overflow: "visible",
|
|
46
|
+
},
|
|
47
|
+
filter,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const name = fileName.toLowerCase().endsWith(".png")
|
|
51
|
+
? fileName
|
|
52
|
+
: `${fileName}.png`;
|
|
53
|
+
const link = document.createElement("a");
|
|
54
|
+
link.download = name;
|
|
55
|
+
link.href = dataUrl;
|
|
56
|
+
link.click();
|
|
57
|
+
|
|
58
|
+
return dataUrl;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Props
|
|
62
|
+
let {
|
|
63
|
+
node = null,
|
|
64
|
+
fileName = "chart",
|
|
65
|
+
}: { node: HTMLElement | null; fileName?: string } = $props();
|
|
66
|
+
|
|
67
|
+
// Local state for optional external triggering
|
|
68
|
+
let isExporting = $state(false);
|
|
69
|
+
|
|
70
|
+
async function exportNow() {
|
|
71
|
+
if (!node) return;
|
|
72
|
+
|
|
73
|
+
isExporting = true;
|
|
74
|
+
|
|
75
|
+
// Measure width to force correct clone sizing
|
|
76
|
+
const rect = node.getBoundingClientRect();
|
|
77
|
+
const measuredWidth = Math.ceil(rect.width);
|
|
78
|
+
|
|
79
|
+
// ------- Clone -------
|
|
80
|
+
const clone = node.cloneNode(true) as HTMLElement;
|
|
81
|
+
Object.assign(clone.style, {
|
|
82
|
+
boxSizing: "border-box",
|
|
83
|
+
width: `${measuredWidth}px`,
|
|
84
|
+
height: "auto",
|
|
85
|
+
transform: "none",
|
|
86
|
+
overflow: "visible",
|
|
87
|
+
fontFamily: "GDS Transport",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// ------- Hide tooltips (optional) -------
|
|
91
|
+
const hideSelectors = ['[role="tooltip"]'];
|
|
92
|
+
clone
|
|
93
|
+
.querySelectorAll<HTMLElement>(hideSelectors.join(","))
|
|
94
|
+
.forEach((el) => {
|
|
95
|
+
el.style.display = "none";
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ------- Sandbox offscreen -------
|
|
99
|
+
const sandbox = document.createElement("div");
|
|
100
|
+
Object.assign(sandbox.style, {
|
|
101
|
+
position: "fixed",
|
|
102
|
+
left: "-10000px",
|
|
103
|
+
top: "0",
|
|
104
|
+
pointerEvents: "none",
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
sandbox.appendChild(clone);
|
|
108
|
+
document.body.appendChild(sandbox);
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await exportChartPNG(clone, {
|
|
112
|
+
fileName,
|
|
113
|
+
margin: 16,
|
|
114
|
+
backgroundColor: "#ffffff",
|
|
115
|
+
pixelRatio: Math.max(2, window.devicePixelRatio || 1),
|
|
116
|
+
filter: (el: Element) => {
|
|
117
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
118
|
+
|
|
119
|
+
// Exclude tooltips only
|
|
120
|
+
if (el.matches(hideSelectors.join(","))) return false;
|
|
121
|
+
|
|
122
|
+
return true;
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
} finally {
|
|
126
|
+
sandbox.remove();
|
|
127
|
+
isExporting = false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// We export the function so parent can trigger it manually
|
|
132
|
+
export { exportNow };
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<!-- Default button (can be hidden if user triggers manually) -->
|
|
136
|
+
<button
|
|
137
|
+
class="govuk-button govuk-button--secondary"
|
|
138
|
+
on:click={exportNow}
|
|
139
|
+
disabled={isExporting}
|
|
140
|
+
>
|
|
141
|
+
{isExporting ? "Exporting…" : "Download this chart"}
|
|
142
|
+
</button>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
node: HTMLElement | null;
|
|
3
|
+
fileName?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const ChartExporter: import("svelte").Component<$$ComponentProps, {
|
|
6
|
+
exportChartPNG: (node: HTMLElement, { fileName, margin, backgroundColor, pixelRatio, filter, }: {
|
|
7
|
+
fileName?: string;
|
|
8
|
+
margin?: number;
|
|
9
|
+
backgroundColor?: string;
|
|
10
|
+
pixelRatio?: number;
|
|
11
|
+
filter?: (node: Element) => boolean;
|
|
12
|
+
}) => Promise<string>;
|
|
13
|
+
exportNow: () => Promise<void>;
|
|
14
|
+
}, "">;
|
|
15
|
+
type ChartExporter = ReturnType<typeof ChartExporter>;
|
|
16
|
+
export default ChartExporter;
|
|
@@ -1,12 +1,51 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
let {
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let {
|
|
3
|
+
summaryText,
|
|
4
|
+
detailedText,
|
|
5
|
+
renderStringAsHTML = false,
|
|
6
|
+
noInset = false,
|
|
7
|
+
overlapBelow = false,
|
|
8
|
+
expanded = $bindable(false),
|
|
9
|
+
groupName = undefined,
|
|
10
|
+
} = $props();
|
|
3
11
|
</script>
|
|
4
12
|
|
|
5
|
-
<details class="govuk-details">
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
<details class="govuk-details" open={expanded} name={groupName}>
|
|
14
|
+
{#if renderStringAsHTML}
|
|
15
|
+
<summary class="govuk-details__summary-text">
|
|
16
|
+
{@html summaryText}
|
|
17
|
+
</summary>
|
|
18
|
+
{:else}
|
|
19
|
+
<summary class="govuk-details__summary-text">{summaryText}</summary>
|
|
20
|
+
{/if}
|
|
21
|
+
|
|
22
|
+
<div
|
|
23
|
+
class={`govuk-details__text ${noInset === true ? "no-inset" : ""} ${overlapBelow === true ? "overlap-below" : ""}`}
|
|
24
|
+
>
|
|
25
|
+
{#if typeof detailedText === "string"}
|
|
26
|
+
{#if renderStringAsHTML}
|
|
27
|
+
{@html detailedText}
|
|
28
|
+
{:else}
|
|
29
|
+
{detailedText}
|
|
30
|
+
{/if}
|
|
31
|
+
{:else if detailedText}
|
|
32
|
+
{@render detailedText()}
|
|
33
|
+
{/if}
|
|
11
34
|
</div>
|
|
12
35
|
</details>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
.no-inset {
|
|
39
|
+
padding: 0;
|
|
40
|
+
border: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
details {
|
|
44
|
+
position: relative;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.overlap-below {
|
|
48
|
+
position: absolute;
|
|
49
|
+
background-color: white;
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
export default Details;
|
|
2
|
-
type Details = {
|
|
3
|
-
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
-
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
-
};
|
|
6
1
|
declare const Details: import("svelte").Component<{
|
|
7
2
|
summaryText: any;
|
|
8
3
|
detailedText: any;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
renderStringAsHTML?: boolean;
|
|
5
|
+
noInset?: boolean;
|
|
6
|
+
overlapBelow?: boolean;
|
|
7
|
+
expanded?: boolean;
|
|
8
|
+
groupName?: any;
|
|
9
|
+
}, {}, "expanded">;
|
|
10
|
+
type Details = ReturnType<typeof Details>;
|
|
11
|
+
export default Details;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import homepageIllustration from "./../../assets/images/homepage-illustration.svg";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
3
4
|
|
|
4
5
|
// Define component props with types and default values
|
|
5
6
|
let {
|
|
@@ -12,6 +13,11 @@
|
|
|
12
13
|
imageAlt = "",
|
|
13
14
|
backgroundColor = "#1d70b8", // GOV.UK blue by default
|
|
14
15
|
textColor = "#FFFFFF",
|
|
16
|
+
imgMarginTop = "15px",
|
|
17
|
+
paddingTop = "30px",
|
|
18
|
+
titlePaddingTop = false,
|
|
19
|
+
paddingBottom = "30px",
|
|
20
|
+
contentSnippet = undefined,
|
|
15
21
|
} = $props<{
|
|
16
22
|
title?: string;
|
|
17
23
|
description?: string;
|
|
@@ -22,18 +28,32 @@
|
|
|
22
28
|
imageAlt?: string;
|
|
23
29
|
backgroundColor?: string;
|
|
24
30
|
textColor?: string;
|
|
31
|
+
imgMarginTop?: string;
|
|
32
|
+
paddingTop?: string;
|
|
33
|
+
titlePaddingTop?: boolean;
|
|
34
|
+
paddingBottom?: string;
|
|
35
|
+
contentSnippet?: Snippet;
|
|
25
36
|
}>();
|
|
37
|
+
|
|
38
|
+
let arg = "hello";
|
|
26
39
|
</script>
|
|
27
40
|
|
|
28
41
|
<div
|
|
29
42
|
class="app-masthead"
|
|
30
|
-
style="background-color: {backgroundColor}; border-bottom-color: {backgroundColor}; --masthead-text-color: {textColor};"
|
|
43
|
+
style="background-color: {backgroundColor}; border-bottom-color: {backgroundColor}; --masthead-text-color: {textColor}; --padding-top: {paddingTop}; --padding-bottom: {paddingBottom};"
|
|
31
44
|
>
|
|
32
45
|
<div class="govuk-width-container">
|
|
33
46
|
<div class="govuk-grid-row">
|
|
34
|
-
<div
|
|
47
|
+
<div
|
|
48
|
+
class="govuk-grid-column-two-thirds-from-desktop {titlePaddingTop
|
|
49
|
+
? 'custom-padding'
|
|
50
|
+
: ''}"
|
|
51
|
+
>
|
|
35
52
|
<h1 class="govuk-heading-xl app-masthead__title">{@html title}</h1>
|
|
36
53
|
<p class="app-masthead__description">{description}</p>
|
|
54
|
+
{#if contentSnippet}
|
|
55
|
+
{@render contentSnippet()}
|
|
56
|
+
{/if}
|
|
37
57
|
{#if includeButton === true}
|
|
38
58
|
<a
|
|
39
59
|
href={buttonHref}
|
|
@@ -61,6 +81,7 @@
|
|
|
61
81
|
<div class="govuk-grid-column-one-third-from-desktop">
|
|
62
82
|
<img
|
|
63
83
|
class="app-masthead__image"
|
|
84
|
+
style="--img-margin-top: {imgMarginTop}"
|
|
64
85
|
src={imageSrc}
|
|
65
86
|
alt={imageAlt}
|
|
66
87
|
role="presentation"
|
|
@@ -88,8 +109,8 @@
|
|
|
88
109
|
@media (min-width: 40.0625em) {
|
|
89
110
|
.app-masthead.app-masthead {
|
|
90
111
|
/* Responsive spacing unit 6: 30px on large screens */
|
|
91
|
-
padding-top:
|
|
92
|
-
padding-bottom:
|
|
112
|
+
padding-top: var(--padding-top);
|
|
113
|
+
padding-bottom: var(--padding-bottom);
|
|
93
114
|
}
|
|
94
115
|
}
|
|
95
116
|
|
|
@@ -128,12 +149,19 @@
|
|
|
128
149
|
}
|
|
129
150
|
|
|
130
151
|
/* @include govuk-media-query($from: desktop) - Desktop breakpoint is 769px */
|
|
131
|
-
@media (min-width:
|
|
152
|
+
@media (min-width: 53em) {
|
|
132
153
|
.app-masthead .app-masthead__image.app-masthead__image {
|
|
133
154
|
display: block;
|
|
134
155
|
width: 100%;
|
|
135
156
|
/* margin-top: govuk-spacing(3); - Static spacing unit 3 is 15px */
|
|
136
|
-
margin-top:
|
|
157
|
+
margin-top: var(--img-margin-top);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@media (max-width: 52.9375em) {
|
|
162
|
+
.govuk-grid-column-two-thirds-from-desktop {
|
|
163
|
+
width: 100%;
|
|
164
|
+
float: none;
|
|
137
165
|
}
|
|
138
166
|
}
|
|
139
167
|
|
|
@@ -276,4 +304,14 @@
|
|
|
276
304
|
.app-masthead__description {
|
|
277
305
|
color: var(--masthead-text-color);
|
|
278
306
|
}
|
|
307
|
+
|
|
308
|
+
.custom-padding {
|
|
309
|
+
padding-top: 32px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@media (max-width: 820px) {
|
|
313
|
+
.custom-padding {
|
|
314
|
+
padding-top: 16px;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
279
317
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
1
2
|
type $$ComponentProps = {
|
|
2
3
|
title?: string;
|
|
3
4
|
description?: string;
|
|
@@ -8,6 +9,11 @@ type $$ComponentProps = {
|
|
|
8
9
|
imageAlt?: string;
|
|
9
10
|
backgroundColor?: string;
|
|
10
11
|
textColor?: string;
|
|
12
|
+
imgMarginTop?: string;
|
|
13
|
+
paddingTop?: string;
|
|
14
|
+
titlePaddingTop?: boolean;
|
|
15
|
+
paddingBottom?: string;
|
|
16
|
+
contentSnippet?: Snippet;
|
|
11
17
|
};
|
|
12
18
|
declare const Masthead: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
19
|
type Masthead = ReturnType<typeof Masthead>;
|