React onDrag not working but onDragStart works - reactjs

I have a simple component with a draggable icon next to it (going to implement my own Resize).
The code is as follows:
type ICanvas = {
currPageId:string
}
const Canvas:FC<ICanvas> = ({currPageId}) => {
const story = useStoryStore(state=>state.story);
const handleDragStart = (e:any) => {
console.log("start")
};
const handleOnDrag = (e:any) => {
console.log("on drag");
};
return (
<Box {...Styles.CanvasContainer} pos='relative'>
<div
className="resize-button"
draggable
onDrag={handleOnDrag}
onDragStart={handleDragStart}
onDragEnd={handleOnDrag}
>
<HorizonIcon type='arrow_chevron_down'/>
</div>
</Box>
)
}
export default Canvas;
The onDragStart event fires as it should, but onDrag doesn't work. I tried adding e.stopPropagation/preventDefault everywhere in all possible permutation but nothing.
I even tried using the Chrome inspect event breakpoints and nothing.
I am using latest react version with Chakra UI provider.
Thanks!

So after some digging and a little bit of luck I found out that I had in my system a dependancy of React-dnd-HTML5backend.
With a little google research I found out that this library causes problem with native dragging events within every application it is installed in.
So the solution would be using react-dnd that I already have installed in my project.

Related

React Bootstrap - Controlled Carousel does not scroll anymore

I use React Bootstrap Carousel in my GatsbyJS project.
I have an issue with the controlled carousel because does not scroll anymore.
I use in a component that display 3 Carousel items.
const SimpleCarousel = () => {
const [index, setIndex] = useState(0)
const items = [1, 2, 3]
function handleSelect(selectedIndex, e) {
setIndex(selectedIndex)
}
return (
<Carousel
activeIndex={index}
onSelect={handleSelect}
>
{items.map((item) => (
<Carousel.Item key={`carousel-item-${item}`}>
<h2>Title {item}</h2>
</Carousel.Item>
))}
)
}
export default SimpleCarousel;
I use activeIndex with a state and onSelect handler as in documentation, but the handler function is not called and the active index does not change.
It works with multiple <Carousel.Item> but not after a map.
Configuration :
Windows 10
node : 12.16.1
react-bootstrap : 1.6.1
boostrap : 4.6.0
I have created a sandbox and copy pasted your code. I noticed that the closing tag of carousel is missing: </Carousel>. Maybe this is the problem and you don't get a proper error somehow?
Anyway the sandbox is working just with copy/pasing your code. The items are changing after few seconds. The onSelect handler is called every time: https://codesandbox.io/s/winter-monad-hv83g4
This is react-boostrap v2 though. I can't manage to add an older version of it as dependency (v1). So when then sandbox is working and yours are not, I assume it's a react-bootstrap 1.6.1 specific issue.

Manually closing the calendar primereact

I'm using primereact version 6.2.1, While using the calendar from primereact i have enabled the option for showTime. This brings up a datePicker with an overlay blocking out the rest of the webpage. All this works fine. Except after a date and time are picked the only way to close the datePicker is to click somewhere else on the browser. Is there a way to close it manually ?
import React, { useRef } from 'react';
import { Calendar } from 'primereact/calendar';
const CustomCalendar = (props) => {
const cal = useRef(null);
const handleClose = () => {
cal.current.hideOverlay()
// if you're using touchUI option you have to hade it also ;)
cal.current.touchUIMask.style.display = "none";
};
return <Calendar
ref={cal}
{...props}
footerTemplate={(e) => <div className='footer-calendar'><button onClick={handleClose}>Done</button></div>}
/>
}
You can close overlay manually using ref, you can check this link
sandbox
or check the github link for more options
github
If you get a ref to your Calendar you can call calendarRef.current.hideOverlay();
I also opened this ticket: https://github.com/primefaces/primereact/issues/2685
Submitted this PR: https://github.com/primefaces/primereact/pull/2687

Is it possible to get SVG to work well with react-top-print?

Idea is to print pdf documents that I am dislaying in pdfviewer component that I have created. I am getting Uint8Array from the server and that is rendered inside component. All works, so good so far.
Problem starts with implementing printing functionality inside my pdf viewer. I am rendering pdf with react-pdf library as SVG.
const PdfViewer = (props) => {
// removed code that is not important for this issue
const elmRef= useRef()
// removed code that is not important for this issue
const handlePrint = useReactToPrint({
content: () => elmRef.current
});
//const handlePrint = useReactToPrint({
return (
<Dialog className="dialogBox" title={props.dataItem[props.field]} onClose={props.modalAction} height={'95vh'} width={'90vw'} onClose={props.onClose}>
<PdfDocumentControls
handlePrint={handlePrint}
/>
<BasePdfViewer className='pdfViewer' pageNumber={pageNumber} file={file} onDocumentLoadSuccess={onDocumentLoadSuccess} zoom={zoom} refElm={elmRef} />
{props.children}
</Dialog>
);
};
When "handlePrint" triggers I am getting dialog box, but it seems not to be able to render svg.
Question: Is there a way to render this SVG properly, as text inside print box?
Solution: As usual, after few days of struggling and just after posting question on SO, brain starts to function and I came with solution.
Rendering pdf as canvas instead of SVG solves the problem, and pdf prints out as intended.
Ty. Cheers

Input fields inside react overlays doesnt work in modal

I have modal screen (using react-bootstrap), on modal screen i have multiple overlays (popup menus) linked to items. These overlays has inputs, and when i click on input it immediately loses focus. I cant figure out whats wrong, because another one popup menu, that i have on normal screen, not modal, works fine. Tried to set autofocus, but it immediately loses too.
I wrote example, https://codesandbox.io/s/rkemy
I think it is somehow connected with popper, because bootstrap overlay uses it, dont know where to dig
The fix provided in the other response is a workaround that doesn't fix the real cause of the issue.
The issue is caused by an internal logic of the Modal component of react-overlay library that is a dependency library of react-bootstrap.
Specifically, the issue is caused by code listed below
const handleEnforceFocus = useEventCallback(() => {
if (!enforceFocus || !isMounted() || !modal.isTopModal()) {
return;
}
const currentActiveElement = activeElement();
if (
modal.dialog &&
currentActiveElement &&
!contains(modal.dialog, currentActiveElement)
) {
modal.dialog.focus();
}
});
that enforce the focus on the first modal open as soon as that modal lose the focus, like when you move the focus on the input.
In order to solve the issue, you have to pass the enforceFocus={false} to your Modal component.
The documentation of the API can be found here: https://react-bootstrap.github.io/react-overlays/api/Modal#enforceFocus
As the docs says:
Generally this should never be set to false as it makes the Modal less accessible to assistive technologies, like screen readers. but in your scenario this is a need to work properly.
Solution is to wrap Overlay in container:
import React from "react";
import { Overlay } from "react-bootstrap";
import { X } from "react-bootstrap-icons";
export const PopupMenuWrapper = (props) => {
const { target, title, show, onClose, children } = props;
const ref = React.useRef(null);
return (
<div ref={ref}>
<Overlay
container = {ref.current}
target={target.current}
show={show}
placement="bottom-start"
rootClose={true}
onHide={onClose}
>
...
</div>
...

How to use useNavigate previous page without accidentally leaving my site

Problem: I'm trying to use useNavigate(-1) to go to previous page, but I just implement a way to people arrive in my SPA with a pasted link (or social media tho), so, when user tries to go back they leave my site xP.
Process: I could use useNavigate("/"), but this makes my page scroll to the top and I want to keep the previous users position, I rather not use a state with my scroll position, but if nothing else is possible or simple...
Context: is a restaurant menu ifood-like page, this problems occurs in product page and I want to go back to product list.
What I'm trying to achieve: some way to check if previous page is out of my domain and not go there, replacing with my root.
ps. I'm using "react-router-dom": "^6.0.0-beta.0"
In earlier versions of React Router DOM, there was a smarter goBack method, but in modern versions (including the v6 beta), you must use the fact that the location.key is "default" for the initial entry to the app's history.
I created an npm package that encapsulates this functionality in a simple React hook.
Install use-back
npm install use-back
Usage
import {useBack} from "use-back";
const BackButton = () => {
const {hasBack, handleBack} = useBack();
return (
<button type="button" onClick={handleBack}>
{hasBack ? "Go Back" : "Go Home"}
</button>
);
};
CodeSandbox Demo
Source Code
The source code is basically the following, which you can also include in your application.
const MagicalBack = () => {
const navigate = useNavigate();
const location = useLocation();
const hasPreviousState = location.key !== "default";
const handleClick = () => {
if (hasPreviousState) {
navigate(-1);
} else {
navigate("/");
}
};
return (
<button type="button" onClick={handleClick}>
{hasPreviousState ? "Go Back" : "Go Home"}
</button>
);
};
CodeSandbox Demo

Resources