React-draggable bounds attribute doesn't work if I don't have a fixed height (I think) - but I can't

Viewed 353

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%;
}

Now my page looks like this: photo

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.

photo2

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)

photo3

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?

0 Answers
Related