https://github.com/k-kinzal/storybook-php
Storybook framework addon for rendering PHP components as stories
https://github.com/k-kinzal/storybook-php
component-driven php storybook storybook-addon storybook-framework ui
Last synced: about 2 months ago
JSON representation
Storybook framework addon for rendering PHP components as stories
- Host: GitHub
- URL: https://github.com/k-kinzal/storybook-php
- Owner: k-kinzal
- License: mit
- Created: 2026-03-17T14:23:21.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-22T05:32:46.000Z (about 2 months ago)
- Last Synced: 2026-04-22T06:36:45.738Z (about 2 months ago)
- Topics: component-driven, php, storybook, storybook-addon, storybook-framework, ui
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/storybook-php
- Size: 1.28 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# storybook-php
[](LICENSE)
[](https://www.npmjs.com/package/storybook-php)
A Storybook framework addon for developing and previewing PHP components as stories.
## Supported Versions
- PHP 8.0-8.5
- Storybook 10.x
- Vite 5.x-8.x
- Node.js 20.19+
## Quick Start
`.storybook/main.ts`:
```typescript
import type { StorybookConfig } from "storybook";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.ts"],
framework: {
name: "storybook-php",
options: {},
},
};
export default config;
```
`src/Greeting.php`:
```php
{$this->greeting}, {$this->name}!";
}
}
```
`src/Greeting.stories.ts`:
```typescript
import type { Meta, StoryObj } from "storybook-php";
import { Greeting } from "./Greeting.php@render";
const meta: Meta = {
component: Greeting,
title: "Components/Greeting",
};
export default meta;
type Story = StoryObj;
export const Default: Story = {
args: { name: "World" },
};
```
```bash
npx storybook-php start
```
## npx storybook-php
| Command | Description |
| ----------------------------------------------------------- | ----------------------------------------------- |
| `npx storybook-php start [storybook opts]` | Start the Storybook dev server |
| `npx storybook-php build [storybook opts]` | Build static Storybook output |
| `npx storybook-php test [vitest opts]` | Run Storybook tests through `vitest run` |
| `npx storybook-php typegen [dirs...] [--options-file path]` | Generate declaration files for PHP import paths |
`start` and `build` accept the same options as the `storybook` CLI (e.g. `-p 6006`).
`test` passes arguments through to `vitest run`.
`typegen` defaults to the `src` directory when no directories are specified. It writes declaration files next to the source import path, including exact-import outputs such as `Button.php@render.d.ts`. When `defaultMethod` resolves, the bare `Button.php.d.ts` output mirrors that callable; otherwise a bare import remains template-shaped.
If your type generation depends on `defaultMethod` or `typeMap`, pass them through `--options-file` because `typegen` does not read `.storybook/main.ts`. The options file can be JSON or a JS module and may also provide `_configDir` for relative path resolution.
For PHP-first repositories that do not want to add a local `package.json`, see [PHP Project Setup](docs/php-project-setup.md) for the `npx`-based setup.
## Testing
```bash
npx --package=storybook-php --package=vitest \
--package=@storybook/addon-vitest \
--package=@vitest/browser-playwright \
storybook-php test
```
Add `@storybook/addon-vitest` to `.storybook/main.ts`:
```typescript
const config: StorybookConfig = {
addons: ["@storybook/addon-vitest"],
// ...
};
```
If your project does not define `vitest.config.*` and you do not pass `--config`, the bundled Vitest config is used automatically. To customize, create your own `vitest.config.*`.
## Import Syntax
PHP components are imported with the `./File.php@method` specifier. The `@method` suffix tells storybook-php which callable to invoke. Constructor parameters and method parameters are merged into the story's args.
| Pattern | Import Syntax | Args Source |
| ---------------------------- | ----------------------------- | -------------------------------------- |
| Class instance method | `./File.php@render` | Constructor params + method params |
| Static method | `./File.php@danger` | Method params only |
| Standalone function | `./file.php@funcName` | Function params |
| Invocable class | `./File.php@__invoke` | Constructor params + `__invoke` params |
| Enum method | `./File.php@swatch` | `_case` + method params |
| Template file | `./file.php` (default import) | Template variables from args |
| Mapped non-PHP import source | `./card.blade.php` | `typeMap.files` decides the public API |
Methods that use `echo` instead of returning a string are captured via output buffering automatically.
Non-PHP sources such as Blade, Twig, or Latte are supported through `framework.options.typeMap.files`. Those mappings can provide public args, redirect execution to a PHP file, select a callable, include extra files for analysis, and attach adapter middleware.
## Configuration
Configure in `.storybook/main.ts` under `framework.options`:
| Option | Type | Default | Description |
| --------------- | -------- | ----------- | -------------------------------------------------------------------------- |
| `bootstrap` | `string` | `undefined` | Path to a PHP file executed before each render (autoloader, config, etc.) |
| `phpBinary` | `string` | `'php'` | Path to the PHP binary |
| `timeout` | `number` | `5000` | Render timeout in milliseconds |
| `defaultMethod` | `string` | `undefined` | Method name used when `@method` is omitted from the import specifier |
| `adapter` | `string` | `undefined` | Path to a PHP adapter file for custom output handling (e.g. Laravel Blade) |
| `typeMap` | `object` | `undefined` | File mappings, callable overrides, and runtime type bindings |
The adapter file must return middleware compatible with `fn(array $context, callable $next): array|string`
Relative option paths are resolved from Storybook's config directory. `defaultMethod` and `typeMap` also affect module resolution, TS plugin output, and `typegen` when you pass them through `--options-file`.
## TypeScript Support
Add to `tsconfig.json` for type support on `.php` imports and IDE integration:
```json
{
"compilerOptions": {
"types": ["storybook-php/client"],
"plugins": [{ "name": "storybook-php/ts-plugin" }]
}
}
```
This gives editor support for `.php` imports without requiring generated files.
To generate declaration files on disk:
```bash
npx storybook-php typegen
```
`typegen` writes both bare-import and exact-import declarations when they resolve:
- `Button.php.d.ts`
- `Button.php@render.d.ts`
For advanced setups, load `defaultMethod` and `typeMap` from a separate file:
```bash
npx storybook-php typegen --options-file storybook-php.config.mjs
```
## Documentation
- [Getting Started](docs/getting-started.md)
- [PHP Project Setup](docs/php-project-setup.md)
- [Rendering Model](docs/rendering-model.md)
- [Framework Options](docs/framework-options.md)
- [Type Mapping](docs/type-mapping.md)
- [Testing and Types](docs/testing-and-types.md)
## License
[MIT](LICENSE)