@eox/pages-theme-eox 1.8.0 → 2.0.0-alpha.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/CHANGELOG.md +6 -0
- package/README.md +83 -0
- package/cypress/support/mocks/vitepress.js +8 -1
- package/cypress.config.js +5 -0
- package/package.json +1 -1
- package/src/Layout.vue +58 -1
- package/src/authors.data.js +14 -0
- package/src/components/BlogList.vue +636 -0
- package/src/components/BlogPost.vue +450 -0
- package/src/components/FeatureCard/Index.vue +370 -26
- package/src/components/HeroSection.vue +1 -1
- package/src/components/ImageCarousel.cy.js +22 -0
- package/src/components/ImageCarousel.vue +268 -0
- package/src/components/ImageElement.cy.js +46 -0
- package/src/components/ImageElement.vue +269 -0
- package/src/components/ImageGallery.cy.js +52 -0
- package/src/components/ImageGallery.vue +622 -0
- package/src/components/SectionHeader.cy.js +54 -0
- package/src/components/SectionHeader.vue +115 -0
- package/src/components/SingleTweet.cy.js +27 -0
- package/src/components/SingleTweet.vue +155 -0
- package/src/components/TagList.vue +293 -0
- package/src/components/TeamPage.vue +333 -0
- package/src/components/TestimonialsSection.cy.js +79 -0
- package/src/components/TestimonialsSection.vue +265 -0
- package/src/index.js +21 -0
- package/src/pages/author/[author].md +4 -0
- package/src/pages/author/[author].paths.js +60 -0
- package/src/pages/blog.md +4 -0
- package/src/pages/tag/[tag].md +4 -0
- package/src/pages/tag/[tag].paths.js +49 -0
- package/src/pages/tag.md +4 -0
- package/src/pages/team.md +4 -0
- package/src/posts.data.js +96 -0
- package/src/style.css +160 -0
- package/src/tagUtils.js +148 -0
- package/src/team.data.js +51 -0
- package/src/vitepressConfig.mjs +97 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# [1.9.0](https://gitlab.eox.at/eox/hub/eoxhub-portal/compare/v1.8.0...v1.9.0) (2026-06-11)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- new components (ImageCarousel, ImageElement, ImageGallery, SingleTweet) and automated loaders (team) ([8ce5f28](https://gitlab.eox.at/eox/hub/eoxhub-portal/commit/8ce5f289f06c1d4ebd7ff4871008f0dec31dabcc))
|
|
8
|
+
|
|
3
9
|
# [1.8.0](https://gitlab.eox.at/eox/hub/eoxhub-portal/compare/v1.7.0...v1.8.0) (2026-06-08)
|
|
4
10
|
|
|
5
11
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -239,6 +239,19 @@ A Call-to-Action section typically placed at the bottom of a page to encourage u
|
|
|
239
239
|
/>
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
+
#### Section Header
|
|
243
|
+
|
|
244
|
+
A standardized three-tier header block for page sections, matching EOX design tokens with a tag badge, a large display title, and an optional subtitle description. Supports light/dark context modes automatically.
|
|
245
|
+
|
|
246
|
+
```html
|
|
247
|
+
<SectionHeader
|
|
248
|
+
tag="Viewing Ready & Basic"
|
|
249
|
+
icon="mdi-star-check-outline"
|
|
250
|
+
title="What our users say about Viewing Products"
|
|
251
|
+
subtitle="Optional paragraph providing context and detail for this section."
|
|
252
|
+
/>
|
|
253
|
+
```
|
|
254
|
+
|
|
242
255
|
#### Logo Section
|
|
243
256
|
|
|
244
257
|
Displays a grid of client or partner logos. It automatically handles logo sizing.
|
|
@@ -379,6 +392,76 @@ An image-overlay card where a background image fills the card and text is render
|
|
|
379
392
|
/>
|
|
380
393
|
```
|
|
381
394
|
|
|
395
|
+
#### Image Element
|
|
396
|
+
|
|
397
|
+
Displays standard images with optional caption and width, and supports interactive side-by-side comparison slider when a `compare` prop is provided.
|
|
398
|
+
|
|
399
|
+
```html
|
|
400
|
+
<!-- Standard Image -->
|
|
401
|
+
<ImageElement
|
|
402
|
+
src="/images/someimage.jpg"
|
|
403
|
+
caption="Standard view"
|
|
404
|
+
width="450px"
|
|
405
|
+
/>
|
|
406
|
+
|
|
407
|
+
<!-- Image Comparison Slider -->
|
|
408
|
+
<ImageElement
|
|
409
|
+
src="/images/eoxcloudless2024.jpg"
|
|
410
|
+
compare="/images/eoxcloudless2023.jpg"
|
|
411
|
+
caption="2024 vs. 2023 comparison"
|
|
412
|
+
/>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
#### Image Gallery
|
|
416
|
+
|
|
417
|
+
A unified, responsive image grid and lightbox gallery. Supports both plain link/grid layouts and touch-friendly lightbox galleries.
|
|
418
|
+
|
|
419
|
+
##### Properties
|
|
420
|
+
|
|
421
|
+
| Prop | Type | Default | Description |
|
|
422
|
+
| :--------- | :-------------- | :---------- | :---------------------------------------------------------------------------------------------------- |
|
|
423
|
+
| `images` | `String\|Array` | — | Comma-separated image paths string, array of paths, or array of image objects with caption and links. |
|
|
424
|
+
| `columns` | `Number` | `2` | Number of columns (1, 2, 3, 4, 5). |
|
|
425
|
+
| `layout` | `String` | `"gallery"` | Layout mode: `"gallery"` (featured image + thumbnails) or `"grid"` (regular grid of images). |
|
|
426
|
+
| `lightbox` | `Boolean` | `true` | Enable fullscreen lightbox overlay when clicking an image. |
|
|
427
|
+
|
|
428
|
+
```html
|
|
429
|
+
<!-- Gallery with Lightbox -->
|
|
430
|
+
<ImageGallery images="/img1.jpg, /img2.jpg, /img3.jpg" layout="gallery" />
|
|
431
|
+
|
|
432
|
+
<!-- Direct Image Grid with Captions & Links -->
|
|
433
|
+
<ImageGallery
|
|
434
|
+
layout="grid"
|
|
435
|
+
:columns="3"
|
|
436
|
+
:images="[
|
|
437
|
+
{ src: '/img1.jpg', caption: 'Link to A', link: '/page-a' },
|
|
438
|
+
{ src: '/img2.jpg', caption: 'Only Caption' },
|
|
439
|
+
{ src: '/img3.jpg', caption: 'Link to B', link: '/page-b' }
|
|
440
|
+
]"
|
|
441
|
+
/>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
#### Image Carousel
|
|
445
|
+
|
|
446
|
+
A simple CSS-driven accessible image slideshow.
|
|
447
|
+
|
|
448
|
+
```html
|
|
449
|
+
<ImageCarousel
|
|
450
|
+
:images="[
|
|
451
|
+
{ src: '/slide1.jpg', caption: 'Slide 1 Caption' },
|
|
452
|
+
{ src: '/slide2.jpg', caption: 'Slide 2 Caption' }
|
|
453
|
+
]"
|
|
454
|
+
/>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
#### Single Tweet
|
|
458
|
+
|
|
459
|
+
A privacy-respecting Twitter/X embed wrapper that checks Matomo cookie consent before rendering.
|
|
460
|
+
|
|
461
|
+
```html
|
|
462
|
+
<SingleTweet id="1276442045352226817" />
|
|
463
|
+
```
|
|
464
|
+
|
|
382
465
|
#### Feedback Form
|
|
383
466
|
|
|
384
467
|
**Feedback Form** for collecting user feedback can be enabled by configuring the theme:
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { reactive, ref } from "vue";
|
|
1
|
+
import { reactive, ref, defineComponent, h } from "vue";
|
|
2
|
+
|
|
3
|
+
export const VPNavBarSearch = defineComponent({
|
|
4
|
+
name: "VPNavBarSearch",
|
|
5
|
+
render() {
|
|
6
|
+
return h("div", { class: "VPNavBarSearch" }, "Search");
|
|
7
|
+
},
|
|
8
|
+
});
|
|
2
9
|
|
|
3
10
|
const site = ref({
|
|
4
11
|
title: "Test Site",
|
package/cypress.config.js
CHANGED
|
@@ -10,6 +10,11 @@ export default defineConfig({
|
|
|
10
10
|
viteConfig: {
|
|
11
11
|
resolve: {
|
|
12
12
|
alias: {
|
|
13
|
+
// Alias vitepress/theme to our mock
|
|
14
|
+
"vitepress/theme": path.resolve(
|
|
15
|
+
__dirname,
|
|
16
|
+
"cypress/support/mocks/vitepress.js",
|
|
17
|
+
),
|
|
13
18
|
// Alias vitepress to our mock
|
|
14
19
|
vitepress: path.resolve(
|
|
15
20
|
__dirname,
|
package/package.json
CHANGED
package/src/Layout.vue
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<div
|
|
3
|
+
v-if="frontmatter.layout === 'blog'"
|
|
4
|
+
class="layout-blog min-h-screen flex flex-col"
|
|
5
|
+
>
|
|
6
|
+
<NavBar />
|
|
7
|
+
<NewsBanner v-if="theme.newsBanner" :content="theme.newsBanner" />
|
|
8
|
+
<main class="flex-grow">
|
|
9
|
+
<BlogList />
|
|
10
|
+
</main>
|
|
11
|
+
<Footer v-if="frontmatter.footer !== false" />
|
|
12
|
+
<CookieBanner v-if="theme.theme.brandConfig?.analytics"></CookieBanner>
|
|
13
|
+
</div>
|
|
14
|
+
<div
|
|
15
|
+
v-else-if="frontmatter.layout === 'tags'"
|
|
16
|
+
class="layout-tags min-h-screen flex flex-col"
|
|
17
|
+
>
|
|
18
|
+
<NavBar />
|
|
19
|
+
<NewsBanner v-if="theme.newsBanner" :content="theme.newsBanner" />
|
|
20
|
+
<main class="flex-grow">
|
|
21
|
+
<TagList />
|
|
22
|
+
</main>
|
|
23
|
+
<Footer v-if="frontmatter.footer !== false" />
|
|
24
|
+
<CookieBanner v-if="theme.theme.brandConfig?.analytics"></CookieBanner>
|
|
25
|
+
</div>
|
|
26
|
+
<div
|
|
27
|
+
v-else-if="frontmatter.layout === 'team'"
|
|
28
|
+
class="layout-team min-h-screen flex flex-col"
|
|
29
|
+
>
|
|
30
|
+
<NavBar />
|
|
31
|
+
<NewsBanner v-if="theme.newsBanner" :content="theme.newsBanner" />
|
|
32
|
+
<main class="flex-grow">
|
|
33
|
+
<TeamPage />
|
|
34
|
+
</main>
|
|
35
|
+
<Footer v-if="frontmatter.footer !== false" />
|
|
36
|
+
<CookieBanner v-if="theme.theme.brandConfig?.analytics"></CookieBanner>
|
|
37
|
+
</div>
|
|
38
|
+
<div
|
|
39
|
+
v-else-if="frontmatter.layout === 'post' || isBlogPost"
|
|
40
|
+
class="layout-post min-h-screen flex flex-col"
|
|
41
|
+
>
|
|
42
|
+
<NavBar />
|
|
43
|
+
<NewsBanner v-if="theme.newsBanner" :content="theme.newsBanner" />
|
|
44
|
+
<main class="flex-grow">
|
|
45
|
+
<BlogPost />
|
|
46
|
+
</main>
|
|
47
|
+
<Footer v-if="frontmatter.footer !== false" />
|
|
48
|
+
<CookieBanner v-if="theme.theme.brandConfig?.analytics"></CookieBanner>
|
|
49
|
+
</div>
|
|
50
|
+
<Layout v-else :class="`layout-${frontmatter.layout}`">
|
|
3
51
|
<template #layout-top>
|
|
4
52
|
<slot name="layout-top"></slot>
|
|
5
53
|
<NavBar />
|
|
@@ -33,11 +81,20 @@
|
|
|
33
81
|
</template>
|
|
34
82
|
|
|
35
83
|
<script setup>
|
|
84
|
+
import { computed } from "vue";
|
|
36
85
|
import DefaultTheme from "vitepress/theme";
|
|
37
86
|
import { useData, useRouter } from "vitepress";
|
|
38
87
|
const { Layout } = DefaultTheme;
|
|
39
88
|
const { frontmatter, page, theme } = useData();
|
|
40
89
|
const router = useRouter();
|
|
90
|
+
|
|
91
|
+
const isBlogPost = computed(() => {
|
|
92
|
+
return (
|
|
93
|
+
frontmatter.value.layout === "post" ||
|
|
94
|
+
page.value.relativePath.startsWith("_posts/") ||
|
|
95
|
+
/^\d{4}\/\d{2}\//.test(page.value.relativePath)
|
|
96
|
+
);
|
|
97
|
+
});
|
|
41
98
|
</script>
|
|
42
99
|
|
|
43
100
|
<style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContentLoader } from "vitepress";
|
|
2
|
+
|
|
3
|
+
export default createContentLoader("_team/*.md", {
|
|
4
|
+
transform(rawData) {
|
|
5
|
+
return rawData.map((page) => {
|
|
6
|
+
return {
|
|
7
|
+
id: page.frontmatter.id || "",
|
|
8
|
+
name: page.frontmatter.title || "",
|
|
9
|
+
url: page.url,
|
|
10
|
+
guest: page.frontmatter.guest || false,
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
});
|