Giter VIP home page Giter VIP logo

Comments (7)

mylesfarm avatar mylesfarm commented on July 19, 2024 6

+1 for this idea, I too would like to add a border to the arrow as in @tonix-tuft's demo.

from react-tiny-popover.

StevenYuysy avatar StevenYuysy commented on July 19, 2024 3

Here is a workaround for adding border to arrow. base on @tonix-tuft 's code.

function getArrowStyle(position: string, arrowSize = 10) {
  switch (position) {
    case 'left':
      return {
        right: 1,
        borderLeft: `${arrowSize}px solid white`,
        zIndex: 1,
      };
    case 'right':
      return {
        left: 1,
        borderRight: `${arrowSize}px solid white`,
        zIndex: 1,
      };
    default:
      return {
        bottom: 1,
        borderTop: `${arrowSize}px solid white`,
        zIndex: 1,
      };
  }
}

// ...
<Popover
  isOpen={isOpen}
  position="top"
  content={({ position, targetRect, popoverRect }) => {
    const arrowSize = 4;
    return (
      <ArrowContainer
        position={position}
        targetRect={targetRect}
        popoverRect={popoverRect}
        arrowSize={arrowSize}
      >
        <ArrowContainer
          position={position}
          targetRect={targetRect}
          popoverRect={popoverRect}
          arrowSize={arrowSize}
          style={{
            paddingLeft: 0,
            paddingTop: 0,
            paddingBottom: 0,
            paddingRight: 0,
          }}
          arrowStyle={getArrowStyle(position, arrowSize)}
        >
          {/* popover content */}
        </ArrowContainer>
      </ArrowContainer>
    );
  }}
>
{/* children */}
</Popover>
// ...

from react-tiny-popover.

tonix-tuft avatar tonix-tuft commented on July 19, 2024

@adammlr I was able to kinda achieve what you say by wrapping ArrowContainer in another ArrowContainer and overriding some CSS styles with !important:

...
return (
            <div className="my-component">
                <Popover containerClassName="my-component-popover"
                    isOpen={isPopoverOpen}
                    align="end"
                    position="bottom"
                    onClickOutside={this.props.onPopoverClickOutside}
                    disableReposition
                    padding={8}
                    content={({ position, targetRect, popoverRect }) => (
                        <ArrowContainer position={position}
                            targetRect={targetRect}
                            popoverRect={popoverRect}
                            arrowSize={10}>
                            <ArrowContainer position={position}
                                targetRect={targetRect}
                                popoverRect={popoverRect}
                                arrowSize={10}>
                                <div className="my-component-popover-content">
                                    Hi! I'm popover content. Here's my position: {position}.
                                </div>
                            </ArrowContainer>
                        </ArrowContainer>
                    )}>
                    <div onClick={this.props.onTogglePopover}>
                        Click me!
                    </div>
                </Popover>
            </div>
)

And the CSS:

.my-component-popover {
    overflow: visible !important;

    & > div > div:first-child {
        border-bottom-color: white !important;
        top: 1px !important;
        z-index: 999999 !important;
    }

    & > div > div > div:first-child {
        border-bottom-color: #ccc !important;
    }

    & > div > div {
        padding: 0 !important;
    }

    .my-component-popover-content {
        background: white;
        padding: 10px;
        border: 1px solid #ccc;
        box-shadow: 0 10px 15px rgba(0,0,0,0.05), 10px 0px 15px rgba(0,0,0,0.05), -10px 0px 15px rgba(0,0,0,0.05), 0px -5px 40px rgba(0,0,0,0.05);
    }
}

Result:

Screen Shot 2019-08-13 at 00 57 44

Anyway, I think it would be very useful and great if the library provided us with the possibility to pass a custom className prop to the div element of the arrow element (maybe <ArrowContainer arrowClassName="my-custom-class-name" ... />), as well as to the padding div element which wraps the arrow and the popover content.

Then the styling with CSS would be far way easier than now.

from react-tiny-popover.

mckenziec avatar mckenziec commented on July 19, 2024

Nesting ArrowContainers is a neat idea but the padding override isn't working for me. The double left padding of 10px bumps the popover away from the arrow. It would be awesome if tiny-popover just supported arrow outlines instead of having to write a page of inline style overrides. That generated inner div is a real pain to override the padding on.

from react-tiny-popover.

tonix-tuft avatar tonix-tuft commented on July 19, 2024

Yeah, I agree with you, but it worked in my case, though it's hacky...

from react-tiny-popover.

McWatt avatar McWatt commented on July 19, 2024

Missing bottom styles case for @StevenYuysy's fix:

case "bottom":
	return {
		top: 1,
		borderBottom: `${arrowSize}px solid white`,
		zIndex: 1,
	};

from react-tiny-popover.

snoolord avatar snoolord commented on July 19, 2024

for anyone looking at this in 2024, there is breaking changes with targetRect -> childRect and @tonix-tuft & @StevenYuysy 's solution is really slick. it basically is overlaying two "triangles" on top of each other to make it look like there is a "border" on the triangle.
I only needed the 'bottom' case but you'll need to play around with the top, bottom, left, right values in the functions below depending on the padding of your popover content and direction.

getArrowStyle -> moves the "arrow"
getArrowBorderStyle -> moves the "arrow"s border

                const arrowColor = '#272725'
                const arrowBorderColor = '#575350'
                function getArrowStyle(position?: string, arrowSize = 10) {
                  switch (position) {
                    case 'left':
                      return {
                        right: 1,
                        borderLeft: `${arrowSize}px solid ${arrowColor}`,
                        zIndex: 1
                      }
                    case 'right':
                      return {
                        left: 1,
                        borderRight: `${arrowSize}px solid ${arrowColor}`,
                        zIndex: 1
                      }
                    case 'bottom':
                      return {
                        top: -16,
                        borderBottom: `${arrowSize}px solid ${arrowColor}`,
                        zIndex: 1
                      }
                    default:
                      return {
                        bottom: 1,
                        borderTop: `${arrowSize}px solid ${arrowColor}`,
                        zIndex: 1
                      }
                  }
                }

                function getArrowBorderStyle(position?: string, arrowSize = 10) {
                  switch (position) {
                    case 'left':
                      return {
                        right: 1
                      }
                    case 'right':
                      return {
                        left: 1
                      }
                    case 'bottom':
                      return {
                        top: -18
                      }
                    default:
                      return {
                        bottom: 1
                      }
                  }
                }

                const arrowSize = 8
                return (
                  <ArrowContainer
                    position={position}
                    childRect={childRect}
                    popoverRect={popoverRect}
                    arrowSize={arrowSize}
                    arrowColor={arrowBorderColor}
                    arrowStyle={getArrowBorderStyle(position, arrowSize)}
                  >
                    <ArrowContainer
                      position={position}
                      childRect={childRect}
                      popoverRect={popoverRect}
                      arrowSize={arrowSize}
                      style={{
                        paddingLeft: 0,
                        paddingTop: 0,
                        paddingBottom: 0,
                        paddingRight: 0
                      }}
                      arrowColor={arrowColor}
                      arrowStyle={getArrowStyle(position, arrowSize)}
                    >
                      <span
                        className={cn(
                          'bg-popover shadow-md rounded p-5',
                          `border border-[${arrowBorderColor}] `
                        )}
                      >
                        oooo that arrow is so nice
                      </span>
                    </ArrowContainer>
                  </ArrowContainer>
                )
              }}
            >
              <div
                className={cn(
                  'not-draggable flex items-center',
                  'rounded-sm py-1.5 px-2.5 hover:cursor-pointer hover:bg-toolbar-viewHover'
                )}
                onClick={() => {
                  setIsConfigOptionsOpen(!isConfigOptionsOpen)
                }}
              >
                <CircleEllipsis size={20} />
              </div>
            </Popover>

PixelSnap 2024-03-15 at 22 48 26@2x

hope that helps!

standing on the shoulders of giants gif

from react-tiny-popover.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.