Skip to content

Commit 19545b4

Browse files
committed
readme tweaks
1 parent 66e8085 commit 19545b4

File tree

3 files changed

+73
-73
lines changed

3 files changed

+73
-73
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ integrating it into [Webpack Encore](https://github.com/symfony/webpack-encore).
3737
- [Twig Component](https://github.com/symfony/ux-twig-component):
3838
A system to build reusable "components" with Twig
3939
- [Live Component](https://github.com/symfony/ux-live-component):
40-
Gives Twig Components a URL and a JavaScript library to automatically re-render via Ajax as your user interacts with it
40+
Gives Twig Components a URL and a JavaScript library to automatically re-render via Ajax as your user interacts with it
4141

4242
## Stimulus Tools around the World
4343

src/LiveComponent/README.md

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ use Symfony\UX\LiveComponent\LiveComponentInterface;
1919
class ProductSearchComponent implements LiveComponentInterface
2020
{
2121
public string $query = '';
22-
22+
2323
private ProductRepository $productRepository;
24-
24+
2525
public function __construct(ProductRepository $productRepository)
2626
{
2727
$this->productRepository = $productRepository;
2828
}
29-
29+
3030
public function getProducts(): array
3131
{
3232
// example method that returns an array of Products
@@ -48,7 +48,7 @@ class ProductSearchComponent implements LiveComponentInterface
4848
value="{{ this.query }}"
4949
data-action="live#update"
5050
>
51-
51+
5252
<ul>
5353
{% for product in this.products %}
5454
<li>{{ product.name }}</li>
@@ -139,7 +139,7 @@ component's interface to `LiveComponentInterface`:
139139
}
140140
```
141141

142-
Then, in the template, make sure there is *one* HTML element around
142+
Then, in the template, make sure there is _one_ HTML element around
143143
your entire component and use the `{{ init_live_component() }}` function
144144
to initialize the Stimulus controller:
145145

@@ -158,7 +158,7 @@ and give the user a new random number:
158158
```twig
159159
<div {{ init_live_component(this) }}>
160160
<strong>{{ this.randomNumber }}</strong>
161-
161+
162162
<button
163163
data-action="live#$render"
164164
>Generate a new number!</button>
@@ -172,7 +172,7 @@ cool, but let's keep going because... things get cooler.
172172

173173
## LiveProps: Stateful Component Properties
174174

175-
Let's make our component more flexible by adding `$min` and `$max` properties:
175+
Let's make our component more flexible by adding `$min` and `$max` properties:
176176

177177
```php
178178
// src/Components/RandomNumberComponent.php
@@ -192,7 +192,7 @@ class RandomNumberComponent implements LiveComponentInterface
192192
{
193193
return rand($this->min, $this->max);
194194
}
195-
195+
196196
// ...
197197
}
198198
```
@@ -208,10 +208,10 @@ But what's up with those `@LiveProp` annotations? A property with
208208
the `@LiveProp` annotation (or `LiveProp` PHP 8 attribute) becomes
209209
a "stateful" property for this component. In other words, each time
210210
we click the "Generate a new number!" button, when the component
211-
re-renders, it will *remember* the original values for the `$min` and
211+
re-renders, it will _remember_ the original values for the `$min` and
212212
`$max` properties and generate a random number between 5 and 500.
213213
If you forgot to add `@LiveProp`, when the component re-rendered,
214-
those two values would *not* be set on the object.
214+
those two values would _not_ be set on the object.
215215

216216
In short: LiveProps are "stateful properties": they will always
217217
be set when rendering. Most properties will be LiveProps, with
@@ -222,9 +222,9 @@ the component is rendered) and
222222

223223
## data-action="live#update": Re-rendering on LiveProp Change
224224

225-
Could we allow the user to *choose* the `$min` and `$max` values
225+
Could we allow the user to _choose_ the `$min` and `$max` values
226226
and automatically re-render the component when they do? Definitely!
227-
And *that* is where live components really shine.
227+
And _that_ is where live components really shine.
228228

229229
Let's add two inputs to our template:
230230

@@ -237,7 +237,7 @@ Let's add two inputs to our template:
237237
data-model="min"
238238
data-action="live#update"
239239
>
240-
240+
241241
<input
242242
type="number"
243243
value="{{ this.max }}"
@@ -252,8 +252,8 @@ Let's add two inputs to our template:
252252

253253
Notice the `data-action="live#update"` on each `input`. When the
254254
user types, live components reads the `data-model` attribute (e.g. `min`)
255-
and re-renders the component using the *new* value for that field! Yes,
256-
as you type in a box, the component automatically updates to reflect the
255+
and re-renders the component using the _new_ value for that field! Yes,
256+
as you type in a box, the component automatically updates to reflect the
257257
new number!
258258

259259
Well, actually, we're missing one step. By default, a `LiveProp` is
@@ -273,7 +273,7 @@ class RandomNumberComponent implements LiveComponentInterface
273273
- /** @LiveProp() */
274274
+ /** @LiveProp(writable=true) */
275275
public int $max = 1000;
276-
276+
277277
// ...
278278
}
279279
```
@@ -292,7 +292,7 @@ don't need to think about it.
292292
### Lazy Updating on "blur" or "change" of a Field
293293

294294
Sometimes, you might want a field to re-render only after the user
295-
has changed an input *and* moved to another field. Browsers dispatch
295+
has changed an input _and_ moved to another field. Browsers dispatch
296296
a `change` event in this situation. To re-render when this event
297297
happens, add it to the `data-action` call:
298298

@@ -330,7 +330,7 @@ is clicked). To do that, use the `updateDefer` method:
330330

331331
Now, as you type, the `max` "model" will be updated in JavaScript, but
332332
it won't, yet, make an Ajax call to re-render the component. Whenever
333-
the next re-render *does* happen, the updated `max` value will be used.
333+
the next re-render _does_ happen, the updated `max` value will be used.
334334

335335
### Using name="" instead of data-model
336336

@@ -347,7 +347,7 @@ code works identically to the previous example:
347347
+ name="min"
348348
data-action="live#update"
349349
>
350-
350+
351351
// ...
352352
</div>
353353
```
@@ -365,7 +365,7 @@ re-rendering or an [action](#actions) is processing. For example:
365365
<span data-loading="show">Loading</span>
366366
```
367367

368-
Or, to *hide* an element while the component is loading:
368+
Or, to _hide_ an element while the component is loading:
369369

370370
```twig
371371
<!-- hide when the component is loading -->
@@ -448,13 +448,13 @@ class RandomNumberComponent implements LiveComponentInterface
448448
$this->min = 0;
449449
$this->max = 1000;
450450
}
451-
451+
452452
// ...
453453
}
454454
```
455455

456456
To call this, add `data-action="live#action"` and `data-action-name`
457-
to an element (e.g. a button or form):
457+
to an element (e.g. a button or form):
458458

459459
```twig
460460
<button
@@ -488,7 +488,7 @@ request will be made!
488488
#### Actions & Services
489489

490490
One really neat thing about component actions is that they are
491-
*real* Symfony controllers. Internally, they are processed
491+
_real_ Symfony controllers. Internally, they are processed
492492
identically to a normal controller method that you would create
493493
with a route.
494494

@@ -514,7 +514,7 @@ class RandomNumberComponent implements LiveComponentInterface
514514
$this->max = 1000;
515515
$logger->debug('The min/max were reset!');
516516
}
517-
517+
518518
// ...
519519
}
520520
```
@@ -556,12 +556,12 @@ class RandomNumberComponent extends AbstractController implements LiveComponentI
556556
public function resetMinMax()
557557
{
558558
// ...
559-
559+
560560
$this->addFlash('success', 'Min/Max have been reset!');
561-
561+
562562
return $this->redirectToRoute('app_random_number');
563563
}
564-
564+
565565
// ...
566566
}
567567
```
@@ -723,7 +723,7 @@ class PostFormComponent extends AbstractController implements LiveComponentInter
723723

724724
The trait forces you to create an `instantiateForm()` method,
725725
which is used when the component is rendered via AJAX. Notice that,
726-
in order to recreate the *same* form, we pass in the `Post` object
726+
in order to recreate the _same_ form, we pass in the `Post` object
727727
and set it as a `LiveProp`.
728728

729729
The template for this component will render the form, which is
@@ -760,23 +760,23 @@ Mostly, this is a pretty boring template! It includes the normal
760760
`init_live_component(this)` and then you render the form however you want.
761761

762762
But the result is incredible! As you finish changing each field, the
763-
component automatically re-renders - including showing any validation
763+
component automatically re-renders - including showing any validation
764764
errors for that field! Amazing!
765765

766766
This is possible thanks to a few interesting pieces:
767767

768-
* `data-action="change->live#update"`: instead of adding `data-action`
769-
to *every* field, you can place this on a parent element. Thanks to
770-
this, as you change or type into fields (i.e. the `input` event),
771-
the model for that field will update and the component will re-render.
768+
- `data-action="change->live#update"`: instead of adding `data-action`
769+
to _every_ field, you can place this on a parent element. Thanks to
770+
this, as you change or type into fields (i.e. the `input` event),
771+
the model for that field will update and the component will re-render.
772772

773-
* The fields in our form do not have a `data-model=""` attribute. But
774-
that's ok! When that is absent, the `name` attribute is used instead.
775-
`ComponentWithFormTrait` has a modifiable `LiveProp` that captures
776-
these and submits the form using them. That's right: each render time
777-
the component re-renders, the form is *submitted* using the values.
778-
However, if a field has not been modified yet by the user, its
779-
validation errors are cleared so that they aren't rendered.
773+
- The fields in our form do not have a `data-model=""` attribute. But
774+
that's ok! When that is absent, the `name` attribute is used instead.
775+
`ComponentWithFormTrait` has a modifiable `LiveProp` that captures
776+
these and submits the form using them. That's right: each render time
777+
the component re-renders, the form is _submitted_ using the values.
778+
However, if a field has not been modified yet by the user, its
779+
validation errors are cleared so that they aren't rendered.
780780

781781
### Form Rendering Problems
782782

@@ -831,13 +831,13 @@ public function buildForm(FormBuilderInterface $builder, array $options)
831831

832832
### Submitting the Form via an action()
833833

834-
Notice that, while we *could* add a `save()` [component action](#actions)
834+
Notice that, while we _could_ add a `save()` [component action](#actions)
835835
that handles the form submit through the component, we've chosen not
836-
to do that so far. The reason is simple: by creating a normal route &
837-
controller that handles the submit, our form continues to work without
836+
to do that so far. The reason is simple: by creating a normal route &
837+
controller that handles the submit, our form continues to work without
838838
JavaScript.
839839

840-
However, you *can* do this if you'd like. In that case, you wouldn't
840+
However, you _can_ do this if you'd like. In that case, you wouldn't
841841
need any form logic in your controller:
842842

843843
```php
@@ -864,7 +864,7 @@ And you wouldn't pass any `form` into the component:
864864
}) }}
865865
```
866866

867-
When you do *not* pass a `form` into a component that uses `ComponentWithFormTrait`,
867+
When you do _not_ pass a `form` into a component that uses `ComponentWithFormTrait`,
868868
the form will be created for you automatically. Let's add the `save()`
869869
action to the component:
870870

@@ -947,7 +947,7 @@ class EditPostComponent implements LiveComponentInterface
947947
}
948948
```
949949

950-
In the template, let's render an HTML form *and* a "preview" area
950+
In the template, let's render an HTML form _and_ a "preview" area
951951
where the user can see, as they type, what the post will look like
952952
(including rendered the `content` through a Markdown filter from the
953953
`twig/markdown-extra` library):
@@ -975,9 +975,9 @@ where the user can see, as they type, what the post will look like
975975

976976
This is pretty straightforward, except for one thing: the `data-model`
977977
attributes aren't targeting properties on the component class itself,
978-
they're targeting *embedded* properties within the `$post` property.
978+
they're targeting _embedded_ properties within the `$post` property.
979979

980-
Out-of-the-box, modifying embedded properties is *not* allowed. However,
980+
Out-of-the-box, modifying embedded properties is _not_ allowed. However,
981981
you can enable it via the `exposed` option:
982982

983983
```diff
@@ -996,12 +996,12 @@ class EditPostComponent implements LiveComponentInterface
996996
```
997997

998998
With this, both the `title` and the `content` properties of the
999-
`$post` property *can* be modified by the user. However, notice
1000-
that the `LiveProp` does *not* have `modifiable=true`. This
999+
`$post` property _can_ be modified by the user. However, notice
1000+
that the `LiveProp` does _not_ have `modifiable=true`. This
10011001
means that while the `title` and `content` properties can be
10021002
changed, the `Post` object itself **cannot** be changed. In other
10031003
words, if the component was originally created with a Post
1004-
object with id=2, a bad user could *not* make a request that
1004+
object with id=2, a bad user could _not_ make a request that
10051005
renders the component with id=3. Your component is protected from
10061006
someone changing to see the form for a different `Post` object,
10071007
unless you added `writable=true` to this property.
@@ -1011,8 +1011,8 @@ unless you added `writable=true` to this property.
10111011
**NOTE** If your component [contains a form](#forms), then validation
10121012
is built-in automatically. Follow those docs for more details.
10131013

1014-
If you're building some sort of form *without* using Symfony's form
1015-
component, you *can* still validate your data.
1014+
If you're building some sort of form _without_ using Symfony's form
1015+
component, you _can_ still validate your data.
10161016

10171017
First use the `ValidatableComponentTrait` and add any constraints you need:
10181018

@@ -1038,7 +1038,7 @@ class EditUserComponent implements LiveComponentInterface
10381038
* @Assert\IsTrue()
10391039
*/
10401040
public bool $agreeToTerms = false;
1041-
1041+
10421042
public static function getComponentName() : string
10431043
{
10441044
return 'edit_user';
@@ -1050,12 +1050,12 @@ Be sure to add the `@Assert\IsValid` to any property where you want
10501050
the object on that property to also be validated.
10511051

10521052
Tahnks to this setup, the component will now be automatically validated
1053-
on each render, but in a smart way: a property will only be validated
1053+
on each render, but in a smart way: a property will only be validated
10541054
once its "model" has been updated on the frontend. The system keeps track
10551055
of which models have been updated (e.g. `data-action="live#update"`)
10561056
and only stores the errors for those fields on re-render.
10571057

1058-
You can also trigger validation of your *entire* object manually
1058+
You can also trigger validation of your _entire_ object manually
10591059
in an action:
10601060

10611061
```php

0 commit comments

Comments
 (0)