Skip to main content
Version: 2.x

Composer API

Any HTML element mounted in micro-lc via layout or mount point, or any composable application is provided with the property composerApi, which provides the same dynamic capability for mounting HTML subtrees micro-lc itself uses under the hood.

The composer API is an object with two methods:

  • premount which flattens polymorphic configurations and injects import maps, and
  • createComposerContext which builds an appender that can be called by assigning a root HTML DOM appending the dynamically configured HTML DOM as subtree of the root.
  • render wraps lit-html render method and injects a context

premount

interface ComposerApi {
// ... rest of the API
premount: (
config: PluginConfiguration,
proxyWindow?: ImportShimContext,
reporter?: (err: unknown) => void
) => Promise<ResolvedConfig>
}

premount allows to reduce the PluginConfiguration type to the following ResolvedConfig type

interface ResolvedConfig {
content: Content
sources: {
importmap?: ImportMap
uris: string[]
}
}

the optional proxyWindow which defaults to the current window must implement the importShim interface, allows to override the importmap features, namely to set a no-op behaviour or select an iframe window. Notice that the interface is equivalent to

interface ImportShimContext {
importShim<D, E extends Record<string, unknown>>(
uri: string, parentUrl?: string
): Promise<{ default: D } & E>
}

After being called, premount ensures all import maps declared are available and uris sources have been fetched and their code run. If there is no sources in the PluginConfiguration, premount is a no-operation. Moreover an error reporter can be injected since premount will not throw on errors.

createComposerContext

interface ComposerApi {
// ... rest of the API
createComposerContext: (
content: Content,
options: ComposerOptions
) => Promise<ComposerContextAppender>
}

Once premount has been run, if needed, createComposerContext provides a callback for appending the DOM configured in content:

type ComposerContextAppender = (container: HTMLElement | DocumentFragment, options?: RenderOptions) => void

where container is the root element that will be used to append the composed subtree and options refer to optional features provided by the lit-html render method.

Finally, options in createComposerContext is the object to interact with when the compiler needs to be instructed to recognize some properties as special context. This feature allows to inject JS context avoiding eval and works according to the composability principles.

render

interface ComposerApi {
// ... rest of the API
render: (
config: ResolvedConfig,
container: HTMLElement,
context: Record<string, unknown> = {}
) => Promise<ComposerContextAppender>
}

Alternatively, if the use case requires to append a ResolvedConfig to a container html element and inject a context of properties, render provides a useful shortcut.

Standalone usage

The composer API can be directly injected in your browser as a module by adding a script import from CDN source or in your code as a dependency.

To add it to your codebase:

npm install @micro-lc/composer

Otherwise, add to your index.html the following script:

  <script type="importmap">
{
"imports": {
"@micro-lc/composer": "https://cdn.jsdelivr.net/npm/@micro-lc/composer@latest/dist/bundle/index.min.js"
}
}
</script>

and then use it in your scripts:

<body>
<div id="root"></div>
<script type="module">
import {render} from '@micro-lc/composer'

(async function () {
const root = document.getElementById('root')

render({content: "Hello 👋"}, root)
})()
</script>
</body>

in case your browser does not support modules we recommend to add es-module-shims.