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
3 changes: 0 additions & 3 deletions plugins/collapse.phtml

This file was deleted.

31 changes: 24 additions & 7 deletions view/frontend/layout/default_hyva.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<!-- Add menus -->
<referenceBlock name="topmenu_generic">
<block
name="topmenu-mobile"
Expand All @@ -12,7 +13,6 @@
</arguments>
</block>
</referenceBlock>

<block
name="topmenu-desktop"
class="Snowdog\Menu\Block\Menu"
Expand All @@ -21,7 +21,6 @@
<argument name="menu" xsi:type="string">hyva-topmenu-desktop</argument>
</arguments>
</block>

<referenceBlock name="footer-content">
<block
name="menu-footer"
Expand All @@ -38,16 +37,34 @@
/>
</referenceBlock>

<!-- Move/Remove blocks -->
<move element="topmenu-desktop" destination="header.container" after="-"/>
<referenceBlock name="topmenu_mobile" remove="true"/>
<referenceBlock name="topmenu_desktop" remove="true"/>

<!-- Add scripts -->
<referenceBlock name="script-alpine-js">
<block
name="alpine-plugin-collapse"
template="Snowdog_Menu::page/js/plugins/collapse.phtml"
/>
</referenceBlock>

<move element="topmenu-desktop" destination="header.container" after="-"/>

<referenceBlock name="topmenu_mobile" remove="true"/>
<referenceBlock name="topmenu_desktop" remove="true"/>
<referenceContainer name="before.body.end">
<block
class="Magento\Framework\View\Element\Template"
name="snowdog-menu.footer.menu.js"
template="Snowdog_Menu::hyva-menu-footer/menu-js.phtml"
/>
<block
class="Magento\Framework\View\Element\Template"
name="snowdog-menu.desktop.menu.js"
template="Snowdog_Menu::hyva-topmenu-desktop/menu-js.phtml"
/>
<block
class="Magento\Framework\View\Element\Template"
name="snowdog-menu.mobile.menu.js"
template="Snowdog_Menu::hyva-topmenu-mobile/menu-js.phtml"
/>
</referenceContainer>
</body>
</page>
11 changes: 11 additions & 0 deletions view/frontend/layout/hyva_checkout_components.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="topmenu-mobile" remove="true" />
<referenceBlock name="snowdog-menu.mobile.menu.js" remove="true" />

<referenceBlock name="topmenu-desktop" remove="true" />
<referenceBlock name="snowdog-menu.desktop.menu.js" remove="true" />
</body>
</page>
77 changes: 77 additions & 0 deletions view/frontend/templates/hyva-menu-footer/menu-js.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
use Hyva\Theme\ViewModel\HyvaCsp;

/** @var HyvaCsp $hyvaCsp */
?>
<script>
function footerMenu() {
return {
isDesktop: true,
indexid: '',
checkIsDesktopResolution() {
this.isDesktop = window.matchMedia('(min-width: 1024px)').matches;
},
toggleSubmenu(event, index) {
const focusableElements = 'button:not([disabled]), a[href]:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])'

event.stopPropagation()
this[index] = !this[index]

if (this[index]) {
this.$nextTick(() => {
this.$refs['submenu-' + index] && this.$refs['submenu-' + index].querySelector(focusableElements) && this.$refs['submenu-' + index].querySelector(focusableElements).focus()
})
} else {
this.$nextTick(() => {
this.$refs['submenu-toggle-' + index] && this.$refs['submenu-toggle-' + index].focus()
})
}
},
['onVisibilityChange'](event) {
return this.checkIsDesktopResolution();
},
['!isDesktop']() {
return !this.isDesktop;
},
['onResize'](event) {
return this.checkIsDesktopResolution();
},
['init']() {
return this.checkIsDesktopResolution();
},
}
}

function footerMenuItem() {
return Object.assign({
indexid: '',
init() {
this.indexid = this.$el.dataset.indexid
},
['showSubmenu']() {
return this.isDesktop || !!this[this.indexid]
},
['getAriaExpanded']() {
return this[this.indexid] === true;
},
['getAriaHidden']() {
return !this.isDesktop && this[this.indexid] === false ? true : false;
},
['getIconClass']() {
return {'rotate-180': this[this.indexid] === true};
},
['onClick'](event) {
this.toggleSubmenu(event, `${this.indexid}`);
},
['onEscape'](event) {
!this.isDesktop && this.toggleSubmenu(event, `${this.indexid}`);
},
});
}

window.addEventListener('alpine:init', () => {
Alpine.data('footerMenu', footerMenu);
Alpine.data('footerMenuItem', footerMenuItem);
}, {once: true});
</script>
<?php $hyvaCsp->registerInlineScript() ?>
63 changes: 20 additions & 43 deletions view/frontend/templates/hyva-menu-footer/menu.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Magento\Framework\Escaper;
use Snowdog\Menu\Block\Menu;
use Hyva\Theme\ViewModel\HyvaCsp;

/** @var Escaper $escaper */
/** @var Menu $block */
Expand All @@ -16,45 +17,18 @@ $heroicons = $viewModels->require(HeroiconsOutline::class);
?>

<?php if ($menu): ?>
<script>
'use strict';

const initMenuFooter<?= $escaper->escapeHtml($uniqueId) ?> = () => ({
isDesktop: true,
checkIsDesktopResolution() {
this.isDesktop = window.matchMedia('(min-width: 1024px)').matches
},
toggleSubmenu(event, index) {
const focusableElements = 'button:not([disabled]), a[href]:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])'

event.stopPropagation()
this[index] = !this[index]

if (this[index]) {
this.$nextTick(() => {
this.$refs['submenu-' + index]?.querySelector(focusableElements)?.focus()
})
} else {
this.$nextTick(() => {
this.$refs['submenu-toggle-' + index]?.focus()
})
}
},
})
</script>
<div
class="
<?= $escaper->escapeHtmlAttr($menu->getCssClass()) ?>
snowdog-menu-footer w-full flex flex-wrap text-primary-darker
snowdog-menu-footer w-full flex flex-wrap text-primary-darker
"
x-data="initMenuFooter<?= $escaper->escapeHtml($uniqueId) ?>()"
x-data="footerMenu"
x-init="init"
@resize.window.debounce="onResize"
@visibilitychange.window.debounce="onVisibilityChange"
>
<ul class="w-full flex flex-col flex-wrap lg:flex-row lg:justify-between lg:gap-6 divide-y divide-container lg:divide-y-0"
x-init="checkIsDesktopResolution()"
@resize.window.debounce="checkIsDesktopResolution()"
@visibilitychange.window.debounce="checkIsDesktopResolution()"
>
<?php foreach ($block->getNodes() as $node): ?>
<ul class="w-full flex flex-col flex-wrap lg:flex-row lg:justify-between lg:gap-6 divide-y divide-container lg:divide-y-0">
<?php foreach ($block->getNodes() as $key => $node): ?>
<?php
$childrenLevel = $node->getLevel() + 1;
$children = $block->getNodes($childrenLevel, $node);
Expand All @@ -63,45 +37,48 @@ $heroicons = $viewModels->require(HeroiconsOutline::class);
$title = $node->getTitle();
$nodeType = $node->getType();
$nodeClasses = $node->getClasses();
?>
<li x-data="{'<?= /* @noEscape */ (string) $indexId ?>': false }"
?>
<li x-data="footerMenuItem"
x-init="init"
data-indexid="<?= /* @noEscape */ (string) $indexId ?>"
class="flex-1"
>
<?php if ($node->getIsParent() && !$node->getIsViewAllLink()): ?>
<div @keydown.escape="(event) => !isDesktop && toggleSubmenu(event, '<?= /* @noEscape */ (string) $indexId ?>')">
<div @keydown.escape="onEscape">
<span x-show="isDesktop"
x-cloak="tablet"
class="block font-bold mb-6"
>
<?= $escaper->escapeHtml($title) ?>
</span>
<button x-show="!isDesktop"
<button
x-show="!isDesktop"
x-cloak="desktop"
x-ref="submenu-toggle-<?= /* @noEscape */ (string) $indexId ?>"
class="
w-full py-4 font-bold
"
@click="(event) => toggleSubmenu(event, '<?= /* @noEscape */ (string) $indexId ?>')"
:aria-expanded="<?= /* @noEscape */ (string) $indexId ?> === true"
@click="onClick"
:aria-expanded="getAriaExpanded"
type="button"
>
<div class="flex items-center justify-between">
<span>
<?= $escaper->escapeHtml($title) ?>
</span>
<div class="transition-transform"
:class="{'rotate-180' : <?= /* @noEscape */ (string) $indexId ?> === true}"
:class="getIconClass"
>
<?= $heroicons->chevronDownHtml('text-gray-500', 20, 20, ['aria-hidden' => 'true']); ?>
</div>
</div>
</button>
<div x-show="isDesktop || !!<?= /* @noEscape */ (string) $indexId ?>"
<div x-show="showSubmenu"
x-cloak="tablet"
x-ref="submenu-<?= /* @noEscape */ (string) $indexId ?>"
x-collapse
class="pb-2"
:aria-hidden="!isDesktop && <?= /* @noEscape */ (string) $indexId ?> === false ? 'true' : 'false'"
:aria-hidden="getAriaHidden"
>
<?= /* @noEscape */ $block->renderSubmenu($children, $node, $childrenLevel) ?>
</div>
Expand Down
69 changes: 69 additions & 0 deletions view/frontend/templates/hyva-topmenu-desktop/menu-js.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
use Hyva\Theme\ViewModel\HyvaCsp;
/** @var HyvaCsp $hyvaCsp */
?>
<script>
function topmenuDesktop() {
return {
openSubmenuId: null,
closeSubmenu() {
this.openSubmenuId = null;
},
onSubmenuEscape() {
this.$refs['sr-button-' + this.openSubmenuId]?.focus();
this.closeSubmenu();
}
}
}

function topmenuDesktopItem() {
return {
nodeId: '',
hasChildren: false,
init() {
this.nodeId = this.$el.dataset.nodeid;
this.hasChildren = this.$el.dataset.haschildren === 'true';
},
openSubmenu() {
this.openSubmenuId = this.nodeId;
},
toggleSubmenu() {
if (this.openSubmenuId === this.nodeId) {
this.openSubmenuId = null;
hyva.releaseFocus();
} else {
this.openSubmenuId = this.nodeId;
this.$nextTick(() => {
hyva.trapFocus(this.$refs['submenu-' + this.nodeId]);
});
}
},
getItemClass() {
return {
'bg-white rounded-t-lg shadow-md': this.hasChildren && this.openSubmenuId === this.nodeId
};
},
getButtonClass() {
return { 'rotate-180': this.openSubmenuId === this.nodeId };
},
getAriaExpanded() {
return this.openSubmenuId === this.nodeId ? 'true' : 'false';
}
}
}

function topmenuDesktopSubmenu() {
return {
shouldDisplaySubmenu() {
return this.openSubmenuId === this.$el.dataset.parentNodeIndex
}
}
}

window.addEventListener('alpine:init', () => {
Alpine.data('topmenuDesktop', topmenuDesktop);
Alpine.data('topmenuDesktopItem', topmenuDesktopItem);
Alpine.data('topmenuDesktopSubmenu', topmenuDesktopSubmenu);
}, {once: true});
</script>
<?php $hyvaCsp->registerInlineScript() ?>
Loading
Loading