halfnelson / nativescript-source-to-jsx-def

Walk nativescript source to generate JSX types for `svelte-type-checker-vscode`
Other
4 stars 1 forks source link

[Discussion] supporting elements with irregular parent:child relationships #19

Open shirakaba opened 4 years ago

shirakaba commented 4 years ago

An issue into which to dump our discussion on #svelte leading on from how to handle plugins, which frequently have irregular parent:child relationships.

halfnelson commented 4 years ago

So after poking around with JSX, it looks like we might be able to auto generate something like this:

    interface IntrinsicElements {
        radSideDrawer: { mainContent?: Element ,  drawerContent?: Element },
        radSideDrawer$mainContent: { children?: Element }
        radSideDrawer$drawerContent: { children?: Element }
    }
shirakaba commented 4 years ago

Are you proposing an approach like this?

<radSideDrawer>
  <radSideDrawer$mainContent>
    <contentView/>
  </radSideDrawer$mainContent>

  <radSideDrawer$drawerContent>
    <contentView/>
  </radSideDrawer$drawerContent>
</radSideDrawer>

I'm not totally sure whether that solves things in a renderer-agnostic manner.

React Reconciler kinda expects each JSX intrinsic element to be a node in the tree. i.e. each element has a parent (unless it's the most basal element), may have some children, and it itself should be a distinct instance of something from the host platform.

At the time of creating the instance for radSideDrawer$mainContent, React Reconciler does not give us access to the parent (indeed, it works from leaf to tree-top rather than vice versa), so I can't make radSideDrawer$mainContent return the parent RadSideDrawer instance and make it act as a sort of non-participant in the element tree.

Equally, when each <contentView/> gets inserted into the tree, neither have access to their grandparent (the RadSideDrawer instance) to perform the RadSideDrawer > ContentView appendChild operation.

Maybe it's enough for Svelte Native 😅 but for RNS I'd still be stumped.

shirakaba commented 4 years ago

This could maaaaaaybe be considered if our plugins CLI could generate some chaperone classes that could be constructed in those positions in the tree:

// Or maybe extends ViewBase?
class RadSideDrawer$DrawerContent extends Observable {
    // implements node operations to coordinate its parent with its child
    // i.e.: grandparent (RadSideDrawer) > chaperone > grandchild (ContentView)
}

... But I think that's opening a whole new rabbit hole, and technically creating (although small) more memory burden than NativeScript Core. More than anything, I'm hesitant that we'd hit some other limitation of React Reconciler along the way.

And if it's a bad fit for React Reconciler, it may well be a bad fit for many renderers.

shirakaba commented 4 years ago

Starting to think it would be worth trying to pose this question to a React core team member. I tend to get tumbleweeds and crickets when asking, but sometimes if you catch them at the right time, they do respond.