Skip to content

Commit 4e1737d

Browse files
elastic.co/guide/* redesign (#2478)
* get basic sticky nav and highlighting working * remove unused code * sticky toc, updated toc style, refine otp highlighting * adjust otp styles * add book_title styles * remove book title div * Update resources/web/template.html * use chevron icons instead of plus icons fix current_page_parent * style index page * unstick on narrow screens check on various screen sizes * remove chevron icon from book_title * use overflow auto * remove redundant font-size that was resolving to 85% of 85% * remove dupe CSS; scroll to active TOC element * revert bootstrap.css change * remove console.log * revert link color bug; swap to `container-fluid` * fix `scrollIntoView()` bug on widths <769px * Update resources/web/style/on_this_page.pcss * fix padding bug * limit width of text in collapsible toc groups * remove z-index from sticky classes * address feedback from @chandlerprall * use scrollTop instead of scrollIntoView * clean up code comments * fix `Uncaught TypeError` and variable spelling Co-authored-by: Colleen McGinnis <colleen.mcginnis@elastic.co>
1 parent 54bd6b0 commit 4e1737d

11 files changed

+284
-60
lines changed

resources/web/docs_js/index.js

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ import "../../../../../node_modules/details-polyfill";
1919
// Add support for URLSearchParams Web API in IE
2020
import "../../../../../node_modules/url-search-params-polyfill";
2121

22-
export function init_headers(right_col, lang_strings) {
22+
// Vocab:
23+
// TOC = table of contents
24+
// OTP = on this page
25+
export function init_headers(sticky_content, lang_strings) {
2326
// Add on-this-page block
24-
var this_page = $('<div id="this_page"></div>').prependTo(right_col);
25-
this_page.append('<h2>' + lang_strings('On this page') + '</h2>');
27+
var this_page = $('<div id="this_page"></div>').prependTo(sticky_content);
28+
this_page.append('<p id="otp" class="aside-heading">' + lang_strings('On this page') + '</p>');
2629
var ul = $('<ul></ul>').appendTo(this_page);
2730
var items = 0;
2831
var baseHeadingLevel = 0;
@@ -57,7 +60,7 @@ export function init_headers(right_col, lang_strings) {
5760
.remove();
5861
var text = title_container.html();
5962
const adjustedLevel = hLevel - baseHeadingLevel;
60-
const li = '<li class="heading-level-' + adjustedLevel + '"><a href="#' + this.id + '">' + text + '</a></li>';
63+
const li = '<li id="otp-text-' + i + '" class="heading-level-' + adjustedLevel + '"><a href="#' + this.id + '">' + text + '</a></li>';
6164
ul.append(li);
6265
}
6366
}
@@ -170,6 +173,44 @@ function init_toc(lang_strings) {
170173
});
171174
}
172175

176+
// In the OTP, highlight the heading of the section that is
177+
// currently visible on the page.
178+
// If more than one is visible, highlight the heading for the
179+
// section that is higher on the page.
180+
function highlight_otp() {
181+
let visibleHeadings = []
182+
const observer = new IntersectionObserver(entries => {
183+
entries.forEach(entry => {
184+
const id = entry.target.getAttribute('id');
185+
const element = document.querySelector(`#sticky_content #this_page a[href="#${id}"]`);
186+
const itemId = $(element).parent().attr('id')
187+
// All heading elements have an `entry` (even the title).
188+
// The title does not exist in the OTP, so we must exclude it.
189+
// Checking for the existence of `itemId` ensures we don't parse elements that don't exist.
190+
if (itemId){
191+
const itemNumber = parseInt(itemId.match(/\d+/)[0], 10);
192+
if (entry.intersectionRatio > 0){
193+
visibleHeadings.push(itemNumber);
194+
} else {
195+
const position = visibleHeadings.indexOf(itemNumber);
196+
visibleHeadings.splice(position, 1)
197+
}
198+
if (visibleHeadings.length > 0) {
199+
visibleHeadings.sort((a, b) => a - b)
200+
// Remove existing active classes
201+
$('a.active').removeClass("active");
202+
// Add active class to the first visible heading
203+
$('#otp-text-' + visibleHeadings[0] + ' > a').addClass('active')
204+
}
205+
}
206+
})
207+
})
208+
209+
document.querySelectorAll('#guide a[id]').forEach((heading) => {
210+
observer.observe(heading);
211+
})
212+
}
213+
173214
// Main function, runs on DOM ready
174215
$(function() {
175216
var lang = $('section#guide[lang]').attr('lang') || 'en';
@@ -228,7 +269,16 @@ $(function() {
228269

229270
AlternativeSwitcher(store());
230271

231-
var right_col = $('#right_col'); // Move rtp container to top right and make visible
272+
// Move rtp container to top right and make visible
273+
var sticky_content = $('#sticky_content');
274+
// Left column that contains the TOC
275+
var left_col = $('#left_col');
276+
// Middle column that contains the main content
277+
var middle_col = $('#middle_col');
278+
// Right column that contains the OTP and demand gen content
279+
var right_col = $('#right_col');
280+
// Empty column below TOC on small screens so the demand gen content can be positioned under the main content
281+
var bottom_left_col = $('#bottom_left_col');
232282

233283
$('.page_header > a[href="../current/index.html"]').click(function() {
234284
utils.get_current_page_in_version('current');
@@ -271,14 +321,24 @@ $(function() {
271321
if (div.length == 0 && $('#guide').find('div.article,div.book').length == 0) {
272322
var url = location.href.replace(/[^\/]+$/, 'toc.html');
273323
var toc = $.get(url, {}, function(data) {
274-
right_col.append(data);
324+
left_col.append(data);
275325
init_toc(LangStrings);
276326
utils.open_current(location.pathname);
277327
}).always(function() {
278-
init_headers(right_col, LangStrings);
328+
init_headers(sticky_content, LangStrings);
329+
highlight_otp();
279330
});
280331
} else {
281332
init_toc(LangStrings);
333+
// Style book landing page (no main content, just a TOC and demand gen content)
334+
335+
// Set the width of the left column to zero
336+
left_col.removeClass().addClass('col-0');
337+
bottom_left_col.removeClass().addClass('col-0');
338+
// Set the width of the middle column (containing the TOC) to 9
339+
middle_col.removeClass().addClass('col-12 col-lg-9 guide-section');
340+
// Set the width of the demand gen content to 3
341+
right_col.removeClass().addClass('col-12 col-lg-3 sticky-top-md h-almost-full-lg');
282342
}
283343

284344
PR.prettyPrint();
@@ -299,6 +359,26 @@ $(function() {
299359
$('a.edit_me_private').show();
300360
}
301361

362+
// scroll to selected TOC element; if it doesn't exist yet, wait and try again
363+
// window.width must match the breakpoint of `.sticky-top-md`
364+
if($(window).width() >= 769){
365+
var scrollToSelectedTOC = setInterval(() => {
366+
if ($('.current_page').length) {
367+
// Get scrollable element
368+
var container = document.querySelector("#left_col");
369+
// Get active table of contents element
370+
var activeItem = document.querySelector(".current_page")
371+
// If the top of the active item is out of view (or in the bottom 100px of the visible portion of the TOC)
372+
// scroll so the top of the active item is at the top of the visible portion TOC
373+
if (container.offsetHeight - 100 <= activeItem.offsetTop) {
374+
// Scroll to active item
375+
container.scrollTop = activeItem.offsetTop
376+
}
377+
clearInterval(scrollToSelectedTOC);
378+
}
379+
}, 150);
380+
}
381+
302382
// Test comment used to detect unminifed JS in tests
303383
});
304384

resources/web/docs_js/utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function open_current(pathname) {
1818
var page = pathname.match(/[^\/]+$/)[0];
1919
var current = $('div.toc a[href="' + page + '"]');
2020
current.addClass('current_page');
21+
current.parent().parent().addClass('current_page_li');
2122
current.parentsUntil('ul.toc', 'li.collapsible').addClass('show');
2223
}
2324

resources/web/style/base_styles.pcss

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,60 @@
3030
details {
3131
margin-bottom: 1.15em;
3232
}
33+
34+
.container-fluid {
35+
@media screen and (min-width: 1560px) {
36+
max-width: 1500px;
37+
}
38+
}
39+
40+
.sticky-top-md {
41+
position: -webkit-relative;
42+
position: relative;
43+
@media screen and (min-width: 769px) {
44+
position: -webkit-sticky;
45+
position: sticky;
46+
top: 0;
47+
}
48+
}
49+
50+
.sticky-top-lg {
51+
position: -webkit-relative;
52+
position: relative;
53+
@media screen and (min-width: 993px) {
54+
position: -webkit-sticky;
55+
position: sticky;
56+
top: 0;
57+
}
58+
}
59+
60+
.h-almost-full-md {
61+
@media screen and (min-width: 769px) {
62+
height: 95vh;
63+
}
64+
}
65+
66+
.h-almost-full-lg {
67+
@media screen and (min-width: 993px) {
68+
height: 95vh;
69+
}
70+
}
71+
72+
#left_col {
73+
overflow: auto;
74+
}
75+
76+
.aside-heading {
77+
font-weight: 600;
78+
margin-top: 20px;
79+
margin-bottom: 10px;
80+
}
81+
82+
.media-type {
83+
opacity: 0.6;
84+
text-transform: uppercase;
85+
font-size: 80%;
86+
font-weight: 400;
87+
margin-bottom: 0px;
88+
}
3389
}

resources/web/style/docbook.pcss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@
1818
.guide-section {
1919
margin-bottom: 30px;
2020
}
21+
22+
#sticky_content {
23+
padding-bottom: 30px;
24+
}

resources/web/style/heading.pcss

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,11 @@
7777
background-image: inline("img/edit-me-private.png");
7878
display: none;
7979
}
80-
}
80+
81+
/* Titlepage headings don't need large gaps around them */
82+
.titlepage {
83+
.title {
84+
margin: 10px 0 16px;
85+
}
86+
}
87+
}

resources/web/style/link.pcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#guide {
22
a {
3-
color: #00a9e5;
3+
color: #0077CC;
44
font-weight: normal;
55
text-decoration: none;
66
outline: none;

resources/web/style/on_this_page.pcss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55

66
.heading-level-1 {
77
display: block;
8-
padding-left: 1.5em !important;
8+
padding-left: 1em !important;
99
}
1010

1111
.heading-level-2 {
1212
display: block;
13-
padding-left: 3em !important;
13+
padding-left: 2em !important;
1414
}
1515

1616
.heading-level-3 {
1717
display: block;
18-
padding-left: 4.5em !important;
18+
padding-left: 3em !important;
1919
}
2020
}

resources/web/style/rtpcontainer.pcss

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
* on the rtpcontainer in general. */
66
#rtpcontainer {
77
.mktg-promo {
8-
margin: 55px 0 30px;
9-
padding: 32px;
10-
border: 1px solid #d4dae5;
8+
padding: 12px;
119
}
1210
h3 {
1311
margin: 5px 0;
@@ -47,7 +45,7 @@
4745
li {
4846
align-items: center;
4947
list-style: none;
50-
min-height: 50px;
48+
min-height: 30px;
5149
padding-left: 0.6em;
5250
display: flex;
5351
font-size: 14px;

resources/web/style/this_page.pcss

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#this_page {
2-
margin-bottom: 0;
3-
padding-left: 1em;
2+
padding-bottom: 20px;
3+
display: block;
4+
border-bottom: 1px solid #dee2e6;
5+
max-height:40vh;
6+
overflow: auto;
7+
@media screen and (max-width: 992px) {
8+
display: none;
9+
}
410
h2 {
511
font-size: 1.5em;
612
line-height: 1.5em;
@@ -13,6 +19,11 @@
1319
}
1420
li {
1521
line-height: 1.2em;
16-
margin-bottom: .5em;
22+
margin-top: .3em;
23+
margin-bottom: .3em;
24+
}
25+
.active {
26+
font-weight: 700;
27+
font-style: ul;
1728
}
1829
}

0 commit comments

Comments
 (0)