From c92163b60a2d47c1693ef13435504a3c7b366f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BA=9A=E6=98=95?= <1549469775@qq.com> Date: Sat, 22 Feb 2025 16:35:02 +0800 Subject: [PATCH] fix bug --- electron.vite.config.ts | 1 + src/renderer/src/pages/_ui/Browser.vue | 462 ++++++++++++++++++++++++++++++++ src/renderer/src/pages/index.vue | 470 +-------------------------------- 3 files changed, 468 insertions(+), 465 deletions(-) create mode 100644 src/renderer/src/pages/_ui/Browser.vue diff --git a/electron.vite.config.ts b/electron.vite.config.ts index ee44d56..2f3e93d 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -56,6 +56,7 @@ export default defineConfig({ root: resolve(__dirname, "src/renderer"), // https://github.com/posva/unplugin-vue-router extensions: [".vue", ".setup.tsx"], + exclude: ['**/_ui'] }), }, }), diff --git a/src/renderer/src/pages/_ui/Browser.vue b/src/renderer/src/pages/_ui/Browser.vue new file mode 100644 index 0000000..35971ee --- /dev/null +++ b/src/renderer/src/pages/_ui/Browser.vue @@ -0,0 +1,462 @@ +<script setup lang="ts"> +import { onBeforeMount, onBeforeUnmount, onMounted, ref, useTemplateRef, nextTick } from "vue" +import { PopupMenu } from "@/bridge/PopupMenu" + +// const PlaceHolderRef = useTemplateRef("PlaceHolder") +// function OnResize() { +// const el = PlaceHolderRef.value +// if (el) { +// const rect = el.getBoundingClientRect().toJSON() +// console.log(rect) +// api.call("TabsCommand.bindElement", rect) +// } +// } +// onMounted(OnResize) +// window.addEventListener("resize", OnResize) +// onBeforeUnmount(() => { +// window.removeEventListener("resize", OnResize) +// }) + +const PlaceHolder = useTemplateRef("PlaceHolder") +const { stop } = useResizeObserver(PlaceHolder, () => { + const el = PlaceHolder.value + if (el) { + const rect = el.getBoundingClientRect().toJSON() + api.call("TabsCommand.bindElement", rect) + } +}) + +onBeforeUnmount(() => { + stop() +}) + +const list = ref<any[]>([]) +const curUrl = ref<any>("") +const curIndex = ref<any>(-1) +const listener = (_, v) => { + list.value = v + const el = v.find(v => v.isActive) + curIndex.value = v.findIndex(v => v.isActive) + if (el) { + curUrl.value = el.showUrl + } else { + curUrl.value = "" + } +} +if (import.meta.hot) { + api.off("TabsCommand.update", listener) +} +api.on("TabsCommand.update", listener) +onMounted(() => { + api.call("TabsCommand.sync") +}) + +onBeforeMount(async () => { + list.value = await fetch("api://fuck/TabsService/getAllTabs").then(async res => await res.json()) +}) + +// const url = ref("") + +// async function addTab() { +// if (!url.value) url.value = "about:blank" +// await fetch("api://fuck/TabsService/add", { +// method: "POST", +// body: JSON.stringify({ url: url.value }), +// }) +// url.value = "" +// onClick() +// } + +function handleTabContextMenu(_, index) { + const menu = new PopupMenu([ + { + label: "右侧关闭", + click() { + const all: number[] = [] + list.value.forEach((_, i) => { + if (i <= index) return + all.push(i) + }) + fetch("api://fuck/TabsService/closeTabAll", { + method: "POST", + body: JSON.stringify({ active: all }), + }) + }, + }, + { + type: "separator", + }, + ]) + menu.show() +} + +function scrollTabIntoView(index: number) { + nextTick(() => { + const tabList = document.querySelector(".tab-list") + const tabItems = tabList?.querySelectorAll(".tab-item") + if (tabList && tabItems && tabItems[index]) { + tabItems[index].scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" }) + } + }) +} + +async function changeTab(_, index) { + await api.call("TabsCommand.setActive", index) + scrollTabIntoView(index) +} + +function addTabInput() { + if (curUrl.value) { + if (curIndex.value !== undefined && curIndex.value >= 0) { + api.call("TabsCommand.nagivate", curIndex.value, curUrl.value) + } else { + api.call("TabsCommand.add", curUrl.value) + } + } +} + +async function addTab() { + await api.call("TabsCommand.add", "about:blank") + scrollTabIntoView(list.value.length - 1) +} + +async function closeTab(_, index) { + await fetch("api://fuck/TabsService/closeTab", { + method: "POST", + body: JSON.stringify({ active: index }), + }) + onClick() +} + +const onClick = async () => { + list.value = await api.call("TabsCommand.getAllTabs") + // list.value = await fetch("api://fuck/TabsService/getAllTabs").then(async res => await res.json()) + // fetch("api://fuck/BasicService/showAbout").then(async res => console.log(await res.json())) + // fetch("api://index/openAbout", { + // method: "POST", + // body: JSON.stringify({ a: "234" }), + // }).then(async res => console.log(await res.json())) +} + +function onClickDevTool() { + fetch("api://fuck/BasicService/openTabDevtool") +} +</script> + +<template> + <div h="100px" flex flex-col b-b="1px solid var(--border-color)" class="tab-container"> + <!-- Tab列表 --> + <div class="tab-list-container"> + <div class="tab-list"> + <div + v-for="(item, index) in list" + :key="index" + :class="{ + 'tab-item': true, + active: item.isActive, + }" + @contextmenu="handleTabContextMenu(item, index)" + @click="changeTab(item, index)" + > + <div class="tab-content"> + <!-- 网站图标 --> + <img v-if="item.favicons?.length" :src="item.favicons[0]" class="tab-icon" alt="" /> + <div v-else class="tab-icon-placeholder"></div> + + <!-- 标题 --> + <div class="tab-title">{{ item.title || "加载中..." }}</div> + + <!-- 关闭按钮 --> + <div class="tab-close" @click.stop="closeTab(item, index)"> + <svg width="16" height="16" viewBox="0 0 16 16"> + <path + d="M12.81 4.36l-1.17-1.17L8 6.83 4.36 3.19 3.19 4.36 6.83 8l-3.64 3.64 1.17 1.17L8 9.17l3.64 3.64 1.17-1.17L9.17 8z" + fill="currentColor" + /> + </svg> + </div> + </div> + </div> + </div> + + <!-- 新建标签页按钮移到容器外部 --> + <div class="new-tab-button-container"> + <div class="new-tab-button" @click.stop="addTab()"> + <svg width="20" height="20" viewBox="0 0 20 20"> + <path d="M10 4v12M4 10h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" /> + </svg> + </div> + </div> + </div> + + <!-- 地址栏 --> + <div class="address-bar"> + <div class="url-input-container"> + <input v-model="curUrl" placeholder="输入网址" type="text" class="url-input" /> + </div> + <button class="action-button" @click="addTabInput()">前往</button> + <button class="action-button" @click="onClickDevTool()">DevTool</button> + </div> + </div> + + <!-- 内容区域 --> + <div ref="PlaceHolder" ml="1px" flex-1 h-0 flex items-center justify-center> + <!-- 保持原有内容 --> + </div> +</template> + +<style scoped> +.tab-container { + background: var(--tab-bar-bg, #f3f3f3); + border-bottom: none; + padding-top: 4px; + height: auto; + min-height: 80px; +} + +.tab-list-container { + position: relative; + display: flex; + align-items: flex-end; + height: 32px; + padding: 0; + margin-bottom: 0; + width: 100%; + overflow: auto; +} + +.tab-list { + height: 32px; + display: flex; + align-items: flex-end; + gap: 0; + margin-bottom: 0; + overflow-x: auto; + overflow-y: hidden; + padding: 0 4px; + /* 隐藏滚动条但保持功能 */ + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + &::-webkit-scrollbar { + display: none; /* Chrome, Safari and Opera */ + } +} + +.tab-item { + position: relative; + min-width: 160px; + max-width: 240px; + height: 29px; + margin-right: -6px; + border-radius: 6px 6px 0 0; + background: var(--tab-bg, #dee1e6); + transition: all 0.15s ease; + z-index: 1; + display: flex; + align-items: center; + flex-shrink: 0; /* 防止标签被压缩 */ + cursor: pointer; +} + +.tab-item::after { + content: ""; + position: absolute; + right: 0; + top: 6px; + height: 16px; + width: 1px; + background: var(--tab-separator-color, #bdc1c6); + opacity: 0.3; +} + +.tab-item:hover { + background: var(--tab-hover-bg, #e9ebee); +} + +.tab-item.active { + background: var(--tab-active-bg, #fff); + z-index: 2; + height: 32px; + margin-bottom: -1px; +} + +.tab-item.active::before { + content: ""; + position: absolute; + left: 0; + right: 0; + top: 0; + height: 2px; + background: var(--primary-color, #1a73e8); + border-radius: 2px 2px 0 0; +} + +.tab-content { + display: flex; + align-items: center; + padding: 0 8px; + height: 100%; + gap: 6px; + width: 100%; +} + +.tab-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + border-radius: 3px; +} + +.tab-icon-placeholder { + width: 16px; + height: 16px; + background: #bdc1c6; + border-radius: 50%; + flex-shrink: 0; + opacity: 0.7; +} + +.tab-title { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 12px; + color: var(--text-color, #5f6368); + line-height: 1.2; + padding-right: 4px; +} + +.tab-item.active .tab-title { + color: var(--active-text-color, #202124); +} + +.tab-close { + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + color: var(--icon-color, #5f6368); + opacity: 0; + transition: opacity 0.15s ease; + flex-shrink: 0; +} + +.tab-item:hover .tab-close { + opacity: 0.6; +} + +.tab-close:hover { + background: var(--close-hover-bg, rgba(0, 0, 0, 0.08)); + opacity: 1; +} + +.new-tab-button-container { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 32px; + background: var(--tab-bar-bg); +} + +.new-tab-button { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; + color: var(--icon-color, #5f6368); + transition: all 0.15s ease; + cursor: pointer; + opacity: 0.8; + background: transparent; +} + +.new-tab-button:hover { + background: var(--tab-hover-bg, rgba(0, 0, 0, 0.06)); + opacity: 1; +} + +.address-bar { + padding: 8px 12px; + margin: 0; + background: var(--address-bar-bg, #fff); + display: flex; + align-items: center; + gap: 8px; + width: 100%; + border-top: 1px solid var(--tab-separator-color, rgba(0, 0, 0, 0.1)); +} + +.url-input-container { + flex: 1; + height: 36px; + background: var(--input-bg, #f1f3f4); + border-radius: 18px; + padding: 0 16px; + display: flex; + align-items: center; + margin: 0; + min-width: 0; +} + +.url-input { + width: 100%; + height: 100%; + border: none; + background: transparent; + outline: none; + font-size: 14px; + color: var(--text-color, #333); +} + +.action-button { + flex-shrink: 0; + height: 36px; + padding: 0 16px; + border: none; + border-radius: 18px; + background: transparent; + color: var(--text-color, #333); + font-size: 14px; + cursor: pointer; + transition: all 0.2s; +} + +.action-button:hover { + background: var(--button-hover-bg, #f1f3f4); +} + +/* 修改CSS变量 */ +:root { + --tab-bar-bg: #f1f3f4; + --tab-bg: rgba(32, 33, 36, 0.1); + --tab-hover-bg: rgba(32, 33, 36, 0.08); + --tab-active-bg: #fff; + --tab-separator-color: rgba(0, 0, 0, 0.2); + --text-color: #5f6368; + --active-text-color: #202124; + --icon-color: #5f6368; + --close-hover-bg: rgba(0, 0, 0, 0.08); + --primary-color: #1a73e8; + --new-tab-shadow: 0 -8px 12px -6px rgba(0, 0, 0, 0.1); +} + +[data-theme="dark"] { + --tab-bar-bg: #202124; + --tab-bg: rgba(255, 255, 255, 0.1); + --tab-hover-bg: rgba(255, 255, 255, 0.08); + --tab-active-bg: #292a2d; + --tab-separator-color: rgba(255, 255, 255, 0.2); + --text-color: #9ba0a5; + --active-text-color: #e8eaed; + --icon-color: #9ba0a5; + --close-hover-bg: rgba(255, 255, 255, 0.08); + --primary-color: #8ab4f8; + --new-tab-shadow: 0 -8px 12px -6px rgba(0, 0, 0, 0.3); +} +</style> diff --git a/src/renderer/src/pages/index.vue b/src/renderer/src/pages/index.vue index 31d6727..dc280d9 100644 --- a/src/renderer/src/pages/index.vue +++ b/src/renderer/src/pages/index.vue @@ -1,478 +1,18 @@ <script setup lang="ts"> -import { onBeforeMount, onBeforeUnmount, onMounted, ref, useTemplateRef, nextTick } from "vue" -import { PopupMenu } from "@/bridge/PopupMenu" - -// const PlaceHolderRef = useTemplateRef("PlaceHolder") -// function OnResize() { -// const el = PlaceHolderRef.value -// if (el) { -// const rect = el.getBoundingClientRect().toJSON() -// console.log(rect) -// api.call("TabsCommand.bindElement", rect) -// } -// } -// onMounted(OnResize) -// window.addEventListener("resize", OnResize) -// onBeforeUnmount(() => { -// window.removeEventListener("resize", OnResize) -// }) - -const PlaceHolder = useTemplateRef("PlaceHolder") -const { stop } = useResizeObserver(PlaceHolder, () => { - const el = PlaceHolder.value - if (el) { - const rect = el.getBoundingClientRect().toJSON() - api.call("TabsCommand.bindElement", rect) - } -}) - -onBeforeUnmount(() => { - stop() -}) - -const list = ref<any[]>([]) -const curUrl = ref<any>("") -const curIndex = ref<any>(-1) -const listener = (_, v) => { - list.value = v - const el = v.find(v => v.isActive) - curIndex.value = v.findIndex(v => v.isActive) - if (el) { - curUrl.value = el.showUrl - } else { - curUrl.value = "" - } -} -if (import.meta.hot) { - api.off("TabsCommand.update", listener) -} -api.on("TabsCommand.update", listener) -onMounted(() => { - api.call("TabsCommand.sync") -}) - -onBeforeMount(async () => { - list.value = await fetch("api://fuck/TabsService/getAllTabs").then(async res => await res.json()) -}) - -// const url = ref("") - -// async function addTab() { -// if (!url.value) url.value = "about:blank" -// await fetch("api://fuck/TabsService/add", { -// method: "POST", -// body: JSON.stringify({ url: url.value }), -// }) -// url.value = "" -// onClick() -// } - -function handleTabContextMenu(_, index) { - const menu = new PopupMenu([ - { - label: "右侧关闭", - click() { - const all: number[] = [] - list.value.forEach((_, i) => { - if (i <= index) return - all.push(i) - }) - fetch("api://fuck/TabsService/closeTabAll", { - method: "POST", - body: JSON.stringify({ active: all }), - }) - }, - }, - { - type: "separator", - }, - ]) - menu.show() -} - -function scrollTabIntoView(index: number) { - nextTick(() => { - const tabList = document.querySelector('.tab-list') - const tabItems = tabList?.querySelectorAll('.tab-item') - if (tabList && tabItems && tabItems[index]) { - tabItems[index].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }) - } - }) -} - -async function changeTab(_, index) { - await api.call("TabsCommand.setActive", index) - scrollTabIntoView(index) -} - -function addTabInput() { - if (curUrl.value) { - if (curIndex.value !== undefined && curIndex.value >= 0) { - api.call("TabsCommand.nagivate", curIndex.value, curUrl.value) - } else { - api.call("TabsCommand.add", curUrl.value) - } - } -} - -async function addTab() { - await api.call("TabsCommand.add", "about:blank") - scrollTabIntoView(list.value.length - 1) -} - -async function closeTab(_, index) { - await fetch("api://fuck/TabsService/closeTab", { - method: "POST", - body: JSON.stringify({ active: index }), - }) - onClick() -} - -const onClick = async () => { - list.value = await api.call("TabsCommand.getAllTabs") - // list.value = await fetch("api://fuck/TabsService/getAllTabs").then(async res => await res.json()) - // fetch("api://fuck/BasicService/showAbout").then(async res => console.log(await res.json())) - // fetch("api://index/openAbout", { - // method: "POST", - // body: JSON.stringify({ a: "234" }), - // }).then(async res => console.log(await res.json())) -} - -function onClickDevTool() { - fetch("api://fuck/BasicService/openTabDevtool") -} +import Browser from "./_ui/Browser.vue" </script> <template> <div h-full flex> <div w="200px" relative> + <div p="8px 10px" text="12px" @click="$router.push('/_ui/Browser')" border border-b cursor="pointer" hover:bg-gray-100>浏览器</div> + <div p="8px 10px" text="12px" border border-b cursor="pointer" hover:bg-gray-100>浏览器</div> <AdjustLine></AdjustLine> </div> <div b-l="1px solid #E5E5E5" flex-1 w-0 overflow-auto flex flex-col> - <!-- Tab栏 --> - <div h="100px" flex flex-col b-b="1px solid var(--border-color)" class="tab-container"> - <!-- Tab列表 --> - <div class="tab-list-container"> - <div class="tab-list"> - <div - v-for="(item, index) in list" - :key="index" - :class="{ - 'tab-item': true, - 'active': item.isActive - }" - @contextmenu="handleTabContextMenu(item, index)" - @click="changeTab(item, index)" - > - <div class="tab-content"> - <!-- 网站图标 --> - <img - v-if="item.favicons?.length" - :src="item.favicons[0]" - class="tab-icon" - alt="" - /> - <div v-else class="tab-icon-placeholder"></div> - - <!-- 标题 --> - <div class="tab-title">{{ item.title || "加载中..." }}</div> - - <!-- 关闭按钮 --> - <div class="tab-close" @click.stop="closeTab(item, index)"> - <svg width="16" height="16" viewBox="0 0 16 16"> - <path d="M12.81 4.36l-1.17-1.17L8 6.83 4.36 3.19 3.19 4.36 6.83 8l-3.64 3.64 1.17 1.17L8 9.17l3.64 3.64 1.17-1.17L9.17 8z" - fill="currentColor"/> - </svg> - </div> - </div> - </div> - </div> - - <!-- 新建标签页按钮移到容器外部 --> - <div class="new-tab-button-container"> - <div class="new-tab-button" @click.stop="addTab()"> - <svg width="20" height="20" viewBox="0 0 20 20"> - <path d="M10 4v12M4 10h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> - </svg> - </div> - </div> - </div> - - <!-- 地址栏 --> - <div class="address-bar"> - <div class="url-input-container"> - <input - v-model="curUrl" - placeholder="输入网址" - type="text" - class="url-input" - /> - </div> - <button class="action-button" @click="addTabInput()">前往</button> - <button class="action-button" @click="onClickDevTool()">DevTool</button> - </div> - </div> - - <!-- 内容区域 --> - <div ref="PlaceHolder" ml="1px" flex-1 h-0 flex items-center justify-center> - <!-- 保持原有内容 --> - </div> + <Browser></Browser> </div> </div> </template> -<style scoped> -.tab-container { - background: var(--tab-bar-bg, #f3f3f3); - border-bottom: none; - padding-top: 4px; - height: auto; - min-height: 80px; -} - -.tab-list-container { - position: relative; - display: flex; - align-items: flex-end; - height: 32px; - padding: 0; - margin-bottom: 0; - width: 100%; - overflow: auto; -} - -.tab-list { - height: 32px; - display: flex; - align-items: flex-end; - gap: 0; - margin-bottom: 0; - overflow-x: auto; - overflow-y: hidden; - padding: 0 4px; - /* 隐藏滚动条但保持功能 */ - scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE and Edge */ - &::-webkit-scrollbar { - display: none; /* Chrome, Safari and Opera */ - } -} - -.tab-item { - position: relative; - min-width: 160px; - max-width: 240px; - height: 29px; - margin-right: -6px; - border-radius: 6px 6px 0 0; - background: var(--tab-bg, #dee1e6); - transition: all 0.15s ease; - z-index: 1; - display: flex; - align-items: center; - flex-shrink: 0; /* 防止标签被压缩 */ - cursor: pointer; -} - -.tab-item::after { - content: ''; - position: absolute; - right: 0; - top: 6px; - height: 16px; - width: 1px; - background: var(--tab-separator-color, #bdc1c6); - opacity: 0.3; -} - -.tab-item:hover { - background: var(--tab-hover-bg, #e9ebee); -} - -.tab-item.active { - background: var(--tab-active-bg, #fff); - z-index: 2; - height: 32px; - margin-bottom: -1px; -} - -.tab-item.active::before { - content: ''; - position: absolute; - left: 0; - right: 0; - top: 0; - height: 2px; - background: var(--primary-color, #1a73e8); - border-radius: 2px 2px 0 0; -} - -.tab-content { - display: flex; - align-items: center; - padding: 0 8px; - height: 100%; - gap: 6px; - width: 100%; -} - -.tab-icon { - width: 16px; - height: 16px; - flex-shrink: 0; - border-radius: 3px; -} - -.tab-icon-placeholder { - width: 16px; - height: 16px; - background: #bdc1c6; - border-radius: 50%; - flex-shrink: 0; - opacity: 0.7; -} - -.tab-title { - flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - font-size: 12px; - color: var(--text-color, #5f6368); - line-height: 1.2; - padding-right: 4px; -} - -.tab-item.active .tab-title { - color: var(--active-text-color, #202124); -} - -.tab-close { - width: 16px; - height: 16px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - color: var(--icon-color, #5f6368); - opacity: 0; - transition: opacity 0.15s ease; - flex-shrink: 0; -} - -.tab-item:hover .tab-close { - opacity: 0.6; -} - -.tab-close:hover { - background: var(--close-hover-bg, rgba(0, 0, 0, 0.08)); - opacity: 1; -} - -.new-tab-button-container { - display: flex; - align-items: center; - justify-content: center; - width: 40px; - height: 32px; - background: var(--tab-bar-bg); -} - -.new-tab-button { - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 6px; - color: var(--icon-color, #5f6368); - transition: all 0.15s ease; - cursor: pointer; - opacity: 0.8; - background: transparent; -} - -.new-tab-button:hover { - background: var(--tab-hover-bg, rgba(0, 0, 0, 0.06)); - opacity: 1; -} - -.address-bar { - padding: 8px 12px; - margin: 0; - background: var(--address-bar-bg, #fff); - display: flex; - align-items: center; - gap: 8px; - width: 100%; - border-top: 1px solid var(--tab-separator-color, rgba(0, 0, 0, 0.1)); -} - -.url-input-container { - flex: 1; - height: 36px; - background: var(--input-bg, #f1f3f4); - border-radius: 18px; - padding: 0 16px; - display: flex; - align-items: center; - margin: 0; - min-width: 0; -} - -.url-input { - width: 100%; - height: 100%; - border: none; - background: transparent; - outline: none; - font-size: 14px; - color: var(--text-color, #333); -} - -.action-button { - flex-shrink: 0; - height: 36px; - padding: 0 16px; - border: none; - border-radius: 18px; - background: transparent; - color: var(--text-color, #333); - font-size: 14px; - cursor: pointer; - transition: all 0.2s; -} - -.action-button:hover { - background: var(--button-hover-bg, #f1f3f4); -} - -/* 修改CSS变量 */ -:root { - --tab-bar-bg: #f1f3f4; - --tab-bg: rgba(32, 33, 36, 0.1); - --tab-hover-bg: rgba(32, 33, 36, 0.08); - --tab-active-bg: #fff; - --tab-separator-color: rgba(0, 0, 0, 0.2); - --text-color: #5f6368; - --active-text-color: #202124; - --icon-color: #5f6368; - --close-hover-bg: rgba(0, 0, 0, 0.08); - --primary-color: #1a73e8; - --new-tab-shadow: 0 -8px 12px -6px rgba(0, 0, 0, 0.1); -} - -[data-theme="dark"] { - --tab-bar-bg: #202124; - --tab-bg: rgba(255, 255, 255, 0.1); - --tab-hover-bg: rgba(255, 255, 255, 0.08); - --tab-active-bg: #292a2d; - --tab-separator-color: rgba(255, 255, 255, 0.2); - --text-color: #9ba0a5; - --active-text-color: #e8eaed; - --icon-color: #9ba0a5; - --close-hover-bg: rgba(255, 255, 255, 0.08); - --primary-color: #8ab4f8; - --new-tab-shadow: 0 -8px 12px -6px rgba(0, 0, 0, 0.3); -} -</style> +<style lang="scss" scoped></style>