drop icon indicating copy to clipboard operation
drop copied to clipboard

Horizonal overflow with drop

Open brianmhunt opened this issue 10 years ago • 16 comments

A wide drop will overflow horizontally, making part of the drop invisible. This appears to be as-designed. Here is a jsFiddle illustrating the issue.

It would be really nice, if it is possible, if there were a way for a drop to re-position itself horizontally as it overflows.

The easiest end-user workaround is to add tetherOptions.constraints like this:

 new Drop(
   tetherOptions:
      constraints: [
        to: 'scrollParent',
        attachment: 'together',
        pin: true
      ]
  )

Here is a jsFiddle

Thanks to the brilliant design of tether, this works quite well. The only issue, as you can see from the latter jsFiddle, is that the arrow that points to the target is missing.

So really, what we're talking about here is the little arrow thingy. It's a small thing, but to some it's important, so I thought I'd mention it. :)

Cheers.

brianmhunt avatar Mar 12 '14 14:03 brianmhunt

Is there a workaround for this issue?

Hashedhash avatar Jul 16 '14 17:07 Hashedhash

Would love to use this lib if it supports responsive design. The size of drop, position of arrow should be adjusted and re-positioned automatically.

dkonayuki avatar Sep 12 '14 16:09 dkonayuki

Bumping this; starting to use Drop and would love to use it more, but the constrainToWindow only seems to work for vertical positioning; horizontal simply overflows.

Gorb avatar Feb 19 '15 15:02 Gorb

As a first step, I made some changes to drop and tether. Here's the same jsFiddle from above, with my updated drop.js file used. It keeps the default arrows and just forces the tooltip content to be constrained to the window. This can and should be improved so that the arrow is pointing to its target correctly imo.

In order to accomplish this, I introduced a new option to tether: keepElementAttached. When an element is pinned, its attachment to its target, and the target's attachment to it are both severed. With keepElementAttached, the element's attachment is retained, but the target's attachment is severed. This allows the element to be styled as it would if it were fully attached, but still remain inside the window.

Drop, by default, should set keepElementAttached to true in order to keep its arrows. So I added the new drop option retainArrows to facilitate this.

markalfred avatar Apr 06 '15 16:04 markalfred

@markalfred That's awesome! Would you mind creating a PR with your changes to possibly get these changes into the project? Would love to iterate on your contributions as this is definitely an issues we've run into as well (and clearly many others) :smile_cat:

geekjuice avatar May 12 '15 04:05 geekjuice

@geekjuice I've been playing with other potential solutions. For our project, we decided to patch drop so that a center-attached element could change to a left- or right-attached in order to keep it in the viewport. Which solution do you feel is more in line with the goals of the project?

Example:

drop

markalfred avatar May 12 '15 14:05 markalfred

I think that this is what most people (including myself) would expect to happen unless specified otherwise. This is really awesome though and I'd love to see how you are accomplishing this. Ideally, it would be nice to offer both solutions via some options, but if I had to choose one, definitely the latter. :+1: :tada:

geekjuice avatar May 12 '15 14:05 geekjuice

:+1: It's via a tether patch here. The example above uses these custom options:

tetherOptions:
  attachment: 'top center'
  targetAttachment: 'middle center'
  constraints: [
    to: 'window'
    attachment: 'together element'
  ]

But I can explore bubbling these settings up to drop itself.

markalfred avatar May 12 '15 14:05 markalfred

Ah if it's through tether, I think it's better to keep it that way.

geekjuice avatar May 12 '15 14:05 geekjuice

I'd prefer the latter solution as well, as the first solution could lead to the arrow no longer pointing to the target correctly. I vote for including the patch of markalfred in Tether.

@markalfred As tether is no longer CoffeeScript based, maybe you could redo your patch to fit the current Tether version? That'd be awesome :-)

NicBright avatar Jun 29 '15 08:06 NicBright

@markalfred: I'm also interested in your auto-positioning patch. See #100.

dandv avatar Jul 19 '15 20:07 dandv

+1 Is there any news on this matter? Horizontal auto positioning would be great!

jonerd avatar Feb 08 '16 16:02 jonerd

I stumbled upon this problem as well and is currently using this workaround until it's fixed in the project:

/**
 * Create the drop and register subscription to open event
 */
let drop = new Drop(options);
drop.on('open', () => positionDrop(drop));

/**
 * Ensures drop is horizontally within viewport (vertical is already solved by drop.js).
 */
function positionDrop(drop) {
    let dropWidth = drop.drop.getBoundingClientRect().width,
        left = drop.target.getBoundingClientRect().left,
        right = $(window).width() - left,
        direction = dropWidth > right ? 'right' : 'left';

    drop.tether.attachment.left = direction;
    drop.tether.targetAttachment.left = direction;
    drop.position();
}

I tried version 1.2.0 of Tether - which includes a fix for horizontal positioning - but couldn't get it to work.

streamside avatar Feb 26 '16 16:02 streamside

Did anyone have any luck with @streamside's code? It's not working for me, but I definitely could be doing something wrong. Edit: Woops! Silliness on my part, thanks streamside - works great!

Edit: It turns out that it's a bit hit and miss. See my comment here for a better solution.

josephrocca avatar Mar 14 '17 17:03 josephrocca

@streamside code help me a lot. Thank you. However it still contain a little bug which it does not support center align.

ve3 avatar Jul 03 '17 09:07 ve3

In case it's helpful to anyone, here's my iteration on @streamside's function to support center position

function positionDrop(drop) {
    let bodyRect = document.body.getBoundingClientRect(),
        dropHalf = drop.drop.getBoundingClientRect().width / 2,
        targetRect = drop.target.getBoundingClientRect(),
        targetCenter = targetRect.width / 2 + targetRect.left,
        horizontal = 'center'

    if (targetCenter - dropHalf < 0 ) {
        horizontal = 'left'
    } else if (targetCenter + dropHalf > bodyRect.right) {
        horizontal = 'right'
    }

    drop.tether.attachment.left = horizontal
    drop.tether.targetAttachment.left = horizontal
    drop.position()
}

samhernandez avatar Oct 19 '17 16:10 samhernandez