async
lifecycle
browser
utilities
Primary colorBlue
RadiusDefault
Wallet balance
Active currencies for 2026
USD
$12,450
78% of target$16,000
EUR
€8,230
41% of target€20,000
Conversion rates update every hour from your linked bank account.
import { useCssVar } from '@siberiacancode/reactuse';
import { ChevronDownIcon } from 'lucide-react';
import { useRef } from 'react';
const ACCENT_COLORS = [
{ value: 'oklch(0.55 0.18 250)', label: 'Blue' },
{ value: 'oklch(0.55 0.22 300)', label: 'Violet' },
{ value: 'oklch(0.65 0.22 0)', label: 'Pink' },
{ value: 'oklch(0.65 0.18 50)', label: 'Orange' },
{ value: 'oklch(0.65 0.15 160)', label: 'Green' }
];
const RADIUS_OPTIONS = [
{ value: '0rem', label: 'None' },
{ value: '0.3rem', label: 'Small' },
{ value: '0.625rem', label: 'Default' },
{ value: '1rem', label: 'Large' },
{ value: '1.5rem', label: 'Extra large' }
];
const PORTFOLIO = [
{ label: 'USD', amount: 12450, achieved: 78, target: 16000 },
{ label: 'EUR', amount: 8230, achieved: 41, target: 20000 }
];
const formatMoney = (value: number, currency: string) =>
new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
maximumFractionDigits: 0
}).format(value);
const Demo = () => {
const containerRef = useRef<HTMLElement>(null);
const primary = useCssVar(containerRef, '--demo-primary', 'oklch(0.55 0.18 250)');
const radius = useCssVar(containerRef, '--demo-radius', '0.625rem');
const activeColor =
ACCENT_COLORS.find((color) => color.value === primary.value) ?? ACCENT_COLORS[0];
const activeRadius =
RADIUS_OPTIONS.find((option) => option.value === radius.value) ?? RADIUS_OPTIONS[2];
return (
<section ref={containerRef} className='flex flex-col gap-5 p-4'>
<div className='flex flex-col'>
<div className='flex items-center justify-between py-3'>
<div className='flex flex-col'>
<span className='text-muted-foreground text-xs'>Primary color</span>
<span className='text-sm font-medium'>{activeColor.label}</span>
</div>
<div className='flex items-center gap-1.5'>
{ACCENT_COLORS.map((color) => (
<div
key={color.value}
style={{
backgroundColor: color.value,
outline: primary.value === color.value ? `2px solid ${color.value}` : 'none',
outlineOffset: '2px'
}}
className='size-4 cursor-pointer rounded-full transition-transform hover:scale-110'
onClick={() => primary.set(color.value)}
/>
))}
</div>
</div>
<div className='flex items-center justify-between py-3'>
<div className='flex flex-col'>
<span className='text-muted-foreground text-xs'>Radius</span>
<span className='text-sm font-medium'>{activeRadius.label}</span>
</div>
<div className='relative'>
<select
value={radius.value ?? '0.625rem'}
onChange={(event) => radius.set(event.target.value)}
>
{RADIUS_OPTIONS.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>
<div className='bg-card flex flex-col overflow-hidden rounded-[var(--demo-radius)] border'>
<div className='flex flex-col gap-5 p-5'>
<div className='flex items-start justify-between gap-4'>
<div className='flex flex-col gap-1'>
<h4>Wallet balance</h4>
<p className='text-muted-foreground text-sm'>Active currencies for 2026</p>
</div>
<button
className='rounded-[var(--demo-radius)]! bg-[var(--demo-primary)]! text-white'
type='button'
>
Add money
</button>
</div>
<div className='flex flex-col gap-3'>
{PORTFOLIO.map((item) => (
<div
key={item.label}
className='bg-muted/40 flex flex-col gap-2 rounded-[var(--demo-radius)] bg-[var(--demo-primary)] p-4'
>
<span className='text-muted-foreground text-xs tracking-widest uppercase'>
{item.label}
</span>
<div className='flex items-baseline justify-between'>
<span className='text-3xl font-semibold tracking-tight'>
{formatMoney(item.amount, item.label)}
</span>
</div>
<div className='bg-background/60 ип h-1 w-full overflow-hidden rounded-full'>
<div
style={{
width: `${item.achieved}%`
}}
className='h-full rounded-full bg-[var(--demo-primary)] transition-all'
/>
</div>
<div className='text-muted-foreground flex items-center justify-between text-xs'>
<span>{item.achieved}% of target</span>
<span className='font-medium'>{formatMoney(item.target, item.label)}</span>
</div>
</div>
))}
</div>
</div>
<div className='bg-muted/30 text-muted-foreground border-t px-5 py-3 text-xs'>
Conversion rates update every hour from your linked bank account.
</div>
</div>
</section>
);
};
export default Demo;
Installation
pnpm add @siberiacancode/reactuseUsage
const { ref, value, set, remove } = useCssVar('--color', 'red');
// or
const { value, set, remove } = useCssVar(ref, '--color', 'red');Type Declarations
import type { HookTarget } from '@/utils/helpers';
import type { StateRef } from '../useRefState/useRefState';
export interface UseCssVarReturn {
/** The value of the CSS variable */
value: string;
/** Remove the value of the CSS variable */
remove: () => void;
/** Set the value of the CSS variable */
set: (value: string) => void;
}
export interface UseCssVar {
<Target extends HTMLElement>(
key: string,
initialValue?: string
): UseCssVarReturn & {
ref: StateRef<Target>;
};
(target: HookTarget, key: string, initialValue?: string): UseCssVarReturn;
}API
Parameters
| Name | Type | Default | Note |
|---|---|---|---|
| key | string | - | The CSS variable key |
| initialValue | string | - | The initial value of the CSS variable |
Returns
UseCssVarReturn & { ref: StateRef<Element> }Parameters
| Name | Type | Default | Note |
|---|---|---|---|
| target | HookTarget | - | The target element |
| key | string | - | The CSS variable key |
| initialValue | string | - | The initial value of the CSS variable |
Returns
UseCssVarReturnContributors
ddebabin
Last updated on