0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Improved newsletter dragging

refs https://github.com/TryGhost/Team/issues/1582

- The draggable object container was too small and didn't include the drag handle
- Increased the size of the draggable object to include the drag handle by adding a container div
- The drag handle now doesn't require you to hover the card before becoming visible
- Fixed a bug where some newsletters would show the drag handle even when they were not hovered when you were dragging a different newsletter. When dragging, now only the dragged newsletter will show the drag handle, so it is more clear where you are dragging to.
- Fixed fading animation of the drag handle (visibilty animation needed step-start and step-end added)
- Fixed jumpiness when dragging or moving the last newsletter card, due to animated margin updates after a drag
- Fixed padding issue for newsletter cards on smaller devices (padding did increase) breaking the animation
This commit is contained in:
Simon Backx 2022-05-06 13:56:05 +02:00
parent 9af743ff3f
commit 089686132c
2 changed files with 108 additions and 89 deletions

View file

@ -47,78 +47,79 @@
>
{{#each this.filteredNewsletters as |newsletter|}}
<DraggableObject
class="gh-main-content-card gh-newsletter-card {{if (and (eq newsletter.status "active") (not this.displayingDefault)) "gh-newsletter-card-draggable"}} {{unless this.displayingDefault "multiple"}}"
class="gh-newsletter-card-container {{if (and (eq newsletter.status "active") (not this.displayingDefault)) "gh-newsletter-card-draggable"}} {{unless this.displayingDefault "multiple"}}"
@content={{newsletter}}
@dragHandle=".grab-newsletter"
@isSortable={{true}}
>
{{svg-jar "grab" class="grab-newsletter"}}
{{#if this.displayingDefault}}
<div class="gh-newsletter-card-block title-block">
<h3 class="gh-newsletter-card-name">
{{newsletter.name}}
</h3>
<p class="gh-newsletter-card-description">
{{newsletter.description}}
</p>
</div>
{{else}}
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="gh-newsletter-card-block title-block">
<h3 class="gh-newsletter-card-name">
{{newsletter.name}}
</h3>
<p class="gh-newsletter-card-description">
{{newsletter.description}}
</p>
</LinkTo>
{{/if}}
{{#if (feature "multipleNewslettersUI")}}
<div class="gh-newsletter-card-block stats-block {{unless this.displayingDefault "multiple"}}">
<div>
<h3 class="gh-newsletter-card-name">{{newsletter.count.members}}</h3>
<p class="gh-newsletter-card-description">Subscribers</p>
</div>
<div>
<h3 class="gh-newsletter-card-name">{{newsletter.count.posts}}</h3>
<p class="gh-newsletter-card-description">Posts sent</p>
</div>
</div>
{{/if}}
<div class="gh-newsletter-card-block cta-block">
<div class="gh-main-content-card gh-newsletter-card">
{{#if this.displayingDefault}}
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="gh-btn gh-btn-green" data-test-button="customize-newsletter"><span>Customize &rarr;</span></LinkTo>
<div class="gh-newsletter-card-block title-block">
<h3 class="gh-newsletter-card-name">
{{newsletter.name}}
</h3>
<p class="gh-newsletter-card-description">
{{newsletter.description}}
</p>
</div>
{{else}}
<GhBasicDropdown @verticalPosition="below" @horizontalPosition="right" @renderInPlace={{true}} as |dd|>
<dd.Trigger class="gh-btn gh-btn-action-icon gh-btn-icon gh-btn-outline gh-product-card-actions-button icon-only">
<span data-test-newsletter-menu-trigger>
{{svg-jar "dotdotdot"}}
<span class="hidden">Actions</span>
</span>
</dd.Trigger>
<dd.Content class="relative-dropdown-menu gh-newsletter-actions-menu">
<ul class="dropdown-menu dropdown-triangle-top-right" role="listbox" {{css-transition "anim-fade-in-scale"}}>
<li>
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="mr2" data-test-button="customize-newsletter"><span>Edit</span></LinkTo>
</li>
{{#if (eq newsletter.status "active")}}
<li>
<button class="mr2" type="button" {{on "click" (fn this.archiveNewsletter newsletter)}}>
<span>Archive</span>
</button>
</li>
{{/if}}
{{#if (eq newsletter.status "archived")}}
<li>
<button class="mr2" type="button" {{on "click" (fn this.unarchiveNewsletter newsletter)}}>
<span>Reactivate</span>
</button>
</li>
{{/if}}
</ul>
</dd.Content>
</GhBasicDropdown>
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="gh-newsletter-card-block title-block">
<h3 class="gh-newsletter-card-name">
{{newsletter.name}}
</h3>
<p class="gh-newsletter-card-description">
{{newsletter.description}}
</p>
</LinkTo>
{{/if}}
{{#if (feature "multipleNewslettersUI")}}
<div class="gh-newsletter-card-block stats-block {{unless this.displayingDefault "multiple"}}">
<div>
<h3 class="gh-newsletter-card-name">{{newsletter.count.members}}</h3>
<p class="gh-newsletter-card-description">Subscribers</p>
</div>
<div>
<h3 class="gh-newsletter-card-name">{{newsletter.count.posts}}</h3>
<p class="gh-newsletter-card-description">Posts sent</p>
</div>
</div>
{{/if}}
<div class="gh-newsletter-card-block cta-block">
{{#if this.displayingDefault}}
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="gh-btn gh-btn-green" data-test-button="customize-newsletter"><span>Customize &rarr;</span></LinkTo>
{{else}}
<GhBasicDropdown @verticalPosition="below" @horizontalPosition="right" @renderInPlace={{true}} as |dd|>
<dd.Trigger class="gh-btn gh-btn-action-icon gh-btn-icon gh-btn-outline gh-product-card-actions-button icon-only">
<span data-test-newsletter-menu-trigger>
{{svg-jar "dotdotdot"}}
<span class="hidden">Actions</span>
</span>
</dd.Trigger>
<dd.Content class="relative-dropdown-menu gh-newsletter-actions-menu">
<ul class="dropdown-menu dropdown-triangle-top-right" role="listbox" {{css-transition "anim-fade-in-scale"}}>
<li>
<LinkTo @route="settings.newsletters.edit-newsletter" @model={{newsletter.id}} class="mr2" data-test-button="customize-newsletter"><span>Edit</span></LinkTo>
</li>
{{#if (eq newsletter.status "active")}}
<li>
<button class="mr2" type="button" {{on "click" (fn this.archiveNewsletter newsletter)}}>
<span>Archive</span>
</button>
</li>
{{/if}}
{{#if (eq newsletter.status "archived")}}
<li>
<button class="mr2" type="button" {{on "click" (fn this.unarchiveNewsletter newsletter)}}>
<span>Reactivate</span>
</button>
</li>
{{/if}}
</ul>
</dd.Content>
</GhBasicDropdown>
{{/if}}
</div>
</div>
</DraggableObject>
{{else}}

View file

@ -908,10 +908,20 @@
.gh-newsletters .gh-expandable-block {
padding: 24px;
/* Correct last card margin by reducing bottom padding */
padding-bottom: 12px;
}
.gh-newsletter-card-container {
margin-left: -24px;
padding-left: 24px;
position: relative;
}
.gh-newsletters .gh-main-content-card:last-of-type {
margin-bottom: 0;
/* Note that we need to keep the margin of the cards consistent, or they'll jump when we drag the cards to sort them */
margin-bottom: 12px;
}
.gh-newsletter-card {
@ -919,48 +929,56 @@
display: flex;
align-items: center;
justify-content: space-between;
transition: margin 125ms ease-in-out, padding 125ms ease-in-out;
}
.gh-newsletter-card[draggable="true"] {
/* required to avoid background being picked up when dragging */
.gh-newsletter-card-container[draggable="true"] {
/* required to avoid background being picked up when dragging (Chrome only) */
z-index: 1;
}
.gh-newsletter-card-draggable:hover {
margin-left: 4px;
padding-left: 20px;
}
.gh-newsletter-card .grab-newsletter {
display: none;
}
.gh-newsletter-card-draggable .grab-newsletter {
display: inline-block;
}
@media (max-width: 980px) {
.gh-newsletter-card {
padding: 4vmin 48px;
}
}
.gh-newsletter-card .grab-newsletter {
.gh-newsletter-card-container .grab-newsletter {
visibility: hidden;
position: absolute;
top: 0;
left: -20px;
left: 8px;
width: 2rem;
height: 100%;
padding-right: 2px;
fill: var(--lightgrey-d2);
cursor: move;
opacity: 0;
transition: visibility 0s, opacity 200ms ease-in-out;
transition: visibility 200ms step-end, opacity 200ms ease-in-out;
}
.gh-newsletter-card.multiple:hover .grab-newsletter {
.gh-newsletter-card {
transition: margin 125ms ease-in-out, padding 125ms ease-in-out;
}
/*
When dragging, the :hover selector could be on the wrong element. So we explicitly ignore :hover when we are dragging and switch to the .is-dragging-object
*/
body:not([data-user-is-dragging]) .gh-newsletter-card-draggable:hover .gh-newsletter-card, .gh-newsletter-card-draggable.is-dragging-object .gh-newsletter-card {
margin-left: 4px;
padding-left: 20px;
}
body:not([data-user-is-dragging]) .gh-newsletter-card-draggable:hover .grab-newsletter, .gh-newsletter-card-draggable.is-dragging-object .grab-newsletter {
visibility: visible;
opacity: 1;
/*
To make sure the grab handler also fades out correctly and only change visibility after the animation,
we need to update the animation curve for visibility to step-start at the start of the animation
*/
transition: visibility 200ms step-start, opacity 200ms ease-in-out;
}
.gh-newsletter-card-container .grab-newsletter {
display: none;
}
.gh-newsletter-card-draggable .grab-newsletter {
display: inline-block;
}
.gh-newsletter-card-block.title-block {