contao-components/handorgel
Handorgel integration for Contao, providing an accessible, lightweight accordion/collapsible UI component as a Contao component/package. Helps add expandable panels to front ends with simple setup and consistent behavior across browsers.
Installation
composer require contao-components/handorgel
Ensure your Laravel app meets Handorgel’s PHP requirements (PHP 8.1+ recommended).
Basic Usage Handorgel is a JavaScript-based package for creating interactive, animated SVG diagrams (e.g., flowcharts, org charts). To integrate:
@vite(['resources/js/handorgel.js', 'resources/css/handorgel.css'])
<div id="handorgel-container"></div>
<script>
const handorgel = new Handorgel({
container: '#handorgel-container',
data: {
nodes: [{ id: '1', label: 'Node 1' }],
edges: []
}
});
</script>
First Use Case Visualize a simple workflow (e.g., user signup flow) with nodes/edges. Use Laravel’s Blade to pass dynamic data:
@php
$workflowData = [
'nodes' => ['auth' => ['label' => 'Authentication'], 'profile' => ['label' => 'Profile Setup']],
'edges' => [['from' => 'auth', 'to' => 'profile']]
];
@endphp
<script>
new Handorgel({ container: '#workflow', data: @json($workflowData) });
</script>
Laravel Eloquent ↔ Handorgel Data
Map database models to Handorgel’s nodes/edges format. Example:
$nodes = User::with('roles')->get()->map(fn ($user) => [
'id' => $user->id,
'label' => $user->name,
'data' => ['role' => $user->roles->first()->name] // Custom attributes
]);
Pass to Handorgel via @json($nodes->toArray()).
API Endpoints Create a Laravel API route to fetch Handorgel data dynamically:
Route::get('/handorgel-data', function () {
return response()->json([
'nodes' => Node::all()->toHandorgelFormat(),
'edges' => Edge::all()->toHandorgelFormat()
]);
});
Real-Time Updates Use Laravel Echo + Pusher to push Handorgel data changes (e.g., node additions) to clients:
Echo.channel('handorgel-updates')
.listen('NodeAdded', (data) => {
handorgel.addNode(data.node);
});
Server-Side Rendering (SSR) For SPAs, pre-render Handorgel diagrams on the server (Laravel) and hydrate client-side:
// In a controller
return inertia('HandorgelPage', [
'initialData' => $handorgelData
]);
// Inertia page
const { initialData } = props;
const handorgel = new Handorgel({ data: initialData });
Custom Interactions Extend Handorgel with Laravel-backed actions:
handorgel.on('nodeClick', (nodeId) => {
axios.post(`/nodes/${nodeId}/actions`, { action: 'archive' });
});
SVG Scaling Issues
viewBox or set a fixed container height:
#handorgel-container {
height: 600px;
width: 100%;
}
Data Format Strictness
nodes/edges. Validate with Laravel’s Form Requests:
public function rules() {
return [
'nodes.*.id' => 'required|string',
'edges.*.from' => 'required|exists:nodes,id'
];
}
JavaScript Initialization Race Conditions
defer or DOMContentLoaded:
<script defer>
document.addEventListener('DOMContentLoaded', () => {
new Handorgel({ container: '#handorgel-container' });
});
</script>
nodeAdded). Listen in browser console:
handorgel.on('*', (event) => console.log(event));
\Log::debug('Handorgel data:', $handorgelData);
Custom Node Templates Override Handorgel’s default node rendering via CSS/JS:
handorgel.setNodeTemplate((node) => `
<div class="custom-node ${node.data.type}">
${node.label}
</div>
`);
Laravel Service Provider Bind Handorgel to Laravel’s container for dependency injection:
// app/Providers/AppServiceProvider.php
$this->app->singleton(Handorgel::class, function () {
return new Handorgel(config('handorgel.defaults'));
});
Testing
Use Laravel’s Livewire or Alpine.js to test Handorgel interactions:
// Example with Alpine
<div x-data="{ handorgel: null }" x-init="
handorgel = new Handorgel({ container: '#container' });
handorgel.on('nodeClick', () => alert('Test passed!'));
">
How can I help you explore Laravel packages today?