I'm using the react-draggable package in order to make some elements draggable.
I want to set the elements to be able to be dragged only in a specific part of the page, and that can be done with the "bounds" attribute according to the docs.
So I want to set the bound to the parent element. It can be done using bounds="parent", and having an element with position: relative/absolute and a fixed width and height. Then this element will be considered the parent.
I don't really know how to create a minimal, reproductive, example in this case (if someone would help me I'll gladly do it) because I have multiple react components and also images. I know about TypeScript Playground, but I don't know how can I link CSS/images/other components there.
Here are my components though: DraggableGameStart.tsx
import GameDetails from '../GameComponents/GameDetails';
import GameImage from '../GameComponents/GameImage';
import DraggableGameAnswers from './DraggableGameAnswers';
import './css/DraggableGameStart.css';
import DraggableGameSlots from './DraggableGameSlots';
function DraggableGameStart() {
return (
<div className="draggable-game-content">
<div className="draggable-game">
<GameDetails
info="test"
question="test"
/>
<GameImage
images={[{ imgSrc: './Untitled.png', imgAlt: 'test' },
{ imgSrc: './Untitled.png', imgAlt: 'test' },
{ imgSrc: './Untitled.png', imgAlt: 'test' },
{ imgSrc: './Untitled.png', imgAlt: 'test' }]}
className="draggable-game-image"
/>
<DraggableGameSlots
numberOfSlots={4}
className="draggable-game-slot-custom4"
/>
<DraggableGameAnswers/>
</div>
</div>
);
}
export default DraggableGameStart;
GameDetails.tsx
import './css/GameDetails.css';
import Audio from './Audio';
type GameDetailsProps = {
info: string,
question: string
}
function GameDetails(props: GameDetailsProps) {
return (
<div className="game-details">
<div className="game-details-header">
<div className="game-details-content">
<div className="info">
<span className="info-text">
{props.info}
</span>
</div>
<div className="question">
<span className="question-text">
{props.question}
</span>
</div>
</div>
<Audio/>
</div>
</div>
);
}
export default GameDetails;
GameImage.tsx
import './css/GameImage.css';
type Image = {
imgSrc: string,
imgAlt: string
}
type GameImageProps = {
images: Array<Image>,
className: string
}
function GameImage(props: GameImageProps) {
return (
<div className="game-image-wrapper">
{props.images.map((pair) => (
<img className={props.className} src={process.env.PUBLIC_URL + pair.imgSrc} alt={pair.imgAlt} />
))}
</div>);
}
export default GameImage;
DraggableGameSlots.tsx
import "./css/DraggableGameSlots.css";
type DraggableGameSlotsProps = {
className: string,
numberOfSlots: number
}
function DraggableGameSlots(props: DraggableGameSlotsProps)
{
let sloturiConfigurate = Array<boolean>(props.numberOfSlots).fill(true);
return (
<div className="draggable-game-slots">
{
sloturiConfigurate.map((val, index) => (
<div className={`draggable-game-slot ${props.className}`}>
Drop here
</div>
))
}
</div>
);
}
export default DraggableGameSlots;
DraggableGameAnswers.tsx
import Draggable from 'react-draggable';
import DraggableGameImage from './DraggableGameImage';
import './css/DraggableGameAnswers.css';
function DraggableGameAnswers() {
return (
<div className="draggable-game-answers">
<DraggableGameImage className="draggable-game-image-answer" imgSrc="./Untitled.png" imgAlt="test"></DraggableGameImage>
<DraggableGameImage className="draggable-game-image-answer" imgSrc="./Untitled.png" imgAlt="test"></DraggableGameImage>
<DraggableGameImage className="draggable-game-image-answer" imgSrc="./Untitled.png" imgAlt="test"></DraggableGameImage>
<DraggableGameImage className="draggable-game-image-answer" imgSrc="./Untitled.png" imgAlt="test"></DraggableGameImage>
</div>
);
}
export default DraggableGameAnswers;
Now, the CSS
DraggableGameStart.css
.draggable-game-content {
width: 100%;
height: 40rem;
}
.draggable-game {
position: relative;
border: 1px solid black;
border-radius: 25px;
margin-left: 1.5rem;
height: 38rem;
text-align: center;
margin-bottom: 1rem;
}
GameDetails.css
.game-details {
padding-top: 1rem;
}
.info, .question{
border: 1px solid black;
border-radius: 1.5rem;
text-align: left;
margin: 0.1rem 0;
height: 2.5rem;
line-height: 2.5rem;
align-items: center;
}
.game-details-header {
display:flex;
flex-direction:row;
justify-content: center;
}
.game-details-content {
width:75%;
}
.info-text, .question-text {
margin-left: 1.25rem;
}
GameImage.css
.game-details-image {
margin-top: 2rem;
border-radius: 15px;
width: 200px;
height: 200px;
}
.game-answers-image {
border-radius: 15px;
width: 200px;
height: 200px;
margin: 0 !important;
padding: 0 !important;
}
.draggable-game-image {
border-radius: 15px;
margin: 1rem;
}
DraggableGameSlots.css
.draggable-game-slot {
display: inline-block;
border-radius: 15px;
margin: 0 1rem 1rem 1rem;
border: 1px dashed black;
width: 200px;
height: 200px;
line-height: 200px;
}
DraggableGameAnswers.css
.draggable-game-answers {
height: 100%;
}
due to the height settings in DraggableGameStart.
But the content overflows - and I just can't set the height to be more, because in the other components this height is sufficient for my layout, this is the only page where it overflows.
So I thought about changing the height to min-height - and my page will look okay then.
The only problem is that now the bounds attribute of react-draggable doesn't work properly - the element is dragged only on the top of the .draggable-game div, and only horizontally. Here's what happens if I drag a bit a button (just so the events are fired)
And from this position it can be dragged only horizontally.
So, my question is: is there any way to make the bounds setting work properly while also having set the min-height property? Or is there any better way to achieve what I want without using min-height and while also making bounds work?


