Traits serve as the fundamental elements for customizing the sidebar of the Visual Builder for the selected component. They empower developers to tailor the sidebar of the Visual Builder for a specific component, unlocking endless possibilities for customization.

Categories of Traits

Experro-Storefront provides you with two categories of traits: 1. Default traits 2. Customizable traits

Category 1 - Default traits

Default traits are the simplest and most straightforward method to generate the sidebar of the Visual Builder for a specific component. Experro-Storefront offers a wide range of default traits. As follows:
  1. TEXT The text trait is utilized to render a textbox on the sidebar of the Visual Builder. This trait allows you to access the value entered in the textbox as a prop within your component.
You can use this trait by following the example shown below:
import { Widget } from 'experro-storefront';
import { CustomComponent } from '../../custom-component';

const CustomComponentWidget = Widget.createWidget({
  component: CustomComponent,
  label:"<div  class='gjs-fonts gjs-f-b1 custom-widget'>Example Component</div>",
  category: 'Basic Components',
  content: '<CustomComponent/>',
  widgetName: 'CustomComponent',
  widgetProperties: {
    defaults: {
      name: 'Example Component',
      attributes: {
        exampleText: '',
      },
      activeOnRender: true,
      traits: [
        {
          type: 'text',
          label: 'Example text',
          name: 'exampleText',
        }
      ]
    },
  },
});

export default CustomComponentWidget;
As shown in the example above, an array of traits has been added in the widget file of the component. Within that array, an object is included. The type property is used to display the trait on the sidebar, the label property represents the label for the corresponding element, and the name property is utilized to access the value inside the component.
To access the value of the trait within the component, it is essential to pass the name attribute in the widget’s attributes. Failure to include the name attribute will result in the inability to retrieve the trait’s value in the component.
  1. NUMBER The number trait is utilized to render a number input on the sidebar of the Visual Builder.
traits: [
 {
   type: 'number',
   label: 'Example number',
   name: 'exampleNumber',
 }
]
  1. CHECKBOX The checkbox trait is used to render a checkbox on the sidebar of the Visual Builder.
traits: [
 {
   type: 'checkbox',
   label: 'Example Value',
   name: 'exampleValue',
   valueTrue: 'yes',
   valueFalse: 'no',
 }
]
  1. SELECT The checkbox trait is used to render a drop down on the sidebar of the Visual Builder.
traits: [
  {
    type: 'select',
    label: 'options',
    name: 'options',
    options: [
      { id: 'opt1', name: 'Option 1'},
      { id: 'opt2', name: 'Option 2'},
    ]
  }
]

Category 2 - Customizable traits

Customizable traits share similarities with default traits but provide additional features and functionalities. The implementation process for customizable traits is a bit different. Customizable traits inherit all the types from default traits and include the following additional types.
  1. TEXT The Customizable text trait is the same as the default trait text, but with some additional features. We will disclose those features further in this section.
To use a customizable trait, please refer to the example below:
const configObj = {
  headingText: '',
  traitConfig: [
    {
      type: 'exp_text',
      internalName: 'headingText',
      displayName: 'Heading Text',
    },
  ]
}

const CustomComponentWidget = Widget.createWidget({
  component: CustomComponent,
  label:"<div class='gjs-fonts gjs-f-b1 custom-widget'>Custom Component</div>",
  category: 'Basic Components',
  content: '<CustomComponent/>',
  widgetName: 'CustomComponent',
  widgetProperties: {
    defaults: {
      name: 'Custom Component',
      attributes: {
        component_content: JSON.stringify(configObj);
      },
      activeOnRender: true,
      traits: [
        {
          type: 'experro-storefront',
          name: 'component_content',
        },
      ],
    },
  },
});
As discussed in the documentation for creating a custom component using free form, it is necessary to include a configObj in the widget file of your custom component. Subsequently, you should pass the stringified version of that object as the component_content attribute when defining the component’s attributes. In addition to that, we need to include a trait array, as shown in the example above.
  1. TEXT AREA The TEXT AREA trait works the same as the TEXT trait; the only difference is that it renders a text area.
const configObj = {
  descriptionText: '',
  traitConfig: [
    {
      type: 'exp_textArea',
      internalName: 'descriptionText',
      displayName: 'Description Text',
    },
  ]
}
  1. CHECKBOX The CHECKBOX trait is used to render a checkbox on the sidebar of the UI builder.
const configObj = {
  check: '',
  traitConfig: [
    {
      type: 'exp_checkbox',
      displayName: 'Check',
      internalName: 'check',
    },
  ]
}
  1. COLOR PICKER The Color picker trait is used to add a color picker to the sidebar of the UI builder.
const configObj = {
  headingColor: '#191919',
    traitConfig: [
    {
      type: 'exp_colorPicker',
      internalName: 'headingColor',
      displayName: 'Heading Color',
      defaultValue: '#191919',
    },
  ],
}
  1. DROPDOWN This trait is used to render a dropdown on the side bar of the UI builder.
const configObj = {
  headingSize: '',
    traitConfig: [
    {
      type: 'exp_dropDown',
      displayName: 'Heading size',
      internalName: 'headingSize',
      options: [
        { name: 'Heading 1', value: 'h1' },
        { name: 'Heading 2', value: 'h2' },
        { name: 'Heading 3', value: 'h3' },
        { name: 'Heading 4', value: 'h4' },
        { name: 'Heading 5', value: 'h5' },
        { name: 'Heading 6', value: 'h6' },
      ],
    },
  ],
}
  1. DATA SOURCE DROPDOWN If you want to integrate data support from both the Content Library and Free form into your component, then you can use the data source dropdown trait.
This trait will render a dropdown on the sidebar of the UI builder with two options:
  1. Free From
  2. Content Library
const configObj = {
  dataSource: '',
  traitConfig: [
    {
      type: 'exp_dataSourceDropDown',
    },
  ]
}
There will be no internalName property for this trait. You can access the value from this trait using the fixed key dataSource.
  1. CONTENT MODEL POPUP If you want to use or integrate data from the contentLibrary, the CONTENT MODAL POPUP trait is required to display the list of records on the sidebar of the UI builder for that component.
const configObj = {
  modelInternalName: 'internal_name_for_component',
  traitConfig: [
    {
      type: 'exp_contentModalPopUp',
      modelInternalName: 'internal_name_for_component',
    }
  ]
}
One need to add the modelInternName of the component in its config, as shown in the above code snippet.
  1. IMAGE SELECTOR The IMAGE SELECTOR trait is used to add an image selector to the sidebar of the UI builder.
const configObj = {
  internalName: 'internal_name_for_component',
  traitConfig: [
     {
      type: 'exp_imageSelector',
      internalName: 'imageData',
      dependent: 'dataSource',
      subDependency: 'freeForm'
    }
  ]
}
CONDITIONAL RENDER A TRAIT You can also render a trait conditionally, which means that you can choose to display a trait only when there is a value in another trait. Just follow the example below.
const configObj = {
  descriptionText: '',
  traitConfig: [
     {
      type: 'exp_textArea',
      internalName: 'titleText',
      displayName: 'Title Text',
    },
    {
      type: 'exp_textArea',
      internalName: 'descriptionText',
      displayName: 'Description Text',
      dependent: 'titleText',
    }
  ]
}
In the above example, there is a property called dependent in the traitConfig. In the dependent property, you can see that the internalName of the above object is given. This means that the description text trait will only be rendered when there is a value in title text.
const configObj = {
  descriptionText: '',
  traitConfig: [
     {
      type: 'exp_textArea',
      internalName: 'titleText',
      displayName: 'Title Text',
    },
    {
      type: 'exp_textArea',
      internalName: 'descriptionText',
      displayName: 'Description Text',
      dependent: 'titleText',
      subDependency: 'example,
    }
  ]
}
In the above example, you can see one more property called ‘subDependency’. This example indicates that the descriptionText trait is dependent on titleText and will only render when the value of titleText is exactly the same as the value specified in the subDependency flag.