react-text-row-count
Version:
React helper that adds a data-row-count attribute based on measured text rows.
64 lines (45 loc) • 2.08 kB
Markdown
with text inside, reflecting how many visual text rows it currently spans.
- **Accurate measurement**: Computes rows by measuring the element height (minus padding and borders) divided by its line height.
- **Auto-updates**: Reacts to mutations, element resizes, window resizes, and font loading changes.
- **Zero wrapper**: Does not render an extra DOM node; it clones its only child and sets the data attribute.
```bash
npm i react-text-row-count
```
Peer dependency: `react` (>=17).
```tsx
import RowCount from "react-text-row-count";
export function Example() {
return (
<RowCount onRowCountChanged={(rows) => console.log("Rows:", rows)}>
<div style={{ lineHeight: 1.5 }}>
This text will receive a data-row-count attribute that updates when its
content or size changes.
</div>
</RowCount>
);
}
```
The inner element will receive the `data-row-count` attribute in the DOM and a `rowcountchanged` DOM event will be dispatched when it changes.
- **`<RowCount>`**
- **children**: `ReactElement` (required). Must be a single element; the component clones it to inject a ref.
- **onRowCountChanged**: `(rows: number) => void`. Called whenever the computed row count changes.
A `rowcountchanged` event is also emitted on the child element:
```tsx
useEffect(() => {
const el = document.querySelector('[data-row-count]');
const handler = (e: any) => console.log('DOM rows:', e.detail.rowCount);
el?.addEventListener('rowcountchanged', handler);
return () => el?.removeEventListener('rowcountchanged', handler);
}, []);
```
- The measurement runs on animation frames and coalesces rapid changes.
- The component attaches `ResizeObserver`, `MutationObserver`, and a `resize` listener. These are cleaned up on unmount.
- For best accuracy, ensure your element has a known/computed `line-height` and is not subject to transforms that affect layout without affecting layout boxes.
MIT
Adds a `data-row-count` attribute to a React element