@bttrlabs/utils
v1.0.2
Published
Shared utility functions for the Bttr Design System
Readme
@bttrlabs/utils
Comprehensive, theme-agnostic utility functions for the Bttr Design System. This package provides a collection of well-tested, type-safe utilities for common programming tasks.
@bttr/utils
Comprehensive, theme-agnostic utility functions for the Bttr Design System. This package provides a collection of well-tested, type-safe utilities for common programming tasks.
Features
Installation
pnpm add @bttrlabs/utilsUtilities
Class Name Utilities
Merge CSS class names with Tailwind conflict resolution:
import { cn } from '@bttrlabs/utils';
cn('px-2 py-1', 'px-3'); // => 'py-1 px-3'
cn('text-red-500', { 'text-blue-500': true }); // => 'text-blue-500'Color Utilities
Manipulate and convert colors:
import { hexToRgb, rgbToHex, isLightColor, getContrastColor, lighten, darken, alpha } from '@bttrlabs/utils';
hexToRgb('#ff5733'); // => { r: 255, g: 87, b: 51 }
rgbToHex(255, 87, 51); // => '#ff5733'
isLightColor('#ffffff'); // => true
getContrastColor('#000000'); // => '#ffffff'
lighten('#808080', 0.2); // => '#a6a6a6'
darken('#808080', 0.2); // => '#666666'
alpha('#ff5733', 0.5); // => 'rgba(255, 87, 51, 0.5)'Format Utilities
Format numbers, dates, currency, and more:
import { formatNumber, formatCurrency, formatDate, formatRelativeTime, formatFileSize, formatPhoneNumber, formatPercent } from '@bttrlabs/utils';
formatNumber(1234.5); // => '1,234.5'
formatCurrency(1234.56); // => '$1,234.56'
formatDate(new Date(), 'long'); // => 'January 15, 2024'
formatRelativeTime(new Date(Date.now() - 60000)); // => '1 minute ago'
formatFileSize(1536); // => '1.5 KB'
formatPhoneNumber('1234567890'); // => '(123) 456-7890'
formatPercent(0.1234, 2); // => '12.34%'Validation Utilities
Validate emails, URLs, phone numbers, passwords, and credit cards:
import { isValidEmail, isValidUrl, isValidPhone, getPasswordStrength, isValidCreditCard, validate } from '@bttrlabs/utils';
isValidEmail('[email protected]'); // => true
isValidUrl('https://example.com'); // => true
isValidPhone('1234567890'); // => true
getPasswordStrength('MyP@ssw0rd!'); // => { score: 4, feedback: [] }
isValidCreditCard('4532015112830366'); // => true
// Generic validation with rules
validate('[email protected]', [
{ type: 'required' },
{ type: 'pattern', value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ }
]); // => { valid: true, errors: [] }String Utilities
Manipulate and transform strings:
import { capitalize, toTitleCase, truncate, slugify, stripHtml, randomString, toCamelCase, toKebabCase, toSnakeCase } from '@bttrlabs/utils';
capitalize('hello world'); // => 'Hello world'
toTitleCase('hello world'); // => 'Hello World'
truncate('Hello World', 8); // => 'Hello...'
slugify('Hello World!'); // => 'hello-world'
stripHtml('<p>Hello <strong>World</strong></p>'); // => 'Hello World'
randomString(8); // => 'aBc123Xy'
toCamelCase('hello-world'); // => 'helloWorld'
toKebabCase('helloWorld'); // => 'hello-world'
toSnakeCase('helloWorld'); // => 'hello_world'Array Utilities
Work with arrays efficiently:
import { unique, groupBy, sortBy, chunk, flatten, shuffle, sample, intersection, difference, sum, average } from '@bttrlabs/utils';
unique([1, 2, 2, 3, 4, 4]); // => [1, 2, 3, 4]
groupBy([{ type: 'fruit', name: 'apple' }], 'type'); // => { fruit: [...] }
sortBy([{ age: 30 }, { age: 25 }], ['age']); // => [{ age: 25 }, { age: 30 }]
chunk([1, 2, 3, 4, 5], 2); // => [[1, 2], [3, 4], [5]]
flatten([1, [2, 3], [4, [5, 6]]]); // => [1, 2, 3, 4, 5, 6]
shuffle([1, 2, 3, 4, 5]); // => [3, 1, 5, 2, 4]
sample([1, 2, 3, 4, 5], 3); // => [2, 5, 1]
intersection([1, 2, 3], [2, 3, 4]); // => [2, 3]
difference([1, 2, 3, 4], [2, 4]); // => [1, 3]
sum([1, 2, 3, 4]); // => 10
average([1, 2, 3, 4]); // => 2.5Object Utilities
Manipulate objects deeply:
import { deepClone, deepMerge, pick, omit, isEmpty, get, set, isEqual } from '@bttrlabs/utils';
const obj = { a: 1, b: { c: 2 } };
deepClone(obj); // Creates a deep copy
deepMerge({ a: 1 }, { b: 2 }, { c: 3 }); // => { a: 1, b: 2, c: 3 }
pick({ a: 1, b: 2, c: 3 }, ['a', 'c']); // => { a: 1, c: 3 }
omit({ a: 1, b: 2, c: 3 }, ['b']); // => { a: 1, c: 3 }
isEmpty({}); // => true
get({ user: { name: 'John' } }, 'user.name'); // => 'John'
set({}, 'user.name', 'John'); // => { user: { name: 'John' } }
isEqual({ a: 1 }, { a: 1 }); // => truePerformance Utilities
Optimize function execution:
import { debounce, throttle, memoize, batch, retry } from '@bttrlabs/utils';
// Debounce: delay execution until calls stop
const debouncedSearch = debounce((query) => {
console.log('Searching:', query);
}, 300);
// Throttle: limit execution rate
const throttledScroll = throttle(() => {
console.log('Scroll handled');
}, 100);
// Memoize: cache function results
const expensiveCalc = memoize((n) => n * n);
// Batch: collect calls and execute once
const batchSave = batch((items) => {
console.log('Saving:', items);
}, 500);
// Retry: retry failed async operations
await retry(() => fetch('/api/data'), 3, 1000);Browser Utilities
Browser detection and interaction:
import { getBrowser, getDeviceType, copyToClipboard, downloadFile, isInViewport, prefersDarkMode, prefersReducedMotion, getScrollPosition, scrollTo } from '@bttrlabs/utils';
getBrowser(); // => 'chrome' | 'firefox' | 'safari' | etc.
getDeviceType(); // => 'mobile' | 'tablet' | 'desktop'
await copyToClipboard('Hello World');
downloadFile('data', 'file.txt');
isInViewport(element); // => true/false
prefersDarkMode(); // => true/false
prefersReducedMotion(); // => true/false
getScrollPosition(); // => { x: 0, y: 100 }
scrollTo(0); // Scroll to topStorage Utilities
localStorage and sessionStorage wrappers with JSON support:
import { storage, sessionStore, setWithExpiry, getWithExpiry } from '@bttrlabs/utils';
// Set data (automatically serialized)
storage.set('user', { name: 'John', age: 30 });
// Get data (automatically deserialized)
const user = storage.get<User>('user');
// Remove data
storage.remove('user');
// Clear all
storage.clear();
// Storage with expiration
setWithExpiry('token', 'abc123', 60 * 60 * 1000); // 1 hour
const token = getWithExpiry<string>('token');
// sessionStorage has the same API
sessionStore.set('tempData', { id: 123 });TypeScript Support
All utilities are fully typed with TypeScript:
import type { RGB, RGBA, FormatNumberOptions, PasswordStrength, ValidationRule, DebouncedFunc, DeviceType, BrowserType } from '@bttrlabs/utils';Testing
The package includes 122+ unit tests covering all utilities:
pnpm testLicense
MIT
Contributing
Contributions are welcome! Please ensure all tests pass and add tests for new features.
