UX: consistent share modal & popup, refactoring (#13759)
This commit is contained in:
parent
1c82989f77
commit
8de8989576
|
@ -49,8 +49,11 @@ export default Component.extend({
|
|||
if (this.element) {
|
||||
const linkInput = this.element.querySelector("#share-link input");
|
||||
linkInput.value = this.link;
|
||||
linkInput.setSelectionRange(0, this.link.length);
|
||||
linkInput.focus();
|
||||
if (!this.site.mobileView) {
|
||||
// if the input is auto-focused on mobile, iOS requires two taps of the copy button
|
||||
linkInput.setSelectionRange(0, this.link.length);
|
||||
linkInput.focus();
|
||||
}
|
||||
}
|
||||
}, 200);
|
||||
},
|
||||
|
|
|
@ -4,13 +4,21 @@
|
|||
{{#if date}}
|
||||
<span class="date">{{displayDate}}</span>
|
||||
{{/if}}
|
||||
|
||||
{{d-button
|
||||
action=(action "close")
|
||||
class="btn btn-flat close"
|
||||
icon="times"
|
||||
aria-label="share.close"
|
||||
title="share.close"
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="text" aria-label={{i18n "share.url"}}>
|
||||
<div class="share-link-container">
|
||||
<input class="share-link-input" type="text" aria-label={{i18n "share.url"}}> {{copy-button selector="input.share-link-input"}}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="share-link-actions">
|
||||
<div class="sources">
|
||||
{{#each sources as |s|}}
|
||||
{{share-source source=s title=model.title action=(action "share")}}
|
||||
|
@ -19,27 +27,26 @@
|
|||
|
||||
<div class="alt-actions">
|
||||
{{#if topic.details.can_reply_as_new_topic}}
|
||||
<div class="reply-as-new-topic">
|
||||
{{#if topic.isPrivateMessage}}
|
||||
<a href class="new-topic" {{action "replyAsNewTopic"}} aria-label={{i18n "post.reply_as_new_private_message"}} title={{i18n "post.reply_as_new_private_message"}}>
|
||||
{{d-icon "plus"}}
|
||||
{{i18n "user.new_private_message"}}
|
||||
</a>
|
||||
{{else}}
|
||||
<a href class="new-topic" {{action "replyAsNewTopic"}} aria-label={{i18n "post.reply_as_new_topic"}} title={{i18n "post.reply_as_new_topic"}}>
|
||||
{{d-icon "plus"}}
|
||||
{{i18n "topic.create"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if topic.isPrivateMessage}}
|
||||
{{d-button
|
||||
action=(action "replyAsNewTopic")
|
||||
class="btn btn-default new-topic"
|
||||
icon="plus"
|
||||
aria-label="post.reply_as_new_private_message"
|
||||
title="post.reply_as_new_private_message"
|
||||
label="user.new_private_message"
|
||||
}}
|
||||
{{else}}
|
||||
{{d-button
|
||||
action=(action "replyAsNewTopic")
|
||||
class="btn btn-default new-topic"
|
||||
icon="plus"
|
||||
aria-label="post.reply_as_new_topic"
|
||||
title="post.reply_as_new_topic"
|
||||
label="topic.create"
|
||||
}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{d-button
|
||||
action=(action "close")
|
||||
class="btn btn-flat close"
|
||||
icon="times"
|
||||
aria-label="share.close"
|
||||
title="share.close"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
{{d-button action=(action "share" source) class=(concat "share-" source.id) translatedTitle=source.title translatedAriaLabel=source.title icon=(if source.icon source.icon source.htmlIcon)}}
|
||||
{{d-button
|
||||
action=(action "share" source)
|
||||
class=(concat "btn-default share-" source.id)
|
||||
translatedTitle=source.title
|
||||
translatedAriaLabel=source.title
|
||||
icon=(if source.icon source.icon source.htmlIcon)
|
||||
}}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<form>
|
||||
<div class="input-group invite-link">
|
||||
<label for="invite-link">{{i18n "user.invited.invite.instructions"}}</label>
|
||||
<div class="invite-input-with-button">
|
||||
<div class="share-link-container">
|
||||
{{input
|
||||
name="invite-link"
|
||||
class="invite-link"
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
<div class="input-group input-email">
|
||||
<label for="invite-email">{{d-icon "envelope"}}{{i18n "user.invited.invite.restrict_email"}}</label>
|
||||
<div class="invite-input-with-button">
|
||||
<div class="invite-email-container">
|
||||
{{input
|
||||
id="invite-email"
|
||||
value=buffered.email
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<form>
|
||||
<div class="input-group invite-link">
|
||||
<label for="invite-link">{{i18n "topic.share.instructions"}}</label>
|
||||
<div class="invite-input-with-button">
|
||||
<div class="share-link-container">
|
||||
{{input
|
||||
name="invite-link"
|
||||
class="invite-link"
|
||||
|
@ -12,50 +12,51 @@
|
|||
{{copy-button selector="input.invite-link"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="share-link-actions">
|
||||
<div class="sources">
|
||||
{{#each sources as |s|}}
|
||||
{{share-source source=s title=topic.title action=(action "share")}}
|
||||
{{/each}}
|
||||
|
||||
<div class="sources">
|
||||
{{#each sources as |s|}}
|
||||
{{share-source source=s title=topic.title action=(action "share")}}
|
||||
{{/each}}
|
||||
|
||||
{{d-button
|
||||
class="btn-default"
|
||||
label="topic.share.notify_users.title"
|
||||
icon="hand-point-right"
|
||||
action=(action "toggleNotifyUsers")
|
||||
}}
|
||||
|
||||
{{#if allowInvites}}
|
||||
{{d-button
|
||||
class="btn-default"
|
||||
label="topic.share.invite_users"
|
||||
icon="user-plus"
|
||||
action=(action "inviteUsers")
|
||||
label="topic.share.notify_users.title"
|
||||
icon="hand-point-right"
|
||||
action=(action "toggleNotifyUsers")
|
||||
}}
|
||||
|
||||
{{#if allowInvites}}
|
||||
{{d-button
|
||||
class="btn-default"
|
||||
label="topic.share.invite_users"
|
||||
icon="user-plus"
|
||||
action=(action "inviteUsers")
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if showNotifyUsers}}
|
||||
<div class="input-group invite-users">
|
||||
<label for="invite-users">{{i18n "topic.share.notify_users.instructions"}}</label>
|
||||
<div class="notify-user-input">
|
||||
{{user-chooser
|
||||
value=users
|
||||
onChange=(action "onChangeUsers")
|
||||
options=(hash
|
||||
topicId=topic.id
|
||||
maximum=(unless currentUser.staff 1)
|
||||
excludeCurrentUser=true
|
||||
)
|
||||
}}
|
||||
{{d-button
|
||||
icon="check"
|
||||
class="btn-primary"
|
||||
disabled=(if users false true)
|
||||
action=(action "notifyUsers")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if showNotifyUsers}}
|
||||
<div class="input-group invite-users">
|
||||
<label for="invite-users">{{i18n "topic.share.notify_users.instructions"}}</label>
|
||||
<div class="invite-input-with-button">
|
||||
{{user-chooser
|
||||
value=users
|
||||
onChange=(action "onChangeUsers")
|
||||
options=(hash
|
||||
topicId=topic.id
|
||||
maximum=(unless currentUser.staff 1)
|
||||
excludeCurrentUser=true
|
||||
)
|
||||
}}
|
||||
{{d-button
|
||||
icon="check"
|
||||
class="btn-primary"
|
||||
disabled=(if users false true)
|
||||
action=(action "notifyUsers")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</form>
|
||||
{{/d-modal-body}}
|
||||
|
|
|
@ -30,7 +30,7 @@ acceptance("Share and Invite modal", function (needs) {
|
|||
"it shows the topic sharing url"
|
||||
);
|
||||
|
||||
assert.ok(count("button[class^='share-']") > 1, "it shows social sources");
|
||||
assert.ok(count("button[class*='share-']") > 1, "it shows social sources");
|
||||
|
||||
assert.ok(
|
||||
exists(".btn[aria-label='Notify']"),
|
||||
|
|
|
@ -40,7 +40,7 @@ acceptance("Topic", function (needs) {
|
|||
test("Reply as new topic", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("button.share:nth-of-type(1)");
|
||||
await click(".reply-as-new-topic a");
|
||||
await click("button.new-topic");
|
||||
|
||||
assert.ok(exists(".d-editor-input"), "the composer input is visible");
|
||||
|
||||
|
@ -59,7 +59,7 @@ acceptance("Topic", function (needs) {
|
|||
test("Reply as new message", async function (assert) {
|
||||
await visit("/t/pm-for-testing/12");
|
||||
await click("button.share:nth-of-type(1)");
|
||||
await click(".reply-as-new-topic a");
|
||||
await click("button.new-topic");
|
||||
|
||||
assert.ok(exists(".d-editor-input"), "the composer input is visible");
|
||||
|
||||
|
|
|
@ -838,166 +838,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.create-invite-modal,
|
||||
.share-topic-modal {
|
||||
.input-group {
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
textarea#invite-message,
|
||||
&.invite-to-topic input[type="text"],
|
||||
.group-chooser,
|
||||
.user-chooser,
|
||||
.future-date-input-selector {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.invite-to-topic input[type="radio"] {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
label .d-icon {
|
||||
color: var(--primary-medium);
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group input[type="text"],
|
||||
.input-group .btn,
|
||||
.user-chooser .select-kit-header,
|
||||
.future-date-input .select-kit-header {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.invite-input-with-button {
|
||||
display: flex;
|
||||
|
||||
.btn {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group.input-expires-at,
|
||||
.input-group.input-email,
|
||||
.input-group.invite-max-redemptions {
|
||||
margin-bottom: 0;
|
||||
|
||||
input[type="text"] {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.future-date-input {
|
||||
.date-picker-wrapper {
|
||||
input {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.control-group:nth-child(2),
|
||||
.control-group:nth-child(3) {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
width: 49%;
|
||||
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-group.input-email {
|
||||
align-items: baseline;
|
||||
display: flex;
|
||||
|
||||
label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.invite-input-with-button {
|
||||
display: inline-flex;
|
||||
flex: 1;
|
||||
|
||||
input[type="text"] {
|
||||
flex: 1;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.invite-max-redemptions {
|
||||
label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.invite-to-topic {
|
||||
#choose-topic-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.show-advanced {
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.create-invite-modal {
|
||||
.input-group {
|
||||
textarea#invite-message,
|
||||
&.invite-to-topic input[type="text"],
|
||||
.group-chooser,
|
||||
.user-chooser,
|
||||
.future-date-input-selector {
|
||||
margin-left: 25px;
|
||||
width: calc(100% - 25px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-topic-modal {
|
||||
form {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.sources {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
button {
|
||||
margin-right: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.share-twitter {
|
||||
.d-icon {
|
||||
color: var(--twitter);
|
||||
}
|
||||
}
|
||||
.share-facebook {
|
||||
.d-icon {
|
||||
color: var(--facebook);
|
||||
}
|
||||
}
|
||||
|
||||
.invite-users {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group-add-members-modal {
|
||||
.input-group {
|
||||
margin-bottom: 0.5em;
|
||||
|
|
|
@ -1,26 +1,80 @@
|
|||
// styles that apply to the "share" popup when sharing a link to a post or topic
|
||||
// styles that apply to the "share" modal & popup when sharing a link to a post or topic
|
||||
|
||||
.share-link-container {
|
||||
display: flex;
|
||||
button {
|
||||
transition-property: background-color, color; // don't transition outline
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
font-size: var(--font-up-1);
|
||||
margin-bottom: 0;
|
||||
&:focus + button {
|
||||
outline: 1px solid var(--tertiary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-link-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
margin-top: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.sources {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.new-topic {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.alt-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.share-twitter {
|
||||
.d-icon {
|
||||
color: var(--twitter);
|
||||
}
|
||||
}
|
||||
.share-facebook {
|
||||
.d-icon {
|
||||
color: var(--facebook);
|
||||
}
|
||||
}
|
||||
|
||||
// post share popup
|
||||
|
||||
#share-link {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
z-index: z("dropdown");
|
||||
box-shadow: shadow("card");
|
||||
background-color: var(--secondary);
|
||||
padding: 8px 8px 4px 8px;
|
||||
padding: 0.5em;
|
||||
width: 300px;
|
||||
display: none;
|
||||
&.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 0.5em;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
font-size: $font-0;
|
||||
|
@ -30,74 +84,166 @@
|
|||
.date {
|
||||
font-weight: normal;
|
||||
color: var(--primary-med-or-secondary-med);
|
||||
}
|
||||
}
|
||||
|
||||
.copy-text {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
margin: 5px 5px 5px 15px;
|
||||
color: var(--success);
|
||||
opacity: 1;
|
||||
transition: opacity 0.25s;
|
||||
font-size: $font-0;
|
||||
&:not(.success) {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.social-link {
|
||||
margin-right: 8px;
|
||||
font-size: $font-up-4;
|
||||
.d-icon {
|
||||
color: var(--tertiary-or-white);
|
||||
}
|
||||
.d-icon-fab-facebook {
|
||||
// Adheres to Facebook brand guidelines
|
||||
color: var(--facebook-or-white);
|
||||
}
|
||||
.d-icon-fab-twitter-square {
|
||||
// Adheres to Twitter brand guidelines
|
||||
color: var(--twitter-or-white);
|
||||
}
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
font-size: $font-up-1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
margin-top: 8px;
|
||||
|
||||
.sources {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
max-width: 45%;
|
||||
|
||||
.social-link {
|
||||
margin-right: 8px;
|
||||
}
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.alt-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
height: 36px;
|
||||
|
||||
.close-share {
|
||||
font-size: $font-up-3;
|
||||
color: var(--primary-med-or-secondary-med);
|
||||
}
|
||||
|
||||
.new-topic {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.btn.close {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// topic share modal
|
||||
|
||||
.share-topic-modal {
|
||||
form {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.invite-users {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 1.5em 0 0.25em;
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notify-user-input {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
|
||||
.select-kit {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.multi-select-header {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select-kit.multi-select .choices {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.select-kit.multi-select.is-expanded + button {
|
||||
outline: 1px solid var(--tertiary); // outline the button when the input is outlined, to match height
|
||||
}
|
||||
}
|
||||
|
||||
// topic invite modal
|
||||
|
||||
.create-invite-modal {
|
||||
form {
|
||||
margin: 0;
|
||||
input[type="text"],
|
||||
.btn,
|
||||
.select-kit-header {
|
||||
height: 2.27rem;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-right: 0.5em;
|
||||
.d-icon {
|
||||
color: var(--primary-medium);
|
||||
margin-right: 0.75em;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-group:not(:last-of-type) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.input-group.input-expires-at,
|
||||
.input-group.input-email,
|
||||
.input-group.invite-max-redemptions {
|
||||
input[type="text"] {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.existing-topic,
|
||||
p {
|
||||
// p is for "no topics found"
|
||||
margin-left: 1.75em;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.future-date-input {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
.control-group:nth-child(1) {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;
|
||||
}
|
||||
.control-group:nth-child(2) {
|
||||
margin-left: 1.75em;
|
||||
margin-right: 1.5em;
|
||||
}
|
||||
.control-group:nth-child(2),
|
||||
.control-group:nth-child(3) {
|
||||
grid-row-start: 2;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
input {
|
||||
height: 100%;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0.5em;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-group.input-email {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
label {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.invite-email-container {
|
||||
flex: 1 1 auto;
|
||||
#invite-email {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.invite-max-redemptions {
|
||||
label {
|
||||
display: inline;
|
||||
}
|
||||
input {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.show-advanced {
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
textarea#invite-message,
|
||||
&.invite-to-topic input[type="text"],
|
||||
.group-chooser,
|
||||
.user-chooser,
|
||||
.future-date-input-selector {
|
||||
margin-left: 1.75em;
|
||||
width: calc(100% - 1.75em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue