CLAUDE.md
CLAUDE.mdCLAUDE.mdroot
Quality
100/100
Scores the file, not the repository.Length
1,076 words
26 headings · 15 code blocksRepository
32k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## Project Overview67Filament is a full-stack UI framework for Laravel built with Livewire. It provides admin panels, forms, tables, notifications, actions, infolists, and widgets as composable packages.89## Critical: Naming Conventions1011### Variable Names1213**Never use abbreviated variable names.** Use full descriptive names:1415```php16// GOOD17$exception, $component, $response, $configuration, $record, $livewire1819// BAD - never do this20$e, $comp, $res, $cfg, $rec, $lw21```2223Only exception: universally understood abbreviations like `$id`, `$url`.2425### Pest Test Names2627**Always use backticks for code references. Add `()` for methods:**2829```php30// GOOD31it('can use `aspectRatio()` to force image cropping')32it('returns `null` for `getImageCropAspectRatio()` by default')33it('validates `$record` is an instance of `Model`')3435// BAD - missing backticks36it('can use aspectRatio to force image cropping')37it('returns null for getImageCropAspectRatio by default')38```3940### Code Comments4142**Use backticks when referencing code in comments:**4344```php45// GOOD46// Uses `evaluate()` to resolve the `Closure`47// Returns `null` if the `$record` is not set4849// BAD50// Uses evaluate() to resolve the Closure51```5253## Development Commands5455**Always update tests when making changes.** For UI components, add browser tests using Pest Browser with `visit()`. Always call `assertNoAccessibilityIssues()` in both light and dark modes (`->inDarkMode()`).5657```bash58composer test # Run all tests (SQLite + commands + PHPStan)59composer test:sqlite # Run tests with SQLite60composer test:mysql # Run tests with MySQL61composer test:pgsql # Run tests with PostgreSQL62composer test:phpstan # Run PHPStan static analysis63composer cs # Run all code style fixes (Rector + Pint + Prettier)6465npm run build # Build all JS and CSS66npm run build-demo # Build and publish to ../demo if it exists6768# Run a single test file69vendor/bin/pest tests/src/Forms/Components/FileUploadTest.php7071# Run a single test by name72vendor/bin/pest --filter="it can use \`aspectRatio\(\)\` to force image cropping"73```7475## Coding Patterns7677### Fluent API7879Components use `make()` constructor and fluent chainable methods. Nullable properties have nullable setters so they can be undone:8081```php82TextInput::make('name')83 ->label('Full name')84 ->icon('heroicon-o-user')8586// Property and setter share the same name, nullable to allow unsetting87protected string | Closure | null $icon = null;8889public function icon(string | Closure | null $icon): static90{91 $this->icon = $icon;9293 return $this;94}9596// Getter prefixed with `get`, uses `evaluate()` for `Closure` support97public function getIcon(): ?string98{99 return $this->evaluate($this->icon);100}101```102103### Boolean Methods104105```php106// Property - `is`/`should`/`can`/`has` prefix, defaults `false`, supports `Closure`107protected bool | Closure $isDisabled = false;108109// Setter - verb form, defaults `true`, pass `false` to undo110public function disabled(bool | Closure $condition = true): static111{112 $this->isDisabled = $condition;113114 return $this;115}116117// Getter - cast to `bool`118public function isDisabled(): bool119{120 return (bool) $this->evaluate($this->isDisabled);121}122```123124### Static Closures125126Use `static fn` when the closure doesn't use `$this`:127128```php129->placeholder(static fn (Select $component): ?string => $component->isDisabled() ? null : 'Select...')130->visible(fn (): bool => $this->canView()) // Uses `$this`, cannot be static131```132133### Container Resolution134135Use `app()` instead of `new` to allow users to bind custom implementations:136137```php138app(RelationshipJoiner::class)->prepareQuery($relationship) // Good139(new RelationshipJoiner())->prepareQuery($relationship) // Avoid140```141142### Extensibility143144Do not use `final` or `readonly` classes - users need to extend Filament classes.145146### Concerns and Contracts147148Traits in `Concerns/` directories: `Can*` (capabilities), `Has*` (properties).149Interfaces in `Contracts/` directories.150151## Coding Standards152153### PHPDoc154155Only add when providing type info beyond native PHP types:156157```php158/** @var array<string, array{label: string, icon: string}> */ // Good159/** @param string $name The name */ // Redundant160```161162### Deprecations163164Keep old public methods used in docs, mark deprecated:165166```php167/** @deprecated Use `newMethod()` instead. */168public function oldMethod(): void169{170 return $this->newMethod();171}172```173174## Architecture175176### Packages (`packages/`)177178Core: **support** (base utilities) → **schemas** (UI layouts) → **forms**, **infolists**, **tables**, **actions**, **notifications**, **widgets** → **panels** (full admin framework)179180Other: query-builder, upgrade, spatie-laravel-media-library-plugin, spatie-laravel-settings-plugin, spatie-laravel-tags-plugin, spatie-laravel-google-fonts-plugin, spark-billing-provider181182### Key Classes183184- **Resources** (`packages/panels/src/Resources/`): CRUD interfaces for Eloquent models185- **Pages** (`packages/panels/src/Pages/`): Livewire page components186- **Schema Components** (`packages/schemas/src/Components/`): Base UI components187- **Actions** (`packages/actions/src/`): Modal-based operations188- **Panel** (`packages/panels/src/Panel.php`): Admin panel configuration189190### File Locations191192- Tests: `tests/src/{Forms,Tables,Actions,Panels}/`193- Docs: `docs/` and `packages/{package}/docs/`194- Views: `packages/{package}/resources/views/`195- CSS: `packages/{package}/resources/css/`196- Translations: `packages/{package}/resources/lang/{locale}/`197198### CSS Hook Classes199200**Never use Tailwind classes directly in Blade views.** All Tailwind classes must be in CSS files using `@apply`:201202```css203.fi-fo-field {204 @apply grid gap-y-2;205}206```207208Hook class naming:209- Prefix: `fi-` with package codes (`fi-fo-` forms, `fi-ta-` tables, `fi-ac-` actions, etc.)210- Abbreviations: `btn`, `col`, `ctn`, `wrp`211212## Writing Documentation213214**Always update documentation for user-facing features** in `packages/{package}/docs/`.215216- **Tone**: Direct, second person ("You may set...", "You can do this using...")217- **Structure**: Start with `## Introduction`, show simplest code first218- **Headings**: Use gerunds ("Setting the type" not "Type settings", "Enabling search" not "Search")219- **Formatting**: Backticks for code (`method()`, `ClassName`), include `use` statements220- **Asides**: `<Aside variant="tip|info|danger">...</Aside>`221222### Documentation Screenshots223224Screenshots are in `docs-assets/screenshots/`. To add new screenshots:2252261. **Add component examples** to the appropriate Livewire component in `docs-assets/app/app/Livewire/` (e.g., `Schemas/LayoutDemo.php`). Give each example a unique `->id()` for the selector:227```php228 Group::make()229 ->id('myComponent')230 ->extraAttributes(['class' => 'p-16 max-w-2xl'])231 ->schema([232 // Your component here233 ]),234```2352362. **Add screenshot definitions** to `docs-assets/screenshots/schema.js`:237```js238 'schemas/layout/my-component/simple': {239 url: 'schemas/layout',240 selector: '#myComponent',241 viewport: { width: 1920, height: 640, deviceScaleFactor: 3 },242 },243```2442453. **Build assets** if you changed any CSS or JS files. Two builds are required — the repo root compiles each package's dist output, and the docs app has its own Vite build that bundles those outputs into `docs-assets/app/public/build/`. Skipping the second step leaves the docs app serving stale CSS, and screenshots will render against pre-change styles:246```bash247 # Terminal 1: compile package dist output248 npm run build249250 # Terminal 2: bundle the docs app's CSS from the package output251 cd docs-assets/app && npm run build252```253 If you also changed the Livewire demo or Blade views, clear caches afterwards: `cd docs-assets/app && php artisan optimize:clear`.2542554. **Generate screenshots**:256```bash257 # Terminal 1: Start the app server (must use default port 8000)258 cd docs-assets/app && php artisan serve259260 # Terminal 2: Run from the screenshots directory261 cd docs-assets/screenshots262 export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true263 export PUPPETEER_EXECUTABLE_PATH=$(which chromium)264 node script.js "schemas/layout/my-component/*" # Filter pattern265```266267 **Important:** The script expects `http://127.0.0.1:8000`. Don't use a custom port.2682695. **Use in docs** with `<AutoScreenshot name="schemas/layout/my-component/simple" alt="Description" version="4.x" />`270271Screenshots are generated in `images/light/` and `images/dark/`. Use natural, realistic content - not test-like examples.272
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 3 days ago | |
| lollipopkit/flutter_server_boxCLAUDE.md · 8.3k | CLAUDE.md | buildteststylearch+2 | 98/100 | 3 days ago | |
| supabase/supabase.claude/CLAUDE.md · 107k | CLAUDE.md | testlint-formatstylearch+1 | 97/100 | 3 days ago | |
| ruvnet/rufloruflo/src/ruvocal/CLAUDE.md · 67k | CLAUDE.md | setupbuildtestlint-format+6 | 97/100 | 3 days ago | |
| MetaMask/metamask-design-systemCLAUDE.md · 34 | CLAUDE.md | buildtestlint-formatstyle+5 | 97/100 | 3 days ago |
