Snippet 5: Creating a simple, but cool delete button with Alpine.js and TailwindCSS
Sometimes ideas pop into my head that I don't immediately need, but I think are a good exercise. So I carve out 15 minutes of my day to code an example to learn and save to my library of components for future use.
The idea today came from building a delete modal for a website. I just found it to be a lot of code and work to pop up a whole extra element for the sheer use of just clicking a confirm button.
So I figured why not give it a shot and inline it. Keep in mind I've put no thought into any accessibility or mobile aspects of this type of approach.
I wanted it to use Alpine.js, Tailwind, have transitions, support dark mode, and localization.
This is what I came up with:
I even made it dispatch an event so that it can disable other delete buttons around it if need be:
It uses a regular HTML form under the hood with a delete request, so you would need a Laravel route like so:
1Route::delete('{item}', [ItemController::class, 'delete'])->name('item.delete')
This is how you would use it:
1<x-buttons.delete :action="route('item.delete', $item)" />
Final Component
1@props(['action', 'buttonText' => __('Delete')]) 2 3<div x-data="{ initial: true, deleting: false }" class="text-sm flex items-center"> 4 <button 5 x-on:click.prevent="deleting = true; initial = false" 6 x-show="initial" 7 x-on:deleting.window="$el.disabled = true" 8 x-transition:enter="transition ease-out duration-150" 9 x-transition:enter-start="opacity-0 transform scale-90"10 x-transition:enter-end="opacity-100 transform scale-100"11 class="text-white p-1 rounded bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 disabled:opacity-50"12 >13 {{ $buttonText }}14 </button>15 16 <div17 x-show="deleting"18 x-transition:enter="transition ease-out duration-150"19 x-transition:enter-start="opacity-0 transform scale-90"20 x-transition:enter-end="opacity-100 transform scale-100"21 x-transition:leave="transition ease-in duration-150"22 x-transition:leave-start="opacity-100 transform scale-100"23 x-transition:leave-end="opacity-0 transform scale-90"24 class="flex items-center space-x-3"25 >26 <span class="dark:text-white">@lang('Are you sure?')</span>27 28 <form x-on:submit="$dispatch('deleting')" method="post" action="{{ $action }}">29 @csrf30 @method('delete')31 32 <button33 x-on:click="$el.form.submit()"34 x-on:deleting.window="$el.disabled = true"35 type="submit"36 class="text-white p-1 rounded bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 disabled:opacity-50"37 >38 @lang('Yes')39 </button>40 41 <button42 x-on:click.prevent="deleting = false; setTimeout(() => { initial = true }, 150)"43 x-on:deleting.window="$el.disabled = true"44 class="text-white p-1 rounded bg-gray-600 hover:bg-gray-700 dark:bg-gray-500 dark:hover:bg-gray-600 disabled:opacity-50"45 >46 @lang('No')47 </button>48 </form>49 </div>50</div>