Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring search bar into view on desktop #1872

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion assets/css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,28 @@ body.sidebar-closed .content {
left: 0;
}

@media screen and (max-width: 768px) {
@media screen and (hover: hover) and (max-width: 768px) {
body.sidebar-opening .content {
left: 0;
width: 100%;
}

body.sidebar-closed .sidebar-button {
position: absolute;
top: 14px;
}

body.sidebar-closed .sidebar-button.fixed {
position: fixed;
padding: 16px 12px 18px 19px;
}

body.sidebar-closed .sidebar-button.fixed-top {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The burger menu has to be moved downward to be properly aligned with the searchbox when we are scrolled down the page. When we are at the top of the page, the top-search div is padded differently so we have to compensate in this situation.

position: fixed;
}
}

@media screen and (hover: none) {
.content,
body.sidebar-opening .content {
left: 0;
Expand All @@ -137,6 +158,7 @@ body.sidebar-closed .content {

body.sidebar-closed .sidebar-button {
position: absolute;
top: 14px;
}

.sm-fixed {
Expand Down
24 changes: 17 additions & 7 deletions assets/css/search-bar.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
.top-search {
position: relative;
top: 0;
z-index: 101;
margin-top: 10px;
background-color: var(--background);
padding: 0.8rem 0;
}

@media (max-width: 480px) or ((min-width: 481px) and (max-width: 768px)) {
.top-search {
padding: 0.8rem 1.8rem 0.8rem 3rem;
margin-left: -1rem;
margin-right: -1rem;
}
}

.top-search.sticky {
position: sticky;
}

.search-settings {
Expand Down Expand Up @@ -114,13 +130,7 @@
color: var(--iconAction);
}

@media (max-width: 480px) or ((min-width: 481px) and (max-width: 768px)) {
.search-bar {
margin-left: 0px;
}
}

@media (max-width: 768px) {
@media (hover: none) {
.top-search {
margin-top: 0;
position: absolute;
Expand Down
13 changes: 12 additions & 1 deletion assets/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,21 @@ export function getProjectNameAndVersion () {
}

/**
* Return `true` if the client's OS is MacOS
* Return `true` if the client's OS is MacOS.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added a missing period from my last PR :)

*
* @return {Boolean}
*/
export function isMacOS () {
return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
}

/**
* Return `true` if the client's device is touch-enabled.
*
* @return {Boolean}
*/
export function isTouchDevice () {
return (('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0))
}
68 changes: 44 additions & 24 deletions assets/js/search-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
AUTOCOMPLETE_CONTAINER_SELECTOR,
AUTOCOMPLETE_SUGGESTION_SELECTOR
} from './autocomplete/autocomplete-list'
import { isMacOS, qs } from './helpers'
import { isMacOS, isTouchDevice, qs } from './helpers'

const SEARCH_INPUT_SELECTOR = 'form.search-bar input'
const SEARCH_CLOSE_BUTTON_SELECTOR = 'form.search-bar .search-close-button'
const TOP_SEARCH_SELECTOR = '.top-search'

/**
* Initializes the sidebar search box.
Expand All @@ -34,6 +35,16 @@ export function setSearchInputValue (value) {
*/
export function focusSearchInput () {
const searchInput = qs(SEARCH_INPUT_SELECTOR)

if (!isTouchDevice()) {
qs(TOP_SEARCH_SELECTOR).classList.add('sticky')
if (window.scrollY === 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above.

qs('.sidebar-button').classList.add('fixed-top')
} else {
qs('.sidebar-button').classList.add('fixed')
}
}

searchInput.focus()
}

Expand Down Expand Up @@ -139,38 +150,47 @@ function hideAutocomplete () {
}

let lastScrollTop = window.scrollY
const topSearch = document.querySelector('.top-search')
const topSearch = document.querySelector(TOP_SEARCH_SELECTOR)
const sidebarMenu = document.getElementById('sidebar-menu')
const backgroundLayer = document.querySelector('.background-layer')
const scrollThreshold = 70 // Set a threshold for scroll, adjust as needed
const searchInput = qs(SEARCH_INPUT_SELECTOR)
const sidebarButton = qs('.sidebar-button')

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

// Add 'fixed' class when not at the top
if (currentScroll > scrollThreshold * 2) {
topSearch.classList.add('sm-fixed')
sidebarMenu.classList.add('sm-fixed')
backgroundLayer.classList.add('sm-fixed')
}
if (isTouchDevice()) {
// Add 'fixed' class when not at the top
if (currentScroll > scrollThreshold * 2) {
topSearch.classList.add('sm-fixed')
sidebarMenu.classList.add('sm-fixed')
backgroundLayer.classList.add('sm-fixed')
}

if (currentScroll === 0) {
// Remove 'fixed' class when at the top
topSearch.classList.remove('sm-fixed')
sidebarMenu.classList.remove('sm-fixed')
backgroundLayer.classList.remove('sm-fixed')
}
if (currentScroll === 0) {
// Remove 'fixed' class when at the top
topSearch.classList.remove('sm-fixed')
sidebarMenu.classList.remove('sm-fixed')
backgroundLayer.classList.remove('sm-fixed')
}

if (currentScroll > lastScrollTop && currentScroll > scrollThreshold) {
// Scrolling down and past the threshold
topSearch.classList.add('sm-hidden')
sidebarMenu.classList.add('sm-hidden')
backgroundLayer.classList.add('sm-hidden')
} else {
// Scrolling up or at the top of the page
topSearch.classList.remove('sm-hidden')
sidebarMenu.classList.remove('sm-hidden')
backgroundLayer.classList.remove('sm-hidden')
if (currentScroll > lastScrollTop && currentScroll > scrollThreshold) {
// Scrolling down and past the threshold
topSearch.classList.add('sm-hidden')
sidebarMenu.classList.add('sm-hidden')
backgroundLayer.classList.add('sm-hidden')
} else {
// Scrolling up or at the top of the page
topSearch.classList.remove('sm-hidden')
sidebarMenu.classList.remove('sm-hidden')
backgroundLayer.classList.remove('sm-hidden')
}
} else if (currentScroll !== lastScrollTop) {
topSearch.classList.remove('sticky')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to extract these into a closeSearchbar function but it's only called once and it would require passing in the DOM elements as dependencies otherwise we'd running three DOM queries in a scroll callback which would be worse than this run-on sentence :)

sidebarButton.classList.remove('fixed')
sidebarButton.classList.remove('fixed-top')
searchInput.blur()
}

lastScrollTop = currentScroll <= 0 ? 0 : currentScroll
Expand Down
1 change: 0 additions & 1 deletion lib/ex_doc/formatter/html/templates/sidebar_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,4 @@
<span class="sr-only">Settings</span>
</button>
</div>

</div>
Loading