Skip to content

Commit 77fc08f

Browse files
committed
Update scripts
1 parent 59e8e7b commit 77fc08f

3 files changed

Lines changed: 39 additions & 344 deletions

File tree

CLAUDE.md

Lines changed: 26 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,53 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
Codemod to transform styled-components to StyleX using jscodeshift.
88

9-
## Tech Stack
10-
11-
- **Runtime**: Node.js >=22.20
12-
- **Package Manager**: pnpm >=10.22.0
13-
- **Language**: TypeScript (ESM)
14-
- **Build**: tsdown
15-
- **Test**: vitest
16-
- **Lint**: oxlint
17-
- **Visual Testing**: Storybook 10
18-
- **Codemod Framework**: jscodeshift
19-
209
## Commands
2110

2211
```bash
2312
pnpm install # Install dependencies
24-
pnpm build # Build with tsdown
2513
pnpm test # Run tests (watch mode)
2614
pnpm test:run # Run tests once (no rebuild needed - uses source directly)
27-
pnpm typecheck # Type check with tsc
28-
pnpm lint # Lint with oxlint
29-
pnpm run ci # Run lint + typecheck + test
15+
pnpm typecheck # Type check
16+
pnpm lint:fix # Lint with auto fixes applied
17+
pnpm run ci # Run lint + typecheck + test + build
3018
pnpm storybook # Start Storybook dev server (port 6006)
3119
```
3220

3321
**Note**: Tests run against source files directly (via vitest), so `pnpm test:run` does NOT require rebuilding. Only `node scripts/debug-test.mjs` requires a prior build.
3422

35-
## Project Structure
23+
## Transformation Goals
3624

37-
```
38-
src/
39-
├── index.ts # Main exports
40-
├── transform.ts # Transform implementation
41-
├── __tests__/transform.test.ts # Test runner (auto-discovers test cases)
42-
├── run.ts # Programmatic runner (runTransform)
43-
└── adapter.ts # Adapter API (value resolution + dynamic handlers)
44-
45-
test-cases/
46-
├── *.input.tsx # Input files (styled-components)
47-
├── *.output.tsx # Expected output files (StyleX)
48-
├── *.stylex.ts # StyleX theme variables (defineVars)
49-
├── *.warnings.json # Expected warnings for test cases
50-
├── lib/ # Helper files for test cases
51-
│ ├── helpers.ts # styled-components helpers (color, truncate)
52-
│ ├── helpers.stylex.ts # StyleX version of helpers
53-
│ └── colors.stylex.ts # StyleX color variables
54-
└── TestCases.stories.tsx # Auto-discovering Storybook stories
55-
56-
.storybook/
57-
├── main.ts # Storybook config (Vite, React, StyleX)
58-
└── preview.ts # Storybook preview config
59-
```
25+
The codemod should handle conversions like:
26+
27+
- `styled.div` / `styled(Component)``stylex.create()` + `stylex.props()`
28+
- Template literal CSS → StyleX object syntax
29+
- Dynamic props/interpolations → StyleX variants or dynamic styles
30+
- `keyframes``stylex.keyframes()`
31+
- Theme values → CSS variables or `stylex.createTheme()`
32+
- `css` helper → Plain style objects
33+
- `.attrs()` → Inline props on element
6034

6135
## Scripts
6236

37+
Run repo scripts directly with `node`.
38+
6339
- `scripts/debug-test.mjs` - Generates `.actual.tsx` files for failing test cases to compare against expected `.output.tsx` files. Run with `node scripts/debug-test.mjs` after `pnpm build`.
64-
- `scripts/update-fixtures.mjs` - Updates fixture files.
40+
- `scripts/regenerate-test-case-outputs.mts` - Updates test case output files.
41+
- All supported test cases: `node scripts/regenerate-test-case-outputs.mts`
42+
- Single test case: `node scripts/regenerate-test-case-outputs.mts --only attrs`
43+
- Multiple test cases: `node scripts/regenerate-test-case-outputs.mts --only attrs,css-helper`
6544

6645
## Adding Test Cases
6746

6847
Create matching `.input.tsx` and `.output.tsx` files in `test-cases/`. Tests auto-discover all pairs and fail if any file is missing its counterpart.
6948

70-
Unsupported fixtures can be named `_unsupported.<case>.input.tsx` and should NOT have an output file.
49+
Unsupported test cases can be named `_unsupported.<case>.input.tsx` and should NOT have an output file.
7150

7251
**Test categories:**
7352

7453
- **File pairing**: Verifies all test cases have matching input/output files
7554
- **Output linting**: Runs oxlint on all output files to ensure valid code
76-
- **Transform tests**: Verifies transform produces expected output fixtures for supported cases
55+
- **Transform tests**: Verifies transform produces expected output test cases for supported cases
7756

7857
## Storybook Visual Testing
7958

@@ -85,97 +64,10 @@ Storybook renders all test cases side-by-side (input with styled-components, out
8564

8665
Run `pnpm storybook` to start the dev server and visually compare transformations.
8766

88-
## File Organization Rule (Exports First)
89-
90-
When editing this repo, **keep all exports at the top of each file** (after imports), and keep **non-exported helpers further down**.
91-
92-
- **Allowed at top**: `import …`, then `export …` (types, consts, functions, classes).
93-
- **Not allowed**: introducing a new `export …` _after_ non-exported top-level declarations (e.g. `const …`, `function …`, `type …`).
67+
Use the Playwright MCP to inspect test case rendering.
9468

95-
This keeps entrypoints easy to scan and makes refactors/splits predictable.
69+
## Rules
9670

97-
Example (good):
98-
99-
```ts
100-
import type { Foo } from "./foo.js";
101-
102-
export function doThing(x: Foo) {
103-
return helper(x);
104-
}
105-
106-
function helper(x: Foo) {
107-
return x;
108-
}
109-
```
110-
111-
## Visual Inspection with Playwright MCP
112-
113-
Use the Playwright MCP to inspect test case rendering:
114-
115-
1. Start Storybook: `pnpm storybook`
116-
2. Navigate to `http://localhost:6006/?path=/story/test-cases--all`
117-
3. Use Playwright MCP to take screenshots and verify input/output match visually
118-
119-
The "All" story shows every test case side-by-side, making it easy to compare styled-components input with StyleX output.
120-
121-
## StyleX Requirements
122-
123-
Output files must use valid StyleX syntax:
124-
125-
- **No CSS shorthands**: Use `backgroundColor` not `background`, `borderWidth`/`borderStyle`/`borderColor` not `border`
126-
- **defineVars must be exported**: Theme variables must be in separate `.stylex.ts` files with named exports
127-
- **createTheme needs base vars**: `stylex.createTheme(baseVars, overrides)` requires two arguments
128-
129-
## Test Cases (from styled-components docs)
130-
131-
| Test Case | Pattern |
132-
| ------------------------------- | -------------------------------------------------------------------- |
133-
| `basic` | `styled.h1`, `styled.section` |
134-
| `adapting-props` | Props interpolation with `${props => ...}` |
135-
| `extending-styles` | `styled(Component)` inheritance |
136-
| `pseudo-selectors` | `&:hover`, `&:focus`, `&::before` |
137-
| `keyframes` | `keyframes` + animation |
138-
| `attrs` | `.attrs()` for default props |
139-
| `theming` | `ThemeProvider` + `props.theme` |
140-
| `css-helper` | `css` helper for shared styles |
141-
| `as-prop` | Polymorphic `as` prop |
142-
| `global-styles` | `createGlobalStyle` |
143-
| `media-queries` | `@media (min-width: ...)` responsive styles |
144-
| `nesting` | Child selectors `> *`, `&:not(:first-child)` |
145-
| `component-selector` | `${Link}:hover &` referencing other components |
146-
| `style-objects` | Object syntax `styled.div({...})` |
147-
| `conditional-styles` | Short-circuit `${props => props.x && '...'}` |
148-
| `styled-component` | `styled(CustomComponent)` with className |
149-
| `transient-props` | `$prefix` props to prevent DOM forwarding |
150-
| `refs` | Ref forwarding to styled components |
151-
| `use-theme` | `useTheme` hook for accessing theme |
152-
| `with-theme` | `withTheme` HOC for class components |
153-
| `sibling-selectors` | Adjacent `& + &` and general `& ~ &` sibling selectors |
154-
| `specificity` | Double ampersand `&&` and `&&&` for specificity boost |
155-
| `descendant-component-selector` | `${Child} { ... }` parent styling child component |
156-
| `forwarded-as` | `forwardedAs` prop for passing `as` through HOCs |
157-
| `function-theme` | `theme={fn}` function that receives parent theme |
158-
| `adhoc-theme` | Per-instance `theme` prop override |
159-
| `attribute-selectors` | `&[disabled]`, `&[type="text"]`, `&[href^="https"]` |
160-
| `css-variables` | `var(--custom-property)` CSS custom properties |
161-
| `css-calc` | `calc()` expressions in styles |
162-
| `multiple-animations` | Combining multiple keyframes animations |
163-
| `important` | `!important` declarations (removed in output) |
164-
| `universal-selector` | `& *` universal descendant selector |
165-
| `complex-selectors` | Multiple/compound selectors `&:hover, &:focus` |
166-
| `string-interpolation` | Static string interpolations `${variable}` |
167-
| `should-forward-prop` | `.withConfig({ shouldForwardProp })` prop filtering |
168-
| `with-config` | `.withConfig({ displayName, componentId })` |
169-
| `helpers` | Helper functions: `color()` theme accessor, `truncate()` CSS snippet |
170-
171-
## Transformation Goals
172-
173-
The codemod should handle conversions like:
174-
175-
- `styled.div` / `styled(Component)``stylex.create()` + `stylex.props()`
176-
- Template literal CSS → StyleX object syntax
177-
- Dynamic props/interpolations → StyleX variants or dynamic styles
178-
- `keyframes``stylex.keyframes()`
179-
- Theme values → CSS variables or `stylex.createTheme()`
180-
- `css` helper → Plain style objects
181-
- `.attrs()` → Inline props on element
71+
- **keep all exports at the top of each file** (after imports), and keep **non-exported helpers further down**
72+
- src folder code should never depend on test-cases or test-case logic
73+
- transformations should be safe, bail if we cannot preserve the semantics of the input

0 commit comments

Comments
 (0)