mirror of
https://github.com/pheralb/svgl.git
synced 2024-11-10 14:46:54 +08:00
⚙️ Add support for download light & dark svgs.
This commit is contained in:
parent
ffff743283
commit
6a0520e2f8
@ -1,14 +1,20 @@
|
||||
<script lang="ts">
|
||||
import type { iSVG } from '../types/svg';
|
||||
|
||||
import download from 'downloadjs';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { MIMETYPE, getSvgContent } from '../utils/getSvgContent';
|
||||
import jszip from 'jszip';
|
||||
|
||||
// Utils:
|
||||
import { MIMETYPE, getSvgContent } from '@/utils/getSvgContent';
|
||||
import { flyAndScale } from '@/utils/flyAndScale';
|
||||
|
||||
// Icons:
|
||||
import { CopyIcon, DownloadIcon, LinkIcon } from 'lucide-svelte';
|
||||
import { CopyIcon, DownloadIcon, LinkIcon, PackageIcon, PaintBucket } from 'lucide-svelte';
|
||||
|
||||
// Main Card:
|
||||
import CardSpotlight from './cardSpotlight.svelte';
|
||||
import { DropdownMenu } from 'bits-ui';
|
||||
|
||||
// Props:
|
||||
export let svgInfo: iSVG;
|
||||
@ -16,7 +22,33 @@
|
||||
// Download SVG:
|
||||
const downloadSvg = (url?: string) => {
|
||||
download(url || '');
|
||||
toast.success('Downloading...');
|
||||
toast.success(`Downloading...`, {
|
||||
description: `${svgInfo.title} - ${svgInfo.category}`
|
||||
});
|
||||
};
|
||||
|
||||
// Download all variants:
|
||||
const downloadAllVariants = async ({ route }: iSVG) => {
|
||||
const zip = new jszip();
|
||||
|
||||
if (typeof route === 'string') {
|
||||
downloadSvg(route);
|
||||
return;
|
||||
}
|
||||
|
||||
const lightSvg = await getSvgContent(route.light, false);
|
||||
const darkSvg = await getSvgContent(route.dark, false);
|
||||
|
||||
zip.file(`${svgInfo.title}.svg`, lightSvg);
|
||||
zip.file(`${svgInfo.title}.dark.svg`, darkSvg);
|
||||
|
||||
zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||
download(content, `${svgInfo.title}.zip`, 'application/zip');
|
||||
});
|
||||
|
||||
toast.success('Downloading light & dark variants...', {
|
||||
description: `${svgInfo.title} - ${svgInfo.category}`
|
||||
});
|
||||
};
|
||||
|
||||
// Copy SVG to clipboard:
|
||||
@ -43,6 +75,7 @@
|
||||
|
||||
<CardSpotlight>
|
||||
<div class="flex flex-col items-center justify-center rounded-md p-4">
|
||||
<!-- Image -->
|
||||
<img
|
||||
class="hidden dark:block mb-4 mt-2 h-10"
|
||||
src={typeof svgInfo.route !== 'string' ? svgInfo.route.dark : svgInfo.route}
|
||||
@ -57,6 +90,7 @@
|
||||
title={svgInfo.title}
|
||||
loading="lazy"
|
||||
/>
|
||||
<!-- Title -->
|
||||
<div class="mb-3 flex flex-col items-center justify-center">
|
||||
<p class="truncate text-[15px] font-medium text-balance text-center select-all">
|
||||
{svgInfo.title}
|
||||
@ -66,6 +100,7 @@
|
||||
class="text-sm lowercase text-neutral-500 hover:underline font-mono">{svgInfo.category}</a
|
||||
>
|
||||
</div>
|
||||
<!-- Actions -->
|
||||
<div class="flex items-center space-x-1">
|
||||
<button
|
||||
title="Copy to clipboard"
|
||||
@ -95,8 +130,30 @@
|
||||
>
|
||||
<CopyIcon size={iconSize} strokeWidth={iconStroke} />
|
||||
</button>
|
||||
<button
|
||||
title="Download"
|
||||
|
||||
{#if typeof svgInfo.route !== 'string'}
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger
|
||||
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
|
||||
>
|
||||
<DownloadIcon size={iconSize} strokeWidth={iconStroke} />
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content
|
||||
class="w-full shadow-md max-w-[229px] rounded-md border border-neutral-100 dark:border-neutral-800 bg-white dark:bg-neutral-900 px-1 py-1.5 shadow-popover"
|
||||
transition={flyAndScale}
|
||||
sideOffset={3}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
class="flex h-10 select-none items-center rounded-md py-3 pl-3 pr-1.5 text-sm font-medium hover:bg-neutral-100 dark:hover:bg-neutral-700/40"
|
||||
on:click={() => {
|
||||
downloadAllVariants(svgInfo);
|
||||
}}
|
||||
>
|
||||
<PackageIcon class="mr-2" size={18} />
|
||||
<p>Light & Dark variants</p>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item
|
||||
class="flex h-10 select-none items-center rounded-md py-3 pl-3 pr-1.5 text-sm font-medium hover:bg-neutral-100 dark:hover:bg-neutral-700/40"
|
||||
on:click={() => {
|
||||
const svgHasTheme = typeof svgInfo.route !== 'string';
|
||||
|
||||
@ -119,10 +176,23 @@
|
||||
: svgInfo.route
|
||||
);
|
||||
}}
|
||||
>
|
||||
<PaintBucket class="mr-2" size={18} />
|
||||
Only {document.documentElement.classList.contains('dark') ? 'dark' : 'light'} variant
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
||||
{:else}
|
||||
<button
|
||||
title="Download SVG"
|
||||
on:click={() => {
|
||||
if (typeof svgInfo.route === 'string') downloadSvg(svgInfo.route);
|
||||
}}
|
||||
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
|
||||
>
|
||||
<DownloadIcon size={iconSize} strokeWidth={iconStroke} />
|
||||
</button>
|
||||
{/if}
|
||||
<a
|
||||
href={svgInfo.url}
|
||||
title="Website"
|
||||
|
@ -23,7 +23,6 @@
|
||||
let filteredSvgs: iSVG[] = [];
|
||||
|
||||
// Order by last added:
|
||||
|
||||
if (searchTerm.length === 0) {
|
||||
filteredSvgs = allSvgs.sort((a: iSVG, b: iSVG) => {
|
||||
return b.id! - a.id!;
|
||||
|
Loading…
Reference in New Issue
Block a user