purescript-contrib / purescript-react-dom

Low-level React DOM bindings for PureScript
MIT License
16 stars 16 forks source link

createPortal #21

Open andys8 opened 3 years ago

andys8 commented 3 years ago

I noticed react-dom has a portal feature but createPortal is missing here. If there Is no reason against it, I would suggest adding the functionality.

ReactDOM.createPortal(child, container)

https://reactjs.org/docs/react-dom.html#createportal https://reactjs.org/docs/portals.html

thomashoneyman commented 3 years ago

@andys8 I'm surprised it's not already here. From a quick look at the implementation, we can provide an FFI definition along these lines:

                               -- container   -- child        -- optional key  -- resulting portal
foreign import createPortal :: HTMLElement -> ReactElement -> Maybe String -> ReactElement

I would need to spend a little more time to verify these types. For example, it's not clear:

  1. Whether HTMLElement is the most appropriate type for the container (it's usually a sensible default, but it may be too general or too restrictive for portals)
  2. Whether ReactElement is the most appropriate type for the child (technically, React accepts any 'react node', which includes fragments, strings, and numbers, but to be usable it seems sensible to me to use ReactElement)

Ideally portals would be usable like any other ReactElement, which is why I didn't suggest introducing a new ReactPortal type as React does in their TypeScript definitions. So the above type is my best estimate of what type we might introduce for this feature, though other maintainers may have their own ideas.

We could support both keyed and non-keyed variants instead of including the optional argument:

-- no key
createPortal' :: HTMLElement -> ReactElement -> ReactElement

-- with key
createPortal :: HTMLElement -> ReactElement -> String -> ReactElement