Skip to content

@verbose/composables

sh
npm install @verbose/composables

Composition utilities for DOM, browser APIs, and common UI patterns. All return reactive signals or computed values.

DOM

createRef<T>()

Creates a reference object to be attached to a DOM element via the ref prop.

tsx
import { createRef } from '@verbose/composables'

const inputRef = createRef<HTMLInputElement>()

// In render:
<input ref={inputRef} />

// After mount:
inputRef.current?.focus()

useElementSize(ref)

Tracks the rendered size of an element using ResizeObserver.

ts
import { createRef, useElementSize } from '@verbose/composables'

const ref = createRef<HTMLDivElement>()
const { width, height, stop } = useElementSize(ref)

// width.value and height.value update on resize
ReturnTypeDescription
widthComputed<number>Element width in px
heightComputed<number>Element height in px
stop()() => voidDisconnect observer

useWindowSize()

Tracks the browser window dimensions.

ts
import { useWindowSize } from '@verbose/composables'

const { width, height } = useWindowSize()
// width.value, height.value update on resize

useScrollPosition(target?)

Tracks scroll position of an element or the window.

ts
import { useScrollPosition } from '@verbose/composables'

const { x, y } = useScrollPosition()           // window scroll
const { x, y } = useScrollPosition(el)         // element scroll

useIntersection(ref, options?)

Returns a Computed<boolean> that is true when the element enters the viewport.

ts
import { useIntersection } from '@verbose/composables'

const isVisible = useIntersection(ref, { threshold: 0.5 })

useFocus(ref)

Returns a Computed<boolean> reflecting the focus state of an element.

ts
import { useFocus } from '@verbose/composables'

const focused = useFocus(inputRef)

Browser APIs

useMediaQuery(query)

Matches a CSS media query and returns a reactive boolean.

ts
import { useMediaQuery } from '@verbose/composables'

const isTablet = useMediaQuery('(min-width: 768px)')
// isTablet.value updates when the query result changes

useColorScheme()

Detects the user's preferred color scheme.

ts
import { useColorScheme } from '@verbose/composables'

const { isDark, isLight } = useColorScheme()

useMouse()

Tracks the cursor position in page coordinates.

ts
import { useMouse } from '@verbose/composables'

const { x, y } = useMouse()

useKeyCombo(combo)

Detects a keyboard shortcut being held down.

ts
import { useKeyCombo } from '@verbose/composables'

const isSaving = useKeyCombo('ctrl+s')
const isUndo = useKeyCombo('ctrl+z')

Combo syntax: modifier keys joined with + followed by the key name. Modifiers: ctrl, shift, alt, meta.

useIdle(timeout?)

Detects user inactivity. Resets on mouse, keyboard, touch, or scroll events.

ts
import { useIdle } from '@verbose/composables'

const idle = useIdle(30_000)  // 30 seconds, default is 60s
// idle.value === true when user has been inactive

Utilities

useClipboard(resetDelay?)

Provides clipboard read/write with a reactive copied flag.

ts
import { useClipboard } from '@verbose/composables'

const { copy, copied, content } = useClipboard(2000)

await copy('Hello!')
copied.value   // true for 2 seconds
content.value  // 'Hello!'
ReturnTypeDescription
copy(text)(string) => Promise<void>Write to clipboard
copiedComputed<boolean>True for resetDelay ms after copy
contentComputed<string>Last copied text

useGeolocation(options?)

Requests the user's geolocation reactively.

ts
import { useGeolocation } from '@verbose/composables'

const { lat, lng, error, loading } = useGeolocation()
ReturnTypeDescription
latComputed<number | null>Latitude
lngComputed<number | null>Longitude
errorComputed<GeolocationPositionError | null>Position error
loadingComputed<boolean>Request in progress

useTimeAgo(source, locale?)

Formats a date signal as a human-readable relative time string. Defaults to pt-BR locale.

ts
import { signal } from '@verbose/core'
import { useTimeAgo } from '@verbose/composables'

const date = signal(new Date(Date.now() - 3600_000))
const label = useTimeAgo(date)
// label.value === '1 hora atrás'

const labelEn = useTimeAgo(date, 'en-US')
// labelEn.value === '1 hour ago'

usePagination(options)

Manages pagination state for a list.

ts
import { usePagination } from '@verbose/composables'

const pager = usePagination({ total: 100, pageSize: 10, initial: 1 })

pager.page.value       // 1
pager.totalPages.value // 10
pager.hasNext.value    // true
pager.offset.value     // 0

pager.next()           // page → 2
pager.goTo(5)          // page → 5
pager.last()           // page → 10
pager.prev()           // page → 9
pager.first()          // page → 1

options can also be a function that returns options reactively.

ReturnTypeDescription
pageComputed<number>Current page (1-based)
totalPagesComputed<number>Total number of pages
offsetComputed<number>Item offset for current page
pageSizeComputed<number>Items per page
hasNextComputed<boolean>Whether next page exists
hasPrevComputed<boolean>Whether previous page exists
pagesComputed<number[]>Array of page numbers
next()() => voidGo to next page
prev()() => voidGo to previous page
goTo(p)(number) => voidJump to a specific page
first()() => voidGo to first page
last()() => voidGo to last page

Released under the MIT License.