diff --git a/sites/docs/content/functions/box.md b/sites/docs/content/functions/box.md
index ac70b896..ff61b8a2 100644
--- a/sites/docs/content/functions/box.md
+++ b/sites/docs/content/functions/box.md
@@ -1,6 +1,7 @@
---
title: Box
description: Box your state and take it anywhere
+category: State
---
count.value++}>
@@ -35,7 +36,10 @@ Initializes the boxed state.
### `box.with`
-Allows you to use getters and setters to define a box. Useful to pass around state.
+Creates reactive state using getter and setter functions. If a setter function is provided, the box
+is writable. If not, the box is readonly.
+
+Useful for passing synced reactive values across boundaries.
```svelte
-
-Runed provides utilities to power your applications using the magic of
-[Svelte Runes](https://svelte.dev/blog/runes).
-
-Here are some tools that are provided:
-
-- Debouncing utilities synced with state
-- Element size tracking
-- RequestAnimationFrame helpers
-- etc.
-
-## Next Steps
-
-Start using Runed in your Svelte app by following the [Getting Started](/docs/getting-started)
-guide. If you have any questions or need help, feel free to ask in the
-[Discord](https://discord.gg/hbAGu6akVy)!
+Runed is a collection of utilities for Svelte 5 that make composing powerful applications and
+libraries a breeze, leveraging the power of [Svelte Runes](https://svelte.dev/blog/runes).
diff --git a/sites/docs/contentlayer.config.js b/sites/docs/contentlayer.config.js
index 2f79f476..51df5516 100644
--- a/sites/docs/contentlayer.config.js
+++ b/sites/docs/contentlayer.config.js
@@ -23,7 +23,7 @@ const computedFields = {
export const Doc = defineDocumentType(() => ({
name: "Doc",
- filePathPattern: `**/*.md`,
+ filePathPattern: `./*.md`,
fields: {
title: {
type: "string",
@@ -41,8 +41,28 @@ export const Doc = defineDocumentType(() => ({
computedFields,
}));
+export const FunctionDoc = defineDocumentType(() => ({
+ name: "FunctionDoc",
+ filePathPattern: "functions/**/*.md",
+ fields: {
+ title: {
+ type: "string",
+ required: true,
+ },
+ description: {
+ type: "string",
+ required: true,
+ },
+ category: {
+ type: "string",
+ required: true,
+ },
+ },
+ computedFields,
+}));
+
export default makeSource({
contentDirPath: "./content",
- documentTypes: [Doc],
+ documentTypes: [Doc, FunctionDoc],
disableImportAliasWarning: true,
});
diff --git a/sites/docs/src/lib/config/navigation.ts b/sites/docs/src/lib/config/navigation.ts
index 4a94194b..fc0cb167 100644
--- a/sites/docs/src/lib/config/navigation.ts
+++ b/sites/docs/src/lib/config/navigation.ts
@@ -1,3 +1,5 @@
+import { allFunctionDocs } from "../../../.contentlayer/generated";
+
export type NavItem = {
title: string;
href?: string;
@@ -20,8 +22,54 @@ export type Navigation = {
sidebar: SidebarNavItem[];
};
+const CATEGORIES = ["State", "Elements", "Browser", "Component", "Utilities"] as const;
+type Category = (typeof CATEGORIES)[number];
+
+function isCategory(category: string): category is Category {
+ return CATEGORIES.includes(category as Category);
+}
+
+function generateFunctionsNav() {
+ const categories = new Set(
+ allFunctionDocs
+ .map((doc) => doc.category)
+ .filter((category): category is Category => isCategory(category))
+ );
+
+ const navItems: SidebarNavItem[] = [];
+
+ // Create a map to store the items for each category
+ const categoryItemsMap: Record = {};
+
+ // Populate the map with items for each category
+ for (const doc of allFunctionDocs) {
+ if (!categoryItemsMap[doc.category]) {
+ categoryItemsMap[doc.category] = [];
+ }
+ categoryItemsMap[doc.category]?.push({
+ title: doc.title,
+ href: `/docs/functions/${doc.slug}`,
+ items: [],
+ });
+ }
+
+ // Sort the categories based on the provided sort order
+ const sortedCategories = CATEGORIES.filter((category) => categories.has(category));
+
+ // Create the navItems array based on the sorted categories
+ for (const category of sortedCategories) {
+ const items = categoryItemsMap[category] ?? [];
+ navItems.push({
+ title: category,
+ items,
+ collapsible: false,
+ });
+ }
+
+ return navItems;
+}
+
export const navigation: Navigation = {
- // By default, `main` navigation items are rendered in the top navigation bar.
main: [
{
title: "Documentation",
@@ -38,7 +86,6 @@ export const navigation: Navigation = {
external: true,
},
],
- // By default, `sidebar` navigation only supports 2 levels of navigation.
sidebar: [
{
title: "Overview",
@@ -56,47 +103,6 @@ export const navigation: Navigation = {
},
],
},
-
- {
- title: "Functions",
- collapsible: true,
- items: [
- {
- title: "Box",
- href: "/docs/functions/box",
- items: [],
- },
- {
- title: "useActiveElement",
- href: "/docs/functions/use-active-element",
- items: [],
- },
- {
- title: "useDebounce",
- href: "/docs/functions/use-debounce",
- items: [],
- },
- {
- title: "useElementSize",
- href: "/docs/functions/use-element-size",
- items: [],
- },
- {
- title: "useEventListener",
- href: "/docs/functions/use-event-listener",
- items: [],
- },
- {
- title: "useMounted",
- href: "/docs/functions/use-mounted",
- items: [],
- },
- {
- title: "useSupported",
- href: "/docs/functions/use-supported",
- items: [],
- },
- ],
- },
+ ...generateFunctionsNav(),
],
};