Skip to content

Commit 66c0430

Browse files
Move towards using attributes
1 parent 5a513d2 commit 66c0430

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+498
-328
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="col-span-12 md:col-span-3 2xl:col-span-{{ $width }}">
2+
{{ $slot }}
3+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="grid grid-cols-{{ $columns }} gap-{{ $gap }}">
2+
{{ $slot }}
3+
</div>

src/Attributes/Element.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace AppKit\UI\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_PROPERTY)]
8+
final class Element
9+
{
10+
public function __construct(public string $elementName)
11+
{
12+
13+
}
14+
}

src/Attributes/ExposedAsState.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace AppKit\UI\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_PARAMETER|Attribute::TARGET_METHOD)]
8+
final class ExposedAsState
9+
{
10+
public function __construct()
11+
{
12+
13+
}
14+
}

src/Attributes/Inheritable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Attribute;
66

77
#[Attribute(Attribute::TARGET_PARAMETER)]
8-
class Inheritable
8+
final class Inheritable
99
{
1010
public function __construct(public array|string $fromComponents)
1111
{

src/Attributes/Slotable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Attribute;
66

77
#[Attribute(Attribute::TARGET_PARAMETER)]
8-
class Slotable
8+
final class Slotable
99
{
1010
public function __construct(public ?string $slotName = null)
1111
{

src/Components/Alert.php

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace AppKit\UI\Components;
44

5+
use AppKit\UI\Attributes\Element;
6+
use AppKit\UI\Attributes\ExposedAsState;
57
use AppKit\UI\Attributes\Slotable;
68
use AppKit\UI\ElementAttributeBag;
79

@@ -12,40 +14,42 @@ class Alert extends BaseComponent
1214
*
1315
* @var ElementAttributeBag
1416
*/
15-
public ElementAttributeBag $titleAttributes;
17+
#[Element('title')]
18+
public ?ElementAttributeBag $titleAttributes = null;
1619

1720
/**
1821
* Attributes to be applied to the error message
1922
*
2023
* @var ElementAttributeBag
2124
*/
22-
public ElementAttributeBag $contentAttributes;
25+
#[Element('content')]
26+
public ?ElementAttributeBag $contentAttributes = null;
2327

2428
/**
2529
* Attributes to be applied to the error message
2630
*
2731
* @var ElementAttributeBag
2832
*/
29-
public ElementAttributeBag $iconAttributes;
33+
#[Element('icon')]
34+
public ?ElementAttributeBag $iconAttributes = null;
3035

3136
/**
32-
* The name of the view that this component renders
37+
* Create an instance of the component
3338
*
34-
* @var string
39+
* @param string|null $icon
40+
* @param string|null $title
41+
* @param string|null $type
3542
*/
36-
protected string $viewName = 'components.alert';
37-
3843
public function __construct(
39-
#[Slotable]
40-
public ?string $title = null,
4144
#[Slotable]
4245
public ?string $icon = null,
46+
47+
#[Slotable]
48+
public ?string $title = null,
49+
50+
#[ExposedAsState]
4351
public ?string $type = 'success',
4452
) {
45-
$this->titleAttributes = $this->registerAttributeBuilderElement('title');
46-
$this->contentAttributes = $this->registerAttributeBuilderElement('content');
47-
$this->iconAttributes = $this->registerAttributeBuilderElement('icon');
48-
49-
$this->exposePropertyAsState('type');
53+
// constructor promotion handles the rest
5054
}
5155
}

src/Components/App.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,9 @@
55
class App extends BaseComponent
66
{
77
/**
8-
* The name of the view that this component renders
9-
*
10-
* @var string
8+
* Create an instance of the component
119
*/
12-
protected string $viewName = 'components.app';
13-
14-
public function __construct(
15-
16-
) {
17-
10+
public function __construct() {
11+
// constructor promotion handles the rest
1812
}
1913
}

src/Components/BaseComponent.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
namespace AppKit\UI\Components;
44

5+
use AppKit\UI\Attributes\Element;
6+
use AppKit\UI\Attributes\ExposedAsState;
57
use AppKit\UI\Attributes\Inheritable;
68
use AppKit\UI\Attributes\Slotable;
79
use AppKit\UI\ComponentBuilder;
810
use AppKit\UI\Components\Concerns\HasComponentBuilder;
11+
use AppKit\UI\Components\Concerns\InteractsWithComponentStack;
912
use AppKit\UI\ElementAttributeBag;
1013
use AppKit\UI\Facades\UI;
1114
use AppKit\UI\Support\Attributes;
1215
use Attribute;
16+
use Closure;
1317
use Illuminate\Support\Collection;
18+
use Illuminate\Support\Str;
1419
use Illuminate\View\Component as BladeComponent;
1520
use Illuminate\View\ComponentAttributeBag;
1621
use ReflectionClass;
@@ -21,6 +26,7 @@
2126
abstract class BaseComponent extends BladeComponent
2227
{
2328
use HasComponentBuilder;
29+
use InteractsWithComponentStack;
2430

2531
/**
2632
* The name of the view that this component renders
@@ -45,8 +51,44 @@ abstract class BaseComponent extends BladeComponent
4551
*/
4652
public function withAttributes(array $attributes)
4753
{
54+
// flag to the service provider that we are starting this component
4855
UI::startComponent($this);
4956

57+
// if we don't have a view name passed in, we try to generate one based on a convention
58+
if (empty($this->viewName)) {
59+
$this->viewName = Str::of(static::class)
60+
->remove('AppKit\UI\Components\\')
61+
->replace('\\', '.')
62+
->kebab()
63+
->replace('.-', '.')
64+
->prepend('components.');
65+
}
66+
67+
// find parameters that are being exposed as a state
68+
Attributes::find(ExposedAsState::class)
69+
->onConstructorParameters()
70+
->ofClass(static::class)
71+
->get()
72+
->keys()
73+
->each(fn ($parameter) => $this->exposePropertyAsState($parameter));
74+
75+
Attributes::find(ExposedAsState::class)
76+
->onMethods()
77+
->ofClass(static::class)
78+
->get()
79+
->keys()
80+
->each(fn ($method) => $this->defineState($method, Closure::fromCallable([$this, $method])));
81+
82+
// find the element attribute bags that we need to register
83+
Attributes::find(Element::class)
84+
->onProperties()
85+
->ofClass(static::class)
86+
->get()
87+
->each(function ($attribute, $property) {
88+
$this->{$property} = $this->registerElement($attribute->elementName);
89+
});
90+
91+
// create a collection of child components
5092
$this->childComponents = new Collection();
5193

5294
// ensure that we have an attribute bag assigned to the component
@@ -247,6 +289,7 @@ public function render()
247289
// if we have inheritable attributes on the component (attributes passed in from another attribute bag)
248290
if (isset($data['inheritedAttributes'])) {
249291
// we merge them in right at the end
292+
dd($this->inheritedAttributes);
250293
$data['attributes'] = $data['attributes']->merge($this->inheritedAttributes);
251294
}
252295

src/Components/Button.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,30 @@
22

33
namespace AppKit\UI\Components;
44

5+
use AppKit\UI\Attributes\ExposedAsState;
6+
57
class Button extends BaseComponent
68
{
79
/**
8-
* The name of the view that this component renders
10+
* Create an instance of the component
911
*
10-
* @var string
12+
* @param string $color
13+
* @param string $size
14+
* @param string $shape
15+
* @param string|null $href
1116
*/
12-
protected string $viewName = 'components.button';
13-
1417
public function __construct(
18+
#[ExposedAsState]
1519
public string $color = 'red',
20+
21+
#[ExposedAsState]
1622
public string $size = 'md',
23+
24+
#[ExposedAsState]
1725
public string $shape = 'rounded',
26+
1827
public ?string $href = null,
1928
) {
20-
$this->exposePropertyAsState('color');
21-
$this->exposePropertyAsState('size');
22-
$this->exposePropertyAsState('shape');
29+
// constructor promotion handles the rest
2330
}
2431
}

0 commit comments

Comments
 (0)