Use no shadow dom field in client sided Binder (CKEditor)

I am currently trying to create a custom field with a CKEditor. I followed the documentation Binding Data to Custom Components and this works. For the CKEditor to be rendered, I cannot have the template in the Shadow DOM.
As soon as I remove the Shadow DOM like following, the Binder does not get changed value anymore. No Validator get called and when submitting, the old value is still in the bean.

createRenderRoot(): HTMLElement | ShadowRoot {
   // Do not use a shadow root
   return this;
}

Using Hilla 2.5 with Lit. Reproduceable with Flow 24.5 starter today.

Does someone know can I create a custom component without a Shadow DOM that the binder can listen to? Does some know a solution to this or does this sound like an bug?
When this don’t work, I won’t use the Binder for this field and handle the value myself.

Thanks!

There are already some CKEditor addons out there, maybe you can have a glimpse there, how they solved the integration.

The Binder in Flow should not care about the client side structure, as long as the bound server side component implements the respective “has value and change event” interface and fires a value change event. Have you checked, if that is the case? (Not sure, what it requires in Hilla to work)

I do not use the Binder in Flow. Only client sided the @hilla/form package.

Thanks, I will look into the addons, maybe I can find there some input.

You need to wrap the CKEditor in a component that has the shared API’s of the Vaadin’s field components, I mean properties and attributes with the same name. The Binder will e.g. assume that the value is in property value. It also assumes that the is attribute “invalid”, when being set, field will show error styles when validation error occurs. The should be also attribute error-message which is set by Binder when validation error occurs. The attribute required will turn on the required indicator. These properties and attributes should be operable via actual root element of the component, not just React props, and you should use forwardRef to pass that root element on, so that the field directive can use it.