facebook / yoga

Yoga is an embeddable layout engine targeting web standards.

Home Page:https://yogalayout.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[website-next] Replace Yoga Node Editor with `@theme/CodeBlock`

NickGerleman opened this issue · comments

I did a really rough port of the yoga node editor sidebar from the previous Yoga playground, replacing the existing UI library with Docusaurus/Infima provided primitives and a small amount of custom CSS.

Before After (light) After (dark)
image image image

Instead of trying to make a polished series of forms, it would be simpler, and probably a better UX, to present a CSS style code editor instead. @docusaurus/theme-live-codeblock already exists to allow this type of scenario.

Some thoughts:

  • Instead of trying to make a polished series of forms, it would be simpler, and probably a better UX, to present a CSS style code editor instead

    Hmm... at that point perhaps it would make sense to make it just accept HTML (or JSX). I don't find the UI for creating nodes very intuitive either.

  • It occurs to me that UI-wise there isn't really anything Yoga-specific about the playground. It's essentially just a Flexbox playground that happens to use Yoga layout. It could be cool to add an option to layout with other layout engines too. I partially have Taffy in mind of course. But from a Yoga a perspective, the more useful comparison may the browser engine. If you could input the same HTML and get it to render with either the browser you're using or Yoga that could be super helpful to debugging layout issues. I've seen people use the Expo playground for this, but that requires emulating an entire mobile OS to run Yoga layout. It would be awesome in the Yoga playground could serve this role.

  • I wonder if it would make more sense to make the playground it's own standalone component rather than closely integrating it with the docs. Then it could be used for other scenarios (such as reproducing layout bugs, debugging tests, etc) too. It could still be embedded within the docs, but it wouldn't be invalidated if you ever want to change docs hosting framework in future.

Hmm... at that point perhaps it would make sense to make it just accept HTML (or JSX). I don't find the UI for creating nodes very intuitive either.

I've seen people use the Expo playground for this, but that requires emulating an entire mobile OS to run Yoga layout. It would be awesome in the Yoga playground could serve this role.

react-live does seem to highlight JSX snippets as a main use case. We can also customize JSX parsing I think: https://babeljs.io/docs/babel-plugin-transform-react-jsx#custom

Something like this could be nice:

<Config useWebDefaults={true}>
  <Node width={200} height={200} padding={20} >
    <Node flex={1} minHeight="50%" />
    <Node flex={1} />
    <Node flex={1} />
  </Node>
</Config>

Probably with some more extra attributes depending on how we would need to visually distinguish the nodes.

I wonder if it would make more sense to make the playground it's own standalone component rather than closely integrating it with the docs.

I particularly wanted to get rid of antd, or at least the version previously being used, because it brought in a lot of warnings, and enough was linked in that it nearly doubled the cumulative bundle size.

For context, without antd, we get bundles that look like this, where the red square is a 48KB when gzipped (including base64 encoded Yoga wasm, C++ runtime, and JS bindings).

I want to goal on the colors, typography, Tab UI, responsive grid lengths, shadow styles, etc be consistent with the rest of the documentation. Docusaurus's CSS library is available independent of Docusaurus, which makes taking a dependency on it a decent boundary, giving some good design primitives for a documentation oriented site. https://infima.dev/docs/getting-started/introduction/

For stuff like the live codeblock component, I think I'd also want to reuse Docusaurus primitive in the playground, for UI consistency. But I think that might be the only place that will need to depend on Docusaurus primitives (so the editor UI would not be usable outside Docusaurus).

it wouldn't be invalidated if you ever want to change docs hosting framework in future.

I think it is likely Yoga will stay on Docusaurus for some time. It is used by, and has a symbiotic relationship with a lot of other Meta OSS projects.

  1. https://reactnative.dev
  2. https://create-react-app.dev/
  3. https://hermesengine.dev/
  4. https://relay.dev
  5. https://componentkit.org/
  6. https://facebook.github.io/metro/
  7. https://fbflipper.com

We can also customize JSX parsing I think: https://babeljs.io/docs/babel-plugin-transform-react-jsx#custom

Yeah, I don't even think the parsing needs to change. I believe the snippet above is valid vanilla JSX. You just set which function it calls (instead of React.createElement) to create nodes to a function of your choice, and everything ought to just work :)

Depending on Infima as the UI library definitely seems reasonable.

Regarding the editor, it looks like https://reactnative.dev/ is not using the built in editor component. Rather it's using this Docusaurus plugin (https://github.com/facebook/react-native-website/tree/main/plugins/remark-snackplayer) to automatically embed https://github.com/expo/snack, which ends up looking like:

Screenshot 2023-11-02 at 12 22 50

(https://reactnative.dev/docs/flexbox)

IMO something like Expo Snack but which could render in-browser but with layout provided by Yoga would be ideal. Perhaps it would even make sense to add this to Expo Snack itself?

Current iteration:

Yoga.JSX.Reduced.mov

That's pretty cool. Is there a reason that the root node needs to be a different component type? Could that not be inferred by it being the outermost node?

Some ideas. Although they might be a little ambitious:

  • It would be cool if hovering a node in the code (or actually moving the caret onto a node) highlighted that node in the preview. And vice versa.
  • It would be cool if there was some kind of dev-tools like functionality. Possibly it would be better to have that instead of a compile error on an invalid property?
  • It would be cool if it was possible to get IDE-like code completion, red underlining, etc in the code editor.

The compile errors and exceptions on invalid input are more disruptive right that I would prefer.

The current implementation ends up using pretty stock “react-live”, which is oriented towards rendering a fragment of a react component, with any context passed in.

That’s part of why root node is special. It will:

  1. Recurse the tree of (no-op) React children, converting to a tree of styles.
  2. Converting the tree of styles into Yoga nodes, then measurements.
  3. Rendering an absolutely positioned box for where each Yoga node lands.

Wed also ideally add a config node. Right now I have it using default yoga config (no web defaults).

Correlating on hover/selection is something that would be helpful, but is not nicely exposed.

Im going to count this as done for now.