MetaFor - v0.3.1
    Preparing search index...

    Type Alias ViewDefinitionParams<C, S>

    Параметры функции рендеринга представления актора.

    В функцию render компонента MetaFor передаётся объект с полезными утилитами и данными для построения UI.

    import { describe, test, expect } from "bun:test"
    import { MetaFor } from "../../metafor"
    import { messagesFixture } from "../../fixture/message"

    describe("инициализация ребенка с переданным контекстом от родителя", async () => {
    document.body.innerHTML = `<metafor-parent-243234></metafor-parent-243234>`

    const { waitForMessages } = messagesFixture({ meta: "child-243232" })

    let childContext: any
    let countChildMount = 0
    MetaFor("child-243232")
    .context((types) => ({
    message: types.string.required("child message"),
    count: types.number.required(1),
    }))
    .states({
    idle: {},
    })
    .core()
    .processes()
    .reactions()
    .view({
    onMount: () => {
    countChildMount++
    },
    render: ({ context, html }) => html`
    <div>
    <p>Сообщение: ${context.message}</p>
    <p>Счетчик: ${context.count}</p>
    </div>
    `,
    })

    MetaFor("parent-243234")
    .context((types) => ({
    parentMessage: types.string.required("message"),
    parentCount: types.number.required(0),
    }))
    .states({
    idle: {},
    })
    .core()
    .processes()
    .reactions((reaction) => [
    [
    ["idle"],
    reaction()
    .filter({
    op: "add",
    })
    .equal(({ patch }) => {
    childContext = patch.value.context
    }),
    ],
    ])
    .view({
    render: ({ context, html }) => html`
    <div>
    <h1>Родитель: ${context.parentMessage}</h1>
    <metafor-child-243232
    context=${{
    message: context.parentMessage,
    count: context.parentCount,
    }}></metafor-child-243232>
    </div>
    `,
    })

    const childMessages = await waitForMessages(400)

    test("в реакции родителя при добавлении ребенка получаем переданный контекст", async () => {
    expect(childContext, "контекст ребенка должен соответствовать переданному от родителя").toEqual({
    message: "message",
    count: 0,
    })
    })
    test("не должно быть сообщения с патчем обновления контекста ребенка", async () => {
    expect(childMessages, "патч обновления контекста ребенка не должен быть").toHaveLength(1)
    expect(childMessages[0]!.patch.op, "патч обновления контекста ребенка должен быть add").toEqual("add")
    })
    test("ребенок должен быть отрендерен 1 раз", () => {
    expect(countChildMount, "ребенок должен быть отрендерен 1 раз").toEqual(1)
    })
    })
    render({ context, update, state, html, ref, repeat, when, map, style }) {
    const inputRef = ref();
    return html`
    <div ${style({ color: state === 'error' ? 'red' : 'black' })}>
    <h2>${context.title}</h2>
    <input ${ref(inputRef)} value=${context.value} @input=${e => update({ value: e.target.value })} />
    <ul>
    ${repeat(context.items, (item, i) => html`<li>${i}: ${item}</li>`)}
    </ul>
    ${when(context.items.length > 0, () => html`<span>Есть элементы</span>`, () => html`<span>Пусто</span>`)}
    <ol>
    ${map(context.items, (item, i) => html`<li>${item}</li>`)}
    </ol>
    </div>
    `;
    }
    type ViewDefinitionParams<C extends ContextSchema, S extends string> = {
        update: Update<C>;
        context: ExtractValues<C>;
        state: S;
        html: typeof html;
        ref: typeof ref;
        repeat: typeof repeat;
        when: typeof when;
        map: typeof map;
        style: typeof styleMap;
    }

    Type Parameters

    Index

    Properties

    update: Update<C>

    Функция для обновления контекста. Вызывается с частичным объектом контекста для изменения состояния.

    update({ value: 42 })
    
    context: ExtractValues<C>

    Текущее состояние контекста. Содержит все поля, определённые в .context(...)

    html`<div>${context.value}</div>`
    
    state: S

    Текущее состояние автомата/актора. Обычно строка, определённая в .states(...)

    html`<span>${state === 'error' ? 'Ошибка' : 'Ок'}</span>`
    
    html: typeof html

    Функция шаблонизации (аналог lit-html). Используется для создания HTML-шаблонов с интерполяцией.

    html`<div>${context.value}</div>`
    
    ref: typeof ref

    Директива для получения ссылки на DOM-элемент. Используется для доступа к элементу после рендера.

    const r = ref();
    html`<input ${ref(r)} />`
    // r.value будет содержать DOM-элемент
    repeat: typeof repeat

    Директива для эффективного рендера списков с ключами. Позволяет оптимально обновлять DOM при изменении массива.

    html`<ul>${repeat(context.items, (item, i) => html`<li>${i}: ${item}</li>`)}</ul>`
    

    Или возвращать напрямую:

    return repeat(context.items, (item, i) => html`<li>${i}: ${item}</li>`)
    
    when: typeof when

    Директива для условного рендера. Позволяет элегантно отображать разные шаблоны в зависимости от условия.

    html`<div>${when(flag, () => html`<span>Да</span>`, () => html`<span>Нет</span>`)}</div>`
    

    Или возвращать напрямую:

    return when(flag, () => html`<span>Да</span>`, () => html`<span>Нет</span>`)
    
    map: typeof map

    Директива для простого отображения массива в элементы. Удобна для простых случаев, когда не нужны ключи.

    html`<ul>${map(items, (item, i) => html`<li>${item}</li>`)}</ul>`
    

    Или возвращать напрямую:

    return map(items, (item, i) => html`<li>${item}</li>`)
    
    style: typeof styleMap

    Директива для применения inline-стилей к элементу. Позволяет динамически задавать стили через объект.

    html`<div ${style({ color: 'red', fontWeight: 600 })}></div>`