Add admin scroll controls and site interaction fixes
This commit is contained in:
parent
25e5afedf2
commit
fb1531f7c5
|
|
@ -923,6 +923,72 @@ body[data-file-picker-active="true"] .editor {
|
|||
align-content: start;
|
||||
}
|
||||
|
||||
.range-field {
|
||||
gap: 0.46rem;
|
||||
}
|
||||
|
||||
.range-control {
|
||||
display: flex;
|
||||
min-height: 2.72rem;
|
||||
align-items: center;
|
||||
gap: 0.85rem;
|
||||
border-radius: var(--launcher-radius-control);
|
||||
background: var(--field);
|
||||
padding: 0 0.86rem;
|
||||
}
|
||||
|
||||
.range-control input[type="range"] {
|
||||
height: 1.5rem;
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
appearance: none;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
accent-color: #f7f8f4;
|
||||
}
|
||||
|
||||
.range-control input[type="range"]::-webkit-slider-runnable-track {
|
||||
height: 0.32rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.range-control input[type="range"]::-webkit-slider-thumb {
|
||||
width: 1.08rem;
|
||||
height: 1.08rem;
|
||||
margin-top: -0.38rem;
|
||||
appearance: none;
|
||||
border-radius: 50%;
|
||||
background: #f7f8f4;
|
||||
box-shadow: 0 0 0 0.28rem rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.range-control input[type="range"]::-moz-range-track {
|
||||
height: 0.32rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.range-control input[type="range"]::-moz-range-thumb {
|
||||
width: 1.08rem;
|
||||
height: 1.08rem;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
background: #f7f8f4;
|
||||
box-shadow: 0 0 0 0.28rem rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.range-value {
|
||||
min-width: 3.4rem;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 850;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.boolean-field input,
|
||||
.group-head-toggle input {
|
||||
width: 2.42rem;
|
||||
|
|
|
|||
|
|
@ -202,9 +202,12 @@ const GROUP_COPY = {
|
|||
"Видео-окно": "Окно демо-видео и подключенный медиа-файл.",
|
||||
Пункты: "Текстовые пункты внутри секции.",
|
||||
Слайдер: "Видео-превью и подписи карточек внутри горизонтального слайдера.",
|
||||
Скролл: "Скорость локальной прокрутки внутри блока: меньше значение — спокойнее шаг, больше — быстрее.",
|
||||
"Один клик": "Подблок про быстрое добавление и настройку компонентов.",
|
||||
MCP: "Подблок про MCP-сервер и контекст Webflow.",
|
||||
FAQ: "Список вопросов и тексты ответов в mail-интерфейсе.",
|
||||
"Окно FAQ": "Название окна FAQ и служебные подписи mail-интерфейса.",
|
||||
Отправитель: "Профиль отправителя в FAQ: аватар, имя и подписи письма.",
|
||||
FAQ: "Вопросы и ответы mail-интерфейса. Каждый пункт можно добавить, удалить и переставить.",
|
||||
CTA: "Финальный призыв к действию: заголовок, пояснение, кнопка и ссылка.",
|
||||
Тарифы: "Верхняя часть тарифной таблицы: заголовки, планы, цены, кнопки и примечания.",
|
||||
"Строки тарифов": "Повторяемые строки тарифной таблицы и значения по каждому плану.",
|
||||
|
|
@ -324,6 +327,7 @@ function inferFieldGroup(path) {
|
|||
if (path === "content.legalHtml") return "Юридический блок";
|
||||
if (path === "content.windowTitle" || path === "content.videoSrc") return "Видео-окно";
|
||||
if (path.startsWith("content.features.")) return "Пункты";
|
||||
if (path.startsWith("content.scroll.")) return "Скролл";
|
||||
if (path.startsWith("content.sliderItems.")) return "Слайдер";
|
||||
if (path.startsWith("content.oneClick.")) return "Один клик";
|
||||
if (path.startsWith("content.mcp.")) return "MCP";
|
||||
|
|
@ -1393,8 +1397,19 @@ function prepareCollectionItemForInsert(items, item) {
|
|||
return nextItem;
|
||||
}
|
||||
|
||||
function fieldInputValue(input) {
|
||||
if (input.type === "checkbox") return input.checked;
|
||||
|
||||
if (input.dataset.valueType === "number" || input.type === "range" || input.type === "number") {
|
||||
const value = Number.parseFloat(input.value);
|
||||
return Number.isFinite(value) ? value : 0;
|
||||
}
|
||||
|
||||
return input.value;
|
||||
}
|
||||
|
||||
function syncFieldValue(block, path, input) {
|
||||
setByPath(block, path, input.type === "checkbox" ? input.checked : input.value);
|
||||
setByPath(block, path, fieldInputValue(input));
|
||||
el.json.value = JSON.stringify(block, null, 2);
|
||||
markDirty();
|
||||
}
|
||||
|
|
@ -1431,6 +1446,60 @@ function renderBooleanField({ block, editableField, grid }) {
|
|||
grid.append(label);
|
||||
}
|
||||
|
||||
function formatRangeValue(value, editableField) {
|
||||
const step = Number.parseFloat(editableField.step ?? 1);
|
||||
const precision = Number.isFinite(step) && step > 0 && step < 1 ? String(step).split(".")[1]?.length || 0 : 0;
|
||||
return `${Number(value).toFixed(precision)}${editableField.suffix || ""}`;
|
||||
}
|
||||
|
||||
function renderRangeField({ block, editableField, grid }) {
|
||||
const label = document.createElement("label");
|
||||
const labelRow = document.createElement("span");
|
||||
const labelText = document.createElement("span");
|
||||
const kind = document.createElement("span");
|
||||
const path = document.createElement("span");
|
||||
const control = document.createElement("span");
|
||||
const input = document.createElement("input");
|
||||
const output = document.createElement("span");
|
||||
const min = Number.parseFloat(editableField.min ?? 0);
|
||||
const max = Number.parseFloat(editableField.max ?? 1);
|
||||
const step = Number.parseFloat(editableField.step ?? 0.01);
|
||||
const rawValue = Number.parseFloat(getByPath(block, editableField.path));
|
||||
const value = Number.isFinite(rawValue) ? rawValue : min;
|
||||
|
||||
label.className = "field-control range-field wide";
|
||||
labelRow.className = "field-label-row";
|
||||
labelText.className = "field-label-text";
|
||||
labelText.textContent = editableField.label || editableField.path;
|
||||
kind.className = "field-kind";
|
||||
kind.textContent = editableField.kind || "range";
|
||||
path.className = "field-path";
|
||||
path.textContent = editableField.path;
|
||||
control.className = "range-control";
|
||||
output.className = "range-value";
|
||||
labelRow.append(labelText, kind);
|
||||
|
||||
input.dataset.path = editableField.path;
|
||||
input.dataset.valueType = "number";
|
||||
input.type = "range";
|
||||
input.min = Number.isFinite(min) ? String(min) : "0";
|
||||
input.max = Number.isFinite(max) ? String(max) : "1";
|
||||
input.step = Number.isFinite(step) ? String(step) : "0.01";
|
||||
input.value = String(value);
|
||||
output.textContent = formatRangeValue(value, editableField);
|
||||
|
||||
input.addEventListener("input", () => {
|
||||
const active = activeBlock();
|
||||
if (!active) return;
|
||||
output.textContent = formatRangeValue(input.value, editableField);
|
||||
syncFieldValue(active, editableField.path, input);
|
||||
});
|
||||
|
||||
control.append(input, output);
|
||||
label.append(labelRow, control, path);
|
||||
grid.append(label);
|
||||
}
|
||||
|
||||
function renderHeaderBooleanToggle({ block, editableField, head }) {
|
||||
const label = document.createElement("label");
|
||||
const input = document.createElement("input");
|
||||
|
|
@ -1458,6 +1527,11 @@ function renderCollectionScalarField({ block, field, grid }) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (field.kind === "range") {
|
||||
renderRangeField({ block, editableField: field, grid });
|
||||
return;
|
||||
}
|
||||
|
||||
const label = document.createElement("label");
|
||||
const labelRow = document.createElement("span");
|
||||
const labelText = document.createElement("span");
|
||||
|
|
@ -1723,6 +1797,11 @@ function renderContentFields(block) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (editableField.kind === "range") {
|
||||
renderRangeField({ block, editableField, grid });
|
||||
continue;
|
||||
}
|
||||
|
||||
const label = document.createElement("label");
|
||||
const labelRow = document.createElement("span");
|
||||
const labelText = document.createElement("span");
|
||||
|
|
@ -1770,7 +1849,7 @@ function syncContentFields() {
|
|||
if (!block) return;
|
||||
|
||||
for (const input of el.contentFields.querySelectorAll("[data-path]")) {
|
||||
setByPath(block, input.dataset.path, input.type === "checkbox" ? input.checked : input.value);
|
||||
setByPath(block, input.dataset.path, fieldInputValue(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,240 @@
|
|||
(() => {
|
||||
const BOUND_FLAG = "__nodedcWheelOverrideBound";
|
||||
const GLOBAL_SLIDER_BOUND_FLAG = "__nodedcGlobalSliderWheelOverrideBound";
|
||||
const SYNTHETIC_WHEEL_FLAG = "__nodedcSyntheticWheel";
|
||||
const SLIDER_WHEEL_MULTIPLIER = 3;
|
||||
const SLIDER_BASE_COOLDOWN = 220;
|
||||
const MAIL_BASE_COOLDOWN = 280;
|
||||
const MIN_SCROLL_SPEED = 0.2;
|
||||
const MAX_SCROLL_SPEED = 2;
|
||||
const DEFAULT_SCROLL_SPEED = 0.55;
|
||||
|
||||
function isDesktopPointer() {
|
||||
return window.matchMedia?.("(pointer: fine)").matches ?? true;
|
||||
}
|
||||
|
||||
function shouldIgnoreWheel(event) {
|
||||
return event.ctrlKey || !isDesktopPointer();
|
||||
}
|
||||
|
||||
function createSyntheticWheel(event, deltaX, deltaY) {
|
||||
if (typeof WheelEvent !== "function") return null;
|
||||
|
||||
const syntheticEvent = new WheelEvent("wheel", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
view: window,
|
||||
deltaX,
|
||||
deltaY,
|
||||
deltaZ: event.deltaZ || 0,
|
||||
deltaMode: event.deltaMode,
|
||||
altKey: event.altKey,
|
||||
metaKey: event.metaKey,
|
||||
shiftKey: event.shiftKey,
|
||||
});
|
||||
|
||||
Object.defineProperty(syntheticEvent, SYNTHETIC_WHEEL_FLAG, { value: true });
|
||||
return syntheticEvent;
|
||||
}
|
||||
|
||||
function createSyntheticHorizontalWheel(event) {
|
||||
return createSyntheticWheel(event, event.deltaY * SLIDER_WHEEL_MULTIPLIER, 0);
|
||||
}
|
||||
|
||||
function getPrimaryWheelDelta(event) {
|
||||
return Math.abs(event.deltaX) > Math.abs(event.deltaY) ? event.deltaX : event.deltaY;
|
||||
}
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
}
|
||||
|
||||
function getScrollSpeed(surface) {
|
||||
const rawValue = surface?.dataset?.scrollSpeed ?? surface?.closest?.("[data-scroll-speed]")?.dataset?.scrollSpeed;
|
||||
const value = Number.parseFloat(rawValue);
|
||||
|
||||
if (!Number.isFinite(value)) return DEFAULT_SCROLL_SPEED;
|
||||
return clamp(value, MIN_SCROLL_SPEED, MAX_SCROLL_SPEED);
|
||||
}
|
||||
|
||||
function getStepCooldown(baseCooldown, surface) {
|
||||
return Math.round(baseCooldown / getScrollSpeed(surface));
|
||||
}
|
||||
|
||||
function dispatchPointerStep(item) {
|
||||
if (typeof PointerEvent !== "function") return false;
|
||||
|
||||
const rect = item.getBoundingClientRect();
|
||||
const eventInit = {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: rect.left + rect.width / 2,
|
||||
clientY: rect.top + rect.height / 2,
|
||||
pointerId: 1,
|
||||
pointerType: "mouse",
|
||||
isPrimary: true,
|
||||
};
|
||||
|
||||
item.dispatchEvent(new PointerEvent("pointerdown", eventInit));
|
||||
document.dispatchEvent(new PointerEvent("pointerup", eventInit));
|
||||
return true;
|
||||
}
|
||||
|
||||
function stepMailList(surface, event) {
|
||||
const now = Date.now();
|
||||
const lastStep = Number(surface.__nodedcMailWheelLastStep || 0);
|
||||
if (now - lastStep < getStepCooldown(MAIL_BASE_COOLDOWN, surface)) return;
|
||||
|
||||
const items = Array.from(surface.children);
|
||||
if (!items.length) return;
|
||||
|
||||
const currentIndex = Math.max(
|
||||
0,
|
||||
items.findIndex((item) => item.classList.contains("current")),
|
||||
);
|
||||
const direction = event.deltaY > 0 ? 1 : -1;
|
||||
const nextIndex = Math.max(0, Math.min(items.length - 1, currentIndex + direction));
|
||||
|
||||
if (nextIndex === currentIndex) return;
|
||||
|
||||
if (dispatchPointerStep(items[nextIndex])) {
|
||||
surface.__nodedcMailWheelLastStep = now;
|
||||
}
|
||||
}
|
||||
|
||||
function stepSlider(surface, event) {
|
||||
const delta = getPrimaryWheelDelta(event);
|
||||
if (Math.abs(delta) < 1) return;
|
||||
|
||||
const now = Date.now();
|
||||
const lastStep = Number(surface.__nodedcSliderWheelLastStep || 0);
|
||||
if (now - lastStep < getStepCooldown(SLIDER_BASE_COOLDOWN, surface)) return;
|
||||
|
||||
const slider = surface.__nodedcSlider;
|
||||
if (slider && typeof slider.goToNext === "function" && typeof slider.goToPrev === "function") {
|
||||
if (delta > 0) slider.goToNext();
|
||||
else slider.goToPrev();
|
||||
|
||||
surface.__nodedcSliderWheelLastStep = now;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(event.deltaY) >= Math.abs(event.deltaX)) {
|
||||
const syntheticEvent = createSyntheticHorizontalWheel(event);
|
||||
if (syntheticEvent) {
|
||||
surface.dispatchEvent(syntheticEvent);
|
||||
surface.__nodedcSliderWheelLastStep = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSliderAtPoint(event) {
|
||||
if (!Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) return null;
|
||||
|
||||
return Array.from(document.querySelectorAll('[data-module="slider"]')).find((surface) => {
|
||||
const rect = surface.getBoundingClientRect();
|
||||
const left = Math.max(rect.left, 0);
|
||||
const right = Math.min(rect.right, window.innerWidth);
|
||||
|
||||
return (
|
||||
event.clientX >= left &&
|
||||
event.clientX <= right &&
|
||||
event.clientY >= rect.top &&
|
||||
event.clientY <= rect.bottom
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function bindGlobalSliderWheel() {
|
||||
if (document[GLOBAL_SLIDER_BOUND_FLAG]) return;
|
||||
document[GLOBAL_SLIDER_BOUND_FLAG] = true;
|
||||
|
||||
document.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (shouldIgnoreWheel(event) || event[SYNTHETIC_WHEEL_FLAG]) return;
|
||||
if (event.target?.closest?.('[data-module="mail-list"]')) return;
|
||||
|
||||
const slider = findSliderAtPoint(event);
|
||||
if (!slider) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
stepSlider(slider, event);
|
||||
},
|
||||
{ capture: true, passive: false },
|
||||
);
|
||||
}
|
||||
|
||||
function bindSliderWheel(surface) {
|
||||
if (!surface || surface[BOUND_FLAG]) return;
|
||||
|
||||
surface[BOUND_FLAG] = true;
|
||||
|
||||
surface.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (shouldIgnoreWheel(event) || event[SYNTHETIC_WHEEL_FLAG]) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
stepSlider(surface, event);
|
||||
},
|
||||
{ capture: true, passive: false },
|
||||
);
|
||||
|
||||
surface.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (shouldIgnoreWheel(event)) return;
|
||||
event.stopPropagation();
|
||||
},
|
||||
{ passive: false },
|
||||
);
|
||||
}
|
||||
|
||||
function bindMailListWheel(surface) {
|
||||
if (!surface || surface[BOUND_FLAG]) return;
|
||||
|
||||
surface[BOUND_FLAG] = true;
|
||||
|
||||
surface.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (shouldIgnoreWheel(event)) return;
|
||||
event.preventDefault();
|
||||
|
||||
if (Math.abs(event.deltaY) >= Math.abs(event.deltaX)) {
|
||||
stepMailList(surface, event);
|
||||
}
|
||||
},
|
||||
{ capture: true, passive: false },
|
||||
);
|
||||
|
||||
surface.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (shouldIgnoreWheel(event)) return;
|
||||
event.stopPropagation();
|
||||
},
|
||||
{ passive: false },
|
||||
);
|
||||
}
|
||||
|
||||
function bindInteractiveScroll() {
|
||||
bindGlobalSliderWheel();
|
||||
document.querySelectorAll('[data-module="slider"]').forEach(bindSliderWheel);
|
||||
document.querySelectorAll('[data-module="mail-list"]').forEach(bindMailListWheel);
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", bindInteractiveScroll, { once: true });
|
||||
} else {
|
||||
bindInteractiveScroll();
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
bindInteractiveScroll();
|
||||
window.setTimeout(bindInteractiveScroll, 500);
|
||||
});
|
||||
})();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -519,9 +519,23 @@
|
|||
"bodyHtml": "Используйте <span class=\"darker-70\">несколько агентов параллельно</span> чтобы добавлять кастомный код, анимации и функциональность."
|
||||
}
|
||||
]
|
||||
},
|
||||
"scroll": {
|
||||
"speed": 0.55
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -816,9 +830,23 @@
|
|||
"videoSrc": "./assets/media/publish-flow.mp4",
|
||||
"title": "Публикация"
|
||||
}
|
||||
]
|
||||
],
|
||||
"scroll": {
|
||||
"speed": 0.55
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -1020,9 +1048,30 @@
|
|||
"question": "Это работает с MCP?",
|
||||
"answerHtml": "<p>Система изначально рассчитана на работу с Webflow MCP. </p><p>Подключите проект и авторизацию, чтобы ИИ-агенты получили доступ к Webflow-сборке. Подключение приложения в Webflow Designer даёт агентам доступ к контенту, элементам, стилям и CSS, а кастомный код получает полный контекст проекта.</p>"
|
||||
}
|
||||
]
|
||||
],
|
||||
"sender": {
|
||||
"avatarSrc": "./assets/webflow/images/69d2db06ed4081cf9bdacdc4_federic0.avif",
|
||||
"avatarAlt": "Аватар NODE.DC",
|
||||
"name": "NODE.DC",
|
||||
"replyLabel": "Ответить",
|
||||
"sentLabel": "Отправлено с iPhone"
|
||||
},
|
||||
"scroll": {
|
||||
"speed": 0.55
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -1070,158 +1119,70 @@
|
|||
"label": "Окно: название",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Видео-окно"
|
||||
"group": "Окно FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.0.question",
|
||||
"label": "FAQ 1: вопрос",
|
||||
"path": "content.sender.avatarSrc",
|
||||
"label": "Отправитель: аватар",
|
||||
"kind": "media",
|
||||
"renderAs": "attr",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.avatarAlt",
|
||||
"label": "Отправитель: alt аватара",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.0.answerHtml",
|
||||
"label": "FAQ 1: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"path": "content.sender.name",
|
||||
"label": "Отправитель: имя",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.replyLabel",
|
||||
"label": "Отправитель: подпись ответа",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.sentLabel",
|
||||
"label": "Отправитель: нижняя подпись",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.faq",
|
||||
"label": "Вопросы и ответы",
|
||||
"kind": "collection",
|
||||
"renderAs": "collection",
|
||||
"group": "FAQ",
|
||||
"itemTemplate": {
|
||||
"question": "Новый вопрос",
|
||||
"answerHtml": "<p>Новый ответ.</p>"
|
||||
},
|
||||
"itemFields": [
|
||||
{
|
||||
"path": "question",
|
||||
"label": "Вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.1.question",
|
||||
"label": "FAQ 2: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.1.answerHtml",
|
||||
"label": "FAQ 2: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.2.question",
|
||||
"label": "FAQ 3: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.2.answerHtml",
|
||||
"label": "FAQ 3: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.3.question",
|
||||
"label": "FAQ 4: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.3.answerHtml",
|
||||
"label": "FAQ 4: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.4.question",
|
||||
"label": "FAQ 5: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.4.answerHtml",
|
||||
"label": "FAQ 5: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.5.question",
|
||||
"label": "FAQ 6: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.5.answerHtml",
|
||||
"label": "FAQ 6: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.6.question",
|
||||
"label": "FAQ 7: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.6.answerHtml",
|
||||
"label": "FAQ 7: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.7.question",
|
||||
"label": "FAQ 8: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.7.answerHtml",
|
||||
"label": "FAQ 8: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.8.question",
|
||||
"label": "FAQ 9: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.8.answerHtml",
|
||||
"label": "FAQ 9: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.9.question",
|
||||
"label": "FAQ 10: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.9.answerHtml",
|
||||
"label": "FAQ 10: ответ",
|
||||
"path": "answerHtml",
|
||||
"label": "Ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
|
|
@ -1310,14 +1271,14 @@
|
|||
"key": "cViz:pricingTable:pricing-table.html",
|
||||
"regionId": "cViz",
|
||||
"regionLabel": "Секции",
|
||||
"title": "Тарифная таблица",
|
||||
"title": "Тарифы: интро и таблица",
|
||||
"description": "pricing-table.html",
|
||||
"block": {
|
||||
"region": "cViz",
|
||||
"id": "pricing-table",
|
||||
"type": "pricingTable",
|
||||
"template": "pricing-table.html",
|
||||
"adminLabel": "Тарифная таблица",
|
||||
"adminLabel": "Тарифы: интро и таблица",
|
||||
"anchor": "pricing-wrap",
|
||||
"content": {
|
||||
"pricing": {
|
||||
|
|
@ -1978,16 +1939,16 @@
|
|||
"key": "cViz:pricingIntro:pricing-intro.html",
|
||||
"regionId": "cViz",
|
||||
"regionLabel": "Секции",
|
||||
"title": "Интро тарифов",
|
||||
"title": "Интро тарифов (устаревший дубль)",
|
||||
"description": "pricing-intro.html",
|
||||
"block": {
|
||||
"region": "cViz",
|
||||
"id": "pricing-intro",
|
||||
"type": "pricingIntro",
|
||||
"template": "pricing-intro.html",
|
||||
"adminLabel": "Интро тарифов",
|
||||
"adminLabel": "Интро тарифов (устаревший дубль)",
|
||||
"anchor": "waitlist",
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"content": {
|
||||
"eyebrow": "Тарифы",
|
||||
"heading": {
|
||||
|
|
|
|||
|
|
@ -349,35 +349,35 @@
|
|||
"anchor": "hero",
|
||||
"content": {
|
||||
"heading": {
|
||||
"muted": "Ваш Webflow ",
|
||||
"main": "ИИ-инструменты"
|
||||
"muted": "Платформа",
|
||||
"main": " для цифровых контуров предприятия "
|
||||
},
|
||||
"introHtml": "Несколько агентов для проекта Webflow: от <span class=\"darker-70\">Designer</span> до <span class=\"darker-70\">кастомного кода.</span>",
|
||||
"introHtml": "<span class=\"darker-70\">Hub, Engine, Ops</span> и прикладные модули в единой экосистеме управления, разработки и\nисполнения. ",
|
||||
"cards": [
|
||||
{
|
||||
"muted": "Полный",
|
||||
"main": "агентный контроль",
|
||||
"bodyHtml": "Интеграция с <span class=\"darker-70\">Webflow MCP,</span> мультиагентный режим позволяет работать с <span class=\"darker-70\">несколькими экземплярами</span> параллельно."
|
||||
"bodyHtml": "<span class=\"darker-70\">Единый агентный слой</span> с доступом к задачам, кодовой базе, данным, моделям и связанным сервисам."
|
||||
},
|
||||
{
|
||||
"muted": "Компонентная",
|
||||
"main": "библиотека",
|
||||
"bodyHtml": "Собирайте с учетом <span class=\"darker-70\">ИИ-агентов</span> разные компонентные заготовки дают основу, а стиль и сложную функциональность можно дорабатывать промптами."
|
||||
"muted": "Модульная ",
|
||||
"main": "архитектура",
|
||||
"bodyHtml": "Подключаемые <span class=\"darker-70\">приложения, роли, контуры доступа, рабочие пространства и специализированные инструменты.</span> "
|
||||
},
|
||||
{
|
||||
"muted": "Деплой ",
|
||||
"main": "пайплайн",
|
||||
"bodyHtml": "<span class=\"darker-70\">Деплой в один клик,</span> непрерывный пайплайн, мгновенный откат и быстрая <span class=\"darker-70\">доставка через CDN.</span>"
|
||||
"muted": "Разработка ",
|
||||
"main": "и запуск",
|
||||
"bodyHtml": "Сборка <span class=\"darker-70\">workflow, интерфейсов и рабочих контуров</span> с передачей результатов в <span class=\"darker-70\">операционный слой.</span>"
|
||||
}
|
||||
],
|
||||
"form": {
|
||||
"messagePlaceholder": "Сообщение (необязательно)",
|
||||
"namePlaceholder": "Ваше имя*",
|
||||
"emailPlaceholder": "Email для регистрации*",
|
||||
"submitLabel": "Встать в лист ожидания",
|
||||
"submitLabel": "Подать заявку",
|
||||
"successHeading": "Заявка принята. Спасибо.",
|
||||
"successTextHtml": "Мы скоро свяжемся. <br/>",
|
||||
"betaCtaLabel": "Подать заявку в бету?",
|
||||
"betaCtaLabel": "Подать заявку?",
|
||||
"founderIntroHtml": "Или оформить ранний Founder-доступ<br/>",
|
||||
"founderCtaHtml": "Оформить Founder-доступ <span class=\"darker-70\">350€</span>",
|
||||
"spotsLabel": "До 200 мест",
|
||||
|
|
@ -387,13 +387,13 @@
|
|||
"legalHtml": "<a href=\"https://docs.google.com/document/d/1vME2w8ZB88HoH-JyvkkiL7exrcMfWhkERfFRlnIeZFA/edit?usp=sharing\" target=\"_blank\">Политика конфиденциальности</a> • <a href=\"https://docs.google.com/document/d/1vME2w8ZB88HoH-JyvkkiL7exrcMfWhkERfFRlnIeZFA/edit?usp=sharing\" target=\"_blank\">Политика cookie</a><br/>© — Все права защищены<br/>2026",
|
||||
"accessCard": {
|
||||
"enabled": true,
|
||||
"iconSrc": "./assets/webflow/images/69ad964d951f9d17cc5a919e_logo-app.svg",
|
||||
"iconSrc": "./assets/uploads/images/hero-waitlist/dclogo_white_alpha-mquue8ar.png",
|
||||
"iconAlt": "Иконка NODE.DC",
|
||||
"wordmarkSrc": "./assets/webflow/images/69ad96a28b06b7552a339137_logtype.svg?v=node-dc",
|
||||
"wordmarkAlt": "Логотип NODE.DC",
|
||||
"release": "Бета-релиз: июль 2026",
|
||||
"heading": "Ранний доступ",
|
||||
"description": "Кастомный код, MCP и ИИ-агенты для Webflow в одном рабочем контуре."
|
||||
"release": "Selfhost платформа ",
|
||||
"heading": "Запросить DEMO",
|
||||
"description": "NODE.DC - платформа для задач, процессов, данных, агентов и инженерных модулей."
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
|
|
@ -847,9 +847,23 @@
|
|||
"bodyHtml": "Используйте <span class=\"darker-70\">несколько агентов параллельно</span> чтобы добавлять кастомный код, анимации и функциональность."
|
||||
}
|
||||
]
|
||||
},
|
||||
"scroll": {
|
||||
"speed": 0.2
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -1137,9 +1151,23 @@
|
|||
"videoSrc": "./assets/media/publish-flow.mp4",
|
||||
"title": "Публикация"
|
||||
}
|
||||
]
|
||||
],
|
||||
"scroll": {
|
||||
"speed": 0.55
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -1334,9 +1362,30 @@
|
|||
"question": "Это работает с MCP?",
|
||||
"answerHtml": "<p>Система изначально рассчитана на работу с Webflow MCP. </p><p>Подключите проект и авторизацию, чтобы ИИ-агенты получили доступ к Webflow-сборке. Подключение приложения в Webflow Designer даёт агентам доступ к контенту, элементам, стилям и CSS, а кастомный код получает полный контекст проекта.</p>"
|
||||
}
|
||||
]
|
||||
],
|
||||
"sender": {
|
||||
"avatarSrc": "./assets/uploads/images/faq/2025-05-14-23.46.35-mquyvzbg.jpg",
|
||||
"avatarAlt": "Аватар NODE.DC",
|
||||
"name": "NODE.DC",
|
||||
"replyLabel": "Ответить",
|
||||
"sentLabel": "Отправлено с iPhone"
|
||||
},
|
||||
"scroll": {
|
||||
"speed": 0.55
|
||||
}
|
||||
},
|
||||
"editableFields": [
|
||||
{
|
||||
"path": "content.scroll.speed",
|
||||
"label": "Скорость скролла",
|
||||
"kind": "range",
|
||||
"renderAs": "number",
|
||||
"group": "Скролл",
|
||||
"min": 0.2,
|
||||
"max": 2,
|
||||
"step": 0.05,
|
||||
"suffix": "x"
|
||||
},
|
||||
{
|
||||
"path": "content.heading.muted",
|
||||
"label": "Заголовок: приглушённая строка",
|
||||
|
|
@ -1384,158 +1433,70 @@
|
|||
"label": "Окно: название",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Видео-окно"
|
||||
"group": "Окно FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.0.question",
|
||||
"label": "FAQ 1: вопрос",
|
||||
"path": "content.sender.avatarSrc",
|
||||
"label": "Отправитель: аватар",
|
||||
"kind": "media",
|
||||
"renderAs": "attr",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.avatarAlt",
|
||||
"label": "Отправитель: alt аватара",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.0.answerHtml",
|
||||
"label": "FAQ 1: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"path": "content.sender.name",
|
||||
"label": "Отправитель: имя",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.replyLabel",
|
||||
"label": "Отправитель: подпись ответа",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.sender.sentLabel",
|
||||
"label": "Отправитель: нижняя подпись",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "Отправитель"
|
||||
},
|
||||
{
|
||||
"path": "content.faq",
|
||||
"label": "Вопросы и ответы",
|
||||
"kind": "collection",
|
||||
"renderAs": "collection",
|
||||
"group": "FAQ",
|
||||
"itemTemplate": {
|
||||
"question": "Новый вопрос",
|
||||
"answerHtml": "<p>Новый ответ.</p>"
|
||||
},
|
||||
"itemFields": [
|
||||
{
|
||||
"path": "question",
|
||||
"label": "Вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.1.question",
|
||||
"label": "FAQ 2: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.1.answerHtml",
|
||||
"label": "FAQ 2: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.2.question",
|
||||
"label": "FAQ 3: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.2.answerHtml",
|
||||
"label": "FAQ 3: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.3.question",
|
||||
"label": "FAQ 4: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.3.answerHtml",
|
||||
"label": "FAQ 4: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.4.question",
|
||||
"label": "FAQ 5: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.4.answerHtml",
|
||||
"label": "FAQ 5: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.5.question",
|
||||
"label": "FAQ 6: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.5.answerHtml",
|
||||
"label": "FAQ 6: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.6.question",
|
||||
"label": "FAQ 7: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.6.answerHtml",
|
||||
"label": "FAQ 7: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.7.question",
|
||||
"label": "FAQ 8: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.7.answerHtml",
|
||||
"label": "FAQ 8: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.8.question",
|
||||
"label": "FAQ 9: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.8.answerHtml",
|
||||
"label": "FAQ 9: ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
},
|
||||
{
|
||||
"path": "content.faq.9.question",
|
||||
"label": "FAQ 10: вопрос",
|
||||
"kind": "text",
|
||||
"renderAs": "text",
|
||||
"group": "FAQ",
|
||||
"replaceAll": true
|
||||
},
|
||||
{
|
||||
"path": "content.faq.9.answerHtml",
|
||||
"label": "FAQ 10: ответ",
|
||||
"path": "answerHtml",
|
||||
"label": "Ответ",
|
||||
"kind": "html",
|
||||
"renderAs": "html",
|
||||
"group": "FAQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
|
|
@ -1617,7 +1578,7 @@
|
|||
"id": "pricing-table",
|
||||
"type": "pricingTable",
|
||||
"template": "pricing-table.html",
|
||||
"adminLabel": "Тарифная таблица",
|
||||
"adminLabel": "Тарифы: интро и таблица",
|
||||
"anchor": "pricing-wrap",
|
||||
"content": {
|
||||
"pricing": {
|
||||
|
|
@ -2278,7 +2239,7 @@
|
|||
"id": "pricing-intro",
|
||||
"type": "pricingIntro",
|
||||
"template": "pricing-intro.html",
|
||||
"adminLabel": "Интро тарифов",
|
||||
"adminLabel": "Интро тарифов (устаревший дубль)",
|
||||
"anchor": "waitlist",
|
||||
"enabled": false,
|
||||
"content": {
|
||||
|
|
@ -2838,7 +2799,7 @@
|
|||
"enabled": true,
|
||||
"content": {
|
||||
"footer": {
|
||||
"appIconSrc": "./assets/webflow/images/69ad964d951f9d17cc5a919e_logo-app.svg",
|
||||
"appIconSrc": "./assets/uploads/images/footer/dclogo_white_alpha-mquumh7v.png",
|
||||
"appIconAlt": "Иконка NODE.DC",
|
||||
"wordmarkSrc": "./assets/webflow/images/69ad96a28b06b7552a339137_logtype.svg?v=node-dc",
|
||||
"wordmarkAlt": "Логотип NODE.DC",
|
||||
|
|
|
|||
17
index.html
17
index.html
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
<section class="s"><div class="c _w-60"><hgroup data-module="hg" class="ho"><h2 class="main-h h2"><span class="darker-40">{{text:content.heading.muted}}</span><span>{{text:content.heading.main}}</span></h2><div class="h-txt">{{html:content.introHtml}}</div></hgroup></div><div class="c full"><div class="w-dyn-list"><div data-module="slider" role="list" class="slider w-dyn-items"><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.0.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.0.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.1.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.1.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.2.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.2.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.3.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.3.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.4.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.4.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.5.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.5.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.6.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.6.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.7.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.7.title}}</h3></hgroup></div></div></div></div><div class="webgl-target-w"><div data-scale="1, 0.6" data-module="webgl-target" class="webgl-target"></div></div></section>
|
||||
<section class="s"><div class="c _w-60"><hgroup data-module="hg" class="ho"><h2 class="main-h h2"><span class="darker-40">{{text:content.heading.muted}}</span><span>{{text:content.heading.main}}</span></h2><div class="h-txt">{{html:content.introHtml}}</div></hgroup></div><div class="c full"><div class="w-dyn-list"><div data-module="slider" data-scroll-speed="{{attr:content.scroll.speed}}" role="list" class="slider w-dyn-items"><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.0.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.0.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.1.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.1.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.2.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.2.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.3.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.3.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.4.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.4.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.5.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.5.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.6.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.6.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.7.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.7.title}}</h3></hgroup></div></div></div></div><div class="webgl-target-w"><div data-scale="1, 0.6" data-module="webgl-target" class="webgl-target"></div></div></section>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
<section class="s"><div class="c _w-60"><hgroup data-module="hg" class="ho flip"><h2 class="main-h h1"><span class="darker-40">{{text:content.heading.muted}}</span><span class="darker-70">{{text:content.heading.middle}}</span><span>{{text:content.heading.main}}</span></h2><div class="h-txt">{{html:content.introHtml}}</div></hgroup></div><div class="c full"><div class="w-dyn-list"><div data-module="slider" role="list" class="slider w-dyn-items"><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.0.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.0.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.1.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.1.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.2.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.2.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.3.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.3.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.4.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.4.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.5.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.5.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.6.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.6.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.7.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.7.title}}</h3></hgroup></div></div></div></div><div class="gap-v"><div class="c _w-60"><hgroup data-module="hg" class="ho"><h2 class="main-h h2"><span class="darker-40">{{text:content.oneClick.heading.muted}}</span><span class="darker-70">{{text:content.oneClick.heading.middle}}</span><span>{{text:content.oneClick.heading.main}}</span></h2><div class="txt-w"><div class="h-txt">{{html:content.oneClick.introHtml}}</div><div class="hg-par darker-40">{{text:content.oneClick.items.0.eyebrow}}</div><div class="h-txt">{{html:content.oneClick.items.0.bodyHtml}}</div><div class="hg-par darker-40">{{text:content.oneClick.items.1.eyebrow}}</div><div class="h-txt">{{html:content.oneClick.items.1.bodyHtml}}</div></div></hgroup></div><div class="c _w-60"><hgroup data-module="hg" class="ho flip"><h2 class="main-h h2"><span class="darker-40">{{text:content.mcp.heading.muted}}</span><span class="darker-70">{{text:content.mcp.heading.middle}}</span><span>{{text:content.mcp.heading.main}}</span></h2><div class="txt-w"><div class="h-txt">{{html:content.mcp.introHtml}}</div><div class="hg-par darker-40">{{text:content.mcp.items.0.eyebrow}}</div><div class="h-txt">{{html:content.mcp.items.0.bodyHtml}}</div></div></hgroup></div></div></section>
|
||||
<section class="s"><div class="c _w-60"><hgroup data-module="hg" class="ho flip"><h2 class="main-h h1"><span class="darker-40">{{text:content.heading.muted}}</span><span class="darker-70">{{text:content.heading.middle}}</span><span>{{text:content.heading.main}}</span></h2><div class="h-txt">{{html:content.introHtml}}</div></hgroup></div><div class="c full"><div class="w-dyn-list"><div data-module="slider" data-scroll-speed="{{attr:content.scroll.speed}}" role="list" class="slider w-dyn-items"><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.0.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.0.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.1.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.1.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.2.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.2.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.3.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.3.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.4.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.4.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.5.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.5.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.6.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.6.title}}</h3></hgroup></div><div role="listitem" class="slide-w w-dyn-item"><div class="video-cut"><div class="video-screen"><video src="{{attr:content.sliderItems.7.videoSrc}}" playsinline="true" muted="" loop="" preload="none" data-module="video-handle" class="video-el"></video></div></div><hgroup class="slide-he-w"><h3 data-title="" class="slide-he">{{text:content.sliderItems.7.title}}</h3></hgroup></div></div></div></div><div class="gap-v"><div class="c _w-60"><hgroup data-module="hg" class="ho"><h2 class="main-h h2"><span class="darker-40">{{text:content.oneClick.heading.muted}}</span><span class="darker-70">{{text:content.oneClick.heading.middle}}</span><span>{{text:content.oneClick.heading.main}}</span></h2><div class="txt-w"><div class="h-txt">{{html:content.oneClick.introHtml}}</div><div class="hg-par darker-40">{{text:content.oneClick.items.0.eyebrow}}</div><div class="h-txt">{{html:content.oneClick.items.0.bodyHtml}}</div><div class="hg-par darker-40">{{text:content.oneClick.items.1.eyebrow}}</div><div class="h-txt">{{html:content.oneClick.items.1.bodyHtml}}</div></div></hgroup></div><div class="c _w-60"><hgroup data-module="hg" class="ho flip"><h2 class="main-h h2"><span class="darker-40">{{text:content.mcp.heading.muted}}</span><span class="darker-70">{{text:content.mcp.heading.middle}}</span><span>{{text:content.mcp.heading.main}}</span></h2><div class="txt-w"><div class="h-txt">{{html:content.mcp.introHtml}}</div><div class="hg-par darker-40">{{text:content.mcp.items.0.eyebrow}}</div><div class="h-txt">{{html:content.mcp.items.0.bodyHtml}}</div></div></hgroup></div></div></section>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -114,7 +114,12 @@ function renderEachBlocks(html, block) {
|
|||
throw new Error(`Each token "${path}" in block "${block.id}" must point to an array`);
|
||||
}
|
||||
|
||||
return items.map((item) => renderTemplate(innerHtml, item ?? {})).join("");
|
||||
return items
|
||||
.map((item) => {
|
||||
const itemScope = item && typeof item === "object" && !Array.isArray(item) ? item : { value: item };
|
||||
return renderTemplate(innerHtml, { ...block, ...itemScope });
|
||||
})
|
||||
.join("");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue