# Templates The library provides `html` and `svg` functions for defining templates (both have the same interface, but `svg` uses the SVG namespace). They use the tagged template literals syntax to create the DOM and update dynamic parts, leaving static content untouched. > For the best development experience, check whether your code editor supports highlighting HTML in tagged template literals. ## Usage ```typescript html`
${value}
` : Function ``` * **arguments**: * HTML content as a template content * `value` - dynamic values as a property values or element content * **returns**: * an update function, which takes `host` and `target` arguments ```javascript import { html } from 'hybrids'; const update = ({ value }) => html`
${value}
`; ``` ```typescript svg`${value}` : Function ``` * **arguments**: * SVG content as a template content * `value` - dynamic values as a property values or element content * **returns**: * an update function, which takes `host` and `target` arguments ```javascript import { html, svg } from 'hybrids'; const update = ({ radius }) => html` ${ svg`` } `; ``` The `` container element has to be created with the `html` function. Use the `svg` function only for creating the internal structure of the `` element. ## Properties & Attributes ```javascript // el.propertyName = value, el.otherProperty = value html``; ``` An expression as the element's attribute content sets the corresponding existing case-sensitive property, the translated camelCased property, or falls back to the attribute value if the property is not found or is read-only (like `form` or `list` of the `
` ``` ### Special Cases The default action for the `class` and `style` attributes would not work as expected, as they are implemented differently in the DOM. The `class` attribute reflects the `classList` and `className` properties. The `style` property returns a `CSSStyleDeclaration` rather than a simple string value. Because of that, the template engine supports them differently. #### Class The `class` attribute expression adds or removes class names from an element's `classList`. An expression can be a string, an array of strings, or a map of keys with boolean values: ```javascript const name = 'one two'; const array = ['one', 'two']; const map = { one: true, two: false }; html`
`; ``` #### Style The `style` attribute expression sets style properties via the `CSSStyleDeclaration` API. An expression has to be an object with dashed or camelCase keys with values. ```javascript const styles = { backgroundColor: 'red', 'font-face': 'Arial', }; html`
`; ``` However, the preferred way to style elements is using the ` `, }); ``` ## Plugins The template engine's `html` and `svg` functions return an update function, which is later called with proper arguments by the library (when used in the `render` property). If you need more control over the update process, you can use a custom function that internally uses the result of the `html` or `svg` function. ```javascript function myPlugin(fn) { return (host, target) => { // do something when library calls the update function // ... // Call the original update function from compiled template fn(host, target); }; } define({ tag: "my-element", render: () => myPlugin(html`
...
`), }) ``` For simpler syntax, you can use the `.use()` helper method. It can be chained, so a list of plugins will be applied in order. ```typescript html`...`.use(plugin: (fn: ((host, target) => void) => (host, target) => void): Function ``` * **arguments**: * `plugin` - a function, which takes the original update function and returns a new update function * **returns**: * an update function compatible with content expression ```javascript define({ tag: "my-element", render: () => html`
...
`.use(myPlugin), }); ``` ### Transition API The built-in `html.transition` plugin uses the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API). It works best with whole-viewport transitions, like app-style navigation events, but it can be used for any other transition as well. The API must be attached to only one element in the DOM tree, so it is recommended to use it with the root element of the application (which is always attached to the DOM): ```javascript define({ tag: 'my-app', stack: router([Home]), render: ({ stack }) => html`
...
${stack}
... `.use(html.transition), }); ``` !> The transition API will only be triggered when an element that uses `html.transition` updates. In the above example, it will be triggered only when the `stack` property changes. Any change to internal elements of the `stack` will not trigger the transition. The transition API can be customized via CSS properties. DOM elements can have custom view transition names. The [layout engine](./layout-engine.md) supports the `view` rule, which sets it: ```javascript export default define({ tag: 'my-app-home', render: () => html` `, }); ``` ## Limitations The engine tries to support all required features for creating rich HTML templates, but there are a few cases where expressions cannot be used or have some limitations. ### Table Family Elements ``, ``, ``, ``, ``, `` elements with expressions should not have additional text other than whitespace: ##### Breaks template: ```javascript html`${cellOne} ${cellTwo} some text`; ``` ##### Works fine: ```javascript html`${cellOne} ${cellTwo}`; ``` ### Template Element Expressions inside the `
`, `
`, `` and `