Skip to content

Commit a718598

Browse files
committed
Refactor search bar
* Use fewer selectors and classes * Unify scrolling and focus handling * Fix gutter on small screens
1 parent ac40c44 commit a718598

13 files changed

+126
-208
lines changed

assets/css/layout.css

+4-42
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ body {
4141
}
4242

4343
.sidebar-button {
44+
padding: 26px 12px 18px 19px;
4445
position: fixed;
4546
z-index: 200;
4647
top: 0;
@@ -61,18 +62,15 @@ body {
6162

6263
.content-inner {
6364
max-width: var(--content-width);
65+
min-height: 100%;
6466
margin: 0 auto;
65-
padding: 3px var(--content-gutter);
67+
padding: 0 var(--content-gutter) 10px;
6668
}
6769

6870
.content-inner:focus {
6971
outline: none;
7072
}
7173

72-
.content-outer {
73-
min-height: 100%;
74-
}
75-
7674
body:is(.sidebar-opening, .sidebar-opened) .sidebar-button {
7775
transform: translateX(calc(var(--sidebarWidth) - 100%));
7876
}
@@ -122,50 +120,14 @@ body.sidebar-closed .content {
122120
left: 0;
123121
}
124122

125-
@media screen and (hover: hover) and (max-width: 768px) {
126-
body.sidebar-opening .content {
127-
left: 0;
128-
width: 100%;
129-
}
130-
131-
body.sidebar-closed .sidebar-button {
132-
position: absolute;
133-
top: 14px;
134-
}
135-
136-
body.sidebar-closed .sidebar-button.fixed {
137-
position: fixed;
138-
padding: 16px 12px 18px 19px;
139-
}
140-
141-
body.sidebar-closed .sidebar-button.fixed-top {
142-
position: fixed;
143-
}
144-
}
145-
146-
@media screen and (hover: none) {
123+
@media screen and (max-width: 768px) {
147124
.content,
148125
body.sidebar-opening .content {
149126
left: 0;
150127
width: 100%;
151128
}
152129

153-
.content-inner {
154-
padding-top: 60px;
155-
padding-bottom: 30px;
156-
overflow-x: auto;
157-
}
158-
159130
body.sidebar-closed .sidebar-button {
160131
position: absolute;
161-
top: 14px;
162-
}
163-
164-
.sm-fixed {
165-
position: fixed !important;
166-
}
167-
168-
.sm-hidden {
169-
top: -70px !important;
170132
}
171133
}

assets/css/print.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
display: none;
99
}
1010

11-
.top-search, .background-layer {
11+
.top-search {
1212
display: none;
1313
}
1414

@@ -27,6 +27,10 @@
2727
display: none;
2828
}
2929

30+
.content-inner {
31+
padding: 0;
32+
}
33+
3034
.content-inner .section-heading a.hover-link {
3135
display: none;
3236
}

assets/css/search-bar.css

+33-37
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
11
.top-search {
2-
position: relative;
3-
top: 0;
4-
z-index: 101;
5-
margin-top: 10px;
62
background-color: var(--background);
7-
padding: 0.8rem 0;
8-
}
9-
10-
@media (max-width: 480px) or ((min-width: 481px) and (max-width: 768px)) {
11-
.top-search {
12-
padding: 0.8rem 1.8rem 0.8rem 3rem;
13-
margin-left: -1rem;
14-
margin-right: -1rem;
15-
}
16-
}
17-
18-
.top-search.sticky {
19-
position: sticky;
3+
top: 0;
4+
z-index: 99;
5+
position: relative;
6+
width: 100%;
7+
padding: 10px 0;
208
}
219

2210
.search-settings {
@@ -130,27 +118,15 @@
130118
color: var(--iconAction);
131119
}
132120

133-
@media (hover: none) {
121+
@media screen and (max-width: 768px) {
122+
/* Code and blockquotes take the full gutter on small screens,
123+
so we need the search to the same */
134124
.top-search {
135-
margin-top: 0;
136-
position: absolute;
137-
top: 13px;
138-
height: 57px;
139-
left: 56px;
140-
right: 20px;
141-
transition: top var(--sidebarTransitionDuration) ease-in-out;
142-
z-index: 99;
143-
}
144-
145-
.background-layer {
146-
position: absolute;
147-
top: 0;
148-
left: 0;
149-
right: 0;
150-
height: 70px;
151-
background-color: var(--background);
152-
transition: all var(--sidebarTransitionDuration) ease-in-out;
153-
z-index: 98;
125+
padding-left: calc(var(--content-gutter) + 36px);
126+
padding-right: var(--content-gutter);
127+
margin-left: calc(-1 * var(--content-gutter));
128+
margin-right: calc(-1 * var(--content-gutter));
129+
width: calc(2 * var(--content-gutter) + 100%);
154130
}
155131

156132
.search-settings {
@@ -163,3 +139,23 @@ body.search-focused .search-bar .search-close-button {
163139
transform: scaleY(1);
164140
transition: transform 0.15s ease-out 0.15s;
165141
}
142+
143+
@media screen and (hover: hover) {
144+
body.search-focused .top-search {
145+
position: sticky !important;
146+
}
147+
148+
body.search-focused.sidebar-closed .sidebar-button {
149+
position: fixed !important;
150+
}
151+
}
152+
153+
@media screen and (hover: none) {
154+
body.scroll-sticky .top-search {
155+
position: sticky !important;
156+
}
157+
158+
body.scroll-sticky.sidebar-closed .sidebar-button {
159+
position: fixed !important;
160+
}
161+
}

assets/css/sidebar.css

-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@
398398
cursor: pointer;
399399
background-color: transparent;
400400
border: none;
401-
padding: 28px 12px 18px 19px;
402401
font-size: var(--sidebarFontSize);
403402
}
404403

assets/js/helpers.js

-11
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,3 @@ export function getProjectNameAndVersion () {
168168
export function isMacOS () {
169169
return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
170170
}
171-
172-
/**
173-
* Return `true` if the client's device is touch-enabled.
174-
*
175-
* @return {Boolean}
176-
*/
177-
export function isTouchDevice () {
178-
return (('ontouchstart' in window) ||
179-
(navigator.maxTouchPoints > 0) ||
180-
(navigator.msMaxTouchPoints > 0))
181-
}

assets/js/search-bar.js

+17-46
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import {
77
AUTOCOMPLETE_CONTAINER_SELECTOR,
88
AUTOCOMPLETE_SUGGESTION_SELECTOR
99
} from './autocomplete/autocomplete-list'
10-
import { isMacOS, isTouchDevice, qs } from './helpers'
10+
import { isMacOS, qs } from './helpers'
1111

1212
const SEARCH_INPUT_SELECTOR = 'form.search-bar input'
1313
const SEARCH_CLOSE_BUTTON_SELECTOR = 'form.search-bar .search-close-button'
14-
const TOP_SEARCH_SELECTOR = '.top-search'
1514

1615
/**
1716
* Initializes the sidebar search box.
@@ -35,16 +34,8 @@ export function setSearchInputValue (value) {
3534
*/
3635
export function focusSearchInput () {
3736
const searchInput = qs(SEARCH_INPUT_SELECTOR)
38-
39-
if (!isTouchDevice()) {
40-
qs(TOP_SEARCH_SELECTOR).classList.add('sticky')
41-
if (window.scrollY === 0) {
42-
qs('.sidebar-button').classList.add('fixed-top')
43-
} else {
44-
qs('.sidebar-button').classList.add('fixed')
45-
}
46-
}
47-
37+
// We also add the class before so we don't move the screen position
38+
document.body.classList.add('search-focused')
4839
searchInput.focus()
4940
}
5041

@@ -162,47 +153,27 @@ function hideAutocomplete () {
162153
}
163154

164155
let lastScrollTop = window.scrollY
165-
const topSearch = document.querySelector(TOP_SEARCH_SELECTOR)
166-
const sidebarMenu = document.getElementById('sidebar-menu')
167-
const backgroundLayer = document.querySelector('.background-layer')
168156
const scrollThreshold = 70 // Set a threshold for scroll, adjust as needed
169-
const searchInput = qs(SEARCH_INPUT_SELECTOR)
170-
const sidebarButton = qs('.sidebar-button')
171157

172158
window.addEventListener('scroll', function () {
173159
const currentScroll = window.scrollY
174160

175-
if (isTouchDevice()) {
176-
// Add 'fixed' class when not at the top
177-
if (currentScroll > scrollThreshold * 2) {
178-
topSearch.classList.add('sm-fixed')
179-
sidebarMenu.classList.add('sm-fixed')
180-
backgroundLayer.classList.add('sm-fixed')
181-
}
161+
// Add 'scroll-sticky' class when not at the top
162+
if (currentScroll > scrollThreshold * 2) {
163+
document.body.classList.add('scroll-sticky')
164+
}
182165

183-
if (currentScroll === 0) {
184-
// Remove 'fixed' class when at the top
185-
topSearch.classList.remove('sm-fixed')
186-
sidebarMenu.classList.remove('sm-fixed')
187-
backgroundLayer.classList.remove('sm-fixed')
188-
}
166+
// Remove when at the top
167+
if (currentScroll === 0) {
168+
document.body.classList.remove('scroll-sticky')
169+
}
189170

190-
if (currentScroll > lastScrollTop && currentScroll > scrollThreshold) {
191-
// Scrolling down and past the threshold
192-
topSearch.classList.add('sm-hidden')
193-
sidebarMenu.classList.add('sm-hidden')
194-
backgroundLayer.classList.add('sm-hidden')
195-
} else {
196-
// Scrolling up or at the top of the page
197-
topSearch.classList.remove('sm-hidden')
198-
sidebarMenu.classList.remove('sm-hidden')
199-
backgroundLayer.classList.remove('sm-hidden')
200-
}
201-
} else if (currentScroll !== lastScrollTop) {
202-
topSearch.classList.remove('sticky')
203-
sidebarButton.classList.remove('fixed')
204-
sidebarButton.classList.remove('fixed-top')
205-
searchInput.blur()
171+
if (currentScroll > lastScrollTop && currentScroll > scrollThreshold) {
172+
// Scrolling down and past the threshold
173+
document.body.classList.remove('scroll-sticky')
174+
} else {
175+
// Scrolling up or at the top of the page
176+
document.body.classList.add('scroll-sticky')
206177
}
207178

208179
lastScrollTop = currentScroll <= 0 ? 0 : currentScroll

formatters/html/dist/html-B2KBCIGP.js formatters/html/dist/html-5VHYSU4S.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

formatters/html/dist/html-elixir-UXH7N42W.css

-6
This file was deleted.

formatters/html/dist/html-elixir-ZVNZTSAB.css

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

formatters/html/dist/html-erlang-GHFCMISR.css

-6
This file was deleted.

formatters/html/dist/html-erlang-HDO4UZJC.css

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/ex_doc/formatter/html/templates/footer_template.eex

+32-33
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
1-
<footer class="footer">
2-
<p>
3-
<%= if config.package do %>
4-
<span class="line">
5-
<a href="https://hex.pm/packages/<%= config.package %>/<%= config.version %>" class="footer-hex-package">Hex Package</a>
6-
7-
<a href="https://preview.hex.pm/preview/<%= config.package %>/<%= config.version %>">Hex Preview</a>
8-
9-
<%= source_path = node && Map.get(node, :source_path); if source_path do %>
10-
(<a href="https://preview.hex.pm/preview/<%= config.package %>/<%= config.version %>/show/<%= source_path %>">current file</a>)
11-
<% end %>
12-
</span>
13-
<% end %>
14-
1+
<footer class="footer">
2+
<p>
3+
<%= if config.package do %>
154
<span class="line">
16-
<button class="a-main footer-button display-quick-switch" title="Search HexDocs packages">
17-
Search HexDocs
18-
</button>
5+
<a href="https://hex.pm/packages/<%= config.package %>/<%= config.version %>" class="footer-hex-package">Hex Package</a>
196

20-
<%= if "epub" in config.formatters do %>
21-
<a href="<%= config.project %>.epub" title="ePub version">
22-
Download ePub version
23-
</a>
7+
<a href="https://preview.hex.pm/preview/<%= config.package %>/<%= config.version %>">Hex Preview</a>
8+
9+
<%= source_path = node && Map.get(node, :source_path); if source_path do %>
10+
(<a href="https://preview.hex.pm/preview/<%= config.package %>/<%= config.version %>/show/<%= source_path %>">current file</a>)
2411
<% end %>
2512
</span>
26-
</p>
13+
<% end %>
14+
15+
<span class="line">
16+
<button class="a-main footer-button display-quick-switch" title="Search HexDocs packages">
17+
Search HexDocs
18+
</button>
2719

28-
<p class="built-using">
29-
Built using
30-
<a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener" translate="no">ExDoc</a> (v<%= ExDoc.version() %>) for the
31-
<%= if config.proglang == :erlang do %>
32-
<a href="https://erlang.org" title="Erlang" target="_blank" translate="no">Erlang programming language</a>
33-
<% else %>
34-
<a href="https://elixir-lang.org" title="Elixir" target="_blank" translate="no">Elixir programming language</a>
20+
<%= if "epub" in config.formatters do %>
21+
<a href="<%= config.project %>.epub" title="ePub version">
22+
Download ePub version
23+
</a>
3524
<% end %>
36-
</p>
37-
<%= before_closing_footer_tag(config, :html) %>
38-
</footer>
39-
</div>
25+
</span>
26+
</p>
27+
28+
<p class="built-using">
29+
Built using
30+
<a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener" translate="no">ExDoc</a> (v<%= ExDoc.version() %>) for the
31+
<%= if config.proglang == :erlang do %>
32+
<a href="https://erlang.org" title="Erlang" target="_blank" translate="no">Erlang programming language</a>
33+
<% else %>
34+
<a href="https://elixir-lang.org" title="Elixir" target="_blank" translate="no">Elixir programming language</a>
35+
<% end %>
36+
</p>
37+
<%= before_closing_footer_tag(config, :html) %>
38+
</footer>
4039
</div>
4140
</main>
4241
</div>

0 commit comments

Comments
 (0)