mirror of
https://github.com/esphome/esphome-docs.git
synced 2024-12-25 17:17:54 +01:00
Make search results appear in a fixed window; (#3858)
This commit is contained in:
parent
0138eca827
commit
13fbdb1d00
@ -1,3 +1,9 @@
|
||||
/* provide this to be queried in JS. Sadly can't be used in media-queries just yet*/
|
||||
|
||||
:root {
|
||||
--mobile-width-stop: 875;
|
||||
}
|
||||
|
||||
.row-odd {
|
||||
background-color: #f3f6f6;
|
||||
}
|
||||
@ -263,9 +269,8 @@ div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
.search-results {
|
||||
background-color: #f8f8f8;
|
||||
box-shadow: 0 6px 10px rgb(0 0 0 / 0.2);
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: 1500;
|
||||
margin-top: 4px;
|
||||
padding-right: 6px;
|
||||
padding-left: 6px;
|
||||
border-radius: 12px;
|
||||
@ -277,6 +282,21 @@ div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 875px) {
|
||||
/* hide search result thumbnails on mobile */
|
||||
.pagefind-modular-list-thumb {
|
||||
width: 0;
|
||||
}
|
||||
/* reduce height of search box */
|
||||
.pagefind-modular-input-wrapper {
|
||||
scale: 90%;
|
||||
}
|
||||
.logo {
|
||||
scale: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* dark theme */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
@ -383,6 +403,7 @@ div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
.pagefind-ui__form, .pagefind-modular-input, .search-results {
|
||||
color: #ececec !important;
|
||||
}
|
||||
|
||||
:root {
|
||||
--pagefind-ui-primary: #eeeeee;
|
||||
--pagefind-ui-text: #eeeeee;
|
||||
|
@ -26,7 +26,8 @@
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta property="og:site_name" content="ESPHome">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=3, interactive-widget=overlays-content">
|
||||
{% endblock %}
|
||||
|
||||
{% block relbar_top %}
|
||||
@ -39,7 +40,6 @@
|
||||
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="search-results" id="search-results"></div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
|
@ -1,42 +1,150 @@
|
||||
<script src="/pagefind/pagefind-modular-ui.js"></script>
|
||||
<div class="pagefind-ui__form" id="search"></div>
|
||||
<div class="search-results" id="mobile-search-results"></div>
|
||||
<script>
|
||||
let callbackAdded = null;
|
||||
|
||||
|
||||
class El {
|
||||
constructor(tagname) {
|
||||
this.element = document.createElement(tagname);
|
||||
}
|
||||
|
||||
id(s) {
|
||||
this.element.id = s;
|
||||
return this;
|
||||
}
|
||||
|
||||
class(s) {
|
||||
this.element.classList.add(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
attrs(obj) {
|
||||
for (const [k,v] of Object.entries(obj)) {
|
||||
this.element.setAttribute(k, v);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
text(t) {
|
||||
this.element.innerText = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
html(t) {
|
||||
this.element.innerHTML = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
handle(e, f) {
|
||||
this.element.addEventListener(e, f);
|
||||
return this;
|
||||
}
|
||||
|
||||
addTo(el) {
|
||||
if (el instanceof El) {
|
||||
el.element.appendChild(this.element);
|
||||
} else {
|
||||
el.appendChild(this.element);
|
||||
}
|
||||
return this.element;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
const std_target = document.getElementById("search-results");
|
||||
const mobile_target = document.getElementById("mobile-search-results");
|
||||
|
||||
const targetClass = "search-results";
|
||||
const docel = document.getElementsByClassName("document");
|
||||
if (docel.length === 0)
|
||||
return;
|
||||
const inpel = document.getElementById("search");
|
||||
if (!inpel)
|
||||
return;
|
||||
|
||||
var mobileWidth = getComputedStyle(document.body).getPropertyValue("--mobile-width-stop");
|
||||
|
||||
function isMobile() {
|
||||
return window.innerWidth <= mobileWidth;
|
||||
}
|
||||
|
||||
const target = document.createElement("div");
|
||||
target.classList.add(targetClass);
|
||||
target.id = targetClass;
|
||||
target.style.display = "none";
|
||||
docel.item(0).appendChild(target);
|
||||
|
||||
const margin = 20;
|
||||
|
||||
const resultTemplate = (result) => {
|
||||
let wrapper = new El("li").class("pagefind-modular-list-result");
|
||||
|
||||
let thumb = new El("div").class("pagefind-modular-list-thumb").addTo(wrapper);
|
||||
if (result?.meta?.image) {
|
||||
new El("img").class("pagefind-modular-list-image").attrs({
|
||||
src: result.meta.image,
|
||||
alt: result.meta.image_alt || result.meta.title
|
||||
}).addTo(thumb);
|
||||
}
|
||||
|
||||
let inner = new El("div").class("pagefind-modular-list-inner").addTo(wrapper);
|
||||
let title = new El("p").class("pagefind-modular-list-title").addTo(inner);
|
||||
new El("a").class("pagefind-modular-list-link").text(result.meta?.title).attrs({
|
||||
href: result.meta?.url || result.url
|
||||
}).addTo(title);
|
||||
|
||||
let excerpt = new El("p").class("pagefind-modular-list-excerpt").addTo(inner);
|
||||
new El("a").class("pagefind-modular-list-link").html(result.excerpt).attrs({
|
||||
href: result.meta?.url || result.url
|
||||
}).addTo(excerpt);
|
||||
|
||||
return wrapper.element;
|
||||
}
|
||||
|
||||
|
||||
function resizeTarget() {
|
||||
const searchPos = inpel.getBoundingClientRect();
|
||||
var leftPos;
|
||||
var topPos;
|
||||
var maxWidth = 650;
|
||||
target.style.width = "auto;"
|
||||
target.style.height = "fit-content";
|
||||
target.style.maxWidth = maxWidth + "px";
|
||||
let rightPos = margin;
|
||||
if (isMobile()) {
|
||||
// position search results left aligned with the search box, and below.
|
||||
leftPos = margin / 2;
|
||||
topPos = searchPos.bottom + margin / 2;
|
||||
rightPos = margin / 2;
|
||||
} else {
|
||||
// position search results top aligned with the search box, and to its right.
|
||||
leftPos = searchPos.right + margin * 2;
|
||||
topPos = searchPos.top;
|
||||
if (rightPos - leftPos > maxWidth)
|
||||
rightPos = leftPos + maxWidth;
|
||||
}
|
||||
target.style.right = rightPos + "px";
|
||||
target.style.top = topPos + "px";
|
||||
target.style.left = leftPos + "px";
|
||||
let twidth = window.innerWidth - margin - leftPos;
|
||||
if (twidth > maxWidth)
|
||||
twidth = maxWidth;
|
||||
target.style.width = twidth + "px";
|
||||
target.style.maxHeight = (window.innerHeight - margin - topPos) + "px";
|
||||
}
|
||||
|
||||
window.addEventListener("resize", (event) => { resizeTarget(); });
|
||||
|
||||
function showTarget() {
|
||||
var target = std_target;
|
||||
if (window.innerWidth <= 875) {
|
||||
target = mobile_target;
|
||||
std_target.style.display = "none";
|
||||
} else {
|
||||
mobile_target.style.display = "none";
|
||||
}
|
||||
target.style.display = "block";
|
||||
const rect = target.getBoundingClientRect();
|
||||
const height = window.innerHeight;
|
||||
target.style.width = "100%";
|
||||
target.style.height = "fit-content";
|
||||
target.style.maxHeight = (height - rect.top - 10) + "px";
|
||||
if (!callbackAdded) {
|
||||
callbackAdded = true;
|
||||
if (target.style.display !== "block") {
|
||||
target.style.display = "block";
|
||||
document.addEventListener('click', clickCallback);
|
||||
}
|
||||
resizeTarget();
|
||||
}
|
||||
|
||||
function hideTargets() {
|
||||
std_target.style.display = "none";
|
||||
mobile_target.style.display = "none";
|
||||
std_target.style.height = "0";
|
||||
mobile_target.style.height = "0";
|
||||
if (callbackAdded) {
|
||||
if (target.style.display !== "none") {
|
||||
target.style.display = "none";
|
||||
document.removeEventListener('click', clickCallback);
|
||||
callbackAdded = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,19 +165,17 @@
|
||||
}));
|
||||
|
||||
instance.add(new PagefindModularUI.ResultList({
|
||||
containerElement: "#search-results"
|
||||
}));
|
||||
instance.add(new PagefindModularUI.ResultList({
|
||||
containerElement: "#mobile-search-results"
|
||||
containerElement: "#search-results",
|
||||
resultTemplate: resultTemplate
|
||||
}));
|
||||
|
||||
const clickCallback = (event) => {
|
||||
const path = event.composedPath();
|
||||
if (path.includes(std_target) || path.includes(mobile_target) || path.includes(inpel))
|
||||
if (path.includes(target) || path.includes(inpel))
|
||||
return;
|
||||
hideTargets();
|
||||
};
|
||||
if (std_target && mobile_target) {
|
||||
if (target) {
|
||||
instance.on("results", (results) => {
|
||||
if (results.results.length) {
|
||||
showTarget();
|
||||
|
Loading…
Reference in New Issue
Block a user