lbs91
lbs91

Reputation: 173

Modal positioning in tailwind solidjs app

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)}>
          &times 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} />
    &nbsp;I have read and agree to the <TermsModal />{" "}
   </label>

Before triggering

After triggering

Upvotes: 0

Views: 1415

Answers (1)

snnsnn
snnsnn

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

Related Questions