Skip to content

Instantly share code, notes, and snippets.

@bennobuilder
Created March 27, 2025 15:16
Show Gist options
  • Save bennobuilder/762e4bf9f44045508ff2e4b6f8dd7e77 to your computer and use it in GitHub Desktop.
Save bennobuilder/762e4bf9f44045508ff2e4b6f8dd7e77 to your computer and use it in GitHub Desktop.
use-css-variable
'use client';
import React, { useId } from 'react';
export function useCssVariable<GValue extends string | number>(
elementRef: React.RefObject<HTMLElement | null>,
config: TCssVariableConfig<GValue> | (() => TCssVariableConfig<GValue>),
deps: React.DependencyList = []
) {
const id = useId();
const { variable, variableName, initialValue, unit } = React.useMemo(() => {
const resolvedConfig = typeof config === 'function' ? config() : config;
const { name, initialValue, unit = '' } = resolvedConfig;
const variableName = `--${name}-${id}`;
const variable = `var(${variableName}, ${initialValue}${unit})`;
return { variable, variableName, initialValue, unit };
}, [config, id, ...deps]);
const updateValue = React.useCallback(
(value: GValue) => {
elementRef.current?.style.setProperty(variableName, `${value}${unit}`);
},
[elementRef, variableName, unit]
);
React.useEffect(() => {
updateValue(initialValue);
}, [updateValue, initialValue, ...deps]);
return [variable, updateValue] as const;
}
interface TCssVariableConfig<GValue extends string | number> {
name: string;
initialValue: GValue;
unit?: string;
}
@bennobuilder
Copy link
Author

My use case

Screen.Recording.2025-03-27.at.16.18.05.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment