main
vue 150 lines 3.76 KB
Raw
1 <template>
2 <header class="toolbar" :class="{ boxed }">
3 <div class="wrap flex items-center justify-end gap-3">
4 <div class="logo-box flex cursor-pointer items-center gap-2" @click="openNav()">
5 <Logo type="small" />
6 <Icon :size="20" name="carbon:chevron-right" />
7 </div>
8
9 <Breadcrumb class="grow" />
10 <PinnedPages />
11
12 <PillWrapper>
13 <Search />
14 <FullscreenSwitch />
15 <ThemeSwitch />
16 <Notifications />
17 <Avatar />
18 </PillWrapper>
19 </div>
20
21 <BlurEffect />
22 <div v-if="gradient" :class="`gradient-${gradient}`"></div>
23 </header>
24 </template>
25
26 <script lang="ts" setup>
27 import BlurEffect from "@/components/common/BlurEffect.vue"
28 import Icon from "@/components/common/Icon.vue"
29 import { useThemeStore } from "@/stores/theme"
30 import Logo from "../Logo.vue"
31 import Avatar from "./Avatar.vue"
32 import Breadcrumb from "./Breadcrumb.vue"
33 import FullscreenSwitch from "./FullscreenSwitch.vue"
34 import Notifications from "./Notifications.vue"
35 import PillWrapper from "./PillWrapper.vue"
36 import PinnedPages from "./PinnedPagesV2.vue"
37 import Search from "./Search.vue"
38 import ThemeSwitch from "./ThemeSwitch.vue"
39
40 const { boxed, gradient } = defineProps<{
41 boxed: boolean
42 gradient?: "body" | "sidebar"
43 }>()
44
45 const themeStore = useThemeStore()
46 const openNav = () => themeStore.openSidebar()
47 </script>
48
49 <style lang="scss" scoped>
50 .toolbar {
51 position: sticky;
52 top: 0;
53 left: 0;
54 height: var(--toolbar-height);
55 width: 100%;
56 max-width: 100%;
57 padding: 0 var(--view-padding);
58 z-index: 3;
59 overflow: hidden;
60
61 .wrap {
62 height: var(--toolbar-height);
63 overflow: hidden;
64 width: 100%;
65 max-width: 100%;
66 position: relative;
67 z-index: 1;
68
69 @media (max-width: 850px) {
70 .pinned-pages {
71 display: none;
72 }
73 }
74
75 @media (max-width: 700px) {
76 justify-content: space-between;
77 .breadcrumb {
78 display: none;
79 }
80 }
81 }
82
83 &.boxed {
84 padding: 0;
85 .wrap {
86 padding: 0 var(--view-padding);
87 max-width: var(--boxed-width);
88 margin: 0 auto;
89 }
90 }
91
92 .gradient-sidebar {
93 position: absolute;
94 inset: 0;
95 background-color: var(--bg-sidebar-color);
96 background: linear-gradient(
97 to bottom,
98 rgba(var(--bg-sidebar-color-rgb) / 1) 0%,
99 rgba(var(--bg-sidebar-color-rgb) / 0.945) 8.6%,
100 rgba(var(--bg-sidebar-color-rgb) / 0.888) 16.2%,
101 rgba(var(--bg-sidebar-color-rgb) / 0.83) 22.9%,
102 rgba(var(--bg-sidebar-color-rgb) / 0.769) 28.9%,
103 rgba(var(--bg-sidebar-color-rgb) / 0.707) 34.4%,
104 rgba(var(--bg-sidebar-color-rgb) / 0.644) 39.5%,
105 rgba(var(--bg-sidebar-color-rgb) / 0.578) 44.5%,
106 rgba(var(--bg-sidebar-color-rgb) / 0.511) 49.5%,
107 rgba(var(--bg-sidebar-color-rgb) / 0.443) 54.7%,
108 rgba(var(--bg-sidebar-color-rgb) / 0.373) 60.3%,
109 rgba(var(--bg-sidebar-color-rgb) / 0.301) 66.4%,
110 rgba(var(--bg-sidebar-color-rgb) / 0.228) 73.3%,
111 rgba(var(--bg-sidebar-color-rgb) / 0.153) 81%,
112 rgba(var(--bg-sidebar-color-rgb) / 0.077) 89.9%,
113 rgba(var(--bg-sidebar-color-rgb) / 0) 100%
114 );
115 }
116 .gradient-body {
117 position: absolute;
118 inset: 0;
119 background-color: var(--bg-body-color);
120 background: linear-gradient(
121 to bottom,
122 rgba(var(--bg-body-color-rgb) / 1) 0%,
123 rgba(var(--bg-body-color-rgb) / 0.738) 19%,
124 rgba(var(--bg-body-color-rgb) / 0.541) 34%,
125 rgba(var(--bg-body-color-rgb) / 0.382) 47%,
126 rgba(var(--bg-body-color-rgb) / 0.278) 56.5%,
127 rgba(var(--bg-body-color-rgb) / 0.194) 65%,
128 rgba(var(--bg-body-color-rgb) / 0.126) 73%,
129 rgba(var(--bg-body-color-rgb) / 0.075) 80.2%,
130 rgba(var(--bg-body-color-rgb) / 0.042) 86.1%,
131 rgba(var(--bg-body-color-rgb) / 0.021) 91%,
132 rgba(var(--bg-body-color-rgb) / 0.008) 95.2%,
133 rgba(var(--bg-body-color-rgb) / 0.002) 98.2%,
134 rgba(var(--bg-body-color-rgb) / 0) 100%
135 );
136 }
137 }
138
139 .direction-rtl {
140 .toolbar {
141 .wrap {
142 .logo-box {
143 .n-icon {
144 transform: rotateY(180deg);
145 }
146 }
147 }
148 }
149 }
150 </style>