Skip to content

Commit 0aaebc0

Browse files
Merge branch 'main' into 4527-use-the-exising-breakpoints-utlity-in-the-new-composible-header
2 parents 9e3448a + 23fe32f commit 0aaebc0

File tree

13 files changed

+783
-97
lines changed

13 files changed

+783
-97
lines changed

.changeset/old-fireants-arrive.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@swisspost/design-system-components': minor
3+
---
4+
5+
Updated the `post-icon` component to make it SSR conform.

.changeset/seven-kids-remember.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@swisspost/design-system-styles': minor
3+
---
4+
5+
Added helper classes to the `.section` component, which allow content to bleed out to the edge of the `.section` or the `.container` element. Either on both sides, or only to the left or right edge.

.changeset/tricky-foxes-check.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@swisspost/design-system-components': patch
3+
---
4+
5+
Fixed overflow handling in the main navigation to ensure all navigation items can be accessed.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
describe('mainnavigation', { baseUrl: null, includeShadowDom: true }, () => {
2+
function isFullyVisible($el: JQuery<HTMLElement>) {
3+
const $mainnavigation = $el.parents('post-mainnavigation');
4+
const $listItem = $el.parents('post-list-item');
5+
6+
let firstVisiblePosition = 0;
7+
if (!$listItem.is(':first-child')) {
8+
firstVisiblePosition += $mainnavigation.children('.left-scroll-button').width();
9+
}
10+
11+
let lastVisiblePosition = Cypress.config('viewportWidth');
12+
if (!$listItem.is(':last-child')) {
13+
lastVisiblePosition -= $mainnavigation.children('.right-scroll-button').width();
14+
}
15+
16+
const { left, width } = $el.get(0).getBoundingClientRect();
17+
return left >= firstVisiblePosition && left + width <= lastVisiblePosition;
18+
}
19+
20+
describe('default', () => {
21+
beforeEach(() => {
22+
cy.visit('./cypress/fixtures/post-mainnavigation.test.html');
23+
24+
cy.get('post-mainnavigation[data-hydrated]').as('mainnavigation');
25+
26+
cy.get('@mainnavigation')
27+
.find('post-megadropdown-trigger > button, a:not(post-megadropdown *)')
28+
.should('have.length', 20)
29+
.as('navigationItems');
30+
31+
// remove scroll transition to speed up the tests
32+
cy.get('@mainnavigation')
33+
.find('nav')
34+
.then($nav => {
35+
$nav.css('transition', 'none');
36+
});
37+
});
38+
39+
it('should be in a container with an hidden horizontal overflow', () => {
40+
cy.get('@mainnavigation')
41+
.parent('post-header')
42+
.parent()
43+
.then($parent => {
44+
expect($parent.css('overflow-x')).eq('hidden');
45+
});
46+
});
47+
48+
it('should always show the navigation item that is currently focused', () => {
49+
cy.get('@navigationItems').last().as('last').focus();
50+
cy.get('@last').should('be.visible');
51+
52+
cy.get('@navigationItems').first().as('first').focus();
53+
cy.get('@first').should('be.visible');
54+
});
55+
56+
describe('right scroll', () => {
57+
beforeEach(() => {
58+
cy.get('@mainnavigation').find('.right-scroll-button button').as('rightScroll');
59+
});
60+
61+
it('should correctly show the right scroll button', () => {
62+
cy.get('@mainnavigation').then($mainnavigation => {
63+
cy.get('@rightScroll').then($rightScroll => {
64+
expect($rightScroll.outerHeight()).eq($mainnavigation.innerHeight());
65+
});
66+
});
67+
});
68+
69+
it('should click until the last navigation item is visible', () => {
70+
cy.get('@rightScroll').should('be.visible');
71+
72+
cy.get('@navigationItems').each($el => {
73+
if (!isFullyVisible($el)) cy.get('@rightScroll').click({ force: true });
74+
cy.wrap($el).then(isFullyVisible).should('be.true');
75+
});
76+
77+
cy.get('@rightScroll').should('be.hidden');
78+
});
79+
80+
it('should scroll continuously until the last navigation item is visible', () => {
81+
cy.get('@mainnavigation').trigger('mousedown', Cypress.config('viewportWidth') - 5, 5);
82+
cy.wait(800);
83+
cy.get('@mainnavigation').trigger('mouseup');
84+
85+
cy.get('@navigationItems').last().should('be.visible');
86+
});
87+
88+
it('should focus until the last navigation item is visible', () => {
89+
cy.get('@rightScroll').should('be.visible');
90+
91+
cy.get('@navigationItems').each($el => {
92+
cy.wrap($el).focus().then(isFullyVisible).should('be.true');
93+
});
94+
95+
cy.get('@rightScroll').should('be.hidden');
96+
});
97+
98+
it('should not be able to click on a navigation item for a short amount of time after scroll', () => {
99+
const click = () => {
100+
cy.get('post-header').then($header => {
101+
cy.get('post-header').click(Cypress.config('viewportWidth') - 5, $header.height() - 5);
102+
});
103+
};
104+
105+
// click until the last navigation item is visible
106+
cy.get('@navigationItems').each($el => {
107+
if (!isFullyVisible($el)) click();
108+
});
109+
110+
// click on the position where the scroll right button was, the last item should not be triggered
111+
click();
112+
cy.get('@navigationItems').last().invoke('attr', 'aria-expanded').should('not.eq', 'true');
113+
114+
// wait and click again on the position where the scroll right button was, the last item should then be triggered
115+
cy.wait(400);
116+
click();
117+
cy.get('@navigationItems').last().invoke('attr', 'aria-expanded').should('eq', 'true');
118+
});
119+
120+
it('should show the mega-dropdown at the correct position after scroll', () => {
121+
// click until the last navigation item is visible
122+
cy.get('@navigationItems').last().focus();
123+
124+
// open the last mega-dropdown
125+
cy.get('@navigationItems').last().click();
126+
127+
// check the mega-dropdown visible and position
128+
cy.get('@mainnavigation')
129+
.find('post-megadropdown .megadropdown')
130+
.last()
131+
.should('be.visible')
132+
.then($megadropdown => {
133+
expect($megadropdown.position().left).eq(0);
134+
});
135+
});
136+
});
137+
138+
describe('left scroll', () => {
139+
beforeEach(() => {
140+
cy.get('@navigationItems').last().focus();
141+
142+
cy.get('@navigationItems')
143+
.then($options => $options.get().reverse())
144+
.as('navigationItemsReversed');
145+
146+
cy.get('@mainnavigation').find('.left-scroll-button button').as('leftScroll');
147+
148+
cy.wait(0); // wait for rendering
149+
});
150+
151+
it('should correctly show the left scroll button', () => {
152+
cy.get('@mainnavigation').then($mainnavigation => {
153+
cy.get('@leftScroll').then($leftScroll => {
154+
expect($leftScroll.outerHeight()).eq($mainnavigation.innerHeight());
155+
});
156+
});
157+
});
158+
159+
it('should click until the first navigation item is visible', () => {
160+
cy.get('@leftScroll').should('be.visible');
161+
162+
cy.get('@navigationItemsReversed').each($el => {
163+
if (!isFullyVisible($el)) cy.get('@leftScroll').click({ force: true });
164+
cy.wrap($el).then(isFullyVisible).should('be.true');
165+
});
166+
167+
cy.get('@leftScroll').should('be.hidden');
168+
});
169+
170+
it('should scroll continuously until the first navigation item is visible', () => {
171+
cy.get('@mainnavigation').trigger('mousedown', 5, 5);
172+
cy.wait(800);
173+
cy.get('@mainnavigation').trigger('mouseup');
174+
175+
cy.get('@navigationItems').first().should('be.visible');
176+
});
177+
178+
it('should focus until the first navigation item is visible', () => {
179+
cy.get('@leftScroll').should('be.visible');
180+
181+
cy.get('@navigationItemsReversed').each($el => {
182+
cy.wrap($el).focus().then(isFullyVisible).should('be.true');
183+
});
184+
185+
cy.get('@leftScroll').should('be.hidden');
186+
});
187+
188+
it('should not be able to click on a navigation item for a short amount of time after scroll', () => {
189+
const click = () => {
190+
cy.get('post-header').then($header => {
191+
cy.get('post-header').click(5, $header.height() - 5);
192+
});
193+
};
194+
// click until the first navigation item is visible
195+
cy.get('@navigationItemsReversed').each($el => {
196+
if (!isFullyVisible($el)) click();
197+
});
198+
199+
// click on the position where the scroll left button was, the first item should not be triggered
200+
click();
201+
cy.get('@navigationItems').first().invoke('attr', 'aria-expanded').should('not.eq', 'true');
202+
203+
// wait and click again on the position where the scroll left button was, the first item should then be triggered
204+
cy.wait(400);
205+
click();
206+
cy.get('@navigationItems').first().invoke('attr', 'aria-expanded').should('eq', 'true');
207+
});
208+
});
209+
});
210+
211+
describe('Accessibility', () => {
212+
beforeEach(() => {
213+
cy.visit('./cypress/fixtures/post-mainnavigation.test.html');
214+
cy.get('post-mainnavigation[data-hydrated]').should('be.visible');
215+
cy.injectAxe();
216+
});
217+
218+
it('Has no detectable a11y violations on load', () => {
219+
cy.checkA11y('post-mainnavigation');
220+
});
221+
});
222+
});

0 commit comments

Comments
 (0)