Browse Source

头部样式修改

黄琪勇 4 months ago
parent
commit
8de2db50b9

+ 1 - 1
.env

@@ -1,3 +1,3 @@
 # 公共环境变量
 
-VITE_APP_TITLE="ppt"
+VITE_APP_TITLE="PPT"

BIN
public/favicon.ico


+ 47 - 39
src/components/Popover.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="popover" :class="{ 'center': center }" ref="triggerRef">
+  <div class="popover" :class="{ center: center }" ref="triggerRef">
     <div class="popover-content" :style="contentStyle" ref="contentRef">
       <slot name="content" v-if="contentVisible"></slot>
     </div>
@@ -8,29 +8,32 @@
 </template>
 
 <script lang="ts" setup>
-import { type CSSProperties, onMounted, onUnmounted, ref, watch, computed } from 'vue'
-import tippy, { type Instance, type Placement } from 'tippy.js'
+import { type CSSProperties, onMounted, onUnmounted, ref, watch, computed } from "vue"
+import tippy, { type Instance, type Placement } from "tippy.js"
 
-import 'tippy.js/animations/scale.css'
+import "tippy.js/animations/scale.css"
 
-const props = withDefaults(defineProps<{
-  value?: boolean
-  trigger?: 'click' | 'mouseenter' | 'manual'
-  placement?: Placement
-  appendTo?: HTMLElement | 'parent'
-  contentStyle?: CSSProperties
-  center?: boolean
-  offset?: number
-}>(), {
-  value: false,
-  trigger: 'click',
-  placement: 'bottom',
-  center: false,
-  offset: 8,
-})
+const props = withDefaults(
+  defineProps<{
+    value?: boolean
+    trigger?: "click" | "mouseenter" | "manual"
+    placement?: Placement
+    appendTo?: HTMLElement | "parent"
+    contentStyle?: CSSProperties
+    center?: boolean
+    offset?: number
+  }>(),
+  {
+    value: false,
+    trigger: "click",
+    placement: "bottom",
+    center: false,
+    offset: 8
+  }
+)
 
 const emit = defineEmits<{
-  (event: 'update:value', payload: boolean): void
+  (event: "update:value", payload: boolean): void
 }>()
 
 const instance = ref<Instance>()
@@ -42,11 +45,14 @@ const contentStyle = computed(() => {
   return props.contentStyle || {}
 })
 
-watch(() => props.value, () => {
-  if (!instance.value) return
-  if (props.value) instance.value.show()
-  else instance.value.hide()
-})
+watch(
+  () => props.value,
+  () => {
+    if (!instance.value) return
+    if (props.value) instance.value.show()
+    else instance.value.hide()
+  }
+)
 
 onUnmounted(() => {
   if (instance.value) instance.value.destroy()
@@ -60,21 +66,21 @@ onMounted(() => {
     placement: props.placement,
     interactive: true,
     appendTo: props.appendTo || document.body,
-    maxWidth: 'none',
+    maxWidth: "none",
     offset: [0, props.offset],
     duration: 200,
-    animation: 'scale',
-    theme: 'popover',
+    animation: "scale",
+    theme: "popover",
     onShow() {
       contentVisible.value = true
     },
     onShown() {
-      if (!props.value) emit('update:value', true)
+      if (!props.value) emit("update:value", true)
     },
     onHidden() {
-      if (props.value) emit('update:value', false)
+      if (props.value) emit("update:value", false)
       contentVisible.value = false
-    },
+    }
   })
 })
 </script>
@@ -86,18 +92,20 @@ onMounted(() => {
   align-items: center;
 }
 .popover-content {
-  background-color: #fff;
-  padding: 10px;
-  border: 1px solid $borderColor;
-  box-shadow: $boxShadow;
-  border-radius: $borderRadius;
-  font-size: 13px;
+  padding: 8px;
+  background: #ffffff;
+  box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.1);
+  border-radius: 8px;
+  font-weight: 400;
+  font-size: 14px;
+  color: #333333;
+  line-height: 20px;
 }
 </style>
 
 <style lang="scss">
-.tippy-box[data-theme~='popover'] {
+.tippy-box[data-theme~="popover"] {
   border: 0;
   outline: 0;
 }
-</style>
+</style>

+ 15 - 14
src/components/PopoverMenuItem.vue

@@ -1,38 +1,39 @@
 <template>
-  <div class="popover-menu-item" :class="{ 'center': center }" @click="emit('click')">
+  <div class="popover-menu-item" :class="{ center: center }" @click="emit('click')">
     <slot></slot>
   </div>
 </template>
 
 <script lang="ts" setup>
-withDefaults(defineProps<{
-  center?: boolean
-}>(), {
-  center: false,
-})
+withDefaults(
+  defineProps<{
+    center?: boolean
+  }>(),
+  {
+    center: false
+  }
+)
 
 const emit = defineEmits<{
-  (event: 'click'): void
+  (event: "click"): void
 }>()
 </script>
 
 <style lang="scss" scoped>
 .popover-menu-item {
   min-width: 80px;
-  padding: 6px 10px;
-  border-radius: $borderRadius;
-  font-size: 13px;
+  padding: 8px 24px;
   cursor: pointer;
+  border-radius: 4px;
 
   &.center {
     text-align: center;
   }
-
   &:hover {
-    background-color: #f1f1f1;
+    background: #f5f6fa;
   }
   & + .popover-menu-item {
-    margin-top: 2px;
+    margin-top: 8px;
   }
 }
-</style>
+</style>

+ 0 - 2
src/plugins/icon.ts

@@ -115,7 +115,6 @@ import {
   Left,
   Right,
   MoveOne,
-  HamburgerButton,
   Attention,
   CheckOne,
   CloseOne,
@@ -245,7 +244,6 @@ export const icons: Icons = {
   IconLeft: Left,
   IconRight: Right,
   IconMoveOne: MoveOne,
-  IconHamburgerButton: HamburgerButton,
   IconAttention: Attention,
   IconCheckOne: CheckOne,
   IconCloseOne: CloseOne,

BIN
src/views/Editor/EditorHeader/imgs/file.png


+ 60 - 99
src/views/Editor/EditorHeader/index.vue

@@ -34,47 +34,32 @@
             >快捷操作</PopoverMenuItem
           >
         </template>
-        <div class="menu-item"><IconHamburgerButton class="icon" /></div>
+        <div class="menuCon" :class="{ menuVisible: mainMenuVisible }">
+          <img class="icon" src="./imgs/file.png" />
+        </div>
       </Popover>
-
+      <div class="line"></div>
       <div class="title">
-        <Input class="title-input" ref="titleInputRef" v-model:value="titleValue" @blur="handleUpdateTitle()" v-if="editingTitle" />
-        <div class="title-text" @click="startEditTitle()" :title="title" v-else>{{ title }}</div>
+        <div class="title-text">{{ title }}</div>
       </div>
     </div>
 
     <div class="right">
-      <div class="group-menu-item">
-        <div class="menu-item" v-tooltip="'幻灯片放映(F5)'" @click="enterScreening()">
-          <IconPpt class="icon" />
-        </div>
-        <Popover trigger="click" center>
-          <template #content>
-            <PopoverMenuItem @click="enterScreeningFromStart()">从头开始</PopoverMenuItem>
-            <PopoverMenuItem @click="enterScreening()">从当前页开始</PopoverMenuItem>
-          </template>
-          <div class="arrow-btn"><IconDown class="arrow" /></div>
-        </Popover>
-      </div>
-      <!-- <div class="menu-item" v-tooltip="'导出'" @click="setDialogForExport('pptx')">
-        <IconDownload class="icon" />
-      </div> -->
+      <div class="cancelBtn">取消</div>
+      <div class="saveBtn">保存课件</div>
     </div>
 
     <Drawer :width="320" v-model:visible="hotkeyDrawerVisible" placement="right">
       <HotkeyDoc />
       <template v-slot:title>快捷操作</template>
     </Drawer>
-
     <FullscreenSpin :loading="exporting" tip="正在导入..." />
   </div>
 </template>
 
 <script lang="ts" setup>
-import { nextTick, ref } from "vue"
 import { storeToRefs } from "pinia"
 import { useMainStore, useSlidesStore } from "@/store"
-import useScreening from "@/hooks/useScreening"
 import useImport from "@/hooks/useImport"
 import useSlideHandler from "@/hooks/useSlideHandler"
 import type { DialogForExportTypes } from "@/types/export"
@@ -83,33 +68,18 @@ import HotkeyDoc from "./HotkeyDoc.vue"
 import FileInput from "@/components/FileInput.vue"
 import FullscreenSpin from "@/components/FullscreenSpin.vue"
 import Drawer from "@/components/Drawer.vue"
-import Input from "@/components/Input.vue"
 import Popover from "@/components/Popover.vue"
 import PopoverMenuItem from "@/components/PopoverMenuItem.vue"
+import { ref } from "vue"
 
 const mainStore = useMainStore()
 const slidesStore = useSlidesStore()
 const { title } = storeToRefs(slidesStore)
-const { enterScreening, enterScreeningFromStart } = useScreening()
 const { importPPTXFile, exporting } = useImport()
 const { resetSlides } = useSlideHandler()
 
 const mainMenuVisible = ref(false)
 const hotkeyDrawerVisible = ref(false)
-const editingTitle = ref(false)
-const titleInputRef = ref<InstanceType<typeof Input>>()
-const titleValue = ref("")
-
-const startEditTitle = () => {
-  titleValue.value = title.value
-  editingTitle.value = true
-  nextTick(() => titleInputRef.value?.focus())
-}
-
-const handleUpdateTitle = () => {
-  slidesStore.setTitle(titleValue.value)
-  editingTitle.value = false
-}
 
 /* 导出老逻辑 */
 const setDialogForExport = (type: DialogForExportTypes) => {
@@ -122,10 +92,10 @@ const setDialogForExport = (type: DialogForExportTypes) => {
 .editor-header {
   background-color: #fff;
   user-select: none;
-  border-bottom: 1px solid $borderColor;
+  border-bottom: 1px solid #dedede;
   display: flex;
   justify-content: space-between;
-  padding: 0 5px;
+  padding: 0 24px;
 }
 .left,
 .right {
@@ -133,75 +103,66 @@ const setDialogForExport = (type: DialogForExportTypes) => {
   justify-content: center;
   align-items: center;
 }
-.menu-item {
-  height: 30px;
+.menuCon {
   display: flex;
   justify-content: center;
   align-items: center;
-  font-size: 14px;
-  padding: 0 10px;
-  border-radius: $borderRadius;
   cursor: pointer;
-
-  .icon {
-    font-size: 18px;
-    color: #666;
+  margin-right: 8px;
+  width: 34px;
+  height: 34px;
+  border-radius: 6px;
+  margin-left: -8px;
+  &.menuVisible {
+    background: rgba(34, 71, 133, 0.08);
   }
-
-  &:hover {
-    background-color: #f1f1f1;
+  & > img {
+    width: 20px;
+    height: 20px;
   }
 }
-.group-menu-item {
-  height: 30px;
-  display: flex;
-  margin: 0 8px;
-  padding: 0 2px;
-  border-radius: $borderRadius;
-
-  &:hover {
-    background-color: #f1f1f1;
-  }
-
-  .menu-item {
-    padding: 0 3px;
-  }
-  .arrow-btn {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    cursor: pointer;
-  }
+.line {
+  width: 1px;
+  height: calc(100% - 26px);
+  background-color: #dedede;
 }
 .title {
-  height: 30px;
-  margin-left: 2px;
-  font-size: 13px;
-
-  .title-input {
-    width: 200px;
-    height: 100%;
-    padding-left: 0;
-    padding-right: 0;
-
-    ::v-deep(input) {
-      height: 28px;
-      line-height: 28px;
-    }
-  }
+  margin-left: 16px;
   .title-text {
-    min-width: 20px;
-    max-width: 400px;
-    line-height: 30px;
-    padding: 0 6px;
-    border-radius: $borderRadius;
-    cursor: pointer;
-
-    @include ellipsis-oneline();
-
-    &:hover {
-      background-color: #f1f1f1;
-    }
+    font-weight: 600;
+    font-size: 15px;
+    color: #131415;
+  }
+}
+.cancelBtn {
+  width: 88px;
+  height: 32px;
+  background: #f1f2f6;
+  border-radius: 6px;
+  line-height: 32px;
+  font-weight: 600;
+  font-size: 14px;
+  color: #1e2022;
+  text-align: center;
+  cursor: pointer;
+  &:hover {
+    opacity: 0.8;
+  }
+}
+.saveBtn {
+  margin-left: 16px;
+  width: 88px;
+  height: 32px;
+  background: linear-gradient(312deg, #1b7af8 0%, #3cbbff 100%);
+  border-radius: 6px;
+  line-height: 32px;
+  font-weight: 600;
+  font-size: 14px;
+  color: #ffffff;
+  text-align: center;
+  cursor: pointer;
+  &:hover {
+    opacity: 0.8;
   }
 }
 </style>

+ 3 - 3
src/views/Editor/index.vue

@@ -55,10 +55,10 @@ usePasteEvent()
   height: 100%;
 }
 .layout-header {
-  height: 40px;
+  height: 48px;
 }
 .layout-content {
-  height: calc(100% - 80px);
+  height: calc(100% - 113px);
   display: flex;
 }
 .layout-content-left {
@@ -67,7 +67,7 @@ usePasteEvent()
   flex-shrink: 0;
 }
 .center-top {
-  height: 40px;
+  height: 65px;
 }
 .layout-content-center {
   width: calc(100% - 160px - 260px);