Skip to content
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

refactor(au-compose): always create host for non custom element composition #1906

Merged
merged 6 commits into from
Feb 20, 2024

Conversation

bigopon
Copy link
Member

@bigopon bigopon commented Feb 18, 2024

📖 Description

Currently the <au-compose/> composition tries to be smart when composing non-custom element:

  • if the <au-compose/> usage is not containerless (via <au-compose containerless/> usage): it'll use its own host element (<au-compose/> element) as the host for the composition
  • if the <au-compose/> usage is a containerless: it'll use its comment markers as the comment markers for the composition

This has a few issues:

This PR refactors the <au-compose/> composing behavior:

  • <au-compose/> itself will always be containerless
  • non custom element host element is always created, but will be replaced by a marker if there's no host element name specified
    • For example, the following template
    <au-compose component.bind="{ a: 1 }" template="<div>hey</div>">
    will result in rendered composed html (ignore the <au-compose/> related own html):
    <!--au-start--><div>hey</div><!--au-end-->
    This is often the desired behavior, but sometimes it's also necessary to have a wrapping element for regardless what the template for the composition is, imagine composing form fields wrapping in a field container:
    Usage:
    <au-compose component.bind="{  name: firstName }" template="<input class='field-control' value.bind='name'>">
    Desirable output:
    <div>
      <input class="field-control">
    </div>
    This can be achieved via tag binding on the <au-compose> element. tag is a new bindable property of the <au-compose> element and is used to specify what element to create in the non custom element composition. For the above example, we can do:
    <au-compose
        component.bind="{  name: firstName }"
        tag="div"
        template="<input class='field-control' value.bind=name>">
    All the extra bindings on the <au-compose/> usage will also be transferred to this host element, which means we can do
    <au-compose tag="div" class="field-container" template="...">
    to have the following composed html:
    <div class="field-container">...

always create new composition host/location for non custom element
@bigopon
Copy link
Member Author

bigopon commented Feb 18, 2024

cc @Sayan751 @fkleuver @ekzobrain

@ekzobrain
Copy link
Contributor

ekzobrain commented Feb 18, 2024

@bigopon give me a couple of days to look at it, please. Need to dive in again.

@bigopon
Copy link
Member Author

bigopon commented Feb 19, 2024

doc change is here https://github.com/aurelia/aurelia/pull/1906/files#diff-8cd6af03635c2537aa4b1ff7d67527c37afa3205f4e823d8c79620fe9cfcea54R62

### Customized host element
When composing a custom element as component, a host element will be created based on the custom element name (e.g `my-input` results in `<my-input>`).
For non custom element composition, a comment will be created as the host, like in the following example:
{% code title="my-component.html" %}
```html
<au-compose template="<input class='input-field' value.bind='value'">
```
{% endcode %}
The rendered HTML will be:
```html
<!--au-start--><input class='input-field'><!--au-end-->
```
the comments `<!--au-start-->` and `<!--au-end-->` are the boundary of the composed html. Though sometimes it's desirable to have a real HTML element as the host. This can be achieved via the `tag` bindable property on the `<au-compose>` element. For example, in the same scenario above, we want to wrap the `<input class='input-field'>` in a `<div>` element with class `form-field`:
{% code title="my-component.html" %}
```html
<au-compose tag='div' class='form-field' template="<input class='input-field' value.bind='value'">
```
{% endcode %}
The rendered HTML will be:
```html
<div class='form-field'><input class='input-field'></div>
```
This behavior can be used to switch between different host elements when necessary, all bindings declared on `<au-compose>` will be transferred to the newly created host element if there is one.

Copy link

codecov bot commented Feb 20, 2024

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (3c74be9) 88.37% compared to head (bd1be5b) 88.38%.
Report is 2 commits behind head on master.

Files Patch % Lines
...e-html/src/resources/custom-elements/au-compose.ts 97.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1906      +/-   ##
==========================================
+ Coverage   88.37%   88.38%   +0.01%     
==========================================
  Files         260      260              
  Lines       22856    22858       +2     
  Branches     5299     5298       -1     
==========================================
+ Hits        20198    20203       +5     
+ Misses       2658     2655       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bigopon
Copy link
Member Author

bigopon commented Feb 20, 2024

@ekzobrain no worries. I'll go ahead first, will accommodate any issues we discover

@bigopon bigopon merged commit 8a28e0a into master Feb 20, 2024
28 checks passed
@bigopon bigopon deleted the refactor/au-compose-tag branch February 20, 2024 06:36
AureliaEffect pushed a commit that referenced this pull request Mar 2, 2024
2.0.0-beta.12 (2024-03-02)

**BREAKING CHANGE:**

* **enhance:** call app tasks with `.enhance` API, return app root instead of controller (#1916) ([4d522b2](4d522b2))
* **au-compose:** always create host for non custom element composition (#1906) ([8a28e0a](8a28e0a))

**Features:**

* **au-compose:** ability to compose string as element name (#1913) ([06aa113](06aa113))

**Bug Fixes:**

* **router:** prevent multiple navigation at the same time (#1895) ([deed11e](deed11e))
* **router:** properly handle false in conditional router hooks (#1900) ([a671463](a671463))
* **di:** dont jit register resources ([8ffde34](8ffde34))
* **di:** new instance resolver (#1909) ([efe208c](efe208c))
* **runtime:** tweak typings of injectable token ([89f76eb](89f76eb))

**Refactorings:**

* **runtime:** delay overriding array prototypes (#1914) ([d8be144](d8be144))
* **router:** use resolve ([89f76eb](89f76eb))
* **runtime:** better type inferrence for injectable token ([89f76eb](89f76eb))
* **di:** simplify container has, cleanup router ([89f76eb](89f76eb))

**Docs:**

* **docs:** add JS examples using resolve for IHttpClient (#1907) ([d57c1f1](d57c1f1))
* **doc:** remove define hook from documentation (#1903) ([f684141](f684141))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants