Skip to content

Commit

Permalink
Prevent aware variables from leaking into the attribute bag
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnathonKoster committed Jan 22, 2025
1 parent c17bfe7 commit 1ffd2cc
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 1 deletion.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The main visual difference when working with Dagger components is the use of the
- [Using the aware Directive](#using-the-aware-directive)
- [Using the aware Builder Method](#using-the-aware-builder-method)
- [Accessing Arbitrary Parent Data](#accessing-arbitrary-parent-data)
- [Aware Variables and Attributes](#aware-variables-and-attributes)
- [Property Validation](#property-validation)
- [Shorthand Validation Rules](#shorthand-validation-rules)
- [Compiler Attributes](#compiler-attributes)
Expand Down Expand Up @@ -530,6 +531,26 @@ You may also supply the name of the parent component you'd like to retrieve data
{{ $component->parent('nav')->someValue }}
```

### Aware Variables and Attributes

Aware variables will automatically be added to the component's props list, preventing them from appearing in the attribute bag.

```blade
<!-- /resources/dagger/views/menu/index.blade.php -->
@props(['color'])
<ul>
{{ $slot}}
</ul>
```

```blade
<!-- /resources/dagger/views/menu/item.blade.php -->
@aware(['color']) // "color" will be automatically added to the component's props.
<li {{ $attributes }}>{{ $slot }}</li>
```

## Property Validation

You may use Laravel's [validation](https://laravel.com/docs/validation) features to validate the *props* of your Dagger components. To do this, you may use the `validateProps` builder method to specify the prop and validation rules you'd like to enforce. As an example, the following would ensure that a `title` property was supplied to the `button` component:
Expand Down
7 changes: 6 additions & 1 deletion src/Compiler/TemplateCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,11 @@ protected function compileNodes(array $nodes): string

$compiledComponentTemplate = $this->compileCompilerDirectives($compiledComponentTemplate);

$propNames = array_flip(array_merge(
$componentModel->getPropNames(),
$componentModel->getAwareVariables(),
));

$swapVars = [
'#cachePath#' => $cachePath ?? '',
'#sourcePath#' => Utils::normalizePath($sourcePath),
Expand All @@ -549,7 +554,7 @@ protected function compileNodes(array $nodes): string
'VarSuffix' => $varSuffix,
'#componentName#' => $node->tagName,
'$dependentVars,' => $this->compileBoundScopeVariables(),
'$compiledPropNames' => Str::squish($this->compilePhpArray(array_flip($componentModel->getPropNames()))),
'$compiledPropNames' => Str::squish($this->compilePhpArray($propNames)),
'componentVarName' => $componentModel->getVariableName(),
'$compiledParams' => $compiledComponentParams,
'#inner#' => $this->storeComponentBlock($innerContent),
Expand Down
48 changes: 48 additions & 0 deletions tests/Compiler/AwareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,51 @@
$this->render('<c-aware.default />')
);
});

test('aware removes items from the attribute bag', function () {
$template = <<<'BLADE'
<c-aware_attributes.menu color="purple">
<c-aware_attributes.menu.item>...</c-aware_attributes.menu.item>
<c-aware_attributes.menu.item color="red">...</c-aware_attributes.menu.item>
</c-aware_attributes.menu>
BLADE;

$expected = <<<'EXPECTED'
<div class="bg-purple-200">
<li class="text-purple-800">...</li>
<li class="text-red-800">...</li>
</div>
EXPECTED;

$this->assertSame(
$expected,
$this->render($template)
);
});

test('aware removes items from the attribute bag when supplied with default values', function () {
$template = <<<'BLADE'
<c-aware_attributes.menu color="purple">
<c-aware_attributes.menu.item_default>...</c-aware_attributes.menu.item_default>
<c-aware_attributes.menu.item_default color="red">...</c-aware_attributes.menu.item_default>
</c-aware_attributes.menu>
BLADE;

$expected = <<<'EXPECTED'
<div class="bg-purple-200">
<li class="text-purple-800">...</li>
<li class="text-red-800">...</li>
</div>
EXPECTED;

$this->assertSame(
$expected,
$this->render($template)
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@props(['color'])

<div {{ $attributes->merge(['class' => "bg-{$color}-200"]) }}>
{{ $slot }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@aware(['color'])

<li {{ $attributes->merge(['class' => "text-{$color}-800"]) }}>{{ $slot }}</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@aware(['color' => 'just a default'])

<li {{ $attributes->merge(['class' => "text-{$color}-800"]) }}>{{ $slot }}</li>

0 comments on commit 1ffd2cc

Please sign in to comment.