Skip to Content
UtilsMisc

Misc utils

import { cx, copyToClipboard, downloadFile } from '@gg-software/utils';

copyToClipboard and downloadFile are browser helpers — during SSR they safely no-op (false / undefined).

cx

Join class names conditionally. Accepts strings, numbers, nested arrays and { className: condition } objects; falsy values are skipped.

cx('btn', isActive && 'btn--active', { 'btn--lg': large }); // → "btn btn--active btn--lg" cx(['a', ['b', null]], 0, undefined, 'c'); // "a b c"

copyToClipboard

Copy text to the clipboard — async Clipboard API with a legacy execCommand fallback. Resolves to whether the copy succeeded.

const ok = await copyToClipboard('hello'); toast({ title: ok ? 'Copied' : 'Copy failed' });

downloadFile

Trigger a browser download of a Blob or string — CSV/JSON exports.

downloadFile(csv, 'orders.csv', 'text/csv'); downloadFile(JSON.stringify(rows, null, 2), 'rows.json', 'application/json'); downloadFile(blob, 'photo.jpg'); // mimeType comes from the Blob
ParameterTypeDefault
dataBlob | string
filenamestring
mimeTypestring (used for string data)'text/plain'

parseQueryString

Query string → object. Repeated keys become arrays; a leading ? is tolerated.

parseQueryString('?q=shoes&page=2'); // { q: "shoes", page: "2" } parseQueryString('tag=a&tag=b'); // { tag: ["a", "b"] }

buildUrl

Append query params to a URL. null/undefined values are skipped, arrays repeat the key, params already on the base are kept.

buildUrl('/search', { q: 'shoes', page: 2 }); // "/search?q=shoes&page=2" buildUrl('/filter', { tag: ['a', 'b'], empty: null }); // "/filter?tag=a&tag=b" buildUrl('https://api.example.com/items?v=1', { page: 2 });

noop

A function that does nothing — the classic default callback.

const { onChange = noop } = props;