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, andcreateComposerContext
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
wrapslit-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
- yarn
npm install @micro-lc/composer
yarn add @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.