Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/inshadowin/use-rects
https://github.com/inshadowin/use-rects
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/inshadowin/use-rects
- Owner: Inshadowin
- License: mit
- Created: 2024-08-10T11:17:08.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-09-10T10:27:20.000Z (4 months ago)
- Last Synced: 2024-11-11T01:52:23.203Z (about 2 months ago)
- Language: TypeScript
- Size: 357 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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
;
```