How to set and unset cookies using AlpineJS and Tailwind Toggle - javascript

I have the following code that uses tailwindcss for the toggle, and AlpineJS for adding a cookie base on the toggle state (on/off).
But I can't seem to make it work.
Here's the codepen: https://codepen.io/williamharvey/pen/GRMBqzO
Any help or direction will be appreciated
Thanks
And here's the code.
<div
class="flex w-full items-center bg-gray-100 border-b border-gray-200 px-5 py-3 text-sm"
x-data="{ cookieConcent1: docCookies.getItem('cookieConcent1') === 'true'} "
x-init="$watch('!cookieConcent1', val => docCookies.setItem('cookieConcent1', val))"
x-bind:class="{ 'cookieConcent1': cookieConcent1 }">
<div class="flex-1">
<p>Strictly necessary cookies</p>
</div>
<div class="w-10 text-right">
<button type="button"
class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-300 bg-gray-200"
x-data="{ on: true }"
role="switch"
aria-checked="false"
:aria-checked="on.toString()"
#click="on = !on;cookieConcent1 = !cookieConcent1"
x-state:on="Enabled"
x-state:off="Not Enabled"
:class="{ 'bg-green-400': on, 'bg-gray-200': !(on) }
">
<span class="sr-only">Use setting</span>
<span aria-hidden="true" class="pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 translate-x-0"
x-state:on="Enabled"
x-state:off="Not Enabled"
:class="{ 'translate-x-5': on, 'translate-x-0': !(on) }
"></span>
</button>
</div>
</div>

Related

Popover on hover vue headllessui

I'm trying to implement the popover from headlessui of vue package with hover. I try to use the mouseenter and mouseleave and the other mouse events but nothing change.
Any solution? There is a better solution? i search on internet I cant nothing about this. I search on headlessui github discussions but nothing.
<template>
<div class="fixed top-16 w-full max-w-sm px-4">
<Popover v-slot="{ open }" class="relative">
<PopoverButton
:class="open ? '' : 'text-opacity-90'"
class="group inline-flex items-center rounded-md bg-orange-700 px-3 py-2 text-base font-medium text-white hover:text-opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
>
<span>Solutions</span>
<ChevronDownIcon
:class="open ? '' : 'text-opacity-70'"
class="ml-2 h-5 w-5 text-orange-300 transition duration-150 ease-in-out group-hover:text-opacity-80"
aria-hidden="true"
/>
</PopoverButton>
<transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="translate-y-1 opacity-0"
enter-to-class="translate-y-0 opacity-100"
leave-active-class="transition duration-150 ease-in"
leave-from-class="translate-y-0 opacity-100"
leave-to-class="translate-y-1 opacity-0"
>
<PopoverPanel
class="absolute left-1/2 z-10 mt-3 w-screen max-w-sm -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl"
>
<div
class="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5"
>
<div class="relative grid gap-8 bg-white p-7 lg:grid-cols-2">
<a
v-for="item in solutions"
:key="item.name"
:href="item.href"
class="-m-3 flex items-center rounded-lg p-2 transition duration-150 ease-in-out hover:bg-gray-50 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
>
<div
class="flex h-10 w-10 shrink-0 items-center justify-center text-white sm:h-12 sm:w-12"
>
<div v-html="item.icon"></div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">
{{ item.name }}
</p>
<p class="text-sm text-gray-500">
{{ item.description }}
</p>
</div>
</a>
</div>
<div class="bg-gray-50 p-4">
<a
href="##"
class="flow-root rounded-md px-2 py-2 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
>
<span class="flex items-center">
<span class="text-sm font-medium text-gray-900">
Documentation
</span>
</span>
<span class="block text-sm text-gray-500">
Start integrating products and tools
</span>
</a>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</div>
</template>
Seems like common request in HeadlessUI community.
Another solution found this solution on Github that worked fine for me.
for vanilla vue 3 with js the original solution link Github Issue
Nuxt 3 with typescript maintaining accessibility here's the code ↓
<script setup lang="ts">
import { Popover, PopoverButton, PopoverPanel } from '#headlessui/vue'
interface Props {
label: string
hasHref?: boolean
href?: string
}
const props = defineProps<Props>()
const popoverHover = ref(false)
const popoverTimeout = ref()
const hoverPopover = (e: any, open: boolean): void => {
popoverHover.value = true
if (!open) {
e.target.parentNode.click()
}
}
const closePopover = (close: any): void => {
popoverHover.value = false
if (popoverTimeout.value) clearTimeout(popoverTimeout.value)
popoverTimeout.value = setTimeout(() => {
if (!popoverHover.value) {
close()
}
}, 100)
}
</script>
<template>
<Popover v-slot="{ open, close }" class="relative">
<PopoverButton
:class="[
open ? 'text-primary' : 'text-gray-900',
'group inline-flex items-center rounded-md bg-white text-base font-medium hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2'
]"
#mouseover="(e) => hoverPopover(e, open)"
#mouseleave="closePopover(close)"
>
<span v-if="!hasHref">{{ props.label }}</span>
<span v-else>
<NuxtLink :to="href">
{{ props.label }}
</NuxtLink>
</span>
<IconsChevronDown
:class="[
open ? 'rotate-180 transform text-primary' : '',
' ml-1 h-5 w-5 text-primary transition-transform group-hover:text-primary'
]"
aria-hidden="true"
/>
</PopoverButton>
<transition
enter-active-class="transition ease-out duration-200"
enter-from-class="opacity-0 translate-y-1"
enter-to-class="opacity-100 translate-y-0"
leave-active-class="transition ease-in duration-150"
leave-from-class="opacity-100 translate-y-0"
leave-to-class="opacity-0 translate-y-1"
>
<PopoverPanel
class="absolute left-1/2 z-10 mt-3 ml-0 w-auto min-w-[15rem] -translate-x-1/2 transform px-2 sm:px-0"
#mouseover.prevent="popoverHover = true"
#mouseleave.prevent="closePopover(close)"
>
<div
class="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5"
>
<div class="relative grid gap-1 bg-white p-3">
<slot> put content here </slot>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</template>
It is in the docs:showing-hiding-popover.
open is an internal state used to determine if the component is shown or hidden. To implement your own functionality, you can remove it and use the static prop to always render a component. Then you can mange the visibility with your own state ref and a v-if/v-show. The mouse-action has to be in the upper scope, so it is not triggered leaving the component, e.g. moving the mouse from button to panel.
Below is a modified example from the API documentation:
<template>
<Popover
#mouseenter="open = true"
#mouseleave="open = false"
#click="open = !open"
>
<PopoverButton #click="open = !open">
Solutions
<ChevronDownIcon :class="{ 'rotate-180 transform': open }" />
</PopoverButton>
<div v-if="open">
<PopoverPanel static>
Insights
Automations
Reports
</PopoverPanel>
</div>
</Popover>
</template>
<script setup>
import { ref } from 'vue';
import { Popover, PopoverButton, PopoverPanel } from '#headlessui/vue';
import { ChevronDownIcon } from '#heroicons/vue/20/solid';
const open = ref(false);
</script>

How to get dropdown button to work in react

How do I get the drop-down button to work within a card in React?
I am building in react and using Tailwind css card to display API information. I do not want to show all the info at once so plan to use a dropdown to say "show more" but somehow it won't work.
Button shows but when clicked nothing happens. Here is the code below, this also applies to dropdown code from the tailwind official website so something wrong with my app that I cannot figure out.
You can see the code display here
Thank you
<h5 class="text-gray-900 text-xl leading-tight font-medium mb-2">Card title</h5>
<p class="text-gray-700 text-base mb-4">
Some quick example text to build on the card title and make up the bulk of the card's
content.
</p>
<button
class="dropdown-toggle inline-block px-6 py-2.5 bg-purple-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-purple-700 hover:shadow-lg focus:bg-purple-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-purple-800 active:shadow-lg active:text-white transition duration-150 ease-in-out flex items-center whitespace-nowrap"
type="button"
id="dropdownMenuButton2"
data-bs-toggle="dropdown"
aria-expanded="false"
>
SHOW MORE
<svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="caret-down"
class="w-2 ml-2"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512"
>
<path
fill="currentColor"
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
></path>
</svg>
</button>
<ul
class="dropdown-menu min-w-max absolute hidden bg-white text-base z-50 float-left py-2 list-none text-left rounded-lg shadow-lg mt-1 hidden m-0 bg-clip-padding border-none bg-gray-800"
aria-labelledby="dropdownMenuButton2"
>
<h6
class="text-gray-400 font-semibold text-sm py-2 px-4 block w-full whitespace-nowrap bg-transparent"
>
Dropdown header
</h6>
<span
class="text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-gray-300"
>Dropdown item text</span
>
<li>
<a
class="dropdown-item text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-gray-300 hover:bg-gray-700 hover:text-white focus:text-white focus:bg-gray-700 active:bg-blue-600"
href="#"
>Action</a
>
</li>
<li>
<a
class="dropdown-item text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-gray-300 hover:bg-gray-700 hover:text-white focus:text-white focus:bg-gray-700"
href="#"
>Another action</a
>
</li>
<li>
<a
class="dropdown-item text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-gray-300 hover:bg-gray-700 hover:text-white focus:text-white focus:bg-gray-700"
href="#"
>Something else here</a
>
</li>
<li><hr class="h-0 my-2 border border-solid border-t-0 border-gray-300 opacity-25" /></li>
<li>
<a
class="dropdown-item text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-gray-300 hover:bg-gray-700 hover:text-white focus:text-white focus:bg-gray-700"
href="#"
>Separated link</a
>
</li>
</ul>
</div>
</div>
Just remove hidden class from ul tag and you can use one of component library like flowbite or daisyui

Capture value of input counter created with tailwind and alpine JS

I have a counter made with Tailwind and Alpine JS. I am trying to capture the value of the input field when the user types in or uses the counter buttons, but I am only able to capture the value when a user types their response. Any ideas on how to capture the values when the user uses the counter buttons to increment or decrement?
<!-- counter -->
<div class="z-50 relative" x-data="{ quantity : 0 }">
<div class="fisker-bold text-gray-900 text-center mx-auto text-sm">
Quantity</div>
<div class=" mt-1 mb-3 flex rounded-md justify-center">
<button #click="quantity--" type="button"
class=" relative inline-flex items-center space-x-2 px-4 py-2 text-sm font-medium rounded-l-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 bg-gray-300">
-
</button>
<div class="relative flex items-stretch focus-within:z-10">
<input type="text" x-model="quantity" name="qty-1" id="qty-1"
class="text-center focus:ring-blue-500 focus:border-indigo-500 block w-20 text-gray-900 rounded-none pl-3 sm:text-sm border-gray-300 bg-gray-300"
value="0">
</div>
<button #click="quantity++" type="button"
class="relative inline-flex items-center space-x-2 px-4 py-2 text-sm font-medium rounded-r-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 bg-gray-300">
+
</button>
</div>
</div>
<!-- counter -->
<script>
$(function () {
$("#qty-1").on("change", function () {
var text = $(this).find('option:selected').text();
$('#qty').text(' x' + text);
});
});
</script>

Need to pass a input value to another DIV in AlpineJS

I need to pass the input values to a modal, but i can't do it with x-ref. Is this the right way to do it?
<div x-data="orderSearch()" class="container mt-2 mx-auto" x-ref="root">
<div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 mt-2 mb-3">
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200 bg-green-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-green-800" x-data="{ qty: '', val: '', total: ''}" x-effect="total = qty * val">
Definir estratégia de COMPRA:
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorcompra" type="text" placeholder="Valor" autofocus x-model.number="qty" x-ref="valorcompra" #keydown.enter="fetchOrder('buy',$refs.quantidadecompra.value,$refs.valorcompra.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadecompra" type="text" placeholder="Quantidade" x-model.number="val" x-ref="quantidadecompra" #keydown.enter="fetchOrder('buy',$refs.quantidadecompra.value,$refs.valorcompra.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="totalcompra" type="text" placeholder="Total" x-model.number="total" x-ref="totalcompra" #keydown.enter="fetchOrder('buy',$refs.quantidadevenda.value,$refs.valorcompra.value)" x-bind:disabled="true">
</div>
</div>
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200 bg-red-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-red-800" x-data="{ qty: '', val: '', total: ''}" x-effect="total = qty * val">
Definir estratégia de VENDA:
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorvenda" type="text" placeholder="Valor" autofocus x-model.number="qty" x-ref="valorvenda" #keydown.enter="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadevenda" type="text" placeholder="Quantidade" x-model.number="val" x-ref="quantidadevenda" #keydown.enter="modal=true">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="totalvenda" type="text" placeholder="Total" x-model.number="total" x-ref="totalvenda" #keydown.enter="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)" x-bind:disabled="true">
</div>
</div>
</div>
<!-- Dialog (full screen) -->
<div class="absolute top-0 left-0 flex items-center justify-center w-full h-full" style="background-color: rgba(0,0,0,.5);" x-show="modal">
<!-- A basic modal dialog with title, body and one button to close -->
<div class="h-auto p-4 mx-2 text-left bg-white rounded shadow-xl md:max-w-xl md:p-6 lg:p-8 md:mx-0">
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg font-medium leading-6 text-gray-900">
Confirmação!
</h3>
<div class="mt-2">
<p class="text-sm leading-5 text-gray-500" x-text="'Deseja cadastrar a ordem de venda?'">
</p>
</div>
</div>
<!-- One big close button. --->
<div class="mt-4 flex justify-between">
<div class="cancela px-4 bg-red-400 p-3 rounded-lg text-white hover:bg-red-600" #click="modal=false">Cancelar</div>
<div class="ok px-4 bg-green-400 p-3 rounded-lg text-white hover:bg-green-600" #click="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">Confirmar</div>
</div>
</div>
</div>
<!-- fim modal div -->
</div>
Must be read input values here:
<div class="ok px-4 bg-green-400 p-3 rounded-lg text-white hover:bg-green-600" #click="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">Confirmar</div>
I tried to find this answer for two days but i cant.
Can you help me?
i tried a $store solution and it1s done:
<script>
const element = document.querySelector("#valorvenda")
element.addEventListener('change', (event) => {
const quantidadevenda = document.querySelector("#quantidadevenda").value
Alpine.store('venda', {
valorcompra: document.querySelector("#valorcompra").value,
quantidadecompra:quantidadevenda,
valorvenda: event.target.value,
quantidadevenda: quantidadevenda,
})
console.log(Alpine.store('fields').valorvenda);
})
</script>
It's like a state management and works fine!
Thanks all.

Alpinejs Accordion and Toggle on click

I’m using Alpinejs and Tailwind.
I'm trying to create an accordion with a toggle on each tab, but I want that toggle to trigger at the same time as when a user clicks to open each part of the accordion... here's what I got so far:
<ul class="block mb-4" x-data="{pay:null}">
<li class="flex flex-col">
<div #click="pay !== 'cc' ? pay = 'cc' : pay = null" class="cursor-pointer px-5 py-3 flex items-center bg-blue-50 border text-xl font-semibold border-blue-800 text-blue-800 inline-block hover:shadow rounded-t">
<button type="button" class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 bg-gray-200" x-data="{ on: false }" aria-pressed="false" :aria-pressed="on.toString()" #click="on = !on" x-state:on="Enabled" x-state:off="Not Enabled" :class="{ 'bg-orange-500': on, 'bg-white': !(on) }">
<span class="sr-only">Credit Card</span>
<span aria-hidden="true" class="pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 translate-x-0" x-state:on="Enabled" x-state:off="Not Enabled" :class="{ 'translate-x-5': on, 'translate-x-0': !(on) }"></span>
</button>
<span class="ml-2">Credit / Debit Card</span>
</div>
<p x-show="pay == 'cc'" class="bg-white border-l border-r border-blue-800 py-4 px-2">
This is made with Alpine JS and Tailwind CSS
</p>
</li>
<li class="flex align-center flex-col">
<h4 #click="pay !== 1 ? pay = 1 : pay = null" class="cursor-pointer px-5 py-3 bg-indigo-400 text-white text-center inline-block hover:opacity-75 hover:shadow hover:-mb-3">Accordion item 2</h4>
<p x-show="pay == 1" class="border py-4 px-2">
There's no external CSS or JS
</p>
</li>
<li class="flex align-center flex-col">
<h4 #click="pay !== 2 ? pay = 2 : pay = null" :class="{'cursor-pointer px-5 py-3 bg-indigo-500 text-white text-center inline-block hover:opacity-75 hover:shadow hover:-mb-3': true, 'rounded-b': pay != 2}">Accordion item 3</h4>
<p x-show="pay == 2" :class="{'border py-4 px-2': true, 'rounded-b': pay == 2}">
Pretty cool huh?
</p>
</li>
</ul>
https://codepen.io/kennyk3/pen/eYBwEXN
I'm pretty green, so bear with me. I actually just want to comment but don't have enough reputation.
First of all, you need to remove bg-gray-200 from your <button class> because you're binding :class="{ bg-{color} } for on: true and on: false states. Another one is bg-orange-500 and ring-orange-500 isn't a defined utility on Tailwind CSS. Maybe you mean bg-yellow-500 and ring-yellow-500? Other than that, what is x-state? I can't find it in Alpine.js docs.
Okay, about your requested problem, your code actually has 2 issues.
You want a parent component to communicate with a child component, like a nested component. Alpine.js doesn't do that. Either you merge both components holding multiple properties in the parent component so that you only have one x-data or you $dispatch('customEvent') on your <div> at the #click event (together with pay toggling) and listen to the #customEvent.window on your <button> component.
Alternatively, you can install Alpine Magic Helpers for the $component/$parent communication or install Spruce for saving all states.
Because of your <button> is nested in your <div>, you're firing both #click events every time you #click the <button>. This is why your code looks like the <button> component communicates with your <ul> component which is untrue. You're firing two different #click events. Because of this behavior, if you $dispatch('customEvent') from your <div> component and listen to the #customEvent.window on your <button>, you'll end up toggling your on state twice. Try add #click.debounce.250 on your <button> together with the #customEvent.window and you'll see it toggles to and fro.
As for that, you need to remove #click event on your <button> while listening to the #customEvent.window so that the toggling happens once, or better you merge both x-data making your <ul> holding multiple properties (no need to $dispatch('customEvent') on your <div> and #click on your <button>, just one #click on your <div>).
In my implementation, I make x-data to hold both:
<ul class="block mb-4" x-data="{pay:null, on: false}">
<li class="flex flex-col">
<div #click="pay !== 'cc' ? pay = 'cc' : pay = null, on = !on" class="cursor-pointer px-5 py-3 flex items-center bg-blue-50 border text-xl font-semibold border-blue-800 text-blue-800 inline-block hover:shadow rounded-t">
<button type="button" class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500" aria-pressed="false" :aria-pressed="on.toString()" x-state:on="Enabled" x-state:off="Not Enabled" :class="{ 'bg-yellow-500': on, 'bg-gray-200': !(on) }">
<span class="sr-only">Credit Card</span>
<span aria-hidden="true" class="pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 translate-x-0" x-state:on="Enabled" x-state:off="Not Enabled" :class="{ 'translate-x-5': on, 'translate-x-0': !(on) }"></span>
</button>
<span class="ml-2">Credit / Debit Card</span>
</div>
<p x-show="pay == 'cc'" class="bg-white border-l border-r border-blue-800 py-4 px-2">
This is made with Alpine JS and Tailwind CSS
</p>
</li>
<li class="flex align-center flex-col">
<h4 #click="pay !== 1 ? pay = 1 : pay = null" class="cursor-pointer px-5 py-3 bg-indigo-400 text-white text-center inline-block hover:opacity-75 hover:shadow hover:-mb-3">Accordion item 2</h4>
<p x-show="pay == 1" class="border py-4 px-2">
There's no external CSS or JS
</p>
</li>
<li class="flex align-center flex-col">
<h4 #click="pay !== 2 ? pay = 2 : pay = null" :class="{'cursor-pointer px-5 py-3 bg-indigo-500 text-white text-center inline-block hover:opacity-75 hover:shadow hover:-mb-3': true, 'rounded-b': pay != 2}">Accordion item 3</h4>
<p x-show="pay == 2" :class="{'border py-4 px-2': true, 'rounded-b': pay == 2}">
Pretty cool huh?
</p>
</li>
</ul>
https://codepen.io/wanahmadfiras/pen/jOVgBrz
Accordions (among other components) are now part of official AlpineJS documentation. Use them for perfect out of the box accordions.

Categories

Resources