diff --git a/app.js b/app.js
index 31f4937..eaa3cad 100644
--- a/app.js
+++ b/app.js
@@ -1,155 +1,122 @@
-const body = document.body;
-const modal = document.querySelector('.modal');
+const navDialogEl = document.querySelector(".dialog");
+const dialogOverlay = document.querySelector(".dialog-overlay");
-const openModal = document.querySelectorAll('.modal-open');
-const closeModal = document.querySelectorAll('.modal-close');
-const overlay = document.querySelector('.modal-overlay');
-
-const toggleModal = function() {
- modal.classList.toggle('opacity-0');
- modal.classList.toggle('pointer-events-none');
- body.classList.toggle('modal-active');
-};
-
-for (let i = 0; i < openModal.length; i++) {
- openModal[i].addEventListener('click', function(event) {
- event.preventDefault();
- toggleModal();
- });
-};
-
-for (let i = 0; i < closeModal.length; i++) {
- closeModal[i].addEventListener('click', toggleModal);
-}
-
-overlay.addEventListener('click', toggleModal);
-
-document.onkeydown = function(evt) {
- evt = evt || window.event;
- let isEscape = false;
-
- if ("key" in evt) {
- isEscape = (evt.key === "Escape" || evt.key === "Esc");
- } else {
- isEscape = (evt.keyCode === 27);
- }
- if (isEscape && document.body.classList.contains('modal-active')) {
- toggleModal();
- }
-};
+const myDialog = new Dialog(navDialogEl, dialogOverlay);
+myDialog.addEventListeners(".open-dialog", ".close-dialog");
+const menuButton = document.getElementById("menu-button");
+const menuContainer = document.getElementById("menu-container");
-const menuButton = document.getElementById('menu-button');
-const menuContainer = document.getElementById('menu-container');
-
-menuButton.addEventListener('click', function(event) {
- menuContainer.classList.toggle('hidden');
+menuButton.addEventListener("click", function(event) {
+ menuContainer.classList.toggle("hidden");
});
-
-const computersButton = document.querySelectorAll('.computers-button');
-const computersContainer = document.getElementById('computers-container');
-const computersCards = document.getElementById('computers-cards');
-const computersGrid = document.getElementById('computers-grid');
-const idevicesButton = document.querySelectorAll('.idevices-button');
-const idevicesContainer = document.getElementById('idevices-container');
-const idevicesCards = document.getElementById('idevices-cards');
-const idevicesGrid = document.getElementById('idevices-grid');
-const collectionLabel = document.getElementById('collection-label');
-const uiButtons = document.querySelectorAll('.computers-button, .idevices-button');
-const modeButtons = document.querySelectorAll('.mode-button');
+const computersButton = document.querySelectorAll(".computers-button");
+const computersContainer = document.getElementById("computers-container");
+const computersCards = document.getElementById("computers-cards");
+const computersGrid = document.getElementById("computers-grid");
+const idevicesButton = document.querySelectorAll(".idevices-button");
+const idevicesContainer = document.getElementById("idevices-container");
+const idevicesCards = document.getElementById("idevices-cards");
+const idevicesGrid = document.getElementById("idevices-grid");
+const collectionLabel = document.getElementById("collection-label");
+const uiButtons = document.querySelectorAll(
+ ".computers-button, .idevices-button"
+);
+const modeButtons = document.querySelectorAll(".mode-button");
const showCollection = function(collection) {
let items = null;
let label = null;
- if (collection === 'computers') {
- items = document.querySelectorAll('#computers-container .card');
- label = 'Computers (' + items.length + ')';
- idevicesContainer.classList.add('hidden');
- computersContainer.classList.remove('hidden');
+ if (collection === "computers") {
+ items = document.querySelectorAll("#computers-container .card");
+ label = "Computers (" + items.length + ")";
+ idevicesContainer.classList.add("hidden");
+ computersContainer.classList.remove("hidden");
} else {
- items = document.querySelectorAll('#idevices-container .card');
- label = 'iDevices (' + items.length + ')';
- idevicesContainer.classList.remove('hidden');
- computersContainer.classList.add('hidden');
+ items = document.querySelectorAll("#idevices-container .card");
+ label = "iDevices (" + items.length + ")";
+ idevicesContainer.classList.remove("hidden");
+ computersContainer.classList.add("hidden");
}
uiButtons.forEach(function(element) {
const dataCollection = element.dataset.collection;
if (dataCollection === collection) {
- element.classList.remove('text-gray-800');
- element.classList.add('text-purple-600');
+ element.classList.remove("text-gray-800");
+ element.classList.add("text-purple-800");
} else {
- element.classList.add('text-gray-800');
- element.classList.remove('text-purple-600');
+ element.classList.add("text-gray-800");
+ element.classList.remove("text-purple-800");
}
});
collectionLabel.innerHTML = label;
const params = new URLSearchParams(location.search);
- params.set('collection', collection);
- window.history.replaceState({}, '', `${location.pathname}?${params}`);
+ params.set("collection", collection);
+ window.history.replaceState({}, "", `${location.pathname}?${params}`);
// TODO: replaceState is not updating the title
document.title = `${label} - Leo's Collection`;
// Mobile: close menu after click
- if (!menuContainer.classList.contains('hidden')) {
- menuContainer.classList.add('hidden');
+ if (!menuContainer.classList.contains("hidden")) {
+ menuContainer.classList.add("hidden");
}
-}
+};
uiButtons.forEach(function(element) {
- element.addEventListener('click', function(event) {
+ element.addEventListener("click", function(event) {
const collection = element.dataset.collection;
showCollection(collection);
+
+ event.preventDefault();
});
});
const toggleMode = function(mode) {
- if (mode === 'grid') {
- computersCards.classList.add('hidden');
- idevicesCards.classList.add('hidden');
- computersGrid.classList.remove('hidden');
- idevicesGrid.classList.remove('hidden');
+ if (mode === "grid") {
+ computersCards.classList.add("hidden");
+ idevicesCards.classList.add("hidden");
+ computersGrid.classList.remove("hidden");
+ idevicesGrid.classList.remove("hidden");
} else {
- computersCards.classList.remove('hidden');
- idevicesCards.classList.remove('hidden');
- computersGrid.classList.add('hidden');
- idevicesGrid.classList.add('hidden');
+ computersCards.classList.remove("hidden");
+ idevicesCards.classList.remove("hidden");
+ computersGrid.classList.add("hidden");
+ idevicesGrid.classList.add("hidden");
}
modeButtons.forEach(function(button) {
const dataMode = button.dataset.mode;
if (dataMode === mode) {
- button.classList.remove('text-gray-800');
- button.classList.add('text-purple-600');
+ button.classList.remove("text-gray-800");
+ button.classList.add("text-purple-800");
} else {
- button.classList.add('text-gray-800');
- button.classList.remove('text-purple-600');
+ button.classList.add("text-gray-800");
+ button.classList.remove("text-purple-800");
}
});
const params = new URLSearchParams(location.search);
- params.set('mode', mode);
- window.history.replaceState({}, '', `${location.pathname}?${params}`);
-}
+ params.set("mode", mode);
+ window.history.replaceState({}, "", `${location.pathname}?${params}`);
+};
modeButtons.forEach(function(element) {
- element.addEventListener('click', function(event) {
+ element.addEventListener("click", function(event) {
const mode = element.dataset.mode;
toggleMode(mode);
});
});
-
const params = new URLSearchParams(location.search);
-if (params.get('collection')) {
- showCollection(params.get('collection'));
+if (params.get("collection")) {
+ showCollection(params.get("collection"));
}
-if (params.get('mode')) {
- toggleMode(params.get('mode'));
+if (params.get("mode")) {
+ toggleMode(params.get("mode"));
}
diff --git a/dialog.js b/dialog.js
new file mode 100644
index 0000000..f5ace34
--- /dev/null
+++ b/dialog.js
@@ -0,0 +1,108 @@
+// Acessible dialog by Ire Aderinokun
+// https://bitsofco.de/accessible-modal-dialog/
+
+function Dialog(dialogEl, overlayEl) {
+ this.dialogEl = dialogEl;
+ this.overlayEl = overlayEl;
+ this.focusedElBeforeOpen;
+
+ var focusableEls = this.dialogEl.querySelectorAll(
+ 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]'
+ );
+ this.focusableEls = Array.prototype.slice.call(focusableEls);
+
+ this.firstFocusableEl = this.focusableEls[0];
+ this.lastFocusableEl = this.focusableEls[this.focusableEls.length - 1];
+
+ this.close(); // Reset
+}
+
+Dialog.prototype.open = function() {
+ var Dialog = this;
+
+ this.dialogEl.removeAttribute("aria-hidden");
+ this.dialogEl.classList.remove("hidden");
+ this.overlayEl.removeAttribute("aria-hidden");
+ this.overlayEl.classList.remove("hidden");
+ document.body.classList.add("overflow-hidden");
+
+ this.focusedElBeforeOpen = document.activeElement;
+
+ this.dialogEl.addEventListener("keydown", function(e) {
+ Dialog._handleKeyDown(e);
+ });
+
+ this.overlayEl.addEventListener("click", function() {
+ Dialog.close();
+ });
+
+ this.firstFocusableEl.focus();
+};
+
+Dialog.prototype.close = function() {
+ this.dialogEl.setAttribute("aria-hidden", true);
+ this.dialogEl.classList.add("hidden");
+ this.overlayEl.setAttribute("aria-hidden", true);
+ this.overlayEl.classList.add("hidden");
+ document.body.classList.remove("overflow-hidden");
+
+ if (this.focusedElBeforeOpen) {
+ this.focusedElBeforeOpen.focus();
+ }
+};
+
+Dialog.prototype._handleKeyDown = function(e) {
+ var Dialog = this;
+ var KEY_TAB = 9;
+ var KEY_ESC = 27;
+
+ function handleBackwardTab() {
+ if (document.activeElement === Dialog.firstFocusableEl) {
+ e.preventDefault();
+ Dialog.lastFocusableEl.focus();
+ }
+ }
+ function handleForwardTab() {
+ if (document.activeElement === Dialog.lastFocusableEl) {
+ e.preventDefault();
+ Dialog.firstFocusableEl.focus();
+ }
+ }
+
+ switch (e.keyCode) {
+ case KEY_TAB:
+ if (Dialog.focusableEls.length === 1) {
+ e.preventDefault();
+ break;
+ }
+ if (e.shiftKey) {
+ handleBackwardTab();
+ } else {
+ handleForwardTab();
+ }
+ break;
+ case KEY_ESC:
+ Dialog.close();
+ break;
+ default:
+ break;
+ }
+};
+
+Dialog.prototype.addEventListeners = function(openDialogSel, closeDialogSel) {
+ var Dialog = this;
+
+ var openDialogEls = document.querySelectorAll(openDialogSel);
+ for (var i = 0; i < openDialogEls.length; i++) {
+ openDialogEls[i].addEventListener("click", function() {
+ Dialog.open();
+ });
+ }
+
+ var closeDialogEls = document.querySelectorAll(closeDialogSel);
+ for (var i = 0; i < closeDialogEls.length; i++) {
+ closeDialogEls[i].addEventListener("click", function() {
+ Dialog.close();
+ });
+ }
+};
diff --git a/index.html b/index.html
index 4607bb4..f34025e 100644
--- a/index.html
+++ b/index.html
@@ -26,38 +26,27 @@
-
+
-
-
-
+
+
+
Leo's Collection
-
-
-
+
-
+
-
-
-
-
@@ -65,16 +54,16 @@
-
Computers
+
Computers
-
-
- Cards
+
+
+ Cards
-
-
- Grid
+
+
+ Grid
@@ -83,29 +72,32 @@
-
+
-
{{computer}}
-
+
{{computer}}
+
{{notes}}
@@ -114,23 +106,23 @@
-
+
- Photo
- Computer
- Bought at
- Hardware
- Notes
+ Photo
+ Computer
+ Bought at
+ Hardware
+ Notes
-
+
-
+
{{computer}}
@@ -141,9 +133,7 @@
{{hardware}}
-
- {{notes}}
-
+ {{notes}}
@@ -154,29 +144,32 @@
-
+
-
{{device}}
-
+
{{device}}
+
{{notes}}
@@ -185,23 +178,23 @@
-
+
- Photo
- Device
- Bought at
- Hardware
- Notes
+ Photo
+ Device
+ Bought at
+ Hardware
+ Notes
-
+
-
+
{{device}}
@@ -212,9 +205,7 @@
{{hardware}}
-
- {{notes}}
-
+ {{notes}}
@@ -222,36 +213,36 @@
-
-
-
-
+
+
+
+
diff --git a/readme.md b/readme.md
index 705ff17..d4503dc 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-# Collection [![Twitter Follow](https://img.shields.io/twitter/follow/leozera?label=Follow%20on%20Twitter)](https://twitter.com/leozera/) ![Netlify Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fdeveloper.oswaldlabs.com%2Fnetlify-status%2Fb634d562-0afe-4c7b-bdd6-32688bf36b0b)
+# Collection [![Twitter Follow](https://img.shields.io/twitter/follow/leozera?label=Follow%20on%20Twitter)](https://twitter.com/leozera/) ![Netlify Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fdeveloper.oswaldlabs.com%2Fnetlify-status%2Fb634d562-0afe-4c7b-bdd6-32688bf36b0b) ![Code Style Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)
This is a simple website I made for my Apple Collection.