Version 12 to 13
This migration guide contains migration instructions for:
- eightshift/boilerplate - 11+ --> 12.0.0
- eightshift/boilerplate-plugin - 4+ --> 5.0.0
- eightshift/frontend-libs - 12+ --> 13.0.0
- eightshift/libs - 8+ --> 9.0.0
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:
getNavigatorVibrateescapeStringelementChildrenHeightdevice
Helpers moved to ES UI components
Import these helpers from @eightshift/ui-components/utilities instead of Frontend libs:
truncatetruncateMiddleunescapeHTMLcamelCasepascalCasesnakeCasekebabCaseisEmptylowerFirstupperFirsthasisPlainObjectisObjectisEqualdebouncethrottle
Helpers with new names
These helpers should be imported from @eightshift/ui-components/utilities instead of Frontend libs:
camelize→camelCaseclassnames→clsxucfirst→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:
iconsillustrationsblockIconsBlockIcon
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/calcCWcalc-dynamic-size/calcDScalc-grid-width/calcGWline-height/lhem
Keyframes
Keyframes were removed from Frontend libs
Mixins
Removed mixins:
flex-containerbox-sizing(replace withbox-sizing, if no arguments were specified, the default isborder-box)column-offset-modifiersflex-column-width-modifiersflex-column-widthflex-grid-width-modifiersflex-grid-widthflex-horizontal-align-modifiersflex-vertical-align-modifierstext-align-modifiersstretchplaceholderinline-font-colorsgrid-offset-modifiersfont-smoothingcustom-bulletslink-modifierslinkmodifiers-deepmodifiers-rangemodifiersresponsive-modifiersresponsive-selectors-visibilityresponsive-selectorsresponsivefor-each-attributees-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).
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.
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:
isTileButtonpopoverPosition
Renamed props:
additionalClasses→className
AnimatedContentVisibility
Replace with AnimatedVisibility from Eightshift UI components.
Rename props:
showIf→visibleadditionalContainerClasses→className
Control
Replace with BaseControl from Eightshift UI components.
Rename props:
additionalClasses→classNameadditionalLabelClasses→labelClassNameinlineLabel→inline
Removed props:
wrapChildren
BlockInserter
Rename props:
additionalClasses→className
Label-specific:
- If
hasLabelwas set, replace it withlabel - If
customLabelwas set, removehasLabeland renamecustomLabeltolabel
Collapsable
Replace with Expandable from Eightshift UI components.
Rename props:
additionalClasses→className
ColorPalette
Replace with ColorPicker from Eightshift UI components.
Rename props:
additionalClasses→classNamenoShadeGrouping→noColorGroups
Removed props:
inlineLabellayoutsearchableactions
ColorPicker
Replace with ColorPicker from Eightshift UI components.
Rename props:
noShadeGrouping→noColorGroupshelp→subtitle
If type is set to generic, replace that with default.
Removed props:
pickerPopupTitlesearchablecolorPaletteLayoutexpandedborderinlineLabeladditionalClassesadditionalTriggerClassespopoverPositionadditionalControlsbuttonIconOverrideadditionalButtonArgsadditionalColorPaletteArgs
ColorSwatch
Replace with ColorSwatch from Eightshift UI components.
Rename props:
additionalClasses→className
Removed props:
selectedlarger
Select
Replace with Select from Eightshift UI components.
Rename props:
inlineLabel→inlinecloseMenuAfterSelect→keepMenuOpenAfterSelect(also invert the logic!)additionalSelectClasses→className
Removed props:
additionalProps- instead, pass props to the component directlyadditionalClasses
MultiSelect
Replace with MultiSelect from Eightshift UI components.
Rename props:
inlineLabel→inlineadditionalSelectClasses→className
Removed props:
additionalProps- instead, pass props to the component directlyadditionalClasses
AsyncSelect
Replace with AsyncSelect from Eightshift UI components.
Rename props:
inlineLabel→inlinecloseMenuAfterSelect→keepMenuOpenAfterSelect(also invert the logic!)additionalSelectClasses→className
Removed props:
additionalProps- instead, pass props to the component directlyadditionalClassesnoOptionCaching
AsyncMultiSelect
Replace with AsyncMultiSelect from Eightshift UI components.
Rename props:
inlineLabel→inlineadditionalSelectClasses→classNamecustomDropdownArrow→customDropdownIndicator
Removed props:
additionalProps- instead, pass props to the component directlyadditionalClassesnoOptionCaching
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→markersonAfterChange→onChangeEndleftAddition→beforerightAddition→after
Removed props:
discretereverseonBeforeChangehandleColoradditionalClassadditionalSliderClassnoTooltiptooltipPlacementtooltipFormatvalueDisplayvalueDisplayElement
RangeSlider
Replace with Slider from Eightshift UI components.
Rename props:
marks→markersonAfterChange→onChangeEndleftAddition→beforerightAddition→after
Removed props:
discretereverseonBeforeChangehandleColoradditionalClassadditionalSliderClassnoTooltiptooltipPlacementtooltipFormatvalueDisplayvalueDisplayElementpushablenoCrossdraggableTrack
ColumnConfigSlider
Replace with ColumnConfigSlider from Eightshift UI components.
Rename props:
numOfColumns→columnsnoOffsetHandle→disableOffsetnoWidthHandle→disableWidth
Removed props:
additionalClass
FancyDivider
Replace with Spacer from Eightshift UI components.
Rename props:
label→textadditionalClasses→className
Removed props:
additionalClasshasTopSpacingnoBottomSpacing
IconLabel
Replace with RichLabel from Eightshift UI components.
Rename props:
additionalClasses→className
Removed props:
standaloneaddSubtitleGap
Notification
Replace with Notice from Eightshift UI components.
Rename props:
additionalClasses→classNametext→labeliconOverride→icon
LinkInput/LinkEditComponent
Replace with LinkInput from Eightshift UI components.
Rename props:
additionalClasses→classNametext→labeliconOverride→icon
Removed props:
anchorIconnoDeletehideAnchorNoticeadditionalOptions(make sure to relocate those components somewhere else)additionalOptionTiles(make sure to relocate those components somewhere else)
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→classNametext→labeliconOverride→icon
Removed props:
typeadditionalTriggerClasses
MenuSeparator
Replace with MenuSeparator from Eightshift UI components.
MenuItem
Replace with MenuItem from Eightshift UI components.
Rename props:
additionalClass→className
Removed props:
customProps- instead, pass props to the component directly
Menu
Replace with Menu from Eightshift UI components.
Rename props:
icon→triggerIconlabel→triggerLabelbuttonProps→triggerProps
Removed props:
customProps- instead, pass props to the component directlydisabled- instead, pass throughtriggerProps={{ disabled: disabled }}popoverAdditionalClass- instead, pass throughpopoverProps={{ className: 'your-class-name-here' }}isSubmenu- instead, check docs for real submenusadditionalClass- instead, pass throughtriggerProps={{ className: 'your-class-name-here' }}
NumberPicker
Replace with NumberPicker from Eightshift UI components.
Rename props:
icon→triggerIcon
Removed props:
noDragToChangeactionsadditionalClassesinputFieldprefixClasssuffixClassextraButton- instead, pass that as a child of theNumberPickercomponentnoExtraButtonSeparatorroundToDecimals
OptionSelector
Replace with OptionSelect from Eightshift UI components.
Rename props:
inlineLabel→inlineiconOnly→noItemLabeladditionalButtonClass→classNameadditionalContainerClass→itemClassName
Removed props:
optionLabels- merge intooptionsif neededbordernoWrapalignment- add theverticalprop ifalignment='vertical'was usedlargerIconscompactButtons- if needed, can be implemented withitemProps={{ size: 'small' }}labelOnlyOnActiveadditionalClass
PopoverWithTrigger
Replace with TriggeredPopover from Eightshift UI components.
Rename props:
popoverClass→classNameposition→placement
Removed props:
contentClass- merge intoclassNamenoArrowtrigger- Important: check your component and addtriggerButtonLabel/triggerButtonIconprops as needed. If you need a custom trigger, pass it via thetriggerprop. It should be a component that's clickable, similar to a button.additionalCloseActions- can be reimplemented withonOpenChange, check the docsadditionalPopoverProps- pass props directly to the component insteadallowCloseFromChildren
Toggle
Replace with:
Togglefrom Eightshift UI components iftypewastoggleCheckboxfrom Eightshift UI components iftypewascheckboxToggleButtonfrom Eightshift UI components iftypewasbutton,iconButtonortileButton
Rename props:
additionalClasses→classNamehelp→subtitle(doesn't apply toToggleButton)
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>
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.
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
isPressedis present, withToggleButtonfrom@eightshift/ui-components. - otherwise,
Buttonfrom@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
closableattribute. - if you had an icon in the panel, separate it from the
titleand pass it to theiconprop - 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
labeland pass it to theiconprop
TextAreaControl
Replace TextAreaControl from @wordpress/components with InputField from @eightshift/ui-components.
After that:
- set
typetomultiline - if you had an icon in the panel, separate it from the
labeland pass it to theiconprop