This post is more than a year old. There is a chance the content is outdated.

Snippet 5: Creating a simple, but cool delete button with Alpine.js and TailwindCSS

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 <div
17 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 @csrf
30 @method('delete')
31 
32 <button
33 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 <button
42 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>
Anthony Rappa

By Anthony Rappa

Hello! I'm a full stack developer from Long Island, New York. Working mainly with Laravel, Tailwind, Livewire, and Alpine.js (TALL Stack). I share everything I know about these tools and more, as well as any useful resources I find from the community. You can find me on GitHub and LinkedIn.