Merge pull request #1355 from jsit/fix/site-sidebar-collapse

fix(a11y): Fix some a11y issues in Site Sidebar and use native Bootstrap Collapse and Card classes
This commit is contained in:
SleeplessOne1917 2023-06-18 13:37:36 +00:00 committed by GitHub
commit ad0c24f3ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 160 additions and 112 deletions

View file

@ -15,6 +15,7 @@ export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
const banner = this.props.banner;
const icon = this.props.icon;
return (
(banner || icon) && (
<div className="position-relative mb-2">
{banner && <PictrsImage src={banner} banner alt="" />}
{icon && (
@ -26,6 +27,7 @@ export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
/>
)}
</div>
)
);
}
}

View file

@ -443,16 +443,17 @@ export class Home extends Component<any, HomeState> {
admins={admins}
counts={counts}
showLocal={showLocal(this.isoData)}
isMobile={true}
/>
)}
{showTrendingMobile && (
<div className="col-12 card border-secondary mb-3">
<div className="card-body">{this.trendingCommunities(true)}</div>
<div className="card border-secondary mb-3">
{this.trendingCommunities()}
</div>
)}
{showSubscribedMobile && (
<div className="col-12 card border-secondary mb-3">
<div className="card-body">{this.subscribedCommunities}</div>
<div className="card border-secondary mb-3">
{this.subscribedCommunities(true)}
</div>
)}
</div>
@ -471,8 +472,60 @@ export class Home extends Component<any, HomeState> {
return (
<div id="sidebarContainer">
<section id="sidebarMain" className="card border-secondary mb-3">
<div className="card-body">
{this.trendingCommunities()}
</section>
<SiteSidebar
site={site}
admins={admins}
counts={counts}
showLocal={showLocal(this.isoData)}
/>
{this.hasFollows && (
<div className="accordion">
<section
id="sidebarSubscribed"
className="card border-secondary mb-3"
>
{this.subscribedCommunities(false)}
</section>
</div>
)}
</div>
);
}
trendingCommunities() {
switch (this.state.trendingCommunitiesRes?.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
case "success": {
const trending = this.state.trendingCommunitiesRes.data.communities;
return (
<>
<header className="card-header d-flex align-items-center">
<h5 className="mb-0">
<T i18nKey="trending_communities">
#
<Link className="text-body" to="/communities">
#
</Link>
</T>
</h5>
</header>
<div className="card-body">
{trending.length > 0 && (
<ul className="list-inline">
{trending.map(cv => (
<li key={cv.community.id} className="list-inline-item">
<CommunityLink community={cv.community} />
</li>
))}
</ul>
)}
{canCreateCommunity(this.state.siteRes) && (
<LinkButton
path="/create_community"
@ -484,86 +537,58 @@ export class Home extends Component<any, HomeState> {
translationKey="explore_communities"
/>
</div>
</section>
<SiteSidebar
site={site}
admins={admins}
counts={counts}
showLocal={showLocal(this.isoData)}
/>
{this.hasFollows && (
<section
id="sidebarSubscribed"
className="card border-secondary mb-3"
>
<div className="card-body">{this.subscribedCommunities}</div>
</section>
)}
</div>
);
}
trendingCommunities(isMobile = false) {
switch (this.state.trendingCommunitiesRes?.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
case "success": {
const trending = this.state.trendingCommunitiesRes.data.communities;
return (
<div className={!isMobile ? "mb-2" : ""}>
<h5>
<T i18nKey="trending_communities">
#
<Link className="text-body" to="/communities">
#
</Link>
</T>
</h5>
<ul className="list-inline mb-0">
{trending.map(cv => (
<li
key={cv.community.id}
className="list-inline-item d-inline-block"
>
<CommunityLink community={cv.community} />
</li>
))}
</ul>
</div>
</>
);
}
}
}
get subscribedCommunities() {
subscribedCommunities(isMobile = false) {
const { subscribedCollapsed } = this.state;
return (
<div>
<h5>
<>
<header
className="card-header d-flex align-items-center"
id="sidebarSubscribedHeader"
>
<h5 className="mb-0 d-inline">
<T class="d-inline" i18nKey="subscribed_to_communities">
#
<Link className="text-body" to="/communities">
#
</Link>
</T>
</h5>
{!isMobile && (
<button
type="button"
className="btn btn-sm text-muted"
onClick={linkEvent(this, this.handleCollapseSubscribe)}
aria-label={i18n.t("collapse")}
data-tippy-content={i18n.t("collapse")}
aria-label={
subscribedCollapsed ? i18n.t("expand") : i18n.t("collapse")
}
data-tippy-content={
subscribedCollapsed ? i18n.t("expand") : i18n.t("collapse")
}
data-bs-toggle="collapse"
data-bs-target="#sidebarSubscribedBody"
aria-expanded="true"
aria-controls="sidebarSubscribedBody"
>
<Icon
icon={`${subscribedCollapsed ? "plus" : "minus"}-square`}
classes="icon-inline"
/>
</button>
</h5>
{!subscribedCollapsed && (
)}
</header>
<div
id="sidebarSubscribedBody"
className="collapse show"
aria-labelledby="sidebarSubscribedHeader"
>
<div className="card-body">
<ul className="list-inline mb-0">
{UserService.Instance.myUserInfo?.follows.map(cfv => (
<li
@ -574,8 +599,9 @@ export class Home extends Component<any, HomeState> {
</li>
))}
</ul>
)}
</div>
</div>
</>
);
}

View file

@ -12,6 +12,7 @@ interface SiteSidebarProps {
showLocal: boolean;
counts?: SiteAggregates;
admins?: PersonView[];
isMobile?: boolean;
}
interface SiteSidebarState {
@ -29,31 +30,49 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
render() {
return (
<div className="accordion">
<section id="sidebarInfo" className="card border-secondary mb-3">
<div className="card-body">
<div>
<div className="mb-2">{this.siteName()}</div>
<header
className="card-header d-flex align-items-center"
id="sidebarInfoHeader"
>
{this.siteName()}
{!this.state.collapsed && (
<>
<BannerIconHeader banner={this.props.site.banner} />
{this.siteInfo()}
</>
)}
</div>
</header>
<div
id="sidebarInfoBody"
className="collapse show"
aria-labelledby="sidebarInfoHeader"
>
<div className="card-body">{this.siteInfo()}</div>
</div>
</section>
</div>
);
}
siteName() {
return (
<h5 className="mb-0 d-inline">
{this.props.site.name}
<>
<h5 className="mb-0 d-inline">{this.props.site.name}</h5>
{!this.props.isMobile && (
<button
className="btn btn-sm text-muted"
type="button"
className="btn btn-sm"
onClick={linkEvent(this, this.handleCollapseSidebar)}
aria-label={i18n.t("collapse")}
data-tippy-content={i18n.t("collapse")}
aria-label={
this.state.collapsed ? i18n.t("expand") : i18n.t("collapse")
}
data-tippy-content={
this.state.collapsed ? i18n.t("expand") : i18n.t("collapse")
}
data-bs-toggle="collapse"
data-bs-target="#sidebarInfoBody"
aria-expanded="true"
aria-controls="sidebarInfoBody"
>
{this.state.collapsed ? (
<Icon icon="plus-square" classes="icon-inline" />
@ -61,7 +80,8 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
<Icon icon="minus-square" classes="icon-inline" />
)}
</button>
</h5>
)}
</>
);
}