Icon Component
To create an icon component, you can use any image format (jpg, png), but it is highly recommended to use svg. SVGs are vector-based, lightweight, and easily styled using Tailwind CSS classes.
Recommended: PPIcons
PPIcons is the premier icon library specifically designed for PHPX. It offers over 1600+ icons and includes a dedicated CLI for easy selection and installation.
Manual Implementation
In this example, we will create a SearchIcon component using raw SVGs. You can source SVGs from libraries like Google Icons or Lucide Icons.
Create a new file at src/app/Lib/GoogleIcons/Search.php:
<?php
namespace Lib\GoogleIcons;
use PP\PHPX\PHPX;
class Search extends PHPX
{
public ?string $class = '';
public function __construct(array $props = [])
{
parent::__construct($props);
}
public function render(): string
{
$class = $this->getMergeClasses($this->class);
$attributes = $this->getAttributes([
'class' => $class,
]);
return <<<HTML
<svg
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 -960 960 960"
width="24px"
fill="currentColor"
{$attributes}
>
<path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/>
</svg>
HTML;
}
}
Supported Props
| Prop | Default | Description |
|---|---|---|
| class | "" | Custom Tailwind CSS classes for styling (e.g., color, size). |
| attributes | [] | Any standard HTML attributes to pass to the <svg> tag. |
Usage Example
You can now integrate the component into your application. Notice how we use Tailwind classes like text-primary or size-10 to style the SVG externally.
<?php
use Lib\GoogleIcons\Search;
?>
<div class="w-full h-96 grid place-items-center bg-background">
<div class="flex gap-4 flex-col w-full max-w-sm">
<!-- Basic Icon Usage -->
<div class="flex items-center gap-2">
<span class="text-sm font-medium">Large Icon:</span>
<Search class="size-10 text-primary" />
</div>
<!-- Inside an Input Group -->
<div class="relative">
<label for="search" class="sr-only">Search</label>
<Search class="absolute left-2.5 top-2.5 size-4 text-muted-foreground" />
<input
id="search"
name="search"
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pl-9 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
type="text"
placeholder="Search documentation..." />
</div>
<!-- Inside a Button -->
<button class="inline-flex items-center justify-center gap-2 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 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2">
Search
<Search class="size-4" />
</button>
</div>
</div>