Tailwind CSS and Alpine JS AI Output Interactions
Output interactions allow users to interact with the AI's response. They can be used to copy the result text, share the generated content and more.
This component requires Alpine JS v3 to function properly. Some advanced features may require additional Alpine plugins (such as focus).
Tell Me MoreCopy to clipboard
A button that allows users to copy the AI's response to the clipboard.
Here is a joke about penguins:
Why don't penguins like talking to strangers at parties?
Because they find it too ice-breaking!
<div x-data="{
copiedToClipboard: false,
copyToClipboard() {
navigator.clipboard
.writeText($refs.targetText.textContent)
.then(() => {
this.copiedToClipboard = true
})
.catch((err) => {
this.copiedToClipboard = false
})
},
}" class="">
<pre x-ref="targetText" class="">
<p>Here is a joke about penguins:</p>
<p>Why don't penguins like talking to strangers at parties?</p>
<p>Because they find it too ice-breaking!</p>
</pre>
<button class="" title="Copy" aria-label="Copy" x-on:click="copyToClipboard()" x-on:click.away="copiedToClipboard = false">
<span class="" x-text="copiedToClipboard ? 'copied' : 'copy the response to clipboard'"></span>
<svg
x-show="!copiedToClipboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
class="" aria-hidden="true">
<path fill-rule="evenodd" d="M13.887 3.182c.396.037.79.08 1.183.128C16.194 3.45 17 4.414 17 5.517V16.75A2.25 2.25 0 0 1 14.75 19h-9.5A2.25 2.25 0 0 1 3 16.75V5.517c0-1.103.806-2.068 1.93-2.207.393-.048.787-.09 1.183-.128A3.001 3.001 0 0 1 9 1h2c1.373 0 2.531.923 2.887 2.182ZM7.5 4A1.5 1.5 0 0 1 9 2.5h2A1.5 1.5 0 0 1 12.5 4v.5h-5V4Z" clip-rule="evenodd"/>
</svg>
<svg x-show="copiedToClipboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M11.986 3H12a2 2 0 0 1 2 2v6a2 2 0 0 1-1.5 1.937V7A2.5 2.5 0 0 0 10 4.5H4.063A2 2 0 0 1 6 3h.014A2.25 2.25 0 0 1 8.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM10.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z" clip-rule="evenodd"/>
<path fill-rule="evenodd" d="M2 7a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm6.585 1.08a.75.75 0 0 1 .336 1.005l-1.75 3.5a.75.75 0 0 1-1.16.234l-1.75-1.5a.75.75 0 0 1 .977-1.139l1.02.875 1.321-2.64a.75.75 0 0 1 1.006-.336Z" clip-rule="evenodd"/>
</svg>
</button>
</div>
Download button
A button to download AI-generated content. Please remember that this feature only works for assets hosted on the same origin. If you use a cross-origin URL, the download won't work, and the file will open directly in your browser.
<div class="">
<img src="/your-file" alt="variation 1 - image in webp format" class="" />
<a role="button" href="/your-file" download="penguin-ai-robot" class="">
<span class="">download variation 1</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
</a>
</div>
Share widget/modal
Share
<div x-data="{
fallbackModalIsOpen: false,
copiedToClipboard: false,
share() {
// check if web share API is available
if (navigator.share) {
navigator.share({
title: document.title,
text: 'Check out this site',
url: window.location.href,
})
} else {
this.fallbackModalIsOpen = true
}
},
copyUrlToClipboard(url) {
navigator.clipboard
.writeText(url)
.then(() => {
this.copiedToClipboard = true
})
.catch((err) => {
this.copiedToClipboard = false
})
},
}">
<button title="Share" x-on:click="share()" class="">
<span class="">share</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="">
<path fill-rule="evenodd" d="M15.75 4.5a3 3 0 1 1 .825 2.066l-8.421 4.679a3.002 3.002 0 0 1 0 1.51l8.421 4.679a3 3 0 1 1-.729 1.31l-8.421-4.678a3 3 0 1 1 0-4.132l8.421-4.679a3 3 0 0 1-.096-.755Z" clip-rule="evenodd" />
</svg>
</button>
<!-- Modal -->
<div x-cloak x-show="fallbackModalIsOpen" class="" role="dialog" aria-labelledby="sharetModalTitle" aria-modal="true" x-on:click.self="fallbackModalIsOpen = false" x-on:keydown.esc.window="fallbackModalIsOpen = false" x-transition.opacity.duration.200ms x-trap.inert.noscroll="fallbackModalIsOpen">
<div x-show="fallbackModalIsOpen" class="" x-transition:enter="transition delay-100 duration-200 ease-out motion-reduce:transition-opacity" x-transition:enter-end="scale-100 opacity-100" x-transition:enter-start="scale-50 opacity-0">
<!-- Dialog Header -->
<div class="">
<h3 id="sharetModalTitle" class="">Share</h3>
<button aria-label="close modal" x-on:click="fallbackModalIsOpen = false">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="">
<path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z" clip-rule="evenodd" />
</svg>
</button>
</div>
<!-- Dialog Body -->
<div class="">
<!-- Social Icons -->
<div class="">
<!-- X - Twitter -->
<a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.penguinui.com%2F&text=UI%20Components%20for%20Tailwind%20CSS%20and%20Alpine%20JS" class="" target="_blank">
<div class="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="">
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z" />
</svg>
</div>
<span class="">X(Twitter)</span>
</a>
<!-- Facebook -->
<a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.penguinui.com%2F" class="" target="_blank">
<div class="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="">
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951" />
</svg>
</div>
<span class="">Facebook</span>
</a>
<!-- Reddit -->
<a href="http://www.reddit.com/submit?url=https%3A%2F%2Fwww.penguinui.com%2F&title=UI%20Components%20for%20Tailwind%20CSS%20and%20Alpine%20JS" class="" target="_blank">
<div class="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="">
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z" />
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165" />
</svg>
</div>
<span class="">Reddit</span>
</a>
<!-- LinkedIn -->
<a href="http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.penguinui.com%2F&title=UI%20Components%20for%20Tailwind%20CSS%20and%20Alpine%20JS" class="" target="_blank">
<div class="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="">
<path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854zm4.943 12.248V6.169H2.542v7.225zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248S2.4 3.226 2.4 3.934c0 .694.521 1.248 1.327 1.248zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016l.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225z" />
</svg>
</div>
<span class="">Linkedin</span>
</a>
<!-- Email -->
<a href="mailto:?subject=Check out Penguin UI&body=Check out this cool UI components library http://www.penguinui.com." class="" target="_blank">
<div class="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="">
<path d="M1.5 8.67v8.58a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V8.67l-8.928 5.493a3 3 0 0 1-3.144 0L1.5 8.67Z" />
<path d="M22.5 6.908V6.75a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v.158l9.714 5.978a1.5 1.5 0 0 0 1.572 0L22.5 6.908Z" />
</svg>
</div>
<span class="">Email</span>
</a>
</div>
<!-- Copy -->
<div class="">
<label for="shareLink" class="">share link</label>
<input id="shareLink" type="text" class="" x-ref="shareUrl" x-bind:value="window.location.href" />
<button class="" x-on:click="copyUrlToClipboard($refs.shareUrl.value)" x-on:click.away="copiedToClipboard = false">
<span class="" x-text="copiedToClipboard ? 'copied' : 'copy the url to clipboard'"></span>
<svg x-cloak x-show="!copiedToClipboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" />
</svg>
<svg x-cloak x-show="copiedToClipboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" aria-hidden="true" class="">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m8.9-4.414c.376.023.75.05 1.124.08 1.131.094 1.976 1.057 1.976 2.192V16.5A2.25 2.25 0 0 1 18 18.75h-2.25m-7.5-10.5H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V18.75m-7.5-10.5h6.375c.621 0 1.125.504 1.125 1.125v9.375m-8.25-3 1.5 1.5 3-3.75" />
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
Data
List of all Alpine JS data used in this component.
Property | Description |
---|---|
copiedToClipboard |
Boolean - Target text is copied to clipboard
|
copyToClipboard() copyUrlToClipboard(url) |
Function - Copies the target text to clipboard
|
share() |
Function - Triggers the share action to display the share widget or modal
|
fallbackModalIsOpen |
Boolean - The fall back share modal is open (When weh share API is not available)
|
Keyboard Navigation
Key | Action |
---|---|
Tab |
Next focusable element gets the focus
|
Space Enter | Focused item gets selected |