Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8639720
feat: Add support for dialogs
MoritzWeber0 Feb 8, 2026
4dfaab2
fix: show dialog triggers as inline text
MoritzWeber0 Feb 8, 2026
ef23d16
feat: Also open dialog on enter key
MoritzWeber0 Feb 8, 2026
146546c
fix: z-index
MoritzWeber0 Feb 8, 2026
c0046e3
refactor: improve naming of classes
MoritzWeber0 Feb 8, 2026
79e1d3c
fix: rounded scrollbar corners
MoritzWeber0 Feb 8, 2026
0014b52
refactor: rename button classes
MoritzWeber0 Feb 8, 2026
c9f9a0c
feat: use dvh instead vh
MoritzWeber0 Feb 8, 2026
ea75e56
fix: Remove stena line dialog
MoritzWeber0 Feb 10, 2026
6e968d3
feat: Improve accessibility on dialog-trigger
MoritzWeber0 Feb 10, 2026
7fcbbc1
fix: Improve accessibility on dialog close button
MoritzWeber0 Feb 13, 2026
930dc73
feat: Make dialog header sticky
MoritzWeber0 Feb 13, 2026
46069eb
feat: Make icon margin in links more generic
MoritzWeber0 Feb 13, 2026
aea2d39
fix: Descrease margin top/bottom for dialog header
MoritzWeber0 Feb 13, 2026
9234929
fix: Increase headings in dialog
MoritzWeber0 Feb 13, 2026
c04e69e
fix: Move dialog close button to the right
MoritzWeber0 Feb 13, 2026
52ece10
refactor: Merge button and button-internal partial
MoritzWeber0 Feb 13, 2026
6a19bf9
fix: Remove event listener on dialog close
MoritzWeber0 Feb 13, 2026
1cda054
fix: Add additional checks for overlay close on resize
MoritzWeber0 Feb 14, 2026
5ce60dd
Merge branch 'main' into feat/add-dialogs
therobrob Feb 20, 2026
b22fc71
feat: Use modal dialog
MoritzWeber0 Feb 20, 2026
80df44c
fix: Disable scrolling when dialog is open
MoritzWeber0 Feb 21, 2026
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
7 changes: 4 additions & 3 deletions assets/js/contentNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const initAside = () => {
let isClosed = true;

const closeSheet = () => {
if (isClosed) return;

isClosed = true;
aside.classList.remove("o-aside--open");
asideContent.removeAttribute("role");
Expand Down Expand Up @@ -107,10 +109,9 @@ const initAside = () => {
wasMobile = true;
closeSheet();
}
if (!isMobile()) {
if (wasMobile && !isMobile()) {
wasMobile = false;
closeOverlay();
aside.classList.remove("o-aside--open");
closeSheet();
}
};

Expand Down
44 changes: 44 additions & 0 deletions assets/js/dialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function getCloseButton(dialog) {
return dialog.querySelector(".o-dialog__header > .a-button");
}

function openDialog(dialogId) {
const dialog = document.getElementById(dialogId);
if (!dialog) return;

dialog.showModal();
}

function initDialogs() {
document.querySelectorAll("dialog").forEach((dialog) => {
dialog.addEventListener("click", (e) => {
if (e.target === dialog) {
dialog.close();
}
});

const closeButton = getCloseButton(dialog);
if (closeButton) {
closeButton.addEventListener("click", () => dialog.close());
}
});

document.querySelectorAll("[data-dialog-trigger]").forEach((trigger) => {
const handler = (e) => {
if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) {
e.preventDefault();
const dialogId = trigger.getAttribute("data-dialog-trigger");
openDialog(dialogId);
}
};

trigger.addEventListener("click", handler);
trigger.addEventListener("keydown", handler);
});
}

if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initDialogs);
} else {
initDialogs();
}
1 change: 1 addition & 0 deletions assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ import "./dropdown.js";
import "./search.js";
import "./interactiveMap.js";
import "./expander.js";
import "./dialog.js";
2 changes: 2 additions & 0 deletions assets/js/mobileMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ function closeMobileMenu() {
const navContainer = document.querySelector(".o-header__nav");
const menuButton = document.querySelector(".o-nav__menu-button");

if (!navContainer.classList.contains("o-header__nav--open")) return;

navContainer.classList.remove("o-header__nav--open");
menuButton.setAttribute("aria-expanded", false);
closeOverlay();
Expand Down
9 changes: 8 additions & 1 deletion assets/sass/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
display: inline-flex;
align-items: center;
gap: 0.4rem;
border: 0.2rem solid var(--link-default);
border-radius: var(--border-radius-m);
font-size: 1.5rem;
cursor: pointer;
Expand All @@ -25,4 +24,12 @@
padding: 0.6rem;
display: block;
}

&__external {
border: 0.2rem solid var(--link-default);
}

&__internal {
border: none;
}
}
69 changes: 69 additions & 0 deletions assets/sass/dialog.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.o-dialog {
max-height: calc(100dvh - 14rem);
overflow: auto;
display: flex;
flex-direction: column;

.a-anchorlink {
margin-bottom: 0;

&__link {
display: none;
}

> h2 {
margin-bottom: 1rem;
}
}

.o-divider {
display: none;
}

&__wrapper {
width: fit-content;
border: none;
padding: 0;
background-color: var(--bg-default);
color: var(--color-body);
border-radius: var(--border-radius-m);
border: var(--border);
overflow: hidden;

&::backdrop {
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
}
}

&__header {
position: sticky;
top: 0;
background-color: var(--bg-default);
display: flex;
column-gap: 1rem;
align-items: center;
justify-content: space-between;
padding: 1rem 1rem 1rem 2rem;
border-bottom: var(--border);
border-color: var(--color-table-border);

.o-divider {
display: none;
}

> h1 {
margin: 0;
font-size: 2.2rem;
}
}

&__body {
padding: 2rem;
overflow: auto;

> *:last-child {
margin-bottom: 0;
}
}
}
8 changes: 7 additions & 1 deletion assets/sass/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@
z-index: 14;
}

body:has(.overlay--show) {
#header:has(.overlay--dialog),
.overlay--dialog {
z-index: 10;
}

body:has(.overlay--show),
body:has(dialog[open]) {
overflow: hidden;
}
1 change: 1 addition & 0 deletions assets/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
@import "tag.scss";
@import "floatImage.scss";
@import "teamMember.scss";
@import "dialog.scss";
9 changes: 8 additions & 1 deletion assets/sass/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@ button {
@include focus-indicator(0.2rem);
}

a {
a,
.o-link {
color: var(--link-default);
transition:
color 0.3s ease,
background-color 0.3s ease;
text-underline-offset: 0.2rem;
border-radius: var(--border-radius-s);
text-decoration: underline;
cursor: pointer;

&:hover,
&:focus {
Expand All @@ -80,6 +83,10 @@ a {
display: none;
}
}

& > .material-symbols-rounded {
margin: 0 0.2rem;
}
}

main {
Expand Down
2 changes: 1 addition & 1 deletion content/country/belgium/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Additionally, international [Eurostar](/operator/eurostar "Eurostar") trains ope
Furthermore, international `TGV` trains of the [SNCF](/operator/sncf "SNCF") from France operate, for which the FIP Coupon of SNCB are not valid. Only special FIP Global Fares can be booked for these trains. For the Eurocity trains from Brussels to Paris operated by OUIGO, no FIP discounts apply.

{{< identify-operator sources="db-website,vagonweb" >}}
Not all trains in the country (e. g. `ICE`) are shown in the [SNCB / NMBS online timetable](https://www.belgiantrain.be/en/).
Not all trains in the country (e.g. `ICE`) are shown in the [SNCB / NMBS online timetable](https://www.belgiantrain.be/en/).
{{< /identify-operator >}}

## Interesting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ params:
url: "https://www.renfe.com/es/en/suburban"
---

On the Renfe Cercanías website (suburban trains), you can search for train connections in any suburban train network. To do this, select the relevant region on the website and then click on _Timetables_. In suburban train networks with multiple operators (e. g. Barcelona), only Renfe trains are displayed.
On the Renfe Cercanías website (suburban trains), you can search for train connections in any suburban train network. To do this, select the relevant region on the website and then click on _Timetables_. In suburban train networks with multiple operators (e.g. Barcelona), only Renfe trains are displayed.
3 changes: 3 additions & 0 deletions i18n/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ country:
many: Länder
one: Land
other: Länder
dialog:
close: Schließen
open: Öffnet Dialog
discord: FIP Guide Community
donation: Spenden
editPage: Seite bearbeiten
Expand Down
3 changes: 3 additions & 0 deletions i18n/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ country:
many: countries
one: country
other: countries
dialog:
close: Close
open: Opens dialog
discord: FIP Guide Community
donation: Donate
editPage: Edit page
Expand Down
3 changes: 3 additions & 0 deletions i18n/fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ country:
one: pays
other: pays
countryselection: Choisir un pays
dialog:
close: Fermer
open: Ouvre le dialogue
discord: Communauté FIP Guide
donation: Donation
editPage: Modifier la page
Expand Down
1 change: 0 additions & 1 deletion layouts/partials/booking.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
{{- $content := partial "increase-headings" (dict "content" .page.Content "offset" 2) -}}
{{- $content := partial "prefix-footnotes" (dict "content" $content "prefix" .page.File.ContentBaseName) -}}
{{- $content := partial "prefix-heading-ids" (dict "content" $content "prefix" .page.File.ContentBaseName) -}}
{{- $content := partial "remove-newlines" $content -}}
{{- $content | safeHTML -}}
</div>

Expand Down
25 changes: 17 additions & 8 deletions layouts/partials/button.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
<a
href="{{ .Destination }}"
target="_blank"
rel="noopener noreferrer"
class="a-button o-link__external"
>
{{- .Text -}}{{- partial "icon" "arrow_outward" -}}
</a>
{{ if .Destination }}
<a
href="{{ .Destination }}"
target="_blank"
rel="noopener noreferrer"
class="a-button a-button__external o-link__external"
>
{{- .Text -}}{{- partial "icon" "arrow_outward" -}}
</a>
{{ else }}
<button
class="a-button a-button__internal"
{{- with .Title }}title="{{ . }}"{{- end -}}
>
{{- .Text -}}
</button>
{{ end }}
15 changes: 15 additions & 0 deletions layouts/partials/dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<dialog
id="{{ .ID }}"
class="o-dialog__wrapper"
aria-labelledby="{{ .ID }}-title"
>
<div class="o-dialog o-container">
<header class="o-dialog__header">
<h1 id="{{ .ID }}-title" class="o-dialog__title">{{ .Title }}</h1>
{{- partial "button" (dict "Text" (partial "icon" "close") "Title" (i18n "dialog.close")) -}}
</header>
<div class="o-dialog__body">
{{- partial "increase-headings" (dict "content" .Content) | safeHTML -}}
</div>
</div>
</dialog>
22 changes: 17 additions & 5 deletions layouts/partials/link.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{- $url := .Destination -}}
{{- if and (strings.HasPrefix $url "http") (not (strings.HasPrefix $url site.BaseURL)) -}}
{{- /* Absolute links pointing to external pages, e. g. `https://example.com` */ -}}
{{- /* Absolute links pointing to external pages, e.g. `https://example.com` */ -}}
<a
href="{{ .Destination }}"
target="_blank"
Expand All @@ -11,8 +11,20 @@
>
{{- .Text -}}{{- partial "icon" "arrow_outward" -}}
</a>
{{- else if strings.HasPrefix $url "dialog:" -}}
{{- /* Dialog triggers, e.g. `dialog:test` */ -}}
<span
class="o-link"
role="button"
tabindex="0"
aria-haspopup="dialog"
aria-label="{{ T "dialog.open" }}"
data-dialog-trigger="{{ strings.TrimPrefix "dialog:" $url }}"
>
{{- .Text -}}{{- partial "icon" "open_in_browser" -}}
</span>
{{- else if strings.HasPrefix $url "mailto:" -}}
{{- /* Email links, e. g. `mailto:example@example.com` */ -}}
{{- /* Email links, e.g. `mailto:example@example.com` */ -}}
<a
href="{{ $url }}"
class="o-link__mail"
Expand All @@ -21,7 +33,7 @@
{{- partial "icon" "mail" -}}{{- .Text -}}
</a>
{{- else if strings.HasPrefix $url "tel:" -}}
{{- /* Telephone links, e. g. `tel:+1234567890` */ -}}
{{- /* Telephone links, e.g. `tel:+1234567890` */ -}}
<a
href="{{ $url | safeURL }}"
class="o-link__tel"
Expand All @@ -30,15 +42,15 @@
{{- partial "icon" "call" -}}{{- .Text -}}
</a>
{{- else if .Page.Ref (dict "path" $url) -}}
{{- /* Internal links, referenced by path (e. g. `/news/1`) */ -}}
{{- /* Internal links, referenced by path (e.g. `/news/1`) */ -}}
<a
href="{{ .Page.Ref (dict "path" $url) }}"
{{- with .Title -}}title="{{ . }}"{{- end -}}
>
{{- .Text -}}
</a>
{{- else if or (strings.HasPrefix $url "/") (strings.HasPrefix $url site.BaseURL) -}}
{{- /* Internal links, referenced by URL (e. g. `/en/news/1`) */ -}}
{{- /* Internal links, referenced by URL (e.g. `/en/news/1`) */ -}}
<a
href="{{ $url | relURL }}"
{{- with .Title -}}title="{{ . }}"{{- end -}}
Expand Down
1 change: 0 additions & 1 deletion layouts/partials/remove-newlines.html

This file was deleted.

6 changes: 6 additions & 0 deletions layouts/shortcodes/dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{ partial "dialog" (dict
"ID" (.Get "id")
"Title" (.Get "title")
"Content" (.Inner | $.Page.RenderString)
)
}}
Loading