Reputation: 173
i have some issues with positioning my modal. I spend lot of time trying to swipe my modal component between other components to get better result but right now i don't really know how to fix it. I have a signup form and I want to trigger the modal in the center of the screen when user click on the button below. Problem is, modal is not opening in the center, its opening from position it was triggered. I have to use absolute class because if I wont, modal is not overriding the page. Any suggestions?
Here is the modal code
import { Component, createSignal } from "solid-js";
const TermsModal = function () {
const [isOpen, setIsOpen] = createSignal(false);
return (
<div class="flex absolute justify-center">
<button
class="text-sm font-bold text-blue-500 uppercase focus:outline-none"
onClick={() => setIsOpen(true)}
>
Privacy Policy
</button>
{isOpen() && (
<>
<div
role="presentation"
class=""
onClick={() => setIsOpen(false)}
onKeyPress={(e) =>
(e.key || e.code) === "Escape" ? setIsOpen(false) : null
}
></div>
<section
role="dialog"
class=" p-4 text-center border-gray-200 rounded-lg shadow sm:p-8 bg-zinc-700"
>
<button aria-label="Close Dialog" onClick={() => setIsOpen(false)}>
× Close button
</button>
{/* Here starts modal content */}
<h1>Terms of Service</h1>
{/* Here ends modal content */}
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi
quaerat totam cumque hic voluptatum sit ratione itaque aspernatur,
possimus ex beatae quo repudiandae dignissimos iure eum
exercitationem labore, corrupti adipisci.
</p>
</section>
</>
)}
</div>
);
};
export default TermsModal;
And here is how i am calling a modal. Its inside the input form together with checkbox. (I also want to make it in one line, but failed)
<label class="text-white m-5 p-1">
<input type="checkbox" checked={false} onChange={handleCheck} />
I have read and agree to the <TermsModal />{" "}
</label>
Upvotes: 0
Views: 1415
Reputation: 13678
That is probably because you are rendering the modal window as a child component of some element. You need to use Portal
to render the modal window as a direct child of the body element so that it won't be affected by its parent's z-index or other css properties.
import { render, Portal } from "solid-js/web";
const style = `
border: 1px solid red;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-flow: column no-wrap;
align-items: center;
justify-content: center;
`
const Component = () => {
return <div style={style}>Inner Content</div>
};
const App = () => {
return <Portal mount={document.body}><Component /></Portal>;
};
render(() => <App />, document.body);
https://playground.solidjs.com/anonymous/13e0670c-79e3-4899-8ed0-151dd531e8c2
You can learn more about Portal:
If you don't want to use a portal and don't need reactivity inside the modal window, you can use onMount
hook to append the modal window to the body element and onCleanup
to remove it.
import { batch, createSignal, onMount, onCleanup } from "solid-js";
import { render } from "solid-js/web";
const style = `
border: 1px solid red;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-flow: column no-wrap;
align-items: center;
justify-content: center;
`
const Component = () => {
const modal = document.createElement("div");
modal.innerHTML = "Some Content";
modal.setAttribute("style", style);
onMount(() => {
document.body.appendChild(modal);
});
onCleanup(() => {
document.body.removeChild(modal);
});
return null;
};
const App = () => {
return <Component />;
};
render(() => <App />, document.body);
Upvotes: 2