Skip to content

Doc Decision Tree Component

The decision tree lives at Where Should My Doc Go? and is embedded in an MDX page as a Solid.js island. It asks a series of questions about the article being written and resolves to a filesystem path, a doc-type label, a short explanation, and optional writing tips.

The tree data lives in a dedicated file, separate from the component code:

src/components/doc-decision-tree/doc-tree-data.ts

The tree is a recursive TreeNode type with two variants:

type TreeNode =
| { kind: "question"; id: string; question: string; options: Option[] }
| {
kind: "result";
id: string;
path: string;
heading: string;
description: string;
tips?: string[];
};

Each question node has an array of options. Each option has a label (bold text on the button), a hint (secondary text below it), and a next pointing to the next node.

Each result node is a leaf. It provides:

  • path — the filesystem path shown to the user (e.g. project/auth/guides/)
  • heading — the doc type label (e.g. “How-to guide”)
  • description — 2–3 sentences explaining what belongs here and why
  • tips — optional bullet points with writing advice

The tree uses a helper function domainQuadrant(domain) that generates the standard Diátaxis question subtree for any domain. To add a new domain, add an entry to the domains array:

const domains = [
{ label: "Authentication", hint: "Login, sessions, tokens, SSO, passkeys", key: "auth" },
{ label: "Networking", hint: "HTTP, DNS, TLS, load balancing, proxies", key: "networking" },
// Add your new domain here:
{ label: "Storage", hint: "Databases, object stores, caching", key: "storage" },
];

The key is used to generate the filesystem path (project/{key}/tutorials/, etc.).

Find the node by its id in the tree and edit its properties. Every node has a unique id string like auth-intent or networking-reference that makes searching straightforward.

The component follows the same pattern as other interactive components in this project (counter, charts): a Solid.js component tree imported into an MDX page with client:load.

src/components/doc-decision-tree/
├── DocDecisionTree.tsx # Top-level: owns history state, derives current node
├── Breadcrumb.tsx # Clickable trail of past choices
├── QuestionCard.tsx # Renders current question + option buttons
├── OptionButton.tsx # Single option: bold label + muted hint
├── ResultCard.tsx # Terminal node: path, description, tips, copy button
├── CopyButton.tsx # Copies the resolved path to clipboard
├── doc-tree-data.ts # The tree definition (edit this to change content)
└── types.ts # TreeNode type definition

All state is a single history signal — an array of chosen option indices (e.g. [1, 2, 0] means “picked option 1, then option 2, then option 0”). The current node is derived by walking the tree using those indices. Backtracking via the breadcrumb just slices the array.

The component uses Tailwind utility classes and pulls Starlight’s CSS custom properties (--sl-color-accent, --sl-color-gray-*, --sl-color-white) so it inherits light and dark mode automatically. The slide-in animation is a single @keyframes rule injected in the top-level component.

The component is imported directly in the MDX page:

import DocDecisionTree from "@components/doc-decision-tree/DocDecisionTree.tsx";
<DocDecisionTree client:load />

client:load is used instead of client:visible because this is the primary interactive element on the page and should be ready immediately.