Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion assets/build/css/public/main.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/build/css/public/main.rtl.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/build/js/public/all-listings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/build/js/public/search-form.js

Large diffs are not rendered by default.

30 changes: 6 additions & 24 deletions assets/src/js/public/components/instantSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -713,34 +713,16 @@ import initSearchCategoryCustomFields from './category-custom-fields';

// Close all search modal
function closeAllSearchModal() {
var searchModalElement = document.querySelectorAll(
const searchModalElements = document.querySelectorAll(
'.directorist-search-modal'
);

searchModalElement.forEach((modal) => {
var modalOverlay = modal.querySelector(
'.directorist-search-modal__overlay'
searchModalElements.forEach((modal) => {
modal.dispatchEvent(
new CustomEvent('directorist-search-modal-close', {
bubbles: true,
})
);
var modalContent = modal.querySelector(
'.directorist-search-modal__contents'
);
var modalBodyOverlay = document.querySelector(
'.directorist-content-active'
);

// Overlay Style
if (modalOverlay) {
modalOverlay.style.cssText =
'opacity: 0; visibility: hidden; transition: 0.5s ease';
// remove overlay class on body
modalBodyOverlay.classList.remove('directorist-overlay-active');
}

// Modal Content Style
if (modalContent) {
modalContent.style.cssText =
'opacity: 0; visibility: hidden; bottom: -200px;';
}
});
}

Expand Down
202 changes: 202 additions & 0 deletions assets/src/js/public/components/searchModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
let activeSearchModal = null;
let activeSearchModalTrigger = null;
let searchModalScrollPosition = 0;
let searchModalInitialized = false;

function setSearchModalPageState(isOpen) {
const contentRoot = document.querySelector(".directorist-content-active");

if (isOpen) {
searchModalScrollPosition = window.scrollY;
document.body.style.setProperty(
"--directorist-search-modal-scroll-offset",
`-${searchModalScrollPosition}px`,
);
}

contentRoot?.classList.toggle("directorist-overlay-active", isOpen);
document.documentElement.classList.toggle(
"directorist-search-modal-open",
isOpen,
);
document.body.classList.toggle("directorist-search-modal-open", isOpen);

if (isOpen) {
return;
}

document.body.style.removeProperty(
"--directorist-search-modal-scroll-offset",
);
window.scrollTo(0, searchModalScrollPosition);
}

function getSearchModalFocusableElement(modalContent) {
return (
modalContent.querySelector(
'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled])',
) || modalContent.querySelector("button:not([disabled]), a[href]")
);
}

export function openSearchModal(searchModalParent, trigger) {
if (!searchModalParent) {
return;
}

if (activeSearchModal && activeSearchModal !== searchModalParent) {
closeSearchModal(activeSearchModal, false);
}

const modalContent = searchModalParent.querySelector(
".directorist-search-modal__contents",
);

if (!modalContent) {
return;
}

activeSearchModal = searchModalParent;
activeSearchModalTrigger = trigger || document.activeElement;
searchModalParent.classList.add("directorist-search-modal--open");
searchModalParent.setAttribute("aria-hidden", "false");
modalContent.setAttribute("role", "dialog");
modalContent.setAttribute("aria-modal", "true");
activeSearchModalTrigger?.setAttribute("aria-expanded", "true");
setSearchModalPageState(true);

const focusTarget = getSearchModalFocusableElement(modalContent);
const focusSearchControl = () => {
if (activeSearchModal === searchModalParent) {
focusTarget?.focus({ preventScroll: true });
}
};

window.requestAnimationFrame(focusSearchControl);
window.setTimeout(() => {
if (document.activeElement !== focusTarget) {
focusSearchControl();
}
}, 350);
}

export function closeSearchModal(searchModalParent, restoreFocus = true) {
if (!searchModalParent) {
return;
}

const modalContent = searchModalParent.querySelector(
".directorist-search-modal__contents",
);
const modalMinimizer = searchModalParent.querySelector(
".directorist-search-modal__minimizer",
);

searchModalParent.classList.remove("directorist-search-modal--open");
searchModalParent.setAttribute("aria-hidden", "true");
modalContent?.removeAttribute("style");
modalContent?.removeAttribute("aria-modal");
modalMinimizer?.classList.remove("minimized");

if (activeSearchModal === searchModalParent) {
const trigger = activeSearchModalTrigger;
trigger?.setAttribute("aria-expanded", "false");
activeSearchModal = null;
activeSearchModalTrigger = null;
setSearchModalPageState(false);

if (restoreFocus && trigger && document.contains(trigger)) {
window.requestAnimationFrame(() =>
trigger.focus({ preventScroll: true }),
);
}
}
}

function initSearchModalSwipeDismiss() {
document
.querySelectorAll(".directorist-search-modal__contents")
.forEach((modalContent) => {
const swipeHandle =
modalContent.querySelector(
".directorist-search-modal__contents__header",
) || modalContent.querySelector(".directorist-search-modal__minimizer");

if (!swipeHandle || swipeHandle.dataset.swipeDismissInitialized) {
return;
}

swipeHandle.dataset.swipeDismissInitialized = "true";
let touchStartY = null;
let touchDistance = 0;

swipeHandle.addEventListener(
"touchstart",
(event) => {
if (
!window.matchMedia("(max-width: 575px)").matches ||
event.touches.length !== 1
) {
return;
}

touchStartY = event.touches[0].clientY;
touchDistance = 0;
modalContent.style.transition = "none";
},
{ passive: true },
);

swipeHandle.addEventListener(
"touchmove",
(event) => {
if (null === touchStartY || event.touches.length !== 1) {
return;
}

touchDistance = Math.max(0, event.touches[0].clientY - touchStartY);
modalContent.style.transform = `translate(-50%, ${touchDistance}px)`;
},
{ passive: true },
);

swipeHandle.addEventListener("touchend", () => {
const searchModalParent = modalContent.closest(
".directorist-search-modal",
);

modalContent.style.removeProperty("transition");
modalContent.style.removeProperty("transform");

if (touchDistance >= 80) {
closeSearchModal(searchModalParent);
}

touchStartY = null;
touchDistance = 0;
});
});
}

export function initSearchModals() {
initSearchModalSwipeDismiss();

if (searchModalInitialized) {
return;
}

searchModalInitialized = true;
document.addEventListener("keydown", (event) => {
if ("Escape" === event.key && activeSearchModal) {
closeSearchModal(activeSearchModal);
}
});

document.addEventListener("directorist-search-modal-close", (event) => {
const searchModalParent = event.target.closest(".directorist-search-modal");

if (searchModalParent) {
closeSearchModal(searchModalParent);
}
});
}
97 changes: 17 additions & 80 deletions assets/src/js/public/search-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import initSearchCategoryCustomFields from './components/category-custom-fields'
import './components/colorPicker';
import './components/directoristDropdown';
import './components/directoristSelect';
import {
closeSearchModal,
initSearchModals,
openSearchModal,
} from './components/searchModal';

class ViewportAwareDropdown {
constructor(options = {}) {
Expand Down Expand Up @@ -959,113 +964,50 @@ document.addEventListener('DOMContentLoaded', () => {
}

// Search Modal Open
function searchModalOpen(searchModalParent) {
// Modal Overlay
let modalOverlay = searchModalParent.querySelector(
'.directorist-search-modal__overlay'
);
// Modal Content
let modalContent = searchModalParent.querySelector(
'.directorist-search-modal__contents'
);

// Modal Overlay Style
modalOverlay.style.cssText =
'opacity: 1; visibility: visible; transition: 0.3s ease;';

// Modal Content Style
modalContent.style.cssText =
'opacity: 1; visibility: visible; bottom: 50%; transform: translate(-50%, 50%)';

// Check if container width is less than 576px
const containerWidth = document.body.offsetWidth;
if (containerWidth < 576) {
// Check if backdrop is added to body
const bodyElement = document.body;
const bodyStyles = getComputedStyle(bodyElement);
const bodyBackdropStyle = bodyStyles?.backdropFilter || '';

if (bodyBackdropStyle !== 'none' && bodyBackdropStyle !== '') {
// If backdrop is added to body, set bottom to 50%
modalContent.style.cssText +=
'bottom: 50%; transform: translate(-50%, 50%)';
} else {
// If backdrop is not added to body, set bottom to 0
modalContent.style.cssText +=
'bottom: 0; transform: translate(-50%, 0)';
}
}
function searchModalOpen(searchModalParent, trigger) {
openSearchModal(searchModalParent, trigger);
}

// Search Modal Close
function searchModalClose(searchModalParent) {
let modalOverlay = searchModalParent.querySelector(
'.directorist-search-modal__overlay'
);
let modalContent = searchModalParent.querySelector(
'.directorist-search-modal__contents'
);

// Overlay Style
if (modalOverlay) {
modalOverlay.style.cssText = 'opacity: 0; visibility: hidden';
}

// Modal Content Style
if (modalContent) {
modalContent.style.cssText =
'opacity: 0; visibility: hidden; bottom: -200px;';
}
closeSearchModal(searchModalParent);
}

// Search Modal Minimizer
function searchModalMinimize(searchModalParent) {
let modalContent = searchModalParent.querySelector(
'.directorist-search-modal__contents'
);
let modalMinimizer = searchModalParent.querySelector(
'.directorist-search-modal__minimizer'
);

if (modalMinimizer.classList.contains('minimized')) {
modalMinimizer.classList.remove('minimized');
modalContent.style.bottom = '0';
} else {
modalMinimizer.classList.add('minimized');
modalContent.style.bottom = '-50%';
}
closeSearchModal(searchModalParent);
}

initSearchModals();

// Search Modal Open Trigger
$('body').on('click', '.directorist-modal-btn', function (e) {
e.preventDefault();
// added overlay class on body
document
.querySelector('.directorist-content-active')
.classList.add('directorist-overlay-active');

let parentElement = this.closest('.directorist-contents-wrap');
if (!parentElement) {
return;
}

if (this.classList.contains('directorist-modal-btn--basic')) {
let searchModalElement = parentElement.querySelector(
'.directorist-search-modal--basic'
);

searchModalOpen(searchModalElement);
searchModalOpen(searchModalElement, this);
}
if (this.classList.contains('directorist-modal-btn--advanced')) {
let searchModalElement = parentElement.querySelector(
'.directorist-search-modal--advanced'
);

searchModalOpen(searchModalElement);
searchModalOpen(searchModalElement, this);
}
if (this.classList.contains('directorist-modal-btn--full')) {
let searchModalElement = parentElement.querySelector(
'.directorist-search-modal--full'
);

searchModalOpen(searchModalElement);
searchModalOpen(searchModalElement, this);
}
});

Expand All @@ -1075,11 +1017,6 @@ document.addEventListener('DOMContentLoaded', () => {
'.directorist-search-modal__contents__btn--close, .directorist-search-modal__overlay',
function (e) {
e.preventDefault();
// removed overlay class from body
document
.querySelector('.directorist-content-active')
.classList.remove('directorist-overlay-active');

let searchModalElement = this.closest(
'.directorist-search-modal'
);
Expand Down
Loading
Loading