Custom behaviors (attachments)

Overview

Custom behaviors (attachments) are code components that function similarly to React wrapper components or higher-order components.

Unlike normal code components that render content/elements onto a page, custom behaviors don’t render anything itself; instead, they inject behavior or prop values into its children.

For example:

Copy
// Example: Add an onClick behavior to an arbitrary element or component.
<OnClickAnalyticsTracker>
<a href='...'/>
</OnClickAnalyticsTracker>
// Add some interactive effects by monitoring the element with IntersectionObserver.
<ParallaxScroll>
<HeroSection/>
</ParallaxScroll>
// Provide some data to its element.
<DataProvider>
<Chart/>
</DataProvider>

Some simple behaviors could be implemented with interactions instead of custom behavior code components. For example, you could program an onClick interaction to trigger state changes, directly in Plasmic Studio.

Registration

To register a custom behavior component, use registerComponent with isAttachment: true. A custom behavior may only have 1 slot prop named children.

Copy
function OnClickAlert({ children, msg, ...props }: { children?: ReactNode; msg?: string }) {
const filteredProps = Object.fromEntries(
Object.entries(props).filter(([key]) => !key.startsWith('data-plasmic') && key !== 'className')
);
return React.Children.map(children, (child) =>
cloneElement(child as ReactElement, {
...filteredProps, // forward extra props for composability
onClick: () => alert(msg)
})
);
}
PLASMIC.registerComponent(OnClickAlert, {
name: 'OnClickAlert',
isAttachment: true,
styleSections: false, // This component does not accept className
props: {
children: 'slot',
msg: 'string'
}
});

Custom behavior vs. normal component

In the above example, we could have also registered OnClickAlert without isAttachment: true like a normal component, and Plasmic Studio editors would still be able to use it. But they would need to wrap some elements in it and manually construct the correct React element tree.

For instance, if they inserted and selected a Button, and now want to wrap it in an OnClickAlert, they would need to:

  1. Insert an OnClickAlert next to the Button.
  2. Drag the Button into the OnClickAlert.
  3. Select the OnClickAlert again.
  4. Configure the OnClickAlert msg prop.

With custom behaviors, editors can instead directly attach behaviors to the Button:

  1. In the Custom Behaviors right sidebar section, add OnClickAlert.
  2. Configure the OnClickAlert msg prop.

This allows editors to think of custom behavior components less as “rendered components to insert in the tree” but rather “behavior to be attached to anything.”

Best practices

  • Handle the children prop robustly. Your custom behavior should accept both a single React element or an array of React elements.
  • Forward passed in props to children. This ensures your custom behavior is composable and can support multiple layers of wrapper components.
  • Avoid introducing layout in the attachment, so that the wrapped component has control of its layout. Register the component with styleSections: false to denote that your custom behavior is not intended to accept styles.
Was this page helpful?

Have feedback on this page? Let us know on our forum.