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

Declarative HTML resolver #7037

Open
janechu opened this issue Dec 3, 2024 · 0 comments
Open

Declarative HTML resolver #7037

janechu opened this issue Dec 3, 2024 · 0 comments
Assignees
Labels
area:fast-element Pertains to fast-element feature A new feature

Comments

@janechu
Copy link
Collaborator

janechu commented Dec 3, 2024

Introduction

Due to popular demand for BTR/SSR solutions, as an alternate approach to using the html tagged template literal this issue outlines the use of a declarative syntax template resolver.

Requires completion of #7036

Requirements

Declarative HTML Template Syntax

The resolver would require an async approach to resolving and attaching the template. This will require a few pieces, the first is the declarative HTML syntax. Once this has been declared on the page for the custom element, it will be added to the element's definition. This template syntax is meant to be able to be interpreted both by JavaScript in the browser, as well as by other languages during BTR/SSR, thus for applying values to create HTML from the template, where JavaScript is not applied we will use JSON and simple data structures.

Below will be an example, as you can see, for browser specific behavior we will keep a JavaScript-like syntax such as with the @click event.

Example HTML:

<f-template name="my-custom-element">
  <template>
      <button data-fe_click="x.handleClick()" data-fb_disabled="x.disabled">
          {{x.greeting}}
      </button>
      <input
          data-fp_value="x.value"
      >
      <f-when condition="x.hasFriends"><!--we assume the value passed to the condition is a boolean-->
          <ul>
              <f-repeat items="x.friends"><!--we assume the items is an array, in this case it might be ["brenda", "james"]-->
                  <li>{{x}}</li><!--this now takes the a new context of the individual array item, so this might render as "brenda"-->
              </f-repeat>
          </ul>
      </f-when>
      <f-slotted items="x.items">
          <slot></slot>
      </f-slotted>
  </template>
</f-template>

The reason that all directives are tags is because they should be made optional to allow for lighter bundles. If you don't use <f-when> (for example) you can choose not to include it.

html Tagged template version:

html`
    <template>
        <button @click="${x => x.handleClick()}" ?disabled="${x => x.disabled}">
            ${x => x.greeting}
        </button>
        <input
            :value="${x => x.value}"
        >
        ${when(
            x => x.hasFriends
            html`<ul>
                ${repeat(
                    x => x.friends,
                    html`<li>${x => x}</li>`
                )}
            </ul>`
        )}
        <slot ${slotted('items')}></slot>
    </template>
`;

Example JSON:

{
    "disabled": true,
    "greeting": "Hello World",
    "value": 42,
    "hasFriends": true,
    "friends": ["brenda", "james"]
}

This syntax is a close mirroring of how html template uses directives etc. so as not to confuse current consumers of html tagged template literal. We recognize that there are current efforts to create a standard for declarative HTML, but as they have not passed any meaningful stage at this time we will wait until the platforms proceed with a solution before we consider convergence.

One issue with declarative HTML is that we will not be interpreting any JavaScript, the developers will not be able to do anything like the following: <f-when condition="x.friends.length > 0">. This limitation means that we will only allow a variable that will be assumed to be a boolean.

Anything in the JSON data structure is assumed to be either an @attr or property of the custom element class. Therefore, hasFriends for example could be an observed property or a reflected attribute that is assigned in the constructor.

Declarative HTML Template resolver

The second piece is the interpretation by a resolver to provide the ViewTemplate. This should be located on a different export path, per #7036 compose step example.

HTML Rendering

Fully documented examples with explanations will be provided to ensure processing of a Declarative HTML template is understood and can be resolved. FAST expects certain additions to the HTML for it to be hydratable, that includes comments etc.

Example rendering:

<my-custom-element greeting="Hello world" disabled>
    <template shadowrootmode="open">
        <button disabled>
            <!--fe-b$$start$$0$$QYOGJbAbyI$$fe-b-->Hello world<!--fe-b$$end$$0$$QYOGJbAbyI$$fe-b-->
        </button>
        <input
            value="42"
        >
        <!--fe-b$$start$$0$$QYOGJbAbym$$fe-b-->
        <ul>
            <!--fe-b$$start$$0$$QYOGJbAbyn$$fe-b--><li>First</li><!--fe-b$$end$$0$$QYOGJbAbyn$$fe-b-->
            <!--fe-b$$start$$0$$QYOGJbAbyo$$fe-b--><li>Second</li><!--fe-b$$end$$0$$QYOGJbAbyo$$fe-b-->
        </ul>
        <!--fe-b$$end$$0$$QYOGJbAbym$$fe-b-->
        <slot>items 1</slot>
    </template>
</my-custom-element>
@janechu janechu added area:fast-element Pertains to fast-element feature A new feature labels Dec 3, 2024
@janechu janechu added this to the FAST Element Future milestone Dec 3, 2024
@janechu janechu self-assigned this Dec 3, 2024
@janechu janechu moved this from Triage to Todo in FAST Architecture Roadmap Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:fast-element Pertains to fast-element feature A new feature
Projects
Status: Todo
Development

No branches or pull requests

1 participant