From c034bf41877ad422614412b319de9a612e6d6be6 Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 5 Sep 2023 13:24:49 -0400 Subject: [PATCH] feat: add sphinx search includes js / css updates to make it work --- _static/css/pydata-overrides.css | 69 ++++++++++++++++++++++++++ _static/js/pydata-search-close.js | 82 +++++++++++++++++++++++++++++++ conf.py | 3 ++ requirements.txt | 1 + 4 files changed, 155 insertions(+) create mode 100644 _static/js/pydata-search-close.js diff --git a/_static/css/pydata-overrides.css b/_static/css/pydata-overrides.css index 89e3e26b5..f2d590d9a 100644 --- a/_static/css/pydata-overrides.css +++ b/_static/css/pydata-overrides.css @@ -80,3 +80,72 @@ tbody tr:nth-child(even) { background-color: var(--table-bg-color-even); } vertical-align: middle; } +/* These are hacks to hide the pydata-theme search popup behind the readthedocs +sphinx search extension interface. +*/ +.search-button__wrapper.show .search-button__search-container, +.search-button__wrapper.show .search-button__overlay { + z-index: 1; +} + +.search-button__wrapper.show .search-button__overlay { + display: none; +} + +/* Make sure it doesn't stick out on the sides of the RtD search screen */ +.search-button__wrapper.show .search-button__search-container { + width: 15%; +} + +/* Handle actual styling of the RtD search extension's screen */ +.search__outer { + background-color: var(--pst-color-on-background); + border: var(--pst-color-border); + border-radius: 0.25em; +} + +.search__outer__input { + background-color: var(--pst-color-on-background); + color: var(--pst-color-text-base); + font-size: var(--pst-font-size-icon); +} + +.rtd__search__credits { + background-color: var(--pst-color-background); + color: var(--pst-color-text-muted); +} + +.rtd__search__credits a { + color: var(--pst-color-link); +} + +.search__result__content, .search__result__subheading, .search__error__box { + color: var(--pst-color-text-base); +} + +.search__result__subheading span { + border-bottom-color: var(--pst-color-text-base); +} + +[data-theme="dark"] .search__outer .search__result__content span, +[data-theme="dark"] .search__outer .search__result__title span { + background-color: var(--pst-color-muted-highlight); /* Dark mode background color */ +} + +.search__outer .search__result__content span, +.search__outer .search__result__title span { + border-bottom-color: var(--pst-color-text-base); +} + +/* Make sure "X" remains visible */ +.search__cross__img { + fill: var(--pst-color-text-base); +} + +/* Prevent hover from actually changing the color by setting it to what it + already is */ +.outer_div_page_results:hover, .search__result__box .active { + background-color: var(--pst-color-on-background); +} + +/* End of styling of the RtD search extension's screen */ diff --git a/_static/js/pydata-search-close.js b/_static/js/pydata-search-close.js new file mode 100644 index 000000000..b7147eaff --- /dev/null +++ b/_static/js/pydata-search-close.js @@ -0,0 +1,82 @@ +// Script to allow use of readthedocs-sphinx-search extension with the pydata +// theme +// +// Based in part on: +// https://github.com/pydata/pydata-sphinx-theme/blob/v0.13.3/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js#L167-L272 + +/******************************************************************************* + * Search + */ +/** Find any search forms on the page and return their input element */ +var findSearchInput = () => { + let forms = document.querySelectorAll("form.bd-search"); + if (!forms.length) { + // no search form found + return; + } else { + var form; + if (forms.length == 1) { + // there is exactly one search form (persistent or hidden) + form = forms[0]; + } else { + // must be at least one persistent form, use the first persistent one + form = document.querySelector( + "div:not(.search-button__search-container) > form.bd-search" + ); + } + return form.querySelector("input"); + } +}; + +/** Function to hide the search field */ +var hideSearchField = () => { + + let input = findSearchInput(); + let searchPopupWrapper = document.querySelector(".search-button__wrapper"); + let hiddenInput = searchPopupWrapper.querySelector("input"); + + if (input === hiddenInput) { + searchPopupWrapper.classList.remove("show"); + } + + if (document.activeElement === input) { + input.blur(); + } +}; + +/** Add an event listener for hideSearchField() for Escape*/ +var addEventListenerForSearchKeyboard = () => { + window.addEventListener( + "keydown", + (event) => { + // Allow Escape key to hide the search field + if (event.code == "Escape") { + hideSearchField(); + } + }, + true + ); +}; + +/** Activate callbacks for search button popup */ +var setupSearchButtons = () => { + addEventListenerForSearchKeyboard(); +}; + +// Custom code to manage closing the RtD search dialog properly +$(document).ready(function(){ + $(".search__cross").click(function(){ + hideSearchField(); + }); + $(".search__outer__wrapper.search__backdrop").click(function(){ + hideSearchField(); + }); + $(".search-button__overlay").click(function(){ + // Shouldn't be necessary since it's currently hidden by CSS, but just in + // case + console.log("Close by search-button__overlay"); + hideSearchField(); + }); +}); + +$(setupSearchButtons); diff --git a/conf.py b/conf.py index 642824fe3..88368e05f 100644 --- a/conf.py +++ b/conf.py @@ -28,6 +28,7 @@ 'sphinx.ext.autodoc', 'sphinx_copybutton', 'sphinx_design', + 'sphinx_search.extension', 'sphinx.ext.intersphinx', ] @@ -132,3 +133,5 @@ "doc_path": "", } +def setup(app): + app.add_js_file('js/pydata-search-close.js') diff --git a/requirements.txt b/requirements.txt index 33d6639db..f83fd3132 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ Babel==2.12.1 myst-parser==1.0.0 pydata-sphinx-theme==0.12.0 +readthedocs-sphinx-search==0.3.1 pytz==2022.7 sphinx==5.3.0 sphinx-copybutton==0.5.2