Comments (16)
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.
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 thegatsby-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.
š 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.
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.
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.
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.
@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 div
s in my own fork? Would be a great help.
from gatsby-plugin-modal-routing.
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 div
s (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.
@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.
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.
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.
@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.
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.
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.
@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 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)
- Animate on closing modal HOT 3
- Hooks not working inside modal - Most likely breaks my Context.Provider HOT 1
- Open specific route always in modal HOT 1
- Doesn't work with TransitionLink HOT 5
- Is there a way to navigate to next/prev modals as in the gatsbygram example? HOT 1
- Provide an example for using custom CSS classes HOT 2
- Background scrolls while modal is open HOT 2
- Different Result on gatsby develop vs. build HOT 4
- Page is not rendered as modal when refreshed. HOT 2
- Transition between modals HOT 3
- Needs to merge PR to fix location accessing HOT 9
- Code Splitting
- Needs an update for supporting gatsby v3 HOT 2
- Close To with parameters
- Always `false` + different props than docs HOT 8
- Has anyone tested this in react testing library?
- A context consumer was rendered with multiple children error HOT 1
- Support for Gatsby 4.0 HOT 8
- I faced same problem, how can we use this plugin within Gatsby v4?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gatsby-plugin-modal-routing.