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
Project settings
Configure your project the way you like.
import { useDefault } from '@siberiacancode/reactuse';
import { ChevronDownIcon, RotateCcwIcon } from 'lucide-react';
interface ProjectSettings {
framework: string;
name: string;
packageManager: string;
styling: string;
}
const DEFAULT_SETTINGS: ProjectSettings = {
name: 'my-awesome-app',
framework: 'next',
packageManager: 'npm',
styling: 'tailwind'
};
const FRAMEWORKS = [
{ value: 'next', label: 'Next.js' },
{ value: 'vite', label: 'Vite' },
{ value: 'remix', label: 'Remix' },
{ value: 'astro', label: 'Astro' }
];
const PACKAGE_MANAGERS = [
{ value: 'npm', label: 'npm' },
{ value: 'pnpm', label: 'pnpm' },
{ value: 'yarn', label: 'yarn' },
{ value: 'bun', label: 'bun' }
];
const STYLING = [
{ value: 'tailwind', label: 'Tailwind CSS' },
{ value: 'css-modules', label: 'CSS Modules' },
{ value: 'styled', label: 'styled-components' },
{ value: 'vanilla', label: 'Vanilla CSS' }
];
const Demo = () => {
const [settings, setSettings] = useDefault<ProjectSettings>(DEFAULT_SETTINGS, DEFAULT_SETTINGS);
const update = (key: keyof ProjectSettings, value: string) =>
setSettings({ ...settings, [key]: value });
const isDefault =
settings.name === DEFAULT_SETTINGS.name &&
settings.framework === DEFAULT_SETTINGS.framework &&
settings.packageManager === DEFAULT_SETTINGS.packageManager &&
settings.styling === DEFAULT_SETTINGS.styling;
return (
<section className='flex w-full max-w-md flex-col gap-4 p-4'>
<div className='flex items-start justify-between gap-4'>
<div className='flex flex-col gap-1'>
<h3>Project settings</h3>
<p className='text-muted-foreground text-sm'>Configure your project the way you like.</p>
</div>
<button
aria-label='Reset to defaults'
className='size-9! rounded-full! p-0!'
data-size='icon'
data-variant='outline'
disabled={isDefault}
type='button'
onClick={() => setSettings(null)}
>
<RotateCcwIcon className='size-4' />
</button>
</div>
<div className='flex flex-col divide-y rounded-xl border'>
<div className='flex items-center justify-between gap-4 px-4 py-3'>
<label className='text-sm font-medium' htmlFor='project-name'>
Name
</label>
<input
className='max-w-44'
id='project-name'
type='text'
value={settings.name}
onChange={(event) => update('name', event.target.value)}
/>
</div>
<div className='flex items-center justify-between gap-4 px-4 py-3'>
<label className='text-sm font-medium' htmlFor='framework'>
Framework
</label>
<div className='relative'>
<select
id='framework'
value={settings.framework}
onChange={(event) => update('framework', event.target.value)}
>
{FRAMEWORKS.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<ChevronDownIcon className='text-muted-foreground pointer-events-none absolute top-1/2 right-2 size-4 -translate-y-1/2' />
</div>
</div>
<div className='flex items-center justify-between gap-4 px-4 py-3'>
<label className='text-sm font-medium' htmlFor='package-manager'>
Package manager
</label>
<div className='relative'>
<select
id='package-manager'
value={settings.packageManager}
onChange={(event) => update('packageManager', event.target.value)}
>
{PACKAGE_MANAGERS.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<ChevronDownIcon className='text-muted-foreground pointer-events-none absolute top-1/2 right-2 size-4 -translate-y-1/2' />
</div>
</div>
<div className='flex items-center justify-between gap-4 px-4 py-3'>
<label className='text-sm font-medium' htmlFor='styling'>
Styling
</label>
<div className='relative'>
<select
id='styling'
value={settings.styling}
onChange={(event) => update('styling', event.target.value)}
>
{STYLING.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<ChevronDownIcon className='text-muted-foreground pointer-events-none absolute top-1/2 right-2 size-4 -translate-y-1/2' />
</div>
</div>
</div>
</section>
);
};
export default Demo;
Installation
pnpm add @siberiacancode/reactuseUsage
const [value, setValue] = useDefault(initialValue, defaultValue);API
Parameters
| Name | Type | Default | Note |
|---|---|---|---|
| initialValue | Value | - | The initial value |
| defaultValue | Value | - | The default value |
Returns
[Value, (value: Value) => void]Contributors
ddebabinhhywax
Last updated on