Skip to content

[LiveComponent] add ability to have array props #241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2022

Conversation

kbond
Copy link
Member

@kbond kbond commented Jan 21, 2022

Q A
Bug fix? yes
New feature? no
Tickets n/a
License MIT

Discovered a bug when working on #220. You currently can't have LiveProp's that are "arrays". This is because the expose system uses arrays and we weren't strict enough in determining when this system was being used.

@kbond kbond added the Bug Bug Fix label Jan 21, 2022
@@ -28,7 +28,7 @@
final class LiveComponentHydrator
{
private const CHECKSUM_KEY = '_checksum';
private const EXPOSED_PROP_KEY = 'id';
private const EXPOSED_PROP_KEY = '_id';
Copy link
Member Author

@kbond kbond Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't mess up the frontend, does it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so

@@ -28,7 +28,7 @@
final class LiveComponentHydrator
{
private const CHECKSUM_KEY = '_checksum';
private const EXPOSED_PROP_KEY = 'id';
private const EXPOSED_PROP_KEY = '_id';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so

@weaverryan weaverryan force-pushed the bug/live-component-array-prop branch from cf553ac to f71e718 Compare January 25, 2022 14:09
@weaverryan
Copy link
Member

Thanks Kevin!

@weaverryan weaverryan merged commit b7bc7e0 into symfony:2.x Jan 25, 2022
weaverryan added a commit that referenced this pull request Jan 31, 2022
…er (kbond)

This PR was merged into the 2.x branch.

Discussion
----------

[WIP][TwigComponent] add component attribute system/helper

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| Tickets       | n/a
| License       | MIT

A common pattern with other component library's (ie blade components/vue) is to pass html attributes to your component that are set on the component's root node. This proposal adds a way to do this with twig components. Enable on your component by adding the `HasAttributesTrait`. Attributes are any data passed to `component()` that cannot be mounted on the component itself. This extra data is added to a `ComponentAttributes` object that lives as a public property on your component (available as `attributes` in your component's template).

This should all work out-of-the box with live components.

Todo:
- [x] Tests
- [x] Documentation
- [x] #240
- [x] #241
- [x] Merge `init_live_component()` into attributes when available
- [x] Document `PreRender` event.
- [x] Adjust `ComponentAttributes` api (defaults instead of merge)
- [ ] `attributes` always available in normal twig component templates (not sure about this - it would effectively make attributes _native_ but it a lame way)
- [x] replace `init_live_component()` with `attributes` in docs
- [x] Finalize docs (versionadded tags)

## Usage

To use, add the `HasAttributesTrait` to your component:

```php
#[AsTwigComponent('my_component')]
class MyComponent
{
    use HasAttributesTrait;
}
```

Then, in your component's template:

```twig
{# templates/components/my_component.html.twig #}

<div{{ attributes }}>
  My Component!
</div>
```

When rendering the component, you can pass an array of html attributes to add:

```twig
{{ component('my_component', { class: 'foo', style: 'color:red' }) }}

{# renders as: #}
<div class="foo" style="color:red">
  My Component!
</div>
```

### Defaults & Merging

In your component template, you can set defaults that are merged with
passed attributes. The passed attributes override the default with
the exception of *class*. For class, the defaults are prepended:

```twig
{# templates/components/my_component.html.twig #}

<button{{ attributes.defaults({ class: 'bar', type: 'button' }) }}>
  My Component!
</button>

{# render component #}
{{ component('my_component', { style: 'color:red' }) }}
{{ component('my_component', { class: 'foo', type: 'submit' }) }}

{# renders as: #}
<div class="bar" style="color:red">
  My Component!
</div>
<div class="bar foo" type="submit">
  My Component!
</div>
```

### Only

```twig
{# templates/components/my_component.html.twig #}

<div{{ attributes.only('class')) }}>
  My Component!
</div>

{# render component #}
{{ component('my_component', { class: 'foo', style: 'color:red' }) }}

{# renders as: #}
<div class="foo">
  My Component!
</div>
```

### Without

```twig
{# templates/components/my_component.html.twig #}

<div{{ attributes.without('class')) }}>
  My Component!
</div>

{# render component #}
{{ component('my_component', { class: 'foo', style: 'color:red' }) }}

{# renders as: #}
<div style="color:red">
  My Component!
</div>
```

### Live Components

We removed the `init_live_component()` twig function (**BC BREAK**) and replaced with the `attributes` variable which is always available (even if your component doesn't use `HasAttributesTrait`).

To upgrade, replace all calls to `init_live_component()` with `attributes`:

```diff
- <div {{ init_live_component() }}>
+ <div {{ attributes }}>
```

Commits
-------

d638782 [Twig][Live] add html attributes system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Bug Fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants