Can I Use This?

This feature is available since Webiny v5.1.0.

What You’ll Learn
  • how to customize an existing Page Builder element
  • how to add settings to an existing element

Overview
anchor

All Page Builder elements are plugins which means we can modify, override or even add new ones.

In this tutorial, you will learn how we can add two predefined settings which are padding and width to the button element.

Plugin Type
anchor

There’s only one plugin you need to modify to customize an element: PbEditorPageElementPlugin.

Plugins of this type require a create function (to create an element data structure), and a render function that returns a React element that gets rendered in the editor.

All element plugins are registered as a factory so you can customize them by passing the following options:

@webiny/app-page-builder/types
type PbEditorElementPluginArgs = {
  // A function to create an element data structure.
  create?: (defaultValue: Partial<PbEditorElement>) => PbEditorElement;
  // Array of element settings plugin names.
  settings?: (
      defaultValue: PbEditorPageElementPluginSettings
  ) => Array<string | Array<string | any>>;
  // A function that return the toolbar properties of the element plugin.
  toolbar?: (defaultValue: PbEditorPageElementPluginToolbar) => React.ReactNode;
  elementType?: string;
};

Add Settings in an Element
anchor

Head over to the apps/admin/code/src/plugins/pageBuilder/ folder where all the plugins related to the Page Builder app are located.

As you can see there are two core sets of plugins:

  1. editor plugins: needed for Page Builder editor
  2. render plugins: needed for Page Builder page preview and to render the actual page in the Website app

For this tutorial, we only need to focus on the editor plugin.

By default, the button element settings look as shown below:

default button element settings in editor sidebardefault button element settings in editor sidebar
(click to enlarge)

Add Settings
anchor

To add the padding and width settings to the button element we pass the settings as the argument to the button element plugin factory.

As shown earlier, settings is a function that gets the defaultSettings of the element as an argument and returns the list of element settings.

Let’s make the following change.

apps/admin/code/src/plugins/pageBuilder/editorPlugins.ts
// Some code is removed for the sake of brevity.
export default [
  ...
  button({
    settings: (defaultValue?: string[]) => [
      ...(Array.isArray(defaultValue) ? defaultValue : []),
      "pb-editor-page-element-style-settings-padding",
      "pb-editor-page-element-style-settings-width"
    ]
  }),
  ...
]
//
// Other element plugins.
//

"pb-editor-page-element-style-settings-padding" and "pb-editor-page-element-style-settings-width" are the name of plugins.

Both are of type: PbEditorPageElementStyleSettingsPlugin.

After saving these changes, the button element settings will have padding and width settings as shown below:

updated button element settings in editor sidebarupdated button element settings in editor sidebar
(click to enlarge)

Hurray!

The padding and width settings are now available to the button element. And, we’re done here…

Not really! If you try changing these settings in the editor no visible change will happen to the button element as shown below:

updated button element settings in editor sidebarupdated button element settings in editor sidebar
(click to enlarge)

This is because the button element has specific styles applied to it in the theme (SCSS file) which overrides the styles applied by these settings via the editor.

Update Stylesheet
anchor

To fix this, we need to update the button element style within the theme so that it takes those settings applied via the editor.

The styles for the button element are written in the .webiny-pb-page-element-button CSS class. And, we need to make the following changes to it:

  • remove padding property
  • update width property
apps/theme/pageBuilder/styles/elements/button.scss
// Some code is removed for the sake of brevity.

.webiny-pb-page-element-button {
  // For the "width" settings in editor sidebar to work
  // The element needs to have "width: 100%"
  width: 100%;
  // padding: 14px 20px !important; <--- comment out or remove this
  //
  // More style definition.
  //
}

//
// More style definition.
//

After saving these changes the previously applied changes will show in the editor.

change button element settings in editor sidebarchange button element settings in editor sidebar
(click to enlarge)

All seems to work well, right? Let’s see:

Now that we have removed the padding property from the button element (SCSS file), a new button dropped into the page doesn’t look good with the default settings as shown below:

default settings for a new button in editordefault settings for a new button in editor
(click to enlarge)

We can fix this by adding the default values for both padding and width properties.

For this, we pass the create argument to the plugin factory. It is a function that gets the default value as the argument and returns the data for that element.

Let’s see the example below:

apps/admin/code/src/plugins/pageBuilder/editorPlugins.ts
import { set } from 'dot-prop-immutable'import { createInitialPerDeviceSettingValue } from '@webiny/app-page-builder/editor/plugins/elementSettings/elementSettingsUtils'import { DisplayMode } from '@webiny/app-page-builder/types'
// Some code is removed for the sake of brevity.
button({settings: (defaultValue) => [  ...defaultValue,  'pb-editor-page-element-style-settings-padding',  'pb-editor-page-element-style-settings-width',],create: (defaultValue) => {   // Set default value for the padding property   let elementData = set(     defaultValue,     'data.settings.padding',     createInitialPerDeviceSettingValue(       { advanced: true, top: '12px', right: '16px', bottom: '12px', left: '16px' }+,       DisplayMode.DESKTOP     )   )
   // Set default value for the width property   elementData = set(     elementData,     'data.settings.width',     createInitialPerDeviceSettingValue({ value: '150px' }, DisplayMode.DESKTOP)   )
   return elementData },})
//// Other element plugins.//

The create function defines the initial value for element settings and data property which can hold any data you might need.

Now if you drop a new button element to the editor it will look much better as shown below:

with default settings value for a new button in editorwith default settings value for a new button in editor
(click to enlarge)

This is because now the padding and width settings have a default value for it.

Here we’ve used the create function for setting the default value for padding and width properties. However, using a similar principle you can do whatever logic you need.

Conclusion
anchor

Congratulations!

You have added predefined settings to an existing Page Builder element. Use a similar approach to customize other elements for the Page Builder app.

You can also check out the full code example in our repo. If you have further questions, feel free to ask for additional help.