fix: replace svg-to-url, ui improve and build

This commit is contained in:
ShareVB 2024-11-10 19:49:01 +01:00
parent e55d4fa5b2
commit 28699f7b5d
8 changed files with 283 additions and 167 deletions

View file

@ -286,6 +286,9 @@
"watchTriggerable": true, "watchTriggerable": true,
"watchWithFilter": true, "watchWithFilter": true,
"whenever": true, "whenever": true,
"toValue": true "toValue": true,
"injectLocal": true,
"provideLocal": true,
"useClipboardItems": true
} }
} }

3
auto-imports.d.ts vendored
View file

@ -36,6 +36,7 @@ declare global {
const h: typeof import('vue')['h'] const h: typeof import('vue')['h']
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject'] const inject: typeof import('vue')['inject']
const injectLocal: typeof import('@vueuse/core')['injectLocal']
const isDefined: typeof import('@vueuse/core')['isDefined'] const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy'] const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive'] const isReactive: typeof import('vue')['isReactive']
@ -65,6 +66,7 @@ declare global {
const onUpdated: typeof import('vue')['onUpdated'] const onUpdated: typeof import('vue')['onUpdated']
const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
const provide: typeof import('vue')['provide'] const provide: typeof import('vue')['provide']
const provideLocal: typeof import('@vueuse/core')['provideLocal']
const reactify: typeof import('@vueuse/core')['reactify'] const reactify: typeof import('@vueuse/core')['reactify']
const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
const reactive: typeof import('vue')['reactive'] const reactive: typeof import('vue')['reactive']
@ -128,6 +130,7 @@ declare global {
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached'] const useCached: typeof import('@vueuse/core')['useCached']
const useClipboard: typeof import('@vueuse/core')['useClipboard'] const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
const useCloned: typeof import('@vueuse/core')['useCloned'] const useCloned: typeof import('@vueuse/core')['useCloned']
const useColorMode: typeof import('@vueuse/core')['useColorMode'] const useColorMode: typeof import('@vueuse/core')['useColorMode']
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']

3
components.d.ts vendored
View file

@ -166,8 +166,11 @@ declare module '@vue/runtime-core' {
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NP: typeof import('naive-ui')['NP'] NP: typeof import('naive-ui')['NP']
NProgress: typeof import('naive-ui')['NProgress'] NProgress: typeof import('naive-ui')['NProgress']
NRadio: typeof import('naive-ui')['NRadio']
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
NScrollbar: typeof import('naive-ui')['NScrollbar'] NScrollbar: typeof import('naive-ui')['NScrollbar']
NSlider: typeof import('naive-ui')['NSlider'] NSlider: typeof import('naive-ui')['NSlider']
NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin'] NSpin: typeof import('naive-ui')['NSpin']
NStatistic: typeof import('naive-ui')['NStatistic'] NStatistic: typeof import('naive-ui')['NStatistic']
NSwitch: typeof import('naive-ui')['NSwitch'] NSwitch: typeof import('naive-ui')['NSwitch']

View file

@ -82,13 +82,12 @@
"plausible-tracker": "^0.3.8", "plausible-tracker": "^0.3.8",
"qrcode": "^1.5.1", "qrcode": "^1.5.1",
"sql-formatter": "^13.0.0", "sql-formatter": "^13.0.0",
"svg-to-url": "^4.0.0", "svgo": "^3.3.2",
"ua-parser-js": "^1.0.35", "ua-parser-js": "^1.0.35",
"ulid": "^2.3.0", "ulid": "^2.3.0",
"unicode-emoji-json": "^0.4.0", "unicode-emoji-json": "^0.4.0",
"unplugin-auto-import": "^0.16.4", "unplugin-auto-import": "^0.16.4",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"vite-plugin-node-polyfills": "^0.22.0",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-i18n": "^9.9.1", "vue-i18n": "^9.9.1",
"vue-router": "^4.1.6", "vue-router": "^4.1.6",
@ -134,6 +133,7 @@
"unplugin-icons": "^0.17.0", "unplugin-icons": "^0.17.0",
"unplugin-vue-components": "^0.25.0", "unplugin-vue-components": "^0.25.0",
"vite": "^4.4.9", "vite": "^4.4.9",
"vite-plugin-node-polyfills": "^0.22.0",
"vite-plugin-pwa": "^0.16.0", "vite-plugin-pwa": "^0.16.0",
"vite-plugin-vue-markdown": "^0.23.5", "vite-plugin-vue-markdown": "^0.23.5",
"vite-svg-loader": "^4.0.0", "vite-svg-loader": "^4.0.0",

373
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,30 @@
import { stringToUrl } from 'svg-to-url'; import { type Config, type PluginConfig, optimize } from 'svgo';
function svgo(config: Config) {
return (data: string) => {
const { plugins = [], ...rest } = config || {};
return optimize(data, {
...rest,
plugins: [
...(plugins.length > 0 ? plugins : ['preset-default']),
'removeXMLNS',
] as PluginConfig[],
}).data.replace(/^<svg/g, '<svg xmlns="http://www.w3.org/2000/svg"');
};
}
export function encodeStr(svgStr: string) {
const encoded = encodeURIComponent(svgStr)
.replace(/%20/g, ' ')
.replace(/%3D/g, '=')
.replace(/%3B/g, ';')
.replace(/%3A/g, ':')
.replace(/%2F/g, '/')
.replace(/%2C/g, ',')
.replace(/%22/g, '\'');
return `data:image/svg+xml,${encoded}`;
}
export type CSSType = 'Background' | 'Border' | 'ListItemBullet' | 'Url'; export type CSSType = 'Background' | 'Border' | 'ListItemBullet' | 'Url';
@ -21,9 +47,8 @@ async function fileToDataUrl(file: File) {
}); });
} }
function svgToDataUrl(image: string) { function svgToDataUrl(svg: string) {
const getUrlFromSvgString = stringToUrl({}); return encodeStr(svgo({})(svg));
return getUrlFromSvgString(image);
} }
export async function imageToCSS( export async function imageToCSS(

View file

@ -10,12 +10,18 @@ const typeOptions = [
{ label: 'CSS Data Url', value: 'Url' }, { label: 'CSS Data Url', value: 'Url' },
]; ];
const inputType = ref<'file' | 'content'>('file');
const type = ref('Background'); const type = ref('Background');
const svgContent = ref(''); const svgContent = ref('');
const fileInput = ref() as Ref<File | null>; const fileInput = ref() as Ref<File | null>;
const cssCode = computedAsync(async () => { const cssCode = computedAsync(async () => {
try { try {
return (await imageToCSS(fileInput.value || svgContent.value, type.value as CSSType)); if (inputType.value === 'file' && fileInput.value) {
return (await imageToCSS(fileInput.value, type.value as CSSType));
}
else {
return (await imageToCSS(svgContent.value, type.value as CSSType));
}
} }
catch (e: any) { catch (e: any) {
return e.toString(); return e.toString();
@ -37,15 +43,31 @@ watch(svgContent, (_, newValue) => {
<template> <template>
<div> <div>
<n-radio-group v-model:value="inputType" name="radiogroup" mb-2 flex justify-center>
<n-space>
<n-radio
value="file"
label="File"
/>
<n-radio
value="content"
label="Content"
/>
</n-space>
</n-radio-group>
<c-file-upload <c-file-upload
v-if="inputType === 'file'"
title="Drag and drop an image here, or click to select a file" title="Drag and drop an image here, or click to select a file"
paste-image paste-image
@file-upload="onUpload" @file-upload="onUpload"
/> />
<n-p>OR</n-p>
<c-input-text <c-input-text
v-if="inputType === 'content'"
v-model:value="svgContent" v-model:value="svgContent"
multiline
rows="5"
label="SVG Content" label="SVG Content"
placeholder="Paste your SVG content here" placeholder="Paste your SVG content here"
mb-2 mb-2

View file

@ -114,8 +114,5 @@ export default defineConfig({
}, },
build: { build: {
target: 'esnext', target: 'esnext',
rollupOptions: {
external: ['node:fs/promises', 'fs'],
},
}, },
}); });