- First create a file in
/react/components/{filename}
import React from 'react';
function CustomComponent() {
return <div />
}
export default CustomComponent;
- In
/react
root create afile
and import this component
import CustomComponent from '/components/{filename}'
export default CustomComponent;
- Create file
interfaces.json
in the blocks.
{
"custom-component": {
"component": "{FileName [step 2]}"
}
}
- Now you can use this custom in your blocks.
{
"store.home": {
"blocks": ["custom-component"]
}
}
- VTEX provides a tool for editing the components called
Site-Editor
, for that we need to create schema and defaultProps object and the component needs to have props for it to work.
- Create Props
function CustomComponent(props) {
return(
<h1>{props.title}</h1>
);
}
- Create defaultProps and Schema
function CustomComponent(props) {
return(
<h1>{props.title}</h1>
);
}
CustomComponent.defaultProps = {
title: "Title Default"
}
CustomComponent.schema = {
title: "Custom Component",
type: "object",
properties: {
title: {
type: "string",
title: "Change title Props",
default: "Custom Title"
}
}
}
- Now the developer can change props two ways
{
"store.home": {
"blocks": ["custom-component#example"]
},
"custom-component#example": {
"props": {
"title: "Change Title Props"
}
}
}
- There are several types of data and we can use the schema to make it easier to style the component
- The
properties
key is the configuration of component props
- string
- boolean
- object
- array
- Here you can use for
images
,url's
,dates
andtexts
props.
- Images
function CustomComponent({ imageDesktop, imageMobile }) {
return(
<div>
<img src={imageDesktop} />
<img src={imageMobile} />
</div>
);
}
- Now has two options to use: One where the user select in computer files or the user paste de image url link.
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
imageDesktop: {
type: 'string',
title: 'Image Desktop',
default: '',
description: 'Paste the URL'
},
imageMobile: {
title: 'Image Mobile',
default: '',
type: 'string',
widget: { //here you can choose a file in your computer
"ui:widget": "image-uploader"
}
}
}
};
- Dates
function CustomComponent({ initialDate, finalDate }) {
return(
<div>
<p>{initialDate}</p>
<p>{finalDate}</p>
</div>
);
}
- Now has two options to use: One where the user select the date or the user write the date.
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
initialDate: {
type: 'string',
title: 'Initial Date',
default: '',
description: '{year}/{month}/{day}'
},
finalDate: {
title: 'Final Date',
//2022-02-23T02:20:42.074Z
default: new Date().toISOString(), //Set current date in select input
type: 'string',
//to user select a date.
format: 'date-time',
widget: {
"ui:widget": "datetime"
}
}
}
};
- Texts/URL's
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
textOrUrl: {
type: 'string',
title: 'Text or URL',
default: '',
}
}
};
function CustomComponent({ active }) {
if(!active) return;
return(
<div>
<h2>Now the component is active!</h2>
</div>
);
}
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
active: {
type: 'boolean',
title: 'Active Component',
default: true,
}
}
};
function CustomComponent({ image }) {
return(
<div>
<img
src={image.url}
alt={image.alt}
title={image.title}
/>
</div>
);
}
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
image: {
title: 'Image Prop',
type: 'object',
properties: {
url: {
type: 'string',
title: 'Image URL',
description: 'URL image'
},
alt: {
type: 'string',
title: 'Image Text Alternative',
},
title: {
type: 'string',
title: 'Attribute title',
},
}
}
}
};
function CustomComponent({ images }) {
const isMobile = window.innerWidth < 768;
return(
<div>
{
images.map((image, index) => (
<img
alt={image.alt}
key={String(index)}
src={image[isMobile ? 'src' : 'mobileSrc']}
/>
))
}
</div>
);
}
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
images: {
type: 'array',
title: 'Images',
default: [
{
src: '',
alt: 'Text alternative',
mobileSrc: ''
}
],
items: { //item configuration
type: 'object',
title: 'Image',
properties: {
src: {
type: 'string',
title: 'Image SRC',
description: 'Image URL [desktop]'
},
alt: {
type: 'string',
title: 'Image Text Alternative',
description: 'Image URL'
},
mobileSrc: {
type: 'string',
title: 'Image SRC [mobile]',
description: 'Image URL'
},
}
}
}
}
};
- You can change Item array name with
__editorItemTitle
property
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
images: {
type: 'array',
title: 'Images',
default: [
{
src: '',
alt: 'Text alternative',
mobileSrc: ''
}
],
items: { //item configuration
type: 'object',
title: 'Image',
properties: {
__editorItemTitle: { // now change name is available
default: 'Image Item',
title: 'Change item name',
type: 'string'
},
src: {
type: 'string',
title: 'Image SRC',
description: 'Image URL [desktop]'
},
alt: {
type: 'string',
title: 'Image Text Alternative',
description: 'Image URL'
},
mobileSrc: {
type: 'string',
title: 'Image SRC [mobile]',
description: 'Image URL'
},
}
}
}
}
};
- The function of the enum is for the prop to have specific values.
- For example: I've a prop
colors
and the possible values are:red
,blue
orblack
.
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
colors: {
type: 'string',
title: 'Color',
default: 'red',
enum: ['red', 'blue', 'black']
}
}
};
- The function of the enumName is for change names in enum.
- For example: I've a prop
colors
and the possible values are:#0ff102
,#1038c9
or#000000
, but for the user I need to show de names:green
,blue
orblack
- If user select the value
green
, the prop returns#0ff102
const schema = {
title: 'Custom Component',
type: 'object',
properties: {
colors: {
type: 'string',
title: 'Color',
default: 'red',
enumNames: ['green', 'blue', 'black'],
enum: [`#0ff102`,`#1038c9`, `#000000`]
}
}
};
- TypeScript is an open source programming language developed by Microsoft. It is a strict syntactic superset of JavaScript and adds optional static typing to the language.
- For more informations, click here
- With TypeScript we can create our own types to help with development
- Using
react
types.
import React from 'react';
interface Props {
title: string;
};
const CustomComponent: React.FC<Props> = props => {
const { title } = props;
return(
<div>
<h1>{title}</h1>
</div>
);
};
- Using our own types:
declare global {
interface Schema {
title: string;
type: Extract<SchemaType, 'object'>;
properties: SchemaProperties;
dependencies?: SchemaDependencies;
}
}
export type SchemaType = 'array' | 'object' | 'string' | 'boolean' | 'number';
export type UiWidget = 'image-uploader' | 'textarea' | 'datetime' | 'select' | 'color';
export interface SchemaDependencies {
[key: string]: {
oneOf: {
properties: {
[key: string]: Partial<SchemaItemProperty>;
}
}[];
}
}
export interface SchemaProperties {
__editorItemTitle?: {
default: string
title: string
type: Extract<SchemaType, 'string'>
},
[key: string]: SchemaItemProperty;
}
export interface SchemaItemProperty {
type: SchemaType;
enumNames?: string[]; //esse funciona junto com o enum
enum?: string[];
default?: any;
title?: string;
description?: string;
properties?: SchemaProperties;
format?: 'date-time',
widget?: {
"ui:widget"?: UiWidget;
},
items?: {
type: SchemaType;
title?: string;
properties?: SchemaProperties;
default?: any;
}
};
declare global {
interface VTEXCustomComponent<Props ={}> extends FunctionComponent<Props> {
getSchema?: (props: Props) => Schema;
schema?: Schema;
defaultProps?: Props;
}
}
interface Props {
title: string;
};
const CustomComponent: VTEXCustomComponent<Props> = ({ title }) => {
return(
<div>
<h1>{title}</h1>
</div>
);
};
CustomComponent.defaultProps = {
title: 'Default value'
}
CustomComponent.schema = {
title: 'Custom Component',
type: 'object',
properties: {
title: {
type: 'string',
default: 'Default value',
title: 'Title prop'
}
}
};
Raphael Capeto π» |
Gabriel Cintra π» |
Gabriel Martins π» |
Made with π€ by Developers.