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
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| %>