@farming-labs/theme 0.2.38 → 0.2.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,12 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  function cn(...classes) {
12
12
  return classes.filter(Boolean).join(" ");
13
13
  }
14
+ const BREADCRUMB_SEPARATOR = "\xA0\xA0>\xA0\xA0";
15
+ const FILTER_LABELS = {
16
+ all: "All",
17
+ pages: "Pages",
18
+ inside: "Inside pages"
19
+ };
14
20
  function stripHtml(html) {
15
21
  if (typeof document !== "undefined") {
16
22
  const el = document.createElement("div");
@@ -22,6 +28,73 @@ function stripHtml(html) {
22
28
  function stripSearchPreview(text) {
23
29
  return text.replace(/```[\s\S]*?```/g, "").replace(/~~~[\s\S]*?~~~/g, "").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^\|?[\s:-]+(\|[\s:-]+)+\|?\s*$/gm, "").replace(/\|/g, " ").replace(/^[-*+]\s+/gm, "").replace(/(\*{1,3}|_{1,3})(.*?)\1/g, "$2").replace(/`([^`]+)`/g, "$1").replace(/`+/g, "").replace(/\s{2,}/g, " ").trim();
24
30
  }
31
+ function breadcrumbForUrl(url) {
32
+ try {
33
+ const parts = new URL(url, "https://docs.local").pathname.split("/").filter(Boolean).map((part) => decodeURIComponent(part).replace(/[-_]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()));
34
+ return parts.length > 0 ? parts.join(BREADCRUMB_SEPARATOR) : "Docs";
35
+ } catch {
36
+ return "Docs";
37
+ }
38
+ }
39
+ function normalizeSearchPhrase(value) {
40
+ return value.toLowerCase().replace(/[?!.,;:]+$/g, "").replace(/\s+/g, " ").trim();
41
+ }
42
+ function escapeRegExp(value) {
43
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
44
+ }
45
+ function literalMatchPriority(query, value) {
46
+ const q = normalizeSearchPhrase(query);
47
+ const text = normalizeSearchPhrase(value ?? "");
48
+ if (!q || !text) return 0;
49
+ if (text === q) return 2;
50
+ const boundary = "[^\\p{L}\\p{N}]";
51
+ return new RegExp(`(^|${boundary})${escapeRegExp(q)}(?=$|${boundary})`, "u").test(text) ? 1 : 0;
52
+ }
53
+ function tokenizeLiteralQuery(query) {
54
+ return Array.from(new Set(query.toLowerCase().replace(/[^\p{L}\p{N}@/_:.-]+/gu, " ").split(/\s+/).map((word) => word.replace(/^[^\p{L}\p{N}@]+|[^\p{L}\p{N}]+$/gu, "")).filter((word) => word.length > 1)));
55
+ }
56
+ function isLiteralLookupQuery(query) {
57
+ const q = normalizeSearchPhrase(query);
58
+ const words = tokenizeLiteralQuery(q);
59
+ return words.length > 0 && words.length <= 3 && words.join(" ") === q;
60
+ }
61
+ function hasDistinctSearchSection(result, label) {
62
+ if (result.type === "page") return false;
63
+ if (!result.section) return true;
64
+ const title = label.split(/\s+[—–]\s+/)[0] ?? "";
65
+ return normalizeSearchPhrase(result.section) !== normalizeSearchPhrase(title);
66
+ }
67
+ function getUrlSearchSegments(url) {
68
+ try {
69
+ const parsed = new URL(url, "https://docs.local");
70
+ return Array.from(new Set(parsed.pathname.split("/").flatMap((segment) => {
71
+ const decoded = decodeURIComponent(segment);
72
+ return [decoded, decoded.replace(/[-_]+/g, " ")];
73
+ }).map(normalizeSearchPhrase).filter(Boolean)));
74
+ } catch {
75
+ return [];
76
+ }
77
+ }
78
+ function exactMatchPriority(query, label, url) {
79
+ const q = normalizeSearchPhrase(query);
80
+ if (!q) return 0;
81
+ const normalizedLabel = normalizeSearchPhrase(label);
82
+ const joinedLabel = normalizeSearchPhrase(label.replace(/\s+[—–-]\s+/g, " "));
83
+ const labelParts = normalizedLabel.split(/\s+[—–-]\s+/).map(normalizeSearchPhrase).filter(Boolean);
84
+ if (normalizedLabel === q || joinedLabel === q) return 4;
85
+ if (labelParts.includes(q)) return 3;
86
+ if (getUrlSearchSegments(url).includes(q)) return 2;
87
+ if (normalizedLabel.startsWith(q) || joinedLabel.startsWith(q)) return 1;
88
+ return 0;
89
+ }
90
+ function resultDisplayLabel(result) {
91
+ const section = result.section ? stripSearchPreview(stripHtml(result.section)) : "";
92
+ if (section) return section;
93
+ const label = stripSearchPreview(stripHtml(result.content));
94
+ const parts = label.split(/\s+[—–]\s+/).map((part) => part.trim()).filter(Boolean);
95
+ if (result.type === "heading" && parts.length > 1) return parts[parts.length - 1] ?? label;
96
+ return label;
97
+ }
25
98
  function fuzzyScore(query, text) {
26
99
  const q = query.trim().toLowerCase();
27
100
  const t = text.toLowerCase();
@@ -56,22 +129,23 @@ function fuzzyScore(query, text) {
56
129
  indices: Array.from(new Set(indices)).sort((a, b) => a - b)
57
130
  };
58
131
  }
59
- function HighlightedLabel({ label, indices }) {
132
+ function HighlightedLabel({ label, indices = [] }) {
60
133
  if (!indices.length) return /* @__PURE__ */ jsx(Fragment$1, { children: label });
61
134
  const out = [];
62
- for (let pos = 0; pos < label.length; pos++) if (indices.includes(pos)) {
63
- let run = label[pos];
64
- let p = pos + 1;
65
- while (indices.includes(p) && p < label.length) {
66
- run += label[p];
67
- p++;
68
- }
69
- out.push(/* @__PURE__ */ jsx("mark", {
135
+ const highlighted = new Set(indices);
136
+ let pos = 0;
137
+ while (pos < label.length) {
138
+ const marked = highlighted.has(pos);
139
+ let end = pos + 1;
140
+ while (end < label.length && highlighted.has(end) === marked) end++;
141
+ const run = label.slice(pos, end);
142
+ if (marked) out.push(/* @__PURE__ */ jsx("mark", {
70
143
  className: "omni-highlight",
71
144
  children: run
72
145
  }, `m-${pos}`));
73
- pos = p - 1;
74
- } else out.push(/* @__PURE__ */ jsx("span", { children: label[pos] }, `t-${pos}`));
146
+ else out.push(/* @__PURE__ */ jsx("span", { children: run }, `t-${pos}`));
147
+ pos = end;
148
+ }
75
149
  return /* @__PURE__ */ jsx(Fragment$1, { children: out });
76
150
  }
77
151
  function SearchIcon() {
@@ -91,99 +165,8 @@ function SearchIcon() {
91
165
  }), /* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })]
92
166
  });
93
167
  }
94
- function FileIcon() {
95
- return /* @__PURE__ */ jsxs("svg", {
96
- width: "16",
97
- height: "16",
98
- viewBox: "0 0 24 24",
99
- fill: "none",
100
- stroke: "currentColor",
101
- strokeWidth: "2",
102
- strokeLinecap: "round",
103
- strokeLinejoin: "round",
104
- children: [/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }), /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })]
105
- });
106
- }
107
- function HashIcon() {
108
- return /* @__PURE__ */ jsxs("svg", {
109
- width: "16",
110
- height: "16",
111
- viewBox: "0 0 24 24",
112
- fill: "none",
113
- stroke: "currentColor",
114
- strokeWidth: "2",
115
- strokeLinecap: "round",
116
- strokeLinejoin: "round",
117
- children: [
118
- /* @__PURE__ */ jsx("line", {
119
- x1: "4",
120
- x2: "20",
121
- y1: "9",
122
- y2: "9"
123
- }),
124
- /* @__PURE__ */ jsx("line", {
125
- x1: "4",
126
- x2: "20",
127
- y1: "15",
128
- y2: "15"
129
- }),
130
- /* @__PURE__ */ jsx("line", {
131
- x1: "10",
132
- x2: "8",
133
- y1: "3",
134
- y2: "21"
135
- }),
136
- /* @__PURE__ */ jsx("line", {
137
- x1: "16",
138
- x2: "14",
139
- y1: "3",
140
- y2: "21"
141
- })
142
- ]
143
- });
144
- }
145
- function TypeIcon() {
146
- return /* @__PURE__ */ jsxs("svg", {
147
- width: "16",
148
- height: "16",
149
- viewBox: "0 0 24 24",
150
- fill: "none",
151
- stroke: "currentColor",
152
- strokeWidth: "2",
153
- strokeLinecap: "round",
154
- strokeLinejoin: "round",
155
- children: [
156
- /* @__PURE__ */ jsx("polyline", { points: "4 7 4 4 20 4 20 7" }),
157
- /* @__PURE__ */ jsx("line", {
158
- x1: "9",
159
- x2: "15",
160
- y1: "20",
161
- y2: "20"
162
- }),
163
- /* @__PURE__ */ jsx("line", {
164
- x1: "12",
165
- x2: "12",
166
- y1: "4",
167
- y2: "20"
168
- })
169
- ]
170
- });
171
- }
172
- function CloseIcon() {
173
- return /* @__PURE__ */ jsxs("svg", {
174
- width: "16",
175
- height: "16",
176
- viewBox: "0 0 24 24",
177
- fill: "none",
178
- stroke: "currentColor",
179
- strokeWidth: "2",
180
- strokeLinecap: "round",
181
- strokeLinejoin: "round",
182
- children: [/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }), /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })]
183
- });
184
- }
185
- function EnterIcon() {
186
- return /* @__PURE__ */ jsxs("svg", {
168
+ function ArrowDownIcon() {
169
+ return /* @__PURE__ */ jsx("svg", {
187
170
  width: "12",
188
171
  height: "12",
189
172
  viewBox: "0 0 24 24",
@@ -192,7 +175,7 @@ function EnterIcon() {
192
175
  strokeWidth: "2",
193
176
  strokeLinecap: "round",
194
177
  strokeLinejoin: "round",
195
- children: [/* @__PURE__ */ jsx("polyline", { points: "9 10 4 15 9 20" }), /* @__PURE__ */ jsx("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" })]
178
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
196
179
  });
197
180
  }
198
181
  function ArrowUpIcon() {
@@ -208,8 +191,8 @@ function ArrowUpIcon() {
208
191
  children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" })
209
192
  });
210
193
  }
211
- function ArrowDownIcon() {
212
- return /* @__PURE__ */ jsx("svg", {
194
+ function CornerDownLeftIcon() {
195
+ return /* @__PURE__ */ jsxs("svg", {
213
196
  width: "12",
214
197
  height: "12",
215
198
  viewBox: "0 0 24 24",
@@ -218,37 +201,7 @@ function ArrowDownIcon() {
218
201
  strokeWidth: "2",
219
202
  strokeLinecap: "round",
220
203
  strokeLinejoin: "round",
221
- children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
222
- });
223
- }
224
- function ExternalLinkIcon() {
225
- return /* @__PURE__ */ jsxs("svg", {
226
- width: "14",
227
- height: "14",
228
- viewBox: "0 0 24 24",
229
- fill: "none",
230
- stroke: "currentColor",
231
- strokeWidth: "2",
232
- strokeLinecap: "round",
233
- strokeLinejoin: "round",
234
- children: [
235
- /* @__PURE__ */ jsx("path", { d: "M15 3h6v6" }),
236
- /* @__PURE__ */ jsx("path", { d: "M10 14 21 3" }),
237
- /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
238
- ]
239
- });
240
- }
241
- function ChevronRightIcon() {
242
- return /* @__PURE__ */ jsx("svg", {
243
- width: "14",
244
- height: "14",
245
- viewBox: "0 0 24 24",
246
- fill: "none",
247
- stroke: "currentColor",
248
- strokeWidth: "2",
249
- strokeLinecap: "round",
250
- strokeLinejoin: "round",
251
- children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" })
204
+ children: [/* @__PURE__ */ jsx("path", { d: "m9 10-5 5 5 5" }), /* @__PURE__ */ jsx("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" })]
252
205
  });
253
206
  }
254
207
  function LoaderIcon() {
@@ -282,21 +235,6 @@ function HistoryIcon() {
282
235
  ]
283
236
  });
284
237
  }
285
- function iconForType(type) {
286
- switch (type) {
287
- case "heading": return /* @__PURE__ */ jsx(HashIcon, {});
288
- case "text": return /* @__PURE__ */ jsx(TypeIcon, {});
289
- default: return /* @__PURE__ */ jsx(FileIcon, {});
290
- }
291
- }
292
- function labelForType(type) {
293
- switch (type) {
294
- case "page": return "Page";
295
- case "heading": return "Section";
296
- case "text": return "Content";
297
- default: return "Result";
298
- }
299
- }
300
238
  /**
301
239
  * Built-in docs search command palette.
302
240
  * Intercepts Cmd+K and sidebar search button to provide an advanced
@@ -311,11 +249,14 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
311
249
  const [loading, setLoading] = useState(false);
312
250
  const [activeIndex, setActiveIndex] = useState(0);
313
251
  const [recents, setRecents] = useState([]);
252
+ const [filter, setFilter] = useState("all");
253
+ const [filterOpen, setFilterOpen] = useState(false);
314
254
  const [mounted, setMounted] = useState(false);
315
255
  const activeLocale = resolveClientLocale(useWindowSearchParams(), locale);
316
256
  const searchApi = useMemo(() => withLangInUrl(api, activeLocale), [activeLocale, api]);
317
257
  const inputRef = useRef(null);
318
258
  const listRef = useRef(null);
259
+ const searchCacheRef = useRef(/* @__PURE__ */ new Map());
319
260
  const setOpenWithAnalytics = useCallback((nextOpen, trigger) => {
320
261
  setOpen(nextOpen);
321
262
  if (!analytics) return;
@@ -374,29 +315,57 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
374
315
  return;
375
316
  }
376
317
  let cancelled = false;
318
+ const controller = new AbortController();
319
+ const cacheKey = `${activeLocale ?? ""}:${searchApi}:${debouncedQuery}`;
320
+ const cached = searchCacheRef.current.get(cacheKey);
321
+ if (cached) {
322
+ setResults(cached);
323
+ setActiveIndex(0);
324
+ setLoading(false);
325
+ return;
326
+ }
377
327
  setLoading(true);
378
328
  (async () => {
379
329
  const startedAt = Date.now();
380
330
  try {
381
331
  const requestUrl = new URL(searchApi, window.location.origin);
382
332
  requestUrl.searchParams.set("query", debouncedQuery);
383
- const res = await fetch(requestUrl.toString());
333
+ const res = await fetch(requestUrl.toString(), { signal: controller.signal });
384
334
  if (!res.ok || cancelled) return;
385
- const items = (await res.json()).map((r) => {
386
- const label = stripSearchPreview(stripHtml(r.content));
335
+ const items = (await res.json()).map((r, sourceIndex) => {
336
+ const sourceLabel = stripSearchPreview(stripHtml(r.content));
337
+ const label = resultDisplayLabel(r);
338
+ const description = r.description ? stripSearchPreview(stripHtml(r.description)).slice(0, 220) : void 0;
387
339
  const { score, indices } = fuzzyScore(debouncedQuery, label);
340
+ const descriptionMatch = description ? fuzzyScore(debouncedQuery, description) : { indices: [] };
341
+ const url = withLangInUrl(r.url, activeLocale);
388
342
  return {
389
343
  id: r.id,
390
344
  label,
391
- subtitle: r.description ? stripSearchPreview(stripHtml(r.description)) : labelForType(r.type),
392
- url: withLangInUrl(r.url, activeLocale),
393
- icon: iconForType(r.type),
345
+ subtitle: breadcrumbForUrl(r.url),
346
+ description,
347
+ url,
348
+ type: r.type,
394
349
  score,
395
- indices
350
+ exactPriority: exactMatchPriority(debouncedQuery, sourceLabel, r.url),
351
+ insideLiteralPriority: hasDistinctSearchSection(r, sourceLabel) && isLiteralLookupQuery(debouncedQuery) ? Math.max(literalMatchPriority(debouncedQuery, r.section), literalMatchPriority(debouncedQuery, description)) : 0,
352
+ sourceIndex,
353
+ indices,
354
+ descriptionIndices: descriptionMatch.indices
396
355
  };
397
356
  });
398
- items.sort((a, b) => b.score - a.score || a.label.localeCompare(b.label));
357
+ items.sort((a, b) => {
358
+ const literalDelta = b.insideLiteralPriority - a.insideLiteralPriority;
359
+ if (literalDelta) return literalDelta;
360
+ if (a.insideLiteralPriority > 0 && b.insideLiteralPriority > 0) return a.sourceIndex - b.sourceIndex;
361
+ return b.exactPriority - a.exactPriority || b.score - a.score || a.sourceIndex - b.sourceIndex || a.label.localeCompare(b.label);
362
+ });
399
363
  if (!cancelled) {
364
+ if (searchCacheRef.current.size >= 20) {
365
+ const firstKey = searchCacheRef.current.keys().next().value;
366
+ if (firstKey) searchCacheRef.current.delete(firstKey);
367
+ }
368
+ searchCacheRef.current.set(cacheKey, items);
400
369
  setResults(items);
401
370
  setActiveIndex(0);
402
371
  if (analytics) emitClientAnalyticsEvent({
@@ -411,6 +380,7 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
411
380
  });
412
381
  }
413
382
  } catch {
383
+ if (controller.signal.aborted) return;
414
384
  if (!cancelled && analytics) emitClientAnalyticsEvent({
415
385
  type: "search_error",
416
386
  locale: activeLocale,
@@ -425,6 +395,7 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
425
395
  })();
426
396
  return () => {
427
397
  cancelled = true;
398
+ controller.abort();
428
399
  };
429
400
  }, [
430
401
  activeLocale,
@@ -437,6 +408,8 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
437
408
  else {
438
409
  setQuery("");
439
410
  setResults([]);
411
+ setFilter("all");
412
+ setFilterOpen(false);
440
413
  setActiveIndex(0);
441
414
  }
442
415
  }, [open]);
@@ -500,9 +473,11 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
500
473
  saveRecent
501
474
  ]);
502
475
  const displayItems = useMemo(() => {
503
- if (results.length > 0) return results;
504
- return [];
505
- }, [results]);
476
+ if (results.length === 0) return [];
477
+ if (filter === "pages") return results.filter((item) => item.type === "page");
478
+ if (filter === "inside") return results.filter((item) => item.type !== "page");
479
+ return results;
480
+ }, [filter, results]);
506
481
  const recentItems = useMemo(() => {
507
482
  if (query.trim() || results.length > 0) return [];
508
483
  return recents.map((r) => ({
@@ -510,15 +485,27 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
510
485
  label: r.label,
511
486
  subtitle: "Recently viewed",
512
487
  url: r.url,
513
- icon: /* @__PURE__ */ jsx(FileIcon, {}),
488
+ type: "page",
514
489
  score: 0,
515
- indices: []
490
+ exactPriority: 0,
491
+ insideLiteralPriority: 0,
492
+ sourceIndex: 0,
493
+ indices: [],
494
+ descriptionIndices: []
516
495
  }));
517
496
  }, [
518
497
  query,
519
498
  results,
520
499
  recents
521
500
  ]);
501
+ useEffect(() => {
502
+ setActiveIndex(0);
503
+ }, [filter, debouncedQuery]);
504
+ function updateFilter(nextFilter) {
505
+ setFilter(nextFilter);
506
+ setFilterOpen(false);
507
+ setActiveIndex(0);
508
+ }
522
509
  function moveActive(delta) {
523
510
  const total = displayItems.length + recentItems.length;
524
511
  if (!total) return;
@@ -567,21 +554,17 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
567
554
  type: "text",
568
555
  role: "combobox",
569
556
  "aria-expanded": "true",
570
- placeholder: "Search documentation…",
557
+ placeholder: "Search",
571
558
  value: query,
572
559
  onChange: (e) => setQuery(e.target.value),
573
560
  onKeyDown: handleKeyDown,
574
561
  className: "omni-search-input"
575
562
  }),
576
- /* @__PURE__ */ jsx("kbd", {
577
- className: "omni-kbd",
578
- children: "⌘ K"
579
- }),
580
563
  /* @__PURE__ */ jsx("button", {
581
564
  "aria-label": "Close",
582
565
  className: "omni-close-btn",
583
566
  onClick: () => setOpenWithAnalytics(false, "button"),
584
- children: /* @__PURE__ */ jsx(CloseIcon, {})
567
+ children: "ESC"
585
568
  })
586
569
  ]
587
570
  })
@@ -603,41 +586,23 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
603
586
  children: "Recent"
604
587
  }), /* @__PURE__ */ jsx("div", {
605
588
  className: "omni-group-items",
606
- children: recentItems.map((item, i) => /* @__PURE__ */ jsxs("button", {
589
+ children: recentItems.map((item, i) => /* @__PURE__ */ jsx("button", {
607
590
  "data-id": item.id,
608
591
  role: "option",
609
592
  "aria-selected": i === activeIndex,
610
593
  onMouseEnter: () => setActiveIndex(i),
611
594
  onClick: () => execute(item),
612
595
  className: cn("omni-item", i === activeIndex && "omni-item-active"),
613
- children: [
614
- /* @__PURE__ */ jsx("div", {
615
- className: "omni-item-icon",
616
- children: item.icon
617
- }),
618
- /* @__PURE__ */ jsxs("div", {
619
- className: "omni-item-text",
620
- children: [/* @__PURE__ */ jsx("div", {
621
- className: "omni-item-label",
622
- children: item.label
623
- }), /* @__PURE__ */ jsx("div", {
624
- className: "omni-item-subtitle",
625
- children: item.subtitle
626
- })]
627
- }),
628
- /* @__PURE__ */ jsx("a", {
629
- href: item.url,
630
- target: "_blank",
631
- rel: "noopener noreferrer",
632
- className: "omni-item-ext",
633
- title: "Open in new tab",
634
- onClick: (e) => {
635
- e.stopPropagation();
636
- },
637
- children: /* @__PURE__ */ jsx(ExternalLinkIcon, {})
638
- }),
639
- /* @__PURE__ */ jsx(ChevronRightIcon, {})
640
- ]
596
+ children: /* @__PURE__ */ jsxs("div", {
597
+ className: "omni-item-text",
598
+ children: [/* @__PURE__ */ jsx("div", {
599
+ className: "omni-item-subtitle",
600
+ children: item.subtitle
601
+ }), /* @__PURE__ */ jsx("div", {
602
+ className: "omni-item-label",
603
+ children: item.label
604
+ })]
605
+ })
641
606
  }, item.id))
642
607
  })]
643
608
  }),
@@ -650,44 +615,36 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
650
615
  className: "omni-group-items",
651
616
  children: displayItems.map((item, i) => {
652
617
  const idx = recentItems.length + i;
653
- return /* @__PURE__ */ jsxs("button", {
618
+ return /* @__PURE__ */ jsx("button", {
654
619
  "data-id": item.id,
655
620
  role: "option",
656
621
  "aria-selected": idx === activeIndex,
657
622
  onMouseEnter: () => setActiveIndex(idx),
658
623
  onClick: () => execute(item),
659
624
  className: cn("omni-item", idx === activeIndex && "omni-item-active"),
660
- children: [
661
- /* @__PURE__ */ jsx("div", {
662
- className: "omni-item-icon",
663
- children: item.icon
664
- }),
665
- /* @__PURE__ */ jsxs("div", {
666
- className: "omni-item-text",
667
- children: [/* @__PURE__ */ jsx("div", {
625
+ children: /* @__PURE__ */ jsxs("div", {
626
+ className: "omni-item-text",
627
+ children: [
628
+ /* @__PURE__ */ jsx("div", {
629
+ className: "omni-item-subtitle",
630
+ children: item.subtitle
631
+ }),
632
+ /* @__PURE__ */ jsx("div", {
668
633
  className: "omni-item-label",
669
634
  children: /* @__PURE__ */ jsx(HighlightedLabel, {
670
635
  label: item.label,
671
636
  indices: item.indices
672
637
  })
673
- }), /* @__PURE__ */ jsx("div", {
674
- className: "omni-item-subtitle",
675
- children: item.subtitle
676
- })]
677
- }),
678
- /* @__PURE__ */ jsx("a", {
679
- href: item.url,
680
- target: "_blank",
681
- rel: "noopener noreferrer",
682
- className: "omni-item-ext",
683
- title: "Open in new tab",
684
- onClick: (e) => {
685
- e.stopPropagation();
686
- },
687
- children: /* @__PURE__ */ jsx(ExternalLinkIcon, {})
688
- }),
689
- /* @__PURE__ */ jsx(ChevronRightIcon, {})
690
- ]
638
+ }),
639
+ item.description && /* @__PURE__ */ jsx("div", {
640
+ className: "omni-item-description",
641
+ children: /* @__PURE__ */ jsx(HighlightedLabel, {
642
+ label: item.description,
643
+ indices: item.descriptionIndices
644
+ })
645
+ })
646
+ ]
647
+ })
691
648
  }, item.id);
692
649
  })
693
650
  })]
@@ -697,20 +654,20 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
697
654
  children: [/* @__PURE__ */ jsx("div", {
698
655
  className: "omni-empty-icon",
699
656
  children: /* @__PURE__ */ jsx(HistoryIcon, {})
700
- }), debouncedQuery ? "No results found. Try a different query." : "Type to search the docs, or browse recent items."]
657
+ }), debouncedQuery && results.length > 0 ? `No ${FILTER_LABELS[filter].toLowerCase()} results found.` : debouncedQuery ? "No results found. Try a different query." : "Type to search the docs, or browse recent items."]
701
658
  })
702
659
  ]
703
660
  }),
704
661
  /* @__PURE__ */ jsx("div", {
705
662
  className: "omni-footer",
706
- children: /* @__PURE__ */ jsx("div", {
663
+ children: /* @__PURE__ */ jsxs("div", {
707
664
  className: "omni-footer-inner",
708
- children: /* @__PURE__ */ jsxs("div", {
665
+ children: [/* @__PURE__ */ jsxs("div", {
709
666
  className: "omni-footer-hints",
710
667
  children: [
711
668
  /* @__PURE__ */ jsxs("span", {
712
669
  className: "omni-footer-hint",
713
- children: [/* @__PURE__ */ jsx(EnterIcon, {}), " to select"]
670
+ children: [/* @__PURE__ */ jsx(CornerDownLeftIcon, {}), " to select"]
714
671
  }),
715
672
  /* @__PURE__ */ jsxs("span", {
716
673
  className: "omni-footer-hint",
@@ -722,10 +679,44 @@ function DocsCommandSearch({ api = "/api/docs", locale, analytics = false }) {
722
679
  }),
723
680
  /* @__PURE__ */ jsxs("span", {
724
681
  className: "omni-footer-hint omni-footer-hint-desktop",
725
- children: [/* @__PURE__ */ jsx(CloseIcon, {}), " to close"]
682
+ children: [/* @__PURE__ */ jsx("span", {
683
+ className: "omni-kbd-sm",
684
+ children: "ESC"
685
+ }), " to close"]
726
686
  })
727
687
  ]
728
- })
688
+ }), /* @__PURE__ */ jsxs("div", {
689
+ className: "omni-footer-filter",
690
+ children: [
691
+ /* @__PURE__ */ jsx("span", {
692
+ className: "omni-filter-label",
693
+ children: "Filter"
694
+ }),
695
+ /* @__PURE__ */ jsxs("button", {
696
+ type: "button",
697
+ className: "omni-filter-button",
698
+ "aria-expanded": filterOpen,
699
+ onClick: () => setFilterOpen((value) => !value),
700
+ children: [FILTER_LABELS[filter], /* @__PURE__ */ jsx(ArrowDownIcon, {})]
701
+ }),
702
+ filterOpen && /* @__PURE__ */ jsx("div", {
703
+ className: "omni-filter-menu",
704
+ role: "group",
705
+ "aria-label": "Search filter",
706
+ children: [
707
+ "all",
708
+ "pages",
709
+ "inside"
710
+ ].map((mode) => /* @__PURE__ */ jsx("button", {
711
+ type: "button",
712
+ "aria-pressed": filter === mode,
713
+ className: cn("omni-filter-option", filter === mode && "omni-filter-option-active"),
714
+ onClick: () => updateFilter(mode),
715
+ children: FILTER_LABELS[mode]
716
+ }, mode))
717
+ })
718
+ ]
719
+ })]
729
720
  })
730
721
  })
731
722
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/theme",
3
- "version": "0.2.38",
3
+ "version": "0.2.39",
4
4
  "description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
5
5
  "keywords": [
6
6
  "docs",
@@ -146,7 +146,7 @@
146
146
  "tsdown": "^0.20.3",
147
147
  "typescript": "^5.9.3",
148
148
  "vitest": "^4.1.8",
149
- "@farming-labs/docs": "0.2.38"
149
+ "@farming-labs/docs": "0.2.39"
150
150
  },
151
151
  "peerDependencies": {
152
152
  "@farming-labs/docs": ">=0.0.1",
@@ -605,6 +605,7 @@ figure.shiki:has(figcaption) > div:first-child,
605
605
  }
606
606
 
607
607
  .omni-group-label {
608
+ display: block !important;
608
609
  letter-spacing: 0.14em;
609
610
  color: color-mix(in srgb, var(--color-fd-foreground) 72%, transparent) !important;
610
611
  }
package/styles/omni.css CHANGED
@@ -22,7 +22,7 @@
22
22
  @keyframes omni-scale-in {
23
23
  from {
24
24
  opacity: 0;
25
- transform: translateX(-50%) scale(0.96) translateY(-4px);
25
+ transform: translateX(-50%) scale(0.98) translateY(-6px);
26
26
  }
27
27
  to {
28
28
  opacity: 1;
@@ -36,7 +36,7 @@
36
36
  }
37
37
  to {
38
38
  opacity: 0;
39
- transform: translateX(-50%) scale(0.96) translateY(-4px);
39
+ transform: translateX(-50%) scale(0.98) translateY(-6px);
40
40
  }
41
41
  }
42
42
 
@@ -56,42 +56,40 @@
56
56
  .omni-overlay {
57
57
  position: fixed;
58
58
  inset: 0;
59
- z-index: 100;
60
- background: rgba(0, 0, 0, 0.55);
61
- backdrop-filter: blur(4px);
59
+ z-index: 50;
60
+ background: rgba(0, 0, 0, 0.2);
61
+ backdrop-filter: blur(2px);
62
62
  animation: omni-fade-in 150ms ease-out;
63
63
  }
64
64
 
65
65
  .omni-content {
66
+ --omni-content-top: clamp(5rem, 16vh, 7rem);
66
67
  position: fixed;
67
- z-index: 101;
68
- top: 18%;
68
+ z-index: 51;
69
+ top: var(--omni-content-top);
69
70
  left: 50%;
70
71
  transform: translateX(-50%);
71
- width: min(720px, calc(100% - 32px));
72
- border-radius: var(--radius, 0.75rem);
73
- border: 1px solid var(--color-fd-border, #262626);
74
- background: var(--color-fd-popover, #0c0c0c);
75
- color: var(--color-fd-foreground, #fafafa);
72
+ display: flex;
73
+ flex-direction: column;
74
+ width: min(720px, calc(100% - 1rem));
75
+ border-radius: 0.75rem;
76
+ border: 1px solid color-mix(in srgb, var(--color-fd-border, #d4d4d4) 70%, transparent);
77
+ background: var(--color-fd-popover, #fafafa);
78
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
76
79
  font-family: var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text",
77
80
  ui-sans-serif, sans-serif);
78
- box-shadow:
79
- 0 24px 60px -12px rgba(0, 0, 0, 0.5),
80
- 0 0 0 1px rgba(255, 255, 255, 0.04);
81
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
81
82
  outline: none;
82
- overflow: hidden;
83
83
  overscroll-behavior: contain;
84
84
  animation: omni-scale-in 200ms cubic-bezier(0.16, 1, 0.3, 1);
85
85
  }
86
86
 
87
87
  @media (max-width: 639px) {
88
88
  .omni-content {
89
- top: 10%;
90
- width: calc(100% - 24px);
91
- max-height: 75vh;
92
- }
93
- .omni-kbd {
94
- display: none;
89
+ --omni-content-top: 1rem;
90
+ top: var(--omni-content-top);
91
+ width: calc(100% - 1rem);
92
+ max-height: calc(100vh - 2rem);
95
93
  }
96
94
  }
97
95
 
@@ -103,54 +101,77 @@
103
101
  display: flex;
104
102
  align-items: center;
105
103
  gap: 0.5rem;
106
- padding: 0.625rem 0.875rem;
104
+ padding: 0.75rem;
107
105
  }
108
106
  .omni-search-icon {
109
107
  color: var(--color-fd-muted-foreground, #a3a3a3);
110
108
  flex-shrink: 0;
111
109
  }
110
+ .omni-search-icon svg {
111
+ width: 1.25rem;
112
+ height: 1.25rem;
113
+ }
112
114
  .omni-search-input {
115
+ width: 0;
113
116
  flex: 1;
114
117
  background: transparent;
115
118
  outline: none;
116
- font-size: 0.875rem;
117
- line-height: 1.25rem;
118
- color: var(--color-fd-foreground, #fafafa);
119
+ font-size: 1.125rem;
120
+ line-height: 1.75rem;
121
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
119
122
  border: none;
120
123
  }
121
124
  .omni-search-input::placeholder {
122
125
  color: var(--color-fd-muted-foreground, #a3a3a3);
123
126
  }
124
127
  .omni-kbd {
125
- border-radius: 0.25rem;
126
- background: var(--color-fd-muted, #262626);
127
- padding: 0.125rem 0.375rem;
128
- font-size: 10px;
128
+ border-radius: 0.375rem;
129
+ border: 1px solid var(--color-fd-border, #d4d4d4);
130
+ background: transparent;
131
+ padding: 0.375rem 0.5rem;
132
+ font-size: 0.75rem;
129
133
  color: var(--color-fd-muted-foreground, #a3a3a3);
130
134
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
131
135
  "Liberation Mono", "Courier New", monospace);
132
- line-height: 1.4;
136
+ line-height: 1rem;
133
137
  }
134
138
  .omni-close-btn {
135
- margin-left: 0.25rem;
136
- border-radius: 0.25rem;
137
- padding: 0.25rem;
139
+ display: inline-flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ gap: 0.25rem;
143
+ min-width: 2.5rem;
144
+ border-radius: 0.375rem;
145
+ border: 1px solid var(--color-fd-border, #d4d4d4);
146
+ padding: 0.375rem 0.5rem;
138
147
  color: var(--color-fd-muted-foreground, #a3a3a3);
139
- transition: background 120ms;
148
+ font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
149
+ "Liberation Mono", "Courier New", monospace);
150
+ font-size: 0.75rem;
151
+ line-height: 1rem;
152
+ font-weight: 500;
153
+ transition:
154
+ background 120ms,
155
+ color 120ms;
140
156
  cursor: pointer;
141
- border: none;
142
157
  background: none;
143
158
  }
144
159
  .omni-close-btn:hover {
145
- background: var(--color-fd-muted, #262626);
160
+ color: var(--color-fd-accent-foreground, var(--color-fd-foreground, #171717));
161
+ background: var(--color-fd-accent, #e5e5e5);
162
+ }
163
+ .omni-close-btn svg {
164
+ display: none;
146
165
  }
147
166
 
148
167
  /* Body / listbox */
149
168
  .omni-body {
150
- max-height: 60vh;
169
+ flex: 1 1 auto;
170
+ min-height: 0;
171
+ max-height: min(540px, calc(100vh - var(--omni-content-top, 7rem) - 8rem));
151
172
  overflow: auto;
152
173
  overscroll-behavior: contain;
153
- padding: 0.25rem;
174
+ padding: 0.5rem;
154
175
  }
155
176
  .omni-body::-webkit-scrollbar {
156
177
  width: 6px;
@@ -168,36 +189,32 @@
168
189
  display: flex;
169
190
  align-items: center;
170
191
  gap: 0.5rem;
171
- padding: 0.5rem 0.75rem;
192
+ padding: 0.75rem 0.625rem;
172
193
  color: var(--color-fd-muted-foreground, #a3a3a3);
173
- font-size: 0.75rem;
194
+ font-size: 0.875rem;
174
195
  }
175
196
 
176
197
  /* Groups */
177
198
  .omni-group {
178
- padding: 0.25rem 0;
199
+ padding: 0;
179
200
  }
180
201
  .omni-group-label {
181
- padding: 0.25rem 0.75rem;
182
- font-size: 10px;
183
- text-transform: uppercase;
184
- letter-spacing: 0.06em;
185
- color: var(--color-fd-muted-foreground, #a3a3a3);
186
- font-weight: 500;
202
+ display: none;
187
203
  }
188
204
  .omni-group-items {
189
205
  display: flex;
190
206
  flex-direction: column;
207
+ gap: 0.25rem;
191
208
  }
192
209
 
193
210
  /* Items */
194
211
  .omni-item {
195
- display: flex;
212
+ position: relative;
213
+ display: block;
196
214
  width: 100%;
197
- align-items: center;
198
- gap: 0.75rem;
199
- border-radius: calc(var(--radius, 0.75rem) - 4px);
200
- padding: 0.5rem 0.75rem;
215
+ flex-shrink: 0;
216
+ border-radius: 0.5rem;
217
+ padding: 0.75rem 0.875rem;
201
218
  text-align: left;
202
219
  font-size: 0.875rem;
203
220
  line-height: 1.25rem;
@@ -209,10 +226,10 @@
209
226
  }
210
227
  .omni-item:hover,
211
228
  .omni-item-active {
212
- background: color-mix(in srgb, var(--color-fd-accent, #262626) 60%, transparent);
229
+ background: var(--color-fd-accent, rgba(209, 209, 209, 0.5));
213
230
  }
214
231
  .omni-item-active {
215
- color: var(--color-fd-accent-foreground, #fafafa);
232
+ color: var(--color-fd-accent-foreground, #171717);
216
233
  }
217
234
  .omni-item-disabled {
218
235
  opacity: 0.5;
@@ -220,51 +237,56 @@
220
237
  }
221
238
 
222
239
  .omni-item-icon {
223
- flex-shrink: 0;
224
- color: var(--color-fd-muted-foreground, #a3a3a3);
240
+ display: none;
225
241
  }
226
242
  .omni-item-active .omni-item-icon {
227
243
  color: var(--color-fd-accent-foreground, #fafafa);
228
244
  }
229
245
  .omni-item-text {
230
- flex: 1;
231
246
  min-width: 0;
232
247
  }
233
248
  .omni-item-label {
249
+ min-width: 0;
234
250
  overflow: hidden;
235
251
  text-overflow: ellipsis;
236
252
  white-space: nowrap;
253
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
254
+ font-weight: 500;
255
+ line-height: 1.35;
237
256
  }
238
257
  .omni-item-subtitle {
258
+ min-width: 0;
239
259
  overflow: hidden;
240
260
  text-overflow: ellipsis;
241
261
  white-space: nowrap;
242
262
  font-size: 0.75rem;
263
+ line-height: 1rem;
243
264
  color: var(--color-fd-muted-foreground, #a3a3a3);
244
- opacity: 0.8;
265
+ opacity: 1;
245
266
  }
246
267
  .omni-item-active .omni-item-subtitle {
247
- color: var(--color-fd-accent-foreground, #fafafa);
248
- opacity: 0.7;
268
+ color: var(--color-fd-muted-foreground, #737373);
269
+ opacity: 1;
270
+ }
271
+ .omni-item-description {
272
+ min-width: 0;
273
+ overflow: hidden;
274
+ display: -webkit-box;
275
+ -webkit-line-clamp: 3;
276
+ -webkit-box-orient: vertical;
277
+ margin-top: 0.625rem;
278
+ padding-left: 0.75rem;
279
+ border-left: 1px solid color-mix(in srgb, var(--color-fd-border, #d4d4d4) 70%, transparent);
280
+ color: color-mix(in srgb, var(--color-fd-popover-foreground, #272727) 82%, transparent);
281
+ font-size: 0.875rem;
282
+ line-height: 1.5rem;
283
+ font-weight: 400;
249
284
  }
250
285
  .omni-item-badge {
251
- color: var(--color-fd-muted-foreground, #a3a3a3);
252
- flex-shrink: 0;
286
+ display: none;
253
287
  }
254
288
  .omni-item-ext {
255
- position: relative;
256
- z-index: 2;
257
- display: inline-flex;
258
- align-items: center;
259
- justify-content: center;
260
- padding: 0.25rem;
261
- border-radius: 0.25rem;
262
- color: var(--color-fd-muted-foreground, #a3a3a3);
263
- flex-shrink: 0;
264
- transition:
265
- color 100ms,
266
- background 100ms;
267
- text-decoration: none;
289
+ display: none;
268
290
  }
269
291
  .omni-item-ext:hover {
270
292
  color: var(--color-fd-foreground, #fafafa);
@@ -290,24 +312,16 @@
290
312
  "Liberation Mono", "Courier New", monospace);
291
313
  }
292
314
  .omni-item-chevron {
293
- width: 0.875rem;
294
- height: 0.875rem;
295
- margin-left: 0.25rem;
296
- color: var(--color-fd-muted-foreground, #a3a3a3);
297
- opacity: 0;
298
- transition: opacity 120ms;
299
- flex-shrink: 0;
300
- }
301
- .omni-item:hover .omni-item-chevron {
302
- opacity: 1;
315
+ display: none;
303
316
  }
304
-
305
317
  /* Highlight */
306
318
  .omni-highlight {
307
- border-radius: 2px;
308
- background: color-mix(in srgb, var(--color-fd-primary, #6366f1) 30%, transparent);
309
- padding: 0 2px;
310
- color: inherit;
319
+ border-radius: 0;
320
+ background: transparent;
321
+ padding: 0;
322
+ color: var(--color-fd-primary, #ca8a04);
323
+ text-decoration: underline;
324
+ text-underline-offset: 2px;
311
325
  }
312
326
 
313
327
  /* Empty states */
@@ -317,7 +331,7 @@
317
331
  color: var(--color-fd-muted-foreground, #a3a3a3);
318
332
  }
319
333
  .omni-empty {
320
- padding: 2rem 0.75rem;
334
+ padding: 1.5rem 0.75rem;
321
335
  text-align: center;
322
336
  font-size: 0.875rem;
323
337
  color: var(--color-fd-muted-foreground, #a3a3a3);
@@ -336,30 +350,105 @@
336
350
  /* Footer */
337
351
  .omni-footer {
338
352
  border-top: 1px solid var(--color-fd-border, #262626);
353
+ background: color-mix(in srgb, var(--color-fd-secondary, #f5f5f5) 50%, transparent);
339
354
  }
340
355
  .omni-footer-inner {
341
356
  display: flex;
342
357
  align-items: center;
343
358
  justify-content: space-between;
344
- padding: 0.5rem 0.75rem;
359
+ gap: 0.75rem;
360
+ padding: 0.625rem 0.75rem;
345
361
  font-size: 0.75rem;
346
362
  color: var(--color-fd-muted-foreground, #a3a3a3);
347
363
  }
348
364
  .omni-footer-hints {
349
365
  display: flex;
350
366
  align-items: center;
351
- gap: 1rem;
367
+ flex-wrap: wrap;
368
+ gap: 0.75rem;
352
369
  }
353
370
  .omni-footer-hint {
354
371
  display: flex;
355
372
  align-items: center;
356
373
  gap: 0.25rem;
374
+ white-space: nowrap;
375
+ }
376
+ .omni-footer-hint svg {
377
+ box-sizing: border-box;
378
+ width: 1.375rem;
379
+ height: 1.375rem;
380
+ padding: 0.25rem;
381
+ border-radius: 0.375rem;
382
+ border: 1px solid var(--color-fd-border, #d4d4d4);
383
+ background: color-mix(in srgb, var(--color-fd-muted, #e5e5e5) 70%, transparent);
384
+ color: var(--color-fd-muted-foreground, #737373);
385
+ flex-shrink: 0;
357
386
  }
358
387
  .omni-footer-hint-desktop {
359
388
  display: none;
360
389
  }
390
+ .omni-footer-filter {
391
+ position: relative;
392
+ display: inline-flex;
393
+ align-items: center;
394
+ gap: 0.5rem;
395
+ margin-left: auto;
396
+ white-space: nowrap;
397
+ }
361
398
  @media (min-width: 640px) {
362
399
  .omni-footer-hint-desktop {
363
400
  display: flex;
364
401
  }
365
402
  }
403
+ .omni-filter-label {
404
+ color: var(--color-fd-muted-foreground, #a3a3a3);
405
+ }
406
+ .omni-filter-value {
407
+ display: inline-flex;
408
+ align-items: center;
409
+ gap: 0.25rem;
410
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
411
+ }
412
+ .omni-filter-button {
413
+ display: inline-flex;
414
+ align-items: center;
415
+ gap: 0.25rem;
416
+ border: 0;
417
+ background: transparent;
418
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
419
+ font: inherit;
420
+ cursor: pointer;
421
+ padding: 0;
422
+ }
423
+ .omni-filter-button:hover {
424
+ color: var(--color-fd-accent-foreground, var(--color-fd-foreground, #171717));
425
+ }
426
+ .omni-filter-menu {
427
+ position: absolute;
428
+ right: 0;
429
+ bottom: calc(100% + 0.5rem);
430
+ z-index: 1;
431
+ width: 10rem;
432
+ border: 1px solid var(--color-fd-border, #d4d4d4);
433
+ border-radius: 0.5rem;
434
+ background: var(--color-fd-popover, #fafafa);
435
+ padding: 0.25rem;
436
+ box-shadow: 0 16px 32px -20px rgba(0, 0, 0, 0.45);
437
+ }
438
+ .omni-filter-option {
439
+ display: flex;
440
+ width: 100%;
441
+ align-items: center;
442
+ border: 0;
443
+ border-radius: 0.375rem;
444
+ background: transparent;
445
+ color: var(--color-fd-popover-foreground, var(--color-fd-foreground, #272727));
446
+ cursor: pointer;
447
+ font: inherit;
448
+ padding: 0.5rem 0.625rem;
449
+ text-align: left;
450
+ }
451
+ .omni-filter-option:hover,
452
+ .omni-filter-option-active {
453
+ background: var(--color-fd-accent, rgba(209, 209, 209, 0.5));
454
+ }
@@ -965,7 +965,7 @@ hr {
965
965
  }
966
966
 
967
967
  .omni-search-input {
968
- font-family: var(--fd-font-mono, ui-monospace, monospace);
968
+ font-family: var(--fd-font-sans, system-ui, -apple-system, sans-serif);
969
969
  }
970
970
 
971
971
  .omni-group-label {
@@ -977,6 +977,15 @@ hr {
977
977
  font-family: var(--fd-font-mono, ui-monospace, monospace);
978
978
  }
979
979
 
980
+ .omni-footer-hint svg {
981
+ border-radius: 0 !important;
982
+ }
983
+
984
+ .omni-filter-menu,
985
+ .omni-filter-option {
986
+ border-radius: 0 !important;
987
+ }
988
+
980
989
  .omni-highlight {
981
990
  background: color-mix(in srgb, var(--color-fd-primary, #6366f1) 25%, transparent);
982
991
  border-radius: 0 !important;
@@ -693,7 +693,7 @@ figure.shiki button[aria-label*="Copy"]:hover {
693
693
  inset-inline-start: var(--fd-threadline-frame-gutter) !important;
694
694
  width: var(--fd-sidebar-width, 260px) !important;
695
695
  height: calc(100vh - var(--docs-header-height, 48px)) !important;
696
- z-index: 102 !important;
696
+ z-index: 49 !important;
697
697
  pointer-events: none !important;
698
698
  }
699
699
 
@@ -710,24 +710,19 @@ figure.shiki button[aria-label*="Copy"]:hover {
710
710
  ) !important;
711
711
  width: var(--fd-toc-width, 224px) !important;
712
712
  height: calc(100vh - var(--docs-header-height, 48px)) !important;
713
+ z-index: 49 !important;
713
714
  pointer-events: none !important;
714
715
  }
715
716
 
716
717
  body:has(#nd-sidebar) .omni-overlay {
717
- left: calc(var(--fd-threadline-frame-gutter) + var(--fd-sidebar-width, 260px)) !important;
718
+ left: 0 !important;
718
719
  right: 0 !important;
719
720
  width: auto !important;
720
721
  }
721
722
 
722
723
  body:has(#nd-sidebar) .omni-content {
723
- left: calc(
724
- var(--fd-threadline-frame-gutter) + var(--fd-sidebar-width, 260px) +
725
- (var(--fd-threadline-main-width) + var(--fd-toc-width, 224px)) / 2
726
- ) !important;
727
- width: min(
728
- 720px,
729
- calc(var(--fd-threadline-main-width) + var(--fd-toc-width, 224px) - 32px)
730
- ) !important;
724
+ left: 50% !important;
725
+ width: min(720px, calc(100% - 1rem)) !important;
731
726
  }
732
727
  }
733
728
 
@@ -775,6 +770,7 @@ figure.shiki button[aria-label*="Copy"]:hover {
775
770
  }
776
771
 
777
772
  .omni-group-label {
773
+ display: block !important;
778
774
  color: var(--muted-foreground) !important;
779
775
  font-size: 0.6875rem !important;
780
776
  font-weight: 500 !important;