Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Component Model Laravel Package

nette/component-model

Nette Component Model provides a lightweight component hierarchy for PHP apps. It supports parent/child relationships, naming, lookup, and lifecycle hooks, making it easy to build reusable UI or service components that can be composed, traversed, and managed consistently.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require nette/component-model

First Use Case: Create a reusable UI component hierarchy (e.g., a form with nested fields).

use Nette\ComponentModel\Component;
use Nette\ComponentModel\Container;

class FormField extends Component {
    public function render(): void {
        echo "<input type='text' name='{$this->getName()}'>";
    }
}

$form = new Container;
$form->addComponent(new FormField(), 'username');
$form->addComponent(new FormField(), 'email');

// Access via ArrayAccess or getComponent()
$form['username']->render();

Where to Look First:

  • src/ComponentModel/Component.php (core component behavior)
  • src/ComponentModel/Container.php (hierarchical management)
  • src/ComponentModel/IComponent.php (interface contracts)

Implementation Patterns

1. Component Hierarchy

Use Container to build nested structures (e.g., admin panels, modular UIs):

$dashboard = new Container;
$dashboard->addComponent(new UserProfile(), 'profile');
$dashboard->addComponent(new Notifications(), 'notifications');

// Access children via ArrayAccess or getComponent()
$dashboard['profile']->loadData();

2. Lifecycle Monitoring

Replace deprecated attached()/detached() with monitor():

class ParentComponent extends Component {
    public function __construct() {
        $this->monitor(ChildComponent::class, function ($child, ?Component $parent) {
            if ($parent === null) {
                echo "Child {$child->getName()} was detached!";
            }
        });
    }
}

3. Debugging with Component Trees

Visualize hierarchies in admin panels:

$tree = $container->getComponentTree();
dd($tree); // Returns array of component names and children

4. Integration with Laravel

Workaround for Laravel Devs: Use Container as a lightweight registry for non-DI components (e.g., Blade views):

// In a service provider
$viewContainer = new Container;
$viewContainer->addComponent(new HeaderView(), 'header');
$viewContainer->addComponent(new FooterView(), 'footer');

// In a Blade view
@php
    $header = $viewContainer['header'];
    $header->render();
@endphp

5. Type Safety

Leverage PHP 8.2+ features:

class Button extends Component {
    public function __construct(
        public string $label,
        public string $type = 'button'
    ) {}
}

Gotchas and Tips

Pitfalls

  1. Deprecated Magic Properties Avoid $component->name or $container->components—use getName()/getComponents() instead (v3.2+ deprecation).

  2. Name Handling

    • getComponent() requires string names (v3.0+). Integers throw NotFoundException.
    • ArrayAccess accepts integers but may cause confusion. Prefer strings like 'btn_submit'.
  3. Monitor Callback Reentry Nested monitor() calls may loop if not guarded. Use refreshMonitors() carefully:

    $this->refreshMonitors(); // Only call this if you’re manually managing lifecycle.
    
  4. PHP 8.5 Dynamic Properties Avoid $this->$dynamicProp in monitor() callbacks—use typed properties or #[AllowDynamicProperties].

  5. Silent Deprecations

    • getComponents($deep) now always returns an array (v3.1.0+). Old code expecting void will break.
    • $deep parameter is silently deprecated—use getComponentTree() instead.

Debugging Tips

  • Exception Messages: NotFoundException includes typo suggestions (e.g., “Did you mean ‘submit’?”).
  • Component Tree: Use getComponentTree() to inspect hierarchies during development.
  • Static Analysis: Enable nette/phpstan-rules for stricter type checks.

Extension Points

  1. Custom Container Extend Container to add validation or auto-loading:

    class ValidatedContainer extends Container {
        public function addComponent(Component $component, string $name): void {
            if (str_contains($name, '..')) {
                throw new \InvalidArgumentException("Invalid name: {$name}");
            }
            parent::addComponent($component, $name);
        }
    }
    
  2. Monitor Wrappers Create helper methods for common callbacks:

    class Component {
        protected function onDetach(callable $callback) {
            $this->monitor(static::class, function ($c, ?Component $parent) use ($callback) {
                if ($parent === null) $callback($c);
            });
        }
    }
    
  3. ArrayAccess Overrides Customize offsetGet() for lazy-loading:

    class LazyContainer extends Container implements ArrayAccess {
        public function offsetGet($offset) {
            if (!isset($this[$offset])) {
                $this[$offset] = new DefaultComponent();
            }
            return parent::offsetGet($offset);
        }
    }
    

Laravel-Specific Quirks

  • Naming Conflicts: Avoid naming classes Component or Container to prevent collisions with Laravel’s Illuminate\Container.
  • Service Container Integration: This package does not integrate with Laravel’s DI. Use it only for non-DI hierarchies (e.g., Blade components, admin panels).
  • Event System: Laravel’s events are separate from Nette’s monitor(). Bridge them manually if needed:
    $component->monitor(ChildComponent::class, function ($child) {
        event(new ComponentAttached($child));
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php