Hyva : How to Create A Fixed Header on Scroll using AlpineJs and Tailwind CSS.

Posted: September 14, 2021 in ALL, Hyva, Magento2
Tags: , , , , , , ,

In this tutorial, Today I will explain How to Create A Fixed Header on Scroll using AlpineJs and Tailwind CSS in Hyva Magento 2 using TailwindCSS and AlpineJS.

You just add below code in your any PHTML file.

<div x-data="{scrolAtTop: true}">
    <div class="w-full"
        :class="{ 'theme-bg-grey6 fixed top-0 z-20 shadow-md': !scrolAtTop }"
        @scroll.window="scrolAtTop = (window.pageYOffset > 200) ? false : true"
    >
       Test Content
    </div>
</div>

In hyva theme you need to just copy below code and paste in header.phtml file

<?php
/**
 * Hyvä Themes - https://hyva.io
 * Copyright © Hyvä Themes 2020-present. All rights reserved.
 * This product is licensed per Magento install
 * See https://hyva.io/license
 */

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

/** @var Escaper $escaper */
/** @var Template $block */
/** @var ViewModelRegistry $viewModels */

/** @var HeroiconsOutline $heroicons */
$heroicons = $viewModels->require(HeroiconsOutline::class);

/** @var Hyva\Theme\ViewModel\StoreConfig $storeConfig */
$storeConfig = $viewModels->require(Hyva\Theme\ViewModel\StoreConfig::class);
$showMiniCart = $storeConfig->getStoreConfig(\Magento\Checkout\Block\Cart\Sidebar::XML_PATH_CHECKOUT_SIDEBAR_DISPLAY)
?>
<script>
    function initHeader () {
        return {
            searchOpen: false,
            cart: {},
            getData(data) {
                if (data.cart) { this.cart = data.cart }
            },
            menu: initHeaderNavigation()
        }
    }
    function initCompareHeader() {
        return {
            compareProducts: null,
            itemCount: 0,
            receiveCompareData(data) {
                if (data['compare-products']) {
                    this.compareProducts = data['compare-products'];
                    this.itemCount = this.compareProducts.count;
                }
            }
        }
    }
</script>
<div x-data="{scrolAtTop: true}">
    <div class="w-full"
        :class="{ 'theme-bg-grey6 fixed top-0 z-20 shadow-md': !scrolAtTop }"
        @scroll.window="scrolAtTop = (window.pageYOffset > 200) ? false : true"
    >
       <nav id="header"
            class="z-30 w-full border-b shadow bg-container-lighter border-container-lighter"
            x-data="initHeader()"
            @keydown.window.escape="searchOpen = false;"
            @private-content-loaded.window="getData(event.detail.data)"
        >
            <div class="container flex flex-wrap items-center justify-between w-full px-6 py-3 mx-auto mt-0">
                <!--Logo-->
                <?= $block->getChildHtml('logo'); ?>

                <!--Main Navigation-->
                <?= $block->getChildHtml('topmenu') ?>

                <div class="flex items-center order-3">
                    <!--Compare Icon-->
                    <a id="compare-link"
                    class="relative invisible inline-block mx-1 no-underline sm:ml-3 hover:text-black"
                    :class="{ 'invisible': !(itemCount > 0) }"
                    href="<?= $escaper->escapeUrl($block->getUrl('catalog/product_compare/index')) ?>"
                    title="<?= $escaper->escapeHtml(__('Compare Products')) ?>"
                    x-data="initCompareHeader()"
                    @private-content-loaded.window="receiveCompareData($event.detail.data)"
                    >
                        <?= $heroicons->scaleHtml(
                            "w-8 h-8 md:h-6 md:w-6 hover:text-black",
                            25,
                            25
                        ) ?>

                        <span class="sr-only label">
                        <?= $escaper->escapeHtml(__('Compare Products')) ?>
                        </span>

                        <span class="absolute top-0 right-0 h-5 px-2 py-1 -mt-5 -mr-4 text-xs font-semibold
                            leading-none text-center text-white uppercase transform -translate-x-1
                            translate-y-1/2 bg-yellow-500 rounded-full"
                        >
                            <span x-text="itemCount"></span>
                            <span x-show="itemCount === 1" class="sr-only">
                                <?= $escaper->escapeHtml(__('item')) ?>
                            </span>
                            <span x-show="itemCount > 1" class="sr-only">
                                <?= $escaper->escapeHtml(__('items')) ?>
                            </span>
                        </span>
                    </a>

                    <!--Search Icon-->
                    <a id="menu-search-icon"
                    class="inline-block ml-1 no-underline sm:ml-3 hover:text-black"
                    href="#"
                    @click.prevent="searchOpen = !searchOpen; $nextTick(function () { document.querySelector('#search').select(); });"
                    >
                        <span class="sr-only label">
                            <?= $escaper->escapeHtml(__('Search')) ?>
                        </span>

                        <?= $heroicons->searchHtml(
                            "w-8 h-8 md:h-6 md:w-6 hover:text-black",
                            25,
                            25
                        ) ?>
                    </a>

                    <!--Customer Icon & Dropdown-->
                    <?= $block->getChildHtml('customer') ?>

                    <!--Cart Icon-->
                    <a id="menu-cart-icon"
                    <?php if ($showMiniCart): ?>@click.prevent.stop="$dispatch('toggle-cart',{});"<?php endif ?>
                    class="relative inline-block ml-1 no-underline sm:ml-3 hover:text-black"
                    href="<?= $escaper->escapeUrl($block->getUrl('checkout/cart/index')) ?>"
                    >
                        <span class="sr-only label">
                            <?= $escaper->escapeHtml(__('Cart')) ?>
                        </span>

                        <?= $heroicons->shoppingCartHtml(
                            "w-8 h-8 md:h-6 md:w-6 hover:text-black",
                            25,
                            25
                        ) ?>

                        <span x-text="cart.summary_count"
                            class="absolute top-0 right-0 hidden h-5 px-2 py-1 -mt-5 -mr-4 text-xs font-semibold
                                leading-none text-center text-white uppercase transform -translate-x-1
                                translate-y-1/2 rounded-full bg-primary"
                            :class="{
                                'hidden': !cart.summary_count,
                                'block': cart.summary_count }"
                        ></span>
                    </a>

                </div>
            </div>
            <!--Search-->
            <div class="absolute z-10 hidden w-full border-t shadow-sm bg-container-lighter border-container-lighter"
                id="search-content"
                :class="{ 'block': searchOpen, 'hidden': !searchOpen }"
                @click.away="searchOpen = false"
                x-show="true"
            >
                <?= $block->getChildHtml('header-search'); ?>
            </div>

            <!--Cart Drawer-->
            <?= $block->getChildHtml('cart-drawer'); ?>

            <!--Authentication Pop-Up-->
            <?= $block->getChildHtml('authentication-popup'); ?>
        </nav>
    </div>
</div>

See example how it’s work:

I hope this blog is easy to understand about How to Create A Fixed Header on Scroll in Hyva Magento 2 using TailwindCSS and AlpineJS. In case, I missed anything or need to add some information, always feel free to leave a comment in this blog, I’ll get back with proper solution.

Keep liking and sharing !!

More will be coming soon… 🙂

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.