Epic Bullet Widget

Mar, 25 2022Epic Bullet Widget

Creating a simple image widget is very easy with bigcommerce "Widget Template" API.
it contains from two main parts:

  1. Schema:

basically schema is group of options that user can pick and chose from, it allow you to customize your layout by making fields values dynamically inserted by the user, then taking that those information from the schema and parse it in template.

bigcommerce support various amount of schema options one of the popular schema options is the "array" type.

arrays are basically a repeatable data that user can add as much as he want and for each one of those we can have as much as customizable data.

[
    {
      "type": "array",
      "label": "Bullets List Item",
      "id": "bullets",
      "defaultCount": 3,
      "entryLabel": "Bullet Item",
      "schema": [
        {
          "type": "tab",
          "label": "Design",
          "sections": [
            {
              "settings": [
                {
                  "type": "input",
                  "label": "Bullet Content",
                  "id": "bullet_content",
                  "default": "Lorem ipsum dolor sit amet, consectetur adipiscing elit , sed do eiusmod tempor incididunt."
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "type": "tab",
      "label": "Design",
      "sections": [
        {
          "label": "Bullets Options",
          "settings": [
            {
              "type": "select",
              "label": "Bullet Type",
              "id": "bulletType",
              "default": "➤",
              "typeMeta": {
                "selectOptions": [
                  {
                    "label": "•",
                    "value": "•"
                  },
                  {
                    "label": "○",
                    "value": "○"
                  },
                  {
                    "label": "➤",
                    "value": "➤"
                  },
                  {
                    "label": "➣",
                    "value": "➣"
                  },
                  {
                    "label": "⮕",
                    "value": "⮕"
                  },
                  {
                    "label": "➔",
                    "value": "➔"
                  },
                  {
                    "label": "✔",
                    "value": "✔"
                  },
                  {
                    "label": "☑",
                    "value": "☑"
                  },
                  {
                    "label": "✘",
                    "value": "✘"
                  }
                ]
              }
            },
            {
              "type": "select",
              "label": "Font weight",
              "id": "fontWeightBullet",
              "default": "700",
              "typeMeta": {
                "selectOptions": [
                  {
                    "label": "Thin",
                    "value": "100"
                  },
                  {
                    "label": "Extra Light (Ultra Light)",
                    "value": "200"
                  },
                  {
                    "label": "Light",
                    "value": "300"
                  },
                  {
                    "label": "Normal",
                    "value": "400"
                  },
                  {
                    "label": "Medium",
                    "value": "500"
                  },
                  {
                    "label": "Semi Bold (Demi Bold)",
                    "value": "600"
                  },
                  {
                    "label": "Bold",
                    "value": "700"
                  },
                  {
                    "label": "Extra Bold (Ultra Bold)",
                    "value": "800"
                  },
                  {
                    "label": "Black (Heavy)",
                    "value": "900"
                  }
                ]
              }
            },
            {
              "type": "number",
              "label": "Font size",
              "id": "fontSizeBullet",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "number",
              "label": "Font size (Tablet)",
              "id": "tabletFontSizeBullet",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "number",
              "label": "Font size (Mobile)",
              "id": "mobileFontSizeBullet",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "color",
              "label": "Text color",
              "id": "fontColorBullet",
              "default": "#000000"
            },
            {
              "type": "boxModel",
              "label": "Padding",
              "id": "paddingBullet",
              "default": {
                "top": {
                  "value": "0",
                  "type": "px"
                },
                "right": {
                  "value": "10",
                  "type": "px"
                },
                "bottom": {
                  "value": "0",
                  "type": "px"
                },
                "left": {
                  "value": "0",
                  "type": "px"
                }
              }
            }
          ]
        },
        {
          "label": "Text Option",
          "settings": [
            {
              "type": "select",
              "label": "Font weight",
              "id": "fontWeight",
              "default": "700",
              "typeMeta": {
                "selectOptions": [
                  {
                    "label": "Thin",
                    "value": "100"
                  },
                  {
                    "label": "Extra Light (Ultra Light)",
                    "value": "200"
                  },
                  {
                    "label": "Light",
                    "value": "300"
                  },
                  {
                    "label": "Normal",
                    "value": "400"
                  },
                  {
                    "label": "Medium",
                    "value": "500"
                  },
                  {
                    "label": "Semi Bold (Demi Bold)",
                    "value": "600"
                  },
                  {
                    "label": "Bold",
                    "value": "700"
                  },
                  {
                    "label": "Extra Bold (Ultra Bold)",
                    "value": "800"
                  },
                  {
                    "label": "Black (Heavy)",
                    "value": "900"
                  }
                ]
              }
            },
            {
              "type": "number",
              "label": "Font size",
              "id": "fontSize",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "number",
              "label": "Font size (Tablet)",
              "id": "tabletFontSize",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "number",
              "label": "Font size (Mobile)",
              "id": "mobileFontSize",
              "default": {
                "value": 20,
                "type": "px"
              },
              "typeMeta": {
                "parseType": "integer"
              }
            },
            {
              "type": "color",
              "label": "Text color",
              "id": "fontColor",
              "default": "#000000"
            },
            {
              "type": "alignment",
              "label": "Alignment",
              "id": "alignment",
              "default": {
                "horizontal": "left",
                "vertical": "middle"
              },
              "typeMeta": {
                "display": "horizontal"
              }
            },
            {
              "type": "boxModel",
              "label": "Padding",
              "id": "paddingList",
              "default": {
                "top": {
                  "value": "0",
                  "type": "px"
                },
                "right": {
                  "value": "0",
                  "type": "px"
                },
                "bottom": {
                  "value": "0",
                  "type": "px"
                },
                "left": {
                  "value": "0",
                  "type": "px"
                }
              }
            }
          ]
        },
        {
          "label": "Spacing",
          "settings": [
            {
              "type": "boxModel",
              "label": "Margin",
              "id": "margin",
              "default": {
                "top": {
                  "value": "0",
                  "type": "px"
                },
                "right": {
                  "value": "0",
                  "type": "px"
                },
                "bottom": {
                  "value": "0",
                  "type": "px"
                },
                "left": {
                  "value": "0",
                  "type": "px"
                }
              }
            },
            {
              "type": "boxModel",
              "label": "Padding",
              "id": "padding",
              "default": {
                "top": {
                  "value": "36",
                  "type": "px"
                },
                "right": {
                  "value": "0",
                  "type": "px"
                },
                "bottom": {
                  "value": "36",
                  "type": "px"
                },
                "left": {
                  "value": "0",
                  "type": "px"
                }
              }
            }
          ]
        },
        {
          "label": "Border",
          "settings": [
            {
              "type": "select",
              "label": "Border style",
              "id": "borderStyle",
              "default": "none",
              "typeMeta": {
                "selectOptions": [
                  {
                    "label": "None",
                    "value": "none"
                  },
                  {
                    "label": "Solid",
                    "value": "solid"
                  },
                  {
                    "label": "Dotted",
                    "value": "dotted"
                  },
                  {
                    "label": "Dashed",
                    "value": "dashed"
                  },
                  {
                    "label": "Double",
                    "value": "double"
                  },
                  {
                    "label": "Groove",
                    "value": "groove"
                  },
                  {
                    "label": "Ridge",
                    "value": "ridge"
                  }
                ]
              }
            },
            {
              "type": "color",
              "label": "Border color",
              "id": "borderColor",
              "default": "transparent"
            },
            {
              "type": "range",
              "label": "Border thickness",
              "id": "borderThickness",
              "default": 0,
              "typeMeta": {
                "rangeValues": {
                  "min": 0,
                  "max": 10,
                  "step": 1,
                  "unit": "px"
                }
              }
            }
          ]
        },
        {
          "label": "Background",
          "settings": [
            {
              "type": "color",
              "label": "Background color",
              "id": "backgroundColor",
              "default": "transparent"
            }
          ]
        }
      ]
    }
  ]

the upper code is basically just inserting a block with "array" type  we give it a "label" that make the user know what this block is for
then we give it an "id" which is what we use in handlebars to use this tab values
the "entry Label" is what we provide to each item in this array as a name.
moving forward the schema array is a group of inputs that get generated dynamically for each image, this can be multiple fields or single field.
in our case we are using the "imageManager" type input which allow us to either upload or choose an image from our system and then use that image.
default object is basically the default values for each tab.

2. Template:
basically template is the part where we write plain HTML, bigcommerce uses handlebars to parse there HTML, we took values of the schema and parse them in here.

<style>

.hidden_element_bullet{
	display: none; 
}

.bullets_{{_.id}}{
	border:{{borderThickness}}px {{borderStyle}} {{borderColor}}; background-color:{{backgroundColor}}; 
    
    margin:{{margin.top.value}}px {{margin.right.value}}px {{margin.bottom.value}}px {{margin.left.value}}px; 
    
    padding:{{padding.top.value}}px {{padding.right.value}}px {{padding.bottom.value}}px {{padding.left.value}}px;
    
    }
   
 .bullets_{{_.id}} ul{
 	list-style: none; 
    padding-left: 0; 
    text-align:{{alignment.horizontal}};
  }
  
  .bullets_{{_.id}} li{
  padding:{{paddingList.top.value}}px{{paddingList.right.value}}px{{paddingList.bottom.value}}px{{paddingList.left.value}}px;
  
  font-size:{{fontSize.value}}px; 
  font-weight:{{fontWeight}}; 
  color:{{fontColor}};
 }
 
 .bullets_{{_.id}} li span{
     padding:{{paddingBullet.top.value}}px {{paddingBullet.right.value}}px {{paddingBullet.bottom.value}}px {{paddingBullet.left.value}}px; 
     
     font-size:{{fontSizeBullet.value}}px; 
     color:{{fontColorBullet}}; 
     font-weight:{{fontWeightBullet}};
 }
 
 @media screen all and (max-width: 1024px){
     .bullets_{{_.id}} li{
     	font-size:{{tabletFontSize}}px;
     }

     .bullets_{{_.id}} li span{
     	font-size:{{tabletFontSizeBullet}}px;
     }
 }
 
 @media screen all and (max-width: 720px){
     .bullets_{{_.id}} li{
     	font-size:{{mobileFontSize}}px;
     }

     .bullets_{{_.id}} li span{
     	font-size:{{mobileFontSizeBullet}}px;
     }
 }
 </style>
 
 <div data-widget-id='bullets' data-widget-name='bullets' class='pbw-bullets bullets_{{_.id}}'> 
 
 <ul>{{#each bullets}}
 <li class='pbw-bullet-single'> 
 <span class='pbw-bullet-span'>{{../bulletType}}</span>{{bullet_content}}</li>
 {{/each}}
 </ul>
 
</div>

this simple code just loop through the images in the schema and for each image in the images we took the "imageUrl" attribute and use the src from it. this will allow us to render the url of the image we have chosen.
you can also notice that we used {{_.id}} which will generate a dynamic uuid for each element in the loop.
this can be helpful to use so that when you are rendering multiple items of blocks you can make each one styled depending on that {{_.id}}

HAPPY CODING!!