Skip to content

Commit 2d24a9b

Browse files
authored
Merge pull request #46 from fipguide/feat/sprungmarken
Feat/sprungmarken
2 parents 7b214a6 + 47f82bb commit 2d24a9b

File tree

13 files changed

+134
-9
lines changed

13 files changed

+134
-9
lines changed

assets/js/anchorlinks.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
function initAnchorlinkEventListener() {
2+
3+
const anchorLinks = document.querySelectorAll(".a-anchorlink__link");
4+
const snackbar = document.getElementById('snackbar');
5+
const snackbarButton = document.getElementById('snackbar-button');
6+
7+
anchorLinks.forEach((element) => {
8+
9+
element.addEventListener('click', () => {
10+
navigator.clipboard.writeText(element.href).then(() => {
11+
showSnackbar();
12+
}).catch(err => {
13+
console.error("Fehler beim Kopieren des Textes:", err);
14+
});
15+
});
16+
});
17+
18+
snackbarButton.addEventListener('click', () => {
19+
closeSnackbar();
20+
});
21+
}
22+
23+
function showSnackbar() {
24+
snackbar.setAttribute('aria-hidden', 'false');
25+
snackbar.classList.add('a-snackbar--show');
26+
27+
setTimeout(closeSnackbar, 5000);
28+
}
29+
30+
function closeSnackbar() {
31+
snackbar.setAttribute('aria-hidden', 'true');
32+
snackbar.classList.remove('a-snackbar--show');
33+
}
34+
35+
if (document.readyState === "interactive") {
36+
if (document.querySelectorAll(".a-anchorlink__link").length) {
37+
initAnchorlinkEventListener();
38+
}
39+
} else {
40+
window.addEventListener("DOMContentLoaded", () => {
41+
if (document.querySelectorAll(".a-anchorlink__link").length) {
42+
initAnchorlinkEventListener();
43+
}
44+
});
45+
}

assets/js/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import './countrySelector.js';
33
import './resizeObserver.js';
44
import './mediaqueries.js';
55
import './highlightHeadline.js';
6+
import './anchorlinks.js';
67
//import './aside.js';

assets/js/mobileMenu.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as mq from './mediaqueries';
21
//import {initWindowOnClick} from './windowOnClickHandling';
32

43
function initMobileMenu() {
@@ -18,7 +17,7 @@ function initMobileMenu() {
1817
//const target = initWindowOnClick();
1918

2019
window.onclick = e => {
21-
console.log(e.target);
20+
//console.log(e.target);
2221
if (e.target.classList.contains('o-header__curtain')) {
2322
closeMobileMenu();
2423
}

assets/sass/anchorlink.scss

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
.a-anchorlink {
2+
display: flex;
3+
}
4+
5+
.a-anchorlink__link {
6+
display: inline-flex;
7+
width: 3.2rem;
8+
height: 3.2rem;
9+
align-items: center;
10+
justify-content: center;
11+
margin-left: .8rem;
12+
border-radius: var(--border-radius-s);
13+
opacity: .8;
14+
15+
&:hover,
16+
&:focus {
17+
background-color: var(--bg-neutral);
18+
opacity: 1;
19+
}
20+
}
21+
22+
.a-snackbar {
23+
position: fixed;
24+
bottom: 0;
25+
background-color: var(--bg-accent);
26+
color: var(--color-onLight);
27+
padding: 1.6rem;
28+
border-radius: var(--border-radius-s);
29+
opacity: 0;
30+
visibility: hidden;
31+
transform: translateY(2rem);
32+
transition: opacity 0.3s ease, transform 0.3s ease;
33+
display: flex;
34+
align-items: center;
35+
align-self: flex-start;
36+
margin: 1rem;
37+
text-wrap: balance;
38+
}
39+
40+
.a-snackbar--show {
41+
opacity: 1;
42+
visibility: visible;
43+
transform: translateY(0);
44+
}
45+
46+
.a-snackbar_button {
47+
background: none;
48+
border: none;
49+
color: inherit;
50+
cursor: pointer;
51+
margin-left: 1rem;
52+
padding: 0;
53+
width: 2.4rem;
54+
height: 2.4rem;
55+
display: flex;
56+
57+
svg {
58+
fill: var(--color-onLight);
59+
}
60+
}

assets/sass/main.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ $icon-remove: '{{(resources.Get "svg/default/remove.svg" | fingerprint "md5").Re
1515
@import "toc.scss";
1616
@import "headings.scss";
1717
@import "form.scss";
18-
@import "expander.scss";
18+
@import "expander.scss";
19+
@import "anchorlink.scss";

assets/sass/styles.scss

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ header {
1616

1717
a:not(.m-teaser) {
1818
color: var(--link-default);
19-
transition: fill 0.3s ease;
19+
transition: all 0.3s ease;
2020
text-underline-offset: .2rem;
2121

2222
&:hover,
@@ -178,7 +178,7 @@ section p:last-child {
178178
}
179179

180180
.o-single__header__title h1 {
181-
margin-bottom: 0rem;
181+
margin-bottom: 0;
182182
}
183183

184184
.o-single__header__title img {
@@ -202,5 +202,4 @@ section p:last-child {
202202
height: 2.4rem;
203203
opacity: 50%;
204204
}
205-
}
206-
205+
}

assets/svg/default/link.svg

+1
Loading

i18n/de.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ toc-backlink: Zurück zu
2727
editPage: Seite bearbeiten
2828
list-disclaimer: Momemtan sind noch nicht für alle Länder und Betreiber Informationen verfügbar. Den aktuellen Bearbeitungsstand findest du auf
2929
list-disclaimer-link: GitHub
30+
anchorLink:
31+
copy: Link zu diesem Abschnitt kopieren
32+
copied: Link wurde in die Zwischenablage kopiert
3033
meta-description:
3134
country: Überblick über die Länder, in denen FIP-Vergünstigungen genutzt werden können.
3235
operator: Überblick über die Betreiber, die FIP-Vergünstigungen anbieten.

i18n/en.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ toc-backlink: Back to
2727
editPage: Edit page
2828
list-disclaimer: Currently, information is not yet available for all countries and operators. You can see the current information status on
2929
list-disclaimer-link: GitHub
30+
anchorLink:
31+
copy: Copy link to this section
32+
copied: Link has been copied to the clipboard
3033
meta-description:
3134
country: Overview of the countries where FIP benefits are available.
3235
operator: Overview of the operators providing FIP benefits.

layouts/_default/baseof.html

+3
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@
1010
<header id="header" class="o-header">{{ partial "header.html" . }}</header>
1111
<main id="content">{{ block "main" . }}{{ end }}</main>
1212
<footer>{{ partial "footer.html" . }}</footer>
13+
{{ if and (eq .Kind "page") (or (eq .Page.Type "country") (eq .Page.Type "operator")) }}
14+
{{ partial "snackbar" . }}
15+
{{ end }}
1316
</body>
1417
</html>

layouts/country/single.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ <h1 data-pagefind-meta="title">{{ .Title }}</h1>
2121
</div>
2222

2323
<div class="content" data-pagefind-weight="2">
24-
{{ .Content }}
24+
{{- with .Content -}}
25+
{{ . | replaceRE "(<h[2] id=\"([^\"]+)\".+)(</h[2]+>)" (print `<span class="a-anchorlink">${1}${3}<a href="#${2}" class="a-anchorlink__link" title="` (T "anchorLink.copy") `">` (partial "ico" (dict "icon" "link")) `</a></span>`) | safeHTML }}
26+
{{- end -}}
2527
</div>
2628
</div>
2729
<div class="o-single__container">

layouts/operator/single.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ <h1 data-pagefind-meta="title">{{ .Title }}</h1>
1919
</div>
2020

2121
<div class="content" data-pagefind-weight="2.5">
22-
{{ .Content }}
22+
{{- with .Content -}}
23+
{{ . | replaceRE "(<h[2] id=\"([^\"]+)\".+)(</h[2]+>)" (print `<span class="a-anchorlink">${1}${3}<a href="#${2}" class="a-anchorlink__link" title="` (T "copyAnchorLink") `">` (partial "ico" (dict "icon" "link")) `</a></span>`) | safeHTML }}
24+
{{- end -}}
2325
</div>
2426
</div>
2527
</div>

layouts/partials/snackbar.html

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<div id="snackbar" role="status" aria-live="polite" class="a-snackbar" aria-hidden="true">
2+
<span>{{ T "anchorLink.copied" }}</span>
3+
<button id="snackbar-button" title='{{ T "menu-close" }}' class="a-snackbar_button">
4+
{{ partial "ico" (dict "icon" "close" ) }}
5+
</button>
6+
</div>

0 commit comments

Comments
 (0)