From 77076a1c3eeed4a1d9f070336c8805ed9d6349b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 17 Jan 2026 19:12:23 +0100 Subject: [PATCH] Improve reference search/filtering semantics --- .../src/repl/components/panel/Reference.jsx | 125 +++++++++++++----- 1 file changed, 92 insertions(+), 33 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index c943db144..24d4a6773 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; @@ -46,6 +46,7 @@ const getInnerText = (html) => { export function Reference() { const [search, setSearch] = useState(''); const [selectedTag, setSelectedTag] = useState(null); + const [selectedFunction, setSelectedFunction] = useState(null); const toggleTag = (tag) => { if (selectedTag === tag) { @@ -55,7 +56,7 @@ export function Reference() { } }; - const visibleFunctions = useMemo(() => { + const searchVisibleFunctions = useMemo(() => { return availableFunctions.filter((entry) => { if (selectedTag) { if (!(entry.tags || ['untagged']).includes(selectedTag)) { @@ -63,6 +64,14 @@ export function Reference() { } } + // if (entry.name === selectedFunction) { + // return true; + // } + + // if (!selectedTag) { + // return false; + // } + if (!search) { return true; } @@ -75,6 +84,19 @@ export function Reference() { }); }, [search, selectedTag]); + const detailVisibleFunctions = useMemo(() => { + return searchVisibleFunctions.filter((x) => { + if (selectedTag === null) { + if (search) { + return true; + } + return x.name === selectedFunction; + } else { + return true; + } + }); + }, [searchVisibleFunctions, selectedFunction, selectedTag]); + const tagCounts = {}; for (const doc of availableFunctions) { (doc.tags || ['untagged']).forEach((t) => { @@ -84,42 +106,60 @@ export function Reference() { }); } + const onSearchTagFilterClick = () => { + const container = document.getElementById('reference-container'); + container.scrollTo(0, 0); + setSelectedTag(null); + setSelectedFunction(null); + }; + + useEffect(() => { + if (selectedFunction) { + const el = document.getElementById(`doc-${selectedFunction}`); + const container = document.getElementById('reference-container'); + container.scrollTo(0, el.offsetTop); + } + }, [selectedFunction]); + return ( - //
- //
- //
-
+
- -
- {Object.entries(tagCounts) - .sort(([a], [b]) => a.localeCompare(b)) - .map(([t, count]) => ( - - toggleTag(t)} - > - {t} ({count}) - {' '} - - ))} -
+ { + setSelectedFunction(null); + setSearch(e); + }} + />
-
- {visibleFunctions.map((entry, i) => ( + {selectedTag && ( +
+ + {selectedTag ? selectedTag + ' x' : 'Filter by tag'} + +
+ )} +
+ {searchVisibleFunctions.map((entry, i) => ( <> { - const el = document.getElementById(`doc-${entry.name}`); - const container = document.getElementById('reference-container'); - container.scrollTo(0, el.offsetTop); + if (entry.name === selectedFunction) { + setSelectedFunction(null); + } else { + setSelectedFunction(entry.name); + } }} > {entry.name} @@ -134,11 +174,28 @@ export function Reference() { >

API Reference

-

+

This is the long list of functions you can use. Remember that you don't need to remember all of those and that you can already make music with a small set of functions!

- {visibleFunctions.map((entry, i) => ( +
+ {detailVisibleFunctions.map((entry, i) => (

@@ -170,7 +227,9 @@ export function Reference() { ))}

- ))} + )) ||

Searcb or select a tag to get started.

} + {detailVisibleFunctions.length > 0 &&
} + {/* {!selectedTag &&

Select a tag to see the functions.

} */}