I've got the tailwind UI toggle working. However the toggle it self doesn't do anything in a form. It needs a Checkbox. Hence I'm trying to add a checkbox that checks and unchecks when the toggle is clicked.
I gave it the right data-model, but nothing happens.
<div>
<div class="flex items-center justify-between" x-data="{ on: false }">
<span class="flex flex-grow flex-col">
<span class="text-sm font-medium text-gray-900" id="availability-label">Books</span>
<span class="text-sm text-gray-500" id="availability-description">Yes gibe me a free book</span>
</span>
<button type="button"
class="relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 bg-gray-200"
role="switch" aria-checked="false" x-ref="switch" x-state:on="Enabled" x-state:off="Not Enabled"
:class="{ 'bg-primary-600': on, 'bg-gray-200': !(on) }" aria-labelledby="availability-label"
aria-describedby="availability-description" :aria-checked="on.toString()" #click="on = !on">
<span aria-hidden="true"
class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out translate-x-0"
x-state:on="Enabled" x-state:off="Not Enabled" :class="{ 'translate-x-5': on, 'translate-x-0': !(on) }"></span>
</button>
<input type="checkbox" style="display:none" name="free_books" x-model="on">
</div>
</div>
Related
I have following sample, written in tailwind css:
https://play.tailwindcss.com/f9iOK1e0oM
I want to have my control buttons on the bottom if the grid containers, however, they have different content sizes for the blue "tag" boxes, so the grid gets increased in height by some containers. however, as I am working with grid, all boxes are getting this height then. this is ok. But my control buttons should be always on the bottom of the containers, so that "Enabled" and "Delete" should not be so far away from bottom for the second container.
How to achieve this?
You need to add flex flex-col to the li element. And grow to the first child div and grow-0 max-h-max to the second child div.
<li class="flex flex-col col-span-1 divide-y divide-gray-200 rounded-lg bg-white shadow">
<div class=" grow flex w-full flex-col items-start justify-between p-6">
<div class="flex w-full items-start justify-between space-x-3">
<h3 class="truncate text-sm font-medium text-gray-900">243rfh83294d-23r8fj2n48r-24fi43bf</h3>
<span class="inline-block flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800"> running </span>
</div>
<p class="mt-1 whitespace-pre-wrap text-xs font-bold text-gray-500">Interval: <span class="font-normal">1234</span></p>
<p class="mt-1 whitespace-pre-wrap text-xs font-bold text-gray-500">Next run: <span class="font-normal">1234</span></p>
<p class="mt-1 whitespace-pre-wrap">
<span class="inline-block flex-shrink-0 rounded-full bg-blue-100 px-2 py-0.5 text-xs text-blue-800">test 1</span>
</p>
</div>
<div>
<div class="-mt-px flex shrink-0 grow-0 divide-x divide-gray-200 max-h-max">
<div class="flex w-0 flex-1">
<button class="relative -mr-px inline-flex w-0 flex-1 items-center justify-center rounded-bl-lg border border-transparent py-4 text-sm font-medium text-gray-700 hover:text-gray-500">
<span class="ml-3">Enabled</span>
</button>
</div>
<div class="-ml-px flex w-0 flex-1">
<button class="group relative inline-flex w-0 flex-1 items-center justify-center rounded-br-lg border border-transparent py-4 text-sm font-medium text-gray-700 transition hover:text-red-500">
<span class="ml-3">Delete</span>
</button>
</div>
</div>
</div>
</li>
https://play.tailwindcss.com/ilTMM5glku
I have done this only for the second card, but you should do it for all cards. So that when the content changes, the button row will always stick to the bottom and keep the same height in all cards.
Hope this helps.
This is my code in html + tailwind css:
<div className="flex justify-center">
<div className="flex flex-col justify-center items-start gap-5">
<div className="form-check">
<input
className="form-check-input appearance-none rounded-full h-7 w-7 border-4 border-[#5F6368] bg-[#C4C4C4] hover:shadow-lg hover:shadow-[#5F6368] hover:border-[#3B52B5] checked:bg-[#7EABFF] checked:border-[#3B52B5] focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-5 cursor-pointer"
type="radio"
name="flexRadioDefault"
id="flexRadioDefault1"
/>
<label
className="form-check-label text-3xl text-right font-bold text-gray-800"
htmlFor="flexRadioDefault1"
>
الخيار 1
</label>
</div>
</div>
</div>
How can I make the radio choice from right to left?
Make just one div as a parent of the input field and the label. Then give the parent div these classes: flex flex-row-reverse items-center
<div className="form-check flex flex-row-reverse items-center">
<input
className="form-check-input appearance-none rounded-full h-7 w-7 border-4 border-[#5F6368] bg-[#C4C4C4] hover:shadow-lg hover:shadow-[#5F6368] hover:border-[#3B52B5] checked:bg-[#7EABFF] checked:border-[#3B52B5] focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-5 cursor-pointer"
type="radio"
name="flexRadioDefault"
id="flexRadioDefault1"
/>
<label
className="form-check-label text-3xl text-right font-bold text-gray-800"
htmlFor="flexRadioDefault1"
>
الخيار 1
</label>
</div>
I'm using Tailwind CSS and I want to show the white dropdown over the modal.
I tried using z-index but I can't make it work.
Any ideas?
This is my modal code:
<TransitionRoot as="template" :show="isOpen">
<Dialog as="div" class="inset-0 fixed overflow-y-auto">
<div class="flex min-h-screen text-center px-4 pt-4 pb-20 items-end justify-center sm:p-0 sm:block">
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
<DialogOverlay class="bg-gray-975 bg-opacity-85 inset-0 transition-opacity fixed" />
</TransitionChild>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:h-screen sm:inline-block sm:align-middle" aria-hidden="true"></span>
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-200" leave-from="opacity-100 translate-y-0 sm:scale-100" leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<div class="rounded-lg shadow-xl text-left transform transition-all text-gray-850 inline-block align-bottom overflow-hidden sm:max-w-lg sm:my-8 sm:w-full sm:align-middle dark:text-gray-200">
...
</div>
</TransitionChild>
</div>
</Dialog>
And this is my dropdown code:
<Listbox v-model="selectedPerson">
<div class="mt-1 relative z-50">
<ListboxButton
class="bg-white rounded-lg cursor-default shadow-md text-left w-full py-2 pr-10 pl-3 relative sm:text-sm focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-white focus-visible:ring-2 focus-visible:ring-opacity-75 focus-visible:ring-offset-orange-300 focus-visible:ring-offset-2">
<span class="block truncate">{{ selectedPerson.name }}</span>
<span class="flex pr-2 inset-y-0 right-0 absolute items-center pointer-events-none">
<SelectorIcon class="h-5 text-gray-400 w-5" aria-hidden="true" />
</span>
</ListboxButton>
...
</div>
Remove class overflow-hidden from <div class="rounded-lg shadow-xl text-left transform transition-all text-gray-850 inline-block align-bottom overflow-hidden sm:max-w-lg sm:my-8 sm:w-full sm:align-middle dark:text-gray-200">.
codesandbox
Change the class that sets the position of the child element from absolute to fixed
I am trying to use sample tailwindui.com components.
They have the animation part defined in the comments, but I am not able to make out how I should those in my code. I am using plain html/js and would prefer to not use any framework/lib for this.
Here I am trying to show/hide a modal dialog.
The animation doe for the background overlay is given as
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
I have no idea how to encode this information to the background overlay div.
<div id="myModal" class="hidden fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
Here is what I have tried so far;
<style>
.modalEntry {animation:modal-in 1s;}
.modalExit {animation:modal-in 1s;}
#keyframes modal-in {
from {opacity-0;}
to {opacity-100;}
}
#keyframes modal-out {
from {opacity-100;}
to {opacity-0;}
}
</style>
<button class="border border-red-500" onclick="toggleModal()">Toggle modal</button>
<!-- This example requires Tailwind CSS v2.0+ -->
<div id="myModal" class="hidden fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed modalEntry inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true"></span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
<!-- Heroicon name: outline/exclamation -->
<svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Deactivate account</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.</p>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button onclick="toggleModal()" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">Deactivate</button>
<button onclick="toggleModal()" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">Cancel</button>
</div>
</div>
</div>
</div>
<script>
function toggleModal () {
document.getElementById("myModal").classList.toggle("hidden");
}
</script>
I have put the same in a codepen for the ease of testing.
https://codepen.io/rishavs/pen/BadMQaN?editors=1000
i`m using jquery on a legacy php project, perhaps you could get the idea from that.
First add an id to slide-over-title, and suggested animations.
<div class="fixed inset-0 overflow-hidden z-[2000] bg-gray-200 transform transition ease-in-out duration-500 sm:duration-700 translate-x-full" aria-labelledby="slide-over-title" id="slide-over-title" role="dialog" aria-modal="true">
then create simple "toggle" function to use anywhere
function toggleSlider() {
if($("#slide-over-title").hasClass("translate-x-full")) {
$("#slide-over-title").removeClass("translate-x-full");
$("#slide-over-title").addClass("translate-x-0");
} else {
$("#slide-over-title").addClass("translate-x-full");
$("#slide-over-title").removeClass("translate-x-0");
}
}
On the snippet i am using the tailwind cdn, but for production you should use the tailwind preprocesor or cli to generate an optimized css file
function toggleSlider() {
if($("#slide-over-title").hasClass("translate-x-full")) {
$("#slide-over-title").removeClass("translate-x-full");
$("#slide-over-title").addClass("translate-x-0");
} else {
$("#slide-over-title").addClass("translate-x-full");
$("#slide-over-title").removeClass("translate-x-0");
}
}
<button onclick="toggleSlider()">Toggle Slider</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<div class="fixed inset-0 overflow-hidden z-[2000] bg-gray-200 transform transition ease-in-out duration-500 sm:duration-700 translate-x-full" aria-labelledby="slide-over-title" id="slide-over-title" role="dialog" aria-modal="true">
<div class="absolute inset-0 overflow-hidden">
<div class="absolute inset-0" aria-hidden="true"></div>
<div class="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 sm:pl-16">
<!--
Slide-over panel, show/hide based on slide-over state.
Entering: "transform transition ease-in-out duration-500 sm:duration-700"
From: "translate-x-full"
To: "translate-x-0"
Leaving: "transform transition ease-in-out duration-500 sm:duration-700"
From: "translate-x-0"
To: "translate-x-full"
-->
<div class="pointer-events-auto w-screen max-w-2xl">
<div class="flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl">
<div class="px-4 sm:px-6">
<div class="flex items-start justify-between">
<h2 class="text-lg font-medium text-gray-900" id="slide-over-title">Panel title</h2>
<div class="ml-3 flex h-7 items-center">
<button type="button" class="rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" onclick="toggleSlider()">
<span class="sr-only">Close panel</span>
<!-- Heroicon name: outline/x -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
<div class="relative mt-6 flex-1 px-4 sm:px-6">
<!-- Replace with your content -->
<div class="absolute inset-0 px-4 sm:px-6">
<div class="h-full border-2 border-dashed border-gray-200" aria-hidden="true"></div>
</div>
<!-- /End replace -->
</div>
</div>
</div>
</div>
</div>
</div>
The easiest way to apply the transition effects without using Vue/React on tailwindui is to use Alpine.js, as explained in the docs:
<div
x-show="isOpen"
x-transition:enter="transition ease-out duration-100 transform"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75 transform"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg"
>
If you want to write it by yourself, then you need to make sure that you first change the display (block/hidden) then you need to wait a frame before you apply the actual transition class. This is required, as changing the status from display:none to display:block does not trigger css transition animations (see Transitions on the CSS display property). Also you need to make sure that you hide your element after the transition has taken place (so ona duration-200 class, you would need to wait 200ms). Otherwise it would be hidden immediately without transition animation.
You could use "visibility" instead of "display", but that would not be a good option for the module, as the background goes over your entire page and makes other buttons unclickable.
To wait one frame before next repaint, you may use the window.requestAnimationFrame() method. Another possibility to implement it is using the setTimeout method, as done at https://stackoverflow.com/a/40447192
I actually found a github repository which implements only this x-transition from alpine with the aim to be used for tailwind-ui transitions https://github.com/CaptainCodeman/x-transition and its ~1kb gzipped, but alpine.js is ~7kb gzipped with a ton of other functionality, so I think it makes sense to go directly with alpine.js
In addition, when you implement it by your own, or use alpine.js, you still need to make sure that you meet the wai aria practices.
I am creating a form that will be fixed to the top of a page. However, when I implement position: fixed to the parent div of the form, the search bar and buttons do not work. Here is the code:
<div className="fixed flex xl:pl-64 md:pl-2 sm:pl-2 p-4 w-2/4 bg-red-600 top-0 w-full ">
<h1 className="text-2xl text-white float-left"> Customer Search </h1>
<input className="border-2 border-gray-300 bg-white h-10 px-5 pr-16 rounded-lg text-sm focus:outline-none"
name="search"
placeholder="Search for..."
type="text"/>
<div className="text-white py-2 px-4 rounded border-2 border-red-100"> search </div>
<div className="text-white py-2 px-4 rounded border-2 border-red-100"> filter </div>
<div className="text-white py-2 px-4 rounded border-2 border-red-100"> clear </div>
</div>
Now, I did it in JSFiddle and the buttons do work. So now I am wondering, what could be wrong with my code? When I remove fixed, the search bar and buttons work just fine.
Welp, I fixed it. Much simpler than anticipated. I just added z-10 to the header. I guess it was being overlapped by some non-viewable thing.
<div style={{'height': '900px'}} className="w-full flex">
<div className="fixed xl:pl-64 md:pl-2 sm:pl-2 p-4 w-full bg-red-600 sm:pb-4 z-10">
<h1 className="text-4xl text-white pl-4 z-50"> Users </h1>
<p className="pt-2 pl-4">
<input className="w-3/4 rounded h-8 border-gray-400 border-2" type="text" placeholder="Search.." name="search"/>
<button className="text-white fa-lg pl-4" type="submit"><FontAwesomeIcon icon={faSearch}/></button>
<button className="ml-6 py-2 px-5 bg-gray-400 shadow z-50">Add User</button>
</p>
</div>