compote-ui 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/file-upload/{dropzone.svelte → file-upload-dropzone.svelte} +2 -2
- package/dist/components/file-upload/file-upload-dropzone.svelte.d.ts +4 -0
- package/dist/components/file-upload/file-upload.svelte +90 -0
- package/dist/components/file-upload/file-upload.svelte.d.ts +5 -0
- package/dist/components/file-upload/types.d.ts +7 -1
- package/dist/components/image-crop-dialog/image-crop-dialog.svelte +8 -1
- package/dist/components/image-cropper/image-cropper.svelte +2 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/components/file-upload/basic-document.svelte +0 -89
- package/dist/components/file-upload/basic-document.svelte.d.ts +0 -4
- package/dist/components/file-upload/basic.svelte +0 -50
- package/dist/components/file-upload/basic.svelte.d.ts +0 -18
- package/dist/components/file-upload/dropzone.svelte.d.ts +0 -4
- package/dist/components/file-upload/files-list.svelte +0 -97
- package/dist/components/file-upload/files-list.svelte.d.ts +0 -18
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { FileUpload } from '@ark-ui/svelte/file-upload';
|
|
3
3
|
import { getAcceptAttribute } from './utils';
|
|
4
|
-
import type {
|
|
4
|
+
import type { FileUploadDropzoneProps } from './types';
|
|
5
5
|
import PhUploadSimple from '../../icons/PhUploadSimple.svelte';
|
|
6
6
|
|
|
7
7
|
let {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
maxFiles = 1,
|
|
11
11
|
onFileAccept,
|
|
12
12
|
...restProps
|
|
13
|
-
}:
|
|
13
|
+
}: FileUploadDropzoneProps = $props();
|
|
14
14
|
|
|
15
15
|
const accept = $derived(getAcceptAttribute(fileType));
|
|
16
16
|
</script>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { FileUpload, type FileUploadFileError } from '@ark-ui/svelte/file-upload';
|
|
3
|
+
import PhX from '../../icons/PhX.svelte';
|
|
4
|
+
import type { FileUploadProps } from './types';
|
|
5
|
+
import { getAcceptAttribute } from './utils';
|
|
6
|
+
import { getFileIcon } from './icons';
|
|
7
|
+
|
|
8
|
+
const errorMessages: Record<FileUploadFileError, string> = {
|
|
9
|
+
TOO_MANY_FILES: 'Too many files',
|
|
10
|
+
FILE_INVALID_TYPE: 'Invalid file type',
|
|
11
|
+
FILE_TOO_LARGE: 'File too large',
|
|
12
|
+
FILE_TOO_SMALL: 'File too small',
|
|
13
|
+
FILE_INVALID: 'Invalid file',
|
|
14
|
+
FILE_EXISTS: 'File already exists'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
fileType,
|
|
19
|
+
label,
|
|
20
|
+
triggerLabel = 'Choose file',
|
|
21
|
+
maxFiles = 1,
|
|
22
|
+
...restProps
|
|
23
|
+
}: FileUploadProps = $props();
|
|
24
|
+
|
|
25
|
+
const accept = $derived(getAcceptAttribute(fileType));
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<FileUpload.Root {maxFiles} {accept} class="flex flex-col gap-1.5" {...restProps}>
|
|
29
|
+
{#if label}
|
|
30
|
+
<FileUpload.Label class="text-sm font-medium">{label}</FileUpload.Label>
|
|
31
|
+
{/if}
|
|
32
|
+
|
|
33
|
+
<FileUpload.Context>
|
|
34
|
+
{#snippet render(context)}
|
|
35
|
+
{@const ctx = context()}
|
|
36
|
+
{@const accepted = ctx.acceptedFiles}
|
|
37
|
+
{@const rejected = ctx.rejectedFiles}
|
|
38
|
+
|
|
39
|
+
{#if maxFiles === 1}
|
|
40
|
+
{#if accepted.length === 0}
|
|
41
|
+
<FileUpload.Trigger
|
|
42
|
+
class="inline-flex h-9 cursor-pointer items-center gap-2 rounded border px-3 text-sm text-ink transition-colors hover:bg-surface-2 disabled:pointer-events-none disabled:opacity-50"
|
|
43
|
+
>
|
|
44
|
+
{triggerLabel}
|
|
45
|
+
</FileUpload.Trigger>
|
|
46
|
+
{/if}
|
|
47
|
+
{:else}
|
|
48
|
+
<FileUpload.Trigger
|
|
49
|
+
disabled={accepted.length >= maxFiles}
|
|
50
|
+
class="inline-flex h-9 cursor-pointer items-center gap-2 rounded border px-3 text-sm text-ink transition-colors hover:bg-surface-2 disabled:pointer-events-none disabled:opacity-50"
|
|
51
|
+
>
|
|
52
|
+
{triggerLabel}
|
|
53
|
+
</FileUpload.Trigger>
|
|
54
|
+
{/if}
|
|
55
|
+
|
|
56
|
+
<FileUpload.ItemGroup class="flex flex-col gap-1">
|
|
57
|
+
{#each accepted as file (file.name)}
|
|
58
|
+
<FileUpload.Item {file} class="flex items-center gap-2 rounded border px-3 py-2 text-sm">
|
|
59
|
+
<FileUpload.ItemPreview type="image/*">
|
|
60
|
+
<FileUpload.ItemPreviewImage class="size-8 shrink-0 rounded object-cover" />
|
|
61
|
+
</FileUpload.ItemPreview>
|
|
62
|
+
{#if !file.type.startsWith('image/')}
|
|
63
|
+
{@const Icon = getFileIcon(file)}
|
|
64
|
+
<Icon class="size-4 shrink-0" />
|
|
65
|
+
{/if}
|
|
66
|
+
<FileUpload.ItemName class="flex-1 truncate" />
|
|
67
|
+
<FileUpload.ItemSizeText class="shrink-0 text-xs text-ink-dim" />
|
|
68
|
+
<FileUpload.ItemDeleteTrigger
|
|
69
|
+
class="ml-auto shrink-0 cursor-pointer text-ink-dim transition-colors hover:text-ink"
|
|
70
|
+
>
|
|
71
|
+
<PhX class="size-4" />
|
|
72
|
+
</FileUpload.ItemDeleteTrigger>
|
|
73
|
+
</FileUpload.Item>
|
|
74
|
+
{/each}
|
|
75
|
+
</FileUpload.ItemGroup>
|
|
76
|
+
|
|
77
|
+
{#if rejected.length > 0}
|
|
78
|
+
<div class="mt-1 flex flex-col gap-0.5">
|
|
79
|
+
{#each rejected as rejection (rejection.file.name)}
|
|
80
|
+
<p class="text-xs text-red-600">
|
|
81
|
+
{rejection.file.name}: {rejection.errors.map((e) => errorMessages[e]).join(', ')}
|
|
82
|
+
</p>
|
|
83
|
+
{/each}
|
|
84
|
+
</div>
|
|
85
|
+
{/if}
|
|
86
|
+
{/snippet}
|
|
87
|
+
</FileUpload.Context>
|
|
88
|
+
|
|
89
|
+
<FileUpload.HiddenInput />
|
|
90
|
+
</FileUpload.Root>
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { FileUploadRootProps } from '@ark-ui/svelte/file-upload';
|
|
2
2
|
import type { FileType } from './utils';
|
|
3
|
-
export interface
|
|
3
|
+
export interface FileUploadDropzoneProps extends FileUploadRootProps {
|
|
4
4
|
fileType: FileType;
|
|
5
5
|
label: string;
|
|
6
6
|
}
|
|
7
|
+
export interface FileUploadProps extends Omit<FileUploadRootProps, 'accept'> {
|
|
8
|
+
fileType?: FileType;
|
|
9
|
+
label?: string;
|
|
10
|
+
triggerLabel?: string;
|
|
11
|
+
maxFiles?: number;
|
|
12
|
+
}
|
|
@@ -47,7 +47,14 @@
|
|
|
47
47
|
}
|
|
48
48
|
</script>
|
|
49
49
|
|
|
50
|
-
<Dialog
|
|
50
|
+
<Dialog
|
|
51
|
+
bind:open
|
|
52
|
+
{title}
|
|
53
|
+
{description}
|
|
54
|
+
onOpenChange={(details) => {
|
|
55
|
+
if (!details.open) onCancel();
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
51
58
|
<ImageCropper bind:getCropData src={imageSrc} alt="Crop preview" {aspectRatio} />
|
|
52
59
|
{#snippet footer()}
|
|
53
60
|
<Button variant="outline" onclick={onCancel} disabled={processing}>Cancel</Button>
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
// eslint-disable-next-line no-useless-assignment
|
|
49
49
|
getCropData = () => imageCropper().getCropData();
|
|
50
50
|
// eslint-disable-next-line no-useless-assignment
|
|
51
|
-
getProcessedImage = (opts?: ProcessImageOptions) =>
|
|
51
|
+
getProcessedImage = (opts?: ProcessImageOptions) =>
|
|
52
|
+
cropImage(src, imageCropper().getCropData(), opts);
|
|
52
53
|
|
|
53
54
|
let cropData = $derived(imageCropper().getCropData());
|
|
54
55
|
</script>
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ export { default as Combobox } from './components/combobox/combobox.svelte';
|
|
|
8
8
|
export { default as Dialog } from './components/dialog/dialog.svelte';
|
|
9
9
|
export { default as AlertDialog } from './components/dialog/alert-dialog.svelte';
|
|
10
10
|
export type { DialogProps, AlertDialogProps } from './components/dialog/dialog.types';
|
|
11
|
-
export { default as FileUploadDropzone } from './components/file-upload/dropzone.svelte';
|
|
12
|
-
export { default as
|
|
11
|
+
export { default as FileUploadDropzone } from './components/file-upload/file-upload-dropzone.svelte';
|
|
12
|
+
export { default as FileUpload } from './components/file-upload/file-upload.svelte';
|
|
13
|
+
export type { FileUploadProps } from './components/file-upload/types';
|
|
13
14
|
export type { FileType } from './components/file-upload/utils';
|
|
14
15
|
export { default as ImageCropper } from './components/image-cropper/image-cropper.svelte';
|
|
15
16
|
export type { ImageCropperProps, ImageCropperCropData } from './components/image-cropper/types';
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ export { default as CheckboxGroup } from './components/checkbox/checkbox-group.s
|
|
|
7
7
|
export { default as Combobox } from './components/combobox/combobox.svelte';
|
|
8
8
|
export { default as Dialog } from './components/dialog/dialog.svelte';
|
|
9
9
|
export { default as AlertDialog } from './components/dialog/alert-dialog.svelte';
|
|
10
|
-
export { default as FileUploadDropzone } from './components/file-upload/dropzone.svelte';
|
|
11
|
-
export { default as
|
|
10
|
+
export { default as FileUploadDropzone } from './components/file-upload/file-upload-dropzone.svelte';
|
|
11
|
+
export { default as FileUpload } from './components/file-upload/file-upload.svelte';
|
|
12
12
|
export { default as ImageCropper } from './components/image-cropper/image-cropper.svelte';
|
|
13
13
|
export { default as ImageCropDialog } from './components/image-crop-dialog/image-crop-dialog.svelte';
|
|
14
14
|
export { default as Listbox } from './components/listbox/listbox.svelte';
|
package/package.json
CHANGED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { FileUpload } from '@ark-ui/svelte/file-upload';
|
|
3
|
-
import { Field } from '@ark-ui/svelte/field';
|
|
4
|
-
|
|
5
|
-
import { getFileIcon } from './icons';
|
|
6
|
-
|
|
7
|
-
import { getAcceptAttribute } from './utils';
|
|
8
|
-
import type { Props } from './types';
|
|
9
|
-
import PhFileText from '../../icons/PhFileText.svelte';
|
|
10
|
-
|
|
11
|
-
let {
|
|
12
|
-
fileType,
|
|
13
|
-
acceptedFiles,
|
|
14
|
-
onFileChange = $bindable(),
|
|
15
|
-
label,
|
|
16
|
-
...restProps
|
|
17
|
-
}: Props = $props();
|
|
18
|
-
const accept = $derived(getAcceptAttribute(fileType));
|
|
19
|
-
// const id = $props.id();
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<!-- {id} -->
|
|
23
|
-
|
|
24
|
-
<Field.Root class="w-full max-w-sm">
|
|
25
|
-
<FileUpload.Root
|
|
26
|
-
{...restProps}
|
|
27
|
-
maxFiles={1}
|
|
28
|
-
{accept}
|
|
29
|
-
{acceptedFiles}
|
|
30
|
-
{onFileChange}
|
|
31
|
-
class="flex flex-col items-start gap-3"
|
|
32
|
-
>
|
|
33
|
-
{#if label}
|
|
34
|
-
<Field.Label>
|
|
35
|
-
{label}
|
|
36
|
-
</Field.Label>
|
|
37
|
-
{/if}
|
|
38
|
-
<FileUpload.Context>
|
|
39
|
-
{#snippet render(context)}
|
|
40
|
-
<div class="flex items-center gap-3">
|
|
41
|
-
<!-- Image Preview / Placeholder -->
|
|
42
|
-
<div
|
|
43
|
-
class="flex h-10 w-10 items-center justify-center overflow-hidden rounded-xl border bg-surface-2"
|
|
44
|
-
>
|
|
45
|
-
{#if context().acceptedFiles.length > 0}
|
|
46
|
-
<FileUpload.ItemGroup>
|
|
47
|
-
{#each context().acceptedFiles as file (file.name)}
|
|
48
|
-
<FileUpload.Item file={context().acceptedFiles[0]}>
|
|
49
|
-
{#if file.type.startsWith('image/')}
|
|
50
|
-
<FileUpload.ItemPreview type="image/*">
|
|
51
|
-
<FileUpload.ItemPreviewImage class="h-full w-full object-cover" />
|
|
52
|
-
</FileUpload.ItemPreview>
|
|
53
|
-
{:else}
|
|
54
|
-
{@const IconComponent = getFileIcon(file)}
|
|
55
|
-
<IconComponent />
|
|
56
|
-
{/if}
|
|
57
|
-
</FileUpload.Item>
|
|
58
|
-
{/each}
|
|
59
|
-
</FileUpload.ItemGroup>
|
|
60
|
-
{:else}
|
|
61
|
-
<PhFileText class="h-5 w-5 text-ink-dim" />
|
|
62
|
-
{/if}
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<!-- Upload/Change Button -->
|
|
66
|
-
<FileUpload.Trigger
|
|
67
|
-
class="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-white hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:outline-hidden"
|
|
68
|
-
>
|
|
69
|
-
{context().acceptedFiles.length > 0 ? 'Change image' : 'Upload image'}
|
|
70
|
-
</FileUpload.Trigger>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<!-- Filename and Remove -->
|
|
74
|
-
{#if context().acceptedFiles.length > 0}
|
|
75
|
-
<FileUpload.ItemGroup>
|
|
76
|
-
<FileUpload.Item file={context().acceptedFiles[0]} class="flex items-center gap-2">
|
|
77
|
-
<FileUpload.ItemName class="text-sm text-ink-dim" />
|
|
78
|
-
<FileUpload.ItemDeleteTrigger class="text-sm text-red-500 hover:text-red-600">
|
|
79
|
-
Remove
|
|
80
|
-
</FileUpload.ItemDeleteTrigger>
|
|
81
|
-
</FileUpload.Item>
|
|
82
|
-
</FileUpload.ItemGroup>
|
|
83
|
-
{/if}
|
|
84
|
-
{/snippet}
|
|
85
|
-
</FileUpload.Context>
|
|
86
|
-
|
|
87
|
-
<FileUpload.HiddenInput />
|
|
88
|
-
</FileUpload.Root>
|
|
89
|
-
</Field.Root>
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import PhUser from '../../icons/PhUser.svelte';
|
|
3
|
-
import { FileUpload } from '@ark-ui/svelte/file-upload';
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<FileUpload.Root maxFiles={1} accept="image/*" class="flex flex-col items-start gap-3">
|
|
7
|
-
<FileUpload.Context>
|
|
8
|
-
{#snippet render(context)}
|
|
9
|
-
<div class="flex items-center gap-3">
|
|
10
|
-
<!-- Image Preview / Placeholder -->
|
|
11
|
-
<div
|
|
12
|
-
class="flex h-10 w-10 items-center justify-center overflow-hidden rounded-xl border bg-surface-2"
|
|
13
|
-
>
|
|
14
|
-
{#if context().acceptedFiles.length > 0}
|
|
15
|
-
<FileUpload.ItemGroup>
|
|
16
|
-
<FileUpload.Item file={context().acceptedFiles[0]}>
|
|
17
|
-
<FileUpload.ItemPreview type="image/*">
|
|
18
|
-
<FileUpload.ItemPreviewImage class="h-full w-full object-cover" />
|
|
19
|
-
</FileUpload.ItemPreview>
|
|
20
|
-
</FileUpload.Item>
|
|
21
|
-
</FileUpload.ItemGroup>
|
|
22
|
-
{:else}
|
|
23
|
-
<PhUser class="h-5 w-5 text-ink-dim" />
|
|
24
|
-
{/if}
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<!-- Upload/Change Button -->
|
|
28
|
-
<FileUpload.Trigger
|
|
29
|
-
class="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-white hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:outline-hidden"
|
|
30
|
-
>
|
|
31
|
-
{context().acceptedFiles.length > 0 ? 'Change image' : 'Upload image'}
|
|
32
|
-
</FileUpload.Trigger>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<!-- Filename and Remove -->
|
|
36
|
-
{#if context().acceptedFiles.length > 0}
|
|
37
|
-
<FileUpload.ItemGroup>
|
|
38
|
-
<FileUpload.Item file={context().acceptedFiles[0]} class="flex items-center gap-2">
|
|
39
|
-
<FileUpload.ItemName class="text-sm text-ink-dim" />
|
|
40
|
-
<FileUpload.ItemDeleteTrigger class="text-sm text-red-500 hover:text-red-600">
|
|
41
|
-
Remove
|
|
42
|
-
</FileUpload.ItemDeleteTrigger>
|
|
43
|
-
</FileUpload.Item>
|
|
44
|
-
</FileUpload.ItemGroup>
|
|
45
|
-
{/if}
|
|
46
|
-
{/snippet}
|
|
47
|
-
</FileUpload.Context>
|
|
48
|
-
|
|
49
|
-
<FileUpload.HiddenInput />
|
|
50
|
-
</FileUpload.Root>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
-
$$bindings?: Bindings;
|
|
4
|
-
} & Exports;
|
|
5
|
-
(internal: unknown, props: {
|
|
6
|
-
$$events?: Events;
|
|
7
|
-
$$slots?: Slots;
|
|
8
|
-
}): Exports & {
|
|
9
|
-
$set?: any;
|
|
10
|
-
$on?: any;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const Basic: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type Basic = InstanceType<typeof Basic>;
|
|
18
|
-
export default Basic;
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { FileUpload } from '@ark-ui/svelte/file-upload';
|
|
3
|
-
import { getFileIcon } from './icons';
|
|
4
|
-
import PhFileText from '../../icons/PhFileText.svelte';
|
|
5
|
-
import PhX from '../../icons/PhX.svelte';
|
|
6
|
-
|
|
7
|
-
const defaultFiles = [
|
|
8
|
-
new File(['Welcome to Ark UI Svelte`'], 'document.pdf', {
|
|
9
|
-
type: 'text/plain'
|
|
10
|
-
}),
|
|
11
|
-
new File(['Welcome to Ark UI Svelte, this is a zip file`'], 'showcase.zip', {
|
|
12
|
-
type: 'application/zip'
|
|
13
|
-
}),
|
|
14
|
-
new File(['Welcome to Ark UI Svelte, this is an excel file`'], 'data.xlsx', {
|
|
15
|
-
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
16
|
-
})
|
|
17
|
-
];
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<FileUpload.Root
|
|
21
|
-
maxFiles={10}
|
|
22
|
-
maxFileSize={100 * 1024 * 1024}
|
|
23
|
-
class="w-full max-w-2xl space-y-4"
|
|
24
|
-
defaultAcceptedFiles={defaultFiles}
|
|
25
|
-
>
|
|
26
|
-
<FileUpload.Context>
|
|
27
|
-
{#snippet render(context)}
|
|
28
|
-
<!-- Dropzone -->
|
|
29
|
-
<FileUpload.Dropzone
|
|
30
|
-
class="flex w-full cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed border-surface-3 bg-surface-2 px-6 py-12 transition-colors hover:bg-surface-3"
|
|
31
|
-
>
|
|
32
|
-
<!-- File Icon -->
|
|
33
|
-
<div
|
|
34
|
-
class="mb-4 flex h-12 w-12 items-center justify-center rounded-full border bg-surface-1"
|
|
35
|
-
>
|
|
36
|
-
<PhFileText class="h-5 w-5 text-ink-dim" />
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
<!-- Text -->
|
|
40
|
-
<div class="space-y-2 text-center">
|
|
41
|
-
<h3 class="text-sm font-medium text-ink">Upload files</h3>
|
|
42
|
-
<p class="text-sm text-ink-dim">Drag & drop or click to browse</p>
|
|
43
|
-
<p class="text-xs text-ink-dim">All files • Max 10 files • Up to 100MB</p>
|
|
44
|
-
</div>
|
|
45
|
-
</FileUpload.Dropzone>
|
|
46
|
-
|
|
47
|
-
<!-- Files List -->
|
|
48
|
-
{#if context().acceptedFiles.length > 0}
|
|
49
|
-
<div class="space-y-3">
|
|
50
|
-
<FileUpload.ItemGroup>
|
|
51
|
-
{#each context().acceptedFiles as file (file.name)}
|
|
52
|
-
<FileUpload.Item {file}>
|
|
53
|
-
<div class="flex items-center gap-3 rounded-lg border bg-surface-1 p-3">
|
|
54
|
-
<!-- File Icon/Preview -->
|
|
55
|
-
<div
|
|
56
|
-
class="flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg border bg-surface-2"
|
|
57
|
-
>
|
|
58
|
-
{#if file.type.startsWith('image/')}
|
|
59
|
-
<FileUpload.ItemPreview type="image/*">
|
|
60
|
-
<FileUpload.ItemPreviewImage class="h-full w-full object-cover" />
|
|
61
|
-
</FileUpload.ItemPreview>
|
|
62
|
-
{:else}
|
|
63
|
-
{@const IconComponent = getFileIcon(file)}
|
|
64
|
-
<IconComponent class="h-4 w-4 opacity-60" />
|
|
65
|
-
{/if}
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
<!-- File Info -->
|
|
69
|
-
<div class="min-w-0 flex-1">
|
|
70
|
-
<FileUpload.ItemName class="truncate text-sm font-medium text-ink" />
|
|
71
|
-
<FileUpload.ItemSizeText class="text-xs text-ink-dim" />
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<!-- Delete Button -->
|
|
75
|
-
<FileUpload.ItemDeleteTrigger
|
|
76
|
-
class="flex h-6 w-6 shrink-0 items-center justify-center text-ink-dim hover:text-ink"
|
|
77
|
-
>
|
|
78
|
-
<PhX class="h-4 w-4" />
|
|
79
|
-
</FileUpload.ItemDeleteTrigger>
|
|
80
|
-
</div>
|
|
81
|
-
</FileUpload.Item>
|
|
82
|
-
{/each}
|
|
83
|
-
</FileUpload.ItemGroup>
|
|
84
|
-
|
|
85
|
-
<!-- Remove All Button -->
|
|
86
|
-
<FileUpload.ClearTrigger
|
|
87
|
-
class="inline-flex items-center rounded-md border bg-surface-1 px-3 py-1.5 text-xs font-medium text-ink hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:outline-hidden"
|
|
88
|
-
>
|
|
89
|
-
Remove all files
|
|
90
|
-
</FileUpload.ClearTrigger>
|
|
91
|
-
</div>
|
|
92
|
-
{/if}
|
|
93
|
-
{/snippet}
|
|
94
|
-
</FileUpload.Context>
|
|
95
|
-
|
|
96
|
-
<FileUpload.HiddenInput />
|
|
97
|
-
</FileUpload.Root>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
-
$$bindings?: Bindings;
|
|
4
|
-
} & Exports;
|
|
5
|
-
(internal: unknown, props: {
|
|
6
|
-
$$events?: Events;
|
|
7
|
-
$$slots?: Slots;
|
|
8
|
-
}): Exports & {
|
|
9
|
-
$set?: any;
|
|
10
|
-
$on?: any;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const FilesList: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type FilesList = InstanceType<typeof FilesList>;
|
|
18
|
-
export default FilesList;
|