frejs / fre

:ghost: Tiny Concurrent UI library with Fiber.
https://fre.deno.dev
MIT License
3.71k stars 350 forks source link

Support for data-driven layout #144

Closed justinushermawan closed 4 years ago

justinushermawan commented 4 years ago

Hi, can I use fre for construct data-driven layout based on JSON schema? Something like this https://github.com/TechniqueSoftware/react-json-schema

yisar commented 4 years ago

I see that one line of code is not supported. We need to modify this line of code

Before that, I'd like to know what the scenario is for you to use this library. Can you give me a codesanbox example?

justinushermawan commented 4 years ago

Hi thank you for a quick response.

A glimpse of what I am trying to build: I'm going to convert my existing script written in vanilla into fre (if possible). This is a script that will listen to server call (in websocket), waiting for incoming message from the server. Most of messages are a task to render the view for user (in JSON schema).

So, there will be no static view inside this app (there are only pre-defined components that are ready for use by JSON definition), all of page views would be rendered dynamically (data-driven layout) based on server message, the data would mention the component detail to be used, including their respective props. Therefore, I need a support from fre to be able to parse the schema into JSX that will be rendered later.

I've made a sandbox of my existing vanilla script, it can't be run of course because need a back end application, but it should be easy to understand because I included an example of schema (line 575) that is commonly received from server.

And that is my scenario, hope it will be possible to do with fre as well as more simple and cleaner. Thank you.

justinushermawan commented 4 years ago

Hi @yisar, I think it's not possible without the existence of DOM object like this one to achieve this goal, what do you think? Do you have any other better idea?

yisar commented 4 years ago

@justinushermawan Sorry for the late reply. I think if you just want to describe the view through objects, you can use vdom directly.

render({
  type: 'div',
  props:{},
  children:[]
})

It's OK to use this way, so you don't need to use JSX.

justinushermawan commented 4 years ago

Hi @yisar , I just tried that way like this:

import { h, render } from 'fre'

const schema = {
  type: 'div',
  props: {
    style: {
      background: 'red'
    }
  },
  children: [
    {
      type: 'h2',
      props: {
        style: {
          color: 'white'
        }
      }
    }
  ]
}

render(schema, document.getElementById('root'))

But it seems not working, is there anything wrong?

yisar commented 4 years ago
const schema = {
  type: 'div',
  props: {
    style: {
      background: 'red'
    },
    children: {
      type: 'h2',
      props: {
        style: {
          color: 'white'
        },
        children: { type: 'text', props: { nodeValue: '111' } }
      }
    }
  }
}

Because of the absence of h function, vdom here needs to process the ending.

The format of fre may not be standard. I will adapt to the new standard as soon as possible.

https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#jsx-transform-changes

justinushermawan commented 4 years ago

Hi @yisar yeah it seems work now, sure I'll wait for next update.

justinushermawan commented 4 years ago

@yisar Btw about the type property in the schema, can it be a Component e.g type: 'Container' component?

yisar commented 4 years ago
function Container(){}
type: Container
yisar commented 4 years ago

Now the vdom structure of fre2 is mature. It has been optimized, and it may not be easy to use, but it should be able to be used directly.