Skip to main content

Version 12 to 13

This migration guide contains migration instructions for:

Note

Potential breaking changes ahead: this update might require a lot of changes, as Frontend libs is being simplified, and some parts extracted into Eightshift UI components.

Expected duration:

  • ~4h for basic replacements and checks
  • ~10-20h for complete replacements and checks (recommended)

Exact time will depend on number of blocks/components and how complex they are.

Helpers​

Removed helpers​

Some helpers were deprecated and removed, without a replacement. If they were used in the project before, you can take the source of the helper from Frontend libs 12 and include it in your project.

These helpers were removed:

  • getNavigatorVibrate
  • escapeString
  • elementChildrenHeight
  • device

Helpers moved to ES UI components​

Import these helpers from @eightshift/ui-components/utilities instead of Frontend libs:

  • truncate
  • truncateMiddle
  • unescapeHTML
  • camelCase
  • pascalCase
  • snakeCase
  • kebabCase
  • isEmpty
  • lowerFirst
  • upperFirst
  • has
  • isPlainObject
  • isObject
  • isEqual
  • debounce
  • throttle

Helpers with new names​

These helpers should be imported from @eightshift/ui-components/utilities instead of Frontend libs:

  • camelize → camelCase
  • classnames → clsx
  • ucfirst → upperFirst

Classnames​

❌

classnames([
'class-1',
'class-2',
'class-3',
])

✅

clsx(
'class-1',
'class-2',
'class-3',
)

If you're using selector and have the condition argument the same as the block argument, you can omit the condition and replace selector with bem.

❌

clsx(
selector(blockClass, blockClass, 'something'),
...
)

✅

clsx(
bem(blockClass, 'something'),
...
)

(bem comes from Frontend libs)

If you have a condition set, you can move it outside of the function call.

❌

clsx(
selector(myCondition, blockClass, 'something'),
...
)

✅

clsx(
myCondition && bem(blockClass, 'something'),
...
)

(bem comes from Frontend libs)

If there's a selector with the same 2 arguments, omit the function.

❌

clsx(
selector(blockClass, blockClass),
...
)

✅

clsx(
blockClass,
...
)

If you have only one entry within classnames/clsx, just keep that entry.

❌

clsx(
classnames([bem(blockClass, selectorClass)]),
...
)

✅

clsx(
bem(blockClass, selectorClass),
...
)

Icons​

Import these from @eightshift/ui-components/icons instead of Frontend libs:

  • icons
  • illustrations
  • blockIcons
  • BlockIcon

Additionally, if you used dangerouslySetInnerHTML for rendering SVGs, you can now use the JsxSvg component to render it more safely and elegantly.

<JsxSvg svg="<svg ..." />

Styles​

Utility classes​

Frontend libs utility classes are deprecated and will be removed in the next version.

Remove them from your code if possible, and check if some of them can be replaced with ones from ES UI components (they have the es- prefix).

CSS reset​

The default CSS reset was updated. Do a quick look-around on your site to see if anything is different, but nothing major is expected.

SCSS​

Some SCSS functionalities were removed from Frontend libs.

If you were using them, you can re-define them in your project. The previous implementation can be checked in Frontend libs v12 source.

Placeholders​

Removed placeholders:

  • %absolute-center
  • %bg-image
  • %clearfix
  • %site-padding
  • %site-padding-correction
  • %link-transition
  • %heading-reset
  • %paragraph-reset
  • %dl-reset

Functions​

Removed functions:

  • calc-column-width / calcCW
  • calc-dynamic-size / calcDS
  • calc-grid-width / calcGW
  • line-height / lh
  • em

Keyframes​

Keyframes were removed from Frontend libs

Mixins​

Removed mixins:

  • flex-container
  • box-sizing (replace with box-sizing, if no arguments were specified, the default is border-box)
  • column-offset-modifiers
  • flex-column-width-modifiers
  • flex-column-width
  • flex-grid-width-modifiers
  • flex-grid-width
  • flex-horizontal-align-modifiers
  • flex-vertical-align-modifiers
  • text-align-modifiers
  • stretch
  • placeholder
  • inline-font-colors
  • grid-offset-modifiers
  • font-smoothing
  • custom-bullets
  • link-modifiers
  • link
  • modifiers-deep
  • modifiers-range
  • modifiers
  • responsive-modifiers
  • responsive-selectors-visibility
  • responsive-selectors
  • responsive
  • for-each-attribute
  • es-eases

Component styles, editor overrides, ...​

The previously included Gutenberg component style overrides are not included by default anymore. overrides-editor.scss is still present, but only a couple of styles are left for compatibility reasons. Instead, you can @import '~@eightshift/ui-components/dist/assets/wp-ui-enhancements.css'; from Eightshift UI components.

es-component-styles.scss (in Frontend libs) are not bundled with overrides-editor.scss anymore, and should be imported separately if needed.

Replace components​

This will take some time, but the guide below should make it easier. Our recommendation is to go block by block (instead of replacing one type of UI component at a time).

Note

Some components will still have fallbacks not to break everything immediately, but replacing them is strongly recommended, as everything will be removed in the next version.

Tip

After replacing components, check if there are any new props that might be useful for your use case.

All components​

  • remove noBottomSpacing
  • remove reducedBottomSpacing

AdvancedColorPicker​

Removed props:

  • isTileButton
  • popoverPosition

Renamed props:

  • additionalClasses → className

AnimatedContentVisibility​

Replace with AnimatedVisibility from Eightshift UI components.

Rename props:

  • showIf → visible
  • additionalContainerClasses → className

Control​

Replace with BaseControl from Eightshift UI components.

Rename props:

  • additionalClasses → className
  • additionalLabelClasses → labelClassName
  • inlineLabel → inline

Removed props:

  • wrapChildren

BlockInserter​

Rename props:

  • additionalClasses → className

Label-specific:

  • If hasLabel was set, replace it with label
  • If customLabel was set, remove hasLabel and rename customLabel to label

Collapsable​

Replace with Expandable from Eightshift UI components.

Rename props:

  • additionalClasses → className

ColorPalette​

Replace with ColorPicker from Eightshift UI components.

Rename props:

  • additionalClasses → className
  • noShadeGrouping → noColorGroups

Removed props:

  • inlineLabel
  • layout
  • searchable
  • actions

ColorPicker​

Replace with ColorPicker from Eightshift UI components.

Rename props:

  • noShadeGrouping → noColorGroups
  • help → subtitle

If type is set to generic, replace that with default.

Removed props:

  • pickerPopupTitle
  • searchable
  • colorPaletteLayout
  • expanded
  • border
  • inlineLabel
  • additionalClasses
  • additionalTriggerClasses
  • popoverPosition
  • additionalControls
  • buttonIconOverride
  • additionalButtonArgs
  • additionalColorPaletteArgs

ColorSwatch​

Replace with ColorSwatch from Eightshift UI components.

Rename props:

  • additionalClasses → className

Removed props:

  • selected
  • larger

Select​

Replace with Select from Eightshift UI components.

Rename props:

  • inlineLabel → inline
  • closeMenuAfterSelect → keepMenuOpenAfterSelect (also invert the logic!)
  • additionalSelectClasses → className

Removed props:

  • additionalProps - instead, pass props to the component directly
  • additionalClasses

MultiSelect​

Replace with MultiSelect from Eightshift UI components.

Rename props:

  • inlineLabel → inline
  • additionalSelectClasses → className

Removed props:

  • additionalProps - instead, pass props to the component directly
  • additionalClasses

AsyncSelect​

Replace with AsyncSelect from Eightshift UI components.

Rename props:

  • inlineLabel → inline
  • closeMenuAfterSelect → keepMenuOpenAfterSelect (also invert the logic!)
  • additionalSelectClasses → className

Removed props:

  • additionalProps - instead, pass props to the component directly
  • additionalClasses
  • noOptionCaching

AsyncMultiSelect​

Replace with AsyncMultiSelect from Eightshift UI components.

Rename props:

  • inlineLabel → inline
  • additionalSelectClasses → className
  • customDropdownArrow → customDropdownIndicator

Removed props:

  • additionalProps - instead, pass props to the component directly
  • additionalClasses
  • noOptionCaching

react-select component wrappers​

Everything works the same, just import the components from @eightshift/ui-components instead.

Slider​

Replace with Slider from Eightshift UI components.

Rename props:

  • marks → markers
  • onAfterChange → onChangeEnd
  • leftAddition → before
  • rightAddition → after

Removed props:

  • discrete
  • reverse
  • onBeforeChange
  • handleColor
  • additionalClass
  • additionalSliderClass
  • noTooltip
  • tooltipPlacement
  • tooltipFormat
  • valueDisplay
  • valueDisplayElement

RangeSlider​

Replace with Slider from Eightshift UI components.

Rename props:

  • marks → markers
  • onAfterChange → onChangeEnd
  • leftAddition → before
  • rightAddition → after

Removed props:

  • discrete
  • reverse
  • onBeforeChange
  • handleColor
  • additionalClass
  • additionalSliderClass
  • noTooltip
  • tooltipPlacement
  • tooltipFormat
  • valueDisplay
  • valueDisplayElement
  • pushable
  • noCross
  • draggableTrack

ColumnConfigSlider​

Replace with ColumnConfigSlider from Eightshift UI components.

Rename props:

  • numOfColumns → columns
  • noOffsetHandle → disableOffset
  • noWidthHandle → disableWidth

Removed props:

  • additionalClass

FancyDivider​

Replace with Spacer from Eightshift UI components.

Rename props:

  • label → text
  • additionalClasses → className

Removed props:

  • additionalClass
  • hasTopSpacing
  • noBottomSpacing

IconLabel​

Replace with RichLabel from Eightshift UI components.

Rename props:

  • additionalClasses → className

Removed props:

  • standalone
  • addSubtitleGap

Notification​

Replace with Notice from Eightshift UI components.

Rename props:

  • additionalClasses → className
  • text → label
  • iconOverride → icon

LinkInput/LinkEditComponent​

Replace with LinkInput from Eightshift UI components.

Rename props:

  • additionalClasses → className
  • text → label
  • iconOverride → icon

Removed props:

  • anchorIcon
  • noDelete
  • hideAnchorNotice
  • additionalOptions (make sure to relocate those components somewhere else)
  • additionalOptionTiles (make sure to relocate those components somewhere else)
Warning

New tab control has been detached from this component. Use a Toggle (from Eightshift UI components) below it instead.

MatrixAlignControl​

Replace with MatrixAlign from Eightshift UI components.

Rename props:

  • additionalClasses → className
  • text → label
  • iconOverride → icon

Removed props:

  • type
  • additionalTriggerClasses

Replace with MenuSeparator from Eightshift UI components.

Replace with MenuItem from Eightshift UI components.

Rename props:

  • additionalClass → className

Removed props:

  • customProps - instead, pass props to the component directly

Replace with Menu from Eightshift UI components.

Rename props:

  • icon → triggerIcon
  • label → triggerLabel
  • buttonProps → triggerProps

Removed props:

  • customProps - instead, pass props to the component directly
  • disabled - instead, pass through triggerProps={{ disabled: disabled }}
  • popoverAdditionalClass - instead, pass through popoverProps={{ className: 'your-class-name-here' }}
  • isSubmenu - instead, check docs for real submenus
  • additionalClass - instead, pass through triggerProps={{ className: 'your-class-name-here' }}

NumberPicker​

Replace with NumberPicker from Eightshift UI components.

Rename props:

  • icon → triggerIcon

Removed props:

  • noDragToChange
  • actions
  • additionalClasses
  • inputField
  • prefixClass
  • suffixClass
  • extraButton - instead, pass that as a child of the NumberPicker component
  • noExtraButtonSeparator
  • roundToDecimals

OptionSelector​

Replace with OptionSelect from Eightshift UI components.

Rename props:

  • inlineLabel → inline
  • iconOnly → noItemLabel
  • additionalButtonClass → className
  • additionalContainerClass → itemClassName

Removed props:

  • optionLabels - merge into options if needed
  • border
  • noWrap
  • alignment - add the vertical prop if alignment='vertical' was used
  • largerIcons
  • compactButtons - if needed, can be implemented with itemProps={{ size: 'small' }}
  • labelOnlyOnActive
  • additionalClass

PopoverWithTrigger​

Replace with TriggeredPopover from Eightshift UI components.

Rename props:

  • popoverClass → className
  • position → placement

Removed props:

  • contentClass - merge into className
  • noArrow
  • trigger - Important: check your component and add triggerButtonLabel / triggerButtonIcon props as needed. If you need a custom trigger, pass it via the trigger prop. It should be a component that's clickable, similar to a button.
  • additionalCloseActions - can be reimplemented with onOpenChange, check the docs
  • additionalPopoverProps - pass props directly to the component instead
  • allowCloseFromChildren

Toggle​

Replace with:

  • Toggle from Eightshift UI components if type was toggle
  • Checkbox from Eightshift UI components if type was checkbox
  • ToggleButton from Eightshift UI components if type was button, iconButton or tileButton

Rename props:

  • additionalClasses → className
  • help → subtitle (doesn't apply to ToggleButton)

Removed props:

  • inlineHelp

ResponsiveToggleButton​

Replace with ResponsiveLegacy from Eightshift UI components.

Sample replacement:

<ResponsiveLegacy
hidden={!showXyz} // If you had '{showXyz && <ResponsiveToggleButton ... />}'
{...getResponsiveLegacyData(manifest.responsiveAttributes.buttonWidth, attributes, manifest, setAttributes)} // 'getResponsiveLegacyData' comes from Frontend libs
breakpointData={globalManifest.globalVariables.breakpoints}
icon={icons.width} // Copy over from 'ResponsiveToggleButton'
label={__('Full-width', 'my-project')} // Copy over from 'ResponsiveToggleButton'
options={[
{ value: 'default', label: __('Fit content', 'my-project') }, // Can be replaced with "{ value: false, label: __('Off', 'my-project') }" if more generic
{ value: 'block', label: __('Full', 'my-project') }, // Can be replaced with "{ value: true, label: __('On', 'my-project') }" if more generic
]}
allowUndefined // If the responsive value can be undefined (= if any of the attribute has no default set). If not, remove this prop and add provide 'inheritValue'.
inline // Optional, but recommended with compact setups
>
{({ currentValue, options, handleChange }) => (
// Replace with any other relevant component, e.g. 'Switch'
<OptionSelect
value={currentValue}
options={options}
onChange={handleChange}
/>
)}
</ResponsiveLegacy>

ResponsiveNumberPicker​

Replace with ResponsiveLegacy from Eightshift UI components.

Sample replacement:

<ResponsiveLegacy
hidden={!showXyz} // If you had '{showXyz && <ResponsiveNumberPicker ... />}'
{...getResponsiveLegacyData(manifest.responsiveAttributes.xyz, attributes, manifest, setAttributes)}
label={__('Width', 'my-project')} // Copy over from 'ResponsiveNumberPicker'
icon={icons.width} // Copy over from 'ResponsiveNumberPicker'
options={generateOptionsFromValue('xyz', attributes, manifest)} // 'generateOptionsFromValue' is from Frontend libs
breakpointData={globalManifest.globalVariables.breakpoints}
allowUndefined // If the responsive value can be undefined (= if any of the attribute has no default set). If not, remove this prop and add provide
inline // Optional, but recommended with compact setups
>
{({ currentValue, handleChange, breakpoint }) => {
return (
// Replace with any other relevant component
<NumberPicker
aria-label={sprintf(__('Width - %s', 'my-project'), breakpoint)}
value={currentValue ?? null} // '?? null' is required if 'allowUndefined' is set
onChange={handleChange}
// This is from previous 'minMaxStepOptionName'
min={manifest.options.carouselItemWidth.min}
max={manifest.options.carouselItemWidth.max}
step={manifest.options.carouselItemWidth.step} // Optional, '1' is the default
size='small'
/>
);
}}
</ResponsiveLegacy>

Responsive​

Replace with ResponsiveLegacy from Eightshift UI components.

Sample replacement:

<ResponsiveLegacy
hidden={!showXyz} // If you had '{showXyz && <Responsive ... />}'
{...getResponsiveLegacyData(manifest.responsiveAttributes.buttonAlign, attributes, manifest, setAttributes)}
label={__('Align', 'my-project')} // Copy over from 'Responsive'
icon={icons.horizontalAlign} // Copy over from 'Responsive'
options={options.buttonAlign} // or use 'getOption' helper
breakpointData={globalManifest.globalVariables.breakpoints}
allowUndefined // If the responsive value can be undefined (= if any of the attribute has no default set). If not, remove this prop and add provide
inline // Optional, but recommended with compact setups
>
{({ currentValue, options, handleChange }) => (
// Replace with any other relevant component
<OptionSelect
value={currentValue}
options={options}
onChange={handleChange}
/>
)}
</ResponsiveLegacy>
Note

In some cases, replacement might be too complicated. It's OK to skip it then, but try to keep this to a minimum.

Repeater​

Replace with Repeater from Eightshift UI components.

Note

In some cases, replacement might be too complicated. It's OK to skip it then, but try to keep this to a minimum.

Modify components​

PresetPicker​

Removed props:

  • showAsCollapsable

Replace Gutenberg components​

Button​

Replace Button from @wordpress/components:

  • if isPressed is present, with ToggleButton from @eightshift/ui-components.
  • otherwise, Button from @eightshift/ui-components.

If label was set and the button itself doesn't have a label, set an aria-label with the same value. Optionally, also set tooltip to the same value.

PanelBody​

Replace PanelBody from @wordpress/components with ContainerPanel from @eightshift/ui-components.

After that:

  • add the closable attribute.
  • if you had an icon in the panel, separate it from the title and pass it to the icon prop
  • if there were extra controls by the title, pass them to actions

TextControl​

Replace TextControl from @wordpress/components with InputField from @eightshift/ui-components.

After that:

  • if you had an icon in the panel, separate it from the label and pass it to the icon prop

TextAreaControl​

Replace TextAreaControl from @wordpress/components with InputField from @eightshift/ui-components.

After that:

  • set type to multiline
  • if you had an icon in the panel, separate it from the label and pass it to the icon prop