Declarations
The APIs on this page are imported from @makoojs/core. inject(), injectEach(), and listen() only create declaration objects; they don't access the DOM, register, or start anything. Declarations are validated and run only after they are passed to core.apply().
inject()
Declares a component: mounts a framework component into an element of the host page.
function inject<TComponent = unknown, TProps = unknown>(
input: MakooComponentInput<TComponent, TProps>
): MakooComponentDeclaration<TComponent, TProps>;import { inject, listen } from '@makoojs/core';
import Toolbar from './Toolbar.vue';
const toolbar = inject({
name: 'toolbar',
injectAt: '#header',
adapter: 'vue',
component: Toolbar,
props: { compact: true },
timeout: 30000,
reinject: true,
listeners: [
listen({ name: 'search-submit', listenAt: '#search', type: 'submit', callback: onSubmit })
]
});MakooComponentInput
| Field | Type | Default | Description |
|---|---|---|---|
name | string | Required | Injection name, unique among the top-level injections of the same Core instance |
injectAt | string | Required | CSS selector of the mount target |
adapter | string | Required | Name of a registered adapter, such as 'vue' or 'react' |
component | TComponent | Required | The framework component to mount |
props | TProps | undefined | Props passed as-is to the root component |
timeout | number | 15000 | Wait budget for each search for the mount target, in milliseconds |
reinject | boolean | false | Whether to search and mount again after the mount target or component container becomes invalid; also determines whether attached listeners can recover locally |
listeners | Array of listen() declarations | [] | Attached listeners, started and stopped together with the component |
Field Constraints
- Attached listener names are unique within the owning component and may match top-level injection names.
- Attached listeners can't set
reinject; they use the component'sreinject.
When an attached listener sets reinject, apply() throws MAKOO_DECLARATION_INVALID; duplicate attached listener names throw MAKOO_INJECTION_NAME_CONFLICT.
Mount Position
Core uses the first element matching injectAt as the mount target, appends a div at its end as the component container, and mounts the component in that container. When the component stops, Core unmounts the component and removes the container, without touching the mount target's original content.
Makoo doesn't copy or freeze props. Vue shallow-copies root props, so for the component to see outside changes, pass a reactive() or ref() as a property of props, for example props: { state }.
injectEach()
Declares an Each Injection: mounts the same framework component on every element matching injectAt, including elements that match later.
function injectEach<TComponent = unknown, TProps = unknown>(
input: MakooComponentEachInput<TComponent, TProps>
): MakooComponentEachDeclaration<TComponent, TProps>;import { injectEach } from '@makoojs/core';
import Badge from './Badge.vue';
const badges = injectEach({
name: 'badges',
injectAt: '.comment .author',
adapter: 'vue',
component: Badge,
props: { compact: true }
});MakooComponentEachInput
| Field | Type | Default | Description |
|---|---|---|---|
name | string | Required | Injection name, unique among the top-level injections of the same Core instance |
injectAt | string | Required | CSS selector; every matching element gets its own Child Injection |
adapter | string | Required | Name of a registered adapter, such as 'vue' or 'react' |
component | TComponent | Required | The framework component to mount on each element |
props | TProps | undefined | Props passed as-is to every mounted component; all of them receive the same object |
injectEach() has no timeout, reinject, or listeners.
Matching and Mounting
- On start, every current match is mounted in document order. While running, elements that start matching later are mounted too, until the Each Injection is stopped or removed.
- There is no wait timeout: when nothing matches, the status stays
collectinginstead of failing. - Each element gets its own component container at its end, exactly like
inject(). An element is mounted at most once per run. - A Child Injection that is stopped, removed, or fails is not remounted on the same element until the Each Injection is stopped and started again. When its element leaves the page, the Child ends with
failed; if that element or a new matching element is inserted later, a new Child is mounted. - A Child Injection's failure doesn't affect the Each Injection or other Children.
To control the Children, see injection() and Each Injection Status.
listen()
Declares a host listener: binds a native event on an element of the host page.
function listen(input: MakooListenerInput): MakooListenerDeclaration;import { listen } from '@makoojs/core';
const escape = listen({
name: 'escape',
listenAt: 'body',
type: 'keydown',
capture: true,
callback(event) {
if (event instanceof KeyboardEvent && event.key === 'Escape') console.log('Escape');
}
});Putting the return value directly into apply() makes it a standalone listener; putting it into inject()'s listeners makes it an attached listener.
MakooListenerInput
| Field | Type | Default | Description |
|---|---|---|---|
name | string | Required | Injection name; attached listeners only need to be unique within the owning component |
listenAt | string | Required | CSS selector of the listener target |
type | string | Required | Event type, such as 'click' |
callback | (this: Element, event: Event) => unknown | Required | Event handler |
capture | boolean | false | Whether to fire in the capture phase |
timeout | number | 15000 | Wait budget for each search for the listener target, in milliseconds |
reinject | boolean | false | Whether to search and bind again after the listener target becomes invalid; only standalone listeners can set it |
Event Handler
- The listener is bound to the first element matching
listenAt.thisis that element, andeventis the native event object. - When the callback throws synchronously or returns a rejected Promise, Core prints a
MAKOO_LISTENER_CALLBACK_FAILEDerror and the listener stays bound. Standalone listeners also write this error tolastError. - The listener target can only be read through
thiswhen the callback is a regularfunction; with arrow functions, useevent.currentTarget.
Declaration Types
type MakooComponentDeclaration<TComponent = unknown, TProps = unknown> = Readonly<
MakooComponentInput<TComponent, TProps> & { kind: 'component' }
>;
type MakooComponentEachDeclaration<TComponent = unknown, TProps = unknown> = Readonly<
MakooComponentEachInput<TComponent, TProps> & { kind: 'component-each' }
>;
type MakooListenerDeclaration = Readonly<MakooListenerInput & { kind: 'listener' }>;MakooInjectionDeclaration
The element type of the array accepted by apply():
type MakooInjectionDeclaration =
| MakooListenerDeclaration
| MakooComponentDeclaration
| MakooComponentEachDeclaration;Declarations are fixed at apply() time; modifying the original object afterwards doesn't affect registered injections. To change selectors, timeouts, or other settings, remove() first and then apply() the new declaration.