Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions packages/react/.skills/f0-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
name: f0-docs
description: Document F0 React components in Storybook (MDX). Load automatically when a new component is created or an existing component gets new props/variants. Covers the 4-step workflow: analyze code, ask creator (if needed), write MDX, update stories.
---

# F0 Docs

Every component in `packages/react/src/components/` must have an MDX documentation file in its `__stories__/` folder. This skill defines the mandatory workflow for writing it correctly.
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“Every component … must have an MDX … in its __stories__/ folder” isn’t accurate for this repo today (there are components using __storybook__/ and some with flat index.stories.tsx outside __stories__/). Consider rephrasing to “next to the stories” and explicitly include __storybook__/ / flat-story cases so the workflow matches the current structure.

Suggested change
Every component in `packages/react/src/components/` must have an MDX documentation file in its `__stories__/` folder. This skill defines the mandatory workflow for writing it correctly.
Every component in `packages/react/src/components/` must have an MDX documentation file next to its stories. In this repo, that may be in `__stories__/`, in `__storybook__/`, or alongside flat story files such as `index.stories.tsx`. This skill defines the mandatory workflow for writing it correctly.

Copilot uses AI. Check for mistakes.

## When to Load

- A new component is created — MDX is required before the work is considered done
- An existing component gets new props or variants — MDX must be updated to cover them
- User asks to document a component in Storybook
- User asks to convert `autodocs` to manual MDX
- `f0-quality-gate` Subagent C reports a missing or incomplete MDX file

---

## Mandatory Workflow — 4 Steps

Execute these steps in order. Do not skip to MDX authoring without completing the analysis first.

### Step 1 — Analyze the component

Read the source files and extract the full public surface: props, types, defaults, variants, stories, and conditional behaviors. Build a WHEN→THEN rule list from the source code.

Full protocol: [`references/component-analysis.md`](./references/component-analysis.md)

### Step 2 — Ask the creator (when needed)

**Infer without asking** for components with a universal role in product UI (Button, Alert, Dialog, Badge, Input, etc.) and for all information that exists in the code.

**Ask the creator** when the component has Factorial-specific behavior that cannot be inferred from code:

- Where in Factorial does this appear?
- What triggers it?
- What Factorial-specific error states or edge cases exist?
- When should developers NOT use this?
- Are there consistent prop combinations used in specific Factorial contexts?

Ask all questions at once. Do not drip-feed. If no Factorial-specific questions apply, skip this step.

Question list: [`references/component-analysis.md → Step 4`](./references/component-analysis.md)

### Step 3 — Evaluate quality target

Before writing, decide the quality level to target (Acceptable / Good / Gold) based on the component's importance and completeness of available information. Check the gold standards:

- `F0Alert/__stories__/F0Alert.mdx` — gold standard: decision tables, DoDonts with visual children, a11y section, dismissible usage

Comment on lines +48 to +51
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The listed “gold standards” (F0Alert/__stories__/F0Alert.mdx, F0Button/__stories__/F0Button.mdx) don’t exist in the current repo state (e.g. F0Alert/__stories__ only has F0Alert.stories.tsx, and F0Button/__stories__ currently has a controls.mdx stub). Also, F0Button.mdx is described as having DocsNav, but this skill later mandates “No DocsNav”. Please update these references to point to files that exist in this repo (or explicitly note they live in a companion PR) and ensure the examples are consistent with the rules.

Suggested change
Before writing, decide the quality level to target (Acceptable / Good / Gold) based on the component's importance and completeness of available information. Check the gold standards:
- `F0Alert/__stories__/F0Alert.mdx` — best in class for decision tables, DoDonts, a11y
- `F0Button/__stories__/F0Button.mdx` — most complete (DocsNav, states, full props reference, 633 lines)
Before writing, decide the quality level to target (Acceptable / Good / Gold) based on the component's importance and completeness of available information. Check the best in-repo references that exist today:
- `F0Alert/__stories__/F0Alert.stories.tsx` — use as the current source of truth for covered variants, states, and scenarios in this repo
- `F0Button/__stories__/controls.mdx` — existing MDX reference for control wiring only; it is not a full gold-standard content example, and you should not add `DocsNav`
If fuller MDX examples such as `F0Alert.mdx` or `F0Button.mdx` land in a companion PR, treat them as supplemental references only if they still match the rules in this skill.

Copilot uses AI. Check for mistakes.
Quality criteria per section: [`references/documentation-quality.md`](./references/documentation-quality.md)

### Step 4 — Write the MDX and update stories

Create the MDX file and remove `autodocs` from the stories meta. Follow the full template and validation checklist.
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“Remove autodocs from the stories meta” is unlikely to achieve the desired effect in this repo because .storybook/preview.tsx sets tags: ["autodocs"] globally for all stories. Please update this step to describe the actual supported way to avoid autodocs conflicts when adding manual MDX in this codebase (and keep it consistent with the storybook-stories skill).

Suggested change
Create the MDX file and remove `autodocs` from the stories meta. Follow the full template and validation checklist.
Create the MDX file and update the corresponding `*.stories.tsx` file to disable autodocs using this repo's supported story-level override for manual MDX pages (do not rely on removing `autodocs` from the stories meta, because autodocs is enabled globally in this codebase). Follow the full template and validation checklist.

Copilot uses AI. Check for mistakes.

Full template + workflow: [`references/mdx-authoring.md`](./references/mdx-authoring.md)

---

## Quick Reference

| Need | Reference |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Source analysis protocol, props inventory, WHEN→THEN extraction, creator questions | [`references/component-analysis.md`](./references/component-analysis.md) |
| Quality criteria per section, WHEN→THEN rules, component relationships, a11y by type, 11 global rules | [`references/documentation-quality.md`](./references/documentation-quality.md) |
| Full MDX template, table templates, utility components (DocsNav, DoDonts), stories update, checklist | [`references/mdx-authoring.md`](./references/mdx-authoring.md) |
| Which components have docs and which need them | [`references/component-status.md`](./references/component-status.md) |
Comment on lines +64 to +69
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Quick Reference row lists “DocsNav” as a utility component, but the linked MDX authoring reference explicitly forbids importing/using DocsNav. This is internally inconsistent and will confuse readers; remove the DocsNav mention here (or replace with the actual allowed utilities like Unstyled/DoDonts).

Suggested change
| Need | Reference |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Source analysis protocol, props inventory, WHEN→THEN extraction, creator questions | [`references/component-analysis.md`](./references/component-analysis.md) |
| Quality criteria per section, WHEN→THEN rules, component relationships, a11y by type, 11 global rules | [`references/documentation-quality.md`](./references/documentation-quality.md) |
| Full MDX template, table templates, utility components (DocsNav, DoDonts), stories update, checklist | [`references/mdx-authoring.md`](./references/mdx-authoring.md) |
| Which components have docs and which need them | [`references/component-status.md`](./references/component-status.md) |
| Need | Reference |
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
| Source analysis protocol, props inventory, WHEN→THEN extraction, creator questions | [`references/component-analysis.md`](./references/component-analysis.md) |
| Quality criteria per section, WHEN→THEN rules, component relationships, a11y by type, 11 global rules | [`references/documentation-quality.md`](./references/documentation-quality.md) |
| Full MDX template, table templates, utility components (Unstyled, DoDonts), stories update, checklist | [`references/mdx-authoring.md`](./references/mdx-authoring.md) |
| Which components have docs and which need them | [`references/component-status.md`](./references/component-status.md) |

Copilot uses AI. Check for mistakes.

---

## Documentation is a Blocking Requirement

A component is not considered done until its MDX file exists and covers all public props and variants. The `f0-quality-gate` enforces this:

- New component with no MDX → **BLOCKING** in Subagent C report
- New prop or variant with no MDX coverage → **BLOCKING** in Subagent C report

---

## Relationship to Other Skills

| Skill | Covers |
| ---------------------- | ------------------------------------------------------------- |
| `f0-docs` (this skill) | MDX documentation files (`__stories__/*.mdx`) |
| `f0-storybook-stories` | Story files (`__stories__/*.stories.tsx`) |
| `f0-storybook-testing` | `play` functions and a11y tests inside story files |
| `f0-quality-gate` | Runs all checks after any code change, including MDX coverage |

MDX and stories are separate files with separate purposes — both are required.
132 changes: 132 additions & 0 deletions packages/react/.skills/f0-docs/references/component-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Component Analysis Reference

Step 1 of the documentation workflow. Before writing a single line of MDX, extract everything the code can tell you — then identify the gaps that only the component creator can fill.

---

## Step 1 — Read the Source Files

Read these files in order:

1. **`F0ComponentName.tsx`** — public props, JSDoc comments, variants, conditional rendering, ARIA attributes, event handlers
2. **`types.ts`** — exported types and union values
3. **`index.tsx`** — export pattern (`experimentalComponent`, `Component({ name, type }`, or plain re-export)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example export pattern in the index.tsx bullet is missing a closing ) (it shows Component({ name, type }). Fix it to a syntactically complete snippet (e.g. Component({ name, type })) so it’s unambiguous for readers.

Suggested change
3. **`index.tsx`** — export pattern (`experimentalComponent`, `Component({ name, type }`, or plain re-export)
3. **`index.tsx`** — export pattern (`experimentalComponent`, `Component({ name, type })`, or plain re-export)

Copilot uses AI. Check for mistakes.
4. **`F0ComponentName.stories.tsx`** — all named story exports; these become `Stories.X` in MDX
5. **`__tests__/F0ComponentName.test.tsx`** — what behavior is already tested (informs guidelines)
6. **`internal-types.ts`** (if exists) — private props to exclude from public documentation

---

## Step 2 — Extract the Public Surface

From the source files, build this inventory:

### Props inventory

For each public prop, record:

| Prop | Type | Default | Required | Source |
| --------- | --------------- | ----------- | -------- | ----------------- |
| `label` | `string` | — | Yes | `F0Button.tsx:12` |
| `variant` | `ButtonVariant` | `"default"` | — | `types.ts:4` |

- Mark props defined in `privateProps` array as **internal — do not document**
- If a prop has no JSDoc, note it as **undocumented — infer or ask**

### Variants inventory

List every value of every union type:

```
variant: "default" | "outline" | "neutral" | "ghost" | "critical" | "promote" | "outlinePromote"
size: "sm" | "md" | "lg"
```

### Stories inventory

List every named export from the stories file:

```
Default, Variants, Sizes, States, IconVariants, WithHref, AsyncAction, Disabled
```

These are the only valid `Stories.X` references in MDX. Do not reference stories that do not exist.

### Behaviors inventory

Note conditional rendering patterns found in the source:

- WHEN `loading={true}` → THEN renders spinner, disables interaction
- WHEN `href` is set → THEN renders as `<a>` instead of `<button>`
- WHEN `hideLabel={true}` → THEN label is visually hidden, still read by screen readers

These become the WHEN→THEN rules in the MDX Guidelines section.

---

## Step 3 — Classify Each Data Point

Use this table to decide what to do with each piece of information:

| Category | Infer without asking | Ask the creator |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| **Prop types and defaults** | Always — comes from the code | Never |
| **Variant names** | Always — comes from `types.ts` | Never |
| **ARIA attributes present in source** | Always — read from JSX | Never |
| **Keyboard behavior** (Enter/Space/Escape) | Yes, for standard roles (button, dialog, listbox) | If the component uses a non-standard interaction model |
| **Visual description of variants** | Yes, for universal UI patterns (filled = primary, outlined = secondary, red = destructive) | If Factorial uses a variant in a non-standard way |
| **Copy rules** (sentence case, verb-first) | Yes — global F0 standard applies | Never |
| **When NOT to use** | Partially — infer from component type (never use Button as tab, never use Alert for transient messages) | Ask for Factorial-specific anti-patterns |
| **Factorial-specific placement** | Never | Ask — where does this appear in the product? |
| **Factorial-specific triggers** | Never | Ask — what user action or system event causes this to appear? |
| **Business error cases** | Never | Ask — what errors does this display in production? |
| **Save / creation patterns** | Never | Ask — does this confirm a save, trigger a save, or neither? |
| **Relationship to other features** | Never | Ask — does this block navigation? Does it appear in a specific flow? |

**Rule:** If the information exists in the code → infer. If it requires knowledge of Factorial's product context → ask.

---

## Step 4 — Questions for the Creator

Ask these questions **only** when the component has Factorial-specific behavior that cannot be inferred from code. Group them and ask all at once — do not drip-feed.

### Placement and triggers

- Where in the Factorial product does this component appear? (Which pages, sections, or flows?)
- What triggers it to appear — a user action, a system state, a backend event?

### When NOT to use (Factorial context)

- Are there cases in Factorial where a developer might reach for this component but shouldn't? What should they use instead?

### Error and edge cases

- What are the real error messages or edge-case states this component displays in production?
- Are there loading, empty, or error states not covered by the current stories?

### Save and creation patterns

- When this component includes an action button, does it confirm a save that already happened, trigger a save, or navigate to a save flow?

### Navigation and blocking

- Does this component block the user from navigating away? Does it appear inside a `F0Dialog`?

### Custom usage at Factorial

- Is there a variant, size, or prop combination that Factorial uses consistently in a specific context (e.g., always `size="sm"` in table rows, always `variant="critical"` for deletion)?

---

## Output of This Step

Before moving to MDX authoring, you should have:

1. A complete props inventory with types, defaults, and required flags
2. A complete variants inventory
3. A list of all story exports (for valid `Stories.X` references)
4. A list of WHEN→THEN behavior rules extracted from source
5. A list of open questions for the creator (if any)

If you have open questions, ask them all at once before writing the MDX. If the component is universal (Button, Alert, Dialog) and has no Factorial-specific behavior, proceed directly to MDX authoring.
Loading
Loading