@communitiesuk/svelte-component-library 0.1.17
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 +188 -0
- package/dist/assets/css/govuk-frontend.min.css +2 -0
- package/dist/assets/css/govuk-frontend.min.css.map +1 -0
- package/dist/assets/fonts/bold-affa96571d-v2.woff +0 -0
- package/dist/assets/fonts/bold-b542beb274-v2.woff2 +0 -0
- package/dist/assets/fonts/light-94a07e06a1-v2.woff2 +0 -0
- package/dist/assets/fonts/light-f591b13f7d-v2.woff +0 -0
- package/dist/assets/govuk_publishing_components/images/icon-autocomplete-search-suggestion.svg +4 -0
- package/dist/assets/govuk_publishing_components/images/icon-close.svg +1 -0
- package/dist/assets/images/favicon.ico +0 -0
- package/dist/assets/images/favicon.svg +1 -0
- package/dist/assets/images/govuk-crest-2x.png +0 -0
- package/dist/assets/images/govuk-crest.png +0 -0
- package/dist/assets/images/govuk-crest.svg +1 -0
- package/dist/assets/images/govuk-icon-180.png +0 -0
- package/dist/assets/images/govuk-icon-192.png +0 -0
- package/dist/assets/images/govuk-icon-512.png +0 -0
- package/dist/assets/images/govuk-icon-mask.svg +1 -0
- package/dist/assets/images/govuk-opengraph-image.png +0 -0
- package/dist/assets/images/homepage-illustration.svg +1 -0
- package/dist/assets/images/homepage.svg +44 -0
- package/dist/assets/images/masthead-illustration.svg +123 -0
- package/dist/assets/images/oflog_crest_black.png +0 -0
- package/dist/assets/images/oflog_crest_white.png +0 -0
- package/dist/assets/images/undraw_approved-wireframe_odf4.svg +1 -0
- package/dist/assets/images/undraw_collaborators_rgw4.svg +1 -0
- package/dist/assets/images/undraw_content-creator_vuqg.svg +1 -0
- package/dist/assets/images/undraw_online-media_opxh.svg +1 -0
- package/dist/assets/images/undraw_pull-request_zlsu.svg +1 -0
- package/dist/assets/images/undraw_reviewed-docs_g0cg.svg +1 -0
- package/dist/components/FilterPanel/codeBlocks.d.ts +3 -0
- package/dist/components/FilterPanel/codeBlocks.js +418 -0
- package/dist/components/content/InsetText.svelte +21 -0
- package/dist/components/content/InsetText.svelte.d.ts +7 -0
- package/dist/components/content/WarningText.svelte +27 -0
- package/dist/components/content/WarningText.svelte.d.ts +8 -0
- package/dist/components/data-vis/axis/Axis.svelte +51 -0
- package/dist/components/data-vis/axis/Axis.svelte.d.ts +33 -0
- package/dist/components/data-vis/axis/Ticks.svelte +113 -0
- package/dist/components/data-vis/axis/Ticks.svelte.d.ts +33 -0
- package/dist/components/data-vis/line-chart/Line.svelte +150 -0
- package/dist/components/data-vis/line-chart/Line.svelte.d.ts +85 -0
- package/dist/components/data-vis/line-chart/LineChart.svelte +249 -0
- package/dist/components/data-vis/line-chart/LineChart.svelte.d.ts +73 -0
- package/dist/components/data-vis/line-chart/Lines.svelte +138 -0
- package/dist/components/data-vis/line-chart/Lines.svelte.d.ts +57 -0
- package/dist/components/data-vis/line-chart/Marker.svelte +61 -0
- package/dist/components/data-vis/line-chart/Marker.svelte.d.ts +37 -0
- package/dist/components/data-vis/line-chart/SeriesLabel.svelte +67 -0
- package/dist/components/data-vis/line-chart/SeriesLabel.svelte.d.ts +43 -0
- package/dist/components/data-vis/line-chart/ValueLabel.svelte +50 -0
- package/dist/components/data-vis/line-chart/ValueLabel.svelte.d.ts +25 -0
- package/dist/components/data-vis/map/Map.svelte +392 -0
- package/dist/components/data-vis/map/Map.svelte.d.ts +47 -0
- package/dist/components/data-vis/map/MapLegend.svelte +41 -0
- package/dist/components/data-vis/map/MapLegend.svelte.d.ts +15 -0
- package/dist/components/data-vis/map/NonStandardControls.svelte +42 -0
- package/dist/components/data-vis/map/NonStandardControls.svelte.d.ts +13 -0
- package/dist/components/data-vis/map/Tooltip.svelte +41 -0
- package/dist/components/data-vis/map/Tooltip.svelte.d.ts +19 -0
- package/dist/components/data-vis/map/colorbrewer.d.ts +337 -0
- package/dist/components/data-vis/map/colorbrewer.js +1523 -0
- package/dist/components/data-vis/map/colors.d.ts +13 -0
- package/dist/components/data-vis/map/colors.js +65 -0
- package/dist/components/data-vis/map/dataJoin.d.ts +2 -0
- package/dist/components/data-vis/map/dataJoin.js +27 -0
- package/dist/components/data-vis/map/fullTopo.json +1 -0
- package/dist/components/data-vis/map/jenks.d.ts +1 -0
- package/dist/components/data-vis/map/jenks.js +51 -0
- package/dist/components/data-vis/map/lad2023.json +1 -0
- package/dist/components/data-vis/map/mapUtils.d.ts +5 -0
- package/dist/components/data-vis/map/mapUtils.js +86 -0
- package/dist/components/data-vis/map/topo.json +1 -0
- package/dist/components/data-vis/table/Table.svelte +247 -0
- package/dist/components/data-vis/table/Table.svelte.d.ts +19 -0
- package/dist/components/layout/Breadcrumbs.svelte +191 -0
- package/dist/components/layout/Breadcrumbs.svelte.d.ts +24 -0
- package/dist/components/layout/Footer.svelte +171 -0
- package/dist/components/layout/Footer.svelte.d.ts +30 -0
- package/dist/components/layout/Header.svelte +43 -0
- package/dist/components/layout/Header.svelte.d.ts +7 -0
- package/dist/components/layout/InternalHeader.svelte +628 -0
- package/dist/components/layout/InternalHeader.svelte.d.ts +15 -0
- package/dist/components/layout/PhaseBanner.svelte +28 -0
- package/dist/components/layout/PhaseBanner.svelte.d.ts +9 -0
- package/dist/components/layout/ServiceNavigation.svelte +143 -0
- package/dist/components/layout/ServiceNavigation.svelte.d.ts +13 -0
- package/dist/components/layout/SideNavigation.svelte +345 -0
- package/dist/components/layout/SideNavigation.svelte.d.ts +25 -0
- package/dist/components/layout/service-navigation-nested-mobile/HeaderNav.svelte +91 -0
- package/dist/components/layout/service-navigation-nested-mobile/HeaderNav.svelte.d.ts +15 -0
- package/dist/components/layout/service-navigation-nested-mobile/MobileNav.svelte +233 -0
- package/dist/components/layout/service-navigation-nested-mobile/MobileNav.svelte.d.ts +27 -0
- package/dist/components/layout/service-navigation-nested-mobile/ServiceNavigationNestedMobile.svelte +70 -0
- package/dist/components/layout/service-navigation-nested-mobile/ServiceNavigationNestedMobile.svelte.d.ts +11 -0
- package/dist/components/layout/service-navigation-nested-mobile/SideNav.svelte +276 -0
- package/dist/components/layout/service-navigation-nested-mobile/SideNav.svelte.d.ts +22 -0
- package/dist/components/ui/Accordion.svelte +244 -0
- package/dist/components/ui/Accordion.svelte.d.ts +23 -0
- package/dist/components/ui/Breadcrumbs.svelte +198 -0
- package/dist/components/ui/Breadcrumbs.svelte.d.ts +24 -0
- package/dist/components/ui/Button.svelte +96 -0
- package/dist/components/ui/Button.svelte.d.ts +17 -0
- package/dist/components/ui/CheckBox.svelte +198 -0
- package/dist/components/ui/CheckBox.svelte.d.ts +27 -0
- package/dist/components/ui/ContentsList.svelte +1117 -0
- package/dist/components/ui/ContentsList.svelte.d.ts +25 -0
- package/dist/components/ui/DateInput.svelte +255 -0
- package/dist/components/ui/DateInput.svelte.d.ts +59 -0
- package/dist/components/ui/Details.svelte +12 -0
- package/dist/components/ui/Details.svelte.d.ts +13 -0
- package/dist/components/ui/FilterPanel.svelte +588 -0
- package/dist/components/ui/FilterPanel.svelte.d.ts +74 -0
- package/dist/components/ui/Footer.svelte +171 -0
- package/dist/components/ui/Footer.svelte.d.ts +30 -0
- package/dist/components/ui/Header.svelte +43 -0
- package/dist/components/ui/Header.svelte.d.ts +7 -0
- package/dist/components/ui/Masthead.svelte +267 -0
- package/dist/components/ui/Masthead.svelte.d.ts +12 -0
- package/dist/components/ui/NavigationExample.svelte +117 -0
- package/dist/components/ui/NavigationExample.svelte.d.ts +3 -0
- package/dist/components/ui/NotificationBanner.svelte +93 -0
- package/dist/components/ui/NotificationBanner.svelte.d.ts +15 -0
- package/dist/components/ui/Radios.svelte +176 -0
- package/dist/components/ui/Radios.svelte.d.ts +28 -0
- package/dist/components/ui/RelatedContent.svelte +596 -0
- package/dist/components/ui/RelatedContent.svelte.d.ts +29 -0
- package/dist/components/ui/Search.svelte +499 -0
- package/dist/components/ui/Search.svelte.d.ts +32 -0
- package/dist/components/ui/SearchAutocomplete.svelte +655 -0
- package/dist/components/ui/SearchAutocomplete.svelte.d.ts +37 -0
- package/dist/components/ui/Select.svelte +116 -0
- package/dist/components/ui/Select.svelte.d.ts +22 -0
- package/dist/components/ui/ServiceNavigation.svelte +143 -0
- package/dist/components/ui/ServiceNavigation.svelte.d.ts +13 -0
- package/dist/components/ui/SideNavigation.svelte +346 -0
- package/dist/components/ui/SideNavigation.svelte.d.ts +25 -0
- package/dist/components/ui/Tabs.svelte +306 -0
- package/dist/components/ui/Tabs.svelte.d.ts +18 -0
- package/dist/components/ui/WhatsNew.svelte +155 -0
- package/dist/components/ui/WhatsNew.svelte.d.ts +29 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.js +44 -0
- package/dist/icons/DoubleChevronButton.svelte +62 -0
- package/dist/icons/DoubleChevronButton.svelte.d.ts +13 -0
- package/dist/icons/IconSearch.svelte +42 -0
- package/dist/icons/IconSearch.svelte.d.ts +6 -0
- package/dist/icons/SingleChevronButtonWithLabel.svelte +132 -0
- package/dist/icons/SingleChevronButtonWithLabel.svelte.d.ts +19 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +45 -0
- package/dist/main.css +1 -0
- package/dist/package-wrapping/BaseInformation.svelte +82 -0
- package/dist/package-wrapping/BaseInformation.svelte.d.ts +15 -0
- package/dist/package-wrapping/BaseNameAndStatus.svelte +108 -0
- package/dist/package-wrapping/BaseNameAndStatus.svelte.d.ts +10 -0
- package/dist/package-wrapping/CodeBlock.svelte +62 -0
- package/dist/package-wrapping/CodeBlock.svelte.d.ts +12 -0
- package/dist/package-wrapping/ComponentDemo.svelte +114 -0
- package/dist/package-wrapping/ComponentDemo.svelte.d.ts +25 -0
- package/dist/package-wrapping/ComponentDemoTEMP.svelte +305 -0
- package/dist/package-wrapping/ComponentDemoTEMP.svelte.d.ts +21 -0
- package/dist/package-wrapping/ComponentDetails.svelte +123 -0
- package/dist/package-wrapping/ComponentDetails.svelte.d.ts +13 -0
- package/dist/package-wrapping/DividerLine.svelte +21 -0
- package/dist/package-wrapping/DividerLine.svelte.d.ts +17 -0
- package/dist/package-wrapping/InputForParameter.svelte +205 -0
- package/dist/package-wrapping/InputForParameter.svelte.d.ts +13 -0
- package/dist/package-wrapping/InputForParameterUpdated.svelte +222 -0
- package/dist/package-wrapping/InputForParameterUpdated.svelte.d.ts +17 -0
- package/dist/package-wrapping/InputForParameterUpdatedTEMP.svelte +203 -0
- package/dist/package-wrapping/InputForParameterUpdatedTEMP.svelte.d.ts +17 -0
- package/dist/package-wrapping/ListOfComponentStatuses.svelte +19 -0
- package/dist/package-wrapping/ListOfComponentStatuses.svelte.d.ts +11 -0
- package/dist/package-wrapping/OverlayAndComponentContainer.svelte +426 -0
- package/dist/package-wrapping/OverlayAndComponentContainer.svelte.d.ts +33 -0
- package/dist/package-wrapping/ParametersSection.svelte +235 -0
- package/dist/package-wrapping/ParametersSection.svelte.d.ts +19 -0
- package/dist/package-wrapping/ParsingErrorToastsContainer.svelte +50 -0
- package/dist/package-wrapping/ParsingErrorToastsContainer.svelte.d.ts +15 -0
- package/dist/package-wrapping/Pill.svelte +54 -0
- package/dist/package-wrapping/Pill.svelte.d.ts +25 -0
- package/dist/package-wrapping/PlaygroundDetails.svelte +106 -0
- package/dist/package-wrapping/PlaygroundDetails.svelte.d.ts +13 -0
- package/dist/package-wrapping/ScreenSizeRadio.svelte +24 -0
- package/dist/package-wrapping/ScreenSizeRadio.svelte.d.ts +11 -0
- package/dist/package-wrapping/ScreenSizeRadioUpdated.svelte +23 -0
- package/dist/package-wrapping/ScreenSizeRadioUpdated.svelte.d.ts +11 -0
- package/dist/package-wrapping/SidebarContainer.svelte +103 -0
- package/dist/package-wrapping/SidebarContainer.svelte.d.ts +23 -0
- package/dist/package-wrapping/WrapperDetailsUpdate.svelte +40 -0
- package/dist/package-wrapping/WrapperDetailsUpdate.svelte.d.ts +15 -0
- package/dist/package-wrapping/templates/Template.svelte +100 -0
- package/dist/package-wrapping/templates/Template.svelte.d.ts +25 -0
- package/dist/templates/ComponentPageTemplate.svelte +1 -0
- package/dist/templates/ComponentPageTemplate.svelte.d.ts +26 -0
- package/dist/utils/data-transformations/convertCSV.d.ts +2 -0
- package/dist/utils/data-transformations/convertCSV.js +22 -0
- package/dist/utils/data-transformations/getValueFromParametersArray.d.ts +1 -0
- package/dist/utils/data-transformations/getValueFromParametersArray.js +9 -0
- package/dist/utils/layoutNavHelpers.d.ts +70 -0
- package/dist/utils/layoutNavHelpers.js +129 -0
- package/dist/utils/package-wrapping-specific/addIndexAndInitialValue.d.ts +1 -0
- package/dist/utils/package-wrapping-specific/addIndexAndInitialValue.js +21 -0
- package/dist/utils/package-wrapping-specific/createBindableParametersValuesArray.d.ts +1 -0
- package/dist/utils/package-wrapping-specific/createBindableParametersValuesArray.js +12 -0
- package/dist/utils/package-wrapping-specific/createParametersObject.d.ts +1 -0
- package/dist/utils/package-wrapping-specific/createParametersObject.js +29 -0
- package/dist/utils/package-wrapping-specific/defineDefaultEventHandler.d.ts +1 -0
- package/dist/utils/package-wrapping-specific/defineDefaultEventHandler.js +14 -0
- package/dist/utils/package-wrapping-specific/trackVisibleParameters.d.ts +1 -0
- package/dist/utils/package-wrapping-specific/trackVisibleParameters.js +29 -0
- package/dist/utils/syntax-highlighting/shikiHighlight.d.ts +7 -0
- package/dist/utils/syntax-highlighting/shikiHighlight.js +76 -0
- package/dist/utils/text-string-conversion/textStringConversion.d.ts +9 -0
- package/dist/utils/text-string-conversion/textStringConversion.js +86 -0
- package/package.json +113 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { replaceState } from "$app/navigation";
|
|
4
|
+
import type { SvelteComponent, Snippet } from "svelte";
|
|
5
|
+
import DOMPurify from "dompurify";
|
|
6
|
+
|
|
7
|
+
// Define Tab type
|
|
8
|
+
export type TabItem = {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
content: string | typeof SvelteComponent | Snippet;
|
|
12
|
+
contentIsHtml?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Component props
|
|
16
|
+
let {
|
|
17
|
+
title = "Contents",
|
|
18
|
+
tabs = [],
|
|
19
|
+
idPrefix = "tab",
|
|
20
|
+
selectedTabId = $bindable(),
|
|
21
|
+
autoAddHeadings = true,
|
|
22
|
+
} = $props<{
|
|
23
|
+
title?: string;
|
|
24
|
+
tabs: TabItem[];
|
|
25
|
+
idPrefix?: string;
|
|
26
|
+
selectedTabId?: string | null;
|
|
27
|
+
autoAddHeadings?: boolean;
|
|
28
|
+
}>();
|
|
29
|
+
|
|
30
|
+
// Component state variables
|
|
31
|
+
let isInitialized = $state(false);
|
|
32
|
+
let isSupported = $state(false);
|
|
33
|
+
let isMobile = $state(false);
|
|
34
|
+
|
|
35
|
+
// DOM element references for programmatic focus
|
|
36
|
+
let tabElements: { [key: string]: HTMLAnchorElement } = {};
|
|
37
|
+
|
|
38
|
+
// Track media query for responsive behavior
|
|
39
|
+
let tabletMql: MediaQueryList | null = null;
|
|
40
|
+
|
|
41
|
+
// Handle tab selection - integrate focus and hash logic directly
|
|
42
|
+
function selectTab(tabId: string, shouldFocus = false): void {
|
|
43
|
+
// Skip if component isn't ready, or tab is already selected
|
|
44
|
+
if (!isSupported || !isInitialized || selectedTabId === tabId) return;
|
|
45
|
+
|
|
46
|
+
// Update the core bindable state
|
|
47
|
+
selectedTabId = tabId;
|
|
48
|
+
|
|
49
|
+
// Handle optional focus
|
|
50
|
+
if (shouldFocus && tabElements[tabId]) {
|
|
51
|
+
// Use setTimeout to defer focus until after Svelte updates the DOM (e.g., tabindex)
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
const tabElement = tabElements[tabId];
|
|
54
|
+
tabElement?.focus(); // Optional chaining for safety
|
|
55
|
+
}, 0);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Update URL hash on non-mobile views
|
|
59
|
+
if (!isMobile) {
|
|
60
|
+
// Use history.replaceState to update the displayed URL hash without causing scroll/navigation.
|
|
61
|
+
const currentUrl = window.location.href;
|
|
62
|
+
const hashIndex = currentUrl.indexOf("#");
|
|
63
|
+
const baseUrl =
|
|
64
|
+
hashIndex !== -1 ? currentUrl.slice(0, hashIndex) : currentUrl;
|
|
65
|
+
const newUrl = `${baseUrl}#${tabId}`;
|
|
66
|
+
replaceState(newUrl, {}); // Use SvelteKit's function
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Handle keyboard navigation
|
|
71
|
+
function handleKeydown(event: KeyboardEvent, currentIndex: number): void {
|
|
72
|
+
// Skip navigation on mobile or if component isn't ready
|
|
73
|
+
if (isMobile || !isSupported || !isInitialized) return;
|
|
74
|
+
|
|
75
|
+
// Initialize to null, indicating no valid navigation key pressed yet.
|
|
76
|
+
// Will be updated to a valid index (0+) if ArrowLeft/Right is pressed.
|
|
77
|
+
let newIndex: number | null = null;
|
|
78
|
+
const numTabs = tabs.length;
|
|
79
|
+
if (numTabs === 0) return; // Cannot navigate an empty list
|
|
80
|
+
|
|
81
|
+
// Define indices and conditions for readability
|
|
82
|
+
const isFirstTab = currentIndex === 0;
|
|
83
|
+
const isLastTab = currentIndex === numTabs - 1;
|
|
84
|
+
const previousIndex = currentIndex - 1;
|
|
85
|
+
const nextIndex = currentIndex + 1;
|
|
86
|
+
const firstIndex = 0;
|
|
87
|
+
const lastIndex = numTabs - 1;
|
|
88
|
+
|
|
89
|
+
if (event.key === "ArrowLeft" || event.key === "Left") {
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
// If it's the first tab, wrap to last, otherwise go to previous.
|
|
92
|
+
newIndex = isFirstTab ? lastIndex : previousIndex;
|
|
93
|
+
} else if (event.key === "ArrowRight" || event.key === "Right") {
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
// If it's the last tab, wrap to first, otherwise go to next.
|
|
96
|
+
newIndex = isLastTab ? firstIndex : nextIndex;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If a navigation key was pressed (newIndex is not null) and the index is valid
|
|
100
|
+
if (newIndex !== null && tabs[newIndex]) {
|
|
101
|
+
const targetTabId = tabs[newIndex].id;
|
|
102
|
+
// Pass true to ensure focus shifts to the new tab
|
|
103
|
+
selectTab(targetTabId, true);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Handle tab click
|
|
108
|
+
function handleTabClick(event: MouseEvent, tabId: string): void {
|
|
109
|
+
// On mobile or without JS support, let default browser behavior happen
|
|
110
|
+
if (isMobile || !isSupported) return;
|
|
111
|
+
event.preventDefault();
|
|
112
|
+
selectTab(tabId);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Handle hash change
|
|
116
|
+
function handleHashChange(): void {
|
|
117
|
+
// Skip on mobile or when not properly initialized
|
|
118
|
+
if (isMobile || !isSupported || !isInitialized) return;
|
|
119
|
+
|
|
120
|
+
const hash = window.location.hash.substring(1);
|
|
121
|
+
if (hash && tabs.some((tab) => tab.id === hash)) {
|
|
122
|
+
// Only select if the hash corresponds to a *different* tab
|
|
123
|
+
if (selectedTabId !== hash) {
|
|
124
|
+
// Focus the tab when navigating via hash change
|
|
125
|
+
selectTab(hash, true);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Initialize tabs on mount
|
|
131
|
+
onMount(() => {
|
|
132
|
+
isSupported =
|
|
133
|
+
document.body?.classList.contains("govuk-frontend-supported") ?? false;
|
|
134
|
+
|
|
135
|
+
// Check URL hash for deep linking AFTER initial prop value is set
|
|
136
|
+
const hash = window.location.hash.substring(1);
|
|
137
|
+
if (hash) {
|
|
138
|
+
const tabFromHash = tabs.find((tab) => tab.id === hash);
|
|
139
|
+
if (tabFromHash && tabFromHash.id !== selectedTabId) {
|
|
140
|
+
// Update state if hash points to a valid, different tab
|
|
141
|
+
// Use selectTab to handle focus and potential URL update if needed
|
|
142
|
+
selectTab(tabFromHash.id, true);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// If after hash check, no tab is selected AND we have tabs, select the first one.
|
|
147
|
+
// This handles the case where the initial prop value was null/invalid and no valid hash was present.
|
|
148
|
+
if (!selectedTabId && tabs.length > 0) {
|
|
149
|
+
selectedTabId = tabs[0].id;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Setup responsive behavior
|
|
153
|
+
if (window) {
|
|
154
|
+
const breakpoint = getBreakpoint();
|
|
155
|
+
if (breakpoint) {
|
|
156
|
+
tabletMql = window.matchMedia(`(min-width: ${breakpoint})`);
|
|
157
|
+
isMobile = !tabletMql.matches;
|
|
158
|
+
|
|
159
|
+
if ("addEventListener" in tabletMql) {
|
|
160
|
+
tabletMql.addEventListener("change", handleMediaChange);
|
|
161
|
+
} else {
|
|
162
|
+
// @ts-ignore - Deprecated fallback
|
|
163
|
+
tabletMql.addListener(handleMediaChange);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Listen for hash changes
|
|
169
|
+
window.addEventListener("hashchange", handleHashChange);
|
|
170
|
+
|
|
171
|
+
isInitialized = true;
|
|
172
|
+
|
|
173
|
+
// Cleanup
|
|
174
|
+
return () => {
|
|
175
|
+
if (tabletMql) {
|
|
176
|
+
if ("removeEventListener" in tabletMql) {
|
|
177
|
+
tabletMql.removeEventListener("change", handleMediaChange);
|
|
178
|
+
} else {
|
|
179
|
+
// @ts-ignore - Deprecated fallback
|
|
180
|
+
tabletMql.removeListener(handleMediaChange);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
window.removeEventListener("hashchange", handleHashChange);
|
|
184
|
+
|
|
185
|
+
// Clear tab element references to prevent memory leaks
|
|
186
|
+
Object.keys(tabElements).forEach((key) => {
|
|
187
|
+
delete tabElements[key];
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Handle media query changes
|
|
193
|
+
function handleMediaChange(
|
|
194
|
+
event: MediaQueryListEvent | MediaQueryList,
|
|
195
|
+
): void {
|
|
196
|
+
// Handle both modern and deprecated event/object types
|
|
197
|
+
isMobile = !event.matches;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Get breakpoint from CSS custom property
|
|
201
|
+
function getBreakpoint(): string | null {
|
|
202
|
+
if (typeof window === "undefined") return null; // Guard for SSR
|
|
203
|
+
const property = `--govuk-frontend-breakpoint-tablet`;
|
|
204
|
+
const value = window
|
|
205
|
+
.getComputedStyle(document.documentElement)
|
|
206
|
+
.getPropertyValue(property);
|
|
207
|
+
return value ? value.trim() : null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Effect to ensure valid tab selection if tabs array changes externally
|
|
211
|
+
$effect(() => {
|
|
212
|
+
// Run this effect whenever isInitialized or tabs changes
|
|
213
|
+
// Check if the currently selected tab ID still exists in the updated tabs array
|
|
214
|
+
if (
|
|
215
|
+
isInitialized &&
|
|
216
|
+
selectedTabId && // Only run if a tab is actually selected
|
|
217
|
+
!tabs.some((tab) => tab.id === selectedTabId)
|
|
218
|
+
) {
|
|
219
|
+
// If selected tab ID is no longer valid, default to the first available tab
|
|
220
|
+
console.log(
|
|
221
|
+
`Effect: selectedTabId '${selectedTabId}' no longer valid. Resetting.`,
|
|
222
|
+
); // Optional Debug
|
|
223
|
+
selectedTabId = tabs[0]?.id ?? null; // Use optional chaining and nullish coalescing
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
</script>
|
|
227
|
+
|
|
228
|
+
<div class="govuk-tabs" data-module="govuk-tabs">
|
|
229
|
+
<h2 class="govuk-tabs__title">
|
|
230
|
+
{title}
|
|
231
|
+
</h2>
|
|
232
|
+
|
|
233
|
+
<ul
|
|
234
|
+
class="govuk-tabs__list"
|
|
235
|
+
role={isSupported && !isMobile ? "tablist" : null}
|
|
236
|
+
>
|
|
237
|
+
{#each tabs as tab, index}
|
|
238
|
+
{@const isSelected = selectedTabId === tab.id}
|
|
239
|
+
{#key tab.id}
|
|
240
|
+
<li
|
|
241
|
+
class="govuk-tabs__list-item"
|
|
242
|
+
class:govuk-tabs__list-item--selected={isSelected && !isMobile}
|
|
243
|
+
role={isSupported && !isMobile ? "presentation" : null}
|
|
244
|
+
>
|
|
245
|
+
<!-- svelte-ignore binding_property_non_reactive -->
|
|
246
|
+
<a
|
|
247
|
+
class="govuk-tabs__tab"
|
|
248
|
+
href={"#" + tab.id}
|
|
249
|
+
id={isSupported && !isMobile ? `${idPrefix}_${tab.id}` : null}
|
|
250
|
+
role={isSupported && !isMobile ? "tab" : null}
|
|
251
|
+
aria-controls={isSupported && !isMobile ? tab.id : null}
|
|
252
|
+
aria-selected={isSupported && !isMobile ? isSelected : null}
|
|
253
|
+
tabindex={isSupported && !isMobile ? (isSelected ? 0 : -1) : null}
|
|
254
|
+
onclick={(e) => handleTabClick(e, tab.id)}
|
|
255
|
+
onkeydown={(e) => handleKeydown(e, index)}
|
|
256
|
+
bind:this={tabElements[tab.id]}
|
|
257
|
+
>
|
|
258
|
+
{tab.label}
|
|
259
|
+
</a>
|
|
260
|
+
</li>
|
|
261
|
+
{/key}
|
|
262
|
+
{/each}
|
|
263
|
+
</ul>
|
|
264
|
+
|
|
265
|
+
{#each tabs as tab}
|
|
266
|
+
{@const isSelected = selectedTabId === tab.id}
|
|
267
|
+
<div
|
|
268
|
+
class="govuk-tabs__panel"
|
|
269
|
+
class:govuk-tabs__panel--hidden={!isSelected && isSupported && !isMobile}
|
|
270
|
+
id={tab.id}
|
|
271
|
+
role={isSupported && !isMobile ? "tabpanel" : null}
|
|
272
|
+
aria-labelledby={isSupported && !isMobile
|
|
273
|
+
? `${idPrefix}_${tab.id}`
|
|
274
|
+
: null}
|
|
275
|
+
hidden={!isSelected && isSupported && !isMobile}
|
|
276
|
+
>
|
|
277
|
+
{#if autoAddHeadings}
|
|
278
|
+
<h2 class="govuk-heading-l">{tab.label}</h2>
|
|
279
|
+
{/if}
|
|
280
|
+
|
|
281
|
+
{#if typeof tab.content === "string"}
|
|
282
|
+
{#if tab.contentIsHtml}
|
|
283
|
+
{@html DOMPurify.sanitize(tab.content)}
|
|
284
|
+
{:else}
|
|
285
|
+
<p class="govuk-body">{tab.content}</p>
|
|
286
|
+
{/if}
|
|
287
|
+
{:else if tab.content satisfies Snippet}
|
|
288
|
+
{@render tab.content()}
|
|
289
|
+
{:else if tab.content}
|
|
290
|
+
<svelte:component this={tab.content} />
|
|
291
|
+
{/if}
|
|
292
|
+
</div>
|
|
293
|
+
{/each}
|
|
294
|
+
</div>
|
|
295
|
+
|
|
296
|
+
<style>
|
|
297
|
+
/* Override components.css tab panel style adding top margin to tab panels */
|
|
298
|
+
.govuk-tabs__panel[role="tabpanel"] {
|
|
299
|
+
margin-top: 0;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* Ensure hidden panels are truly hidden */
|
|
303
|
+
.govuk-tabs__panel--hidden {
|
|
304
|
+
display: none;
|
|
305
|
+
}
|
|
306
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
export type TabItem = {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
content: string | typeof SvelteComponent | Snippet;
|
|
7
|
+
contentIsHtml?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type $$ComponentProps = {
|
|
10
|
+
title?: string;
|
|
11
|
+
tabs: TabItem[];
|
|
12
|
+
idPrefix?: string;
|
|
13
|
+
selectedTabId?: string | null;
|
|
14
|
+
autoAddHeadings?: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare const Tabs: import("svelte").Component<$$ComponentProps, {}, "selectedTabId">;
|
|
17
|
+
type Tabs = ReturnType<typeof Tabs>;
|
|
18
|
+
export default Tabs;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Represents a single news item in the What's New section
|
|
4
|
+
*/
|
|
5
|
+
interface NewsItem {
|
|
6
|
+
/** The date of the news item (e.g., "June 2025") */
|
|
7
|
+
date: string;
|
|
8
|
+
/** The main content/description of the news item */
|
|
9
|
+
content: string;
|
|
10
|
+
/** Optional URL to release notes or more information */
|
|
11
|
+
releaseNotesUrl?: string;
|
|
12
|
+
/** Optional version number for releases (e.g., "v0.1.16") */
|
|
13
|
+
releaseVersion?: string;
|
|
14
|
+
/** Optional array of component links to display as a bulleted list */
|
|
15
|
+
componentLinks?: Array<{
|
|
16
|
+
/** Display text for the link */
|
|
17
|
+
text: string;
|
|
18
|
+
/** URL/href for the link */
|
|
19
|
+
href: string;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* WhatsNew Component
|
|
25
|
+
*
|
|
26
|
+
* A flexible component for displaying news, updates, and release information.
|
|
27
|
+
* Commonly used on homepages or documentation sites to communicate recent changes,
|
|
28
|
+
* new features, or important announcements to users.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```svelte
|
|
32
|
+
* <!-- Basic usage with defaults -->
|
|
33
|
+
* <WhatsNew />
|
|
34
|
+
*
|
|
35
|
+
* <!-- Custom usage -->
|
|
36
|
+
* <WhatsNew
|
|
37
|
+
* title="Latest Updates"
|
|
38
|
+
* titleId="updates"
|
|
39
|
+
* componentLinksIntroText="New components available:"
|
|
40
|
+
* newsItems={[
|
|
41
|
+
* {
|
|
42
|
+
* date: "June 2025",
|
|
43
|
+
* content: "Released new component library",
|
|
44
|
+
* releaseNotesUrl: "https://github.com/example/releases/tag/v1.0.0",
|
|
45
|
+
* releaseVersion: "v1.0.0",
|
|
46
|
+
* componentLinks: [
|
|
47
|
+
* { text: "Button component", href: "/components/button" }
|
|
48
|
+
* ]
|
|
49
|
+
* }
|
|
50
|
+
* ]}
|
|
51
|
+
* />
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
// Define component props with types and default values
|
|
56
|
+
let {
|
|
57
|
+
/** The main heading text for the news section */
|
|
58
|
+
title = "What's new",
|
|
59
|
+
/** The HTML id attribute for the heading element (useful for anchor links) */
|
|
60
|
+
titleId = "whats-new",
|
|
61
|
+
/**
|
|
62
|
+
* Introductory text that appears before component links lists.
|
|
63
|
+
* Set to empty string to hide this text entirely.
|
|
64
|
+
*/
|
|
65
|
+
componentLinksIntroText = "This the first step to refresh the GOV.UK brand. It includes updates to the:",
|
|
66
|
+
/**
|
|
67
|
+
* Array of news items to display. Each item can include:
|
|
68
|
+
* - date: When the news occurred
|
|
69
|
+
* - content: Main description
|
|
70
|
+
* - releaseNotesUrl & releaseVersion: For linking to release notes
|
|
71
|
+
* - componentLinks: For displaying related component links
|
|
72
|
+
*/
|
|
73
|
+
newsItems = [
|
|
74
|
+
{
|
|
75
|
+
date: "15 May 2025",
|
|
76
|
+
content:
|
|
77
|
+
"We released GOV.UK Frontend v5.10.1 with the correct colour for the dot in the refreshed GOV.UK logo, as well as small fixes to the implementation of the brand refresh.",
|
|
78
|
+
releaseNotesUrl:
|
|
79
|
+
"https://github.com/alphagov/govuk-frontend/releases/tag/v5.10.1",
|
|
80
|
+
releaseVersion: "v5.10.1",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
date: "1 May 2025",
|
|
84
|
+
content: "We released GOV.UK Frontend v5.10.0.",
|
|
85
|
+
releaseNotesUrl:
|
|
86
|
+
"https://github.com/alphagov/govuk-frontend/releases/tag/v5.10.0",
|
|
87
|
+
releaseVersion: "v5.10.0",
|
|
88
|
+
componentLinks: [
|
|
89
|
+
{ text: "GOV.UK header component", href: "/components/header/" },
|
|
90
|
+
{ text: "GOV.UK footer component", href: "/components/footer/" },
|
|
91
|
+
{
|
|
92
|
+
text: "Service navigation component",
|
|
93
|
+
href: "/components/service-navigation/",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
text: "Cookie banner component",
|
|
97
|
+
href: "/components/cookie-banner/",
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
] as NewsItem[],
|
|
102
|
+
} = $props<{
|
|
103
|
+
title?: string;
|
|
104
|
+
titleId?: string;
|
|
105
|
+
componentLinksIntroText?: string;
|
|
106
|
+
newsItems?: NewsItem[];
|
|
107
|
+
}>();
|
|
108
|
+
</script>
|
|
109
|
+
|
|
110
|
+
<div class="app-whats-new">
|
|
111
|
+
<div class="govuk-width-container">
|
|
112
|
+
<div class="govuk-main-wrapper govuk-main-wrapper--l">
|
|
113
|
+
<div class="govuk-grid-row">
|
|
114
|
+
<div class="govuk-grid-column-two-thirds-from-desktop">
|
|
115
|
+
<h2 id={titleId} class="govuk-heading-l">{title}</h2>
|
|
116
|
+
|
|
117
|
+
{#each newsItems as item, index}
|
|
118
|
+
<p class="govuk-body">
|
|
119
|
+
<strong>{item.date}:</strong>
|
|
120
|
+
{item.content}
|
|
121
|
+
</p>
|
|
122
|
+
|
|
123
|
+
{#if item.releaseNotesUrl && item.releaseVersion}
|
|
124
|
+
<p class="govuk-body">
|
|
125
|
+
Read the <a href={item.releaseNotesUrl} class="govuk-link"
|
|
126
|
+
>release notes for {item.releaseVersion}</a
|
|
127
|
+
> to see what's changed.
|
|
128
|
+
</p>
|
|
129
|
+
{/if}
|
|
130
|
+
|
|
131
|
+
{#if item.componentLinks && item.componentLinks.length > 0}
|
|
132
|
+
<p class="govuk-body">
|
|
133
|
+
{componentLinksIntroText}
|
|
134
|
+
</p>
|
|
135
|
+
<ul class="govuk-list govuk-list--bullet">
|
|
136
|
+
{#each item.componentLinks as link}
|
|
137
|
+
<li>
|
|
138
|
+
<a href={link.href} class="govuk-link">{link.text}</a>
|
|
139
|
+
</li>
|
|
140
|
+
{/each}
|
|
141
|
+
</ul>
|
|
142
|
+
{/if}
|
|
143
|
+
{/each}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<style>
|
|
151
|
+
.app-whats-new {
|
|
152
|
+
border-bottom: 1px solid #b1b4b6;
|
|
153
|
+
background-color: #f8f8f8;
|
|
154
|
+
}
|
|
155
|
+
</style>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a single news item in the What's New section
|
|
3
|
+
*/
|
|
4
|
+
interface NewsItem {
|
|
5
|
+
/** The date of the news item (e.g., "June 2025") */
|
|
6
|
+
date: string;
|
|
7
|
+
/** The main content/description of the news item */
|
|
8
|
+
content: string;
|
|
9
|
+
/** Optional URL to release notes or more information */
|
|
10
|
+
releaseNotesUrl?: string;
|
|
11
|
+
/** Optional version number for releases (e.g., "v0.1.16") */
|
|
12
|
+
releaseVersion?: string;
|
|
13
|
+
/** Optional array of component links to display as a bulleted list */
|
|
14
|
+
componentLinks?: Array<{
|
|
15
|
+
/** Display text for the link */
|
|
16
|
+
text: string;
|
|
17
|
+
/** URL/href for the link */
|
|
18
|
+
href: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
type $$ComponentProps = {
|
|
22
|
+
title?: string;
|
|
23
|
+
titleId?: string;
|
|
24
|
+
componentLinksIntroText?: string;
|
|
25
|
+
newsItems?: NewsItem[];
|
|
26
|
+
};
|
|
27
|
+
declare const WhatsNew: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
28
|
+
type WhatsNew = ReturnType<typeof WhatsNew>;
|
|
29
|
+
export default WhatsNew;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const foldersLookup: {
|
|
2
|
+
ui: string;
|
|
3
|
+
"data-vis": string;
|
|
4
|
+
};
|
|
5
|
+
export const componentStatusProgressBackgroundColorLookup: {
|
|
6
|
+
"To be developed": string;
|
|
7
|
+
"In progress": string;
|
|
8
|
+
"Baseline completed": string;
|
|
9
|
+
"In use": string;
|
|
10
|
+
};
|
|
11
|
+
export const componentStausLookup: {};
|
|
12
|
+
export namespace propPillLookup {
|
|
13
|
+
export namespace _true {
|
|
14
|
+
let size: string;
|
|
15
|
+
let text: string;
|
|
16
|
+
let textColor: string;
|
|
17
|
+
let bgColor: string;
|
|
18
|
+
let padding: string;
|
|
19
|
+
}
|
|
20
|
+
export { _true as true };
|
|
21
|
+
export namespace bindable {
|
|
22
|
+
let size_1: string;
|
|
23
|
+
export { size_1 as size };
|
|
24
|
+
let text_1: string;
|
|
25
|
+
export { text_1 as text };
|
|
26
|
+
let textColor_1: string;
|
|
27
|
+
export { textColor_1 as textColor };
|
|
28
|
+
let bgColor_1: string;
|
|
29
|
+
export { bgColor_1 as bgColor };
|
|
30
|
+
let padding_1: string;
|
|
31
|
+
export { padding_1 as padding };
|
|
32
|
+
}
|
|
33
|
+
export namespace _false {
|
|
34
|
+
let text_2: string;
|
|
35
|
+
export { text_2 as text };
|
|
36
|
+
let textColor_2: string;
|
|
37
|
+
export { textColor_2 as textColor };
|
|
38
|
+
let bgColor_2: string;
|
|
39
|
+
export { bgColor_2 as bgColor };
|
|
40
|
+
let padding_2: string;
|
|
41
|
+
export { padding_2 as padding };
|
|
42
|
+
}
|
|
43
|
+
export { _false as false };
|
|
44
|
+
}
|
|
45
|
+
export namespace defaultScreenWidthBreakpoints {
|
|
46
|
+
let xs: number;
|
|
47
|
+
let sm: number;
|
|
48
|
+
let md: number;
|
|
49
|
+
let lg: number;
|
|
50
|
+
let xl: number;
|
|
51
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const foldersLookup = {
|
|
2
|
+
ui: "user interaction",
|
|
3
|
+
"data-vis": "data visualisation",
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const componentStatusProgressBackgroundColorLookup = {
|
|
7
|
+
"To be developed": "#b53c17",
|
|
8
|
+
"In progress": "#542059",
|
|
9
|
+
"Baseline completed": "#5C53A2",
|
|
10
|
+
"In use": "#136F63",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const componentStausLookup = {};
|
|
14
|
+
|
|
15
|
+
export const propPillLookup = {
|
|
16
|
+
true: {
|
|
17
|
+
size: "xs",
|
|
18
|
+
text: "{p}",
|
|
19
|
+
textColor: "white",
|
|
20
|
+
bgColor: "#ba029b",
|
|
21
|
+
padding: "0.4rem 0.32rem 0.5rem 0.3rem",
|
|
22
|
+
},
|
|
23
|
+
bindable: {
|
|
24
|
+
size: "xs",
|
|
25
|
+
text: "{b}",
|
|
26
|
+
textColor: "white",
|
|
27
|
+
bgColor: "#1B4079",
|
|
28
|
+
padding: "0.4rem 0.32rem 0.5rem 0.3rem",
|
|
29
|
+
},
|
|
30
|
+
false: {
|
|
31
|
+
text: "=>",
|
|
32
|
+
textColor: "white",
|
|
33
|
+
bgColor: "#00695c",
|
|
34
|
+
padding: "0.1rem 0.15rem",
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const defaultScreenWidthBreakpoints = {
|
|
39
|
+
xs: 420,
|
|
40
|
+
sm: 640,
|
|
41
|
+
md: 768,
|
|
42
|
+
lg: 1024,
|
|
43
|
+
xl: 1280,
|
|
44
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let { open = $bindable(), onClickFunction } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<button onclick={onClickFunction}>
|
|
6
|
+
<svg width="30" height="30">
|
|
7
|
+
{#each [8, 16] as xPos}
|
|
8
|
+
<g
|
|
9
|
+
transform="translate({xPos + (open ? 6 : 0)},15)rotate({open
|
|
10
|
+
? 45
|
|
11
|
+
: -135})"
|
|
12
|
+
>
|
|
13
|
+
{#each [-5, 5] as cxcy}
|
|
14
|
+
<circle cx={cxcy} cy={cxcy}></circle>
|
|
15
|
+
{/each}
|
|
16
|
+
<path d="M -5 -5 l0 9.75 m0.25 0.25 l9.75 0"></path>
|
|
17
|
+
<rect transform="translate(-6, 4)" width="2" height="2" rx="4px"></rect>
|
|
18
|
+
</g>
|
|
19
|
+
{/each}
|
|
20
|
+
</svg>
|
|
21
|
+
</button>
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
svg {
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
transition: background-color 0.3s ease;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
svg:hover {
|
|
30
|
+
border-radius: 3px;
|
|
31
|
+
background-color: #f3f3f3;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
path {
|
|
35
|
+
stroke: #6b7280;
|
|
36
|
+
fill: none;
|
|
37
|
+
stroke-width: 2px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
svg:hover path {
|
|
41
|
+
stroke: #4b5563;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
circle {
|
|
45
|
+
fill: #6b7280;
|
|
46
|
+
stroke: none;
|
|
47
|
+
r: 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
svg:hover circle {
|
|
51
|
+
fill: #4b5563;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
rect {
|
|
55
|
+
stroke: none;
|
|
56
|
+
fill: #6b7280;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
svg:hover rect {
|
|
60
|
+
fill: #4b5563;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default DoubleChevronButton;
|
|
2
|
+
type DoubleChevronButton = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const DoubleChevronButton: import("svelte").Component<{
|
|
7
|
+
open?: any;
|
|
8
|
+
onClickFunction: any;
|
|
9
|
+
}, {}, "open">;
|
|
10
|
+
type $$ComponentProps = {
|
|
11
|
+
open?: any;
|
|
12
|
+
onClickFunction: any;
|
|
13
|
+
};
|