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>