mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06: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|}}
|
{{#each this.usersTemplates as |userTemplate|}}
|
||||||
<a
|
<div data-username={{userTemplate.username}} class="user-info small">
|
||||||
href={{userTemplate.userPath}}
|
<a
|
||||||
data-user-card={{userTemplate.username}}
|
href={{userTemplate.userPath}}
|
||||||
aria-label={{i18n "user.profile_possessive" username=userTemplate.username}}
|
data-user-card={{userTemplate.username}}
|
||||||
>
|
aria-label={{i18n
|
||||||
<div data-username={{userTemplate.username}} class="user-info small">
|
"user.profile_possessive"
|
||||||
|
username=userTemplate.username
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div class="user-image">
|
<div class="user-image">
|
||||||
<div class="user-image-inner">
|
<div class="user-image-inner">
|
||||||
|
|
||||||
{{html-safe userTemplate.avatar}}
|
{{html-safe userTemplate.avatar}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-detail">
|
<div class="user-detail">
|
||||||
@ -27,6 +28,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="title">{{userTemplate.title}}</div>
|
<div class="title">{{userTemplate.title}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
@ -5,6 +5,7 @@ import { renderAvatar } from "discourse/helpers/user-avatar";
|
|||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
tagName: "",
|
||||||
usersTemplates: computed("users.[]", function () {
|
usersTemplates: computed("users.[]", function () {
|
||||||
return (this.users || []).map((user) => {
|
return (this.users || []).map((user) => {
|
||||||
const { name, username } = user;
|
const { name, username } = user;
|
||||||
|
@ -1,63 +1,55 @@
|
|||||||
{{#if this.includeAvatar}}
|
<a
|
||||||
<div class="user-image">
|
href={{if this.includeLink this.userPath}}
|
||||||
<div class="user-image-inner">
|
data-user-card={{if this.includeLink @user.username}}
|
||||||
<a href={{this.userPath}} data-user-card={{@user.username}}>{{avatar
|
aria-label={{if
|
||||||
@user
|
(and this.includeLink @user.username)
|
||||||
imageSize="large"
|
(i18n "user.profile_possessive" username=@user.username)
|
||||||
}}</a>
|
}}
|
||||||
<UserAvatarFlair @user={{@user}} />
|
>
|
||||||
</div>
|
{{#if this.includeAvatar}}
|
||||||
</div>
|
<div class="user-image">
|
||||||
{{/if}}
|
<div class="user-image-inner">
|
||||||
|
{{avatar @user imageSize="large"}}
|
||||||
<div class="user-detail">
|
<UserAvatarFlair @user={{@user}} />
|
||||||
<div class="name-line">
|
</div>
|
||||||
<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}}
|
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/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>
|
</a>
|
||||||
<PluginOutlet
|
|
||||||
@name="after-user-info"
|
|
||||||
@connectorTagName="div"
|
|
||||||
@outletArgs={{hash user=this.user}}
|
|
||||||
/>
|
|
||||||
</span>
|
|
@ -46,9 +46,9 @@
|
|||||||
{{#if this.model.admins}}
|
{{#if this.model.admins}}
|
||||||
<section class="about admins">
|
<section class="about admins">
|
||||||
<h3>{{d-icon "users"}} {{i18n "about.our_admins"}}</h3>
|
<h3>{{d-icon "users"}} {{i18n "about.our_admins"}}</h3>
|
||||||
|
<div class="users">
|
||||||
<AboutPageUsers @users={{this.model.admins}} />
|
<AboutPageUsers @users={{this.model.admins}} />
|
||||||
<div class="clearfix"></div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
@ -63,11 +63,9 @@
|
|||||||
{{#if this.model.moderators}}
|
{{#if this.model.moderators}}
|
||||||
<section class="about moderators">
|
<section class="about moderators">
|
||||||
<h3>{{d-icon "users"}} {{i18n "about.our_moderators"}}</h3>
|
<h3>{{d-icon "users"}} {{i18n "about.our_moderators"}}</h3>
|
||||||
|
|
||||||
<div class="users">
|
<div class="users">
|
||||||
<AboutPageUsers @users={{this.model.moderators}} />
|
<AboutPageUsers @users={{this.model.moderators}} />
|
||||||
</div>
|
</div>
|
||||||
<div class="clearfix"></div>
|
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
@ -95,7 +93,6 @@
|
|||||||
{{#if this.model.can_see_about_stats}}
|
{{#if this.model.can_see_about_stats}}
|
||||||
<section class="about stats">
|
<section class="about stats">
|
||||||
<h3>{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}</h3>
|
<h3>{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}</h3>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -13,8 +13,8 @@ module("Integration | Component | user-info", function (hooks) {
|
|||||||
|
|
||||||
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
|
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
|
||||||
|
|
||||||
assert.strictEqual(query(".name.bold").innerText.trim(), "Evil Trout");
|
assert.strictEqual(query(".name").innerText.trim(), "Evil Trout");
|
||||||
assert.strictEqual(query(".username.margin").innerText.trim(), "eviltrout");
|
assert.strictEqual(query(".username").innerText.trim(), "eviltrout");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prioritized username", async function (assert) {
|
test("prioritized username", async function (assert) {
|
||||||
@ -23,8 +23,8 @@ module("Integration | Component | user-info", function (hooks) {
|
|||||||
|
|
||||||
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
|
await render(hbs`<UserInfo @user={{this.currentUser}} />`);
|
||||||
|
|
||||||
assert.strictEqual(query(".username.bold").innerText.trim(), "eviltrout");
|
assert.strictEqual(query(".username").innerText.trim(), "eviltrout");
|
||||||
assert.strictEqual(query(".name.margin").innerText.trim(), "Evil Trout");
|
assert.strictEqual(query(".name").innerText.trim(), "Evil Trout");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("includeLink", async function (assert) {
|
test("includeLink", async function (assert) {
|
||||||
@ -33,10 +33,10 @@ module("Integration | Component | user-info", function (hooks) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.set("includeLink", true);
|
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);
|
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) {
|
test("includeAvatar", async function (assert) {
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
section.about {
|
section.about {
|
||||||
margin-bottom: 3em;
|
margin-bottom: 3em;
|
||||||
|
|
||||||
|
.users {
|
||||||
|
display: grid;
|
||||||
|
gap: 1em;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(20em, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -191,16 +191,11 @@
|
|||||||
.user-info {
|
.user-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.user-image {
|
|
||||||
padding-right: 0.5em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
.user-detail {
|
.user-detail {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@media screen and (max-width: 600px) {
|
@include breakpoint(tablet) {
|
||||||
// overrides existing media query
|
// overrides existing media query
|
||||||
font-size: var(--font-0);
|
font-size: var(--font-0);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
// Common styles for "user-info" component
|
// Common styles for "user-info" component
|
||||||
.user-info {
|
.user-info {
|
||||||
display: inline-block;
|
> a {
|
||||||
clear: both;
|
display: flex;
|
||||||
margin-bottom: 1em;
|
gap: 1em;
|
||||||
|
min-width: 0;
|
||||||
.user-image {
|
|
||||||
float: left;
|
|
||||||
padding-right: 4px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-image-inner {
|
.user-image-inner {
|
||||||
@ -16,39 +12,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.user-detail {
|
.user-detail {
|
||||||
float: left;
|
min-width: 0;
|
||||||
width: 70%;
|
@include breakpoint(tablet) {
|
||||||
padding-left: 5px;
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
font-size: var(--font-down-1);
|
font-size: var(--font-down-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-line {
|
.name-line {
|
||||||
@include ellipsis;
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
color: var(--primary-high);
|
color: var(--primary-high);
|
||||||
|
.name,
|
||||||
|
.username {
|
||||||
|
@include ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
span:first-child {
|
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 {
|
.title {
|
||||||
margin-top: 3px;
|
margin-top: 0.25em;
|
||||||
color: var(--primary-medium);
|
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 {
|
&.medium {
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user