Bagon Hooks

v0.0.7

A collection of 82+ zero-dependency hooks for SolidJS forked directly from Mantine Hooks, with some improvements.

> install bagon-hooks
Cmd
K

useClickOutside

Detects clicks outside a ref
No detections

useClipboard

A hook that wraps copy-to-clipboard logic with a signal.
Bagon is awesome!

useCollapse

Animate height for expand/collapse panels with proper a11y attributes.

useColorScheme

A hook that returns system color scheme value i.e. either `dark` or `light`.
Your system color scheme is: light

useCounter

A hook that returns a signal with a counter value and functions to increment, decrement, set and reset the counter.
5

useDebouncedCallback

Creates a debounced version of a callback function, delaying its execution until a specified time has elapsed since the last invocation.

useDebouncedSignal

Creates a signal that is debounced with a given wait time.
State: ""

useDebouncedValue

Debounced value from an existing signal.
State: ""|Value: ""

useDidUpdate

This hook works the same way as createEffect but it is not called when component is mounted.

Unlike createEffect, this always has a dependency of signals (like React's useEffect) for the reason that the only way to do this in Solid is using the on() + defer property under the hood.

This logs "Did Update X" to the console. Notice that it doesn't log "Did Update 0" since it happens on mount.

useDisclosure

A simple hook to manage state for dialogs, modals, accordions, etc. Anything that needs to open/close/toggle.

useDisclosureData

For complex usecases where we only need to pass data to the disclosure. I.e. Edit Modals, Confirm Alerts with details about the item clicked, etc.

useDocumentTitle

Sets the `document.title`. Hook is not called during server-side rendering. Only use this for client-only applications.
Home
About
Awesome

useDocumentVisibility

Returns the document.visibilityState - it allows detecting if the current tab is active.
Tab is currently visible

useDrag

Pointer drag handler with movement deltas. Bounds are clamped in the demo.
Drag

useElementSize

Returns width and height of a resizable element. An abstraction over useResizeObserver.
Width: 0.00Height: 0.00
Resize Me

useEventListener

Attaches an event listener to a target (element ref, Window, Document, or MediaQueryList).
Clicks: 0

useEyeDropper

A hook that gives you the ability to open the browser's EyeDropper API and save it to a signal.
Picked Color:

useFavicon

Appends <link /> element to head component with given favicon url. The hook is not called during server side rendering.

useFetch

Fetches data with AbortController support. Returns data, error, loading, abort, and refetch.

useFileDialog

Opens a native file picker dialog and returns the selected files.
No files selected

useFloatingWindow

Draggable floating window with optional absolute positioning and parent clamping.
Drag me
Positioned with strategy: 'absolute' and clamped to this card.

useFocusReturn

Captures the currently focused element and restores focus when a layer closes.

Focus the button, open the dialog, type in dialog content, then close it — focus returns to the trigger.

useFocusTrap

Traps keyboard focus inside an element while active — ideal for modals and drawers.

useFocusWithin

Detects whether focus is within an element or any of its descendants.
Focused: false

useFullscreen

A hook that allows you to enter and exit fullscreen mode. Can also optionally pass a ref of the element to be fullscreened.

useHash

A hook that allows you to get and set the hash value of the current URL like a signal.
Current hash:

useHeadroom

Create sticky headers that hide on scroll down and reappear on scroll up. Uses window scroll — scroll the page to see it update.
Headerpinned=true · 100%

Scroll the page (not this panel) to pin / unpin the header.

pinned: true

scrollProgress: 100%

useHorizontalCollapse

Animate width for side panels and drawers.

Side panel

State: entered

Main content

useHotkeys

Handle hotkeys easily
ctrl + a
ctrl + Enter
shift + g

useHover

Detects hovers on a ref
No detections

useId

Returns a random id.
Random ID: 000010010a300

useIdle

Returns if user has been idle after some milliseconds
Is Idle (1s):true

useInViewport

Simpler alternative to useIntersection that only returns a bool.
Scroll to See Box
Obscured

useInputState

Handles state of native inputs with the onChange or onInput handlers. Syntax sugar over writing your own handler functions and types for the events.

You can treat this as the SolidJS way of Svelte's ease of use with `bind:value` and `bind:checked`
{"input":"","checkbox":false}

useIntersection

Returns intersection observer info about the element ref.
Obscured

useInterval

Calls function with a given interval

Page loaded 0 seconds ago.

useKeyboard

Use this for more general keyboard events, as opposed to useHotkeys.
a
b
c
d

useListState

Manage array state with helpers for append, prepend, insert, remove, reorder, and more.
  • 0: Apple
  • 1: Banana
  • 2: Cherry

useLocalStorage

A hook that allows using value from the localStorage as a signal. The hook works exactly the same way as createSignal, but also writes the value to the localStorage. It even works between tabs!

To test, try changing the value with two tabs open.
Favorite Fruit: apple

useLocalStorageStore

(Improvement) A hook that allows using value from the localStorage as a store for complex and efficient state management. The hook works exactly the same way as createStore, but also writes the value to the localStorage. It even works between tabs!

To test, try changing the value with two tabs open.

useLongPress

Detects long-press gestures; spread handlers onto an element.
Triggered: 0

useMap

Reactive Map helpers for set, delete, clear, and bulk updates.
  • apples: 2
  • oranges: 5
size: 2

useMask

Format input values with a mask while tracking the raw unmasked value.
Raw: (empty)
Complete: no

useMediaQuery

Returns a signal that tracks the current state of a media query. Try resizing the window.
No match

useMounted

Returns true if component is mounted. Useful for rendering only on client-side.

useMouse

Returns the current mouse position and an optional ref to the element that is being tracked.
Track Here
Mouse coordinates {"x":0,"y":0}

useMove

Handles move behavior over any element inside the constraints of a ref.

Can be used to make custom sliders, color pickers, and draggable elements within a container.
Values: {"x":"0.50","y":"0.50"}

useMutationObserver

Observe DOM mutations on an element via MutationObserver.
  • Item 1
  • Item 2
Mutations observed: 0

useNetwork

Returns information about current user's network connection. Try going offline on DevTools.
{
  "online": true
}

useOrientation

Returns the current orientation of the device. Try tilting the device (if on your phone).
{
  "angle": 0,
  "type": "landscape-primary"
}

useOs

Returns the current OS
Current OS: undetermined

usePageLeave

Calls a callback when the mouse leaves the document.
Move your mouse out of the pageLeft count: 0

usePagination

Build pagination ranges with siblings, boundaries, and navigation helpers.
Active page: 1
...

usePrevious

Returns the previous value of a signal/accessor.
Current: 0
Previous: undefined

useQueue

Limit visible state while keeping overflow items in a queue.

Only `limit` items stay in state; overflow goes to queue.

State (active, limit 2)
  • 1
  • 2
Queue (backlog)
  • 3

“Update all (+1)” maps every item in state and queue.

useRadialMove

Track pointer angle around an element's center — useful for knobs and dials.
45°

Drag around the circle

useReducedMotion

Returns true if the user prefers reduced motion.
Prefers reduced motion: undefined

useResizeObserver

Returns information about a resizable element. This is more low-level but gives you more than just width and height.
{
  "rect": {
    "x": 0,
    "y": 0,
    "width": 0,
    "height": 0,
    "top": 0,
    "left": 0,
    "bottom": 0,
    "right": 0
  }
}
Resize Me

useRovingIndex

Manage keyboard-navigable roving tabindex for toolbars, menus, and grids.

Focus the toolbar, then use Arrow keys / Home / End.

Active index: 0

useScrollDirection

Returns the current window scroll direction.
Scroll the page up or downDirection: unknown

useScrollIntoView

Smoothly scroll a target element into view within a scroll parent.
scrolling: false

Spacer block 1

Spacer block 2

Spacer block 3

Spacer block 4

Spacer block 5

Spacer block 6

Spacer block 7

Spacer block 8

Target element

Trailing block 1

Trailing block 2

Trailing block 3

Trailing block 4

Trailing block 5

Trailing block 6

Trailing block 7

Trailing block 8

useScrollSpy

Highlights the active heading inside a local scroll container (last heading with top <= offset).

Introduction

Scroll this pane. The nav on the left tracks the last heading whose top is at or above the offset inside this container — not the whole page.

Setup

Pass a local `scrollHost` and scope the selector to headings inside `.spy-demo`. Nav clicks use `spy.scrollTo(index)` so only the host scrolls.

Usage

Active detection uses relative tops against the host bounding rect, so nested scroll containers work the same as window scrollspies.

Notes

Keep enough content height so each section can reach the top of the scroll host. The offset here is 8px.

Extra space below helps the last heading become active when scrolled into place.

useScroller

Helpers for scrolling an element to top, bottom, or an arbitrary offset.

Line 1

Line 2

Line 3

Line 4

Line 5

Line 6

Line 7

Line 8

Line 9

Line 10

Line 11

Line 12

Line 13

Line 14

Line 15

Line 16

Line 17

Line 18

Line 19

Line 20

Line 21

Line 22

Line 23

Line 24

Line 25

Line 26

Line 27

Line 28

Line 29

Line 30

useSelection

Enhanced selection helper with text/rect/ranges plus set/clear — unlike `useTextSelection`, which only tracks `window.getSelection()`.

Select some of this text with the mouse, or use the buttons below to set a range programmatically.

Selected: (none)
Collapsed: yes

useSessionStorage

Persist a signal value in sessionStorage (cleared when the tab closes).
Stored:

useSet

Reactive unique values (`Set`) — unlike `useMap`, there are no keys, only membership.
  • react
  • solid
  • vue
size: 3

useSplitter

Accessible split views with keyboard and pointer resizing.
Primary (40%)
Secondary

useStateHistory

Track state changes with undo / redo history.
0
history: {"history":[0],"current":0}

useTextSelection

Tracks `window.getSelection()` (Mantine-compatible). For range/rect helpers see `useSelection`.

Select any part of this paragraph. The hook listens to `selectionchange` and updates even though `document.getSelection()` returns the same object reference. Try selecting “Solid” or a longer phrase below.

Solid reactivity needs an explicit version bump when APIs reuse object identity. That is why this demo updates live while you change the selection.

Selected text
(none)

useThrottledCallback

Creates a throttled version of a callback function.

useThrottledState

Like createSignal but the setter is throttled.
Throttled value: ""

useThrottledValue

Returns a throttled version of a reactive value.
Value: ""Throttled: ""

useTimeout

Calls function in given timeout

You: not awesome

You will become Awesome in 1 second after pressing 'Start'. You can also cancel.

useToggle

A hook that toggles between two or multiple values (by implementing a common state pattern). Dev Note: Personally this can be called `useCycle` instead since it cycles through the options.
🍎 apple
🍊 orange
🍇 grape
🥝 kiwi

useUncontrolled

Manages state of both controlled and uncontrolled components. Useful for component libraries that need to support both controlled and uncontrolled usage patterns.

Note that both are still "controlled" in the browser-sense. They just differ in terms of parent-controlled or internally-controlled.

Try toggling between controlled and uncontrolled modes using the checkbox below.

Uncontrolled Mode

{
  "value": "",
  "isControlled": true
}

useValidatedState

Tracks a value alongside validation state and the last valid value.
valid: false
last valid:
Try `carlo@.` (invalid) vs `carlo@a.com` (valid).

useViewportSize

Tracks the browser viewport width and height, updating on resize.
{
  "width": 0,
  "height": 0
}
Resize the window to update

useWindowScroll

Reactive window scroll position with a smooth scrollTo helper.
{
  "x": 0,
  "y": 0
}