Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/inshadowin/use-rects


https://github.com/inshadowin/use-rects

Last synced: about 2 months ago
JSON representation

Awesome Lists containing this project

README

        

# use-rects

Package that allows to resolve DOM elements sizes and positions

# Contents

## usePopupPosition

Allows you to quickly build dropdowns

- `flip` - used to allow popup to change position if there is no space for original align
- `pessimistic` allows to show popup separated from anchor egdes, cause there is no proper fit
- `align` - `topleft` | `bottomleft` | `bottomright` | `topright`
- `trackVisible` - hides dropdown if anchor is hidden/obstructed on the page. Doesn't count anything with 'absolute', 'fixed', etc. as obstruction

### Example of the component

Just copy-paste and use this a base (with some tailwind)

```jsx
import React, { useState } from 'react';
import { usePopupPosition } from 'use-rects';

export const Dropdown = () => {
const [open, setOpen] = useState(false);

// const handleClose = () => setOpen(false);
const handleToggle = () => setOpen(o => !o);

const { popupRef, anchorRef, popupPosition } = usePopupPosition({
delay: 15,
flip: true,
align: 'bottomleft',
});

return (


Trigger

{open && (


Dropdown


)}

);
};
```

### Troublesooting

You still have to build your own dropdown. So remember this:

- add Z-index of you own if needed
- `trackVisible` won't work if you have 'fixed' your navbars and other parts of the layout
- dropdown must have 'height'. don't make it's content with 0 height and make some magic inside
- use results of the hook for position only. don't style this popup. Add your div inside and style it. Insluding margin, borders, etc.

returns:

```tsx
type PopupStyle = {
top?: number;
bottom?: number;

left?: number;
right?: number;

opacity?: 1 | 0;
position?: 'fixed';
display?: 'none' | undefined;
};

type UsePopupResult = {
style: PopupStyle;
meta?: { pessimistic?: boolean; flip?: boolean; anchorWidth?: number };
};

type ReturnType = {
popupRef: (node: HTMLDivElement) => void;
anchorRef: (node: HTMLDivElement) => void;

anchorPosition: Position;
popupPosition: UsePopupResult;
};
```

example:

```jsx
const Dropdown = () => {
const [open, setOpen] = useState(false);
const { popupRef, anchorRef, popupPosition } = usePopupPosition({
delay: 50,
});

return (


setOpen(true)}
value="test me"
/>
{!!open && (
setOpen(false)}
style={{ position: 'fixed', ...popupPosition.style }}
>
DROPDOWN

)}

);
};
```

Use resulting style inside of container. If you need extra margins - don't apply them in combination with `flip`. Put another container inside and style it

## useContainerSize

returns:

```tsx
type ReturnType = {
containerRef: React.MutableRefObject;
height: number;
width: number;
};
```

example:

```tsx
const { height, width, containerRef: ref } = useContainerSize({ delay: 20 });

return

;
```

## useElementPosition

returns:

```tsx
type ReturnType = [(node: HTMLDivElement) => void, Position];
```

example:

```tsx
const [ref, position] = useElementPosition({
delay: 20,
});

return

;
```