A11Y: improve summary page user link structure (#23746)

This commit is contained in:
Kris 2023-10-03 09:43:45 -04:00 committed by GitHub
parent 2cf1e15025
commit f3a7ebf75c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 113 deletions

View File

@ -1,15 +1,16 @@
{{#each this.usersTemplates as |userTemplate|}}
<a
href={{userTemplate.userPath}}
data-user-card={{userTemplate.username}}
aria-label={{i18n "user.profile_possessive" username=userTemplate.username}}
>
<div data-username={{userTemplate.username}} class="user-info small">
<div data-username={{userTemplate.username}} class="user-info small">
<a
href={{userTemplate.userPath}}
data-user-card={{userTemplate.username}}
aria-label={{i18n
"user.profile_possessive"
username=userTemplate.username
}}
>
<div class="user-image">
<div class="user-image-inner">
{{html-safe userTemplate.avatar}}
</div>
</div>
<div class="user-detail">
@ -27,6 +28,6 @@
</div>
<div class="title">{{userTemplate.title}}</div>
</div>
</div>
</a>
</a>
</div>
{{/each}}

View File

@ -5,6 +5,7 @@ import { renderAvatar } from "discourse/helpers/user-avatar";
import { userPath } from "discourse/lib/url";
export default Component.extend({
tagName: "",
usersTemplates: computed("users.[]", function () {
return (this.users || []).map((user) => {
const { name, username } = user;

View File

@ -1,63 +1,55 @@
{{#if this.includeAvatar}}
<div class="user-image">
<div class="user-image-inner">
<a href={{this.userPath}} data-user-card={{@user.username}}>{{avatar
@user
imageSize="large"
}}</a>
<UserAvatarFlair @user={{@user}} />
</div>
</div>
{{/if}}
<div class="user-detail">
<div class="name-line">
<span class={{if this.nameFirst "name bold" "username bold"}}>
{{#if this.includeLink}}
<a href={{this.userPath}} data-user-card={{@user.username}}>
{{if this.nameFirst @user.name (format-username @user.username)}}
</a>
{{else}}
{{if this.nameFirst @user.name (format-username @user.username)}}
{{/if}}
</span>
<span class={{if this.nameFirst "username margin" "name margin"}}>
{{#if this.includeLink}}
<a href={{this.userPath}} data-user-card={{@user.username}}>
{{if this.nameFirst (format-username @user.username) @user.name}}
</a>
{{else}}
{{if this.nameFirst (format-username @user.username) @user.name}}
{{/if}}
</span>
{{#if (and @showStatus @user.status)}}
<UserStatusMessage
@status={{@user.status}}
@showDescription={{@showStatusDescription}}
/>
{{/if}}
<span>
<PluginOutlet
@name="after-user-name"
@connectorTagName="span"
@outletArgs={{hash user=this.user}}
/>
</span>
</div>
<div class="title">{{@user.title}}</div>
{{#if (has-block)}}
<div class="details">
{{yield}}
<a
href={{if this.includeLink this.userPath}}
data-user-card={{if this.includeLink @user.username}}
aria-label={{if
(and this.includeLink @user.username)
(i18n "user.profile_possessive" username=@user.username)
}}
>
{{#if this.includeAvatar}}
<div class="user-image">
<div class="user-image-inner">
{{avatar @user imageSize="large"}}
<UserAvatarFlair @user={{@user}} />
</div>
</div>
{{/if}}
<div class="user-detail">
<div class="name-line">
<span class={{if this.nameFirst "name" "username"}}>
{{if this.nameFirst @user.name (format-username @user.username)}}
</span>
<span class={{if this.nameFirst "username" "name"}}>
{{if this.nameFirst (format-username @user.username) @user.name}}
</span>
{{#if (and @showStatus @user.status)}}
<UserStatusMessage
@status={{@user.status}}
@showDescription={{@showStatusDescription}}
/>
{{/if}}
<span>
<PluginOutlet
@name="after-user-name"
@connectorTagName="span"
@outletArgs={{hash user=this.user}}
/>
</span>
</div>
<div class="title">{{@user.title}}</div>
{{#if (has-block)}}
<div class="details">
{{yield}}
</div>
{{/if}}
</div>
</div>
<span>
<PluginOutlet
@name="after-user-info"
@connectorTagName="div"
@outletArgs={{hash user=this.user}}
/>
</span>
<span>
<PluginOutlet
@name="after-user-info"
@connectorTagName="div"
@outletArgs={{hash user=this.user}}
/>
</span>
</a>

View File

@ -46,9 +46,9 @@
{{#if this.model.admins}}
<section class="about admins">
<h3>{{d-icon "users"}} {{i18n "about.our_admins"}}</h3>
<AboutPageUsers @users={{this.model.admins}} />
<div class="clearfix"></div>
<div class="users">
<AboutPageUsers @users={{this.model.admins}} />
</div>
</section>
{{/if}}
@ -63,11 +63,9 @@
{{#if this.model.moderators}}
<section class="about moderators">
<h3>{{d-icon "users"}} {{i18n "about.our_moderators"}}</h3>
<div class="users">
<AboutPageUsers @users={{this.model.moderators}} />
</div>
<div class="clearfix"></div>
</section>
{{/if}}
@ -95,7 +93,6 @@
{{#if this.model.can_see_about_stats}}
<section class="about stats">
<h3>{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}</h3>
<table class="table">
<thead>
<tr>

View File

@ -13,8 +13,8 @@ module("Integration | Component | user-info", function (hooks) {
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
assert.strictEqual(query(".name.bold").innerText.trim(), "Evil Trout");
assert.strictEqual(query(".username.margin").innerText.trim(), "eviltrout");
assert.strictEqual(query(".name").innerText.trim(), "Evil Trout");
assert.strictEqual(query(".username").innerText.trim(), "eviltrout");
});
test("prioritized username", async function (assert) {
@ -23,8 +23,8 @@ module("Integration | Component | user-info", function (hooks) {
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
assert.strictEqual(query(".username.bold").innerText.trim(), "eviltrout");
assert.strictEqual(query(".name.margin").innerText.trim(), "Evil Trout");
assert.strictEqual(query(".username").innerText.trim(), "eviltrout");
assert.strictEqual(query(".name").innerText.trim(), "Evil Trout");
});
test("includeLink", async function (assert) {
@ -33,10 +33,10 @@ module("Integration | Component | user-info", function (hooks) {
);
this.set("includeLink", true);
assert.ok(exists(`.username a[href="/u/${this.currentUser.username}"]`));
assert.ok(exists(`a[href="/u/${this.currentUser.username}"]`));
this.set("includeLink", false);
assert.notOk(exists(`.username a[href="/u/${this.currentUser.username}"]`));
assert.notOk(exists(`a[href="/u/${this.currentUser.username}"]`));
});
test("includeAvatar", async function (assert) {

View File

@ -1,6 +1,12 @@
section.about {
margin-bottom: 3em;
.users {
display: grid;
gap: 1em;
grid-template-columns: repeat(auto-fit, minmax(20em, 1fr));
}
h3 {
margin-bottom: 1em;
display: flex;

View File

@ -191,16 +191,11 @@
.user-info {
display: flex;
min-width: 0;
margin: 0;
width: 100%;
.user-image {
padding-right: 0.5em;
margin-right: 0.5em;
}
.user-detail {
padding: 0;
width: 100%;
@media screen and (max-width: 600px) {
@include breakpoint(tablet) {
// overrides existing media query
font-size: var(--font-0);
}

View File

@ -1,13 +1,9 @@
// Common styles for "user-info" component
.user-info {
display: inline-block;
clear: both;
margin-bottom: 1em;
.user-image {
float: left;
padding-right: 4px;
margin-right: 10px;
> a {
display: flex;
gap: 1em;
min-width: 0;
}
.user-image-inner {
@ -16,39 +12,39 @@
}
.user-detail {
float: left;
width: 70%;
padding-left: 5px;
@media screen and (max-width: 600px) {
min-width: 0;
@include breakpoint(tablet) {
font-size: var(--font-down-1);
}
.name-line {
@include ellipsis;
display: flex;
gap: 0.5em;
color: var(--primary-high);
.name,
.username {
@include ellipsis;
}
span:first-child {
color: var(--primary);
flex: 0 0 auto;
font-weight: bold;
}
}
.details {
color: var(--primary);
.d-icon-reply {
color: var(--primary-medium);
}
}
.title {
margin-top: 3px;
margin-top: 0.25em;
color: var(--primary-medium);
}
}
&.small {
width: 333px;
@media screen and (max-width: $small-width) {
width: auto;
display: flex;
}
@media screen and (max-width: 600px) {
width: 100%;
}
}
&.medium {
min-height: 60px;