@eox/pages-theme-eox 0.7.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eox/pages-theme-eox",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "description": "Vitepress Theme with EOX branding",
6
6
  "main": "src/index.js",
package/src/Layout.vue CHANGED
@@ -2,126 +2,7 @@
2
2
  <Layout :class="`layout-${frontmatter.layout}`">
3
3
  <template #layout-top>
4
4
  <slot name="layout-top"></slot>
5
- <div class="top-nav at-top row center-align">
6
- <nav class="large-padding no-margin center-align nav-mobile">
7
- <a href="/">
8
- <img
9
- :src="withBase(theme.logo)"
10
- :alt="`${site.title} logo`"
11
- class="logo"
12
- />
13
- </a>
14
- <div class="max"></div>
15
- <button data-ui="#mobile-menu" class="circle transparent">
16
- <i class="mdi mdi-menu"></i>
17
- </button>
18
- <dialog id="mobile-menu" class="max">
19
- <nav>
20
- <a data-ui="#mobile-menu" href="/">
21
- <img
22
- :src="withBase(theme.logo)"
23
- :alt="`${site.title} logo`"
24
- class="logo margin"
25
- />
26
- </a>
27
- <div class="max"></div>
28
- <button data-ui="#mobile-menu" class="circle transparent">
29
- <i class="mdi mdi-close"></i>
30
- </button>
31
- </nav>
32
- <ul class="list border large-space">
33
- <li v-for="item in theme.nav.filter((item) => !item.action)">
34
- <a
35
- data-ui="#mobile-menu"
36
- :href="withBase(item.link)"
37
- :target="item.target"
38
- :rel="item.rel"
39
- :class="item.action ? 'button large medium-elevate cta' : ''"
40
- >
41
- <span>{{ item.text }}</span>
42
- </a>
43
- </li>
44
- </ul>
45
- <div class="grid">
46
- <div class="s12">
47
- <nav v-for="item in theme.nav.filter((item) => item.action)">
48
- <a
49
- data-ui="#mobile-menu"
50
- :href="withBase(item.link)"
51
- :target="item.target"
52
- :rel="item.rel"
53
- :class="
54
- item.action
55
- ? `button responsive large ${item.action} ${item.action === 'primary' || item.action === 'secondary' ? 'medium-elevate' : 'border no-elevate'}`
56
- : 'primary-text'
57
- "
58
- >
59
- <span>{{ item.text }}</span>
60
- <i
61
- v-if="
62
- item.action === 'primary' || item.action === 'secondary'
63
- "
64
- class="mdi mdi-arrow-right"
65
- ></i>
66
- </a>
67
- </nav>
68
- </div>
69
- </div>
70
- </dialog>
71
- </nav>
72
- <nav
73
- class="large-padding no-margin center-align row holder nav-desktop"
74
- >
75
- <a href="/">
76
- <img
77
- :src="withBase(theme.logo)"
78
- :alt="`${site.title} logo`"
79
- class="logo"
80
- />
81
- </a>
82
- <div class="space"></div>
83
- <nav>
84
- <ul class="left-align no-margin">
85
- <li v-for="item in theme.nav.filter((i) => !i.action)">
86
- <a
87
- class="button text"
88
- :href="withBase(item.link)"
89
- :target="item.target"
90
- :rel="item.rel"
91
- >{{ item.text }}</a
92
- >
93
- </li>
94
- </ul>
95
- </nav>
96
- <div class="max"></div>
97
- <nav class="actions">
98
- <ul class="left-align no-margin">
99
- <li v-for="item in theme.nav.filter((item) => item.action)">
100
- <a
101
- class="button right-align"
102
- :class="`${item.action} ${
103
- item.action === 'primary' || item.action === 'secondary'
104
- ? item.action
105
- : 'border'
106
- }`"
107
- :href="withBase(item.link)"
108
- :target="item.target"
109
- :rel="item.rel"
110
- @click="trackEvent(['CTA', 'Click', 'Nav', item.text])"
111
- >
112
- <span>{{ item.text }}</span>
113
- <i
114
- v-if="
115
- item.action === 'primary' || item.action === 'secondary'
116
- "
117
- class="mdi mdi-arrow-right"
118
- ></i>
119
- </a>
120
- </li>
121
- </ul>
122
- </nav>
123
- </nav>
124
- </div>
5
+ <NavBar />
125
6
  <header
126
7
  v-if="frontmatter.hero"
127
8
  class="primary primary-gradient-background"
@@ -156,7 +37,7 @@
156
37
  <h1 class="bold" style="font-size: clamp(2rem, 5vw, 45px)">
157
38
  {{ frontmatter.hero.text }}
158
39
  </h1>
159
- <p>{{ frontmatter.hero.tagline }}</p>
40
+ <p :innerHTML="frontmatter.hero.tagline"></p>
160
41
  </div>
161
42
  <div style="grid-area: actions">
162
43
  <a
@@ -212,7 +93,7 @@
212
93
  <div class="grid">
213
94
  <div class="s12 l6">
214
95
  <img
215
- :src="withBase(theme.logo)"
96
+ :src="withBase(theme.logo.light)"
216
97
  :alt="`${site.title} logo`"
217
98
  class="logo"
218
99
  />
@@ -310,90 +191,9 @@ import { trackEvent } from "./helpers";
310
191
  const { Layout } = DefaultTheme;
311
192
  const { frontmatter, page, site, theme } = useData();
312
193
  const router = useRouter();
313
-
314
- if (!import.meta.env.SSR) {
315
- const scrollListener = () => {
316
- const nav = document.querySelector(".top-nav");
317
-
318
- if (window.scrollY > nav.clientHeight) {
319
- nav.classList.remove("at-top");
320
- } else {
321
- nav.classList.add("at-top");
322
- }
323
- };
324
- window.addEventListener("scroll", scrollListener);
325
- }
326
194
  </script>
327
195
 
328
196
  <style>
329
- .top-nav {
330
- position: sticky;
331
- z-index: 2;
332
- top: 0;
333
- background: var(--surface);
334
- box-shadow:
335
- 0 1px 5px #15142e0d,
336
- 0 4px 16px #15142e1a,
337
- inset 0 0 0 1px #ffffff80;
338
- display: flex;
339
- width: 100%;
340
- transition: all 0.3s ease-in-out;
341
- }
342
- .top-nav.at-top {
343
- box-shadow: none;
344
- }
345
- .Layout.layout-home .top-nav.at-top .nav-desktop .button.primary,
346
- .Layout.layout-home .top-nav.at-top .nav-desktop .button.secondary,
347
- .Layout.layout-home .top-nav.at-top .nav-desktop .button.alt {
348
- display: none;
349
- }
350
- .Layout.layout-home .top-nav.at-top nav.actions {
351
- gap: 0;
352
- }
353
- .top-nav:not(.at-top) > nav {
354
- padding-top: 16px !important;
355
- padding-bottom: 16px !important;
356
- }
357
- .Layout.layout-home .top-nav.at-top {
358
- background: transparent;
359
- color: #f7f8f8;
360
- }
361
- .Layout .top-nav nav .button {
362
- color: var(--on-surface);
363
- }
364
- .Layout.layout-home .top-nav.at-top .nav-desktop .button {
365
- color: var(--on-surface);
366
- background: var(--surface);
367
- }
368
- .Layout.layout-home .top-nav.at-top .nav-desktop .button.text {
369
- color: #f7f8f8;
370
- background: none;
371
- }
372
- .Layout.layout-home .top-nav.at-top .nav-desktop .button.border {
373
- color: #f7f8f8;
374
- border-color: #f7f8f855;
375
- background: none;
376
- }
377
- .Layout.layout-home .top-nav.at-top > nav > a > .logo {
378
- filter: brightness(0) invert(1);
379
- }
380
- img.logo {
381
- height: 32px;
382
- }
383
- nav.nav-mobile {
384
- display: flex;
385
- }
386
- nav.nav-desktop {
387
- display: none;
388
- }
389
- @media (min-width: 768px) {
390
- nav.nav-mobile {
391
- display: none;
392
- }
393
- nav.nav-desktop {
394
- display: flex;
395
- }
396
- }
397
197
  header {
398
198
  margin-top: calc(var(--vp-nav-height) * -1);
399
199
  padding-top: 10rem !important;
@@ -0,0 +1,237 @@
1
+ <template>
2
+ <div class="top-nav at-top row center-align">
3
+ <nav class="large-padding no-margin center-align nav-mobile">
4
+ <a href="/">
5
+ <img
6
+ :src="withBase(theme.logo.light)"
7
+ :alt="`${site.title} logo`"
8
+ class="logo light"
9
+ />
10
+ <img
11
+ v-if="theme.logo.dark"
12
+ :src="withBase(theme.logo.dark)"
13
+ :alt="`${site.title} logo`"
14
+ class="logo dark"
15
+ />
16
+ </a>
17
+ <div class="max"></div>
18
+ <button data-ui="#mobile-menu" class="circle transparent">
19
+ <i class="mdi mdi-menu"></i>
20
+ </button>
21
+ <dialog id="mobile-menu" class="max">
22
+ <nav>
23
+ <a data-ui="#mobile-menu" href="/">
24
+ <img
25
+ :src="withBase(theme.logo.light)"
26
+ :alt="`${site.title} logo`"
27
+ class="logo margin"
28
+ />
29
+ </a>
30
+ <div class="max"></div>
31
+ <button data-ui="#mobile-menu" class="circle transparent">
32
+ <i class="mdi mdi-close"></i>
33
+ </button>
34
+ </nav>
35
+ <ul class="list border large-space">
36
+ <li v-for="item in theme.nav.filter((item) => !item.action)">
37
+ <a
38
+ data-ui="#mobile-menu"
39
+ :href="withBase(item.link)"
40
+ :target="item.target"
41
+ :rel="item.rel"
42
+ :class="item.action ? 'button large medium-elevate cta' : ''"
43
+ >
44
+ <span>{{ item.text }}</span>
45
+ </a>
46
+ </li>
47
+ </ul>
48
+ <div class="grid">
49
+ <div class="s12">
50
+ <nav v-for="item in theme.nav.filter((item) => item.action)">
51
+ <a
52
+ data-ui="#mobile-menu"
53
+ :href="withBase(item.link)"
54
+ :target="item.target"
55
+ :rel="item.rel"
56
+ :class="
57
+ item.action
58
+ ? `button responsive large ${item.action} ${item.action === 'primary' || item.action === 'secondary' ? 'medium-elevate' : 'border no-elevate'}`
59
+ : 'primary-text'
60
+ "
61
+ >
62
+ <span>{{ item.text }}</span>
63
+ <i
64
+ v-if="
65
+ item.action === 'primary' || item.action === 'secondary'
66
+ "
67
+ class="mdi mdi-arrow-right"
68
+ ></i>
69
+ </a>
70
+ </nav>
71
+ </div>
72
+ </div>
73
+ </dialog>
74
+ </nav>
75
+ <nav class="large-padding no-margin center-align row holder nav-desktop">
76
+ <a href="/">
77
+ <img
78
+ :src="withBase(theme.logo.light)"
79
+ :alt="`${site.title} logo`"
80
+ class="logo light"
81
+ />
82
+ <img
83
+ v-if="theme.logo.dark"
84
+ :src="withBase(theme.logo.dark)"
85
+ :alt="`${site.title} logo`"
86
+ class="logo dark"
87
+ />
88
+ </a>
89
+ <div class="space"></div>
90
+ <nav>
91
+ <ul class="left-align no-margin">
92
+ <li v-for="item in theme.nav.filter((i) => !i.action)">
93
+ <a
94
+ class="button text"
95
+ :href="withBase(item.link)"
96
+ :target="item.target"
97
+ :rel="item.rel"
98
+ >{{ item.text }}</a
99
+ >
100
+ </li>
101
+ </ul>
102
+ </nav>
103
+ <div class="max"></div>
104
+ <nav class="actions">
105
+ <ul class="left-align no-margin">
106
+ <li v-for="item in theme.nav.filter((item) => item.action)">
107
+ <a
108
+ class="button right-align"
109
+ :class="`${item.action} ${
110
+ item.action === 'primary' || item.action === 'secondary'
111
+ ? item.action
112
+ : 'border'
113
+ }`"
114
+ :href="withBase(item.link)"
115
+ :target="item.target"
116
+ :rel="item.rel"
117
+ @click="trackEvent(['CTA', 'Click', 'Nav', item.text])"
118
+ >
119
+ <span>{{ item.text }}</span>
120
+ <i
121
+ v-if="item.action === 'primary' || item.action === 'secondary'"
122
+ class="mdi mdi-arrow-right"
123
+ ></i>
124
+ </a>
125
+ </li>
126
+ </ul>
127
+ </nav>
128
+ </nav>
129
+ </div>
130
+ </template>
131
+
132
+ <script setup>
133
+ import { useData, withBase } from "vitepress";
134
+ import { trackEvent } from "../helpers";
135
+
136
+ const { site, theme } = useData();
137
+
138
+ if (!import.meta.env.SSR) {
139
+ const scrollListener = () => {
140
+ const nav = document.querySelector(".top-nav");
141
+
142
+ if (window.scrollY > nav.clientHeight) {
143
+ nav.classList.remove("at-top");
144
+ } else {
145
+ nav.classList.add("at-top");
146
+ }
147
+ };
148
+ window.addEventListener("scroll", scrollListener);
149
+ }
150
+ </script>
151
+
152
+ <style>
153
+ .top-nav {
154
+ position: sticky;
155
+ z-index: 2;
156
+ top: 0;
157
+ background: var(--surface);
158
+ box-shadow:
159
+ 0 1px 5px #15142e0d,
160
+ 0 4px 16px #15142e1a,
161
+ inset 0 0 0 1px #ffffff80;
162
+ display: flex;
163
+ width: 100%;
164
+ transition: all 0.3s ease-in-out;
165
+ }
166
+ .top-nav.at-top {
167
+ box-shadow: none;
168
+ }
169
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button.primary,
170
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button.secondary,
171
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button.alt {
172
+ display: none;
173
+ }
174
+ .Layout.layout-home .top-nav.at-top nav.actions {
175
+ gap: 0;
176
+ }
177
+ .top-nav:not(.at-top) > nav {
178
+ padding-top: 16px !important;
179
+ padding-bottom: 16px !important;
180
+ }
181
+ .Layout.layout-home .top-nav.at-top {
182
+ background: transparent;
183
+ color: #f7f8f8;
184
+ }
185
+ .Layout .top-nav nav .button {
186
+ color: var(--on-surface);
187
+ }
188
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button {
189
+ color: var(--on-surface);
190
+ background: var(--surface);
191
+ }
192
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button.text {
193
+ color: #f7f8f8;
194
+ background: none;
195
+ }
196
+ .Layout.layout-home .top-nav.at-top .nav-desktop .button.border {
197
+ color: #f7f8f8;
198
+ border-color: #f7f8f855;
199
+ background: none;
200
+ }
201
+ .top-nav.at-top > nav > a:has(.logo.dark) > .logo.dark {
202
+ display: none;
203
+ }
204
+ .Layout.layout-home .top-nav.at-top > nav > a:has(.logo.dark) > .logo.light {
205
+ display: none;
206
+ }
207
+ .Layout.layout-home
208
+ .top-nav.at-top
209
+ > nav
210
+ > a:not(:has(.logo.dark))
211
+ > .logo.light {
212
+ filter: brightness(0) invert(1);
213
+ }
214
+ .Layout .top-nav > nav > a > .logo.dark {
215
+ display: none;
216
+ }
217
+ .Layout.layout-home .top-nav.at-top > nav > a > .logo.dark {
218
+ display: block;
219
+ }
220
+ img.logo {
221
+ height: 32px;
222
+ }
223
+ nav.nav-mobile {
224
+ display: flex;
225
+ }
226
+ nav.nav-desktop {
227
+ display: none;
228
+ }
229
+ @media (min-width: 768px) {
230
+ nav.nav-mobile {
231
+ display: none;
232
+ }
233
+ nav.nav-desktop {
234
+ display: flex;
235
+ }
236
+ }
237
+ </style>
package/src/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import DefaultTheme from "vitepress/theme";
2
+ import NavBar from "./components/NavBar.vue";
2
3
  import FeatureSection from "./components/FeatureSection.vue";
3
4
  import FeaturesGallery from "./components/FeaturesGallery.vue";
4
5
  import PricingTable from "./components/PricingTable.vue";
@@ -13,6 +14,7 @@ export default {
13
14
  extends: DefaultTheme,
14
15
  Layout,
15
16
  enhanceApp({ app, router, siteData }) {
17
+ app.component("NavBar", NavBar);
16
18
  app.component("FeatureSection", FeatureSection);
17
19
  app.component("FeaturesGallery", FeaturesGallery);
18
20
  app.component("PricingTable", PricingTable);
package/src/style.css CHANGED
@@ -1,6 +1,9 @@
1
1
  @import "@eox/ui/style.css";
2
2
 
3
3
  :root {
4
+ --vp-nav-height: 74px;
5
+ }
6
+ :root:has(.top-nav.at-top) {
4
7
  --vp-nav-height: 90px;
5
8
  }
6
9
 
@@ -99,7 +99,7 @@ export const generate = (brandConfig) => ({
99
99
  brandConfig.theme?.secondary_color || brandConfig.theme?.primary_color,
100
100
  brandConfig,
101
101
  },
102
- logo: brandConfig.logo,
102
+ logo: { light: brandConfig.logo, dark: brandConfig.logo_dark },
103
103
  footer: {
104
104
  message: `Powered by <img src="https://cockpit.hub.eox.at/storage/uploads/eoxhub/eoxhub_icon.svg" style="display: inline; height: 20px; transform: translateY(5px)" />`,
105
105
  copyright: