Git Product home page Git Product logo

Comments (16)

machineghost avatar machineghost commented on August 19, 2024 2

You can just my repo if you want; it has this functionality already. Of course, it has the downside of not getting any new updates ... but then of course this repo doesn't seem to be actively maintained either, so maybe that doesn't matter?

In any case, to use my repo just change the version in package.json to the repo URL:

"gatsby-plugin-modal-routing": "https://github.com/machineghost/gatsby-plugin-modal-routing/"

(and then of course run npm i)

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024 1

On gatsby-config.js path is not defined. This works ${__dirname}/src/components/modal.js.

Sorry, I left out the import/require line for path (a built-in library). But yeah, the point is that you want to build a full absolute path, by utilizing the current path var (__dirname). It doesn't matter how you build it.

The only thing i haven't figured out yet is how to pass additional props except for the ones you mentioned.
I.e. i have a header inside my modal (which is not part of {children}), i want to pass text there.
I'd prob expect something like: <ModalRoutingContext.Consumer header="my custom header title">
the
You can provide "compile-time" props in the gatsby-config.js file:

{
  resolve: `gatsby-plugin-modal-routing`,
  options: {
    modalProps: {someProp: 5},
    modalComponentPath: path.join(
      __dirname,
      './src/components/ModalComponent'
    )
  }
},

In the above example your component would get passed a props.someProp of 5.

But at "run-time" you just have to use mechanisms you control (hooks, context, etc.) to pass data in. This is because any data (eg. the title) has to somehow live beyond memory/state.

In other words, you could just use, say, link state, on the link to open the modal. This is how the library passes the asModal flag, to render the dialog as a modal initially, but ... when the user reloads the page, that state is lost, including that flag (which is why it then renders as a full page). Presumably you want your modal to still have a title after a reload :)

In general you'll want to derive your modal's title from your URL, and you can do that without passing any title in: just check window.location.

P.S. Also the dialog templates can use Gatsby queries and take a pageContext prop as normal, so if you have a dialog to show say 50 different kinds of cars, you could make a graph query to get all the cars and their IDs. Then in gatsby-node.js, when you make your dialog pages you could use a URL that includes car IDs.

Inside your modal component you could use the ID from the URL to find the car from your graph data with the matching ID, and then display a title of "Buy that car name Dialog".

from gatsby-plugin-modal-routing.

lsirivong avatar lsirivong commented on August 19, 2024

šŸ‘‹ hi @machineghost! This sounds like a great idea. I originally had a similar thought where I wanted to make react-modal an optional dependency.

If you want to put together a proposal or PR for how this would work Iā€™d happily take a look.

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024

PR submitted. As noted, I refactored the library to understand it better, but I understand that refactorings are highly subjective and you may not want them. I submitted them initially to get feedback, but PLEASE feel free to provide feedback of "these refactorings are horrible, please get rid of them entirely and just submit the custom modal stuff".

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024

I should note that the only reason I'd even want to keep the refactorings (well, aside from the fact that I think they might make the code clearer to a future editor) is that I'd also like to make another improvement to this library: I'd like to make it possible for you to define a "background page", so that when someone navigates directly to the modal's URL, it can still show the original page in the background.

Keeping the refactorings would just make the code more familiar and help facilitate doing that, but again I am NOT wedded to them in any way, and if you literally reply to this with just a single sentence ("not a fan") I'll happily redo my commit without them (and no feelings hurt, I promise!)

But on the very off-chance you see them and think "that made sense", I just wanted to get your two cents first.

from gatsby-plugin-modal-routing.

ziyafenn avatar ziyafenn commented on August 19, 2024

Upping this topic. I'm using my own custom <Dialog> and i just can't use this library due to its dependency to react-modal.

from gatsby-plugin-modal-routing.

ziyafenn avatar ziyafenn commented on August 19, 2024

@machineghost thanks a lot. This looks pretty cool!
What would be the best way to style the <dialog>? Just target the CSS classes and restyle them or there is better way? I'd imagine even this library not implementing the Dialog itself within the lib, but that it wraps my own <dialog> so i can customize it as i wish :)

Do you know how i can get rid of div's this lib creates and just use this as a wrapper? Or edit it somehow that i remove the created divs in my own fork? Would be a great help.

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024

First off, sorry: I realized I had a typo (an extra "g" in my name) in my URL. I edited and fixed it to:

 "gatsby-plugin-modal-routing": "https://github.com/machineghost/gatsby-plugin-modal-routing/"

but I imagine you noticed and fixed it yourself if you got things working (if not, please correct it and re-npm i first).

Second (for you or anyone else reading this), I should have clarified how to use it. In gatsby-config.js, when you add the plug-in, provide an extra option of the modalComponentPath:

{
  resolve: `gatsby-plugin-modal-routing`,
  options: {
    modalComponentPath: path.join(
      __dirname,
      './src/components/ModalComponent'
    )
  }
},

Then in /src/components/ModalComponent (or wherever) make whatever modal UI you want, using the arguments that would have gone to React Modal (the dialog's children, a boolean indicating whether the modal should show or not, and a callback you can use to close the modal):

export default ({ children, isOpen, onRequestClose }) => {
  return // any Modal library component or custom component that you want
});

As for:

What would be the best way to style the ? Just target the CSS classes and restyle them or there is better way?

The idea is ... any way you want :) You could, for instance, use the Styled Components library to "bake the CSS into" your own component, or you could use the React CSS Modules library to do it with dynamic classes, or you could use inline style attributes ... or even regular old CSS. Since you control what gets returned, you can add whatever classes/IDs you want.

Do you know how i can get rid of div's this lib creates and just use this as a wrapper? Or edit it somehow that i remove the created divs in my own fork? Would be a great help.

You can see the full scope of what I actually changed in a single commit:
master...machineghost:master

As you can see at the bottom of that link, the render method really isn't creating extra divs (I even used a fragment to avoid them). However, if you can improve on my work, say by removing an unneeded <div>, by all means please submit a PR to my repo, and then we can potentially get all the changes added together to this one (... someday?)

from gatsby-plugin-modal-routing.

ziyafenn avatar ziyafenn commented on August 19, 2024

@machineghost this is perfect!
On gatsby-config.js path is not defined. This works ${__dirname}/src/components/modal.js.

The only thing i haven't figured out yet is how to pass additional props except for the ones you mentioned.
I.e. i have a header inside my modal (which is not part of {children}), i want to pass text there.
I'd prob expect something like: <ModalRoutingContext.Consumer header="my custom header title">

Great job mate!!

from gatsby-plugin-modal-routing.

ziyafenn avatar ziyafenn commented on August 19, 2024

hey @machineghost, thanks a lot for the comprehensive explanation! I made everything work, all looks good.
The only problem I'm facing is that during gatsby build app throws an error.

Here is my gatsby-config.js:

  resolve: `gatsby-plugin-modal-routing`,
  options: {
        modalComponentPath: `${__dirname}/src/components/modal.js`,
        modalProps: { content: {} },
   }

I access the objects inside location.state.content within a modal page by destructing it:

 export default function ContactInfo({ location }) {
  const { contact, username, platform } = location.state.content
  ...
  ...
}

All works perfect on development but throws this error on gatsby build:
WebpackError: TypeError: Cannot read property 'content' of undefined.

I tried accessing first window and then referring to the location and checking first that window and location exist (&&), still the same problem. Have you encountered that?

P.S.
I assume it is not possible to pass functions inside location.state and only static values?

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024

First off, I take it that this line:

modalProps: { content: {} },

was just an approximation. From the rest of the code, I imagine it's actually more like this?

modalProps: { content: { location: someObject } },

If so, it sounds like whatever value you're providing (someObject) is an object, both at development-time and compile-time ... but it only has a state property at development time. Since you're the one providing that value, I don't think it has anything to do with this plug-in.

I assume it is not possible to pass functions inside location.state and only static values?

No, but you can include static values in the URL, and then both the inner-page modal and the page modal will have access to them.

For instance, if contact, username, platform are all strings, you could give your modal a URL of:

www.example.com/modal/contact_modal/contact/[email protected]/username/bobtheuser/platform/windows

Of course, there are limits to how much info you can pass this way. Also, you have to URL encode/decode it (eg. with encodeURIComponent/decodeURIComponent). You can't literally have [email protected] in the URL (like I did): you'd have to to have bob%40example.com ... but as long as you encode/decode things this approach will let you pass a few simple parameters.

If you need anything more complex, you should keep the more complex data in your GraphQL query, and just put the IDs of that data in your URLs.

from gatsby-plugin-modal-routing.

ziyafenn avatar ziyafenn commented on August 19, 2024

@machineghost yeah you're right, that was a problem with the router.

I encountered a bug, which i think has to do with this module. When i test on build / compiled version, on the first run, when opening a link that has state: {modal: true} it gets opened as a page and not as a modal. However, after refreshing the page, it works fine.

from gatsby-plugin-modal-routing.

machineghost avatar machineghost commented on August 19, 2024

I'm unable to reproduce that: on my end everything works fine, even on the first click, in a built version of my site.

Here's the code involved (the getDerivedStateFromProps used in replaceComponentRenderer.js).

  static getDerivedStateFromProps(newProps, state) {
    // TODO: handle history changes
    // Only update the (old) props in state if the location changed
    if (newProps.location.pathname === state.pathname) return null
    const oldProps = state.props
    const oldPageWasModal = _.get(state, 'props.location.state.modal')
    return {
      // ...state,
      pathname: newProps.location.pathname,
      props: newProps,
      // if old page was a modal, keep track so we can render the contents while closing
      // (otherwise keep track so we can render the contents under modals)
      [oldPageWasModal ? 'lastModalProps' : 'prevProps']: oldProps
    }
  }

As you can see, it's just using the props it gets (specifically the location prop, which holds the state from the link), and those should be the same whether you're on the 1st click or any other.

from gatsby-plugin-modal-routing.

decanTyme avatar decanTyme commented on August 19, 2024

I've already covered this in #60, but here's my take on this, just use a hook:

const [modal, closeTo] = useModalRouting({
  modalProps: {
    contentLabel: "Custom content label",
    onAfterOpen: () => {
      console.log("onAfterOpen")
    },
    closeTimeoutMS: 300,
    style: { overlay: {}, content: {} },
    id: "some-id",
    onRequestClose: () => {}, // would error, is an internal-exclusive prop
  },
})

//..
return (
  <div>
    {modal ? (
      <Link to={closeTo}>Close</Link>
    ) : (
      <header className="mb-2">
        <h1>Website Title</h1>
      </header>
    )}

    <h2>Modal Page</h2>

    <Link to="/">Go back to the homepage</Link>
  </div>
)

This allows react-modal to be used as-is; just pass in a config with these props. This is the cleanest API IMO, since it aligns with React's hook concept and doesn't rely on any fancy workarounds just to pass in modal props. This removes the <ModalRoutingContext.Consumer> clutter but it is still available and you can even use both. The gatsby-config.js options still works and will become the "default" props in all modal instances. In my initial testing, it accepts almost all react-modal props, except for isOpen and other props used exclusively internally of course (or maybe still provide a way?).

For now, I don't see any limitations on doing it like this. I also still haven't tried adding support for a custom modal component since I currently don't plan to use another one (react-modal is perfectly fine for my use-case). BUT in my approach you can just use react-modal's contentElement prop, which can take in a custom component! However, as I'm writing this,for some reason, even when put directly in the modal instance as actual props, it doesn't work.

All that's left, then, is to implement these: #47-#29, #58, as I think it there are cases where these are particularly useful.

Anyway, if anyone's interested here's a first look at the hook: decanTyme/gatsby-plugin-modal-routing@master...decanTyme:feat/expose-react-modal-props-hook

from gatsby-plugin-modal-routing.

danilocecilia avatar danilocecilia commented on August 19, 2024

@decanTyme I noticed you haven't published your solution yet, any plans when are you going to push so I can npm i the latest version?

from gatsby-plugin-modal-routing.

decanTyme avatar decanTyme commented on August 19, 2024

@decanTyme I noticed you haven't published your solution yet, any plans when are you going to push so I can npm i the latest version?

Already published here: https://www.npmjs.com/package/@decantyme/gatsby-plugin-modal-routing

Haven't really had time to do stuff on it tho so it might still have some bugs to be ironed out.

from gatsby-plugin-modal-routing.

Related Issues (20)

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.