tech-systems / panes

🎉📱 Create dynamic modals, cards, panes for your applications in few steps. One instance – Thousands solutions. Any framework and free.
https://panejs.com
MIT License
687 stars 40 forks source link

Pane Break Points dont work as expected when changing screen layout #238

Open primeKal opened 5 months ago

primeKal commented 5 months ago

Describe the bug I want to display the bottom sheet pane when the browser is in mobile view and destroy the pane on desktop view. I am using these break points breaks: { top: { enabled: true, height: 160, bounce: true }, middle: { enabled: true, height: 80, bounce: true }, bottom: { enabled: true, height: 50 }, }, Works perfectly when opening the page on mobile view(even mobile) the problem I am facing is whenever I inspect and increase the screen width(layout disappears) and then decrease the screen width I expected the height to be the same(at least similar) but my pane now is stuck to the bottom with very little breakpoints(even hard to know if they exists) One might argue this wont happen in reality, another incident of this is when I have an input field inside the pane and open the page with mobile browser works perfectly, but after pressing the input fields(the screen gets smaller) and entering text and searching, the pane is again stuck to the bottom giving the same behavior as the previous) I am not sure if this is a bug or not but any help is much appreaciated. Working with

To Reproduce Steps to reproduce the behavior: Copy and Paste the following code - BottomSheetComponenet

import React, { ReactElement, useContext, useEffect } from "react" import { useBottomSheet } from "./useBottomSheet" import { CupertinoSettings } from "cupertino-pane" import ModalStateContext from "../Map/context"

  export interface SheetProps {
    children: ReactElement
    isDisplayed: boolean
  }

  const BottomSheet = ({ children, isDisplayed }: SheetProps) => {
    const { state } = useContext(ModalStateContext)
    const settings: CupertinoSettings = {
      parentElement: "body",
      breaks: {
        top: { enabled: true, height: 160, bounce: true },
        middle: { enabled: true, height: 80, bounce: true },
        bottom: { enabled: true, height: 50 },
      },
      // bottomClose: false,
      // freeMode: true,
      buttonDestroy: false,
      events: {
        onDrag: () => console.log("Drag event"),
      },
    }

    const { presentPane, hidePane } = useBottomSheet(".cupertino-pane", settings)
    useEffect(() => {
      console.log("in render")
      if (isDisplayed) {
        presentPane()
      } else {
        hidePane()
      }
    }, [isDisplayed])
    useEffect(() => {
      console.log("in first render")
      if (isDisplayed) {
        presentPane()
      } else {
        hidePane()
      }
    }, [])

    return (
      <>
        <button onClick={presentPane}>Open Pane</button>
        <div className="cupertino-pane">
          {/* Your pane content goes here */}
          {children}
        </div>
      </>
    )
  }

  export default BottomSheet
  `
```custom hook for this bottom sheet 
`// hooks/useCupertinoPane.ts
import { useContext, useEffect, useRef, useState } from "react"
import { CupertinoPane, CupertinoSettings } from "cupertino-pane"
import ModalStateContext from "../Map/context"

export const useBottomSheet = (
  selector: string,
  settings: CupertinoSettings,
) => {
  const paneRef = useRef<CupertinoPane | null>(null)
  const [showContent, setShowContent] = useState(false)
  const { state, dispatch } = useContext(ModalStateContext)

  useEffect(() => {
    if (!paneRef.current) {
      paneRef.current = new CupertinoPane(selector, {
        ...settings,
        bottomClose: false, // Ensure bottomClose is false
        events: {
          onDrag: (event) => {
            if (event.to === "bottom") {
              setShowContent(true)
            } else {
              setShowContent(false)
            }
          },
        },
      })
    }
    // presentPane()
    // if (state.showSearchModal) {
    paneRef.current.present({ animate: true })
    // } else {
    //   paneRef.current.hide()
    // }

    return () => {
      paneRef.current?.destroy()
    }
  }, [])

  const presentPane = async () => {
    console.log("in pane presenter")
    console.log("Presenting pane", paneRef.current?.isPanePresented())
    // if(paneRef.current && !paneRef.current?.isPanePresented()) {
    await paneRef.current?.destroy()
    paneRef.current?.present({ animate: true })
    // }
  }
  const hidePane = async () => {
    console.log("in pane hider")
    await paneRef.current?.present()
    // paneRef.current?.hide()
    paneRef.current?.destroy({ animate: true })
  }

  return { presentPane, hidePane }
}

This is how i called it

{secondaryChild}

isMObile is just a state that checks for windows size change

  useEffect(() => {
    setIsLoading(true)
    apiCall("")

    function handleResize() {
      const isMatch = window.matchMedia("(max-width: 767px)").matches
      console.log(isMatch, "mobile view")
      setIsMobile(isMatch)
    }

    // Attach event listener
    window.addEventListener("resize", handleResize)

    // Call handler right away so state gets updated with initial window size
    handleResize()

    return () => window.removeEventListener("resize", handleResize)
  }, [])`

Expected behavior I just want the height of the pane to remain as it was on first rendering

Screenshots image image

Additional context I am not sure if this is a bug or not, but please if its not can i get a demonstration for typescript

roman-rr commented 5 months ago

@primeKal Big thank you for detailed information including screenshots. I will check in couple days.