mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 01:57:19 +08:00
feat: 实现图标本地加载
目前会导致打包体积失控,但是没有找到更好的方案。
This commit is contained in:
@@ -43,19 +43,24 @@ export default [
|
||||
eslintrc: {
|
||||
enabled: true
|
||||
},
|
||||
parser: 'acorn',
|
||||
vueTemplate: true,
|
||||
addons: {
|
||||
vueDirectives: true
|
||||
},
|
||||
viteOptimizeDeps: true
|
||||
}),
|
||||
Icons({
|
||||
compiler: 'vue3',
|
||||
scale: 1,
|
||||
defaultClass: 'inline-block'
|
||||
}),
|
||||
Components({
|
||||
resolvers: [
|
||||
NaiveUiResolver(),
|
||||
IconsResolver({ customCollections: ['custom'], prefix: 'icon' })
|
||||
IconsResolver()
|
||||
],
|
||||
dts: 'types/components.d.ts'
|
||||
})
|
||||
}),
|
||||
Icons({
|
||||
compiler: 'vue3',
|
||||
scale: 1,
|
||||
defaultClass: 'inline-block',
|
||||
autoInstall: true
|
||||
}),
|
||||
]
|
||||
|
||||
@@ -58,7 +58,8 @@
|
||||
"vue3-gettext": "4.0.0-beta.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.397",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@iconify-json/simple-icons": "^1.2.63",
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@rushstack/eslint-patch": "^1.14.0",
|
||||
"@tsconfig/node24": "^24.0.0",
|
||||
|
||||
23
web/pnpm-lock.yaml
generated
23
web/pnpm-lock.yaml
generated
@@ -102,9 +102,12 @@ importers:
|
||||
specifier: 4.0.0-beta.1
|
||||
version: 4.0.0-beta.1(@vue/compiler-sfc@3.5.25)(vue@3.5.25(typescript@5.9.3))
|
||||
devDependencies:
|
||||
'@iconify/json':
|
||||
specifier: ^2.2.397
|
||||
version: 2.2.419
|
||||
'@iconify-json/mdi':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
'@iconify-json/simple-icons':
|
||||
specifier: ^1.2.63
|
||||
version: 1.2.63
|
||||
'@iconify/vue':
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(vue@3.5.25(typescript@5.9.3))
|
||||
@@ -693,8 +696,11 @@ packages:
|
||||
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@iconify/json@2.2.419':
|
||||
resolution: {integrity: sha512-50GipvrxOs/b03MP0GxCTn65o4S/DDEXbf03oXbglp0m552TcT8yAidLl7kyQ1fiI+rx3LbvZ6hNSU3CrXZnIQ==}
|
||||
'@iconify-json/mdi@1.2.3':
|
||||
resolution: {integrity: sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg==}
|
||||
|
||||
'@iconify-json/simple-icons@1.2.63':
|
||||
resolution: {integrity: sha512-xZl2UWCwE58VlqZ+pDPmaUhE2tq8MVSTJRr4/9nzzHlDdjJ0Ud1VxNXPrwTSgESKY29iCQw3S0r2nJTSNNngHw==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -4077,10 +4083,13 @@ snapshots:
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
|
||||
'@iconify/json@2.2.419':
|
||||
'@iconify-json/mdi@1.2.3':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@iconify-json/simple-icons@1.2.63':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 2.0.3
|
||||
|
||||
'@iconify/types@2.0.0': {}
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@ const columns: DataTableColumns<RowData> = [
|
||||
defaultSortOrder: false,
|
||||
sorter: 'default',
|
||||
render(row) {
|
||||
let icon = 'bi:file-earmark'
|
||||
let icon = 'mdi:file-outline'
|
||||
if (row.dir) {
|
||||
icon = 'bi:folder'
|
||||
icon = 'mdi:folder-outline'
|
||||
} else {
|
||||
icon = getIconByExt(getExt(row.name))
|
||||
}
|
||||
@@ -261,7 +261,7 @@ const handleClose = () => {
|
||||
<n-button type="primary"> {{ $gettext('Create') }} </n-button>
|
||||
</n-popselect>
|
||||
<n-button @click="handleUp">
|
||||
<icon-bi-arrow-up />
|
||||
<i-mdi-arrow-up :size="16" />
|
||||
</n-button>
|
||||
<n-input-group flex-1>
|
||||
<n-tag size="large" v-if="!isInput" flex-1 @click="handleInput">
|
||||
@@ -288,7 +288,7 @@ const handleClose = () => {
|
||||
/>
|
||||
</n-input-group>
|
||||
<n-button @click="refresh">
|
||||
<icon-bi-arrow-clockwise />
|
||||
<i-mdi-refresh :size="16" />
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<n-data-table
|
||||
|
||||
@@ -9,8 +9,8 @@ const { isFullscreen, toggle } = useFullscreen()
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon mr-20 cursor-pointer size="20" @click="toggle">
|
||||
<icon-ant-design:fullscreen-exit-outlined v-if="isFullscreen" />
|
||||
<icon-ant-design:fullscreen-outlined v-else />
|
||||
<i-mdi-fullscreen-exit v-if="isFullscreen" />
|
||||
<i-mdi-fullscreen v-else />
|
||||
</n-icon>
|
||||
</template>
|
||||
{{ $gettext('Fullscreen Display') }}
|
||||
|
||||
@@ -10,8 +10,8 @@ const themeStore = useThemeStore()
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon cursor-pointer size="22" @click="themeStore.toggleCollapsed()">
|
||||
<icon-mdi:format-indent-increase v-if="themeStore.sider.collapsed" />
|
||||
<icon-mdi:format-indent-decrease v-else />
|
||||
<i-mdi-format-indent-increase v-if="themeStore.sider.collapsed" />
|
||||
<i-mdi-format-indent-decrease v-else />
|
||||
</n-icon>
|
||||
</template>
|
||||
{{ $gettext('Menu Zoom') }}
|
||||
|
||||
@@ -14,7 +14,7 @@ const handleReloadPage = () => {
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon mr-20 cursor-pointer size="20" @click="handleReloadPage">
|
||||
<icon-mdi-refresh />
|
||||
<i-mdi-refresh />
|
||||
</n-icon>
|
||||
</template>
|
||||
{{ $gettext('Refresh Tab') }}
|
||||
|
||||
@@ -10,8 +10,8 @@ const theme = useThemeStore()
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon mr-20 cursor-pointer size="20" @click="theme.toggleDarkMode">
|
||||
<icon-mdi-moon-waning-crescent v-if="theme.darkMode" />
|
||||
<icon-mdi-white-balance-sunny v-else />
|
||||
<i-mdi-weather-sunny v-if="theme.darkMode" />
|
||||
<i-mdi-weather-night v-else />
|
||||
</n-icon>
|
||||
</template>
|
||||
{{ $gettext('Switch Theme') }}
|
||||
|
||||
@@ -12,11 +12,11 @@ const toHome = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-60 f-c-c cursor-pointer" @click="toHome">
|
||||
<n-image :src="logo" height="32" preview-disabled />
|
||||
<div class="f-c-c h-60 cursor-pointer" @click="toHome">
|
||||
<n-image :src="logo" preview-disabled class="h-36" />
|
||||
<h2
|
||||
v-show="!themeStore.sider.collapsed"
|
||||
class="ml-10 max-w-140 flex-shrink-0 text-18 font-bold"
|
||||
class="text-18 font-bold ml-10 flex-shrink-0 max-w-140"
|
||||
>
|
||||
{{ themeStore.name }}
|
||||
</h2>
|
||||
|
||||
@@ -52,14 +52,14 @@ const menus = computed<TreeSelectOption[]>(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div h-40 flex justify-between px-20>
|
||||
<div px-20 flex h-40 justify-between>
|
||||
<menu-collapse />
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<the-icon
|
||||
v-show="!themeStore.sider.collapsed"
|
||||
:size="22"
|
||||
icon="material-symbols:settings"
|
||||
icon="mdi:settings-outline"
|
||||
@click="settingModal = true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { addAPIProvider, Icon } from '@iconify/vue'
|
||||
import { icons as mdi } from '@iconify-json/mdi'
|
||||
import { icons as simpleIcons } from '@iconify-json/simple-icons'
|
||||
import { addCollection, Icon } from '@iconify/vue'
|
||||
|
||||
import { NIcon } from 'naive-ui'
|
||||
|
||||
addAPIProvider('', {
|
||||
resources: ['https://iconify.cdn.haozi.net']
|
||||
})
|
||||
addCollection(mdi)
|
||||
addCollection(simpleIcons)
|
||||
|
||||
interface Props {
|
||||
size?: number
|
||||
|
||||
@@ -15,22 +15,29 @@ const getBase = (filename: string) => {
|
||||
}
|
||||
|
||||
const getIconByExt = (ext: string) => {
|
||||
switch (ext) {
|
||||
switch (ext.toLowerCase()) {
|
||||
case 'png':
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
case 'gif':
|
||||
return 'bi:file-earmark-image'
|
||||
case 'webp':
|
||||
case 'svg':
|
||||
return 'mdi-file-image-outline'
|
||||
|
||||
case 'mp4':
|
||||
case 'avi':
|
||||
case 'mkv':
|
||||
case 'rmvb':
|
||||
return 'bi:file-earmark-play'
|
||||
case 'mov':
|
||||
return 'mdi-file-video-outline'
|
||||
|
||||
case 'mp3':
|
||||
case 'flac':
|
||||
case 'wav':
|
||||
case 'ape':
|
||||
return 'bi:file-earmark-music'
|
||||
case 'ogg':
|
||||
return 'mdi-file-music-outline'
|
||||
|
||||
case 'zip':
|
||||
case 'bz2':
|
||||
case 'tar':
|
||||
@@ -38,17 +45,20 @@ const getIconByExt = (ext: string) => {
|
||||
case 'tgz':
|
||||
case 'xz':
|
||||
case '7z':
|
||||
return 'bi:file-earmark-zip'
|
||||
case 'rar':
|
||||
return 'mdi-archive-outline'
|
||||
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
case 'xls':
|
||||
case 'xlsx':
|
||||
return 'bi:file-earmark-word'
|
||||
case 'ppt':
|
||||
case 'pptx':
|
||||
return 'bi:file-earmark-ppt'
|
||||
return 'mdi-file-document-outline'
|
||||
|
||||
case 'pdf':
|
||||
return 'bi:file-earmark-pdf'
|
||||
return 'mdi-file-pdf-box'
|
||||
|
||||
case 'txt':
|
||||
case 'md':
|
||||
case 'log':
|
||||
@@ -56,7 +66,8 @@ const getIconByExt = (ext: string) => {
|
||||
case 'ini':
|
||||
case 'yaml':
|
||||
case 'yml':
|
||||
return 'bi:file-earmark-text'
|
||||
return 'mdi-file-document-outline'
|
||||
|
||||
case 'html':
|
||||
case 'htm':
|
||||
case 'xml':
|
||||
@@ -73,11 +84,13 @@ const getIconByExt = (ext: string) => {
|
||||
case 'go':
|
||||
case 'rb':
|
||||
case 'sh':
|
||||
return 'bi:file-earmark-code'
|
||||
return 'mdi-file-code-outline'
|
||||
|
||||
case '':
|
||||
return 'bi:file-earmark-binary'
|
||||
return 'mdi-file-outline'
|
||||
|
||||
default:
|
||||
return 'bi:file-earmark'
|
||||
return 'mdi-file-outline'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Docker',
|
||||
icon: 'logos:docker-icon',
|
||||
icon: 'simple-icons:docker',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Frp Manager',
|
||||
icon: 'icon-park-outline:connection-box',
|
||||
icon: 'mdi:swap-horizontal',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Memcached',
|
||||
icon: 'logos:memcached',
|
||||
icon: 'mdi:memory',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Percona (MySQL)',
|
||||
icon: 'logos:percona',
|
||||
icon: 'simple-icons:mysql',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'OpenResty (Nginx)',
|
||||
icon: 'logos:nginx',
|
||||
icon: 'simple-icons:nginx',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 7.4',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.0',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.1',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.2',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.3',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.4',
|
||||
icon: 'logos:php',
|
||||
icon: 'simple-icons:php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Podman',
|
||||
icon: 'devicon:podman',
|
||||
icon: 'simple-icons:podman',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PostgreSQL',
|
||||
icon: 'logos:postgresql',
|
||||
icon: 'simple-icons:postgresql',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Redis',
|
||||
icon: 'logos:redis',
|
||||
icon: 'simple-icons:redis',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Rsync Manager',
|
||||
icon: 'file-icons:rsync',
|
||||
icon: 'mdi:folder-sync-outline',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'S3fs Manager',
|
||||
icon: 'logos:aws',
|
||||
icon: 'mdi:dns-outline',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ const uploadRequest = ({ file, onFinish, onError, onProgress }: UploadCustomRequ
|
||||
<n-upload ref="upload" multiple directory-dnd :custom-request="uploadRequest">
|
||||
<n-upload-dragger>
|
||||
<div style="margin-bottom: 12px">
|
||||
<the-icon :size="48" icon="bi:arrow-up-square" />
|
||||
<the-icon :size="60" icon="mdi:arrow-up-bold-box-outline" />
|
||||
</div>
|
||||
<NText text-18>{{ $gettext('Click or drag files to this area to upload') }}</NText>
|
||||
<NP depth="3" m-10>{{
|
||||
|
||||
@@ -108,9 +108,9 @@ const columns: DataTableColumns<RowData> = [
|
||||
defaultSortOrder: false,
|
||||
sorter: 'default',
|
||||
render(row) {
|
||||
let icon = 'bi:file-earmark'
|
||||
let icon = 'mdi:file-outline'
|
||||
if (row.dir) {
|
||||
icon = 'bi:folder'
|
||||
icon = 'mdi:folder-outline'
|
||||
} else {
|
||||
icon = getIconByExt(getExt(row.name))
|
||||
}
|
||||
|
||||
@@ -110,16 +110,16 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<n-flex>
|
||||
<n-button @click="handleBack">
|
||||
<icon-bi-arrow-left />
|
||||
<i-mdi-arrow-left :size="16" />
|
||||
</n-button>
|
||||
<n-button @click="handleForward">
|
||||
<icon-bi-arrow-right />
|
||||
<i-mdi-arrow-right :size="16" />
|
||||
</n-button>
|
||||
<n-button @click="handleUp">
|
||||
<icon-bi-arrow-up />
|
||||
<i-mdi-arrow-up :size="16" />
|
||||
</n-button>
|
||||
<n-button @click="handleRefresh">
|
||||
<icon-bi-arrow-clockwise />
|
||||
<i-mdi-refresh :size="16" />
|
||||
</n-button>
|
||||
<n-input-group flex-1>
|
||||
<n-tag size="large" v-if="!isInput" flex-1 @click="handleInput">
|
||||
@@ -154,7 +154,7 @@ onUnmounted(() => {
|
||||
</template>
|
||||
</n-input>
|
||||
<n-button type="primary" @click="handleSearch">
|
||||
<icon-bi-search />
|
||||
<i-mdi-search :size="16" />
|
||||
</n-button>
|
||||
</n-input-group>
|
||||
</n-flex>
|
||||
|
||||
@@ -45,7 +45,7 @@ const uploadRequest = ({ file, onFinish, onError, onProgress }: UploadCustomRequ
|
||||
<n-upload ref="upload" multiple directory-dnd :custom-request="uploadRequest">
|
||||
<n-upload-dragger>
|
||||
<div style="margin-bottom: 12px">
|
||||
<the-icon :size="48" icon="bi:arrow-up-square" />
|
||||
<the-icon :size="60" icon="mdi:arrow-up-bold-box-outline" />
|
||||
</div>
|
||||
<NText text-18> {{ $gettext('Click or drag files to this area to upload') }}</NText>
|
||||
<NP depth="3" m-10>
|
||||
|
||||
@@ -112,7 +112,7 @@ const handleTest = async () => {
|
||||
</div>
|
||||
<div v-else>{{ $gettext('Pending benchmark') }}</div>
|
||||
<n-progress type="circle" :percentage="100" :stroke-width="3">
|
||||
<the-icon :size="50" icon="bi:cpu" />
|
||||
<the-icon :size="50" icon="mdi:cpu-64-bit" />
|
||||
</n-progress>
|
||||
{{ $gettext('CPU') }}
|
||||
</n-flex>
|
||||
@@ -172,7 +172,7 @@ const handleTest = async () => {
|
||||
</div>
|
||||
<div v-else>{{ $gettext('Pending benchmark') }}</div>
|
||||
<n-progress type="circle" :percentage="100" :stroke-width="3">
|
||||
<the-icon :size="50" icon="bi:memory" />
|
||||
<the-icon :size="50" icon="mdi:memory" />
|
||||
</n-progress>
|
||||
{{ $gettext('Memory') }}
|
||||
</n-flex>
|
||||
@@ -198,7 +198,7 @@ const handleTest = async () => {
|
||||
</div>
|
||||
<div v-else>{{ $gettext('Pending benchmark') }}</div>
|
||||
<n-progress type="circle" :percentage="100" :stroke-width="3">
|
||||
<the-icon :size="50" icon="bi:hdd-stack" />
|
||||
<the-icon :size="50" icon="mdi:harddisk" />
|
||||
</n-progress>
|
||||
{{ $gettext('Disk') }}
|
||||
</n-flex>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { UserConfig } from 'unocss'
|
||||
import { defineConfig, presetAttributify, presetWind3 } from 'unocss'
|
||||
import { defineConfig, presetAttributify, presetWind4 } from 'unocss'
|
||||
|
||||
const config: UserConfig = {
|
||||
content: {
|
||||
@@ -7,7 +7,7 @@ const config: UserConfig = {
|
||||
exclude: ['node_modules', '.git', '.github', '.vscode', 'build', 'dist', 'public', 'types']
|
||||
}
|
||||
},
|
||||
presets: [presetWind3({ dark: 'class' }), presetAttributify()],
|
||||
presets: [presetWind4({ dark: 'class' }), presetAttributify()],
|
||||
shortcuts: [
|
||||
['wh-full', 'w-full h-full'],
|
||||
['f-c-c', 'flex justify-center items-center'],
|
||||
|
||||
Reference in New Issue
Block a user