From c9bd7eebf98c2964ecc5a3d0c28e07ad925981d0 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 29 Jul 2026 19:41:12 +0200 Subject: [PATCH 1/2] Make pixi environment build on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise, this happens: $ pixi install Error: × Failed to update PyPI packages for environment 'default' ├─▶ Failed to prepare distributions ├─▶ Failed to build `pyproj==3.7.2` ├─▶ The build backend returned an error ╰─▶ Call to `setuptools.build_meta.build_wheel` failed (exit status: 1) [stderr] proj executable not found. Please set the PROJ_DIR variable. For more information see: https://pyproj4.github.io/pyproj/stable/installation.html hint: This usually indicates a problem with the package or the build environment. The pixi.lock pins the macOS baseline for osx-arm64 to __osx=13.0 (line 12). pyproj 3.7.2 only ships an arm64 macOS wheel tagged macosx_14_0_arm64 — no wheel exists for anything below macOS 14.0. Since the locked environment's floor (13.0) is below what that wheel declares as its minimum, uv/pixi considers it incompatible and falls back to the sdist, which then needs the system PROJ library to compile against — hence "proj executable not found." rasterio 1.5.0 (also flagged as "installing from remote, not cached" in the verbose log) is very likely hitting the identical issue for the same reason. Both are transitive deps of geopandas/contextily, which the docs deps pull in. --- pixi.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pixi.toml b/pixi.toml index e8678bcf6..b1264dd63 100644 --- a/pixi.toml +++ b/pixi.toml @@ -7,6 +7,9 @@ name = "napari-docs" platforms = ["win-64", "linux-64", "osx-arm64"] # Mac Intel support is not available version = "0.1.0" +[system-requirements] +macos = "14.0" + [feature.base.dependencies] python = "3.13.*" make = "*" From 011ac46145d35575ba9674b329ac0d7b681c797e Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 29 Jul 2026 19:24:05 +0200 Subject: [PATCH 2/2] Unify site search including sub-sites via Pagefind Sphinx's built-in search only covers this site's own pages, so napari.org/workshops (a separately-built mystmd site) was invisible to search here and vice versa. Build a Pagefind index alongside the existing Sphinx build and mount a small widget that merges in the workshops site's Pagefind index at query time, since both are served under the same napari.org origin. --- .github/workflows/build_and_deploy.yml | 5 ++ docs/_static/napari-search-widget.css | 41 +++++++++++ docs/_static/napari-search-widget.js | 90 ++++++++++++++++++++++++ docs/_templates/search-button-field.html | 16 +++++ 4 files changed, 152 insertions(+) create mode 100644 docs/_static/napari-search-widget.css create mode 100644 docs/_static/napari-search-widget.js create mode 100644 docs/_templates/search-button-field.html diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 0477a60fe..b6c05da9d 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -57,6 +57,11 @@ jobs: # Downloads to '/home/runner/work/docs/docs/html' path: html + - name: Build search index + # Consumed by napari-search-widget.js, which merges this index with + # sibling napari.org sub-sites' indexes at query time. + run: npx --yes pagefind@1.5.2 --site html --exclude-selectors ".headerlink" + - name: Deploy Docs if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (startsWith(github.ref, 'refs/tags/v') || startsWith(github.ref, 'refs/heads/main')) uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 diff --git a/docs/_static/napari-search-widget.css b/docs/_static/napari-search-widget.css new file mode 100644 index 000000000..77cb6e2b0 --- /dev/null +++ b/docs/_static/napari-search-widget.css @@ -0,0 +1,41 @@ +/* napari brand overrides for Pagefind's default search UI. + Full variable list: https://pagefind.app/docs/ui/#customising-the-ui-css */ +.napari-search { + position: relative; + --pagefind-ui-primary: #4d9de0; + --pagefind-ui-text: #23252f; + --pagefind-ui-background: #ffffff; + --pagefind-ui-border: #d9dbe1; + --pagefind-ui-tag: #e9ebf1; + --pagefind-ui-border-radius: 6px; + --pagefind-ui-border-width: 1px; + --pagefind-ui-font: inherit; +} + +@media (prefers-color-scheme: dark) { + .napari-search { + --pagefind-ui-text: #f1f1f1; + --pagefind-ui-background: #1e1e21; + --pagefind-ui-border: #3c3e46; + --pagefind-ui-tag: #2c2e36; + } +} + +/* Pagefind's stock UI leaves the results dropdown transparent, relying on + an opaque ancestor to back it — true when embedded in a themed navbar, + false when floating standalone (as on workshops), where it reads as a + broken translucent panel. Always give it its own solid backing. */ +.napari-search .pagefind-ui__results-area { + position: absolute; + top: calc(100% + 0.5rem); + left: 0; + right: 0; + z-index: 1; + max-height: 70vh; + overflow-y: auto; + background: var(--pagefind-ui-background); + border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); + border-radius: var(--pagefind-ui-border-radius); + box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15); + padding: 1rem; +} diff --git a/docs/_static/napari-search-widget.js b/docs/_static/napari-search-widget.js new file mode 100644 index 000000000..7a9bfd742 --- /dev/null +++ b/docs/_static/napari-search-widget.js @@ -0,0 +1,90 @@ +// napari-search-widget.js +// +// Drop-in replacement for a site's native search box. Mounts Pagefind's +// stock UI against this site's own Pagefind bundle, and merges in the +// Pagefind bundles of sibling napari.org sub-sites so results span all of +// them from one search box. +// +// Usage (append to a page, once at least one element matching data-mount +// exists and a Pagefind bundle already exists for this site): +// +// +// +// +// - data-bundle-path: root-relative path to *this* page's own Pagefind +// bundle directory (the folder containing pagefind-ui.js). Required. +// - data-merge-paths: comma-separated root-relative paths to sibling +// sites' Pagefind bundle directories to merge into results. Optional. +// - data-mount: CSS selector matching every element to mount a search UI +// into. Defaults to ".napari-search". Some themes render their navbar +// more than once per page (e.g. a desktop and a mobile variant), and +// this script tag may itself be included more than once as a result — +// every match gets its own independent PagefindUI instance, and each +// match/script pair is only ever initialized once. + +(function () { + const thisScript = document.currentScript; + const bundlePath = thisScript.dataset.bundlePath; + const mergePaths = (thisScript.dataset.mergePaths || '') + .split(',') + .map((s) => s.trim()) + .filter(Boolean); + const mountSelector = thisScript.dataset.mount || '.napari-search'; + // Directory this very