Giter Site home page Giter Site logo

react-teleporter's People

Contributors

andarist avatar bartels avatar bjohn465 avatar blasterpistol avatar dependabot[bot] avatar dgdavid avatar gregberge avatar ypresto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-teleporter's Issues

Suggestion for multiple layouts for frontend and admin

Hello @gregberge

I like your project a lot and it is very helpful.

I need to create a single page app that work both frontend and backend.
Therefore, I have used react-teleporter to solve my problem and it works great.

However, I am not sure if my approach is correct with integrate react-teleporter with multiple layouts.
Here is my current implementation now.

Frontend is a layout component, used in App.tsx
https://github.com/codesanook/Codesanook.Examples/blob/master/codesanook-examples-debug-create-react-app/src/App.tsx#L40

Frontend has react-teleporter target for inject a title.
https://github.com/codesanook/Codesanook.Examples/blob/master/codesanook-examples-debug-create-react-app/src/pages/frontend/Frontend.tsx#L31

And source is from Home.tsx which is a actual page component
https://github.com/codesanook/Codesanook.Examples/blob/master/codesanook-examples-debug-create-react-app/src/pages/frontend/Home.tsx#L7

If it is possible, could you please give me some suggestion or other approach of multiple layouts implementation.
Thanks.

Prevent double usage

  • API should have protection from more than one active Source, and more than one active Target (longer that useEffect)
  • it should properly handle Target and Source remount
  • it should stand Target unmount (probably would fail right now)
  • Source should have an option to enforce Target existence (enabled by default)

Peer dependency to React 17

๐Ÿ’ฌ Questions and Help

Hey! Are there any plans to update the peerDependencies to React 17 any time soon?

Prevent warning on SSR context

๐Ÿ› Bug Report

If you use a Teleporter in SSR context app, you will get a warning because of the useLayoutEffect hook in createTeleporter() function.

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.

To Reproduce

Render an app using server-side rendering.

Expected behavior

It should not emit a warning on Node server.

React 18 type error

React 18 is out. I'm getting some type errors, but react-teleporter is otherwise working for me.

Type errors are is when using Component.Source, likely due to removal of implicit children in the new types, explained here: DefinitelyTyped/DefinitelyTyped#56210

const Component = createTeleporter()

<Component.Source>
  <p>test with element</p>
</Component.Source>

error TS2559: Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'.

<Component.Source>
  test with string
</Component.Source>

error TS2559: Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.

I think updating TeleporterType['Source'] to explicitly add children (children?: React.ReactNode) would likely fix.

Placeholder component

๐Ÿš€ Feature Proposal

A clear and concise description of what the feature is.

Add a Placeholder component which serves as default value when no Source is present.

Example implementation: https://gist.github.com/IniZio/68872edc1acf2ecfadf5ffffa06f321a

Motivation

Please outline the motivation for the proposal.

Provider a default value to Target

Example

Please provide an example for how this feature would be used.

const Header = createTeleporter()

<Header.Target/>

<Header.Placeholder>This is placeholder</<Header.Placeholder>

// This is placeholder
const Header = createTeleporter()

<Header.Target/>

<Header.Placeholder>This is placeholder</<Header.Placeholder>

<Header.Source>Source 1</<Header.Source>

// Source 1

Pitch

Why does this feature belong in the xstyled ecosystem?

Example test cases that don't render the Target component

Hi @gregberge ๐Ÿ‘‹

Thanks a lot for your work on this library! I've gone through the test cases, but I'm not clear on what approach you would recommend to test a component that renders a source teleporter but doesn't include the target itself.

For example:

// Assume we have a component that exports => HeaderSource
import HeaderSource from 'components/HeaderSource'

function SomePage() {
  return (
    <main>
      <HeaderSource>Foo Bar</HeaderSource>
      <section>
        lorem ipsum
      </section>
    </main>

How would you go about testing that the component renders correctly with the correct title?

it('should render correct title', () => {
  render(<SomePage />)
  expect(screen.getByText('Foo Bar')).toBeInTheDocument() // fails as HeaderSource doesn't render correctly in JSDOM
});

multiple teleporters, factory for teleporters

I have a page that has 4 sections in it. Each section has a header and some content. I would like to have teleporters for each section on the page so that their children can teleport headers into the header section area. Each section is the same component instantiated with different "titles." It's also possible that the same child, with different props, will be on the same page multiple times.

Is this possible?

It looks like each call to createTeleporter creates a unique instance.

I was thinking that each Target and Source (from a single createTeleporter call) could be position in the tree and when a source is laid into the react tree, it climbs the tree looking for the nearest Target partner. It's not clear that this is the right model.

Is there way to support my scenario or is that not the intent?

There is a way around this of course which is to define and create a teleporter for every parent-child pair that may occur. Perhaps then I don't need a teleporter then just some functions since I'm in the same tree.

target renders null after unmount/mount

๐Ÿ’ฌ Questions and Help

Hi! I'm looking for some help with some odd behavior I've encountered.

Here's the behavior I'm seeing. The setup, without drowning anyone in code, is:

There is a Root component. There is a Parent component (which is rendered by Root) that contains a Teleporter.Target and is in charge of rendering A and B (using the simple router mentioned below). The OldParent is like Parent in that it renders a .Target

  1. unmount OldParent and mount Parent which renders a Teleporter.Target and mounts A, which renders a Teleporter.Source (ok)
  2. within Parent, unmount A and mount B which contains no Teleporter.Source (ok)
  3. unmount B and (re) mount A ๐Ÿ‘‰ results in null teleportation
    ...
  4. if I unmount the Parent component going back to OldParent and then re-mount it (which re-mounts/renders A) the teleportation works as expected.

I wrote my own baby router component which is what's rendering these A and B components based on some in-memory state. I don't think the router is relevant to the bug, but I mention it because it certainly might be. The rendering boils down to

const Route = useMemo(() => views[last(history).key], [views, history]);

...
// <Parent /> looks like
return (
  <View>
    <Route />
  </View>
)

// where <View /> basically looks like
<>
  {children}
  <Teleporter.Target as="footer" />
</>

The furthest I got while debugging is that in subsequent renders of Teleporter.Source, context.element is null so the Source renders null due to https://github.com/smooth-code/react-teleporter/blob/master/src/index.js#L36

throwing a debugger into the useCallback() block, though, shows that context.element is set to null during the unmount of a PreviousComponent (expected) but then immediately set to the correct element when Parent is mounted, never being called again. When the source in A attempts to render the second time, though, the element state is null because context.element is null within the useLayoutEffect hook.

User props for Target

๐Ÿš€ Feature Proposal

All props for Target moves to div(or other dom element defined in as)

Motivation

Need for reduce dom tree size, because now it is nessesary to use nested div:
<div className={css.fill} onClick={handleClick}><StatusBar.Target /></div>

Example

<StatusBar.Target className={css.fill} onClick={handleClick} />

Event bubbling

๐Ÿš€ Feature Proposal

Bubble events up through the target tree, not the source tree. Or make it an option?

Motivation

Portals do some magic to bubble events up through the component tree that calls the portal, not the location where the portal is actually rendered. This is normally what you want with portals (90% of use-cases I've seen are to just dump the target at the end of the document body), but I feel like it may be unexpected behavior for react-teleporter.

P.S.

Super cool lib, love how simple and powerful it is. Nice work!

Reuse target?

Hi, so I have the code below. A create a teleporter and set up it's target. Then renderAComponent will have a switch that renders different components based on some props.

The first component (A) that renders and imports FooterTeleport and defines a <FooterTeleport.Source> works nice but then on an update a different component (B) renders and replaces (A) and also uses <FooterTeleport.Source> nothing shows up in the target.

Is this a bug or am I doing something wrong?

export const FooterTeleport = createTeleporter();

<>
{renderAComponent()}
<div className={styles.flexFooter}>
<FooterTeleport.Target />
</div>
</>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.