Create your first custom Element
A good first exercise will be to create a simple Hello World Element — as if you didn’t see that one coming!

Step 1 - Create a new Element

  • Click on New Element in the Welcome Screen.

Step 2 - Give it a name

You will be taken to a vev-manifest.json file, which has a nice UI so you don’t have to edit it in raw text (and potentially get some values wrong
).

Step 3 - Build and run (already!)

After clicking Run, you should see the Element Preview update accordingly
Once you click on the Run button, you will see a preview in the right panel.
Great — You’ve already created, compiled, and previewed the default custom code Element in Vev!

Wait, where do I actually write code?

You’re right. The above still technically doesn’t qualify as a proper Hello World example. Let’s take a look and figure out how to make it so (and show you around in the process).

Files & Dependencies

When you create an Element we create the necessary files for that Element to function (and for you to change it). These files include:
  • ElementName (Folder)
    • form.tsx - Contains the code to render the Elements data form (opened by double-clicking on your Element in the Design Editor mode)
    • index.tsx - Contains the code to render the Element. This file needs to export a function or instance of React.Component.
    • styles.scss - Your Elements stylesheet. The .scss filename just means we’re using the Sassy CSS syntax, which is the main syntax for Syntactically Awesome Style Sheets. You can write normal CSS here as well, but Sassy CSS offers so much more. Read more in File: styles.scss.
    • vev-manifest.json - Configuration file for the Element. Settings to adjust name, description, readme, default sizes, icons, and more.
  • package.json - Configuration file for your Element Package. Contains the name for your group of Elements and access/sharing settings.
Read more about the Developer File Structure.

Time to do some custom coding!

To see the code for your new Element, click on index.tsx.

The Index File

Once you open your index.tsx file, you will see the default standard code for Elements in Vev.
1
import { Fragment, useState } from 'react';
2
import { useEditorState } from 'vev';
3
4
export default function ({ text }: Props) {
5
const [count, setCount] = useState<number>(0);
6
const { disabled } = useEditorState();
7
return (
8
<Fragment>
9
<h1>{text}</h1>
10
<p>{disabled ? 'Disabled' : 'Enabled'}</p>
11
<p onClick={() => setCount(count + 1)}>Counter {count}</p>
12
</Fragment>
13
);
14
}
Copied!
Let’s strip this down to the bare essentials. Make your index.tsx file look like this:
1
export default function () {
2
return (
3
<h1>Hello World!</h1>
4
);
5
}
Copied!
When rendering your Element on the Canvas, Vev will take your index.tsx default export and run that function for every instance of that Element you have added.
1
export default function() {}
Copied!
You can also write this as one of the following:
1
// name the function
2
export default function MyCustomComponent() {
3
return <h1>Hello World</h1>
4
}
5
// or ES6 arrow function
6
const MyCustomComponent = () => <h1>Hello World</h1>
7
8
// or the old familiar React component way
9
class MyCustomComponent extends React.Component {
10
render () {
11
return <h1>Hello World</h1>
12
}
13
}
Copied!
Click Run to run your code, your widget preview should update and show your “Hello World!”.

Deploy and use your Code

Let’s deploy this as the first version, and remove that background color in the next step. Click on Deploy and write a commit message, such as “Initial commit!”.
Go to your Design Editor and click Insert. Search for your Hello World widget and draw it on the Canvas.

Adjusting the Look

By default, the container which contains your code has your main palette color set as its background-color. This is defined in the styles.scss file, so let’s open that.
the :host {} rule lets you style the container wrapping your Code. The vev()-syntax enables a Style Control for that rule in the Design Editor. $primary3 refers to the Primary Colour #3 in the project’s current palette. Read Using the styles.scss file for more information on the vev()-syntax and available colors and attributes.
Let’s make our Hello World widget look a little bit nicer. Change your styles.scss to the following:
1
:host{
2
// Removed the $primary3 color from the background.
3
// This will make it optional and available in the Design Editor.
4
5
background: vev();
6
display: flex;
7
justify-content: center;
8
align-items: center;
9
}
10
h1 {
11
border-bottom: vev(1px solid #666);
12
}
Copied!
Save your file, you should see your Preview update
Looks a lot nicer already!
Notice that you now have another Selector for your H1. If you go into your design editor, you will be able to adjust the border with a simple editor.

Adding Controls

Sometimes you want to say something different, Hello World doesn’t always cut it. We can make this text editable by giving the Element some controls.
Open your forms.tsx file, and you will see there’s already a TextField added by default.
There are many fields you can use to create your controls, but for now we’ll just add a ToggleField. Change your form.tsx to the following:
1
<TextField name="text" default="Hello World!" />
2
<ToggleField name="uppercase" label="Caps lock?"/>
Copied!
Save your code, and go back into the Design Editor. When you double-click one of the instances of your Element, its controls will appear.
You can try changing the values. They are saved, but nothing is happening. For something to happen, we need to use this data. Vev will send the values from the controls into the function we made in the beginning, in the index.tsx file. Open this file now.
The data, among a few other things, are sent into your function as an argument. If you add the Props type to the argument you can hover over it to see which values are coming in through the props object.
Let’s extract the two variables we need now, and use them in our widget.
The code should now be
1
export default function ({ text, uppercase }: Props) {
2
const cl = [];
3
if(uppercase) cl.push('uppercase');
4
5
// In React, you need to use className= instead of class=
6
// Why? Read: https://reactjs.org/docs/dom-elements.html#classname
7
return (
8
<h1 className={cl.join(' ')}>{text}</h1>
9
);
10
}
Copied!
and change your H1 rule in the styles.scss file to:
1
h1 {
2
border-bottom: vev(1px solid #666);
3
&.uppercase {
4
text-transform: uppercase;
5
}
6
}
Copied!
Go back into the Design Editor, and double-click one of your custom Elements. Toggle the Uppercase on and watch as the text transforms into uppercase.

Make it a Section also

You can make an Element work as a Section too. When it is a section it only takes a height parameter, its width will be 100%.
Open the Code Editor again, and navigate to your vev-manifest.json file. There you will be able to set the Type to be Element, Section, or Both.
Select the “Can be added as both element and section”, and deploy your code.
Remember to Save your file when you make a change (indicated by the white circle next to the filename). Do this with ⌘+S or CTRL+S
Last modified 2mo ago