mirror of
https://github.com/discourse/discourse.git
synced 2025-01-31 12:38:29 +08:00
A11Y: improve summary page user link structure (#23746)
This commit is contained in:
parent
2cf1e15025
commit
f3a7ebf75c
|
@ -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}}
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user