Adding in sticky headers to posts and pages behind a feature flag

- Adding sticky headers so columns are easier to read and parse
- These are working only behind the feature flag
- Checked against narrower viewports and dark mode

refs https://github.com/TryGhost/Team/issues/1837
This commit is contained in:
James Morris 2022-08-24 15:46:39 +01:00
parent f124d142c9
commit e9813150eb
6 changed files with 112 additions and 80 deletions

View File

@ -771,6 +771,10 @@ input:focus,
background: var(--whitegrey);
}
.gh-list-nodata {
color: #5b6167;
}
.gh-content-status-published {
background: var(--whitegrey-l1);
}
@ -964,6 +968,12 @@ input:focus,
border-top: 1px solid var(--hairline-color-1);
}
@media (max-width: 1200px) {
.gh-list-data {
border-top: 0 none;
}
}
/* Members */
.gh-members-help-card,
.gh-offers-help-card {

View File

@ -58,17 +58,23 @@ ul.nostyle li {
white-space: nowrap;
}
.posts-list .gh-list-row.header,
.pages-list .gh-list-row.header {
position: sticky;
background: var(--white);
z-index: 2;
top: 0;
}
.gh-list-row.header.empty .gh-list-header {
padding: 0;
}
.gh-list:not(.tabbed) .gh-list-header:first-child {
border-top-left-radius: 5px;
padding-left: 0;
}
.gh-list:not(.tabbed) .gh-list-header:last-child {
border-top-right-radius: 5px;
padding-right: 16px;
}
@ -387,6 +393,7 @@ ul.nostyle li {
}
/* Horizontally scrolling list */
.gh-list-sticky,
.gh-list-scrolling {
position: relative;
overflow: auto;
@ -486,6 +493,7 @@ ul.nostyle li {
}
@media (max-width: 800px) {
.gh-list-sticky,
.gh-list-scrolling {
max-width: calc(100% + 8vw);
height: calc(100vh - 193px);
@ -497,6 +505,7 @@ ul.nostyle li {
}
@media (min-width: 1450px) {
.gh-list-sticky,
.gh-list-scrolling {
height: calc(100vh - 96px);
}

View File

@ -598,7 +598,8 @@
padding: 0 0.33em;
}
.posts-list .gh-list-nodata {
.posts-list .gh-list-nodata,
.pages-list .gh-list-nodata {
display: none;
}
}

View File

@ -1078,6 +1078,10 @@
max-width: var(--main-layout-content-maxwidth);
}
.gh-canvas.gh-canvas-sticky {
padding-bottom: 0; /* No padding needed when tables are sticky */
}
.gh-canvas.circle-bg::before {
position: absolute;
display: block;
@ -1558,6 +1562,10 @@
padding-bottom: var(--main-layout-area-padding);
}
.gh-canvas-sticky .view-container {
padding-bottom: 0;
}
.view-content {
padding: 20px;
}

View File

@ -1,4 +1,4 @@
<section class="gh-canvas">
<section class="gh-canvas gh-canvas-sticky">
<GhCanvasHeader class="gh-canvas-header break tablet post-header">
<GhCustomViewTitle @title="Pages" @query={{reset-query-params "posts"}} />
@ -27,41 +27,43 @@
</GhCanvasHeader>
<section class="view-container content-list">
<ol class="pages-list gh-list {{unless this.postsInfinityModel "no-posts"}} {{if this.feature.memberAttribution 'feature-memberAttribution'}}">
{{#if this.postsInfinityModel}}
<li class="gh-list-row header">
<div class="gh-list-header gh-posts-title-header">Title</div>
<div class="gh-list-header gh-posts-status-header">{{#unless this.feature.memberAttribution}}Status{{/unless}}</div>
{{#if this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-signups-header">Signups</div>
<div class="gh-list-header gh-posts-conversions-header">Conversions</div>
{{/if}}
</li>
{{/if}}
{{#each this.postsInfinityModel as |page|}}
<GhPostsListItem
@post={{page}}
data-test-page-id={{page.id}} />
{{else}}
<li class="no-posts-box">
<div class="no-posts">
{{#if this.showingAll}}
{{svg-jar "pages-placeholder" class="gh-pages-placeholder"}}
<h4>Tell the world about yourself.</h4>
<LinkTo @route="editor.new" @model="page" class="gh-btn gh-btn-green">
<span>Create a new page</span>
</LinkTo>
{{else}}
<h4>No pages match the current filter</h4>
<LinkTo @route="pages" @query={{hash type=null author=null tag=null}} class="gh-btn">
<span>Show all pages</span>
</LinkTo>
<div class="{{if this.feature.memberAttribution 'gh-list-sticky'}}">
<ol class="pages-list gh-list {{unless this.postsInfinityModel "no-posts"}} {{if this.feature.memberAttribution 'feature-memberAttribution'}}">
{{#if this.postsInfinityModel}}
<li class="gh-list-row header">
<div class="gh-list-header gh-posts-title-header">Title</div>
<div class="gh-list-header gh-posts-status-header">{{#unless this.feature.memberAttribution}}Status{{/unless}}</div>
{{#if this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-signups-header">Signups</div>
<div class="gh-list-header gh-posts-conversions-header">Conversions</div>
{{/if}}
</div>
</li>
{{/each}}
</ol>
</li>
{{/if}}
{{#each this.postsInfinityModel as |page|}}
<GhPostsListItem
@post={{page}}
data-test-page-id={{page.id}} />
{{else}}
<li class="no-posts-box">
<div class="no-posts">
{{#if this.showingAll}}
{{svg-jar "pages-placeholder" class="gh-pages-placeholder"}}
<h4>Tell the world about yourself.</h4>
<LinkTo @route="editor.new" @model="page" class="gh-btn gh-btn-green">
<span>Create a new page</span>
</LinkTo>
{{else}}
<h4>No pages match the current filter</h4>
<LinkTo @route="pages" @query={{hash type=null author=null tag=null}} class="gh-btn">
<span>Show all pages</span>
</LinkTo>
{{/if}}
</div>
</li>
{{/each}}
</ol>
</div>
<GhInfinityLoader
@infinityModel={{this.postsInfinityModel}}

View File

@ -1,4 +1,4 @@
<section class="gh-canvas">
<section class="gh-canvas gh-canvas-sticky">
<GhCanvasHeader class="gh-canvas-header break tablet post-header">
<GhCustomViewTitle @title={{if this.session.user.isContributor (concat this.config.blogTitle " posts") "Posts"}} @query={{reset-query-params "posts"}} />
@ -27,48 +27,50 @@
</GhCanvasHeader>
<section class="view-container content-list">
<ol class="posts-list gh-list {{unless this.postsInfinityModel "no-posts"}} {{if this.feature.memberAttribution 'feature-memberAttribution'}}">
{{#if this.postsInfinityModel}}
<li class="gh-list-row header">
<div class="gh-list-header gh-posts-title-header">Title</div>
{{#if this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-status-header"></div>
<div class="gh-list-header gh-posts-signups-header">Signups</div>
<div class="gh-list-header gh-posts-conversions-header">Paid</div>
{{/if}}
{{#if (and (not-eq this.settings.membersSignupAccess "none") (not-eq this.settings.editorDefaultEmailRecipients "disabled") (not this.session.user.isContributor) this.feature.emailAnalytics)}}
<div class="gh-list-header gh-posts-sends-header">Sends</div>
<div class="gh-list-header gh-posts-opens-header">Opens</div>
{{/if}}
{{#unless this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-status-header">Status</div>
{{/unless}}
</li>
{{/if}}
<div class="{{if this.feature.memberAttribution 'gh-list-sticky'}}">
<ol class="posts-list gh-list {{unless this.postsInfinityModel "no-posts"}} {{if this.feature.memberAttribution 'feature-memberAttribution'}}">
{{#if this.postsInfinityModel}}
<li class="gh-list-row header">
<div class="gh-list-header gh-posts-title-header">Title</div>
{{#if this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-status-header"></div>
<div class="gh-list-header gh-posts-signups-header">Signups</div>
<div class="gh-list-header gh-posts-conversions-header">Paid</div>
{{/if}}
{{#if (and (not-eq this.settings.membersSignupAccess "none") (not-eq this.settings.editorDefaultEmailRecipients "disabled") (not this.session.user.isContributor) this.feature.emailAnalytics)}}
<div class="gh-list-header gh-posts-sends-header">Sends</div>
<div class="gh-list-header gh-posts-opens-header">Opens</div>
{{/if}}
{{#unless this.feature.memberAttribution}}
<div class="gh-list-header gh-posts-status-header">Status</div>
{{/unless}}
</li>
{{/if}}
{{#each this.postsInfinityModel as |post|}}
<GhPostsListItem
@post={{post}}
data-test-post-id={{post.id}} />
{{else}}
<li class="no-posts-box">
<div class="no-posts">
{{#if this.showingAll}}
{{svg-jar "posts-placeholder" class="gh-posts-placeholder"}}
<h4>Start creating content.</h4>
<LinkTo @route="editor.new" @model="post" class="gh-btn gh-btn-green">
<span>Write a new post</span>
</LinkTo>
{{else}}
<h4>No posts match the current filter</h4>
<LinkTo @route="posts" @query={{hash type=null author=null tag=null}} class="gh-btn">
<span>Show all posts</span>
</LinkTo>
{{/if}}
</div>
</li>
{{/each}}
</ol>
{{#each this.postsInfinityModel as |post|}}
<GhPostsListItem
@post={{post}}
data-test-post-id={{post.id}} />
{{else}}
<li class="no-posts-box">
<div class="no-posts">
{{#if this.showingAll}}
{{svg-jar "posts-placeholder" class="gh-posts-placeholder"}}
<h4>Start creating content.</h4>
<LinkTo @route="editor.new" @model="post" class="gh-btn gh-btn-green">
<span>Write a new post</span>
</LinkTo>
{{else}}
<h4>No posts match the current filter</h4>
<LinkTo @route="posts" @query={{hash type=null author=null tag=null}} class="gh-btn">
<span>Show all posts</span>
</LinkTo>
{{/if}}
</div>
</li>
{{/each}}
</ol>
</div>
<GhInfinityLoader
@infinityModel={{this.postsInfinityModel}}