Custom prop controls for code components
You can create components with custom prop controls.
First, note that you may not need custom controls! If all you want is to show a dynamic set of options in a dropdown, or conditionally show/hide fields, you can use prop control functions.
When registering your component, specify type: ”custom”
and a React copmonent that renders the control.
A minimal example:
// A code component that just renders the propconst CodeComponent = ({ customProp, className }) => <div className={className}>{`${customProp}`}</div>;// A prop control with the value and a button to update itconst CustomProp = ({ updateValue, value }) => (<divstyle={{width: '100%',display: 'flex',justifyContent: 'space-between',padding: '0px 10px 0px 10px'}}><span>Value: {`${value}`}.</span><button onClick={() => updateValue(!value)} style={{ background: 'lightgray', padding: '0px 5px 0px 5px' }}>Change</button></div>);// RegistrationPLASMIC.registerComponent(CodeComponent, {name: 'CodeComponent',props: {customProp: {type: 'custom',control: CustomProp}}});
The props passed to the custom control component are:
componentProps
: The props that were passed to the componentcontextData
: The data fromsetControlContextData()
. See prop control functions.value
: The current value passed to the prop.updateValue
: The callback function to update the value to be passed to the prop.studioOps
: The provided set of operations that can be performed in Plasmic studio.projectData
: The provided project metadata from Plasmic studio.FullscreenModal
andSideModal
: Modal components if the control needs more space (covering either the center of the entire screen, or just the right pane—see next section).
A shorthand if the prop registration doesn’t need to specify any other metadata is to provide the component directly:
PLASMIC.registerComponent(CodeComponent, {name: 'CodeComponent',props: {customProp: CustomProp}});
Showing modals
To show a modal, use FullscreenModal
or SideModal
. These take an onClose
callback, which is fired if users click outside.
const CustomControl = ({ FullscreenModal }) => {const [open, setOpen] = useState(false);return (<divstyle={{width: '100%',display: 'flex',justifyContent: 'space-between',padding: '0px 10px 0px 10px'}}><button onClick={() => setOpen(true)} style={{ background: 'lightgray', padding: '0px 5px 0px 5px' }}>Edit</button><FullscreenModal show={open} onClose={() => setOpen(false)}><div>More UI here!</div><button onClick={() => setOpen(false)}>Close</button></FullscreenModal></div>);};
Usage notes
The controls run inside the Plasmic Studio UI, which is running in a different document/iframe than your application/your app host.
This has a few current implications:
Context from your app host won’t be there. If your components need context (e.g. for styling), for now you will need to wrap each component, like so:
function StandardContexts({ children }) {return (<ThemeProvider><SomeOtherProvider>{children}</SomeOtherProvider></ThemeProvider>);}function CustomProp1(props) {return <StandardContexts>...</StandardContexts>;}function CustomProp2(props) {return <StandardContexts>...</StandardContexts>;}
And, styling must be provided explicitly. Things will be fine if you are using a CSS-in-JS solution that dynamically injects styles into the document, but if you need external stylesheets to be loaded, then you will need to include and manage those yourself.
Have feedback on this page? Let us know on our forum.