@gluonjs/core


@gluonjs/core / src / compose

Function: compose()

compose<Props, Result>(component, props): ComponentTemplateTag<Result>

Binds typed functional-component props to an html template body.

The body is passed as children in one ordinary function call. No component instance, host node, lifecycle, context, event system, or renderer is added.

Type Parameters

Props

Props extends object

Result

Result extends TemplateValue

Parameters

component

(props) => Result

props

CompositionProps<Props>

Returns

ComponentTemplateTag<Result>

Example

Pass a native HTML template body as typed children to one ordinary functional-component call without adding a host or renderer:

ts
import {
  compose,
  defineAtom,
  html,
  mergeProps,
  renderScopedSlot,
  type ClassValue,
  type ComponentTemplateTag,
  type ComponentLayer,
  type CompositionProps,
  type FunctionalComponent,
  type MergeableProps,
  type ScopedSlot,
  type StyleValue,
} from '@gluonjs/core';

const classes: ClassValue = ['product-card', { 'is-selected': true }];
const styles: StyleValue = { display: 'grid', gap: 16 };
const defaults = { class: classes, style: styles, role: 'article' } satisfies MergeableProps;
const props = mergeProps(defaults, { class: 'featured', style: { gap: 24 }, id: 'orbit-lamp' });
const actions: ScopedSlot<{ productId: string }> = ({ productId }) => html`<button data-id=${productId}>Add</button>`;
const layer: ComponentLayer = 'atom';
const ProductActions: FunctionalComponent<{ productId: string }> = ({ productId }) =>
  html`<div ...=${props}>${renderScopedSlot(actions, { productId })}</div>`;
interface PanelProps { title: string; children: import('@gluonjs/core').TemplateValue }
const Panel: FunctionalComponent<PanelProps> = ({ title, children }) => html`<section><h2>${title}</h2>${children}</section>`;
const panelProps: CompositionProps<PanelProps> = { title: 'Checkout' };
const panel: ComponentTemplateTag = compose(Panel, panelProps);
const checkout = panel`<p>Delivery</p>`;
const Actions = defineAtom((props: { productId: string }) => html`${ProductActions(props)}`, 'ProductActions');
console.log(layer, checkout, Actions.layer, Actions({ productId: 'orbit-lamp' }));