feat: add visual theme editing page ui

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/581/head
Ryan Wang 2022-05-29 15:13:01 +08:00
parent 87642a5698
commit 5b24b06859
5 changed files with 175 additions and 10 deletions

View File

@ -40,19 +40,19 @@ const handleChange = (id: number | string) => {
};
</script>
<template>
<div class="tabbar-wrapper" :class="classes">
<div :class="classes" class="tabbar-wrapper">
<div class="tabbar-items">
<div
v-for="(item, index) in items"
:key="index"
class="tabbar-item"
:class="{ 'tabbar-item-active': item[idKey] === activeId }"
class="tabbar-item"
@click="handleChange(item[idKey])"
>
<div v-if="item.icon" class="tabbar-item-icon">
<component :is="item.icon" />
</div>
<div class="tabbar-item-label">
<div v-if="item[labelKey]" class="tabbar-item-label">
{{ item[labelKey] }}
</div>
</div>
@ -74,15 +74,12 @@ const handleChange = (id: number | string) => {
@apply transition-all;
@apply text-base;
@apply justify-center;
@apply gap-2;
.tabbar-item-label,
.tabbar-item-icon {
@apply self-center;
}
.tabbar-item-icon {
@apply mr-2;
}
}
&.tabbar-default {
@ -93,6 +90,7 @@ const handleChange = (id: number | string) => {
margin-bottom: -2px;
justify-content: flex-start;
}
.tabbar-item {
@apply h-10;
@apply px-5;
@ -113,6 +111,7 @@ const handleChange = (id: number | string) => {
@apply gap-1;
justify-content: flex-start;
}
.tabbar-item {
@apply h-10;
@apply px-9;

View File

@ -57,6 +57,14 @@ import IconList from "~icons/ri/list-unordered";
import IconGrid from "~icons/ri/grid-line";
// @ts-ignore
import IconCheckboxFill from "~icons/ri/checkbox-circle-fill";
// @ts-ignore
import IconSearch from "~icons/ri/search-2-line";
// @ts-ignore
import IconComputer from "~icons/ri/computer-line";
// @ts-ignore
import IconPhone from "~icons/ri/smartphone-line";
// @ts-ignore
import IconTablet from "~icons/ri/tablet-line";
export {
IconDashboard,
@ -88,4 +96,8 @@ export {
IconCheckboxFill,
IconArrowUpLine,
IconArrowDownLine,
IconSearch,
IconComputer,
IconPhone,
IconTablet
};

View File

@ -7,6 +7,17 @@
<div class="logo flex justify-center py-5">
<img :src="logo" alt="Halo Logo" style="width: 78px" />
</div>
<div class="px-3">
<div
class="flex p-2 text-gray-400 items-center transition-all bg-gray-100 rounded cursor-pointer hover:text-gray-900"
>
<span class="mr-3">
<IconSearch />
</span>
<span class="flex-1 text-base select-none font-normal">搜索</span>
<div class="text-sm">+K</div>
</div>
</div>
<VRoutesMenu :menus="menus" />
<div class="current-profile">
<div class="profile-avatar">
@ -131,7 +142,7 @@ import { VRoutesMenu } from "@/components/base/menu";
import { VTag } from "@/components/base/tag";
import { menus, minimenus } from "@/router/menus.config";
import logo from "@/assets/logo.svg";
import { IconMore, IconUserSettings } from "@/core/icons";
import { IconMore, IconSearch, IconUserSettings } from "@/core/icons";
import { RouterView, useRoute, useRouter } from "vue-router";
import { ref } from "vue";

View File

@ -130,7 +130,7 @@ export const routes: Array<RouteRecordRaw> = [
},
{
path: "/visual",
component: BasicLayout,
component: BlankLayout,
children: [
{
path: "",

View File

@ -1 +1,144 @@
<template>Visual</template>
<script lang="ts" setup>
import { VButton } from "@/components/base/button";
import { VInput } from "@/components/base/input";
import { VOption, VSelect } from "@/components/base/select";
import { VTextarea } from "@/components/base/textarea";
import { VTabbar, VTabItem, VTabs } from "@/components/base/tabs";
import { computed, ref } from "vue";
import { IconComputer, IconPhone, IconTablet } from "@/core/icons";
const activeId = ref("general");
const deviceActiveId = ref("desktop");
const iframeClasses = computed(() => {
if (deviceActiveId.value === "desktop") {
return "w-full h-full";
}
if (deviceActiveId.value === "tablet") {
return "w-2/3 h-2/3";
}
// phone
return "w-96 h-[50rem]";
});
</script>
<template>
<div class="h-screen flex">
<div class="h-full bg-white w-96 drop-shadow-sm overflow-y-auto">
<VTabs v-model:active-id="activeId">
<VTabItem id="general" class="p-3" label="基础设置">
<form>
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
<div class="space-y-6 sm:space-y-5">
<div class="space-y-2">
<label
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
for="first-name"
>
Halo 当前版本
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<VInput model-value="1.5.3"></VInput>
</div>
</div>
<div class="space-y-2">
<label
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
for="last-name"
>
首页图片
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<VInput
model-value="https://halo.run/upload/2022/03/support-team.svg"
></VInput>
</div>
</div>
</div>
</div>
</form>
</VTabItem>
<VTabItem id="style" class="p-3" label="样式设置">
<form>
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
<div class="space-y-6 sm:space-y-5">
<div class="space-y-2">
<label
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
for="first-name"
>
文章代码高亮语言
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<VTextarea></VTextarea>
</div>
</div>
<div class="space-y-2">
<label
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
for="last-name"
>
文章代码高亮主题
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<VSelect>
<VOption value="java">Java</VOption>
<VOption value="c">C</VOption>
<VOption value="go">Go</VOption>
<VOption value="javascript">JavaScript</VOption>
</VSelect>
</div>
</div>
</div>
</div>
</form>
</VTabItem>
</VTabs>
</div>
<div class="flex-1">
<div
class="flex items-center justify-between p-2 bg-white h-16 drop-shadow-sm"
>
<div>
<h2 class="text-xl font-bold text-gray-800 truncate">
<span>Anatole</span>
</h2>
</div>
<div>
<VTabbar
v-model:active-id="deviceActiveId"
:items="[
{
id: 'desktop',
icon: IconComputer,
},
{
id: 'tablet',
icon: IconTablet,
},
{
id: 'phone',
icon: IconPhone,
},
]"
type="outline"
></VTabbar>
</div>
<div>
<VButton type="secondary">保存</VButton>
</div>
</div>
<div
class="h-full flex justify-center items-center"
style="height: calc(100vh - 4rem)"
>
<iframe
:class="iframeClasses"
class="border-none"
src="http://localhost:8090"
></iframe>
</div>
</div>
</div>
</template>