Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hetari/creative-coding/llms.txt

Use this file to discover all available pages before exploring further.

The Creative Coding playground splits its dashboard logic across two small utility modules. src/utils/dashboard.ts exports buildDashboardItems(), which computes the list of cards to render for any dashboard path by walking the SKETCHES registry. src/utils/slug.ts exports slugToLabel() and stripSortPrefix(), which convert raw URL slugs — potentially carrying filesystem sort prefixes — into clean, human-readable display labels. Together these two modules handle all the dynamic layout and labelling logic without any hard-coded category lists.

buildDashboardItems()

buildDashboardItems() is the core engine of the dashboard. Given the full SKETCHES array and the path currently being viewed, it returns a sorted list of DashboardItem objects describing every card that should appear on screen.

Signature

export function buildDashboardItems(
  sketches: SketchMeta[] = DEFAULT_SKETCHES,
  currentPath: string = '/',
): DashboardItem[]
sketches
SketchMeta[]
The array of sketch metadata to build from. Defaults to the SKETCHES constant exported from src/config/sketches.ts. In normal application code you will always pass SKETCHES explicitly, but the default makes the function convenient to call without arguments and easy to test with custom fixtures.
currentPath
string
The URL path of the dashboard currently being rendered, e.g. '/', '/gsap', or '/gsap/footer'. Defaults to '/'. The function strips trailing slashes and uses the number of path segments to determine display depth, then returns only the immediate children at that depth.

How It Works

The function computes the current nesting depth from currentPath.split('/').filter(Boolean).length. It then iterates over every sketch in the array and checks whether the sketch’s path starts with the same segments as currentPath. For each matching sketch, the child segment at the current depth is extracted and grouped into an internal map. A child entry is marked as a category (hasDeeper: true) if any sketch in the group has additional path segments beyond the immediate child slot, or as a leaf sketch if the sketch path ends exactly at depth + 1. The minimum order value found within each group becomes the sort key for that card, so folder cards rise to the position of their first sketch. The resulting items are sorted ascending by order before being returned.

The DashboardItem Interface

export interface DashboardItem {
  name: string
  path: string
  label: string
  icon: string      // '📁' for categories, '✦' for sketches
  isCategory: boolean
  previewMode: PreviewMode
  order: number
  resources?: string[]
}
FieldTypeDescription
namestringRaw name used as a key — either the sketch title or the raw path slug for categories.
pathstringThe full path this card links to.
labelstringHuman-readable display text shown on the card, derived from title or slugToLabel().
iconstring'📁' for folder/category cards; '✦' for leaf sketch cards.
isCategorybooleantrue when the card links to a nested dashboard; false for a sketch route.
previewMode'image' | 'iframe'Forwarded from SketchMeta.previewMode. Category cards always use 'image'.
ordernumberThe sort key used to order cards within the current view.
resourcesstring[]Optional external reference links, forwarded from the leaf SketchMeta.

Examples

The table below shows the output produced for each call against the current four-sketch registry:
CallReturns
buildDashboardItems(SKETCHES, '/')3 category cards: shader, images, gsap
buildDashboardItems(SKETCHES, '/gsap')2 category cards: footer, loading
buildDashboardItems(SKETCHES, '/gsap/footer')1 sketch card: Ascii Hand
buildDashboardItems(SKETCHES, '/shader')1 sketch card: Learn
Root-level call in detail:
buildDashboardItems(SKETCHES, '/')
// [
//   { name: 'shader', path: '/shader', label: 'Shader', icon: '📁', isCategory: true,  previewMode: 'image', order: 0  },
//   { name: 'images', path: '/images', label: 'Images', icon: '📁', isCategory: true,  previewMode: 'image', order: 10 },
//   { name: 'gsap',   path: '/gsap',   label: 'Gsap',   icon: '📁', isCategory: true,  previewMode: 'image', order: 20 },
// ]
Navigating into a nested category:
buildDashboardItems(SKETCHES, '/gsap')
// [
//   { name: 'footer',  path: '/gsap/footer',  label: 'Footer',  icon: '📁', isCategory: true, previewMode: 'image', order: 20 },
//   { name: 'loading', path: '/gsap/loading', label: 'Loading', icon: '📁', isCategory: true, previewMode: 'image', order: 30 },
// ]
Reaching a leaf level:
buildDashboardItems(SKETCHES, '/gsap/footer')
// [
//   {
//     name: 'Ascii Hand',
//     path: '/gsap/footer/ascii-hand',
//     label: 'Ascii Hand',
//     icon: '✦',
//     isCategory: false,
//     previewMode: 'iframe',
//     order: 20,
//   },
// ]

Nested Path Support

The function supports arbitrary nesting depth. There is no hard-coded limit on the number of category levels. Depth is computed dynamically from the length of the path segment array, so adding a four-level-deep category like 'gsap/animations/scroll/pin' requires no changes to buildDashboardItems() — it is handled automatically.
The function only ever returns immediate children of the current path. It never flattens or skips levels. Navigating deeper is always a separate call with the new path.

slugToLabel() and stripSortPrefix()

These two functions live in src/utils/slug.ts and handle the conversion from raw filesystem-style slugs to polished display labels.

Signatures

export function stripSortPrefix(slug: string): string
export function slugToLabel(slug: string): string

stripSortPrefix()

Removes a leading numeric sort prefix from a slug segment. The convention — digits followed by a hyphen at the start of a folder or file name — lets contributors control filesystem ordering without that prefix appearing anywhere in the UI.
stripSortPrefix('000-learn')      // → 'learn'
stripSortPrefix('010-basics')     // → 'basics'
stripSortPrefix('99-advanced')    // → 'advanced'
stripSortPrefix('shaders')        // → 'shaders'   (no prefix — returned as-is)
stripSortPrefix('123')            // → '123'        (digits only, no hyphen — returned as-is)
The stripping regex is /^\d+-/ — it matches one or more leading digits followed by a single -. A string that is only digits with no hyphen, or that starts with a letter, is returned unchanged.

slugToLabel()

Converts a URL path segment into a human-readable display label by composing three transformations:
  1. Strip sort prefix — delegates to stripSortPrefix()
  2. Replace separators — converts - and _ to spaces
  3. Title-case — capitalises the first letter of every word
slugToLabel('000-learn')        // → 'Learn'
slugToLabel('010-webgl-earth')  // → 'Webgl Earth'
slugToLabel('shaders')          // → 'Shaders'
slugToLabel('my_sketch')        // → 'My Sketch'
When a slug has no numeric prefix, stripSortPrefix() returns it unchanged, and slugToLabel() proceeds directly to the separator-replacement and title-casing steps:
slugToLabel('ascii-hand')       // → 'Ascii Hand'
slugToLabel('reveal-loader')    // → 'Reveal Loader'
All label-formatting rules live in slugToLabel(). If you need to handle acronyms (e.g. keep WebGL fully uppercase), change capitalisation behaviour, or add new separator characters, edit only this one function and every dashboard label updates automatically.

Build docs developers (and LLMs) love