Skip to content

Commit 75b8c38

Browse files
authored
Unrolled build for rust-lang#115660
Rollup merge of rust-lang#115660 - notriddle:notriddle/sidebar-resize, r=GuillaumeGomez rustdoc: allow resizing the sidebar / hiding the top bar Fixes rust-lang#97306 Preview: http://notriddle.com/rustdoc-html-demo-4/sidebar-resize/std/index.html ![image](https://github.com/rust-lang/rust/assets/1593513/a2f40ea2-0436-4e44-99e8-d160dab2a680) ## Summary This feature adds: 1. A checkbox to the Settings popover to hide the persistent navigation bar (the sidebar on large viewports and the top bar on small ones). 2. On large viewports, it adds a resize handle to the persistent sidebar. Resizing it into nothing is equivalent to turning off the persistent navigation bar checkbox in Settings. 3. If the navigation bar is hidden, a toolbar button to the left of the search appears. Clicking it brings the navigation bar back. ## Motivation While "mobile mode" is definitely a good default, it's not the only reason people have wanted to hide the sidebar: * Some people use tiling window managers, and don't like rustdoc's current breakpoints. Changing the breakpoints might help with that, but there's no perfect solution, because there's a gap between "huge screen" and "smartphone" where reasonable people can disagree about whether it makes sense for the sidebar to be on-screen. rust-lang#97306 * Some people ask for ways to reduce on-screen clutter because it makes it easier to focus. There's not a media query for that (and if there was, privacy-conscious users would turn it off). rust-lang#59829 This feature is designed to avoid these problems. Resizing the sidebar especially helps, because it provides a way to hide the sidebar without adding a new top-level button (which would add clutter), and it provides a way to make rustdoc play nicer in complex, custom screen layouts. ## Guide and Reference-level explanation On a desktop or laptop with a mouse, resize the sidebar by dragging its right edge. On any browser, including mobile phones, the sticky top bar or side bar can be hidden from the Settings area (the button with the cog wheel, next to the search bar). When it's hidden, a convenient button will appear on the search bar's left. ## Drawbacks This adds more JavaScript code to the render blocking area. ## Rationale and alternatives The most obvious way to allow people to hide the sidebar would have been to let them "manually enter mobile mode." The upside is that it's a feature we already have. The downside is that it's actually really hard to come up with a terse description. Is it: * A Setting that forces desktop viewers to always have the mobile-style top bar? If so, how do we label it? Should it be visible on mobile, and, if so, does it just not do anything? * A persistent hide/show sidebar button, present on desktop, just like on mobile? That's clutter that I'd like to avoid. ## Prior art * The new file browser in GitHub uses a similar divider with a mouse-over indicator * mdBook and macOS Finder both allow you to resize the sidebar to nothing as a gesture to hide it * https://www.nngroup.com/articles/drag-drop/ ## Future possibilities https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/Table.20of.20contents proposes a new, second sidebar (a table of contents). How should it fit in with this feature? Should it be resizeable? Hideable? Can it be accessed on mobile?
2 parents 96df494 + fd9f1a7 commit 75b8c38

17 files changed

+625
-30
lines changed

src/librustdoc/html/markdown.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2013,6 +2013,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
20132013
map.insert("themeStyle".into(), 1);
20142014
map.insert("settings-menu".into(), 1);
20152015
map.insert("help-button".into(), 1);
2016+
map.insert("sidebar-button".into(), 1);
20162017
map.insert("main-content".into(), 1);
20172018
map.insert("toggle-all-docs".into(), 1);
20182019
map.insert("all-types".into(), 1);

src/librustdoc/html/static/css/noscript.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ rules.
99
margin-left: 0 !important;
1010
}
1111

12-
#copy-path {
12+
#copy-path, #sidebar-button, .sidebar-resizer {
1313
/* It requires JS to work so no need to display it in this case. */
1414
display: none;
1515
}
@@ -132,6 +132,8 @@ nav.sub {
132132
--scrape-example-help-hover-color: #000;
133133
--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
134134
--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
135+
--sidebar-resizer-hover: hsl(207, 90%, 66%);
136+
--sidebar-resizer-active: hsl(207, 90%, 54%);
135137
}
136138
/* End theme: light */
137139

@@ -238,6 +240,8 @@ nav.sub {
238240
--scrape-example-help-hover-color: #fff;
239241
--scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1);
240242
--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
243+
--sidebar-resizer-hover: hsl(207, 30%, 54%);
244+
--sidebar-resizer-active: hsl(207, 90%, 54%);
241245
}
242246
/* End theme: dark */
243247
}

src/librustdoc/html/static/css/rustdoc.css

+162-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
:root {
1010
--nav-sub-mobile-padding: 8px;
1111
--search-typename-width: 6.75rem;
12+
/* DEFAULT_SIDEBAR_WIDTH
13+
see main.js for information on these values
14+
and on the RUSTDOC_MOBILE_BREAKPOINT */
15+
--desktop-sidebar-width: 200px;
16+
--src-sidebar-width: 300px;
1217
}
1318

1419
/* See FiraSans-LICENSE.txt for the Fira Sans license. */
@@ -383,13 +388,15 @@ img {
383388

384389
.sidebar {
385390
font-size: 0.875rem;
386-
flex: 0 0 200px;
391+
flex: 0 0 var(--desktop-sidebar-width);
392+
width: var(--desktop-sidebar-width);
387393
overflow-y: scroll;
388394
overscroll-behavior: contain;
389395
position: sticky;
390396
height: 100vh;
391397
top: 0;
392398
left: 0;
399+
z-index: 100;
393400
}
394401

395402
.rustdoc.src .sidebar {
@@ -398,7 +405,95 @@ img {
398405
overflow-x: hidden;
399406
/* The sidebar is by default hidden */
400407
overflow-y: hidden;
401-
z-index: 1;
408+
}
409+
410+
.hide-sidebar .sidebar,
411+
.hide-sidebar .sidebar-resizer {
412+
display: none;
413+
}
414+
415+
.sidebar-resizer {
416+
touch-action: none;
417+
width: 9px;
418+
cursor: col-resize;
419+
z-index: 200;
420+
position: fixed;
421+
height: 100%;
422+
/* make sure there's a 1px gap between the scrollbar and resize handle */
423+
left: calc(var(--desktop-sidebar-width) + 1px);
424+
}
425+
426+
.rustdoc.src .sidebar-resizer {
427+
/* when closed, place resizer glow on top of the normal src sidebar border (no need to worry
428+
about sidebar) */
429+
left: 49px;
430+
}
431+
432+
.src-sidebar-expanded .rustdoc.src .sidebar-resizer {
433+
/* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer
434+
to right of it */
435+
left: var(--src-sidebar-width);
436+
}
437+
438+
.sidebar-resizing {
439+
-moz-user-select: none;
440+
-webkit-user-select: none;
441+
-ms-user-select: none;
442+
user-select: none;
443+
}
444+
445+
.sidebar-resizing * {
446+
cursor: col-resize !important;
447+
}
448+
449+
.sidebar-resizing .sidebar {
450+
position: fixed;
451+
z-index: 100;
452+
}
453+
.sidebar-resizing > body {
454+
padding-left: var(--resizing-sidebar-width);
455+
}
456+
457+
.sidebar-resizer:hover,
458+
.sidebar-resizer:active,
459+
.sidebar-resizer:focus,
460+
.sidebar-resizer.active {
461+
width: 10px;
462+
margin: 0;
463+
/* when active or hovered, place resizer glow on top of the sidebar (right next to, or even
464+
on top of, the scrollbar) */
465+
left: var(--desktop-sidebar-width);
466+
border-left: solid 1px var(--sidebar-resizer-hover);
467+
}
468+
469+
.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,
470+
.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,
471+
.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,
472+
.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active {
473+
/* when active or hovered, place resizer glow on top of the normal src sidebar border */
474+
left: calc(var(--src-sidebar-width) - 1px);
475+
}
476+
477+
@media (pointer: coarse) {
478+
.sidebar-resizer {
479+
/* too easy to hit the resizer while trying to hit the [-] toggle */
480+
display: none !important;
481+
}
482+
}
483+
484+
.sidebar-resizer.active {
485+
/* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff
486+
while resizing */
487+
padding: 0 140px;
488+
width: 2px;
489+
margin-left: -140px;
490+
border-left: none;
491+
}
492+
.sidebar-resizer.active:before {
493+
border-left: solid 2px var(--sidebar-resizer-active);
494+
display: block;
495+
height: 100%;
496+
content: "";
402497
}
403498

404499
.sidebar, .mobile-topbar, .sidebar-menu-toggle,
@@ -416,7 +511,8 @@ img {
416511

417512
.src-sidebar-expanded .src .sidebar {
418513
overflow-y: auto;
419-
flex-basis: 300px;
514+
flex-basis: var(--src-sidebar-width);
515+
width: var(--src-sidebar-width);
420516
}
421517

422518
.src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) {
@@ -477,6 +573,7 @@ ul.block, .block li {
477573
display: block;
478574
padding: 0.25rem; /* 4px */
479575
margin-left: -0.25rem;
576+
margin-right: 0.25rem;
480577
}
481578

482579
.sidebar h2 {
@@ -775,7 +872,7 @@ h2.section-header > .anchor {
775872
text-decoration: underline;
776873
}
777874

778-
.crate.block a.current { font-weight: 500; }
875+
.crate.block li.current a { font-weight: 500; }
779876

780877
/* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap
781878
as much as needed on mobile (see
@@ -1478,7 +1575,20 @@ a.tooltip:hover::after {
14781575
margin-left: 4px;
14791576
display: flex;
14801577
}
1481-
#settings-menu > a, #help-button > a {
1578+
#sidebar-button {
1579+
display: none;
1580+
}
1581+
.hide-sidebar #sidebar-button {
1582+
display: flex;
1583+
margin-right: 4px;
1584+
position: fixed;
1585+
left: 6px;
1586+
height: 34px;
1587+
width: 34px;
1588+
background-color: var(--main-background-color);
1589+
z-index: 1;
1590+
}
1591+
#settings-menu > a, #help-button > a, #sidebar-button > a {
14821592
display: flex;
14831593
align-items: center;
14841594
justify-content: center;
@@ -1493,10 +1603,21 @@ a.tooltip:hover::after {
14931603
}
14941604

14951605
#settings-menu > a:hover, #settings-menu > a:focus,
1496-
#help-button > a:hover, #help-button > a:focus {
1606+
#help-button > a:hover, #help-button > a:focus,
1607+
#sidebar-button > a:hover, #sidebar-button > a:focus {
14971608
border-color: var(--settings-button-border-focus);
14981609
}
14991610

1611+
#sidebar-button > a:before {
1612+
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \
1613+
fill="none" stroke="black">\
1614+
<rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\
1615+
<circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\
1616+
<path d="m7.6121 3v16 M5.375 7.625h-2 m2 3h-2 m2 3h-2" stroke-width="1.25"/></svg>');
1617+
width: 22px;
1618+
height: 22px;
1619+
}
1620+
15001621
#copy-path {
15011622
color: var(--copy-path-button-color);
15021623
background: var(--main-background-color);
@@ -1711,7 +1832,7 @@ However, it's not needed with smaller screen width because the doc/code block is
17111832
/*
17121833
WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
17131834
If you update this line, then you also need to update the line with the same warning
1714-
in src-script.js
1835+
in src-script.js and main.js
17151836
*/
17161837
@media (max-width: 700px) {
17171838
/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
@@ -1722,6 +1843,10 @@ in src-script.js
17221843
scroll-margin-top: 45px;
17231844
}
17241845

1846+
.hide-sidebar #sidebar-button {
1847+
position: static;
1848+
}
1849+
17251850
.rustdoc {
17261851
/* Sidebar should overlay main content, rather than pushing main content to the right.
17271852
Turn off `display: flex` on the body element. */
@@ -1750,7 +1875,8 @@ in src-script.js
17501875
/* Hide the logo and item name from the sidebar. Those are displayed
17511876
in the mobile-topbar instead. */
17521877
.sidebar .logo-container,
1753-
.sidebar .location {
1878+
.sidebar .location,
1879+
.sidebar-resizer {
17541880
display: none;
17551881
}
17561882

@@ -1818,6 +1944,10 @@ in src-script.js
18181944
top: 0;
18191945
}
18201946

1947+
.hide-sidebar .mobile-topbar {
1948+
display: none;
1949+
}
1950+
18211951
.sidebar-menu-toggle {
18221952
width: 45px;
18231953
/* Rare exception to specifying font sizes in rem. Since this is acting
@@ -1827,6 +1957,10 @@ in src-script.js
18271957
color: var(--main-color);
18281958
}
18291959

1960+
.hide-sidebar .sidebar-menu-toggle {
1961+
display: none;
1962+
}
1963+
18301964
.sidebar-elems {
18311965
margin-top: 1em;
18321966
}
@@ -1870,6 +2004,17 @@ in src-script.js
18702004
display: none;
18712005
}
18722006

2007+
/* sidebar button becomes topbar button */
2008+
#sidebar-button > a:before {
2009+
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
2010+
viewBox="0 0 22 22" fill="none" stroke="black">\
2011+
<rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\
2012+
<circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\
2013+
<path d="m3 7.375h16m0-3h-4" stroke-width="1.25"/></svg>');
2014+
width: 22px;
2015+
height: 22px;
2016+
}
2017+
18732018
/* Display an alternating layout on tablets and phones */
18742019
.item-table, .item-row, .item-table > li, .item-table > li > div,
18752020
.search-results > a, .search-results > a > div {
@@ -2274,6 +2419,8 @@ in src-script.js
22742419
--scrape-example-help-hover-color: #000;
22752420
--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
22762421
--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
2422+
--sidebar-resizer-hover: hsl(207, 90%, 66%);
2423+
--sidebar-resizer-active: hsl(207, 90%, 54%);
22772424
}
22782425
/* End theme: light */
22792426

@@ -2379,6 +2526,8 @@ in src-script.js
23792526
--scrape-example-help-hover-color: #fff;
23802527
--scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1);
23812528
--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
2529+
--sidebar-resizer-hover: hsl(207, 30%, 54%);
2530+
--sidebar-resizer-active: hsl(207, 90%, 54%);
23822531
}
23832532
/* End theme: dark */
23842533

@@ -2488,6 +2637,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
24882637
--scrape-example-help-hover-color: #fff;
24892638
--scrape-example-code-wrapper-background-start: rgba(15, 20, 25, 1);
24902639
--scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0);
2640+
--sidebar-resizer-hover: hsl(34, 50%, 33%);
2641+
--sidebar-resizer-active: hsl(34, 100%, 66%);
24912642
}
24922643

24932644
:root[data-theme="ayu"] h1,
@@ -2519,6 +2670,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
25192670
}
25202671

25212672
:root[data-theme="ayu"] .sidebar .current,
2673+
:root[data-theme="ayu"] .sidebar .current a,
25222674
:root[data-theme="ayu"] .sidebar a:hover,
25232675
:root[data-theme="ayu"] #src-sidebar div.files > a:hover,
25242676
:root[data-theme="ayu"] details.dir-entry summary:hover,
@@ -2569,7 +2721,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
25692721
border-bottom: 1px solid rgba(242, 151, 24, 0.3);
25702722
}
25712723

2572-
:root[data-theme="ayu"] #settings-menu > a img {
2724+
:root[data-theme="ayu"] #settings-menu > a img,
2725+
:root[data-theme="ayu"] #sidebar-button > a:before {
25732726
filter: invert(100);
25742727
}
25752728
/* End theme: ayu */

0 commit comments

Comments
 (0)