elements
lifecycle
browser
- useAudio
- useBattery
- useBluetooth
- useBreakpoints
- useBroadcastChannel
- useBrowserLocation
- useClipboard
- useCopy
- useCssVar
- useDisplayMedia
- useDocumentEvent
- useDocumentTitle
- useDocumentVisibility
- useEventListener
- useEventSource
- useEyeDropper
- useFavicon
- useFileSystemAccess
- useFps
- useFullscreen
- useGamepad
- useGeolocation
- useMeasure
- useMediaControls
- useMediaQuery
- useMemory
- useNetwork
- useObjectUrl
- useOnline
- useOtpCredential
- usePermission
- usePictureInPicture
- usePointerLock
- usePostMessage
- useRaf
- useShare
- useSpeechRecognition
- useSpeechSynthesis
- useSticky
- useVibrate
- useVirtualKeyboard
- useWakeLock
- useWebSocket
utilities
state
- useBoolean
- useControllableState
- useCookie
- useCookies
- useCounter
- useCycleList
- useDefault
- useDisclosure
- useField
- useHash
- useList
- useLocalStorage
- useMap
- useMask
- useMergedRef
- useObject
- useOffsetPagination
- useQueue
- useRafState
- useRefState
- useSessionStorage
- useSet
- useStateHistory
- useStep
- useStorage
- useToggle
- useUrlSearchParam
- useUrlSearchParams
- useValidatedState
- useWizard
user
sensors
- useDeviceMotion
- useDeviceOrientation
- useHotkeys
- useIdle
- useInfiniteScroll
- useIntersectionObserver
- useKeyboard
- useKeyPress
- useKeysPressed
- useMouse
- useMutationObserver
- useOrientation
- usePageLeave
- useParallax
- usePerformanceObserver
- useResizeObserver
- useScroll
- useScrollIntoView
- useScrollTo
- useSwipe
- useTextSelection
- useVisibility
- useWindowEvent
- useWindowFocus
- useWindowScroll
- useWindowSize
import { useClickOutside, useDisclosure, useMeasure, useMergedRef } from '@siberiacancode/reactuse';
import { CheckIcon, ChevronDownIcon } from 'lucide-react';
import { useState } from 'react';
import { cn } from '@/utils/lib';
const FRAMEWORKS = [
{ value: 'react', label: 'React', logo: 'react' },
{ value: 'vue', label: 'Vue', logo: 'vuedotjs' },
{ value: 'svelte', label: 'Svelte', logo: 'svelte' },
{ value: 'angular', label: 'Angular', logo: 'angular' },
{ value: 'solid', label: 'SolidJS', logo: 'solid' },
{ value: 'qwik', label: 'Qwik', logo: 'qwik' }
];
const Demo = () => {
const dropdownMenu = useDisclosure();
const [value, setValue] = useState('react');
const clickOutsideRef = useClickOutside<HTMLDivElement>(() => dropdownMenu.close());
const measure = useMeasure<HTMLDivElement>();
const panelRef = useMergedRef(clickOutsideRef, measure.ref);
const selected = FRAMEWORKS.find((framework) => framework.value === value);
const onSelect = (next: string) => {
setValue(next);
dropdownMenu.close();
};
return (
<section className='flex flex-col items-center'>
<div className='flex w-full max-w-xs flex-col gap-1.5'>
<label className='text-foreground text-sm font-medium' id='framework-label'>
Framework
</label>
<div className='relative'>
<div
aria-expanded={dropdownMenu.opened}
aria-haspopup='listbox'
aria-labelledby='framework-label'
className='border-border bg-card hover:bg-accent flex w-full min-w-[250px] cursor-pointer items-center justify-between gap-2 rounded-lg border px-3 py-2 transition-colors'
onClick={() => dropdownMenu.toggle()}
>
<span className='flex items-center gap-2'>
<img
alt=''
className='size-4 dark:invert'
src={`https://cdn.simpleicons.org/${selected?.logo}/000000`}
/>
<span className='text-foreground text-sm font-medium'>{selected?.label}</span>
</span>
<ChevronDownIcon
className={cn(
'text-muted-foreground size-4 transition-transform',
dropdownMenu.opened && 'rotate-180'
)}
/>
</div>
{dropdownMenu.opened && (
<div
ref={panelRef}
className='absolute top-full right-0 left-0 mt-2'
data-slot='dropdown-menu-content'
>
{FRAMEWORKS.map((framework) => (
<div
key={framework.value}
data-slot='dropdown-menu-item'
onClick={() => onSelect(framework.value)}
>
<img
alt=''
className='size-4 dark:invert'
src={`https://cdn.simpleicons.org/${framework.logo}/000000`}
/>
{framework.label}
{framework.value === value && <CheckIcon className='ml-auto size-4' />}
</div>
))}
</div>
)}
</div>
</div>
</section>
);
};
export default Demo;
Installation
pnpm add @siberiacancode/reactuseUsage
const mergedRef = useMergedRef(firstRef, secondRef);Type Declarations
import type { Ref, RefCallback } from 'react';API
Parameters
| Name | Type | Default | Note |
|---|---|---|---|
| refs | ...Ref<Element>[] | - | The refs to merge |
Returns
RefCallback<Element>Contributors
ddebabin
Last updated on