| name | f0-move-component |
| description | Use when moving an F0 component from one Storybook section to another. Covers folder moves, deprecated re-exports for backward compatibility, and bulk import updates across the codebase. |
f0-move-component
PURPOSE: Step-by-step instructions for moving a component between sections in the F0 design system (packages/react/src/), preserving backward compatibility and keeping all imports consistent.
Storybook Sections Reference
All sections are registered in packages/react/.storybook/main.ts via { directory, titlePrefix } entries.
| Source folder | titlePrefix | Notes |
|---|
src/components | Components | All public F0 components |
src/patterns | Patterns | — |
src/kits | Kits | — |
src/experimental | Experimental | Legacy only — do NOT add new components here |
src/layouts | Layouts | Page layout components |
src/lib | Library | Internal utilities and providers |
src/hooks | Library | Public exported hooks |
src/sds | SDS | Satellite design systems |
src/examples | Examples | Full-app example stories |
src/ui | 🔒 Internal | Radix/shadcn primitive wrappers — not public |
If the destination section is not in this table, see Adding a new section before continuing.
Workflow
Step 1 — Move the entire folder
Move the component folder as-is. Do not rename anything inside it.
mv packages/react/src/<source>/<ComponentName> packages/react/src/<destination>/<ComponentName>
Example — moving F0Button from components to kits:
mv packages/react/src/components/F0Button packages/react/src/kits/F0Button
Step 2 — Do NOT rename any story's title field
The titlePrefix in main.ts is prepended automatically by Storybook. The title field inside each .stories.tsx file only needs the component-relative path — never the section name.
const meta: Meta<typeof F0Button> = {
title: "F0Button",
...
}
const meta: Meta<typeof F0Button> = {
title: "F0Button",
...
}
Step 3 — Add a deprecated re-export in the source section's exports.ts
This preserves backward compatibility for any consumer importing from the old path.
Locate (or create) the exports.ts file at the root of the source section folder and add a @deprecated re-export pointing to the new location.
Pattern:
export * from "../<destination>/<ComponentName>"
Example — after moving F0Button from components to kits:
export * from "../kits/F0Button"
If exports.ts does not exist in the source section, create it with only the deprecated re-export line above.
Step 4 — Update all imports across the codebase
4a — Update @/ alias imports
Replace every occurrence of the old @/ alias import path with the new canonical path.
Dry-run first (lists affected files without modifying them):
grep -r "@/<source>/<ComponentName>" packages/react/src \
--include="*.ts" --include="*.tsx" -l
Apply the replacement:
find packages/react/src -type f \( -name "*.ts" -o -name "*.tsx" \) \
-exec sed -i '' 's|@/<source>/<ComponentName>|@/<destination>/<ComponentName>|g' {} +
Example — updating imports after moving F0Button from components to kits:
grep -r "@/components/F0Button" packages/react/src --include="*.ts" --include="*.tsx" -l
find packages/react/src -type f \( -name "*.ts" -o -name "*.tsx" \) \
-exec sed -i '' 's|@/components/F0Button|@/kits/F0Button|g' {} +
The deprecated re-export added in Step 3 means existing consumers outside packages/react/src (e.g., the Factorial app) continue to work unchanged until they migrate to the new path.
4b — Check and fix relative imports inside the moved component
Files inside the moved component may use relative imports that point to sibling folders
that stayed behind (e.g., ../../../components/Charts/utils/colors). These break silently
because sed on @/ paths does not touch relative paths.
Find broken relative imports inside the moved component:
grep -r "\.\." packages/react/src/<destination>/<ComponentName> \
--include="*.ts" --include="*.tsx" | grep "<source>"
Also check files that were NOT moved but imported FROM the moved component using relative paths:
grep -r "<source>/<ComponentName>" packages/react/src \
--include="*.ts" --include="*.tsx" | grep "\.\."
Fix by converting broken relative paths to @/ alias paths:
find packages/react/src/<destination>/<ComponentName> -type f \( -name "*.ts" -o -name "*.tsx" \) \
-exec sed -i '' 's|\.\./\.\./\.\./\.<source>/SiblingFolder|@/<source>/SiblingFolder|g' {} +
Rule of thumb: after moving, all cross-component imports inside the destination folder should use @/ alias paths, never relative paths that cross folder boundaries outside the component itself.
Step 5 — Verify
Run all checks from packages/react/:
pnpm tsc
pnpm lint
pnpm vitest:ci
Fix any errors before committing.
Checklist
Use this before opening a PR:
Adding a new section
If the destination folder is not registered in main.ts, add an entry to the stories array before moving any component:
stories: [
{
directory: "../src/<new-folder>",
titlePrefix: "<New Section Label>",
},
],
Create the folder if it does not exist:
mkdir -p packages/react/src/<new-folder>
Then continue from Step 1.
Real-world examples from the codebase
These existing deprecated re-exports follow the same pattern described above and can be used as reference:
export * from "../sds/UpsellingKit/exports"
export * from "../sds/ai/Banners/exports"
export * from "../sds/ai/exports"