Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Begin end #24

Open
lsproule opened this issue Jan 22, 2025 · 1 comment
Open

Begin end #24

lsproule opened this issue Jan 22, 2025 · 1 comment

Comments

@lsproule
Copy link

lsproule commented Jan 22, 2025

it would be really nice if we could do something like this

<%= turbo_mount("Card", props: {...}) do %>
 // Regular erb
<% end %>

This would be really cool because then I could create components in react that control a majority of the layout, but for a form or something like that. I can just render the erb there. If this is a feature, I didn't see it, so I was curious what it would take to implement, and if you have any suggestions or ideas. I would love to help on this.

@skryukov
Copy link
Owner

Hey @lsproule thanks for the issue!

I don't think this should be a default behavior, but you can achieve it using a custom plugin like this (using React as example):

import { buildRegisterFunction, TurboMount } from "turbo-mount";
import { createElement, Fragment } from "react";
import { createRoot } from "react-dom/client";

const plugin = {
  mountComponent: (mountProps) => {
    const { el, Component, props } = mountProps;
    const root = createRoot(el);

    // using <template> as a wrapper prevents inner HTML from being displayed on load
    // (SSR is another option)
    const html = (el.querySelector('template') || el).innerHTML

    // Note: this adds another div to wrap HTML elements. You can use custom React
    // components here or pass innerHTML as prop to the original component for better control
    props.children = createElement('div', { dangerouslySetInnerHTML: { __html: html } });

    root.render(createElement(Component, props));

    return () => {
      root.unmount();
    };
  },
};

const registerComponent = buildRegisterFunction(plugin);

export { TurboMount, registerComponent };

export default plugin;

See full demo:
https://stackblitz.com/~/edit/turbo-mount-example-react?file=customReactPlugin.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants