|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let bgVideoTemplate = '<video playsinline loop muted autoplay src="../../media/sample.webm" poster="../../media/sample.webp"><video>'; |
|
|
let bgImageTemplate = '<img src="../../media/4.jpg">'; |
|
|
let defaultSeparatorSvg = '<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 41" width="100%" height="300" fill="var(--bs-body-bg)" preserveAspectRatio="none"><defs><style>.cls-1{fill:inherit}</style></defs><title>rough-edges-bottom</title><path class="cls-1" d="M0,185l125-26,33,17,58-12s54,19,55,19,50-11,50-11l56,6,60-8,63,15v15H0Z" transform="translate(0 -159)"/></svg>'; |
|
|
|
|
|
let section_sort = 1; |
|
|
|
|
|
let SectionContent = [{ |
|
|
name: "Title", |
|
|
key: "title", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "title", |
|
|
inputtype: TextInput |
|
|
},{ |
|
|
name: "Container width", |
|
|
key: "container-width", |
|
|
sort: section_sort++, |
|
|
child:":scope > .container, :scope > .container-fluid", |
|
|
htmlAttr: "class", |
|
|
validValues: ["container", "container-fluid"], |
|
|
inputtype: RadioButtonInput, |
|
|
data: { |
|
|
extraclass:"btn-group-sm btn-group-fullwidth", |
|
|
options: [{ |
|
|
value: "container", |
|
|
icon:"la la-box", |
|
|
text: "Boxed", |
|
|
title: "Boxed" |
|
|
},{ |
|
|
value: "container-fluid", |
|
|
icon:"la la-arrows-alt-h", |
|
|
title: "Full", |
|
|
text: "Full" |
|
|
}] |
|
|
} |
|
|
},{ |
|
|
name: "Container height", |
|
|
key: "container-height", |
|
|
sort: section_sort++, |
|
|
child:":scope > .container:first-child, :scope > .container-fluid:first-child", |
|
|
htmlAttr: "class", |
|
|
validValues: ["", "vh-100"], |
|
|
inputtype: RadioButtonInput, |
|
|
data: { |
|
|
extraclass:"btn-group-sm btn-group-fullwidth", |
|
|
options: [{ |
|
|
value: "container", |
|
|
icon:"la la-expand", |
|
|
text: "Auto", |
|
|
title: "Auto", |
|
|
checked:true, |
|
|
},{ |
|
|
value: "vh-100", |
|
|
icon:"la la-arrows-alt-v", |
|
|
title: "Full", |
|
|
text: "Full" |
|
|
}] |
|
|
} |
|
|
} |
|
|
]; |
|
|
|
|
|
let SectionBackground = [{ |
|
|
key: "section_background_header", |
|
|
inputtype: SectionInput, |
|
|
name:false, |
|
|
sort: section_sort++, |
|
|
|
|
|
data: {header:"Background"}, |
|
|
},{ |
|
|
name: false, |
|
|
key: "section-bg", |
|
|
sort: section_sort++, |
|
|
inputtype: RadioButtonInput, |
|
|
data: { |
|
|
inline: true, |
|
|
extraclass:"btn-group-sm btn-group-fullwidth", |
|
|
options: [{ |
|
|
value: "none", |
|
|
text: "None", |
|
|
title: "None", |
|
|
checked:true, |
|
|
},{ |
|
|
value: "bg-image", |
|
|
icon:"la la-image", |
|
|
text: "Image", |
|
|
title: "Image", |
|
|
},{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
value: "bg-video", |
|
|
icon:"la la-video", |
|
|
text: "Video", |
|
|
title: "Video", |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}], |
|
|
}, |
|
|
hideGroups : function() { |
|
|
document.querySelectorAll('.mb-3[data-group="bg-image"],.mb-3[data-group="bg-video"]').forEach(e => e.classList.add("d-none")); |
|
|
}, |
|
|
|
|
|
onChange : function(node, value, input) { |
|
|
this.hideGroups(); |
|
|
document.querySelectorAll('.mb-3[data-group="'+ input.value + '"].d-none').forEach((el, i) => { |
|
|
el.classList.remove("d-none"); |
|
|
}); |
|
|
|
|
|
let container = node.querySelector(":scope > .background-container"); |
|
|
if (!container) { |
|
|
container = generateElements('<div class="background-container"></div>')[0]; |
|
|
node.appendChild(container); |
|
|
} |
|
|
|
|
|
let img = node.querySelector(":scope > .background-container > img"); |
|
|
let video = node.querySelector(":scope > .background-container > video"); |
|
|
|
|
|
container.querySelectorAll(":scope > *").forEach((el, i) => { |
|
|
el.classList.add("d-none"); |
|
|
}); |
|
|
|
|
|
switch (value) { |
|
|
case "bg-image": |
|
|
if (img) { |
|
|
img.classList.remove("d-none"); |
|
|
} else { |
|
|
container.append(generateElements(bgImageTemplate)[0]); |
|
|
|
|
|
node.click(); |
|
|
} |
|
|
break; |
|
|
case "bg-video": |
|
|
if (video) { |
|
|
video.classList.remove("d-none"); |
|
|
} else { |
|
|
container.append(generateElements(bgVideoTemplate)[0]); |
|
|
|
|
|
node.click(); |
|
|
} |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
return element; |
|
|
}, |
|
|
init: function(node) { |
|
|
let selected = "none"; |
|
|
let img = node.querySelector(":scope > .background-container img"); |
|
|
let video = node.querySelector(":scope > .background-container video"); |
|
|
|
|
|
if (img?.offsetParent) { |
|
|
selected = "bg-image"; |
|
|
} |
|
|
if (video?.offsetParent) { |
|
|
selected = "bg-video"; |
|
|
} |
|
|
|
|
|
this.hideGroups(); |
|
|
return selected; |
|
|
}, |
|
|
},{ |
|
|
name: "Image", |
|
|
key: "src", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "src", |
|
|
child:":scope > .background-container > img", |
|
|
group:"bg-image", |
|
|
inline:true, |
|
|
inputtype: ImageInput |
|
|
},{ |
|
|
name: "Video", |
|
|
child: "source", |
|
|
key: "src", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "src", |
|
|
child:":scope > .background-container > video", |
|
|
group:"bg-video", |
|
|
inline:true, |
|
|
inputtype: VideoInput |
|
|
},{ |
|
|
name: "Poster", |
|
|
key: "poster", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "poster", |
|
|
child:":scope > .background-container > video", |
|
|
group:"bg-video", |
|
|
inline:true, |
|
|
inputtype: ImageInput |
|
|
}, { |
|
|
name: "Parallax", |
|
|
key: "parallax", |
|
|
sort: section_sort++, |
|
|
child:":scope > .background-container", |
|
|
htmlAttr: "class", |
|
|
validValues: ["", "parallax"], |
|
|
inputtype: ToggleInput, |
|
|
data: { |
|
|
className: "form-switch-lg", |
|
|
on: 'parallax', |
|
|
off: '' |
|
|
}, |
|
|
}, |
|
|
]; |
|
|
|
|
|
|
|
|
let SectionOverlay = [{ |
|
|
key: "section_overlay", |
|
|
inputtype: SectionInput, |
|
|
name:false, |
|
|
sort: section_sort++, |
|
|
|
|
|
data: {header:"Overlay"}, |
|
|
},{ |
|
|
|
|
|
name: false, |
|
|
key: "overlay", |
|
|
sort: section_sort++, |
|
|
inline: true, |
|
|
|
|
|
inputtype: ToggleInput, |
|
|
data: { |
|
|
className: "form-switch-lg", |
|
|
on: 'true', |
|
|
off: 'false' |
|
|
}, |
|
|
onChange : function(node, value, input) { |
|
|
let group = document.querySelectorAll('.mb-3[data-group="overlay"]'); |
|
|
let overlay = node.querySelector(":scope > .overlay"); |
|
|
|
|
|
if (value == 'true') { |
|
|
group.forEach(e => e.classList.remove("d-none")); |
|
|
|
|
|
if (!overlay) { |
|
|
overlay = generateElements('<div class="overlay"></div>')[0]; |
|
|
node.appendChild(overlay); |
|
|
} else { |
|
|
overlay.classList.remove("d-none"); |
|
|
} |
|
|
} else { |
|
|
group.forEach(e => e.classList.add("d-none")); |
|
|
if (overlay) overlay.classList.add("d-none"); |
|
|
} |
|
|
|
|
|
return element; |
|
|
}, |
|
|
init: function(node) { |
|
|
let overlay = node.querySelector(":scope > .overlay"); |
|
|
let group = document.querySelectorAll('.mb-3[data-group="overlay"]'); |
|
|
|
|
|
if (overlay && overlay.offsetParent) { |
|
|
group.forEach(e => e.classList.remove("d-none")); |
|
|
return 'true'; |
|
|
} else { |
|
|
group.forEach(e => e.classList.add("d-none")); |
|
|
return 'false'; |
|
|
} |
|
|
} |
|
|
},{ |
|
|
name: "Color", |
|
|
key: "background-color", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "style", |
|
|
child:":scope > .overlay", |
|
|
group:"overlay", |
|
|
inputtype: ColorInput |
|
|
},{ |
|
|
name: "Opacity", |
|
|
key: "opacity", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "style", |
|
|
inline:false, |
|
|
group:"overlay", |
|
|
child:":scope > .overlay", |
|
|
inputtype: RangeInput, |
|
|
data:{ |
|
|
max: 1, |
|
|
min:0, |
|
|
step:0.1 |
|
|
} |
|
|
}]; |
|
|
|
|
|
function sectionSeparatorProperties(name, title) { |
|
|
return [{ |
|
|
key: `section_${name}_separator`, |
|
|
inputtype: SectionInput, |
|
|
name:false, |
|
|
sort: section_sort++, |
|
|
|
|
|
data: {header:`${title} Separator`}, |
|
|
},{ |
|
|
|
|
|
name: false, |
|
|
key: `${name}_separator`, |
|
|
sort: section_sort++, |
|
|
inline: true, |
|
|
inputtype: ToggleInput, |
|
|
data: { |
|
|
className: "form-switch-lg", |
|
|
on: 'true', |
|
|
off: 'false' |
|
|
}, |
|
|
onChange : function(node, value, input) { |
|
|
let group = document.querySelectorAll(`[data-group="${name}_separator"]`); |
|
|
let separator = node.querySelector(`:scope > .${name}.separator`); |
|
|
|
|
|
if (value == 'true') { |
|
|
group.forEach(e => e.classList.remove("d-none")); |
|
|
|
|
|
if (!separator) { |
|
|
separator = generateElements(`<div class="separator ${name}">${defaultSeparatorSvg}</div>`)[0]; |
|
|
node.appendChild(separator); |
|
|
} else { |
|
|
separator.classList.remove("d-none"); |
|
|
} |
|
|
} else { |
|
|
group.forEach(e => e.classList.add("d-none")); |
|
|
separator.classList.add("d-none"); |
|
|
} |
|
|
|
|
|
return element; |
|
|
}, |
|
|
init: function(node) { |
|
|
let group = node.querySelectorAll(`[data-group="${name}_separator"]`); |
|
|
let separator = node.querySelector(`:scope > .${name}.separator`); |
|
|
|
|
|
if (separator && separator.offsetParent) { |
|
|
group.forEach(e => e.classList.remove("d-none")); |
|
|
return 'true'; |
|
|
} else { |
|
|
group.forEach(e => e.classList.add("d-none")); |
|
|
return 'false'; |
|
|
} |
|
|
} |
|
|
},{ |
|
|
name: "Icon", |
|
|
key: "icon", |
|
|
sort: section_sort++, |
|
|
inline:true, |
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
inputtype: HtmlListSelectInput, |
|
|
onChange:function(element, value, input, component) { |
|
|
let newElement = generateElements(value)[0]; |
|
|
let attributes = element.attributes; |
|
|
|
|
|
|
|
|
for (let i = 0; i < attributes.length; i++) { |
|
|
let attr = attributes[i]; |
|
|
if (attr.name && attr.name != "viewBox") { |
|
|
newElement.setAttribute(attr.name, attr.value); |
|
|
} |
|
|
} |
|
|
|
|
|
element.replaceWith(newElement); |
|
|
return newElement; |
|
|
}, |
|
|
data: { |
|
|
url: Vvveb.baseUrl + "../../resources/svg/separators/{value}/index.html", |
|
|
clickElement:"li", |
|
|
insertElement:"svg", |
|
|
elements: 'Loading ...', |
|
|
options: [{ |
|
|
value: "digital-red-panther", |
|
|
text: "Red panther" |
|
|
}] |
|
|
}, |
|
|
},{ |
|
|
name: "Width", |
|
|
key: "width", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "width", |
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
inputtype: RangeInput, |
|
|
data:{ |
|
|
max: 640, |
|
|
min:6, |
|
|
step:1 |
|
|
} |
|
|
},{ |
|
|
name: "Height", |
|
|
key: "height", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "height", |
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
inputtype: RangeInput, |
|
|
data:{ |
|
|
max: 640, |
|
|
min:6, |
|
|
step:1 |
|
|
} |
|
|
},{ |
|
|
name: "Stroke width", |
|
|
key: "stroke-width", |
|
|
sort: section_sort++, |
|
|
htmlAttr: "stroke-width", |
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
inputtype: RangeInput, |
|
|
data:{ |
|
|
max: 512, |
|
|
min:1, |
|
|
step:1 |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
name: "Fill Color", |
|
|
key: "fill", |
|
|
sort: section_sort++, |
|
|
col:4, |
|
|
inline:true, |
|
|
|
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
htmlAttr: "fill", |
|
|
inputtype: ColorInput, |
|
|
},{ |
|
|
name: "Color", |
|
|
key: "color", |
|
|
sort: section_sort++, |
|
|
col:4, |
|
|
inline:true, |
|
|
|
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
htmlAttr: "color", |
|
|
inputtype: ColorInput, |
|
|
},{ |
|
|
name: "Stroke", |
|
|
key: "stroke", |
|
|
sort: section_sort++, |
|
|
col:4, |
|
|
inline:true, |
|
|
|
|
|
group:`${name}_separator`, |
|
|
child:`.separator.${name} > svg`, |
|
|
htmlAttr: "color", |
|
|
inputtype: ColorInput, |
|
|
} |
|
|
]; |
|
|
} |
|
|
|
|
|
let SectionBottomSeparator = [{ |
|
|
key: "section_bottom_separator", |
|
|
inputtype: SectionInput, |
|
|
name:false, |
|
|
sort: section_sort++, |
|
|
|
|
|
data: {header:"Bottom Separator"}, |
|
|
},{ |
|
|
|
|
|
name: false, |
|
|
key: "top_bottom", |
|
|
sort: section_sort++, |
|
|
inline: true, |
|
|
validValues: ["", "active"], |
|
|
inputtype: ToggleInput, |
|
|
data: { |
|
|
className: "form-switch-lg", |
|
|
on: "active", |
|
|
off: "" |
|
|
} |
|
|
}, |
|
|
]; |
|
|
|
|
|
|
|
|
let ComponentSectionContent = [ |
|
|
...SectionContent, |
|
|
...SectionBackground, |
|
|
...SectionOverlay, |
|
|
...sectionSeparatorProperties("top", "Top"), |
|
|
...sectionSeparatorProperties("bottom", "Bottom"), |
|
|
]; |
|
|
|
|
|
|
|
|
let ComponentSectionStyle = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let ComponentSectionAdvanced = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function componentsInit(node) { |
|
|
|
|
|
document.querySelectorAll('.mb-3[data-group]').forEach(e => e.classList.add("d-none")); |
|
|
|
|
|
let img = node.querySelector(":scope > .background-container img"); |
|
|
let video = node.querySelector(":scope > .background-container video"); |
|
|
let overlay = node.querySelector(":scope > .overlay"); |
|
|
let separatorTop = node.querySelector(":scope > .separator.top"); |
|
|
let separatorBottom = node.querySelector(":scope > .separator.bottom"); |
|
|
let bg = ""; |
|
|
|
|
|
if (img && img.offsetParent) { |
|
|
bg = "bg-image"; |
|
|
} |
|
|
|
|
|
if (video && video.offsetParent) { |
|
|
bg = "bg-video"; |
|
|
} |
|
|
|
|
|
let showSection = function (section) { |
|
|
document.querySelectorAll('.mb-3[data-group="' + section + '"]').forEach(e => e.classList.remove("d-none")); |
|
|
} |
|
|
|
|
|
if (bg) { |
|
|
showSection(bg); |
|
|
} |
|
|
|
|
|
if (overlay && overlay.offsetParent) { |
|
|
showSection("overlay"); |
|
|
} |
|
|
|
|
|
if (separatorTop && separatorTop.offsetParent) { |
|
|
showSection("top_separator"); |
|
|
} |
|
|
|
|
|
if (separatorBottom && separatorBottom.offsetParent) { |
|
|
showSection("bottom_separator"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Vvveb.Components.extend("_base", "elements/section", { |
|
|
nodes: ["section"], |
|
|
name: "Section", |
|
|
image: "icons/stream-solid.svg", |
|
|
html: `<section> |
|
|
<div class="container"> |
|
|
<h1>Section</h1> |
|
|
</div> |
|
|
</section>`, |
|
|
properties: [ |
|
|
...ComponentSectionContent, |
|
|
...ComponentSectionStyle, |
|
|
...ComponentSectionAdvanced |
|
|
], |
|
|
init: componentsInit |
|
|
}); |
|
|
|
|
|
|
|
|
Vvveb.Components.extend("_base", "elements/header", { |
|
|
nodes: ["header"], |
|
|
name: "Header", |
|
|
image: "icons/stream-solid.svg", |
|
|
html: `<header> |
|
|
<div class="container"> |
|
|
<h1>Section</h1> |
|
|
</div> |
|
|
</header>`, |
|
|
properties: [ |
|
|
...ComponentSectionContent, |
|
|
...ComponentSectionStyle, |
|
|
...ComponentSectionAdvanced |
|
|
], |
|
|
init: componentsInit |
|
|
}); |
|
|
|
|
|
|
|
|
Vvveb.Components.extend("_base", "elements/footer", { |
|
|
nodes: ["footer"], |
|
|
name: "Footer", |
|
|
image: "icons/stream-solid.svg", |
|
|
html: `<footer> |
|
|
<div class="container"> |
|
|
<h1>Section</h1> |
|
|
</div> |
|
|
</footer>`, |
|
|
properties: [ |
|
|
...ComponentSectionContent, |
|
|
...ComponentSectionStyle, |
|
|
...ComponentSectionAdvanced |
|
|
], |
|
|
init: componentsInit |
|
|
}); |
|
|
|