Button
The Button component is a fundamental UI element. It supports multiple visual styles (variants), sizes, and can render as a button or an anchor link.
Available in PHPXUI
This component is part of the PHPXUI library. You can easily install it and explore more pre-built components for your project.
Implementation
Create a new file at src/app/Lib/Components/Button.php.
Note how the CSS classes below reference your theme variables (e.g., bg-primary, bg-destructive) rather than hardcoded hex codes.
<?php
namespace Lib\Components;
use Lib\PHPX\PHPX;
class Button extends PHPX
{
public ?string $class = '';
public mixed $children = null;
public function __construct(array $props = [])
{
parent::__construct($props);
}
/**
* Compute standard shadcn/ui classes based on props.
*/
private function getComputedClasses(): string
{
$variant = $this->props['variant'] ?? 'default';
$size = $this->props['size'] ?? 'default';
// Base Styles: Focus rings use --ring color, typography uses --foreground
$baseClass = 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50';
// Variants: Mapped to globals.css variables
$variantClasses = [
'default' => 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
'destructive' => 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
'outline' => 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
'secondary' => 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
'ghost' => 'hover:bg-accent hover:text-accent-foreground',
'link' => 'text-primary underline-offset-4 hover:underline',
];
// Sizes
$sizeClasses = [
'default' => 'h-9 px-4 py-2',
'sm' => 'h-8 rounded-md px-3 text-xs',
'lg' => 'h-10 rounded-md px-8',
'icon' => 'h-9 w-9',
];
return $this->getMergeClasses(
$baseClass,
$variantClasses[$variant] ?? $variantClasses['default'],
$sizeClasses[$size] ?? $sizeClasses['default']
);
}
public function render(): string
{
$class = $this->getComputedClasses();
$attributes = $this->getAttributes([
'class' => $class,
'type' => 'button',
]);
return <<<HTML
<button {$attributes}>
{$this->children}
</button>
HTML;
}
}
Props
| Prop | Default | Description |
|---|---|---|
| variant | "default" |
Style variant. Options: default, secondary, destructive, outline, ghost, link.
|
| size | "default" |
Size of the button. Options: default, sm, lg, icon.
|
| type | "button" | HTML button type attribute (e.g., submit, reset). |
Usage
<?php
use Lib\Components\Button;
use Lib\PPIcons\Mail; // Assuming you have an icon component
?>
<div class="flex flex-col gap-8 p-4">
<!-- 1. Variants -->
<div class="flex flex-wrap gap-4 items-center">
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
<!-- 2. Sizes -->
<div class="flex flex-wrap gap-4 items-center">
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
</div>
<!-- 3. Icon Button -->
<div class="flex items-center gap-4">
<Button variant="outline" size="icon">
<Mail class="size-4" />
</Button>
<Button>
<Mail class="mr-2 size-4" /> Login with Email
</Button>
</div>
</div>