Closed alizedebray closed 1 year ago
Had an idea about how to manage the slot issue. It's not ideal, but leaves the definition of the header level and layout entirely in the hands of the project while also retaining accessibility standards:
<post-collapsible>
<h2 slot="header">
<post-collapsible-button>
<post-icon name="island" />
Some heading content here
</post-collapsible-button>
</h2>
<div>I'm the body of the collapsible in the default slot</div>
</post-collapsible>
Another approach would include less flexibility but more stability:
<post-collapsible>
<post-collapsible-header level="2" slot="header">
<post-icon name="island" />
Some header text
</post-collapsible-header>
<div>Some collapsible content</div>
</post-collapsible>
<!-- which renders as -->
<post-collapsible>
<post-collapsible-header>
<h2>
<button aria-expanded="...">
<post-icon ... />
Some header text
</button>
</h2>
</post-collapsible-header>
<div class="collapsible-content-container">
<div>Some collapsible content</div>
</div>
</post-collapsible>
My solution to manage the slot issue is - of course - inspired by the way how it's done in vuejs.
import { Component, Host, Element, Prop, h } from '@stencil/core';
@Component({
tag: 'post-collapse',
// styling the header, header-button and the body can be overwritten by the user with the css :part() selectors
styleUrl: 'collapse.scss',
shadow: true
})
export class PostButton {
@Element() host: HTMLElement;
// use some guid generator to get a strong and valid guid (do not use one, that only uses Math.random function)
collapseId: guid = '2f9fc627-39f7-4eed-905f-987365523c05';
// define headerTag default as 'h2' but give the possibility to change it to 'h1', 'h3', 'h4', 'h5' or 'h6'
@Prop() headerTag: string = 'h2';
@Prop({ mutable: true }) collapsed = false;
// all the code alize allready defined to manage the collapse to work...
render () {
// this gives us the possibility to add the header only if a header-slot is defined
let headerDom = [];
if (this.host.querySelector('[slot="header"]')) {
// We can add custom attributes to header by creating propertis like 'headerClass' or 'headerButtonRole', if there is really a need for that.
// Otherwise I would prefer to leave the elements as clean as possible, because they need to be like so, because of semantic reasons!
headerDom.push(
<this.headerTag
id={`${this.collapseId}--header`}
part="header"
>
<button
aria-expanded={`${!this.collapsed}`}
aria-controls={`${this.collapseId}--body`}
part="header-button"
>
<slot name="header">Provide some fallback content (if possible/necessary)</slot>
</button>
</this.headerTag>
);
}
return (
<Host class="post-collapse">
{ headerDom }
<div
id={`${this.collapseId}--body`}
aria-labelledby={`${this.collapseId}--header`}
part="body"
>
{/* default slot, every thing you define directly inside of the post-collapse component without an explicit slot wrapper goes here */}
<slot>Provide some fallback content (if possible/necessary)</slot>
</div>
</Host>
);
}
}
Discussion summary:
The collapsible component now matches the last discussion's outcomes.
Props are currently not managed with constants as this introduce side effects in the auto-generated documentation (see the "Default" column in the readme, also appeared in storybook "Docs" tab)
Preview environment ready: https://preview-683--swisspost-design-system-styles.netlify.app Preview environment ready: https://preview-683--swisspost-design-system-next.netlify.app
Kudos, SonarCloud Quality Gate passed!
0 Bugs
0 Vulnerabilities
0 Security Hotspots
0 Code Smells
No Coverage information
2.0% Duplication
🦋 Changeset detected
Latest commit: 11b63b3986e486bb855c86359f687c91810c237e
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 2 packages
| Name | Type | | -------------------------------------- | ----- | | @swisspost/design-system-components | Minor | | @swisspost/design-system-documentation | Patch |Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR