Control Canvas Height

Hey @nroth,

I think you’re right that toggleField() will remove the field from the page altogether, making it so that the second field can’t re-show itself. I’ll check with the devs to see if this is intended behavior.

In the meantime, I think a simple workaround is to just put that logic in a Form outlet instead, which lives invisibly at the top of the record (but doesn’t necessarily have to render any UI, and has its own lifecycle independent of any fields):

You can see the demo here: Loading...

In index.tsx, I added:

     itemFormOutlets(model, ctx) {
        switch (model.attributes.api_key) {
            case 'dynamic_select':
                return [
                        id: 'DynamicFieldHider',
                        initialHeight: 0,

                return [];

    ) {
        render(<DynamicFieldHider ctx={ctx}/>);

And moved the hide/show logic into a new entrypoints/DynamicFieldHider.tsx:

import {RenderItemFormOutletCtx} from "datocms-plugin-sdk";
import {useEffect} from "react";

type PropTypes = {
    ctx: RenderItemFormOutletCtx;

export function DynamicFieldHider({ctx}: PropTypes) {

    // Manage field visibilities
    useEffect(() => {
        switch (ctx.formValues['field1']) {
            case 'hide':
                console.log("Hiding Field 2")
                ctx.toggleField('field2', false)
            case 'show':
                console.log("Showing Field 2")
                ctx.toggleField('field2', true)
    }, [ctx.formValues]);

    // We don't need to show any UI for this
    return null;

Updated the demo project with that example. It wasn’t super clear to me how your async fetches worked, so I just simulated a simple timeout in the “Dynamic Select” field editor plugin for field2 (DynamicSelectField.tsx). But how that works doesn’t really matter since the hide/show logic is moved to the Form Outlet instead.

Does that help?