@eox/pages-theme-eox 1.9.0 → 2.0.0-alpha.10
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/.gitlab-ci.yml +4 -1
- package/README.md +88 -11
- package/cypress/support/mocks/authors.data.js +14 -0
- package/cypress/support/mocks/helpers.js +65 -4
- package/cypress/support/mocks/vitepress.js +8 -1
- package/cypress.config.js +14 -0
- package/package.json +3 -1
- package/src/Layout.vue +69 -1
- package/src/authors.data.js +14 -0
- package/src/components/BlogList.vue +655 -0
- package/src/components/BlogPost.vue +472 -0
- package/src/components/CTASection.vue +18 -4
- package/src/components/FeatureCard/Index.vue +462 -31
- package/src/components/FeatureCard/Poster.vue +25 -3
- package/src/components/FeatureSection.cy.js +16 -0
- package/src/components/FeatureSection.vue +3 -8
- package/src/components/FeaturesGallery.vue +34 -2
- package/src/components/Footer.cy.js +52 -2
- package/src/components/Footer.vue +17 -5
- package/src/components/HeroSection.cy.js +20 -0
- package/src/components/HeroSection.vue +140 -25
- package/src/components/ImageCarousel.vue +11 -2
- package/src/components/ImageElement.vue +16 -4
- package/src/components/ImageGallery.vue +29 -4
- package/src/components/LogoSection.vue +26 -3
- package/src/components/MobileNavDropdown.vue +13 -3
- package/src/components/NavBar.cy.js +15 -0
- package/src/components/NavBar.vue +149 -21
- package/src/components/NavDropdown.vue +12 -2
- package/src/components/OpenPositions.vue +292 -0
- package/src/components/SectionHeader.cy.js +54 -0
- package/src/components/SectionHeader.vue +115 -0
- package/src/components/TagList.vue +311 -0
- package/src/components/TeamPage.vue +347 -0
- package/src/components/TestimonialsSection.cy.js +76 -0
- package/src/components/TestimonialsSection.vue +368 -0
- package/src/components/TextSection.cy.js +115 -0
- package/src/components/TextSection.vue +396 -0
- package/src/helpers.js +182 -37
- package/src/helpers.test.js +181 -0
- package/src/index.js +16 -0
- package/src/pages/author/[author].md +5 -0
- package/src/pages/author/[author].paths.js +60 -0
- package/src/pages/blog.md +5 -0
- package/src/pages/tag/[tag].md +5 -0
- package/src/pages/tag/[tag].paths.js +49 -0
- package/src/pages/tag.md +5 -0
- package/src/pages/team.md +5 -0
- package/src/posts.data.js +134 -0
- package/src/style.css +389 -8
- package/src/tagUtils.js +148 -0
- package/src/team.data.js +1 -1
- package/src/vitepressConfig.mjs +101 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import TestimonialsSection from "./TestimonialsSection.vue";
|
|
2
|
+
|
|
3
|
+
describe("<TestimonialsSection />", () => {
|
|
4
|
+
it("renders with default props and switches testimonials", () => {
|
|
5
|
+
cy.mount(TestimonialsSection);
|
|
6
|
+
|
|
7
|
+
// Verify title
|
|
8
|
+
cy.get(".headline h2").should("contain", "What our customers are saying");
|
|
9
|
+
|
|
10
|
+
// Verify first testimonial quote
|
|
11
|
+
cy.get(".quote-text").should(
|
|
12
|
+
"contain",
|
|
13
|
+
"The VirES platform has completely revolutionized",
|
|
14
|
+
);
|
|
15
|
+
cy.get(".author-name").should("contain", "Dr. Fiona Harrison");
|
|
16
|
+
|
|
17
|
+
// Click next button
|
|
18
|
+
cy.get("button[aria-label='Next testimonial']").click();
|
|
19
|
+
|
|
20
|
+
// Verify second testimonial quote
|
|
21
|
+
cy.get(".quote-text").should(
|
|
22
|
+
"contain",
|
|
23
|
+
"Deploying our Area Monitoring System",
|
|
24
|
+
);
|
|
25
|
+
cy.get(".author-name").should("contain", "Dr. Liam O'Connor");
|
|
26
|
+
|
|
27
|
+
// Click prev button
|
|
28
|
+
cy.get("button[aria-label='Previous testimonial']").click();
|
|
29
|
+
|
|
30
|
+
// Verify first testimonial quote again
|
|
31
|
+
cy.get(".quote-text").should(
|
|
32
|
+
"contain",
|
|
33
|
+
"The VirES platform has completely revolutionized",
|
|
34
|
+
);
|
|
35
|
+
cy.get(".author-name").should("contain", "Dr. Fiona Harrison");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("renders custom title and custom testimonials list", () => {
|
|
39
|
+
const customTitle = "What Our Amazing Clients Think";
|
|
40
|
+
const customTestimonials = [
|
|
41
|
+
{
|
|
42
|
+
quote: "This is a custom quote that is extremely positive.",
|
|
43
|
+
author: "Alice Smith",
|
|
44
|
+
role: "Software Architect",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
quote: "Another custom quote for testing purposes.",
|
|
48
|
+
author: "Bob Jones",
|
|
49
|
+
role: "Data Analyst",
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
cy.mount(TestimonialsSection, {
|
|
54
|
+
props: {
|
|
55
|
+
title: customTitle,
|
|
56
|
+
testimonials: customTestimonials,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Check title
|
|
61
|
+
cy.get(".headline h2").should("contain", customTitle);
|
|
62
|
+
|
|
63
|
+
// Check first custom testimonial
|
|
64
|
+
cy.get(".quote-text").should("contain", "This is a custom quote");
|
|
65
|
+
cy.get(".author-name").should("contain", "Alice Smith");
|
|
66
|
+
cy.get(".author-role").should("contain", "Software Architect");
|
|
67
|
+
|
|
68
|
+
// Go next
|
|
69
|
+
cy.get("button[aria-label='Next testimonial']").click();
|
|
70
|
+
|
|
71
|
+
// Check second custom testimonial
|
|
72
|
+
cy.get(".quote-text").should("contain", "Another custom quote");
|
|
73
|
+
cy.get(".author-name").should("contain", "Bob Jones");
|
|
74
|
+
cy.get(".author-role").should("contain", "Data Analyst");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="testimonials-section full-width surface-container-lowest">
|
|
3
|
+
<div class="holder">
|
|
4
|
+
<!-- Left Side: Headline -->
|
|
5
|
+
<div class="headline">
|
|
6
|
+
<h2>
|
|
7
|
+
{{ title }}
|
|
8
|
+
</h2>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<!-- Right Side: Text Block -->
|
|
12
|
+
<div
|
|
13
|
+
v-if="testimonials && testimonials.length > 0"
|
|
14
|
+
class="text-block"
|
|
15
|
+
role="region"
|
|
16
|
+
aria-roledescription="carousel"
|
|
17
|
+
:aria-label="title"
|
|
18
|
+
>
|
|
19
|
+
<!-- Testimonial Quotes Overlapping Grid -->
|
|
20
|
+
<div class="quotes-grid" aria-live="polite">
|
|
21
|
+
<div
|
|
22
|
+
v-for="(item, index) in testimonials"
|
|
23
|
+
:key="index"
|
|
24
|
+
class="quote-slide"
|
|
25
|
+
:class="{
|
|
26
|
+
active: index === currentIndex,
|
|
27
|
+
'quote-text': index === currentIndex,
|
|
28
|
+
}"
|
|
29
|
+
:aria-hidden="index !== currentIndex"
|
|
30
|
+
>
|
|
31
|
+
“{{ item.quote }}”
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<!-- Divider / Separator -->
|
|
36
|
+
<div class="divider"></div>
|
|
37
|
+
|
|
38
|
+
<!-- Frame 469: Author info & sliders -->
|
|
39
|
+
<div class="frame-469">
|
|
40
|
+
<!-- Frame 468: Author Name and Role Overlapping Grid -->
|
|
41
|
+
<div class="frame-468">
|
|
42
|
+
<div
|
|
43
|
+
v-for="(item, index) in testimonials"
|
|
44
|
+
:key="index"
|
|
45
|
+
class="author-slide"
|
|
46
|
+
:class="{ active: index === currentIndex }"
|
|
47
|
+
:aria-hidden="index !== currentIndex"
|
|
48
|
+
>
|
|
49
|
+
<span
|
|
50
|
+
class="author-name-text"
|
|
51
|
+
:class="{ 'author-name': index === currentIndex }"
|
|
52
|
+
>
|
|
53
|
+
{{ item.author }}
|
|
54
|
+
</span>
|
|
55
|
+
<span
|
|
56
|
+
class="author-role-text"
|
|
57
|
+
:class="{ 'author-role': index === currentIndex }"
|
|
58
|
+
>
|
|
59
|
+
{{ item.role }}
|
|
60
|
+
</span>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<!-- sliders: Navigation Buttons -->
|
|
65
|
+
<div class="sliders">
|
|
66
|
+
<!-- Left Arrow Button -->
|
|
67
|
+
<button
|
|
68
|
+
class="nav-button"
|
|
69
|
+
@click="prev"
|
|
70
|
+
aria-label="Previous testimonial"
|
|
71
|
+
>
|
|
72
|
+
<i class="mdi mdi-arrow-left"></i>
|
|
73
|
+
</button>
|
|
74
|
+
|
|
75
|
+
<!-- Right Arrow Button -->
|
|
76
|
+
<button
|
|
77
|
+
class="nav-button"
|
|
78
|
+
@click="next"
|
|
79
|
+
aria-label="Next testimonial"
|
|
80
|
+
>
|
|
81
|
+
<i class="mdi mdi-arrow-right"></i>
|
|
82
|
+
</button>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</section>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script setup>
|
|
91
|
+
import { ref, computed, watch } from "vue";
|
|
92
|
+
|
|
93
|
+
const props = defineProps({
|
|
94
|
+
title: {
|
|
95
|
+
type: String,
|
|
96
|
+
default: "What our customers are saying",
|
|
97
|
+
},
|
|
98
|
+
testimonials: {
|
|
99
|
+
type: Array,
|
|
100
|
+
default: () => [
|
|
101
|
+
{
|
|
102
|
+
quote:
|
|
103
|
+
"The VirES platform has completely revolutionized how Swarm mission data is accessed and analyzed by the global scientific community. Its cloud-native performance and seamless visualization are unmatched.",
|
|
104
|
+
author: "Dr. Fiona Harrison",
|
|
105
|
+
role: "Lead Swarm Researcher, Scientific Advisory Group",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
quote:
|
|
109
|
+
"Deploying our Area Monitoring System on EOxHub workspaces allowed us to process millions of parcels in near real-time. This level of automation and reliability is precisely what we needed for the CAP implementation.",
|
|
110
|
+
author: "Dr. Liam O'Connor",
|
|
111
|
+
role: "Senior Spatial Scientist, Agricultural Paying Agency",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
quote:
|
|
115
|
+
"The EOX base map layers are an essential asset for our global dashboard. Their Sentinel-2 cloudless composites provide a pristine, cloud-free visual experience that our users absolutely love.",
|
|
116
|
+
author: "Sarah Jenkins",
|
|
117
|
+
role: "Chief Product Officer, Global Earth Explorer Platform",
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const currentIndex = ref(0);
|
|
124
|
+
|
|
125
|
+
// Clamp currentIndex if testimonials prop array changes dynamically
|
|
126
|
+
watch(
|
|
127
|
+
() => props.testimonials?.length,
|
|
128
|
+
(len) => {
|
|
129
|
+
if (len && currentIndex.value >= len) {
|
|
130
|
+
currentIndex.value = 0;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const currentTestimonial = computed(() => {
|
|
136
|
+
if (!props.testimonials || props.testimonials.length === 0) return null;
|
|
137
|
+
return props.testimonials[currentIndex.value];
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
function prev() {
|
|
141
|
+
if (!props.testimonials || props.testimonials.length === 0) return;
|
|
142
|
+
currentIndex.value =
|
|
143
|
+
(currentIndex.value - 1 + props.testimonials.length) %
|
|
144
|
+
props.testimonials.length;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function next() {
|
|
148
|
+
if (!props.testimonials || props.testimonials.length === 0) return;
|
|
149
|
+
currentIndex.value = (currentIndex.value + 1) % props.testimonials.length;
|
|
150
|
+
}
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<style scoped>
|
|
154
|
+
section.testimonials-section {
|
|
155
|
+
display: flex;
|
|
156
|
+
justify-content: center;
|
|
157
|
+
overflow-x: hidden;
|
|
158
|
+
padding: 3rem 1.5rem;
|
|
159
|
+
margin-block-start: 6rem;
|
|
160
|
+
margin-block-end: 6rem;
|
|
161
|
+
box-sizing: border-box;
|
|
162
|
+
background-color: var(--surface-container-lowest, #ffffff);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@media (min-width: 1024px) {
|
|
166
|
+
section.testimonials-section {
|
|
167
|
+
padding: 6rem 1.5rem;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.holder {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
gap: 32px;
|
|
175
|
+
width: 100%;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@media (min-width: 1024px) {
|
|
179
|
+
.holder {
|
|
180
|
+
flex-direction: row;
|
|
181
|
+
align-items: flex-start;
|
|
182
|
+
justify-content: space-between;
|
|
183
|
+
gap: 64px;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.headline {
|
|
188
|
+
flex: 1 1 50%;
|
|
189
|
+
max-width: 620px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.headline h2 {
|
|
193
|
+
font-family: "Inter", sans-serif;
|
|
194
|
+
font-style: normal;
|
|
195
|
+
font-weight: 700;
|
|
196
|
+
font-size: 36px !important;
|
|
197
|
+
line-height: 44px;
|
|
198
|
+
letter-spacing: 0.5008px;
|
|
199
|
+
color: #00060a;
|
|
200
|
+
margin: 0 !important;
|
|
201
|
+
padding: 0 !important;
|
|
202
|
+
border-top: none !important;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.text-block {
|
|
206
|
+
flex: 1 1 50%;
|
|
207
|
+
max-width: 620px;
|
|
208
|
+
display: flex;
|
|
209
|
+
flex-direction: column;
|
|
210
|
+
gap: 24px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.quotes-grid {
|
|
214
|
+
display: grid;
|
|
215
|
+
grid-template-columns: 1fr;
|
|
216
|
+
width: 100%;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.quote-slide {
|
|
220
|
+
grid-column: 1;
|
|
221
|
+
grid-row: 1;
|
|
222
|
+
align-self: start;
|
|
223
|
+
font-family: "Inter", sans-serif;
|
|
224
|
+
font-style: normal;
|
|
225
|
+
font-weight: 400;
|
|
226
|
+
font-size: 16px;
|
|
227
|
+
line-height: 24px;
|
|
228
|
+
letter-spacing: 0.5px;
|
|
229
|
+
color: #00060a;
|
|
230
|
+
min-height: 72px;
|
|
231
|
+
opacity: 0;
|
|
232
|
+
visibility: hidden;
|
|
233
|
+
transition:
|
|
234
|
+
opacity 0.25s ease,
|
|
235
|
+
visibility 0.25s ease;
|
|
236
|
+
pointer-events: none;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.quote-slide.active {
|
|
240
|
+
opacity: 1;
|
|
241
|
+
visibility: visible;
|
|
242
|
+
pointer-events: auto;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.quote-text {
|
|
246
|
+
font-family: "Inter", sans-serif;
|
|
247
|
+
font-style: normal;
|
|
248
|
+
font-weight: 400;
|
|
249
|
+
font-size: 16px;
|
|
250
|
+
line-height: 24px;
|
|
251
|
+
letter-spacing: 0.5px;
|
|
252
|
+
color: #00060a;
|
|
253
|
+
min-height: 72px;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.divider {
|
|
257
|
+
width: 100%;
|
|
258
|
+
height: 1px;
|
|
259
|
+
background: #ccd9e2;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.frame-469 {
|
|
263
|
+
display: flex;
|
|
264
|
+
flex-direction: row;
|
|
265
|
+
align-items: center;
|
|
266
|
+
justify-content: space-between;
|
|
267
|
+
gap: 16px;
|
|
268
|
+
width: 100%;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.frame-468 {
|
|
272
|
+
display: grid;
|
|
273
|
+
grid-template-columns: 1fr;
|
|
274
|
+
align-items: flex-start;
|
|
275
|
+
flex-grow: 1;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.author-slide {
|
|
279
|
+
grid-column: 1;
|
|
280
|
+
grid-row: 1;
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-direction: column;
|
|
283
|
+
align-items: flex-start;
|
|
284
|
+
gap: 8px;
|
|
285
|
+
opacity: 0;
|
|
286
|
+
visibility: hidden;
|
|
287
|
+
transition:
|
|
288
|
+
opacity 0.25s ease,
|
|
289
|
+
visibility 0.25s ease;
|
|
290
|
+
pointer-events: none;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.author-slide.active {
|
|
294
|
+
opacity: 1;
|
|
295
|
+
visibility: visible;
|
|
296
|
+
pointer-events: auto;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.author-name,
|
|
300
|
+
.author-name-text {
|
|
301
|
+
font-family: "Inter", sans-serif;
|
|
302
|
+
font-style: normal;
|
|
303
|
+
font-weight: 700;
|
|
304
|
+
font-size: 16px;
|
|
305
|
+
line-height: 24px;
|
|
306
|
+
letter-spacing: 0.5px;
|
|
307
|
+
color: #00060a;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.author-role,
|
|
311
|
+
.author-role-text {
|
|
312
|
+
font-family: "Inter", sans-serif;
|
|
313
|
+
font-style: normal;
|
|
314
|
+
font-weight: 400;
|
|
315
|
+
font-size: 16px;
|
|
316
|
+
line-height: 24px;
|
|
317
|
+
letter-spacing: 0.5px;
|
|
318
|
+
color: #00060a;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@media (prefers-reduced-motion: reduce) {
|
|
322
|
+
.quote-slide,
|
|
323
|
+
.author-slide {
|
|
324
|
+
transition: none;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.sliders {
|
|
329
|
+
display: flex;
|
|
330
|
+
flex-direction: row;
|
|
331
|
+
align-items: center;
|
|
332
|
+
gap: 24px;
|
|
333
|
+
flex-shrink: 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.nav-button {
|
|
337
|
+
display: flex !important;
|
|
338
|
+
flex-direction: row !important;
|
|
339
|
+
justify-content: center !important;
|
|
340
|
+
align-items: center !important;
|
|
341
|
+
padding: 0 !important;
|
|
342
|
+
width: 48px !important;
|
|
343
|
+
min-width: 48px !important;
|
|
344
|
+
max-width: 48px !important;
|
|
345
|
+
height: 48px !important;
|
|
346
|
+
min-height: 48px !important;
|
|
347
|
+
max-height: 48px !important;
|
|
348
|
+
background: #004170 !important;
|
|
349
|
+
box-shadow:
|
|
350
|
+
0px 24px 48px -8px rgba(62, 52, 69, 0.12),
|
|
351
|
+
0px 2px 4px rgba(62, 52, 69, 0.04) !important;
|
|
352
|
+
border-radius: 999px !important;
|
|
353
|
+
border: none !important;
|
|
354
|
+
cursor: pointer !important;
|
|
355
|
+
transition: background-color 0.2s ease !important;
|
|
356
|
+
box-sizing: border-box !important;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.nav-button:hover {
|
|
360
|
+
background: #002e52;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.nav-button i {
|
|
364
|
+
color: #ffffff;
|
|
365
|
+
font-size: 24px;
|
|
366
|
+
line-height: 1;
|
|
367
|
+
}
|
|
368
|
+
</style>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { h } from "vue";
|
|
2
|
+
import TextSection from "./TextSection.vue";
|
|
3
|
+
|
|
4
|
+
describe("<TextSection />", () => {
|
|
5
|
+
it("renders title, tagline and button", () => {
|
|
6
|
+
cy.mount(TextSection, {
|
|
7
|
+
props: {
|
|
8
|
+
title: "Test Section",
|
|
9
|
+
tagline: "Test Tagline",
|
|
10
|
+
buttonText: "Click Me",
|
|
11
|
+
buttonLink: "https://example.com",
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
cy.contains("Test Section").should("exist");
|
|
16
|
+
cy.contains("Test Tagline").should("exist");
|
|
17
|
+
cy.contains("a.button", "Click Me")
|
|
18
|
+
.should("have.attr", "href", "https://example.com")
|
|
19
|
+
.and("have.attr", "target", "_blank");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("renders slot content and image", () => {
|
|
23
|
+
cy.mount(TextSection, {
|
|
24
|
+
props: {
|
|
25
|
+
image: "/test.jpg",
|
|
26
|
+
imageAlt: "Test Image",
|
|
27
|
+
},
|
|
28
|
+
slots: {
|
|
29
|
+
default: "<p>This is paragraph text.</p>",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
cy.contains("This is paragraph text.").should("exist");
|
|
34
|
+
cy.get("img.section-image")
|
|
35
|
+
.should("have.attr", "src", "/test.jpg")
|
|
36
|
+
.and("have.attr", "alt", "Test Image");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("applies reverse class when reverse prop is true", () => {
|
|
40
|
+
cy.mount(TextSection, {
|
|
41
|
+
props: {
|
|
42
|
+
image: "/test.jpg",
|
|
43
|
+
reverse: true,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
cy.get(".text-section").should("have.class", "is-reverse");
|
|
48
|
+
cy.get(".text-section-grid").should("have.class", "grid-reverse");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("applies single column styling when no image is provided", () => {
|
|
52
|
+
cy.mount(TextSection, {
|
|
53
|
+
slots: {
|
|
54
|
+
default: "<p>Single column text</p>",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
cy.get(".text-section").should("have.class", "no-image");
|
|
59
|
+
cy.get(".text-section-grid").should("have.class", "grid-single");
|
|
60
|
+
cy.get(".media-column").should("not.exist");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("applies extra padding-block-end to a single section", () => {
|
|
64
|
+
cy.mount(TextSection, {
|
|
65
|
+
props: {
|
|
66
|
+
title: "Single Section",
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
cy.get(".text-section").should("have.css", "padding-bottom", "80px");
|
|
71
|
+
cy.get(".text-section").should("have.css", "padding-top", "56px");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("applies extra padding-block-end only to the last section when multiple are consecutive", () => {
|
|
75
|
+
const TestWrapper = {
|
|
76
|
+
render() {
|
|
77
|
+
return h("div", [
|
|
78
|
+
h(TextSection, { title: "Section 1" }),
|
|
79
|
+
h(TextSection, { title: "Section 2" }),
|
|
80
|
+
h(TextSection, { title: "Section 3" }),
|
|
81
|
+
]);
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
cy.mount(TestWrapper);
|
|
86
|
+
|
|
87
|
+
// First section: standard padding-bottom 56px, normal padding-top 56px
|
|
88
|
+
cy.get(".text-section").eq(0).should("have.css", "padding-bottom", "56px");
|
|
89
|
+
cy.get(".text-section").eq(0).should("have.css", "padding-top", "56px");
|
|
90
|
+
|
|
91
|
+
// Second section: standard padding-bottom 56px, tightened padding-top 16px
|
|
92
|
+
cy.get(".text-section").eq(1).should("have.css", "padding-bottom", "56px");
|
|
93
|
+
cy.get(".text-section").eq(1).should("have.css", "padding-top", "16px");
|
|
94
|
+
|
|
95
|
+
// Third (last) section: extra padding-bottom 80px, tightened padding-top 16px
|
|
96
|
+
cy.get(".text-section").eq(2).should("have.css", "padding-bottom", "80px");
|
|
97
|
+
cy.get(".text-section").eq(2).should("have.css", "padding-top", "16px");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("handles compact sections with appropriate padding-block-end", () => {
|
|
101
|
+
const TestWrapper = {
|
|
102
|
+
render() {
|
|
103
|
+
return h("div", [
|
|
104
|
+
h(TextSection, { title: "Compact 1", compact: true }),
|
|
105
|
+
h(TextSection, { title: "Compact 2", compact: true }),
|
|
106
|
+
]);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
cy.mount(TestWrapper);
|
|
111
|
+
|
|
112
|
+
cy.get(".text-section").eq(0).should("have.css", "padding-bottom", "28px");
|
|
113
|
+
cy.get(".text-section").eq(1).should("have.css", "padding-bottom", "40px");
|
|
114
|
+
});
|
|
115
|
+
});
|