himself65 / rich-data

Data Viewer
https://rich-data.dev
Mozilla Public License 2.0
146 stars 11 forks source link

Roadmap v3 #1

Open himself65 opened 1 year ago

himself65 commented 1 year ago

BREAKING Changes

Improvement

gregfenton commented 1 year ago

Features/options I'd like to see:

mashirozx commented 1 year ago

Please consider do not introduce any third party state management lib. Keep in mind this should only be a component lib, but not a framework, don't do global things and the lighter the better 🙏

Update:

Please also consider don't use third party UI library 🙏

himself65 commented 1 year ago

Please consider do not introduce any third party state management lib. Keep in mind this should only be a component lib, but not a framework, don't do global things and the lighter the better 🙏

Update:

Please also consider don't use third party UI library 🙏

I will try to use minimal store library and totally remove the third party ui

himself65 commented 1 year ago

Features/options I'd like to see:

  • ability to copy both the key & value of a tree node, not just the value
  • ability to copy a string value but without the surrounding quotes

It will be landing in v2 version

rtritto commented 1 year ago

@Himself65 as said in https://github.com/TexteaInc/json-viewer/issues/144#issuecomment-1416326938, there is a real need to use a store manager? Otherwise native React functions can be used.

mashirozx commented 1 year ago

I think provider+useContext is enough, just to inject the hook model directly.

But there maybe some difficulty to deep change a nested state value which should be noticed or avoid, because there is no set method like zustand

himself65 commented 1 year ago

I believe pure provider + useContext doesn't have much benefit except bundle size reduction.

We have many props and states in json viewer, the store manager will reduce the re-render and less burden

himself65 commented 1 year ago

Features/options I'd like to see:

  • ability to copy both the key & value of a tree node, not just the value
  • ability to copy a string value but without the surrounding quotes

I recently had time to work on this. What kind of API do you like for this part? @gregfenton

mashirozx commented 1 year ago

I believe pure provider + useContext doesn't have much benefit except bundle size reduction.

We have many props and states in json viewer, the store manager will reduce the re-render and less burden

As for the rerender issue, you may have a look at this: https://github.com/dai-shi/use-context-selector

After all, thanks for your contribution, I'll try to create a pr here or maintain a fork by my self when I have time, to take my thoughts into practice. 🫣

himself65 commented 1 year ago

I believe pure provider + useContext doesn't have much benefit except bundle size reduction. We have many props and states in json viewer, the store manager will reduce the re-render and less burden

As for the rerender issue, you may have a look at this: https://github.com/dai-shi/use-context-selector

After all, thanks for your contribution, I'll try to create a pr here or maintain a fork by my self when I have time, to take my thoughts into practice. 🫣

you can give a quick PR and let's discuss the best practice

gregfenton commented 1 year ago

I recently had time to work on this. What kind of API do you like for this part? @gregfenton

I guess I don't really have too much of a preference. A property identifying the "copy type" ? Ultimately I could see myself building some additional UI that would pass the appropriate setting if the UI doesn't have this built in itself.

@Himself65 many, many thanks for doing this!!

himself65 commented 1 year ago

I would like to split the copy/paste behavior in a single module called content-manager first. Let me handle this today

himself65 commented 1 year ago

I recently had time to work on this. What kind of API do you like for this part? @gregfenton

I guess I don't really have too much of a preference. A property identifying the "copy type" ? Ultimately I could see myself building some additional UI that would pass the appropriate setting if the UI doesn't have this built in itself.

@Himself65 many, many thanks for doing this!!

please keep eye on https://github.com/Himself65/data-viewer/pull/32

himself65 commented 1 year ago

I'm thinking about the design of v3 and already have the prototype of it

Basic API

import { createViewerHook } from '@rich-data/viewer'

const useViewer = createViewerHook()

const value = { /* ... */ }
const App = () => {
  const { Viewer } = useViewer()
  return (
    <Viewer value={value}/>
  )
}

Why createViewerHook?

We split the codespace into vanilla.ts and react.tsx, just like jotai and zustand. The vanilla code will only have the new viewer's data structure and logic code.

We will move typeRenderer out of react lifecycle. Which will allow you do this

const plugins: Plugin[] = [
  {
    flavour: 'my_number',
    typeRenderer: {
      flavour: 'my_number',
      is: value => typeof value === 'number',
      Component: ({ value }) => <span> this is number {value}</span>
    }
  } as Plugin<'my_number'>
]

const useViewer = createViewerHook({
  plugins
})

export function App () {
  const { Viewer } = useViewer()
  // display 'this is number 1'
  return (
    <Viewer value={1}/>
  )
}

Example Code: https://github.com/Himself65/data-viewer/blob/4274554d46ad1b65ffbd031c29e6bba928595ebe/packages/playground/src/main.tsx

himself65 commented 1 year ago

Update

Plugin System with Strong TypeScript Support

We now have two types of plugins, block and middleware.

Block defines the UI of a single type, Middleware inject hooks and value into the viewer

type MyPluginMiddleware<C, A> = {
  ping: () => void
}

declare module '@rich-data/viewer' {
  interface ContextMutators<C, A> {
    'my-plugin': MyPluginMiddleware<C, A>
  }
}

const TestPlugin = {
  id: 'my-plugin',
  middleware: (_store) => {
    return {
      ping: () => {
        console.log('ping')
      }
    }
  }
} satisfies Plugin

const {
  useViewer,
  useContext,
  Provider
} = createViewerHook({
  plugins: [
    // ...
    TestPlugin
  ] as const
})

function Example () {
  const { Viewer } = useViewer()
  const context = useContext()
  return (
    <>
      <button
        onClick={() => {
          context.ping()
        }}
      >ping
      </button>
      <Viewer value={/* ... */}/>
    </>
  )
}

export function App () {
  return (
    <Provider>
      <Example/>
    </Provider>
  )
}

Notice that here we have the strong type of support, you comment any lines will alert type error.

Thus, the theme, mui are will be the plugin of the viewer