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

React Component for different Node Types #365

Closed
KieranTH opened this issue May 23, 2024 · 5 comments
Closed

React Component for different Node Types #365

KieranTH opened this issue May 23, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@KieranTH
Copy link

Is your feature request related to a problem? Please describe.

Currently in the React system we have <ReactAsset/> for mimicking the rendering/parsing of Player externally in a React component. One thing I discovered today is that this ReactAsset does not support switches. Which makes sense as Switches aren't assets, and are structured differently.

Describe the solution you'd like

Do we need to expand the component selection in React to allow for external use of Switches in a similar manner to Assets. I imagine this issue pertains to other Node Types too such as templates.

May also be worth investigating whether a global mimic of the parsing is needed. A component which can essentially render any Node Type the same way player renders Views.

I'm interested to see what other people think!

Additional context

An example of the current limitation:

# Component
type ContainerProps = {
children: Asset[]
}
const Container = ({children}: ContainerProps) => {
 return children.map((child) => {
  return <ReactAsset {...child}/>
})
}

# Player Usage

{
  views: [ 
     {
       id: "view",
       type: "container",
       children: [
          {
            asset: {
               id: "text",
               type: "text",
               value: "Blah text"
            }
          },
          # This doesn't work, as it's getting mapped by the Container Component
          {
            dynamicSwitch: [
               {
                  case: "....",
                  asset: {...}
               }
            ]
          }
       ]
     }
  ]
}
@KieranTH KieranTH added the enhancement New feature or request label May 23, 2024
@KieranTH
Copy link
Author

Additional Note:

Because Player's translation layer is pre-emptive, dynamically generated Assets are unable to use expressions or bindings.

To work around this currently, you'd have to do the {{}} syntax parsing yourself for these components.

Example:

# Bindings wont work in this Component
const AssetGenerator = () => {
      const asset = {
        ...,
        id: "test-asset",
        binding: "foo"
       }
       return <ReactAsset {...asset}/>
}

const content = {
...
data: {foo: "bar"},
views: [
 {
   id: "view",
   type: "...",
   values: [
     {
       id: ...,
       type: "dynamic-asset-generator"
     }
   ]
 }
]
}

@KetanReddy
Copy link
Member

In general Switches and Templates should be resolved by Player in the core view AST parsing/resolving phases so the React layer should never have to know about them. The React layer is just mapping the resolved view AST to the registered assets. I might not be fully understanding how you're trying to use Player though, can link a code sandbox or repo I can look at?

@KieranTH
Copy link
Author

In general Switches and Templates should be resolved by Player in the core view AST parsing/resolving phases so the React layer should never have to know about them. The React layer is just mapping the resolved view AST to the registered assets. I might not be fully understanding how you're trying to use Player though, can link a code sandbox or repo I can look at?

Hey thanks for the reply!

Sadly the codebase it's being used is currently private - I'll try and work up a sandbox example. The general premise is that the codebase is built around reusable generic components that a user can build upon (These JSON components/assets may be fetched async through an API call). This relies alot upon the ReactAsset component supplied by Player.

So the first part of this issue I made was around the fact that the ReactAsset is outside the AST parsing - The main pain point for this comes from that if i have an asset that utilises the ReactAsset component at some stage, and try to inject a template or switch, it won't work - which you pointed out.

Funnily enough, another issue I created referenced this point: #494

So essentially the TLDR is that I had a component/asset like a Modal that injected a NEW JSON midway into the Player content with more assets in it, and fed that into a ReactAsset component. So essentially injecting more assets into the content, from rendering an asset built initially. Pretty weird I know!

This sandbox explains both points: https://codesandbox.io/p/sandbox/crzhm9

The SomeComponent.tsx file could be any React component that injects new assets that arent visible to the original content scope. Uncommenting the switch will cause a type error, which is expected at this point, but good to recognise.

So the general to my initial issue was that it would have been really neat if the ReactAsset component hooked into the AST parsing, so that these newly injected assests, which may have contained data bindings, expressions, switches or templates would be parsed.

I hope this makes sense! Happy to clarify anything if needed!

@adierkens
Copy link
Member

You're touching upon a lot of the original ideas behind the async-node support, which was originally designed to make it easier to dynamically inject new content into an already running player -- but many of the basic asset features here should still work for what you need.

The Player's view-model should contain the full picture of what needs to be processed. You can mutate that dynamically at run-time, just not in the React layer like your example shows.

The docs don't really explain the view-processing pipeline very well, but it's broken down into 2 main phases:

  • beforeResolve: Translates an AST Node -> AST Node
  • afterResolve: Translates an AST Node -> Object

In the beforeResolve phase of your asset, you can add in and parse additional content that you can feed into the player -- the player will process it all and give you a new component back.

I took your example and modified it slightly to show how that can works:
https://codesandbox.io/p/sandbox/crimson-meadow-forked-457jgz

The basic flow would be your SomeComponent React component feeds the new content back into the Player via the addChildValue function registered via the transform. That addition kicks off a re-processing of the some-component asset that you can then re-generate the new child-collection of values from.

@KieranTH
Copy link
Author

You're touching upon a lot of the original ideas behind the async-node support, which was originally designed to make it easier to dynamically inject new content into an already running player -- but many of the basic asset features here should still work for what you need.

The Player's view-model should contain the full picture of what needs to be processed. You can mutate that dynamically at run-time, just not in the React layer like your example shows.

The docs don't really explain the view-processing pipeline very well, but it's broken down into 2 main phases:

  • beforeResolve: Translates an AST Node -> AST Node
  • afterResolve: Translates an AST Node -> Object

In the beforeResolve phase of your asset, you can add in and parse additional content that you can feed into the player -- the player will process it all and give you a new component back.

I took your example and modified it slightly to show how that can works: https://codesandbox.io/p/sandbox/crimson-meadow-forked-457jgz

The basic flow would be your SomeComponent React component feeds the new content back into the Player via the addChildValue function registered via the transform. That addition kicks off a re-processing of the some-component asset that you can then re-generate the new child-collection of values from.

That's great! Thank you for setting up that codesandbox example, I'll give that a go!

Very much appreciated - I'll close this issue in that case

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

No branches or pull requests

3 participants