Skip to content

Instantly share code, notes, and snippets.

@tiagofrancafernandes
Last active June 26, 2023 01:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tiagofrancafernandes/b96b0d9bbcc8ecf94a14ec4f24880d5f to your computer and use it in GitHub Desktop.
Save tiagofrancafernandes/b96b0d9bbcc8ecf94a14ec4f24880d5f to your computer and use it in GitHub Desktop.
dev-alpinejs_transitions_snippets
<!--
https://codepen.io/tiagofranca/pen/BaZpzrN
https://jsfiddle.net/TiagoFranca/c1gL598j/
-->
<style>
[x-cloak] {display: none !important;}
.transition-500ms, .transition {
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
.transition-1000ms{
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
.transition-2000ms{
-webkit-transition: opacity 2s ease-in-out;
-moz-transition: opacity 2s ease-in-out;
-ms-transition: opacity 2s ease-in-out;
-o-transition: opacity 2s ease-in-out;
transition: opacity 2s ease-in-out;
}
.enter {opacity: 0;}
.enter.start {opacity: 0.5;}
.enter.end {opacity: 1;}
.leave {opacity: 1;}
.leave.start {opacity: 0.5;}
.leave.end {opacity: 0;}
</style>
<!-- AlpineJS -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{animate: false}">
<button @click="animate = (animate) ? false : true">
Toggle Fade
</button>
<div
x-show="animate"
x-transition:enter="enter"
x-transition:enter-start="enter start"
x-transition:enter-end="enter end"
x-transition:leave="leave"
x-transition:leave-start="leave start"
x-transition:leave-end="leave end"
class="transition-500ms"
x-cloak>
Faded by Alpine.js
</div>
</div>
<!--
https://alpinejs.dev
https://www.youtube.com/watch?v=lTYVyK-CMmU
-->
<style>
[x-cloak] {
display: none !important;
}
</style>
<script src="//unpkg.com/alpinejs" defer></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div x-cloak x-data="app()">
<form @submit.prevent="console.log('submitted')" action="/foo">
<input x-ref="user" placeholder="user"> <br>
<input x-ref="pass" placeholder="pass"> <br>
<button>Submit</button>
</form>
<hr>
<button x-on:click="tog()"> <span x-text="open ? 'Hide':'Show'">Show</span> default users</button>
<span x-show="open">
<ul>
<li>Default users</li>
<template x-for="(user, index) in users" :key="index">
<li>
<button x-text="user.user +' - '+ user.pass + ' (' +user.type +')'" x-on:click="fillUserData(index)"></button>
</li>
</template>
</ul>
</span>
</div>
<script>
function app() {
return {
open: false,
tog() {
this.open = !this.open
},
users: [{
user: "user1@user.com",
pass: "pass1",
type: "admin"
},
{
user: "user2@user.com",
pass: "pass2",
type: "manager"
},
{
user: "user3@user.com",
pass: "pass3",
type: "customer"
},
],
fillUserData(user_index) {
this.$refs.user.value = this.users[user_index].user;
this.$refs.pass.value = this.users[user_index].pass;
}
};
}
</script>
<!-- EVENTS -->
<script>
//Criando evento personalizado. Pode ser um uma função externa
window.dispatchEvent(new CustomEvent(
"title-flash-message", {
detail: {
type: 'success',
message: 'Successfuly'
}
}
));
</script>
<!-- Ouvindo esse evento -->
<div @title-flash-message.window="console.log($event.detail)"></div>
<div x-data>
<button @click="$dispatch('foo')"></button>
</div>
<div x-data @foo.window="console.log('foo was dispatched')">...</div>
mais em: https://alpinejs.dev/essentials/events
<!-- END EVENTS -->

window screen resize listener (detect response mode)

Step 1

document.addEventListener('alpine:init', () => {
    const screenType = (windowWidth) => {
        if (windowWidth <= 700) {
            return 'mobile';
        }

        if (windowWidth <= 1024) {
            return 'medium';
        }

        if (windowWidth <= 2048) {
            return 'large';
        }

        if (windowWidth > 2048) {
            return 'extra large';
        }

        return '';
    }

    Alpine.store('windowWidth', window.innerWidth);
    Alpine.store('windowHeight', window.innerHeight);
    Alpine.store('screenType', screenType(window.innerWidth));
    Alpine.store('screenInfo', {
        width: window.innerWidth,
        height: window.innerHeight,
        screenType: screenType(window.innerWidth),
    });

    new ResizeObserver(entries => {
        const screenInfo = {
            width: entries[0].contentRect.width,
            height: entries[0].contentRect.height,
            screenType: screenType(entries[0].contentRect.width),
        };

        Alpine.store('screenInfo', {
            ...screenInfo
        });

        Alpine.store('windowWidth', entries[0].contentRect.width);
        Alpine.store('windowHeight', entries[0].contentRect.height);
        Alpine.store('screenType', screenType(entries[0].contentRect.width));
    }).observe(document.body);
})

Step 2

<div x-data="{
    // bodyWidth: 0, // Dont will change (is static value)
    init() {
        // $store.bodyWidth = $store.windowWidth; // Dynamic way 1
        // this.bodyWidth = $store.windowWidth;
    },
    get bodyWidth() {
        return $store.windowWidth; // Dynamic way 2
    },
    get screenType() {
        if ($store.windowWidth <= 700) {
            return 'mobile';
        }

        if ($store.windowWidth <= 1024) {
            return 'medium';
        }

        if ($store.windowWidth <= 2048) {
            return 'large';
        }

        if ($store.windowWidth > 2048) {
            return 'extra large';
        }

        return '';
    }
}">
    <p>The width of the element is: <span x-text="bodyWidth"></span> pixels</p>
    <p>Showing for:
            <span x-show="$store.windowWidth <= 1024">mobile</span>
            <span x-show="$store.windowWidth > 1024">desktop</span>
    </p>
    <p>$store.screenType: <span x-text="$store.screenType"></span></p>
    <p>$store.windowWidth: <span x-text="$store.windowWidth"></span> pixels</p>
    <p>$store.windowHeight: <span x-text="$store.windowHeight"></span> pixels</p>
    <p>$store.screenInfo.width: <span x-text="$store.screenInfo.width"></span> pixels</p>
    <p>$store.screenInfo.height: <span x-text="$store.screenInfo.height"></span> pixels</p>
    <p x-show="$store.screenType === 'mobile'">This will show only in mobile screen</p>
    <p x-show="['mobile', 'medium'].includes($store.screenType)">This will show only in mobile and medium screen</p>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment