Basics
Custom Element
js
import {
TypeField,
NameField,
LabelField,
InfoField,
DescriptionField,
ContentField,
BeforeField,
BetweenField,
AfterField,
SizeField,
ColumnsField,
ConditionsField,
} from '@vueform/builder'
import ShareUrlField from './path/to/ShareUrlField.js'
export default {
categories: [],
elements: [
'facebookShare',
],
element: {
types: {
facebookShare: {
label: 'Facebook share',
description: 'Facebook share button',
icon: 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z"/></svg>',
// category: 'static',
schema: {
type: 'facebook-share',
},
sections: {
properties: {
name: 'properties',
label: 'Properties',
fields: {
type: { type: TypeField },
name: { type: NameField },
label: { type: LabelField },
tooltip: { type: InfoField },
description: { type: DescriptionField },
},
},
options: {
name: 'options',
label: 'Options',
fields: {
url: { type: ShareUrlField },
},
},
decorators: {
name: 'decorators',
label: 'Decorators',
fields: {
before: { type: BeforeField },
between: { type: BetweenField },
after: { type: AfterField },
},
},
layout: {
name: 'layout',
label: 'Layout',
fields: {
size: { type: SizeField },
columns: { type: ColumnsField },
},
},
conditions: {
name: 'conditions',
label: 'Conditions',
fields: {
conditions: { type: ConditionsField },
},
},
},
},
separators: {
properties: [
['type', 'name'],
['label', 'tooltip'],
['description'],
],
layout: [
['size'],
['columns'],
],
},
}
}
}
js
import FacebookShareElement from './path/to/FacebookShareElement.vue'
export default {
elements: [
FacebookShareElement,
],
// ...
}
vue
<template>
<ElementLayout>
<template #element>
<div
:class="classes.button"
@click="handleClick"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z"/></svg>
Share on Facebook
</div>
</template>
<!-- Default element slots -->
<template v-for="(component, slot) in elementSlots" #[slot]><slot :name="slot" :el$="el$"><component :is="component" :el$="el$"/></slot></template>
</ElementLayout>
</template>
<script>
import { ref, toRefs } from 'vue'
import VueformElement from '@vueform/vueform/element'
export default VueformElement({
name: 'FacebookShareElement',
props: {
url: {
type: String,
required: false,
default: null,
}
},
}, {
setup(props, { element })
{
const { url } = toRefs(props)
// ================ DATA ================
const defaultClasses = ref({
container: '',
button: 'facebook-share-button',
button_sm: 'facebook-share-button-sm',
button_md: 'facebook-share-button-md',
button_lg: 'facebook-share-button-lg',
$button: (classes, { Size }) => ([
classes.button,
classes[`button_${Size}`],
])
})
// =============== METHODS ==============
const handleClick = () => {
alert(!url?.value ? 'No Share URL provided. Open the element config panel in editor mode and provide a Share URL.' : `Share URL:\n\n${url.value}`)
}
return {
defaultClasses,
handleClick,
}
}
})
</script>
<style lang="scss">
.facebook-share-button {
background-color: #4267B2;
color: #ffffff;
font-weight: 600;
display: inline-flex;
align-items: center;
justify-content: flex-start;
border-radius: 0.25rem;
cursor: pointer;
transition: background .3s;
&:hover {
background-color: #5278c6;
}
svg {
margin-right: 0.375rem;
}
&.facebook-share-button-sm {
font-size: var(--vf-font-size-sm);
padding: 0.125rem 0.75rem 0.125rem 0.5rem;
svg {
width: var(--vf-font-size-sm);
height: var(--vf-font-size-sm);
}
}
&.facebook-share-button-md {
font-size: var(--vf-font-size);
padding: 0.25rem 1rem 0.25rem 0.75rem;
svg {
width: var(--vf-font-size);
height: var(--vf-font-size);
}
}
&.facebook-share-button-lg {
font-size: var(--vf-font-size-lg);
padding: 0.375rem 1.25rem 0.375rem 1rem;
svg {
width: var(--vf-font-size-lg);
height: var(--vf-font-size-lg);
}
}
}
</style>
js
import { BaseElementField } from '@vueform/builder'
export default class ShareUrlField extends BaseElementField
{
name = 'ShareUrlField'
get schema () {
return {
url: {
type: 'textarea',
label: 'Share URL',
columns: { label: 4 },
floating: false,
placeholder: 'https://...',
presets: ['prop-multiline'],
rows: 1,
onMounted(el$) {
setTimeout(() => {
el$.autosize()
}, 0)
},
},
}
}
}