Skip to content

Commit d2fa61a

Browse files
authored
chore(components): remove post-list from post-footer (#6740)
## 📄 Description Removed the `post-list` and `post-list-item` from `post-footer`. Simplified the structure a bit by removing the duplicated grid titles. ## 🚀 Demo If applicable, please add a screenshot or video to illustrate the changes. --- ## 🔮 Design review - [ ] Design review done - [X] No design review needed ## 📝 Checklist - ✅ My code follows the style guidelines of this project - 🛠️ I have performed a self-review of my own code - 📄 I have made corresponding changes to the documentation - ⚠️ My changes generate no new warnings or errors - 🧪 I have added tests that prove my fix is effective or that my feature works - ✔️ New and existing unit tests pass locally with my changes
1 parent 7cdb0db commit d2fa61a

File tree

10 files changed

+526
-468
lines changed

10 files changed

+526
-468
lines changed

.changeset/smart-walls-jump.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@swisspost/design-system-components': major
3+
'@swisspost/design-system-documentation': patch
4+
'@swisspost/design-system-styles': patch
5+
---
6+
7+
Simplified the `post-footer` component by removing the `post-list` and `post-list-item`. The footer now only uses simple `ul` and `li` tags.

packages/components-angular/projects/consumer-app/src/app/app.component.html

Lines changed: 81 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -148,86 +148,92 @@ <h1>Hurray, it works!</h1>
148148

149149
<post-footer label="Footer label">
150150
@for (grid of footerGrids; track grid.slot) {
151-
<span [attr.slot]="grid.slot + '-title'">{{ grid.title }}</span>
152-
<post-list [attr.slot]="grid.slot" [attr.id]="grid.slot">
153-
<h3>{{ grid.title }}</h3>
151+
<span [attr.id]="grid.slot + '-title'" [attr.slot]="grid.slot + '-title'">{{ grid.title }}</span>
152+
<ul [attr.slot]="grid.slot" [attr.aria-labelledby]="grid.slot + '-title'">
154153
@for (link of footerLinks.slice(0, grid.linkCount); track link.text) {
155-
<post-list-item>
154+
<li>
156155
<a [href]="link.url">{{ link.text }}</a>
157-
</post-list-item>
156+
</li>
158157
}
159-
</post-list>
158+
</ul>
160159
}
161160

162-
<post-list slot="socialmedia">
163-
<h3>Follow us</h3>
164-
@for (social of socialMediaLinks; track social.name) {
165-
<post-list-item>
166-
<a [href]="social.url" class="btn btn-primary btn-icon">
167-
<post-icon aria-hidden="true" [name]="social.icon"></post-icon>
168-
<span class="visually-hidden">{{ social.name }}</span>
169-
</a>
170-
</post-list-item>
171-
}
172-
</post-list>
173-
174-
<post-list slot="app">
175-
<h3>Download app</h3>
176-
<post-list-item>
177-
<a
178-
class="app-store-badge"
179-
href="https://play.google.com/store/apps/details?id=com.nth.swisspost&amp;hl=de_CH&amp;pli=1"
180-
>
181-
<img
182-
width="135"
183-
height="40"
184-
src="https://next.design-system.post.ch/assets/images/google-play-badge.svg"
185-
alt="Google Play Store badge"
186-
/>
187-
<span class="visually-hidden">Download the App on Google Play</span>
188-
</a>
189-
</post-list-item>
190-
<post-list-item>
191-
<a class="app-store-badge" href="https://apps.apple.com/ch/app/die-post/id378676700">
192-
<img
193-
width="120"
194-
height="40"
195-
src="https://next.design-system.post.ch/assets/images/apple-store-badge.svg"
196-
alt="Apple App Store badge"
197-
/>
198-
<span class="visually-hidden">Download the App on the Apple Store</span>
199-
</a>
200-
</post-list-item>
201-
</post-list>
202-
203-
<post-list slot="businesssectors">
204-
<h3>Die schweizerische Post AG</h3>
205-
<post-list-item>
206-
<a href="https://www.postauto.ch">PostAuto</a>
207-
</post-list-item>
208-
<post-list-item>
209-
<a href="https://www.postfinance.ch">PostFinance</a>
210-
</post-list-item>
211-
</post-list>
212-
213-
<post-list slot="meta" title-hidden="">
214-
<h3>Meta</h3>
215-
@for (meta of metaLinks; track meta.text) {
216-
<post-list-item>
217-
<a [href]="meta.url">{{ meta.text }}</a>
218-
</post-list-item>
219-
}
220-
<post-list-item>
221-
<button
222-
class="btn btn-link"
223-
[style.minHeight]="0"
224-
[style.border]="'0 none'"
225-
[style.fontWeight]="'inherit'"
226-
>
227-
Cookie Settings
228-
</button>
229-
</post-list-item>
230-
</post-list>
161+
<div slot="socialmedia">
162+
<h3 id="socialmedia">Follow us</h3>
163+
<ul aria-labelledby="socialmedia">
164+
@for (social of socialMediaLinks; track social.name) {
165+
<li>
166+
<a [href]="social.url" class="btn btn-primary btn-icon">
167+
<post-icon aria-hidden="true" [name]="social.icon"></post-icon>
168+
<span class="visually-hidden">{{ social.name }}</span>
169+
</a>
170+
</li>
171+
}
172+
</ul>
173+
</div>
174+
175+
<div slot="app">
176+
<h3 id="app">Download app</h3>
177+
<ul aria-labelledby="app">
178+
<li>
179+
<a
180+
class="app-store-badge"
181+
href="https://play.google.com/store/apps/details?id=com.nth.swisspost&amp;hl=de_CH&amp;pli=1"
182+
>
183+
<img
184+
width="135"
185+
height="40"
186+
src="https://next.design-system.post.ch/assets/images/google-play-badge.svg"
187+
alt="Google Play Store badge"
188+
/>
189+
<span class="visually-hidden">Download the App on Google Play</span>
190+
</a>
191+
</li>
192+
<li>
193+
<a class="app-store-badge" href="https://apps.apple.com/ch/app/die-post/id378676700">
194+
<img
195+
width="120"
196+
height="40"
197+
src="https://next.design-system.post.ch/assets/images/apple-store-badge.svg"
198+
alt="Apple App Store badge"
199+
/>
200+
<span class="visually-hidden">Download the App on the Apple Store</span>
201+
</a>
202+
</li>
203+
</ul>
204+
</div>
205+
206+
<div slot="businesssectors">
207+
<h3 id="businesssectors">Die schweizerische Post AG</h3>
208+
<ul aria-labelledby="businesssectors">
209+
<li>
210+
<a href="https://www.postauto.ch">PostAuto</a>
211+
</li>
212+
<li>
213+
<a href="https://www.postfinance.ch">PostFinance</a>
214+
</li>
215+
</ul>
216+
</div>
217+
218+
<div slot="meta">
219+
<ul aria-label="Meta">
220+
@for (meta of metaLinks; track meta.text) {
221+
<li>
222+
<a [href]="meta.url">{{ meta.text }}</a>
223+
</li>
224+
}
225+
<li>
226+
<button
227+
class="btn btn-link"
228+
[style.minHeight]="0"
229+
[style.border]="'0 none'"
230+
[style.fontWeight]="'inherit'"
231+
>
232+
Cookie Settings
233+
</button>
234+
</li>
235+
</ul>
236+
</div>
231237

232238
<span slot="copyright">© Copyright 2024 by Swiss Post Ltd.</span>
233239
<span slot="copyright">All rights reserved.</span>

packages/components-angular/projects/consumer-app/src/app/app.component.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import { CommonModule } from '@angular/common';
4545
PostMegadropdown,
4646
PostMegadropdownTrigger,
4747
PostTogglebutton,
48-
]
48+
],
4949
})
5050
export class AppComponent implements OnInit {
5151
title = 'consumer-app';
@@ -64,7 +64,7 @@ export class AppComponent implements OnInit {
6464
{ text: 'Small items abroad', url: '/kl' },
6565
{ text: 'Goods abroad', url: '' },
6666
{ text: 'Express and courier', url: '' },
67-
]
67+
],
6868
};
6969

7070
// Header megadropdown data
@@ -77,14 +77,14 @@ export class AppComponent implements OnInit {
7777
sections: [
7878
{
7979
title: 'Send letters',
80-
links: this.megadropdownLinks.standard
80+
links: this.megadropdownLinks.standard,
8181
},
8282
{
8383
title: 'Step by step',
8484
titleLink: '/step-by-step',
85-
links: this.megadropdownLinks.packages
86-
}
87-
]
85+
links: this.megadropdownLinks.packages,
86+
},
87+
],
8888
},
8989
{
9090
id: 'packages',
@@ -94,15 +94,15 @@ export class AppComponent implements OnInit {
9494
sections: [
9595
{
9696
title: 'Send packages',
97-
links: this.megadropdownLinks.packages
97+
links: this.megadropdownLinks.packages,
9898
},
9999
{
100100
title: 'Step by step',
101101
titleLink: '/step-by-step',
102-
links: this.megadropdownLinks.packages
103-
}
104-
]
105-
}
102+
links: this.megadropdownLinks.packages,
103+
},
104+
],
105+
},
106106
];
107107

108108
// Reusable links array for footer grids
@@ -127,21 +127,30 @@ export class AppComponent implements OnInit {
127127

128128
// Social media links (Footer)
129129
public socialMediaLinks = [
130-
{ name: 'Facebook', url: '#facebook', icon: '8004' },
131-
{ name: 'Instagram', url: '#instagram', icon: '8007' },
132-
{ name: 'Youtube', url: '#youtube', icon: '8002' },
133-
{ name: 'Snapchat', url: '#snapchat', icon: '8017' },
134-
{ name: 'Twitter X', url: '#twitter-x', icon: '8000' },
135-
{ name: 'Linkedin', url: '#linkedin', icon: '8005' },
136-
{ name: 'Xing', url: '#xing', icon: '8001' },
130+
{ name: 'Facebook', url: '#facebook', icon: 'facebook' },
131+
{ name: 'Instagram', url: '#instagram', icon: 'instagram' },
132+
{ name: 'Youtube', url: '#youtube', icon: 'youtube' },
133+
{ name: 'Snapchat', url: '#snapchat', icon: 'snapchat' },
134+
{ name: 'Twitter X', url: '#twitter-x', icon: 'twitterx' },
135+
{ name: 'Linkedin', url: '#linkedin', icon: 'linkedin' },
136+
{ name: 'Xing', url: '#xing', icon: 'xing' },
137137
{ name: 'E-Mail', url: 'mailto:[email protected]', icon: 'letter' },
138138
];
139139

140140
// Meta links (Footer)
141141
public metaLinks = [
142-
{ text: 'Accessibility', url: 'https://www.post.ch/en/pages/footer/accessibility-at-swiss-post' },
143-
{ text: 'General Terms and Conditions', url: 'https://www.post.ch/en/pages/footer/general-terms-and-conditions-gtc' },
144-
{ text: 'Data protection and disclaimer', url: 'https://www.post.ch/en/pages/footer/data-protection-and-disclaimer' },
142+
{
143+
text: 'Accessibility',
144+
url: 'https://www.post.ch/en/pages/footer/accessibility-at-swiss-post',
145+
},
146+
{
147+
text: 'General Terms and Conditions',
148+
url: 'https://www.post.ch/en/pages/footer/general-terms-and-conditions-gtc',
149+
},
150+
{
151+
text: 'Data protection and disclaimer',
152+
url: 'https://www.post.ch/en/pages/footer/data-protection-and-disclaimer',
153+
},
145154
{ text: 'Publication details', url: 'https://www.post.ch/en/pages/footer/publication-details' },
146155
];
147156

packages/components/cypress/e2e/footer.cy.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,27 @@ describe('Footer', () => {
1818
it('should have all required grid sections with proper structure', () => {
1919
// Should have 4 grid sections with title-content pairs
2020
cy.get('@footer').find('[slot^="grid-"]').should('have.length', 8); // 4 titles + 4 lists
21-
cy.get('@footer').find('post-list[slot^="grid-"]').should('have.length', 4);
21+
cy.get('@footer').find('ul[slot^="grid-"]').should('have.length', 4);
2222

2323
// Each grid should have title-content pairs
2424
for (let i = 1; i <= 4; i++) {
2525
cy.get('@footer').find(`[slot="grid-${i}-title"]`).should('exist');
26-
cy.get('@footer').find(`post-list[slot="grid-${i}"]`).should('exist');
27-
cy.get('@footer').find(`post-list[slot="grid-${i}"] h3`).should('exist');
26+
cy.get('@footer').find(`ul[slot="grid-${i}"]`).should('exist');
2827
}
2928
});
3029

3130
it('should have all required sections', () => {
3231
const requiredSections = ['socialmedia', 'app', 'businesssectors', 'meta'];
3332

3433
requiredSections.forEach(section => {
35-
cy.get('@footer').find(`post-list[slot="${section}"]`).should('exist');
36-
cy.get('@footer').find(`post-list[slot="${section}"] h3`).should('exist');
34+
cy.get('@footer').find(`div[slot="${section}"]`).should('exist');
35+
36+
// Meta should have an aria-label as it has no visible title
37+
if (section === 'meta') {
38+
cy.get('@footer').find(`div[slot="${section}"] ul`).should('have.attr', 'aria-label', 'Meta');
39+
} else {
40+
cy.get('@footer').find(`div[slot="${section}"] h3`).should('exist');
41+
}
3742
});
3843

3944
cy.get('@footer').find('span[slot="copyright"]').should('have.length.at.least', 1);
@@ -50,14 +55,14 @@ describe('Footer', () => {
5055
it('should have interactive elements', () => {
5156
// Cookie settings button
5257
cy.get('@footer')
53-
.find('post-list[slot="meta"] button')
58+
.find('div[slot="meta"] button')
5459
.should('exist')
5560
.should('be.visible')
5661
.click(); // Test it's clickable
5762

5863
// Social media links with proper styling
5964
cy.get('@footer')
60-
.find('post-list[slot="socialmedia"] a')
65+
.find('div[slot="socialmedia"] a')
6166
.each($link => {
6267
cy.wrap($link)
6368
.should('have.class', 'btn')
@@ -74,7 +79,7 @@ describe('Footer', () => {
7479

7580
it('should display grid layout on desktop', () => {
7681
cy.viewport(1200, 800);
77-
cy.get('@footer').find('post-list[slot^="grid-"]').should('be.visible');
82+
cy.get('@footer').find('ul[slot^="grid-"]').should('be.visible');
7883
cy.get('@footer').find('post-accordion').should('not.exist');
7984
});
8085

@@ -135,7 +140,7 @@ describe('Footer', () => {
135140

136141
// Social media icons marked as decorative
137142
cy.get('@footer')
138-
.find('post-list[slot="socialmedia"] post-icon')
143+
.find('div[slot="socialmedia"] post-icon')
139144
.each($icon => {
140145
cy.wrap($icon).should('have.attr', 'aria-hidden', 'true');
141146
});

packages/components/src/components/post-footer/post-footer.scss

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
@use '@swisspost/design-system-styles/mixins/media';
33
@use '@swisspost/design-system-styles/mixins/list';
44
@use '@swisspost/design-system-styles/mixins/utilities';
5+
@use '@swisspost/design-system-styles/functions/tokens';
6+
@use '@swisspost/design-system-styles/tokens/elements';
7+
8+
tokens.$default-map: elements.$post-heading;
59

610
:host {
711
display: block;
@@ -81,6 +85,20 @@ footer {
8185
}
8286
}
8387

88+
:is(h3, .h3) {
89+
margin: 0;
90+
font-size: tokens.get('h6-font-size');
91+
line-height: tokens.get('heading-line-height');
92+
font-weight: tokens.get('heading-font-weight');
93+
text-wrap: balance;
94+
}
95+
96+
::slotted(ul) {
97+
list-style: none;
98+
padding: 0;
99+
margin: 0;
100+
}
101+
84102
.visually-hidden {
85103
@include utilities.visuallyhidden();
86104
}
@@ -120,7 +138,7 @@ footer {
120138
.footer-app,
121139
.footer-businesssectors,
122140
.footer-meta {
123-
::slotted(post-list) {
141+
::slotted(div) {
124142
display: flex !important;
125143
flex-direction: var(--post-footer-post-list-flex-direction) !important;
126144
gap: var(--post-footer-post-list-gap) !important;
@@ -155,4 +173,3 @@ footer {
155173
.d-none {
156174
display: none;
157175
}
158-

packages/components/src/components/post-footer/post-footer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ export class PostFooter {
9090
private renderColumns() {
9191
return GRID_SLOTS.map(slotName => (
9292
<div class={{ 'd-none': !this.gridSlotDisplayed[slotName] }}>
93+
<h3>
94+
<slot name={slotName + '-title'}></slot>
95+
</h3>
9396
<slot onSlotchange={this.handleGridSlotChange('tablet', 'desktop')} name={slotName}></slot>
9497
</div>
9598
));

0 commit comments

Comments
 (0)