| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| Vvveb.ComponentsGroup['Elements'] = [ |
| |
| "elements/font-icon", |
| "elements/carousel", |
| "elements/gallery", |
| "elements/slider", |
| "elements/tabs", |
| "elements/accordion", |
| "elements/flip-box", |
| "elements/counter", |
| "elements/svg-icon", |
| "elements/figure", |
| |
| "elements/social-icons", |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| "elements/code", |
| "elements/image-compare", |
| |
| |
| |
| |
| |
| ]; |
|
|
| Vvveb.Components.extend("_base","elements/figure", { |
| nodes: ["figure"], |
| name: "Figure", |
| image: "icons/image.svg", |
| resizable:true, |
| html: `<figure> |
| <img src="${Vvveb.baseUrl}icons/image.svg" alt="Trulli"> |
| <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption> |
| <div class="border"></div> |
| </figure>`, |
| |
| stylesheets:[{ |
| |
| 'src': Vvveb.baseUrl + 'css/figure.css', |
| |
| 'mustHaveElement':"figure", |
| }, |
| ], |
| |
| |
| |
| |
| |
| |
| |
| |
| resizable:true, |
| |
| properties: [{ |
| name: "Image", |
| key: "src", |
| child:"img", |
| htmlAttr: "src", |
| inputtype: ImageInput |
| },{ |
| name: "Width", |
| key: "width", |
| child:"img", |
| htmlAttr: "width", |
| inputtype: CssUnitInput |
| },{ |
| name: "Height", |
| key: "height", |
| child:"img", |
| htmlAttr: "height", |
| inputtype: CssUnitInput |
| },{ |
| name: "Alt", |
| key: "alt", |
| child:"img", |
| htmlAttr: "alt", |
| inputtype: TextInput |
| },{ |
| name: "Caption", |
| key: "caption", |
| child:"figcaption", |
| htmlAttr: "innerHTML", |
| inputtype: TextareaInput |
| }] |
| }); |
|
|
|
|
|
|
| |
| Vvveb.Components.extend("_base","elements/font-icon", { |
| classes: ["la", "lab"], |
| name: "Font Icon", |
| image: "icons/star.svg", |
| html: `<i class="la la-star la-2x"></i>`, |
| properties: [ |
| { |
| name: "Icon", |
| key: "icon", |
| inline:true, |
| inputtype: HtmlListSelectInput, |
| onChange:function(element, value, input, component) { |
| element.classList.remove("la", "lab", "lar"); |
| let className = element.getAttribute('class'); |
| element.classList.forEach((value, key, listObj) => { |
| if (value.startsWith("la-") && value != "la-lg") { |
| element.classList.remove(value); |
| } |
| }); |
|
|
| element.classList.add(...input.className.split(" ")); |
| return element; |
| }, |
| data: { |
| url: Vvveb.baseUrl + "../../resources/{value}.html", |
| clickElement:"li", |
| insertElement:"i", |
| elements: 'Loading ...', |
| options: [{ |
| value: "line-awesome", |
| text: "Line-awesome" |
| }] |
| }, |
| },{ |
| name: "Size", |
| key: "type", |
| htmlAttr: "class", |
| inputtype: SelectInput, |
| validValues: ["","la-lg", "la-2x"], |
| data: { |
| options: [{ |
| value: "", |
| text: "Normal" |
| },{ |
| value: "la-lg", |
| text: "Large" |
| },{ |
| value: "la-2x", |
| text: "2x" |
| }] |
| } |
| }] |
| }); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| Vvveb.Components.extend("_base","elements/svg-icon", { |
| nodes: ["svg"], |
| name: "Svg Icon", |
| image: "icons/star.svg", |
| html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="64" height="64"> |
| <path d="M 30.335938 12.546875 L 20.164063 11.472656 L 16 2.132813 L 11.835938 11.472656 L 1.664063 12.546875 L 9.261719 19.394531 L 7.140625 29.398438 L 16 24.289063 L 24.859375 29.398438 L 22.738281 19.394531 Z"/> |
| </svg>`, |
| properties: [{ |
| name: "Icon", |
| key: "icon", |
| inline:true, |
| 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/icons/{value}/index.html", |
| clickElement:"li", |
| insertElement:"svg", |
| elements: 'Loading ...', |
| options: [{ |
| value: "eva-icons", |
| text: "Eva icons" |
| },{ |
| value: "ionicons", |
| text: "IonIcons" |
| },{ |
| value: "linea", |
| text: "Linea" |
| },{ |
| value: "remix-icon", |
| text: "RemixIcon" |
| },{ |
| value: "unicons", |
| text: "Unicons" |
| },{ |
| value: "clarity-icons", |
| text: "Clarity icons" |
| },{ |
| value: "jam-icons", |
| text: "Jam icons" |
| },{ |
| value: "ant-design-icons", |
| text: "Ant design icons" |
| },{ |
| value: "themify", |
| text: "Themify" |
| },{ |
| value: "css.gg", |
| text: "Css.gg" |
| },{ |
| value: "olicons", |
| text: "Olicons" |
| },{ |
| value: "open-iconic", |
| text: "Open iconic" |
| },{ |
| value: "boxicons", |
| text: "Box icons" |
| },{ |
| value: "elegant-font", |
| text: "Elegant font" |
| },{ |
| value: "dripicons", |
| text: "Dripicons" |
| },{ |
| value: "feather", |
| text: "Feather" |
| },{ |
| value: "coreui-icons", |
| text: "Coreui icons" |
| },{ |
| value: "heroicons", |
| text: "Heroicons" |
| },{ |
| value: "iconoir", |
| text: "Iconoir" |
| },{ |
| value: "iconsax", |
| text: "Iconsax" |
| },{ |
| value: "ikonate", |
| text: "Ikonate" |
| },{ |
| value: "tabler-icons", |
| text: "Tabler icons" |
| },{ |
| value: "octicons", |
| text: "Octicons" |
| },{ |
| value: "system-uicons", |
| text: "System-uicons" |
| },{ |
| value: "font-awesome", |
| text: "FontAwesome" |
| },{ |
| value: "pe-icon-7-stroke", |
| text: "Pixeden icon 7 stroke" |
| },{ |
| value: "77_essential_icons", |
| text: "77 essential icons" |
| },{ |
| value: "150-outlined-icons", |
| text: "150 outlined icons" |
| },{ |
| value: "material-design", |
| text: "Material Design" |
| }] |
| }, |
| },{ |
| name: "Width", |
| key: "width", |
| htmlAttr: "width", |
| inputtype: RangeInput, |
| data:{ |
| max: 640, |
| min:6, |
| step:1 |
| } |
| },{ |
| name: "Height", |
| key: "height", |
| htmlAttr: "height", |
| inputtype: RangeInput, |
| data:{ |
| max: 640, |
| min:6, |
| step:1 |
| } |
| },{ |
| name: "Stroke width", |
| key: "stroke-width", |
| htmlAttr: "stroke-width", |
| inputtype: RangeInput, |
| data:{ |
| max: 512, |
| min:1, |
| step:1 |
| } |
| },{ |
| key: "svg_style_header", |
| inputtype: SectionInput, |
| name:false, |
| |
| section: style_section, |
| data: {header:"Svg colors"}, |
| },{ |
| name: "Fill Color", |
| key: "fill", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "fill", |
| inputtype: ColorInput, |
| },{ |
| name: "Color", |
| key: "color", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "color", |
| inputtype: ColorInput, |
| },{ |
| name: "Stroke", |
| key: "Stroke", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "stroke", |
| inputtype: ColorInput, |
| }] |
| }); |
|
|
|
|
| Vvveb.Components.add("elements/svg-element", { |
| nodes: ["path", "line", "polyline", "polygon", "rect", "circle", "ellipse", "g"], |
| name: "Svg element", |
| image: "icons/star.svg", |
| html: ``, |
| properties: [{ |
| name: "Fill Color", |
| key: "fill", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "fill", |
| inputtype: ColorInput, |
| },{ |
| name: "Color", |
| key: "color", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "color", |
| inputtype: ColorInput, |
| },{ |
| name: "Stroke", |
| key: "Stroke", |
| |
| col:4, |
| inline:true, |
| section: style_section, |
| htmlAttr: "color", |
| inputtype: ColorInput, |
| },{ |
| name: "Stroke width", |
| key: "stroke-width", |
| htmlAttr: "stroke-width", |
| inputtype: RangeInput, |
| data:{ |
| max: 512, |
| min:1, |
| step:1 |
| } |
| }] |
| }); |
|
|
| |
| Vvveb.Components.add("elements/gallery", { |
| attributes: ["data-component-gallery"], |
| name: "Gallery", |
| image: "icons/images.svg", |
| html: ` |
| <div class="gallery masonry has-shadow" data-component-gallery> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/1.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/2.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/3.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/4.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/5.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/6.jpg"> |
| </a> |
| </div> |
| <div class="item"> |
| <a> |
| <img src="../../media/posts/7.jpg"> |
| </a> |
| </div> |
| </div> |
| `, |
| properties: [{ |
| name: "Masonry layout", |
| key: "masonry", |
| htmlAttr: "class", |
| validValues: ["masonry", "flex"], |
| inputtype: ToggleInput, |
| data: { |
| on: "masonry", |
| off: "flex" |
| }, |
| setGroup: group => { |
| document.querySelectorAll(".mb-3[data-group]").forEach(el => el.style.display = "none"); |
| document.querySelector('.mb-3[data-group="'+ group + '"]').style.display = ""; |
| }, |
| onChange : function(node, value, input) { |
| this.setGroup(value); |
| return node; |
| }, |
| init: function (node) { |
| if (node.classList.contains("masonry")) { |
| return "masonry"; |
| } else { |
| return "flex"; |
| } |
| }, |
| },{ |
| name: "Image shadow", |
| key: "shadow", |
| htmlAttr: "class", |
| validValues: [ "", "has-shadow"], |
| inputtype: ToggleInput, |
| data: { |
| on: "has-shadow", |
| off: "" |
| }, |
| },{ |
| name: "Horizontal gap", |
| key: "column-gap", |
| htmlAttr: "style", |
| inputtype: CssUnitInput, |
| data:{ |
| max: 100, |
| min:0, |
| step:1 |
| } |
| },{ |
| name: "Vertical gap", |
| key: "margin-bottom", |
| htmlAttr: "style", |
| child: ".item", |
| inputtype: CssUnitInput, |
| data:{ |
| max: 100, |
| min:0, |
| step:1 |
| } |
| },{ |
| name: "Images per row masonry", |
| key: "column-count", |
| group:"masonry", |
| htmlAttr: "style", |
| inputtype: RangeInput, |
| data:{ |
| max: 12, |
| min:1, |
| step:1 |
| } |
| },{ |
| name: "Images per row flex", |
| group:"flex", |
| key: "flex-basis", |
| child: ".item", |
| htmlAttr: "style", |
| inputtype: RangeInput, |
| data:{ |
| max: 12, |
| min:1, |
| step:1 |
| }, |
| onChange: function(node, value, input, component, inputElement) { |
| if (value) { |
| value = 100 / value; |
| value += "%"; |
| } |
| |
| return value; |
| } |
| },{ |
| name: "", |
| key: "addChild", |
| inputtype: ButtonInput, |
| data: {text:"Add image", icon:"la la-plus"}, |
| onChange: function(node) { |
| node.append(generateElements('<div class="item"><a><img src="../../media/posts/1.jpg"></a></div>')[0]); |
| |
| |
| |
| |
| return node; |
| } |
| }], |
| init(node) { |
|
|
| document.querySelectorAll(".mb-3[data-group]").forEach(el => el.style.display = "none"); |
| |
| let source = "flex"; |
| if (node.classList.contains("masonry")) { |
| source = "masonry"; |
| } else { |
| source = "flex"; |
| } |
| |
| document.querySelector('.mb-3[data-group="'+ source + '"]').style.display = ""; |
| } |
| }); |
|
|
| |
| Vvveb.Components.add("elements/tab", { |
| |
| classes: ["tab-pane"], |
| name: "Tab", |
| image: "icons/tabs.svg", |
| html: ``, |
| properties: [{ |
| name: "Id", |
| key: "id", |
| htmlAttr: "id", |
| inline:false, |
| col:6, |
| inputtype: TextInput |
| },{ |
| name: "Class", |
| key: "class", |
| htmlAttr: "class", |
| inline:false, |
| col:6, |
| inputtype: TextInput |
| |
| } , { |
| name: "Active", |
| key: "active", |
| htmlAttr: "class", |
| validValues: ["", "active"], |
| inputtype: ToggleInput, |
| inline:true, |
| col:6, |
| data: { |
| on: "active", |
| off: "" |
| } |
| }] |
| }); |
| |
| Vvveb.Components.add("elements/tabs", { |
| attributes: ["data-component-tabs"], |
| name: "Tabs", |
| image: "icons/tabs.svg", |
| html: ` |
| <div data-component-tabs id="tabs-parentId"> |
| <nav> |
| <div class="nav nav-tabs" role="tablist"> |
| <button class="nav-link active" id="nav-tab-parentId-1" data-bs-toggle="tab" data-bs-target="#nav-parentId-1" type="button" role="tab" aria-controls="nav-1" aria-selected="true">Home</button> |
| <button class="nav-link" id="nav-tab-parentId-2" data-bs-toggle="tab" data-bs-target="#nav-parentId-2" type="button" role="tab" aria-controls="nav-2" aria-selected="false">Profile</button> |
| <button class="nav-link" id="nav-tab-parentId-3" data-bs-toggle="tab" data-bs-target="#nav-parentId-3" type="button" role="tab" aria-controls="nav-3" aria-selected="false">Contact</button> </div> |
| </nav> |
| <div class="tab-content"> |
| <div class="tab-pane p-4 show active" id="nav-parentId-1" role="tabpanel" aria-labelledby="nav-tab-1" tabindex="0"> |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Corporis perferendis rem accusantium ducimus animi nesciunt expedita omnis aut quas molestias!</p> |
| </div> |
| <div class="tab-pane p-4" id="nav-parentId-2" role="tabpanel" aria-labelledby="nav-tab-2" tabindex="0"> |
| <p>Mauris viverra cursus ante laoreet eleifend. Donec vel fringilla ante. Aenean finibus velit id urna vehicula, nec maximus est sollicitudin</p> |
| </div> |
| <div class="tab-pane p-4" id="nav-parentId-3" role="tabpanel" aria-labelledby="nav-tab-3" tabindex="0"> |
| <p>Quisque sagittis non ex eget vestibulum</p> |
| </div> |
| </div> |
| </div>`, |
| afterDrop: function(node) { |
| |
| let parentId = Math.ceil(Math.random() * 1000); |
| node.id = 'tabs-' + parentId; |
| node.innerHTML = node.innerHTML.replaceAll('parentId', parentId); |
|
|
| return node; |
| }, |
| properties: [{ |
| |
| key: "list", |
| component: "elements/tab", |
| children :[{ |
| component: "elements/tab", |
| name: "html/gridcolumn", |
| classesRegex: ["col-"], |
| }], |
| inline:false, |
| inputtype: ListInput, |
| data: { |
| selector:"> .nav-link", |
| container:"nav > .nav-tabs", |
| prefix:"Tab ", |
| name: "text", |
| removeElement: false, |
| |
| }, |
| onChange: function(node, value, input, component, event) { |
| let element = node; |
| let tabsId = element.id.replace('tabs-',''); |
| |
| let nav = node.querySelector("nav .nav-tabs"); |
| let content = node.querySelector(".tab-content"); |
|
|
| if (event.action) { |
| if (event.action == "add") { |
| let random = Math.floor(Math.random() * 100) + 1; |
| let index = nav.childElementCount + 1; |
| |
| nav.append(generateElements(`<button class="nav-link" id="nav-tab-${tabsId}-${index}-${random}" data-bs-toggle="tab" data-bs-target="#tab-${tabsId}-${index}-${random}" type="button" role="tab" aria-controls="tab-${index}-${random}" aria-selected="false">Tab ${index}</button>`)[0]); |
| |
| content.append(generateElements(`<div class="tab-pane p-4" id="tab-${tabsId}-${index}-${random}" role="tabpanel" aria-labelledby="tab-${tabsId}-${index}-${random}" tabindex="0"><p>Never think of results, just do!</p></div>`)[0]); |
| |
| |
| Vvveb.Components.render("elements/tabs"); |
| } |
| |
| let index = event.index + 1; |
| if (event.action == "remove") { |
| nav.querySelector("button:nth-child(" + index + ")").remove(); |
| content.querySelector(".tab-pane:nth-child(" + index + ")").remove(); |
| } else if (event.action == "select") { |
| let tab = nav.querySelector("button:nth-child(" + index + ")"); |
| Vvveb.Builder.iframe.contentWindow.bootstrap.Tab.getOrCreateInstance(tab).show(); |
| } |
| } |
| |
| return node; |
| }, |
| } |
| ] |
| }); |
|
|
|
|
| |
| Vvveb.Components.add("elements/accordion", { |
| classes: ["accordion"], |
| name: "Accordeon", |
| image: "icons/accordion.svg", |
| html: `<div class="accordion" id="accordion-parentId"> |
| <div class="accordion-item"> |
| <h2 class="accordion-header" id="headingOne-parentId"> |
| <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne-parentId" aria-expanded="true" aria-controls="collapseOne-parentId"> |
| Accordion Item #1 |
| </button> |
| </h2> |
| <div id="collapseOne-parentId" class="accordion-collapse collapse show" aria-labelledby="headingOne-parentId" data-bs-parent="#accordion-parentId"> |
| <div class="accordion-body"> |
| <p>Mauris viverra cursus ante laoreet eleifend. Donec vel fringilla ante. Aenean finibus velit id urna vehicula, nec maximus est sollicitudin</p> |
| </div> |
| </div> |
| </div> |
| <div class="accordion-item"> |
| <h2 class="accordion-header" id="headingTwo-parentId"> |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo-parentId" aria-expanded="false" aria-controls="collapseTwo"> |
| Accordion Item #2 |
| </button> |
| </h2> |
| <div id="collapseTwo-parentId" class="accordion-collapse collapse" aria-labelledby="headingTwo-parentId" data-bs-parent="#accordion-parentId"> |
| <div class="accordion-body"> |
| <p>Mauris viverra cursus ante laoreet eleifend. Donec vel fringilla ante. Aenean finibus velit id urna vehicula, nec maximus est sollicitudin</p> |
| </div> |
| </div> |
| </div> |
| <div class="accordion-item"> |
| <h2 class="accordion-header" id="headingThree-parentId"> |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree-parentId" aria-expanded="false" aria-controls="collapseThree"> |
| Accordion Item #3 |
| </button> |
| </h2> |
| <div id="collapseThree-parentId" class="accordion-collapse collapse" aria-labelledby="headingThree-parentId" data-bs-parent="#accordion-parentId"> |
| <div class="accordion-body"> |
| <p>Mauris viverra cursus ante laoreet eleifend. Donec vel fringilla ante. Aenean finibus velit id urna vehicula, nec maximus est sollicitudin</p> |
| </div> |
| </div> |
| </div> |
| </div>`, |
| afterDrop: function(node) { |
| |
| let parentId = Math.ceil(Math.random() * 1000); |
| |
| node.id = 'accordion-' + parentId; |
| node.innerHTML = node.innerHTML.replaceAll('parentId', parentId); |
| |
| return node; |
| }, |
| properties: [{ |
| |
| key: "list", |
| component: "elements/tab", |
| inline:false, |
| inputtype: ListInput, |
| data: { |
| selector:":scope > .accordion-item", |
| container:"", |
| prefix:"Item ", |
| name: "text", |
| nameElement: ".accordion-button", |
| removeElement: false, |
| |
| }, |
| onChange: function(node, value, input, component, event) { |
| let element = node; |
| let accordionId = element.id.replace('accordion-',''); |
| |
| if (event.action) { |
| if (event.action == "add") { |
| let random = Math.floor(Math.random() * 100) + 1; |
| let index = element.childElementCount + 1; |
| |
| node.append(generateElements(`<div class="accordion-item"> |
| <h2 class="accordion-header" id="heading-${index}-${random}"> |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-${index}-${random}" aria-expanded="false" aria-controls="collapseTwo">Accordion Item #${index}</button> |
| </h2> |
| <div id="collapse-${index}-${random}" class="accordion-collapse collapse" aria-labelledby="heading-${index}-${random}" data-bs-parent="#accordion-${accordionId}"> |
| <div class="accordion-body"> |
| <p>Begin with the possible; begin with one step.</p> |
| </div> |
| </div> |
| </div>`)[0]); |
| |
| |
| Vvveb.Components.render("elements/accordion"); |
| } |
| |
| let index = (event.index + 1); |
| if (event.action == "remove") { |
| node.querySelector(":scope > .accordion-item:nth-child(" + index + ")").remove(); |
| } else if (event.action == "select") { |
| let el = node.querySelector(":scope > .accordion-item:nth-child(" + index + ")"); |
| let btn= el.querySelector(".accordion-button"); |
| let collapse = el.querySelector(" .collapse"); |
|
|
| node.querySelectorAll(":scope > .accordion-item .collapse").forEach(e => e.classList.remove("show")); |
| node.querySelectorAll(":scope > .accordion-item .accordion-button").forEach(btn => btn.classList.add("collapsed")); |
| collapse.classList.add("show"); |
| btn.classList.remove("collapsed"); |
| |
| |
| } |
| } |
| |
| return node; |
| }, |
| },{ |
| name: "Flush", |
| key: "flush", |
| htmlAttr: "class", |
| validValues: ["accordion-flush"], |
| inputtype: ToggleInput, |
| data: { |
| on: "accordion-flush", |
| off: "" |
| } |
| }, |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/flip-box", { |
| classes: ["flip-box"], |
| name: "Flip box", |
| image: "icons/flipbox.svg", |
| html: `<div class="flip-box enabled"> |
| <div class="flip-box-inner"> |
| <div class="flip-box-front"> |
| <div class="card"> |
| <img src="../../media/posts/1.jpg" class="card-img-top" alt="Post"> |
| <div class="card-body"> |
| <h5 class="card-title">Card title</h5> |
| <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> |
| <a href="#" class="btn btn-primary">Go somewhere</a> |
| </div> |
| </div> |
| </div> |
| |
| <div class="flip-box-back"> |
| <div class="d-flex align-items-center flex-column"> |
| <div class="flex-shrink-0"> |
| <img src="../../media/posts/2.jpg" alt="Post"> |
| </div> |
| <div class="flex-grow-1 ms-3"> |
| <p> |
| This is some content from a media component. You can replace this with any content and adjust it as needed. |
| </p> |
| |
| <a href="#" class="btn btn-primary">Go somewhere</a> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div>`, |
| properties: [{ |
| name: "Width", |
| key: "width", |
| htmlAttr: "style", |
| inputtype: CssUnitInput |
| },{ |
| name: "Height", |
| key: "height", |
| htmlAttr: "style", |
| inputtype: CssUnitInput |
| },{ |
| name: "Enabled", |
| key: "enabled", |
| htmlAttr: "class", |
| validValues: ["enabled"], |
| inputtype: ToggleInput, |
| data: { |
| on: "enabled", |
| off: "" |
| } |
| },{ |
| name: "Show back", |
| key: "back", |
| htmlAttr: "class", |
| validValues: ["back"], |
| inputtype: ToggleInput, |
| data: { |
| on: "back", |
| off: "" |
| } |
| }, |
| { |
| name: "Vertical", |
| key: "vertical", |
| htmlAttr: "class", |
| validValues: ["vertical"], |
| inputtype: ToggleInput, |
| data: { |
| on: "vertical", |
| off: "" |
| } |
| }, |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/counter", { |
| nodes: [".counter"], |
| name: "Counter", |
| image: "icons/stopwatch.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/testimonial", { |
| nodes: [".counter"], |
| name: "Testimonial", |
| image: "icons/testimonial.svg", |
| html: `<blockquote cite="https://en.wikipedia.org/wiki/Marcus_Aurelius"> |
| <p>Today I shall be meeting with interference, ingratitude, insolence, disloyalty, ill-will, and selfishness all of them due to the offenders' ignorance of what is good or evil.</p> |
| <cite class="small"> |
| <a href="https://en.wikipedia.org/wiki/Marcus_Aurelius" class="text-decoration-none" target="blank">Marcus Aurelius</a> |
| </cite> |
| </blockquote>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/social-icons", { |
| classes: ["social-icons"], |
| name: "Social icons", |
| image: "icons/social-icons.svg", |
| html: `<ul class="social-icons list-unstyled"> |
| <li> |
| <a href="https://facebook.com"> |
| <i class="lab la-facebook-f la-2x"></i> <span>Facebook</span> |
| </a> |
| </li> |
| <li> |
| <a href="https://linkedin.com"> |
| <i class="lab la-linkedin-in la-2x"></i> <span>Linkedin</span> |
| </a> |
| </li> |
| <li> |
| <a href="https://twitter.com"> |
| <i class="lab la-twitter la-2x"></i> <span>Twitter</span> |
| </a> |
| </li> |
| <li> |
| <a href="https://instagram.com"> |
| <i class="lab la-instagram la-2x"></i> <span>Instagram</span> |
| </a> |
| </li> |
| <li> |
| <a href="https://github.com"> |
| <i class="lab la-github la-2x"></i> <span>Github</span> |
| </a> |
| </li> |
| </ul>`, |
| properties: [{ |
| |
| key: "list", |
| |
| inline:false, |
| inputtype: ListInput, |
| data: { |
| selector:"> li", |
| container:"", |
| prefix:"Item ", |
| name: "text", |
| nameElement: "span", |
| removeElement: true, |
| |
| }, |
| onChange: function(node, value, input, component, event) { |
| let element = node; |
|
|
| if (event.action) { |
| if (event.action == "add") { |
| node.append(generateElements(`<li> |
| <a href="https://twitter.com"> |
| <i class="lab la-twitter la-2x"></i> <span>Twitter</span> |
| </a> |
| </li>`)[0]); |
| |
| |
| Vvveb.Components.render("elements/social-icons"); |
| } |
| if (event.action == "remove") { |
| node.querySelector(":scope > li:nth-child(" + event.index + ")").remove(); |
| } else if (event.action == "select") { |
| let el = node.querySelector(":scope > li:nth-child(" + event.index + ")"); |
| |
| |
| } |
| } |
| |
| return node; |
| }, |
| },{ |
| name: "Inline", |
| key: "list-inline", |
| htmlAttr: "class", |
| validValues: ["list-inline"], |
| inputtype: ToggleInput, |
| data: { |
| on: "list-inline", |
| off: "" |
| } |
| },{ |
| name: "Unstyled", |
| key: "list-unstyled", |
| htmlAttr: "class", |
| validValues: ["list-unstyled"], |
| inputtype: ToggleInput, |
| data: { |
| on: "list-unstyled", |
| off: "" |
| } |
| }] |
| }); |
|
|
| function carouselAfterDrop(node) { |
| |
| body = Vvveb.Builder.frameBody; |
|
|
| if (!body.querySelector("#swiper-js")) { |
| let link = document.createElement('link'); |
| let lib = document.createElement('script'); |
| let code = document.createElement('script'); |
| link.href = '../../libs/swiper/swiper-bundle.min.css'; |
| link.id = 'swiper-css'; |
| link.rel = 'stylesheet'; |
| lib.id = 'swiper-js'; |
| lib.type = 'text/javascript'; |
| lib.src = '../../libs/swiper/swiper-bundle.min.js'; |
| code.type = 'text/javascript'; |
| code.text = ` |
| let swiper = []; |
| function initSwiper(onlyNew = false) { |
| if (typeof Swiper == "undefined") return; |
| let list = document.querySelectorAll('.swiper' + (onlyNew ? ":not(.swiper-initialized)" : "") ); |
| list.forEach(el => { |
| let params = { |
| navigation: { |
| nextEl: ".swiper-button-next", |
| prevEl: ".swiper-button-prev", |
| }, |
| pagination: { |
| el: ".swiper-pagination", |
| }, |
| }; |
| for (i in el.dataset) { |
| let param = el.dataset[i]; |
| if (param[0] = '{') { |
| param = JSON.parse(param); |
| } |
| params[i] = param; |
| } |
| swiper.push(new Swiper(el, params)) |
| //swiper.push(new Swiper(el, { ...{autoplay:{delay: 500}}, ...el.dataset})) |
| }); |
| } |
| |
| if (document.readyState !== 'loading') { |
| initSwiper(); |
| } else { |
| document.addEventListener('DOMContentLoaded', initSwiper); |
| }`; |
| |
| body.appendChild(link); |
| body.appendChild(lib); |
| body.appendChild(code); |
| |
| lib.addEventListener('load', function() { |
| Vvveb.Builder.iframe.contentWindow.initSwiper(); |
| }); |
| } else { |
| Vvveb.Builder.iframe.contentWindow.initSwiper(true); |
| } |
| |
| return node; |
| }; |
|
|
| Vvveb.Components.add("elements/carousel", { |
| name: "Carousel", |
| image: "icons/carousel.svg", |
| classes: ["swiper"], |
| html: ` |
| <div class="swiper" data-slides-per-view="3" data-draggable="true"> |
| <div class="swiper-wrapper"> |
| <div class="swiper-slide"><img src="/media/4.jpg" class="img-fluid"><p>Slide 1</p></div> |
| <div class="swiper-slide"><img src="/media/2.jpg" class="img-fluid"><p>Slide 2</p></div> |
| <div class="swiper-slide"><img src="/media/5.jpg" class="img-fluid"><p>Slide 3</p></div> |
| <div class="swiper-slide"><img src="/media/7.jpg" class="img-fluid"><p>Slide 4</p></div> |
| </div> |
| <div class="swiper-pagination"></div> |
| |
| <!-- |
| <div class="swiper-button-prev"></div> |
| <div class="swiper-button-next"></div> |
| --> |
| |
| <!-- <div class="swiper-scrollbar"></div> --> |
| </div> |
| `, |
| afterDrop: carouselAfterDrop, |
| |
| onChange: function (node, property, value) { |
| let element = node; |
| if (property.key == "autoplay" && value == true) { |
| value = {"waitForTransition":true,"enabled":value,"delay":element.dataset.delay}; |
| } |
|
|
| element.swiper.params[property.key] = value; |
| element.swiper.originalParams[property.key] = value; |
| element.swiper.update(); |
| return node; |
| }, |
|
|
| properties: [{ |
| name: "Slides", |
| key: "slidesPerView", |
| inputtype: ListInput, |
| htmlAttr:"data-slides-per-view", |
| inline:true, |
| data: { |
| selector:".swiper-slide", |
| container:".swiper-wrapper", |
| prefix:"Slide ", |
| removeElement: false, |
| |
| }, |
| onChange: function(node, value, input, component, event) { |
| let element = node; |
| let dataset = {}; |
| for (i in element.dataset) { |
| dataset[i] = element.dataset[i]; |
| }; |
|
|
| if (event.action) { |
| if (event.action == "add") { |
| let random = Math.floor(Math.random() * 6) + 1; |
| let index = element.swiper.slides.length + 1; |
| element.swiper.appendSlide(generateElements(`<div class="swiper-slide"><img src="../../media/posts/${random}.jpg" class="img-fluid"><p>Slide ${index}</p></div>`)[0]); |
| element.swiper.slideTo(index); |
| |
| Vvveb.Components.render("elements/carousel"); |
| } |
| if (event.action == "remove") { |
| element.swiper.removeSlide(event.index); |
| } else if (event.action == "select") { |
| element.swiper.slideTo(event.index, 300, true); |
| } |
| } |
| |
| setTimeout(function () { |
| for (i in dataset) { |
| element.swiper.params[i] = dataset[i]; |
| element.dataset[i] = dataset[i]; |
| }; |
| element.swiper.update(); |
| }, 1000); |
| |
| return node; |
| }, |
| },{ |
| name: "Slides per view", |
| key: "slidesPerView", |
| inputtype: NumberInput, |
| htmlAttr:"data-slides-per-view", |
| },{ |
| name: "Space between", |
| key: "spaceBetween", |
| inputtype: NumberInput, |
| htmlAttr:"data-space-between", |
| },{ |
| name: "Speed", |
| key: "speed", |
| inputtype: NumberInput, |
| htmlAttr:"data-speed", |
| data: {step:100}, |
| },{ |
| name: "Delay", |
| key: "delay", |
| inputtype: NumberInput, |
| htmlAttr:"data-delay", |
| data: {step:100}, |
| },{ |
| key: "carousel_options", |
| inputtype: SectionInput, |
| name:false, |
| data: {header:"Options"}, |
| },{ |
| name: "Simulate touch", |
| key: "simulateTouch", |
| htmlAttr:"data-simulate-touch", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ |
| name: "Autoplay", |
| key: "autoplay", |
| htmlAttr:"data-autoplay", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ |
| name: "Auto height", |
| key: "autoHeight", |
| htmlAttr:"data-auto-height", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ |
| name: "Centered slides", |
| key: "centeredSlides", |
| htmlAttr:"data-centered-slides", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ name: "Center insufficient", |
| key: "centerInsufficientSlides", |
| htmlAttr:"data-center-insufficient-slides", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ name: "Loop", |
| key: "loop", |
| htmlAttr:"data-loop", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ name: "Mouse wheel", |
| key: "mousewheel", |
| htmlAttr:"data-mousewheel", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ |
| name: "Pagination", |
| key: "pagination", |
| htmlAttr:"data-pagination", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ name: "Rewind", |
| key: "rewind", |
| htmlAttr:"data-rewind", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| },{ name: "Scrollbar", |
| key: "scrollbar", |
| htmlAttr:"data-scrollbar", |
| inputtype: CheckboxInput, |
| inline:true, |
| col:4 |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ] |
| }); |
|
|
| |
| Vvveb.Components.add("elements/slider", { |
| name: "Slider", |
| image: "icons/slider.svg", |
| html: ` |
| <div class="swiper" data-slides-per-view="1" data-draggable="true" data-navigation='{"nextEl": ".swiper-button-next","prevEl": ".swiper-button-prev"}'> |
| <div class="swiper-wrapper"> |
| <div class="swiper-slide"><img src="/media/posts/1.jpg" class="img-fluid"><p>Slider 1</p></div> |
| <div class="swiper-slide"><img src="/media/posts/2.jpg" class="img-fluid"><p>Slider 2</p></div> |
| <div class="swiper-slide"><img src="/media/posts/3.jpg" class="img-fluid"><p>Slider 3</p></div> |
| <div class="swiper-slide"><img src="/media/posts/4.jpg" class="img-fluid"><p>Slider 4</p></div> |
| </div> |
| <div class="swiper-pagination"></div> |
| |
| <div class="swiper-button-prev"></div> |
| <div class="swiper-button-next"></div> |
| |
| <!-- <div class="swiper-scrollbar"></div> --> |
| </div> |
| `, |
| afterDrop: carouselAfterDrop, |
| }); |
|
|
|
|
| Vvveb.Components.add("elements/icon-list", { |
| nodes: [".counter"], |
| name: "Icon list", |
| image: "icons/icon-list.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/divider", { |
| nodes: [".counter"], |
| name: "Divider", |
| image: "icons/stopwatch.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/separator", { |
| nodes: [".counter"], |
| name: "Separator", |
| image: "icons/separator.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/Image box", { |
| nodes: [".counter"], |
| name: "Image Box", |
| image: "icons/stopwatch.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/Icon box", { |
| nodes: [".counter"], |
| name: "Image Box", |
| image: "icons/stopwatch.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/animated-headline", { |
| nodes: [".counter"], |
| name: "Animated headline", |
| image: "icons/dots_three.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/price-table", { |
| nodes: [".counter"], |
| name: "Price table", |
| image: "icons/price-table.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/price-list", { |
| nodes: [".counter"], |
| name: "Price list", |
| image: "icons/stopwatch.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/reviews", { |
| nodes: [".counter"], |
| name: "Reviews", |
| image: "icons/reviews.svg", |
| html: `<i class="font-icon la la-star"></i>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/code", { |
| nodes: ["code"], |
| name: "Code", |
| image: "icons/code.svg", |
| html: `<code>print "Hello world!"</code>`, |
| properties: [{ |
| name: "Text", |
| key: "text", |
| inline:false, |
| htmlAttr: "innerHTML", |
| inputtype: TextareaInput, |
| data:{ |
| rows:20, |
| } |
| }] |
| }); |
| |
| Vvveb.Components.add("elements/image-compare", { |
| nodes: [".counter"], |
| name: "Image Compare", |
| image: "icons/image-compare.svg", |
| html: `<div class="c-compare" style="--value:50%;"> |
| <img class="c-compare__left" src="img/color.jpg" alt="" /> |
| <img class="c-compare__right" src="img/bw.jpg" alt="" /> |
| </div>`, |
| properties: [ |
| ] |
| }); |
|
|
| Vvveb.Components.add("elements/rating", { |
| nodes: [".rating"], |
| name: "Rating stars", |
| image: "icons/rating.svg", |
| html: `<div class="rating"> |
| <i class="la la-star text-warning"></i> |
| <i class="la la-star text-warning"></i> |
| <i class="la la-star text-warning"></i> |
| <i class="la la-star text-warning"></i> |
| <i class="la la-star text-secondary"></i> |
| </div>`, |
| properties: [ |
| ] |
| }); |
|
|