feat(docs): Adds search field to docs pages (#5012)

* Add docs search to the sidebar

* Fix types
This commit is contained in:
Eric Fennis
2026-10-16 15:22:57 +02:00
committed by GitHub
parent 7b0196e249
commit cfea992598
11 changed files with 356 additions and 73 deletions
+14
View File
@@ -68,6 +68,12 @@ export default defineConfig({
new URL('./theme/components/overrides/VPCarbonAds.vue', import.meta.url),
),
},
{
find: /^.*\/VPNavBarSearch\.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/overrides/VPNavBarSearch.vue', import.meta.url),
),
},
{
find: '~/.vitepress',
replacement: fileURLToPath(new URL('./', import.meta.url)),
@@ -125,6 +131,14 @@ export default defineConfig({
editLink: {
pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path',
},
search: {
provider: 'algolia',
options: {
appId: 'R7KKMCPXOB',
apiKey: 'dd3101054267d35fb28f49c42715f1aa',
indexName: 'lucide',
},
},
carbonAds: {
code: 'CWYIC53U',
placement: 'lucidedev',
+41 -6
View File
@@ -1,7 +1,19 @@
import { PageData } from 'vitepress';
/**
* Mirrors the notices in the repo's LICENSE file, which is bumped by hand — keep the
* year here in step with it.
*/
const LUCIDE_COPYRIGHT = 'Copyright (c) 2026 Lucide Icons and Contributors';
const FEATHER_COPYRIGHT = 'Copyright (c) 2013-present Cole Bemis';
const LICENSE_URL = 'https://lucide.dev/license';
export default async function getStructuredData(iconName: string, pageData: PageData) {
const url = `https://lucide.dev/icons/${iconName}`;
const params = pageData.params ?? {};
const isLab = params.externalLibrary === 'lab';
const url = `https://lucide.dev/icons/${isLab ? 'lab/' : ''}${iconName}`;
const awaitingRelease = Boolean(params.awaitingRelease);
return {
'@context': 'https://schema.org',
@@ -29,18 +41,41 @@ export default async function getStructuredData(iconName: string, pageData: Page
name: iconName,
// TODO: Add support for description extraction from icon metadata
// description: 'An ...SVG icon from the Lucide icon set.',
contentUrl: `https://lucide.dev/api/icons/${iconName}}?width=24&height=24&background=white`,
thumbnailUrl: `https://lucide.dev/api/icons/${iconName}}?width=256&height=256&background=white`,
// `/api/icons/<name>` only renders core icons, a lab name would 404 there.
...(isLab
? {}
: {
contentUrl: `https://lucide.dev/api/icons/${iconName}?width=24&height=24&background=white`,
thumbnailUrl: `https://lucide.dev/api/icons/${iconName}?width=256&height=256&background=white`,
}),
encodingFormat: 'image/svg+xml',
keywords: pageData.params?.tags,
keywords: params.tags,
width: 24,
height: 24,
creator: {
'@type': 'Organization',
name: 'Lucide Icons',
},
datePublished: pageData?.params?.createdRelease?.date,
dateModified: pageData?.params?.changedRelease?.date,
license: LICENSE_URL,
acquireLicensePage: LICENSE_URL,
// The Feather-derived icons are MIT © Cole Bemis; everything else is ISC. Lab
// icons carry no release metadata, so they fall to the ISC-only notice.
copyrightNotice: params.fromFork
? `${LUCIDE_COPYRIGHT}; ${FEATHER_COPYRIGHT}`
: LUCIDE_COPYRIGHT,
creditText: 'Lucide Icons',
// Both dates fall back to the date of the fork for unreleased icons, so neither
...(awaitingRelease
? {}
: {
...(params.createdRelease?.date ? { datePublished: params.createdRelease.date } : {}),
...(params.changedRelease?.date ? { dateModified: params.changedRelease.date } : {}),
}),
// Custom attributes, picked up by the Algolia crawler to rank and sort the icon
// index. Not schema.org vocabulary, consumers that don't know them ignore them.
popularity: params.popularity ?? 0,
awaitingRelease,
},
};
}
@@ -1,10 +1,9 @@
<script setup lang="tsx">
import VPSidebarGroup from 'vitepress/dist/client/theme-default/components/VPSidebarGroup.vue';
import sidebar, { guideSidebarTop } from '../../../sidebar';
import sidebar from '../../../sidebar';
import { useData, useRouter } from 'vitepress';
import Select from '../base/Select.vue';
import { computed, ref, watch, watchEffect } from 'vue';
import { link, route } from '~/.vitepress/data/iconNodes';
import { computed } from 'vue';
import { useLocalStorage } from '@vueuse/core';
const { page } = useData();
@@ -75,14 +74,7 @@ function onSelectFramework(item: Framework) {
</script>
<template>
<VPSidebarGroup
:items="guideSidebarTop"
v-if="page?.relativePath?.startsWith?.('guide')"
/>
<div
class="framework-select"
v-if="page?.relativePath?.startsWith?.('guide')"
>
<div class="framework-select">
<label for="framework-select">Framework</label>
<Select
id="framework-select"
@@ -93,10 +85,7 @@ function onSelectFramework(item: Framework) {
</div>
<VPSidebarGroup
:key="selected.value"
v-if="
page?.relativePath?.startsWith?.('guide') &&
!page?.relativePath?.startsWith?.(selected.value.substring(1))
"
v-if="!page?.relativePath?.startsWith?.(selected.value.substring(1))"
:items="sidebar[selected.value]"
/>
</template>
@@ -0,0 +1,206 @@
<script lang="ts">
import { ref } from 'vue'
// This component can be rendered more than once on a page (e.g. a hidden
// copy inside `.content-body`). DocSearch mounts into the first `#docsearch`
// in the document, so only a single instance may ever render the search box.
const loaded = ref(false)
</script>
<script lang="ts" setup>
import '@docsearch/css/dist/style.css'
import {
computed,
defineAsyncComponent,
onMounted,
onUnmounted,
} from 'vue'
import type { DefaultTheme } from 'vitepress/theme'
import { useData } from 'vitepress'
import FakeInput from '../base/FakeInput.vue'
const VPAlgoliaSearchBox = defineAsyncComponent(() => import('vitepress/dist/client/theme-default/components/VPAlgoliaSearchBox.vue'));
const { theme } = useData<DefaultTheme.Config>()
const algolia = computed(
() =>
(theme.value.search?.options ?? theme.value.algolia) as DefaultTheme.AlgoliaSearchOptions,
)
// whether this instance is the one rendering the (hidden) search box
const isOwner = ref(false)
const shortcutText = ref('')
// to avoid loading the docsearch js upfront (which is more than 1/3 of the
// payload), we delay initializing it until the user has actually clicked or
// hit the hotkey to invoke it.
const preconnect = () => {
const id = 'VPAlgoliaPreconnect'
if (document.getElementById(id)) return
const rIC = window.requestIdleCallback || setTimeout
rIC(() => {
const preconnect = document.createElement('link')
preconnect.id = id
preconnect.rel = 'preconnect'
preconnect.href = `https://${algolia.value.appId}-dsn.algolia.net`
preconnect.crossOrigin = ''
document.head.appendChild(preconnect)
})
}
onMounted(() => {
preconnect()
shortcutText.value = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘K' : 'Ctrl+K'
// once docsearch is initialized it handles the hotkey itself
const handleSearchHotKey = (event: KeyboardEvent) => {
if (loaded.value) return remove()
if (
(event.key.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) ||
(!isEditingContent(event) && event.key === '/')
) {
event.preventDefault()
open()
remove()
}
}
const remove = () => {
window.removeEventListener('keydown', handleSearchHotKey)
}
window.addEventListener('keydown', handleSearchHotKey)
onUnmounted(remove)
})
function open() {
if (!loaded.value) {
loaded.value = true
isOwner.value = true
}
setTimeout(poll, 16)
}
function poll() {
// programmatically open the search box after initialize
const e = new Event('keydown') as any
e.key = 'k'
e.metaKey = true
window.dispatchEvent(e)
setTimeout(() => {
if (!document.querySelector('.DocSearch-Modal')) {
poll()
}
}, 16)
}
function isEditingContent(event: KeyboardEvent): boolean {
const element = event.target as HTMLElement
const tagName = element.tagName
return (
element.isContentEditable ||
tagName === 'INPUT' ||
tagName === 'SELECT' ||
tagName === 'TEXTAREA'
)
}
</script>
<template>
<div class="VPNavBarSearch">
<FakeInput
class="nav-search-input"
:shortcut="shortcutText"
aria-label="Search"
@click="open"
>
Search
</FakeInput>
<!-- docsearch renders its own button here; we only need its modal -->
<div v-if="isOwner" class="docsearch-host">
<VPAlgoliaSearchBox :algolia="algolia" />
</div>
</div>
</template>
<style>
@media (min-width: 768px) {
.VPNavBarSearch {
flex-grow: 1;
padding-left: 0px;
}
}
@media (min-width: 960px) {
.VPNavBarSearch {
padding-left: 0px;
}
}
.VPNavBarSearch {
padding-top: 24px;
}
.VPNavBarSearch .nav-search-input {
padding: 8px 12px;
align-items: center;
width: 100%;
}
.VPNavBarSearch .docsearch-host {
display: none;
}
[class*='DocSearch'] {
--docsearch-primary-color: var(--vp-c-brand-1);
--docsearch-highlight-color: var(--docsearch-primary-color);
--docsearch-text-color: var(--vp-c-text-1);
--docsearch-muted-color: var(--vp-c-text-2);
--docsearch-searchbox-shadow: none;
--docsearch-searchbox-background: transparent;
--docsearch-searchbox-focus-background: transparent;
--docsearch-key-gradient: transparent;
--docsearch-key-shadow: none;
--docsearch-modal-background: var(--vp-c-bg-soft);
--docsearch-footer-background: var(--vp-c-bg);
}
.dark [class*='DocSearch'] {
--docsearch-modal-shadow: none;
--docsearch-footer-shadow: none;
--docsearch-logo-color: var(--vp-c-text-2);
--docsearch-hit-background: var(--vp-c-gray-3);;
--docsearch-container-background: rgba(0, 0, 0, 0.4);
--docsearch-hit-color: var(--vp-c-text-2);
--docsearch-hit-shadow: none;
}
.dark .DocSearch-Footer {
border-top: 1px solid var(--vp-c-divider);
}
.DocSearch-Form {
border: 1px solid var(--vp-c-brand-1);
background-color: var(--vp-c-white);
}
.dark .DocSearch-Form {
background-color: var(--vp-c-default-soft);
}
.DocSearch-Screen-Icon > svg {
margin: auto;
}
</style>
+2 -2
View File
@@ -10,14 +10,14 @@ import HomeHeroInfoBefore from './components/home/HomeHeroInfoBefore.vue';
import { ICON_STYLE_CONTEXT, iconStyleContext } from './composables/useIconStyle';
import { CATEGORY_VIEW_CONTEXT, categoryViewContext } from './composables/useCategoryView';
import { EXTERNAL_LIBS_CONTEXT, externalLibContext } from './composables/useExternalLibs';
import FrameworkSelect from './components/guide/FrameworkSelect.vue';
import SideBarNavBefore from './layouts/SideBarNavBefore.vue';
import SnackPlayer from './components/editors/SnackPlayer.vue';
const theme: Partial<Theme> = {
extends: DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'sidebar-nav-before': () => h(FrameworkSelect),
'sidebar-nav-before': () => h(SideBarNavBefore),
'home-hero-info-before': () => h(HomeHeroInfoBefore),
'sidebar-nav-after': () => h(IconsSidebarNavAfter),
'home-hero-image': () => h(HomeHeroIconsCard),
@@ -0,0 +1,20 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useData } from 'vitepress';
import VPSidebarGroup from 'vitepress/dist/client/theme-default/components/VPSidebarGroup.vue';
import VPNavBarSearch from '../components/overrides/VPNavBarSearch.vue';
import FrameworkSelect from '../components/guide/FrameworkSelect.vue';
import { guideSidebarTop } from '../../sidebar';
const { page } = useData();
const isGuide = computed(() => page.value?.relativePath?.startsWith?.('guide'));
</script>
<template>
<template v-if="isGuide">
<VPNavBarSearch />
<VPSidebarGroup :items="guideSidebarTop" />
<FrameworkSelect />
</template>
</template>
+4
View File
@@ -129,6 +129,10 @@ html {
flex-direction: column-reverse;
}
.content-body .search {
display: none;
}
@media (min-width: 960px) {
.VPHomeHero .container .image {
order: 1;
+24 -24
View File
@@ -4,11 +4,8 @@ import { createGeneralOGImage, createIconOGImage } from './createOGImage';
export async function transformPageData(pageData: PageData) {
pageData.frontmatter.head ??= [];
if (
pageData.relativePath.startsWith('icons/') &&
!pageData.relativePath.startsWith('icons/lab/') &&
pageData.params?.name
) {
if (pageData.relativePath.startsWith('icons/') && pageData.params?.name) {
const isLab = pageData.relativePath.startsWith('icons/lab/');
const iconName = pageData.params.name;
pageData.title = `${iconName} icon details`;
@@ -24,26 +21,29 @@ export async function transformPageData(pageData: PageData) {
const structuredData = await getStructuredData(iconName, pageData);
const ogPath = await createIconOGImage(iconName, pageData.params?.tags || []);
// `createIconOGImage` reads the SVG from `icons/`, where lab icons don't live.
if (!isLab) {
const ogPath = await createIconOGImage(iconName, pageData.params?.tags || []);
if (ogPath) {
const content = `https://lucide.dev${ogPath}`;
pageData.frontmatter.head.push(
[
'meta',
{
property: 'og:image',
content,
},
],
[
'meta',
{
property: 'twitter:image',
content,
},
],
);
if (ogPath) {
const content = `https://lucide.dev${ogPath}`;
pageData.frontmatter.head.push(
[
'meta',
{
property: 'og:image',
content,
},
],
[
'meta',
{
property: 'twitter:image',
content,
},
],
);
}
}
pageData.frontmatter.head.push([
+8 -1
View File
@@ -3,11 +3,18 @@ import iconNodes from '../.vitepress/data/iconNodes';
import * as iconDetails from '../.vitepress/data/iconDetails';
import { IconEntity } from '../.vitepress/theme/types';
/**
* The generated `iconDetails` modules import `iconPopularity/<name>.json` as-is,
* so popularity arrives as the raw `{ count }` object instead of a number.
*/
type IconDetail = Omit<IconEntity, 'popularity'> & { popularity?: { count: number } };
export default {
paths: async () => {
return (Object.values(iconDetails) as unknown as IconEntity[]).map((iconEntity) => {
return (Object.values(iconDetails) as unknown as IconDetail[]).map((iconEntity) => {
const params = {
...iconEntity,
popularity: iconEntity.popularity?.count ?? 0,
relatedIcons: relatedIcons[iconEntity.name].map((name: string) => ({
name,
iconNode: iconNodes[name],
+2
View File
@@ -30,6 +30,7 @@
"author": "Eric Fennis",
"license": "ISC",
"devDependencies": {
"@docsearch/js": "3.8.2",
"@lucide/build-icons": "workspace:*",
"@lucide/helpers": "workspace:*",
"@lucide/shared": "workspace:*",
@@ -57,6 +58,7 @@
"vue-tsc": "^3.3.11"
},
"dependencies": {
"@docsearch/css": "3.8.2",
"@floating-ui/vue": "^2.0.1",
"@headlessui/vue": "^1.7.23",
"@lucide/vue": "workspace:*",
+31 -25
View File
@@ -134,6 +134,9 @@ importers:
docs:
dependencies:
'@docsearch/css':
specifier: 3.8.2
version: 3.8.2
'@floating-ui/vue':
specifier: ^2.0.1
version: 2.0.1(vue@3.5.43(typescript@6.0.3))
@@ -186,6 +189,9 @@ importers:
specifier: ^3.5.43
version: 3.5.43(typescript@6.0.3)
devDependencies:
'@docsearch/js':
specifier: 3.8.2
version: 3.8.2(@algolia/client-search@5.57.0)(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(search-insights@2.8.2)
'@lucide/build-icons':
specifier: workspace:*
version: link:../tools/build-icons
@@ -1273,19 +1279,19 @@ importers:
version: 6.1.0(@babel/core@7.29.7(supports-color@10.2.2))(@types/babel__core@7.20.5)(rollup@4.63.1)(supports-color@10.2.2)
'@solidjs/testing-library':
specifier: next
version: 1.0.0-beta.3(@solidjs/web@2.0.0-rc.14(solid-js@2.0.0-rc.14))(solid-js@2.0.0-rc.14)
version: 1.0.0-beta.3(@solidjs/web@2.0.0-rc.15(solid-js@2.0.0-rc.15))(solid-js@2.0.0-rc.15)
'@solidjs/vite-plugin':
specifier: next
version: 3.0.0-next.35(@solidjs/web@2.0.0-rc.14(solid-js@2.0.0-rc.14))(@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3))(solid-js@2.0.0-rc.14)(supports-color@10.2.2)(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))
version: 3.0.0-next.35(@solidjs/web@2.0.0-rc.15(solid-js@2.0.0-rc.15))(@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3))(solid-js@2.0.0-rc.15)(supports-color@10.2.2)(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))
'@solidjs/web':
specifier: next
version: 2.0.0-rc.14(solid-js@2.0.0-rc.14)
version: 2.0.0-rc.15(solid-js@2.0.0-rc.15)
'@testing-library/jest-dom':
specifier: ^7.0.1
version: 7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3)
babel-preset-solid:
specifier: next
version: 2.0.0-rc.2(@babel/core@7.29.7(supports-color@10.2.2))(solid-js@2.0.0-rc.14)
version: 2.0.0-rc.2(@babel/core@7.29.7(supports-color@10.2.2))(solid-js@2.0.0-rc.15)
esbuild:
specifier: ^0.28.2
version: 0.28.2
@@ -1300,7 +1306,7 @@ importers:
version: 6.5.1(rollup@4.63.1)(typescript@6.0.3)
solid-js:
specifier: next
version: 2.0.0-rc.14
version: 2.0.0-rc.15
typescript:
specifier: ^6.0.3
version: 6.0.3
@@ -5710,8 +5716,8 @@ packages:
resolution: {integrity: sha512-4+pRdrAHtfyE9BUJWBup3TpzJojJjgW2mV1vm/Jik4tWa5epxXB/YrLkwqP1v8+S9XjyKKZu5BSLqmcpswMYeQ==}
engines: {node: '>=22.12.0'}
'@solidjs/signals@2.0.0-rc.14':
resolution: {integrity: sha512-s3v1wpPcX3wfNO0WUERrPrXS+qqJ4ylzH9QTIRKqrgcMVeLEOXgFa3hZrhEoVTp+lVAgido2NH6GCI79twe2fg==}
'@solidjs/signals@2.0.0-rc.15':
resolution: {integrity: sha512-rMhLaYnBvpb9sB3NJGPsqIxjgr0XKU2nvBS7jhWX2fKx+K/m5O0VoAuCgYuTie3BMBZU9vX08NdnFXg508pcew==}
engines: {node: '>=22.12.0'}
'@solidjs/start@2.0.5':
@@ -5777,11 +5783,11 @@ packages:
peerDependencies:
solid-js: ^2.0.0-rc.13
'@solidjs/web@2.0.0-rc.14':
resolution: {integrity: sha512-MhHqUoVBdgAG7EZOANx7Y5SuCFH7sBxzt9uBSYLpJxE503tqoi7pX1UhV7PWxw4LvmPe1PZkdkSOZ8BLchZkhQ==}
'@solidjs/web@2.0.0-rc.15':
resolution: {integrity: sha512-xwt4rNZ9CXTdMraFqmVn/AXuHIXQJ3jnrKyzEZ4ZFdRCBml0VxL8pA5D3YZHSjHoF7okNAmiVtyRCMNz15jQCg==}
engines: {node: '>=22.12.0'}
peerDependencies:
solid-js: ^2.0.0-rc.14
solid-js: ^2.0.0-rc.15
'@speed-highlight/core@1.2.24':
resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==}
@@ -12164,8 +12170,8 @@ packages:
resolution: {integrity: sha512-62bYOI4JZ15KOqL5eReKyWSwAXrGb0fbX8SDnHsbJk2UX+SzSyy1gobas2cxW/0BXcobGfQ1V6ffPyQkMIBdoQ==}
engines: {node: '>=22.12.0'}
solid-js@2.0.0-rc.14:
resolution: {integrity: sha512-fmaqUHgbITf18Hedur6gPnaPE4GrdPgkTbLujHqM5Vl5jxWf9rxwFh6hZMXQs+Kg1pu8KYuOMfqnuSizFQ9I6Q==}
solid-js@2.0.0-rc.15:
resolution: {integrity: sha512-HXiWAEG5Rjp5C7reElUlvdriIadcbpwWwVdztTf0wuxeirw49rGuIzVbSRn06p6GjlINwi5d24Z46b478hNdvw==}
engines: {node: '>=22.12.0'}
solid-refresh@0.6.3:
@@ -18200,7 +18206,7 @@ snapshots:
'@solidjs/signals@2.0.0-rc.13': {}
'@solidjs/signals@2.0.0-rc.14': {}
'@solidjs/signals@2.0.0-rc.15': {}
'@solidjs/start@2.0.5(@solidjs/router@1.0.0(solid-js@1.9.15))(@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3))(crossws@0.4.12(srvx@1.0.5))(ocache@0.3.0)(supports-color@10.2.2)(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))':
dependencies:
@@ -18251,22 +18257,22 @@ snapshots:
'@testing-library/dom': 10.4.1
solid-js: 2.0.0-rc.13
'@solidjs/testing-library@1.0.0-beta.3(@solidjs/web@2.0.0-rc.14(solid-js@2.0.0-rc.14))(solid-js@2.0.0-rc.14)':
'@solidjs/testing-library@1.0.0-beta.3(@solidjs/web@2.0.0-rc.15(solid-js@2.0.0-rc.15))(solid-js@2.0.0-rc.15)':
dependencies:
'@solidjs/web': 2.0.0-rc.14(solid-js@2.0.0-rc.14)
'@solidjs/web': 2.0.0-rc.15(solid-js@2.0.0-rc.15)
'@testing-library/dom': 10.4.1
solid-js: 2.0.0-rc.14
solid-js: 2.0.0-rc.15
'@solidjs/vite-plugin@3.0.0-next.35(@solidjs/web@2.0.0-rc.14(solid-js@2.0.0-rc.14))(@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3))(solid-js@2.0.0-rc.14)(supports-color@10.2.2)(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))':
'@solidjs/vite-plugin@3.0.0-next.35(@solidjs/web@2.0.0-rc.15(solid-js@2.0.0-rc.15))(@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@5.0.3))(solid-js@2.0.0-rc.15)(supports-color@10.2.2)(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/core': 7.29.7(supports-color@10.2.2)
'@solidjs/babel-plugin': 2.0.0-rc.13(@babel/core@7.29.7(supports-color@10.2.2))
'@solidjs/compiler': 2.0.0-rc.13
'@solidjs/web': 2.0.0-rc.14(solid-js@2.0.0-rc.14)
'@solidjs/web': 2.0.0-rc.15(solid-js@2.0.0-rc.15)
'@types/babel__core': 7.20.5
merge-anything: 5.1.7
solid-js: 2.0.0-rc.14
solid-js: 2.0.0-rc.15
vite: 8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0)
vitefu: 1.1.3(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))
optionalDependencies:
@@ -18299,11 +18305,11 @@ snapshots:
seroval-plugins: 1.6.7(seroval@1.6.7)
solid-js: 2.0.0-rc.13
'@solidjs/web@2.0.0-rc.14(solid-js@2.0.0-rc.14)':
'@solidjs/web@2.0.0-rc.15(solid-js@2.0.0-rc.15)':
dependencies:
seroval: 1.6.7
seroval-plugins: 1.6.7(seroval@1.6.7)
solid-js: 2.0.0-rc.14
solid-js: 2.0.0-rc.15
'@speed-highlight/core@1.2.24': {}
@@ -20167,12 +20173,12 @@ snapshots:
optionalDependencies:
solid-js: 1.9.15
babel-preset-solid@2.0.0-rc.2(@babel/core@7.29.7(supports-color@10.2.2))(solid-js@2.0.0-rc.14):
babel-preset-solid@2.0.0-rc.2(@babel/core@7.29.7(supports-color@10.2.2))(solid-js@2.0.0-rc.15):
dependencies:
'@babel/core': 7.29.7(supports-color@10.2.2)
'@dom-expressions/babel-plugin-jsx': 0.50.0-next.44(@babel/core@7.29.7(supports-color@10.2.2))
optionalDependencies:
solid-js: 2.0.0-rc.14
solid-js: 2.0.0-rc.15
bail@2.0.2: {}
@@ -25938,9 +25944,9 @@ snapshots:
seroval: 1.6.7
seroval-plugins: 1.6.7(seroval@1.6.7)
solid-js@2.0.0-rc.14:
solid-js@2.0.0-rc.15:
dependencies:
'@solidjs/signals': 2.0.0-rc.14
'@solidjs/signals': 2.0.0-rc.15
csstype: 3.2.3
seroval: 1.6.7
seroval-plugins: 1.6.7(seroval@1.6.7)