Switch to Component UI modal with episode number sort
Sort patches instance.__pagefind__.search at runtime — the Component
UI exposes no public API for passing sort options to searches.

Assisted-by: Claude Sonnet 4.6 via Claude Code
change rrypumyysuxxlszzswlmsvptvulzwvuy
commit 7bebd23680db282d5345050049e7cc688be8d8b7
author Alpha Chen <alpha@kejadlen.dev>
date
parent woqorwur
diff --git a/Rakefile b/Rakefile
index 27afce4..2522621 100644
--- a/Rakefile
+++ b/Rakefile
@@ -230,21 +230,52 @@ file INDEX_HTML_PATH => [*EPISODE_HTML_PATHS, LAYOUT_TEMPLATE_PATH, INDEX_TEMPLA
     layout_vars: {
       title: "Cooking Issues Transcripts",
       head: <<~HEAD,
-        <link href="./pagefind/pagefind-ui.css" rel="stylesheet">
+        <link href="./pagefind/pagefind-component-ui.css" rel="stylesheet">
         <link rel="canonical" href="https://issues.cooking/" />
       HEAD
       styles: <<~CSS,
         h1 { margin-bottom: 1rem; }
-        #search { margin-bottom: 1.5rem; }
+        pagefind-modal-trigger { margin-bottom: 1.5rem; display: block; }
         ul { list-style: none; }
         li { padding: 0.4rem 0; border-bottom: 1px solid #eee; }
+        #sort-control {
+          display: inline-flex;
+          align-items: center;
+          gap: 4px;
+          margin-left: auto;
+          font: 12px/1 system-ui, -apple-system, sans-serif;
+          color: var(--pf-text-muted, #767676);
+        }
+        #sort-select {
+          font: inherit;
+          color: inherit;
+          background: transparent;
+          border: none;
+          cursor: pointer;
+        }
       CSS
       scripts: <<~HTML,
-        <script src="./pagefind/pagefind-ui.js"></script>
+        <script src="./pagefind/pagefind-component-ui.js"></script>
         <script>
-          window.addEventListener('DOMContentLoaded', (event) => {
-            new PagefindUI({ element: "#search", showSubResults: true, highlightParam: "highlight" });
+          const instance = window.PagefindComponents.getInstanceManager().getInstance('default');
+          const sortSelect = document.getElementById('sort-select');
+          let sortConfig = null;
+
+          function applySort(value) {
+            sortConfig = value ? { episode_number: value } : null;
+            instance.triggerSearch(instance.searchTerm || '');
+          }
+
+          instance.on('results', () => {
+            const pf = instance.__pagefind__;
+            if (pf && !pf._sortPatched) {
+              const orig = pf.search.bind(pf);
+              pf.search = (term, opts = {}) => orig(term, sortConfig ? { ...opts, sort: sortConfig } : opts);
+              pf._sortPatched = true;
+            }
           });
+
+          sortSelect.addEventListener('change', (e) => applySort(e.target.value));
         </script>
       HTML
     })
diff --git a/lib/pages/episode.html.erb b/lib/pages/episode.html.erb
index 701ebe1..89c79b3 100644
--- a/lib/pages/episode.html.erb
+++ b/lib/pages/episode.html.erb
@@ -1,5 +1,5 @@
 <a class="back" href="index.html">← All episodes</a>
-<h1><%= CGI.escapeHTML("#{ep.fetch(:number)}. #{ep.fetch(:title)}") %></h1>
+<h1 data-pagefind-sort="episode_number:<%= ep.fetch(:number) %>"><%= CGI.escapeHTML("#{ep.fetch(:number)}. #{ep.fetch(:title)}") %></h1>
 
 <% ep.fetch(:text).split("\n\n").each do |para| %>
   <% if (m = para.match(/\A\[([^\]]+)\]\s*(.*)/)) %>
diff --git a/lib/pages/index.html.erb b/lib/pages/index.html.erb
index e805cdf..d3426d5 100644
--- a/lib/pages/index.html.erb
+++ b/lib/pages/index.html.erb
@@ -1,6 +1,24 @@
 <h1>Cooking Issues Transcripts</h1>
 
-<div id="search"></div>
+<pagefind-config preload></pagefind-config>
+<pagefind-modal-trigger></pagefind-modal-trigger>
+<pagefind-modal>
+  <pagefind-modal-header>
+    <pagefind-input></pagefind-input>
+  </pagefind-modal-header>
+  <pagefind-modal-body>
+    <pagefind-summary></pagefind-summary>
+    <pagefind-results></pagefind-results>
+  </pagefind-modal-body>
+  <pagefind-modal-footer>
+    <pagefind-keyboard-hints></pagefind-keyboard-hints>
+    <label id="sort-control">Sort: <select id="sort-select">
+      <option value="">Relevance</option>
+      <option value="desc">Episode # ↓</option>
+      <option value="asc">Episode # ↑</option>
+    </select></label>
+  </pagefind-modal-footer>
+</pagefind-modal>
 
 <ul>
 <% transcripts.reverse.each do |ep| %>