PHP code example of hadyfayed / filament-react-wrapper

1. Go to this page and download the library: Download hadyfayed/filament-react-wrapper library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

hadyfayed / filament-react-wrapper example snippets


// app/Providers/Filament/AdminPanelProvider.php
use HadyFayed\ReactWrapper\FilamentReactWrapperPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentReactWrapperPlugin::make(),
        ]);
}

use HadyFayed\ReactWrapper\Components\ReactComponent;

class EditUser extends EditRecord
{
    protected function getHeaderActions(): array
    {
        return [
            ReactComponent::make('UserProfileEditor')
                ->props([
                    'userId' => $this->record->id,
                    'editable' => true
                ])
                ->statePath('userProfile')
        ];
    }
}



namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class ReactComponentServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $registry = app(ReactComponentRegistry::class);

        // Register components with PHP
        $registry->register([
            'name' => 'UserCard',
            'component_path' => 'resources/js/components/UserCard.tsx',
            'default_props' => [
                'showAvatar' => true,
                'size' => 'medium'
            ],
            'metadata' => [
                'category' => 'user',
                'description' => 'Displays user information in a card format',
                'tags' => ['user', 'display', 'card']
            ]
        ]);

        // Register multiple components
        $registry->registerMany([
            [
                'name' => 'ProductCard',
                'component_path' => 'resources/js/components/ProductCard.tsx',
                'default_props' => ['showPrice' => true],
                'metadata' => ['category' => 'product']
            ],
            [
                'name' => 'OrderSummary', 
                'component_path' => 'resources/js/components/OrderSummary.tsx',
                'is_async' => true,
                'config' => ['lazy' => true, 'cache' => true]
            ]
        ]);
    }
}



return [
    'components' => [
        'auto_register' => true,
        'scan_directories' => [
            'resources/js/components',
            'resources/js/widgets'
        ],
        'registered_components' => [
            'UserProfile' => [
                'component_path' => 'resources/js/components/UserProfile.tsx',
                'default_props' => ['editable' => false],
                'config' => ['lazy' => false, 'cache' => true],
                'metadata' => [
                    'category' => 'user',
                    'description' => 'User profile management component'
                ]
            ],
            'DataTable' => [
                'component_path' => 'resources/js/components/DataTable.tsx',
                'is_async' => true,
                'default_props' => [
                    'pageSize' => 10,
                    'sortable' => true
                ],
                'config' => [
                    'lazy' => true,
                    'cache' => true,
                    'preload' => false
                ]
            ]
        ]
    ]
];



use HadyFayed\ReactWrapper\Facades\ReactWrapper;

// In a controller, middleware, or service
class ComponentController extends Controller
{
    public function registerComponent()
    {
        ReactWrapper::register([
            'name' => 'DynamicChart',
            'component_path' => 'resources/js/charts/DynamicChart.tsx',
            'default_props' => [
                'type' => 'line',
                'animated' => true
            ],
            'config' => [
                'lazy' => true,
                'cache' => false // Don't cache dynamic components
            ]
        ]);

        return response()->json(['message' => 'Component registered successfully']);
    }

    public function getRegisteredComponents()
    {
        $components = ReactWrapper::getRegistered();
        return response()->json($components);
    }
}



namespace YourPackage\Providers;

use Illuminate\Support\ServiceProvider;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class YourPackageServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Register package components automatically
        $this->registerPackageComponents();
        
        // Publish package components
        $this->publishes([
            __DIR__.'/../resources/js/components' => resource_path('js/vendor/your-package'),
        ], 'your-package-components');
    }

    protected function registerPackageComponents()
    {
        $registry = app(ReactComponentRegistry::class);

        $packageComponents = [
            'PackageWidget' => [
                'component_path' => 'js/vendor/your-package/PackageWidget.tsx',
                'default_props' => ['theme' => 'package-default'],
                'metadata' => [
                    'category' => 'package-widgets',
                    'package' => 'your-package',
                    'version' => '1.0.0'
                ]
            ]
        ];

        foreach ($packageComponents as $name => $config) {
            $registry->register(array_merge($config, ['name' => $name]));
        }
    }
}



namespace App\Filament\Resources;

use Filament\Resources\Resource;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class UserResource extends Resource
{
    public static function boot()
    {
        parent::boot();
        
        // Register resource-specific components
        app(ReactComponentRegistry::class)->register([
            'name' => 'UserResourceChart',
            'component_path' => 'resources/js/filament/UserResourceChart.tsx',
            'default_props' => [
                'resource' => 'users',
                'metric' => 'registrations'
            ]
        ]);
    }

    public static function form(Form $form): Form
    {
        return $form->schema([
            ReactField::make('user_analytics')
                ->component('UserResourceChart')
                ->props(['userId' => fn($record) => $record?->id])
                ->visible(fn($record) => $record !== null)
        ]);
    }
}



namespace App\Filament\Components;

use HadyFayed\ReactWrapper\Components\ReactComponent;

class UserDashboard extends ReactComponent
{
    protected string $component = 'UserDashboard';
    
    public static function make(string $component = null): static
    {
        return new static($component ?? static::$component);
    }
    
    public function userId(int $userId): static
    {
        $this->props(['userId' => $userId]);
        return $this;
    }
    
    public function editable(bool $editable = true): static
    {
        $this->props(['editable' => $editable]);
        return $this;
    }
}

use App\Filament\Components\UserDashboard;

class Dashboard extends Page
{
    protected static string $view = 'filament.pages.dashboard';
    
    protected function getHeaderWidgets(): array
    {
        return [
            UserDashboard::make()
                ->userId(auth()->id())
                ->editable(true)
                ->statePath('dashboard.user')
        ];
    }
}

use HadyFayed\ReactWrapper\Forms\Components\ReactField;

class UserForm extends Form
{
    public function form(Form $form): Form
    {
        return $form->schema([
            ReactField::make('profile_editor')
                ->component('UserProfileEditor')
                ->props([
                    'allowImageUpload' => true,
                    'maxImageSize' => '2MB'
                ])
                ->statePath('profile')
                ->reactive()
                ->afterStateUpdated(function ($state) {
                    // Handle state updates
                    $this->user->update($state);
                })
        ]);
    }
}



namespace HadyFayed\ReactWrapper\Services;

interface ReactComponentRegistryInterface
{
    public function register(array $definition): void;
    public function registerMany(array $definitions): void;
    public function get(string $name): ?array;
    public function has(string $name): bool;
    public function unregister(string $name): bool;
    public function clear(): void;
    public function getRegistered(): array;
    public function getStats(): array;
    public function scan(string $directory): array;
}



use HadyFayed\ReactWrapper\Facades\ReactWrapper;

// Register component
ReactWrapper::register([
    'name' => 'ComponentName',
    'component_path' => 'path/to/component.tsx',
    'default_props' => ['prop' => 'value'],
    'config' => ['lazy' => true, 'cache' => true],
    'metadata' => ['category' => 'widgets']
]);

// Register multiple components
ReactWrapper::registerMany($components);

// Get component definition
$definition = ReactWrapper::get('ComponentName');

// Check if component exists
$exists = ReactWrapper::has('ComponentName');

// Get all registered components
$components = ReactWrapper::getRegistered();

// Get registration statistics
$stats = ReactWrapper::getStats();

// Scan directory for components
$found = ReactWrapper::scan('resources/js/components');



use HadyFayed\ReactWrapper\Forms\Components\ReactField;

ReactField::make('field_name')
    ->component('ComponentName')           // React component name
    ->props(['key' => 'value'])           // Component props
    ->defaultProps(['default' => true])   // Default props
    ->statePath('form.field')             // State synchronization path
    ->height(400)                         // Container height
    ->width('100%')                       // Container width
    ->reactive()                          // Make field reactive
    ->live()                             // Enable live updates
    ->debounce(300)                      // Debounce updates (ms)
    ->afterStateUpdated(fn($state) => ...) // State change callback
    ->visible(fn($get) => $get('show'))   // Conditional visibility
    ->disabled(fn($get) => !$get('edit')) // Conditional disable
    ->



use HadyFayed\ReactWrapper\Widgets\ReactWidget;

class CustomWidget extends ReactWidget
{
    protected string $component = 'WidgetComponent';
    
    protected function getProps(): array
    {
        return [
            'title' => 'Widget Title',
            'data' => $this->getData(),
            'config' => $this->getConfig()
        ];
    }
    
    protected function getHeight(): ?string
    {
        return '300px';
    }
    
    protected function getStatePath(): ?string
    {
        return 'widgets.custom';
    }
    
    public static function canView(): bool
    {
        return auth()->user()?->can('view-widgets') ?? false;
    }
}



// config/react-wrapper.php
return [
    'debug' => env('REACT_WRAPPER_DEBUG', false),
    'cache_components' => env('REACT_WRAPPER_CACHE', true),
    'preload_components' => env('REACT_WRAPPER_PRELOAD', false),
    'max_state_size' => env('REACT_WRAPPER_MAX_STATE_SIZE', 1000),
    
    'components' => [
        'auto_register' => true,
        'scan_directories' => [
            'resources/js/components',
            'resources/js/widgets'
        ],
        'registered_components' => [
            // Component definitions
        ]
    ],
    
    'memory_safety' => [
        'max_subscriptions_per_path' => 100,
        'cleanup_interval' => 300000, // 5 minutes
        'enable_loop_detection' => true,
    ],
    
    'security' => [
        'validate_props' => true,
        'sanitize_html' => true,
        'max_prop_size' => 1024 * 1024, // 1MB
    ]
];



use HadyFayed\ReactWrapper\Events\ComponentRegistered;
use HadyFayed\ReactWrapper\Events\ComponentRendered;

// Listen for component registration
Event::listen(ComponentRegistered::class, function ($event) {
    Log::info('Component registered: ' . $event->componentName);
});

// Listen for component rendering
Event::listen(ComponentRendered::class, function ($event) {
    // Track component usage
    Analytics::track('component_rendered', [
        'component' => $event->componentName,
        'props' => $event->props
    ]);
});

// config/react-wrapper.php
return [
    'debug' => env('REACT_WRAPPER_DEBUG', false),
    'cache_components' => env('REACT_WRAPPER_CACHE', true),
    'preload_components' => env('REACT_WRAPPER_PRELOAD', false),
    'max_state_size' => env('REACT_WRAPPER_MAX_STATE_SIZE', 1000),
    'memory_safety' => [
        'max_subscriptions_per_path' => 100,
        'cleanup_interval' => 300000, // 5 minutes
        'enable_loop_detection' => true,
    ],
];
typescript
// Automatic cleanup on component unmount
React.useEffect(() => {
  const unsubscribe = globalStateManager.subscribe('user.data', handleUserChange);
  
  return () => {
    unsubscribe(); // Automatic cleanup
  };
}, []);

// Bounded data structures prevent unlimited growth
// Maximum 1000 entries in persistence service with automatic cleanup