<div class="supt-country-picker">
<div class="supt-country-picker__wrapper">
<div class="supt-country-picker__header">
<p class="supt-country-picker__title">Select your country</p>
<button class="supt-country-picker__close-btn" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M0.75 0.75L11.25 11.25" stroke-linecap="round" />
<path d="M11.25 0.75L0.75 11.25" stroke-linecap="round" />
</svg>
</button>
</div>
<div class="supt-country-picker__content">
<!-- Europe Section -->
<div class="supt-country-picker__region -europe">
<p class="supt-country-picker__region__title">Europe</p>
<div class="supt-country-picker__countries">
<div class="supt-country-picker__country">
<a href="https://www.verisure.be" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/belgium.svg" alt="Belgium">
<span class="supt-button-country__title">Belgium</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.dk" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/denmark.svg" alt="Denmark">
<span class="supt-button-country__title">Denmark</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.fi" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/finland.svg" alt="Finland">
<span class="supt-button-country__title">Finland</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.fr" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/france.svg" alt="France">
<span class="supt-button-country__title">France</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.de" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/germany.svg" alt="Germany">
<span class="supt-button-country__title">Germany</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.it" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/italy.svg" alt="Italy">
<span class="supt-button-country__title">Italy</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.ie" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/ireland.svg" alt="Ireland">
<span class="supt-button-country__title">Ireland</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.nl" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/netherlands.svg" alt="Netherlands">
<span class="supt-button-country__title">Netherlands</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.no" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/norway.svg" alt="Norway">
<span class="supt-button-country__title">Norway</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.securitasdirect.pt" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/portugal.svg" alt="Portugal">
<span class="supt-button-country__title">Portugal</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.securitasdirect.es" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/spain.svg" alt="Spain">
<span class="supt-button-country__title">Spain</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.se" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/sweden.svg" alt="Sweden">
<span class="supt-button-country__title">Sweden</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.co.uk" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/uk.svg" alt="UK">
<span class="supt-button-country__title">UK</span>
</span>
</a>
</div>
</div>
</div>
<!-- Latin America Section -->
<div class="supt-country-picker__region -latin-america">
<p class="supt-country-picker__region__title">Latin America</p>
<div class="supt-country-picker__countries">
<div class="supt-country-picker__country">
<a href="https://www.verisure.com.ar" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/argentina.svg" alt="Argentina">
<span class="supt-button-country__title">Argentina</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.com.br" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/brazil.svg" alt="Brazil">
<span class="supt-button-country__title">Brazil</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.cl" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/chile.svg" alt="Chile">
<span class="supt-button-country__title">Chile</span>
</span>
</a>
</div>
<div class="supt-country-picker__country">
<a href="https://www.verisure.pe" class="supt-button-country" target="_blank" rel="noopener noreferrer">
<span class="supt-button-country__inner">
<img class="supt-button-country__flag" src="/sites/gv/files/flmngr/countries/peru.svg" alt="Peru">
<span class="supt-button-country__title">Peru</span>
</span>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="supt-country-picker__overlay" aria-hidden="true"></div>
</div>
No notes defined.
<div class="supt-country-picker">
<div class="supt-country-picker__wrapper">
<div class="supt-country-picker__header">
<p class="supt-country-picker__title">Select your country</p>
<button class="supt-country-picker__close-btn" aria-label="Close">
{% include '02-icons/close-icon.twig' %}
</button>
</div>
<div
class="supt-country-picker__content">
<!-- Europe Section -->
<div class="supt-country-picker__region -europe">
<p class="supt-country-picker__region__title">Europe</p>
<div class="supt-country-picker__countries">
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Belgium',
href: 'https://www.verisure.be',
flag: '/sites/gv/files/flmngr/countries/belgium.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Denmark',
href: 'https://www.verisure.dk',
flag: '/sites/gv/files/flmngr/countries/denmark.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Finland',
href: 'https://www.verisure.fi',
flag: '/sites/gv/files/flmngr/countries/finland.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'France',
href: 'https://www.verisure.fr',
flag: '/sites/gv/files/flmngr/countries/france.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Germany',
href: 'https://www.verisure.de',
flag: '/sites/gv/files/flmngr/countries/germany.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Italy',
href: 'https://www.verisure.it',
flag: '/sites/gv/files/flmngr/countries/italy.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Ireland',
href: 'https://www.verisure.ie',
flag: '/sites/gv/files/flmngr/countries/ireland.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Netherlands',
href: 'https://www.verisure.nl',
flag: '/sites/gv/files/flmngr/countries/netherlands.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Norway',
href: 'https://www.verisure.no',
flag: '/sites/gv/files/flmngr/countries/norway.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Portugal',
href: 'https://www.securitasdirect.pt',
flag: '/sites/gv/files/flmngr/countries/portugal.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Spain',
href: 'https://www.securitasdirect.es',
flag: '/sites/gv/files/flmngr/countries/spain.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Sweden',
href: 'https://www.verisure.se',
flag: '/sites/gv/files/flmngr/countries/sweden.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'UK',
href: 'https://www.verisure.co.uk',
flag: '/sites/gv/files/flmngr/countries/uk.svg'
} %}
</div>
</div>
</div>
<!-- Latin America Section -->
<div class="supt-country-picker__region -latin-america">
<p class="supt-country-picker__region__title">Latin America</p>
<div class="supt-country-picker__countries">
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Argentina',
href: 'https://www.verisure.com.ar',
flag: '/sites/gv/files/flmngr/countries/argentina.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Brazil',
href: 'https://www.verisure.com.br',
flag: '/sites/gv/files/flmngr/countries/brazil.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Chile',
href: 'https://www.verisure.cl',
flag: '/sites/gv/files/flmngr/countries/chile.svg'
} %}
</div>
<div class="supt-country-picker__country">
{% include 'atoms/buttons/button-country/button-country.twig' with {
title: 'Peru',
href: 'https://www.verisure.pe',
flag: '/sites/gv/files/flmngr/countries/peru.svg'
} %}
</div>
</div>
</div>
</div>
</div>
<div class="supt-country-picker__overlay" aria-hidden="true"></div>
</div>
/* No context defined. */
.supt-country-picker {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
padding: 16px;
z-index: $z-index-country-picker;
&__wrapper {
background-color: $color-grey-background;
width: 100%;
height: 100%;
max-width: 826px;
max-height: 100%;
overflow-y: auto;
z-index: 1;
opacity: 0;
transform: translateY(20px);
@media (min-width: $breakpoint-md) {
height: auto;
}
}
&__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: $spacing-4 $spacing-6;
background-color: $color-grey-background;
border-bottom: 1px solid $color-grey-2;
position: sticky;
top: 0;
z-index: 1;
}
&__title {
@extend %t-body-sm;
font-weight: 500;
}
&__close-btn {
@extend %reset-button;
color: $color-grey-5;
svg {
display: block;
width: 12px;
height: 12px;
}
&:hover,
&:focus-visible {
color: $color-black;
}
}
&__content {
display: flex;
flex-direction: column;
@media (min-width: $breakpoint-md) {
flex-direction: row;
justify-content: space-between;
padding: $spacing-10 $spacing-6;
}
&::after {
content: '';
display: none;
background-color: $color-grey-2;
flex-shrink: 0;
order: 1;
width: 100%;
height: 1px;
@media (min-width: $breakpoint-md) {
display: block;
width: 1px;
height: auto;
margin: calc(22px + $spacing-4) $spacing-6 0;
}
}
}
&__region {
padding: $spacing-6 $spacing-6 $spacing-8;
border-bottom: 1px solid $color-grey-2;
@media (min-width: $breakpoint-md) {
padding: 0;
border-bottom: none;
}
&__title {
@extend %t-body-s;
font-weight: 500;
@media (min-width: $breakpoint-md) {
padding-left: $spacing-3-5;
}
}
&.-europe {
order: 0;
@media (min-width: $breakpoint-md) {
width: 495px;
}
.supt-country-picker__countries {
@media (min-width: $breakpoint-md) {
columns: 3;
}
}
}
&.-latin-america {
order: 2;
padding-bottom: $spacing-4;
@media (min-width: $breakpoint-md) {
width: 175px;
padding-bottom: 0;
}
.supt-country-picker__countries {
@media (min-width: $breakpoint-md) {
columns: 1;
}
}
}
}
&__countries {
columns: 2;
margin-top: $spacing-6;
column-gap: $spacing-3;
@media (min-width: $breakpoint-md) {
margin-top: $spacing-4;
column-gap: 87px;
}
}
/* Country Button */
&__country {
margin-bottom: $spacing-4;
@media (min-width: $breakpoint-md) {
margin-bottom: 0;
}
}
&__overlay {
position: absolute;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
transition: opacity 0.3s ease-in-out 0.1s;
}
&.-is-visible {
pointer-events: auto;
.supt-country-picker__overlay {
opacity: 1;
transition-delay: 0s;
}
.supt-country-picker__wrapper {
opacity: 1;
transform: translateY(0);
transition-delay: 0.1s;
}
}
body.-is-loaded & {
&__wrapper {
transition:
opacity 0.3s ease-in-out,
transform 0.3s ease-in-out;
}
}
}
const COUNTRY_PICKER_EVENT_NAME = 'country-picker-toggle';
export const COUNTRY_PICKER_EVENT = new CustomEvent(COUNTRY_PICKER_EVENT_NAME);
const COUNTRY_PICKER_HASH = '#country-picker';
export class CountryPicker {
$element: Element;
$closeButton: HTMLElement;
$countryButtons: NodeListOf<HTMLElement>;
$overlay: HTMLElement;
isVisible: boolean;
focusableElements: HTMLElement[];
firstFocusableElement: HTMLElement | null;
lastFocusableElement: HTMLElement | null;
constructor($element: Element) {
// Bindings
this.toggle = this.toggle.bind(this);
this.close = this.close.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
// Elements
this.$element = $element;
this.$closeButton = $element.querySelector('.supt-country-picker__close-btn') as HTMLElement;
this.$countryButtons = $element.querySelectorAll(
'.supt-button-country'
) as NodeListOf<HTMLElement>;
this.$overlay = $element.querySelector('.supt-country-picker__overlay') as HTMLElement;
this.isVisible = false;
this.firstFocusableElement = null;
this.lastFocusableElement = null;
this.focusableElements = [this.$closeButton, ...this.$countryButtons];
this.firstFocusableElement = this.focusableElements[0] || null;
this.lastFocusableElement = this.focusableElements[this.focusableElements.length - 1] || null;
this.init();
}
init() {
this.bindEvents();
}
bindEvents() {
document.addEventListener(COUNTRY_PICKER_EVENT_NAME, this.toggle);
// Close button functionality
if (this.$closeButton) {
this.$closeButton.addEventListener('click', this.close);
}
// Keyboard navigation
this.$element.addEventListener('keydown', this.handleKeyDown as EventListener);
this.$overlay.addEventListener('click', this.close);
// Close on escape key
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && this.isVisible) {
this.close();
}
});
// ON hash change
window.addEventListener('hashchange', this.onHashChange.bind(this));
this.onHashChange(); // Init
}
onHashChange() {
if (window.location.hash === COUNTRY_PICKER_HASH) {
this.open();
}
}
toggle() {
if (this.isVisible) {
this.close();
} else {
this.open();
}
}
open() {
this.isVisible = true;
this.$element.classList.add('-is-visible');
// Focus first focusable element for accessibility
this.firstFocusableElement?.focus();
}
close() {
this.isVisible = false;
this.$element.classList.remove('-is-visible');
// Remove hash from url
window.history.replaceState({}, '', window.location.pathname);
}
handleKeyDown(event: KeyboardEvent) {
const { key } = event;
const focusedElement = document.activeElement as HTMLElement;
if (!this.isVisible || !this.$element.contains(focusedElement)) return;
switch (key) {
case 'Escape':
event.preventDefault();
this.close();
break;
case 'Tab':
if (event.shiftKey) {
// Shift + Tab (backwards)
if (focusedElement === this.firstFocusableElement) {
event.preventDefault();
this.lastFocusableElement?.focus();
}
} else {
// Tab (forwards)
if (focusedElement === this.lastFocusableElement) {
event.preventDefault();
this.firstFocusableElement?.focus();
}
}
break;
}
}
}