Tailwind black magic: swallowing all pointer events
I wrote two days ago about a real and useful application of Tailwind black magic; here's another.
Buttondown has a dropzone component lets folks drag-and-drop items or click on it to get a file-picker. It's used for importing images, archives, CSVs, the works: because it's so flexible, we expose a slot so that components can customize the text and copy as they see fit:
<template>
<button id="dropzone" ref="dropzoneElement" @click="handleUpload">
<slot />
</button>
</template>
This of course comes with a problem, which is that if you pass in a block element such as a div:
<template>
<Dropzone>
<div> Click to upload a CSV. </div>
</Dropzone>
</template>
Users who click the div won't trigger handleUpload, as the div intercepts the click event. You can of course fix this by manually catching and ignoring the click event on the div (or setting it to pointer-events: none); or you can add a simple rule to the button to ignore pointer events on all of its children:
<template>
<button
id="dropzone"
ref="dropzoneElement"
class="[&>*]:pointer-events-none"
@click="handleUpload"
>
<slot />
</button>
</template>
And voila! Broken down a little:
[&>*]:pointer-events-nonemeans "setpointer-events: noneto all elements that satisfy the rule of[&>*];[&>*]is Tailwind-ese for "> *, relative to the current element`;> *is standard CSS for "all direct children".