Compare commits

..

3 Commits

Author SHA1 Message Date
Pedro Cabral
9e9f05abdf WIP: added button component
add tests
2026-04-27 23:30:33 +02:00
Pedro Cabral
5ae25db82f added storybook 2026-04-27 23:30:33 +02:00
Pedro Cabral
cad935f64b added colour palette 2026-04-27 23:30:18 +02:00
8 changed files with 19 additions and 161 deletions

View File

@@ -1,19 +1,15 @@
<?php <?php
declare(strict_types=1);
namespace App\View\Components; namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\View\Component; use Illuminate\View\Component;
class Button extends Component class Button extends Component
{ {
public const VARIANT_PRIMARY = 'primary';
public const VARIANT_SECONDARY = 'secondary';
public const VARIANT_OUTLINE = 'outline';
public function __construct(public string $variant = self::VARIANT_PRIMARY, public bool $disabled = false) public function __construct(public string $variant = 'primary', public bool $disabled = false)
{ {
// //
} }
@@ -24,15 +20,15 @@ class Button extends Component
'duration-150 ease-in-out'; 'duration-150 ease-in-out';
$classes = match ($this->variant) { $classes = match ($this->variant) {
self::VARIANT_SECONDARY => [ 'secondary' => [
'base' => 'bg-secondary text-text', 'base' => 'bg-secondary text-text',
'hover' => 'hover:bg-secondary-dark', 'hover' => 'hover:bg-secondary-dark',
'disabled' => 'disabled:bg-secondary', 'disabled' => 'disabled:bg-secondary',
], ],
self::VARIANT_OUTLINE => [ 'outline' => [
'base' => 'bg-surface border border-primary text-primary', 'base' => 'bg-outline border border-primary text-primary',
'hover' => 'hover:bg-primary hover:text-text-inverted', 'hover' => 'hover:bg-primary hover:text-text-inverted',
'disabled' => 'disabled:bg-surface disabled:text-primary', 'disabled' => 'disabled:bg-outline disabled:text-primary',
], ],
default => [ default => [
'base' => 'bg-primary text-text-inverted', 'base' => 'bg-primary text-text-inverted',
@@ -55,7 +51,7 @@ class Button extends Component
/** /**
* Get the view / contents that represent the component. * Get the view / contents that represent the component.
*/ */
public function render(): View public function render(): View|Closure|string
{ {
return view('components.button'); return view('components.button');
} }

View File

@@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
namespace App\View\Components;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class Card extends Component
{
public function __construct(public string $header = '')
{
//
}
public function render(): View
{
return view('components.card');
}
}

View File

@@ -19,12 +19,15 @@
--color-secondary-light: #FCD34D; --color-secondary-light: #FCD34D;
--color-secondary-dark: #B45309; --color-secondary-dark: #B45309;
/* OUTLINE */
--color-outline: rgba(0, 0, 0 ,0);
/* BACKGROUND */ /* BACKGROUND */
--color-background: #F8FAFC; --color-background: #F8FAFC;
--color-background-dark: #E2E8F0; --color-background-dark: #E2E8F0;
/* SURFACE */ /* SURFACE */
--color-surface: #ffffff; --color-surface: #FFFFFF;
--color-surface-muted: #F1F5F9; --color-surface-muted: #F1F5F9;
/* TEXT */ /* TEXT */

View File

@@ -1,10 +0,0 @@
<div class="card bg-surface rounded border border-primary shadow">
@if(!empty($header))
<div class="card-header p-4 border-b border-primary">
<h3 class="font-semibold">{{ $header }}</h3>
</div>
@endif
<div class="card-body p-4">
{{ $slot }}
</div>
</div>

View File

@@ -27,15 +27,15 @@
<h3 class="text-l font-semibold">Enabled</h3> <h3 class="text-l font-semibold">Enabled</h3>
<div class="flex gap-4"> <div class="flex gap-4">
<x-button onclick="alert('Default was clicked!')">Default</x-button> <x-button>Default</x-button>
<x-button variant="primary" onclick="alert('Primary was clicked!')">Primary</x-button> <x-button variant="primary">Primary</x-button>
<x-button variant="secondary" onclick="alert('Secondary was clicked!')">Secondary</x-button> <x-button variant="secondary">Secondary</x-button>
<x-button variant="outline" onclick="alert('Outline was clicked!')">Outline</x-button> <x-button variant="outline">Outline</x-button>
</div> </div>
<h3 class="text-l font-semibold">Disabled</h3> <h3 class="text-l font-semibold">Disabled</h3>
@@ -56,16 +56,11 @@
<!-- CARDS --> <!-- CARDS -->
<section class="space-y-4"> <section class="space-y-4">
<h2 class="text-xl font-semibold">Cards</h2> <h2 class="text-xl font-semibold">Cards</h2>
<h3 class="text-l font-semibold">With Header</h3>
<x-card header="Card Header"> <div class="bg-surface p-6 rounded shadow">
<p class="text-text-muted">This is a card component with header.</p> <h3 class="font-semibold">Card title</h3>
</x-card> <p class="text-text-muted">This is a simple card component.</p>
</div>
<h3 class="text-l font-semibold">Without Header</h3>
<x-card>
<p class="text-text-muted">This is a card component without header.</p>
</x-card>
</section> </section>
<!-- TYPOGRAPHY --> <!-- TYPOGRAPHY -->

View File

@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Component;
use Tests\Feature\Component\DataProvider\ButtonTestDataProvider;
use Tests\TestCase;
class ButtonTest extends TestCase
{
public function testGeneratesButtonElement(): void
{
$view = $this->blade('<x-button>Click!</x-button>');
$view->assertSeeHtml('<button ');
$view->assertDontSeeHtml('<a ');
}
public function testButtonCanHaveAttributes(): void
{
$view = $this->blade('<x-button data-attr="123">Click!</x-button>');
$view->assertSeeHtml('data-attr="123"');
}
public function testDefaultVariantIsPrimary(): void
{
$view = $this->blade('<x-button>Click!</x-button>');
$view->assertSeeHtml('bg-primary text-text-inverted');
}
#[\PHPUnit\Framework\Attributes\DataProviderExternal(ButtonTestDataProvider::class, 'getDataForButtonTestWithButtons')]
public function testVariants(string $variant, string $expectedHtml): void
{
$button = sprintf('<x-button variant="%s">Click!</x-button>', $variant);
$view = $this->blade($button);
$view->assertSeeHtml($expectedHtml);
}
}

View File

@@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Component;
use Tests\TestCase;
class CardTest extends TestCase
{
public function testCardWithHeader(): void
{
$view = $this->blade('<x-card header="Test Header">Card Content</x-card>');
$view->assertSeeHtml('<div class="card-header ');
$view->assertSeeHtml('<h3 class="font-semibold">Test Header</h3>');
}
public function testCardWithoutHeader(): void
{
$view = $this->blade('<x-card>Card Content</x-card>');
$view->assertDontSeeHtml('<div class="card-header ');
$view->assertDontSeeHtml('<h3 class="font-semibold">');
}
public function testCardContent(): void
{
$cardContent = '<p class="card-content">This is the card content.</p>';
$view = $this->blade("<x-card>{$cardContent}</x-card>");
$view->assertSeeHtml($cardContent);
}
}

View File

@@ -1,28 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Component\DataProvider;
use App\View\Components\Button;
class ButtonTestDataProvider
{
public static function getDataForButtonTestWithButtons(): array
{
return [
'primary variant' => [
'variant' => Button::VARIANT_PRIMARY,
'expectedHtml' => 'bg-primary text-text-inverted'
],
'secondary variant' => [
'variant' => Button::VARIANT_SECONDARY,
'expectedHtml' => 'bg-secondary text-text'
],
'outline variant' => [
'variant' => Button::VARIANT_OUTLINE,
'expectedHtml' => 'bg-surface border border-primary text-primary'
],
];
}
}