-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add BaseInputFileHeadless demos
- Loading branch information
1 parent
c2a97b7
commit 0cd535f
Showing
1 changed file
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
<script setup lang="ts"> | ||
definePageMeta({ | ||
title: 'BaseInputFileHeadless', | ||
icon: 'system-uicons:cloud-upload', | ||
description: 'Headless input file component', | ||
section: 'form', | ||
}) | ||
// This is the computed value that will be used to display the current avatar | ||
const currentAvatar = computed( | ||
() => 'https://tairo.cssninja.io/img/avatars/10.svg', | ||
) | ||
const inputFile = ref<FileList | null>(null) | ||
const uploadedFiles = ref<FileList | null>(null) | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<NuiPreviewContainer title="BaseInputFileHeadless"> | ||
<NuiPreview title="Profile" description="Profile upload variation"> | ||
<div> | ||
<form action="" method="POST" @submit.prevent=""> | ||
<BaseInputFileHeadless | ||
accept="image/*" | ||
v-model="inputFile" | ||
v-slot="{ open, remove, preview, files }" | ||
> | ||
<div class="relative h-20 w-20"> | ||
<img | ||
v-if="files?.length && files.item(0)" | ||
:src="preview(files.item(0)!).value" | ||
alt="Upload preview" | ||
class="bg-muted-200 dark:bg-muted-700/60 h-20 w-20 rounded-full object-cover object-center" | ||
/> | ||
|
||
<img | ||
v-else | ||
:src="currentAvatar" | ||
alt="Upload preview" | ||
class="bg-muted-200 dark:bg-muted-700/60 h-20 w-20 rounded-full object-cover object-center dark:invert" | ||
/> | ||
|
||
<div | ||
v-if="files?.length && files.item(0)" | ||
class="absolute bottom-0 end-0 z-20" | ||
> | ||
<BaseButtonIcon | ||
size="sm" | ||
rounded="full" | ||
@click="remove(files.item(0)!)" | ||
data-nui-tooltip="Remove image" | ||
class="scale-90" | ||
> | ||
<Icon name="lucide:x" class="h-4 w-4" /> | ||
</BaseButtonIcon> | ||
</div> | ||
|
||
<div v-else class="absolute bottom-0 end-0 z-20"> | ||
<div class="relative" data-nui-tooltip="Upload image"> | ||
<BaseButtonIcon size="sm" rounded="full" @click="open"> | ||
<Icon name="lucide:plus" class="h-4 w-4" /> | ||
</BaseButtonIcon> | ||
</div> | ||
</div> | ||
</div> | ||
</BaseInputFileHeadless> | ||
</form> | ||
</div> | ||
</NuiPreview> | ||
|
||
<NuiPreview title="File" description="File upload variation"> | ||
<div class="max-w-xl"> | ||
<BaseInputFileHeadless | ||
multiple | ||
v-model="uploadedFiles" | ||
v-slot="{ open, remove, preview, drop, files }" | ||
> | ||
<!-- Controls --> | ||
<div class="mb-4 flex items-center gap-2"> | ||
<button | ||
type="button" | ||
class="nui-focus border-muted-200 hover:border-primary-500 text-muted-700 dark:text-muted-200 hover:text-primary-600 dark:border-muted-700 dark:bg-muted-800 dark:hover:border-primary-500 dark:hover:text-primary-600 relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border bg-white transition-colors duration-300" | ||
tooltip="Select files" | ||
@click="open" | ||
> | ||
<Icon name="lucide:plus" class="h-4 w-4" /> | ||
|
||
<span class="sr-only">Select files</span> | ||
</button> | ||
|
||
<button | ||
type="button" | ||
class="nui-focus border-muted-200 hover:border-primary-500 text-muted-700 dark:text-muted-200 hover:text-primary-600 dark:border-muted-700 dark:bg-muted-800 dark:hover:border-primary-500 dark:hover:text-primary-600 relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border bg-white transition-colors duration-300" | ||
tooltip="Start Upload" | ||
> | ||
<Icon name="lucide:arrow-up" class="h-4 w-4" /> | ||
|
||
<span class="sr-only">Start Upload</span> | ||
</button> | ||
</div> | ||
|
||
<div | ||
class="" | ||
@dragenter.stop.prevent | ||
@dragover.stop.prevent | ||
@drop="drop" | ||
> | ||
<div | ||
v-if="!files?.length" | ||
class="nui-focus border-muted-300 dark:border-muted-700 hover:border-muted-400 focus:border-muted-400 dark:hover:border-muted-600 dark:focus:border-muted-700 group cursor-pointer rounded-lg border-[3px] border-dashed p-8 transition-colors duration-300" | ||
tabindex="0" | ||
role="button" | ||
@click="open" | ||
@keydown.enter.prevent="open" | ||
> | ||
<div class="p-5 text-center"> | ||
<Icon | ||
name="mdi-light:cloud-upload" | ||
class="text-muted-400 group-hover:text-primary-500 group-focus:text-primary-500 mb-2 h-10 w-10 transition-colors duration-300" | ||
/> | ||
|
||
<h4 class="text-muted-400 font-sans text-sm"> | ||
Drop files to upload | ||
</h4> | ||
|
||
<div> | ||
<span | ||
class="text-muted-400 font-sans text-[0.7rem] font-semibold uppercase" | ||
> | ||
Or | ||
</span> | ||
</div> | ||
|
||
<label | ||
for="file" | ||
class="text-muted-400 group-hover:text-primary-500 group-focus:text-primary-500 cursor-pointer font-sans text-sm underline underline-offset-4 transition-colors duration-300" | ||
> | ||
Select files | ||
</label> | ||
</div> | ||
</div> | ||
|
||
<ul v-else class="mt-6 space-y-2"> | ||
<li v-for="file in files" :key="file.name"> | ||
<div | ||
class="border-muted-200 dark:border-muted-700 dark:bg-muted-800 relative flex items-center justify-end gap-2 rounded-xl border bg-white p-3" | ||
> | ||
<div class="flex items-center gap-2"> | ||
<div class="shrink-0"> | ||
<img | ||
class="h-14 w-14 rounded-xl object-cover object-center" | ||
v-if="file.type.startsWith('image')" | ||
:src="preview(file).value" | ||
alt="Image preview" | ||
/> | ||
|
||
<img | ||
v-else | ||
class="h-14 w-14 rounded-xl object-cover object-center" | ||
src="/img/avatars/placeholder-file.png" | ||
alt="Image preview" | ||
/> | ||
</div> | ||
|
||
<div class="font-sans"> | ||
<span | ||
class="text-muted-800 dark:text-muted-100 line-clamp-1 block text-sm" | ||
> | ||
{{ file.name }} | ||
</span> | ||
|
||
<span class="text-muted-400 block text-xs"> | ||
{{ formatFileSize(file.size) }} | ||
</span> | ||
</div> | ||
</div> | ||
|
||
<div | ||
class="ms-auto w-32 px-4 transition-opacity duration-300" | ||
:class="'opacity-100'" | ||
> | ||
<BaseProgress :value="0" size="xs" :color="'success'" /> | ||
</div> | ||
|
||
<div class="flex gap-2"> | ||
<button | ||
class="border-muted-200 hover:border-primary-500 text-muted-700 dark:text-muted-200 hover:text-primary-600 dark:border-muted-700 dark:bg-muted-900 dark:hover:border-primary-500 dark:hover:text-primary-600 relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border bg-white transition-colors duration-300 disabled:cursor-not-allowed disabled:opacity-60" | ||
disabled | ||
type="button" | ||
tooltip="Cancel" | ||
> | ||
<Icon name="lucide:slash" class="h-4 w-4" /> | ||
|
||
<span class="sr-only">Cancel</span> | ||
</button> | ||
|
||
<button | ||
class="border-muted-200 hover:border-primary-500 text-muted-700 dark:text-muted-200 hover:text-primary-600 dark:border-muted-700 dark:bg-muted-900 dark:hover:border-primary-500 dark:hover:text-primary-600 relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border bg-white transition-colors duration-300" | ||
type="button" | ||
tooltip="Upload" | ||
> | ||
<Icon name="lucide:arrow-up" class="h-4 w-4" /> | ||
|
||
<span class="sr-only">Upload</span> | ||
</button> | ||
|
||
<button | ||
class="border-muted-200 hover:border-primary-500 text-muted-700 dark:text-muted-200 hover:text-primary-600 dark:border-muted-700 dark:bg-muted-900 dark:hover:border-primary-500 dark:hover:text-primary-600 relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border bg-white transition-colors duration-300" | ||
type="button" | ||
tooltip="Remove" | ||
@click.prevent="remove(file)" | ||
> | ||
<Icon name="lucide:x" class="h-4 w-4" /> | ||
|
||
<span class="sr-only">Remove</span> | ||
</button> | ||
</div> | ||
</div> | ||
</li> | ||
</ul> | ||
</div> | ||
</BaseInputFileHeadless> | ||
</div> | ||
</NuiPreview> | ||
</NuiPreviewContainer> | ||
</div> | ||
</template> |