Skip to content

Commit

Permalink
Merge pull request #170 from statikbe/KarelJanVanHaute/issue98
Browse files Browse the repository at this point in the history
Dropdown position not always correct when displayed in footer
  • Loading branch information
janhenckens authored Oct 9, 2023
2 parents daf3539 + 76172f0 commit a1df279
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 23 deletions.
63 changes: 41 additions & 22 deletions tailoff/js/components/dropdown.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DOMHelper } from '../utils/domHelper';
import { computePosition, flip, shift, size, autoUpdate } from '@floating-ui/dom';

export class DropdownComponent {
constructor() {
Expand Down Expand Up @@ -34,11 +35,27 @@ class DropdownElement {
element.style.position = 'relative';
element.classList.remove('js-dropdown');
this.buttonElement = element.querySelector('.js-dropdown-toggle');
if (!this.buttonElement) {
console.error('Dropdown button not found');
return;
}
if (this.buttonElement.tagName !== 'BUTTON') {
console.error('Dropdown button must be a <button> element');
return;
}
this.menuElement = element.querySelector('.js-dropdown-menu');
if (!this.menuElement) {
console.error('Dropdown menu not found');
return;
}
this.menuItems = Array.from(this.menuElement.querySelectorAll('a[href],button:not([disabled])'));

this.menuElement.classList.add('hidden');
this.buttonElement.setAttribute('role', 'button');
if (this.menuElement.id === '') {
this.menuElement.id = `dropdown-menu-${index}`;
}
this.menuElement.classList.add('fixed');
this.buttonElement.setAttribute('aria-controls', this.menuElement.id);
this.buttonElement.setAttribute('aria-expanded', 'false');

this.clickListener = this.clickAction.bind(this);
Expand Down Expand Up @@ -122,26 +139,28 @@ class DropdownElement {
}

private positionMenu() {
this.menuElement.style.position = 'absolute';
this.menuElement.style.top = '0px';
this.menuElement.style.left = '0px';
this.menuElement.style.willChange = 'transform';

const buttonRect = this.buttonElement.getBoundingClientRect();
const menuRect = this.menuElement.getBoundingClientRect();

let leftPos = this.buttonElement.offsetLeft;

if (buttonRect.left + menuRect.width > window.screen.width) {
leftPos = this.buttonElement.offsetLeft + buttonRect.width - menuRect.width;
}

if (buttonRect.height + menuRect.height + buttonRect.top > window.screen.height) {
this.menuElement.style.transform = `translate(${leftPos}px, ${-menuRect.height}px)`;
} else {
this.menuElement.style.transform = `translate(${leftPos}px, ${
this.buttonElement.offsetTop + buttonRect.height
}px)`;
}
const _self = this;
autoUpdate(this.buttonElement, this.menuElement, () => {
computePosition(this.buttonElement, this.menuElement, {
strategy: 'fixed',
placement: 'bottom-start',
middleware: [
flip(),
shift({ padding: 16 }),
size({
apply({ availableWidth, availableHeight, elements }) {
Object.assign(elements.floating.style, {
minWidth: `${Math.min(_self.buttonElement.clientWidth, availableWidth)}px`,
});
},
}),
],
}).then(({ x, y }) => {
Object.assign(this.menuElement.style, {
left: `${x}px`,
top: `${y}px`,
});
});
});
}
}
2 changes: 1 addition & 1 deletion templates/_site/_layout.twig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{% endif %}
{% endblock %}

{% if not craft.statik.shouldPageBeIndexed(baseUrl, entry) %}
{% if entry is defined and not craft.statik.shouldPageBeIndexed(baseUrl, entry) %}
<meta name="robots" content="noindex">
<meta name="robots" content="nofollow">
{% endif %}
Expand Down
53 changes: 53 additions & 0 deletions templates/jsPlugins/dropdown.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{% extends "_site/_layout" %}

{% set breadcrumbs = [
{
url: './overview.twig',
title: 'Plugins'
},
{
url: './dropdown.twig',
title: 'Dropdown'
},
] %}

{% block content %}
<div class="section section--default">
<div class="container">
{% include '_site/_snippet/_nav/_breadcrumb' %}
<div class="w8/12">
<h1>Dropdown examples</h1>
</div>
</div>
</div>
<div class="section section--default">
<div class="container">
<div class="mb-10 js-dropdown">
<button class="btn js-dropdown-toggle">Toggle the dropdown</button>
<ul class="p-4 bg-white shadow js-dropdown-menu">
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi, possimus illo! Recusandae ducimus laudantium laborum nam excepturi veritatis porro! Minus.</a></li>
</ul>
</div>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere nostrum, sunt dolorum libero magni quidem in optio odit sint quae nesciunt distinctio vitae molestias laborum maiores est cum deserunt expedita? Nihil voluptates ullam iste unde. Suscipit cum atque deleniti blanditiis accusantium nulla eveniet, et sapiente perferendis asperiores harum reprehenderit architecto, minima illo vitae est incidunt cupiditate quod voluptates expedita, iure officia. Earum nihil quasi unde et. Molestias excepturi possimus ea, aut aliquam ducimus assumenda dolorum necessitatibus quod fugit repellendus dolore, aliquid harum. Laborum adipisci impedit eligendi aspernatur atque officiis odit rem earum sunt, unde, deleniti numquam, vitae iste velit eius.</p>
<div class="mt-10 js-dropdown">
<button class="btn js-dropdown-toggle">Toggle the dropdown</button>
<ul class="p-4 bg-white shadow js-dropdown-menu">
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Item 4</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
1 change: 1 addition & 0 deletions templates/jsPlugins/overview.twig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<li><a href="./autocomplete.twig">Autocomplete</a></li>
<li><a href="./backgroundImage.twig">Background Images</a></li>
<li><a href="./chipFilter.twig">Chip Filter</a></li>
<li><a href="./dropdown.twig">Dropdown</a></li>
<li><a href="./filter.twig">Filter</a></li>
<li><a href="./filterButton.twig">Filter Buttons</a></li>
<li><a href="./formValidation.twig">Form Validation</a></li>
Expand Down

0 comments on commit a1df279

Please sign in to comment.