From 102dc0f5a69e8fcf7a6f83bafa37056b4df1dd19 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 10 Oct 2025 12:47:27 +0000
Subject: [PATCH 1/7] Initial plan
From ff9c65d4356187a403489bda4a62920aa89959a8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 10 Oct 2025 12:50:12 +0000
Subject: [PATCH 2/7] Initial plan for Algolia InstantSearch integration
Co-authored-by: joaodibba <113291032+joaodibba@users.noreply.github.com>
---
package-lock.json | 146 +++++-----------------------------------------
1 file changed, 16 insertions(+), 130 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 60bbdc0..6808e97 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,19 +27,6 @@
"vite": "^7.1.9"
}
},
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@codesandbox/nodebox": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/@codesandbox/nodebox/-/nodebox-0.1.8.tgz",
@@ -601,44 +588,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/@open-draft/deferred-promise": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
@@ -1682,13 +1631,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -1790,16 +1732,6 @@
"ieee754": "^1.2.1"
}
},
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/caniuse-lite": {
"version": "1.0.30001749",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001749.tgz",
@@ -1992,19 +1924,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/dompurify": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
- "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
- "license": "(MPL-2.0 OR Apache-2.0)"
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/dotenv": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
@@ -2017,13 +1936,6 @@
"url": "https://dotenvx.com"
}
},
- "node_modules/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/electron-to-chromium": {
"version": "1.5.234",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz",
@@ -2740,9 +2652,9 @@
}
},
"node_modules/lucide": {
- "version": "0.545.0",
- "resolved": "https://registry.npmjs.org/lucide/-/lucide-0.545.0.tgz",
- "integrity": "sha512-mrBH0upkb1TH8ZLkf0XERQAKMdTJ1C+Offr7eSvanmdQ7JrV8jkrFw5jgRAS8fygiZgG4X9mfEg/BXCL+mNMRw==",
+ "version": "0.544.0",
+ "resolved": "https://registry.npmjs.org/lucide/-/lucide-0.544.0.tgz",
+ "integrity": "sha512-U5ORwr5z9Sx7bNTDFaW55RbjVdQEnAcT3vws9uz3vRT1G4XXJUDAhRZdxhFoIyHEvjmTkzzlEhjSLYM5n4mb5w==",
"license": "ISC"
},
"node_modules/magic-string": {
@@ -2777,18 +2689,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/marked": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz",
- "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==",
- "license": "MIT",
- "bin": {
- "marked": "bin/marked.js"
- },
- "engines": {
- "node": ">= 18"
- }
- },
"node_modules/mdast-util-find-and-replace": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
@@ -3841,6 +3741,19 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/minizlib": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
+ "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -3889,39 +3802,12 @@
"node": ">=0.10.0"
}
},
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/outvariant": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.0.tgz",
"integrity": "sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==",
"license": "MIT"
},
- "node_modules/package-json-from-dist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
- "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
- "license": "BlueOak-1.0.0"
- },
"node_modules/parse-entities": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
From 5b0ece34095e7e660e338ed7e1cce94ec158ebf8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 10 Oct 2025 12:55:39 +0000
Subject: [PATCH 3/7] Add Algolia InstantSearch integration components
Co-authored-by: joaodibba <113291032+joaodibba@users.noreply.github.com>
---
package-lock.json | 382 +++++++++++++++++++++++++
package.json | 4 +-
src/components/navbar/NavBar.ts | 28 +-
src/components/search/AlgoliaSearch.ts | 96 +++++++
src/components/search/SearchModal.ts | 80 ++++++
src/components/search/search.scss | 226 +++++++++++++++
6 files changed, 813 insertions(+), 3 deletions(-)
create mode 100644 src/components/search/AlgoliaSearch.ts
create mode 100644 src/components/search/SearchModal.ts
create mode 100644 src/components/search/search.scss
diff --git a/package-lock.json b/package-lock.json
index 6808e97..dfb12f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,9 @@
"dependencies": {
"@codesandbox/sandpack-client": "^2.19.8",
"@mdx-js/mdx": "^3.1.1",
+ "algoliasearch": "^5.40.0",
"highlight.js": "^11.11.1",
+ "instantsearch.js": "^4.80.0",
"lucide": "^0.544.0",
"remark-gfm": "^4.0.1",
"typecomposer": "^0.1.54",
@@ -27,6 +29,216 @@
"vite": "^7.1.9"
}
},
+ "node_modules/@algolia/abtesting": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.6.0.tgz",
+ "integrity": "sha512-c4M/Z/KWkEG+RHpZsWKDTTlApXu3fe4vlABNcpankWBhdMe4oPZ/r4JxEr2zKUP6K+BT66tnp8UbHmgOd/vvqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.40.0.tgz",
+ "integrity": "sha512-qegVlgHtmiS8m9nEsuKUVhlw1FHsIshtt5nhNnA6EYz3g+tm9+xkVZZMzkrMLPP7kpoheHJZAwz2MYnHtwFa9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.40.0.tgz",
+ "integrity": "sha512-Dw2c+6KGkw7mucnnxPyyMsIGEY8+hqv6oB+viYB612OMM3l8aNaWToBZMnNvXsyP+fArwq7XGR+k3boPZyV53A==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.40.0.tgz",
+ "integrity": "sha512-dbE4+MJIDsTghG3hUYWBq7THhaAmqNqvW9g2vzwPf5edU4IRmuYpKtY3MMotes8/wdTasWG07XoaVhplJBlvdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.40.0.tgz",
+ "integrity": "sha512-SH6zlROyGUCDDWg71DlCnbbZ/zEHYPZC8k901EAaBVhvY43Ju8Wa6LAcMPC4tahcDBgkG2poBy8nJZXvwEWAlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.40.0.tgz",
+ "integrity": "sha512-EgHjJEEf7CbUL9gJHI1ULmAtAFeym2cFNSAi1uwHelWgLPcnLjYW2opruPxigOV7NcetkGu+t2pcWOWmZFuvKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.40.0.tgz",
+ "integrity": "sha512-HvE1jtCag95DR41tDh7cGwrMk4X0aQXPOBIhZRmsBPolMeqRJz0kvfVw8VCKvA1uuoAkjFfTG0X0IZED+rKXoA==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.40.0.tgz",
+ "integrity": "sha512-nlr/MMgoLNUHcfWC5Ns2ENrzKx9x51orPc6wJ8Ignv1DsrUmKm0LUih+Tj3J+kxYofzqQIQRU495d4xn3ozMbg==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/events": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz",
+ "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==",
+ "license": "MIT"
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.40.0.tgz",
+ "integrity": "sha512-OfHnhE+P0f+p3i90Kmshf9Epgesw5oPV1IEUOY4Mq1HV7cQk16gvklVN1EaY/T9sVavl+Vc3g4ojlfpIwZFA4g==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.40.0.tgz",
+ "integrity": "sha512-SWANV32PTKhBYvwKozeWP9HOnVabOixAuPdFFGoqtysTkkwutrtGI/rrh80tvG+BnQAmZX0vUmD/RqFZVfr/Yg==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.40.0.tgz",
+ "integrity": "sha512-1Qxy9I5bSb3mrhPk809DllMa561zl5hLsMR6YhIqNkqQ0OyXXQokvJ2zApSxvd39veRZZnhN+oGe+XNoNwLgkw==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.40.0.tgz",
+ "integrity": "sha512-MGt94rdHfkrVjfN/KwUfWcnaeohYbWGINrPs96f5J7ZyRYpVLF+VtPQ2FmcddFvK4gnKXSu8BAi81hiIhUpm3w==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.40.0.tgz",
+ "integrity": "sha512-wXQ05JZZ10Dr642QVAkAZ4ZZlU+lh5r6dIBGmm9WElz+1EaQ6BNYtEOTV6pkXuFYsZpeJA89JpDOiwBOP9j24w==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.40.0.tgz",
+ "integrity": "sha512-5qCRoySnzpbQVg2IPLGFCm4LF75pToxI5tdjOYgUMNL/um91aJ4dH3SVdBEuFlVsalxl8mh3bWPgkUmv6NpJiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@codesandbox/nodebox": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/@codesandbox/nodebox/-/nodebox-0.1.8.tgz",
@@ -1486,6 +1698,12 @@
"@types/ms": "*"
}
},
+ "node_modules/@types/dom-speech-recognition": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.1.tgz",
+ "integrity": "sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==",
+ "license": "MIT"
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1501,6 +1719,12 @@
"@types/estree": "*"
}
},
+ "node_modules/@types/google.maps": {
+ "version": "3.58.1",
+ "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.1.tgz",
+ "integrity": "sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==",
+ "license": "MIT"
+ },
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
@@ -1510,6 +1734,12 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/hogan.js": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hogan.js/-/hogan.js-3.0.5.tgz",
+ "integrity": "sha512-/uRaY3HGPWyLqOyhgvW9Aa43BNnLZrNeQxl2p8wqId4UHMfPKolSB+U7BlZyO1ng7MkLnyEAItsBzCG0SDhqrA==",
+ "license": "MIT"
+ },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -1541,6 +1771,12 @@
"undici-types": "~7.14.0"
}
},
+ "node_modules/@types/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "license": "MIT"
+ },
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -1553,6 +1789,12 @@
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"license": "ISC"
},
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "license": "ISC"
+ },
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@@ -1574,6 +1816,43 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/algoliasearch": {
+ "version": "5.40.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.40.0.tgz",
+ "integrity": "sha512-a9aIL2E3Z7uYUPMCmjMFFd5MWhn+ccTubEvnMy7rOTZCB62dXBJtz0R5BZ/TPuX3R9ocBsgWuAbGWQ+Ph4Fmlg==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/abtesting": "1.6.0",
+ "@algolia/client-abtesting": "5.40.0",
+ "@algolia/client-analytics": "5.40.0",
+ "@algolia/client-common": "5.40.0",
+ "@algolia/client-insights": "5.40.0",
+ "@algolia/client-personalization": "5.40.0",
+ "@algolia/client-query-suggestions": "5.40.0",
+ "@algolia/client-search": "5.40.0",
+ "@algolia/ingestion": "1.40.0",
+ "@algolia/monitoring": "1.40.0",
+ "@algolia/recommend": "5.40.0",
+ "@algolia/requester-browser-xhr": "5.40.0",
+ "@algolia/requester-fetch": "5.40.0",
+ "@algolia/requester-node-http": "5.40.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/algoliasearch-helper": {
+ "version": "3.26.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.0.tgz",
+ "integrity": "sha512-Rv2x3GXleQ3ygwhkhJubhhYGsICmShLAiqtUuJTUkr9uOCOXyF2E71LVT4XDnVffbknv8XgScP4U0Oxtgm+hIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/events": "^4.0.1"
+ },
+ "peerDependencies": {
+ "algoliasearch": ">= 3.1 < 6"
+ }
+ },
"node_modules/astring": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz",
@@ -2280,6 +2559,24 @@
"node": ">=12.0.0"
}
},
+ "node_modules/hogan.js": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz",
+ "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==",
+ "dependencies": {
+ "mkdirp": "0.3.0",
+ "nopt": "1.0.10"
+ },
+ "bin": {
+ "hulk": "bin/hulk"
+ }
+ },
+ "node_modules/htm": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz",
+ "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==",
+ "license": "Apache-2.0"
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -2313,6 +2610,38 @@
"integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
"license": "MIT"
},
+ "node_modules/instantsearch-ui-components": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/instantsearch-ui-components/-/instantsearch-ui-components-0.11.2.tgz",
+ "integrity": "sha512-XxwqUY6NifxSvHYfyfJRiGhqYqHXQFcFNOEjNyFptB9HOkx14yCdayKar4BZxGx353FnFD6b4Z8LdzbGud+RFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.27.6"
+ }
+ },
+ "node_modules/instantsearch.js": {
+ "version": "4.80.0",
+ "resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.80.0.tgz",
+ "integrity": "sha512-l2HTW6+tBs2hGrby43Y7HbWayTifFFKk/ikRU5BXFpCigG6CRAYZLE1NFifAskaj3SVQiY8O8B/T6hJyeMsScA==",
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/events": "^4.0.1",
+ "@types/dom-speech-recognition": "^0.0.1",
+ "@types/google.maps": "^3.55.12",
+ "@types/hogan.js": "^3.0.0",
+ "@types/qs": "^6.5.3",
+ "algoliasearch-helper": "3.26.0",
+ "hogan.js": "^3.0.2",
+ "htm": "^3.0.0",
+ "instantsearch-ui-components": "0.11.2",
+ "preact": "^10.10.0",
+ "qs": "^6.5.1 < 6.10",
+ "search-insights": "^2.17.2"
+ },
+ "peerDependencies": {
+ "algoliasearch": ">= 3.1 < 6"
+ }
+ },
"node_modules/is-alphabetical": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -3754,6 +4083,16 @@
"node": ">= 18"
}
},
+ "node_modules/mkdirp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
+ "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==",
+ "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
+ "license": "MIT/X11",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -3792,6 +4131,21 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+ "license": "MIT",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/normalize-range": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
@@ -3893,6 +4247,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/preact": {
+ "version": "10.27.2",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz",
+ "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/property-information": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
@@ -3903,6 +4267,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@@ -4141,6 +4517,12 @@
"@parcel/watcher": "^2.4.1"
}
},
+ "node_modules/search-insights": {
+ "version": "2.17.3",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
+ "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
+ "license": "MIT"
+ },
"node_modules/source-map": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
diff --git a/package.json b/package.json
index 9e0c2d5..e5a11cf 100644
--- a/package.json
+++ b/package.json
@@ -14,19 +14,21 @@
"dependencies": {
"@codesandbox/sandpack-client": "^2.19.8",
"@mdx-js/mdx": "^3.1.1",
+ "algoliasearch": "^5.40.0",
"highlight.js": "^11.11.1",
+ "instantsearch.js": "^4.80.0",
"lucide": "^0.544.0",
"remark-gfm": "^4.0.1",
"typecomposer": "^0.1.54",
"typecomposer-plugin": "^1.0.10"
},
"devDependencies": {
+ "@tailwindcss/vite": "^4.1.14",
"@types/node": "^24.7.1",
"autoprefixer": "^10.4.21",
"csstype": "^3.1.3",
"sass": "^1.93.2",
"tailwindcss": "^4.1.14",
- "@tailwindcss/vite": "^4.1.14",
"typescript": "^5.9.3",
"vite": "^7.1.9"
}
diff --git a/src/components/navbar/NavBar.ts b/src/components/navbar/NavBar.ts
index a3dd030..a1aaabc 100644
--- a/src/components/navbar/NavBar.ts
+++ b/src/components/navbar/NavBar.ts
@@ -1,5 +1,7 @@
import { AnchorElement, Component, DivElement, ImageElement, Router, SvgElement, App, ref, computed, ButtonElement, BorderPanel } from "typecomposer";
-import { Sun, Moon, createElement, Menu } from "lucide";
+import { Sun, Moon, createElement, Menu, Search } from "lucide";
+import { SearchModal } from "@/components/search/SearchModal";
+import "@/components/search/search.scss";
class ThemeToggle extends Component {
constructor() {
@@ -34,17 +36,35 @@ class NavLinks extends Component {
this.append(new AnchorElement({ rlink: "docs", text: "Docs" }));
this.append(new AnchorElement({ rlink: "playground", text: "Playground" }));
this.append(new AnchorElement({ text: "GitHub", href: "https://github.com/typecomposer/typecomposer" }));
- this.append(new ThemeToggle());
}
}
export class NavBar extends Component {
open = false;
+ private searchModal: SearchModal;
constructor() {
super({ className: "flex items-center justify-between w-screen h-16 px-6 navbar" });
this.append(new Logo());
this.append(new NavLinks());
+
+ // Add search button
+ this.append(
+ new ButtonElement({
+ className: "search-button flex items-center gap-2 px-3 py-2 rounded-md",
+ children: [
+ createElement(Search),
+ new DivElement({
+ className: "search-shortcut hidden md:block",
+ textContent: "⌘K"
+ })
+ ],
+ onclick: () => this.searchModal.open(),
+ })
+ );
+
+ this.append(new ThemeToggle());
+
this.append(
new ButtonElement({
className: "btn-sidebar m-2",
@@ -56,6 +76,10 @@ export class NavBar extends Component {
})
);
this.btn();
+
+ // Add search modal
+ this.searchModal = new SearchModal();
+ this.append(this.searchModal);
}
btn() {
diff --git a/src/components/search/AlgoliaSearch.ts b/src/components/search/AlgoliaSearch.ts
new file mode 100644
index 0000000..f9955be
--- /dev/null
+++ b/src/components/search/AlgoliaSearch.ts
@@ -0,0 +1,96 @@
+import { Component, DivElement, InputElement } from "typecomposer";
+import { liteClient as algoliasearch } from "algoliasearch/lite";
+import instantsearch from "instantsearch.js";
+import { searchBox, hits, configure } from "instantsearch.js/es/widgets";
+
+// Algolia credentials - these should be replaced with actual values
+const ALGOLIA_APP_ID = "YOUR_APP_ID";
+const ALGOLIA_SEARCH_API_KEY = "YOUR_SEARCH_API_KEY";
+const ALGOLIA_INDEX_NAME = "typecomposer_docs";
+
+export class AlgoliaSearch extends Component {
+ private searchInstance: any;
+ private searchContainer: DivElement;
+
+ constructor() {
+ super({
+ className: "algolia-search-container",
+ });
+
+ // Create container for search
+ this.searchContainer = new DivElement({
+ className: "search-wrapper",
+ });
+ }
+
+ onInit(): void {
+ // Initialize Algolia search client
+ const searchClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY);
+
+ // Create InstantSearch instance
+ this.searchInstance = instantsearch({
+ indexName: ALGOLIA_INDEX_NAME,
+ searchClient,
+ insights: false,
+ });
+
+ // Configure search widgets
+ this.searchInstance.addWidgets([
+ configure({
+ hitsPerPage: 8,
+ }),
+
+ searchBox({
+ container: "#searchbox",
+ placeholder: "Search documentation...",
+ showReset: true,
+ showSubmit: false,
+ cssClasses: {
+ root: "search-box-root",
+ form: "search-box-form",
+ input: "search-box-input",
+ reset: "search-box-reset",
+ },
+ }),
+
+ hits({
+ container: "#hits",
+ cssClasses: {
+ root: "hits-root",
+ list: "hits-list",
+ item: "hits-item",
+ },
+ templates: {
+ item: (hit: any, { html, components }: any) => html`
+
+