Common Utils
Utility functions and helpers for cross-platform React development.
Purpose
This library provides utility functions that work consistently across web and mobile platforms, including platform detection, price formatting, error handling, data manipulation, and component utilities. It enables developers to write code that seamlessly works on both React Native and web environments.
Features
- Platform detection utilities for React Native and SSR environments
- Price formatting and manipulation functions
- Error handling and type checking utilities
- Cross-platform prop transformation functions
- Slot system for component composition
- Context scope creation utilities
- CSS variable management (web-only)
- Data manipulation utilities (array, object, string operations)
- Logger with conditional debug output
- Search input generation for SSR compatibility
Installation
- npm
- Yarn
npm install @haus-storefront-react/common-utils
yarn add @haus-storefront-react/common-utils
Note: This is not a public package. Contact the Haus Tech Team for access.
API Reference
isNativePlatform
Detects whether the code is running in React Native or SSR environment.
Signature
function isNativePlatform(): { isReactNative: boolean; isSSR: boolean }
Returns
| Return Value | Type | Description |
|---|---|---|
isReactNative | boolean | Whether the code is running in React Native |
isSSR | boolean | Whether the code is running in SSR (server-side rendering) |
renderHook
Renders a hook conditionally based on platform detection.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
nativeHook | (...args: any[]) => T | Yes | Hook function to use in native/SSR environment |
webHook | (...args: any[]) => R | Yes | Hook function to use in web environment |
nativeArgs | any[] | No | Arguments to pass to native hook |
webArgs | any[] | No | Arguments to pass to web hook |
Returns
T | R - The return value from the appropriate hook
getPrice
Extracts numeric price value from various price types.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
priceValue | PriceRange | SinglePrice | number | Yes | Price object or number |
Returns
number - Numeric price value, or 0 if priceValue is null/undefined
getProductPriceFromVariants
Calculates price range from an array of product variants.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
variants | ProductVariant[] | Yes | Array of product variants |
Returns
Price - Price object with either a single value or min/max range
formatPrice
Formats a numeric price value as a currency string.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
value | number | Yes | Price value in cents |
currency | string | No | Currency code (e.g., 'USD') |
forceDecimals | boolean | No | Force decimal display even for whole numbers |
customPriceCurrency | string | No | Custom currency code to use instead of currency parameter |
Returns
string - Formatted price string (e.g., "$19.99" or "19.99 kr")
isErrorResult
Checks if an input is an ErrorResult type.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input | unknown | Yes | Value to check |
Returns
boolean - Whether the input is an ErrorResult
isGraphQLError
Checks if an input is a GraphQL error.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input | unknown | Yes | Value to check |
Returns
boolean - Whether the input is a GraphQL error
isError
Type guard that checks if an input is a generic ecommerce error.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input | unknown | Yes | Value to check |
Returns
boolean - Type guard result indicating if input is GenericEcomError
getError
Extracts error information from a generic ecommerce error.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
error | GenericEcomError | Yes | Error to extract |
Returns
GenericEcomError | null - Error object or null if not extractable
renderChildren
Renders children with props, supporting both regular children and render props patterns.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
children | ChildrenProps<T> | Yes | Children to render (ReactNode or function) |
props | T | Yes | Props to pass if children is a function |
Returns
ReactNode | ReactElement - Rendered children
insertAndOverwrite
Inserts an array into a target array at a specific position, overwriting existing elements.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
targetArray | T[] | Yes | Array to insert into |
insertArray | T[] | Yes | Array to insert |
position | number | Yes | Position to insert at |
Returns
T[] - Modified target array
extractSlug
Extracts the last segment (slug) from a pathname.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
pathname | string | Yes | Pathname to extract slug from |
Returns
string | null - Extracted slug or null if not found
removeTypename
Recursively removes __typename fields from GraphQL response objects.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
object | T | Yes | Object to clean |
Returns
T - Object without __typename fields
convertAddressToAdressInput
Converts an Address or OrderAddress to CreateAddressInput format.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
address | Address | OrderAddress | No | Address to convert |
Returns
CreateAddressInput | null - Converted address input or null if address is undefined
setCssVariable
Sets a CSS custom property on the document root element (web-only).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | CSS variable name (e.g., '--primary-color') |
value | string | Yes | CSS variable value |
Returns
void
getCssVariable
Gets a CSS custom property value from the document root element (web-only).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | CSS variable name |
defaultValue | string | No | Default value if variable not found |
Returns
string - CSS variable value or default or empty string
generateSearchInput
Generates a search input with all available keys sorted, useful for SSR to generate correct queryKeys for react-query.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
searchInput | SearchInputWithPriceRange | Yes | Search input object |
Returns
SearchInputWithPriceRange - Sorted search input with all keys (missing keys set to undefined)
createContextScope
Creates a context scope factory for component context management.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
scopeName | string | Yes | Name for the context scope |
Returns
Tuple containing:
createContext- Function to create a scoped contextcreateScope- Function to create a scope
transformButtonProps
Transforms web button props to native button props based on platform.
Parameters
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebButtonProps | Yes | Web button props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebButtonProps | NativeButtonProps - Transformed props for the target platform
transformInputProps
Transforms web input props to native input props based on platform.
Parameters
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebInputProps | Yes | Web input props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebInputProps | NativeInputProps - Transformed props for the target platform
transformImageProps
Transforms web image props to native image props based on platform.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebImageProps | Yes | Web image props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebImageProps | NativeImageProps - Transformed props for the target platform
transformDivProps
Transforms web div props to native view props based on platform.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebDivProps | Yes | Web div props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebDivProps | NativeDivProps - Transformed props for the target platform
transformFormProps
Transforms web form props to native form props based on platform.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebFormProps | Yes | Web form props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebFormProps | NativeFormProps - Transformed props for the target platform
transformSpanProps
Transforms web span props to native text props based on platform.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | WebSpanProps | Yes | Web span props |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
WebSpanProps | NativeSpanProps - Transformed props for the target platform
mapImagePropsForNative
Maps web image props to React Native image props.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
props | ImageProps & { src?: string; alt?: string } | Yes | Image props with src and alt |
Returns
ImageProps - React Native image props
getPlatformPrimitive
Gets the appropriate component primitive for a given platform.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webPrimitive | WebPrimitive | Yes | Web HTML element tag |
platform | Platform | Yes | Target platform ('web' or 'native') |
Returns
ElementType - React component type for the platform
createSlot
Creates a slot component that can be replaced with a custom component or renders a platform-appropriate primitive.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
platform | Platform | Yes | Target platform ('web' or 'native') |
asChild | boolean | No | Whether to use slot pattern (replace with child) |
webPrimitive | WebPrimitive | No | Default web primitive to use (default: 'div') |
Returns
SlotComponent | ElementType - Slot component or primitive component
createSlottable
Creates a slottable component wrapper for slot composition.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ownerName | string | Yes | Name of the owning component |
Returns
SlottableComponent - Slottable component
logger
Default logger instance that conditionally logs based on localStorage debug flag.
Returns
Logger - Logger instance
debugUtils
Utility functions for managing debug mode.
Methods
| Method | Type | Description |
|---|---|---|
enable | () => void | Enable debug logging by setting localStorage flag |
disable | () => void | Disable debug logging by removing localStorage flag |
isEnabled | () => boolean | Check if debug mode is currently enabled |
toggle | () => void | Toggle debug mode |
Returns
DebugUtils - Debug utilities object
Basic Usage
Platform Detection
- React
- React Native
import { isNativePlatform } from '@haus-storefront-react/common-utils'
function MyComponent() {
const { isReactNative, isSSR } = isNativePlatform()
if (isSSR) {
return <div>Server rendering...</div>
}
return <div>Platform: {isReactNative ? 'Native' : 'Web'}</div>
}
import { View, Text } from 'react-native'
import { isNativePlatform } from '@haus-storefront-react/common-utils'
function MyComponent() {
const { isReactNative, isSSR } = isNativePlatform()
if (isSSR) {
return <Text>Server rendering...</Text>
}
return <Text>Platform: {isReactNative ? 'Native' : 'Web'}</Text>
}
Price Formatting
- React
- React Native
import { formatPrice, getPrice } from '@haus-storefront-react/common-utils'
function PriceDisplay({ price, currencyCode }) {
const numericPrice = getPrice(price)
const formatted = formatPrice(numericPrice, currencyCode)
return <span>{formatted}</span>
}
import { Text } from 'react-native'
import { formatPrice, getPrice } from '@haus-storefront-react/common-utils'
function PriceDisplay({ price, currencyCode }) {
const numericPrice = getPrice(price)
const formatted = formatPrice(numericPrice, currencyCode)
return <Text>{formatted}</Text>
}
Error Handling
- React
- React Native
import { isError, getError } from '@haus-storefront-react/common-utils'
function ErrorDisplay({ error }) {
if (!isError(error)) return null
const errorInfo = getError(error)
return <div>Error: {errorInfo?.message}</div>
}
import { View, Text } from 'react-native'
import { isError, getError } from '@haus-storefront-react/common-utils'
function ErrorDisplay({ error }) {
if (!isError(error)) return null
const errorInfo = getError(error)
return <Text>Error: {errorInfo?.message}</Text>
}
Advanced Usage
Complex Cross-Platform Component
- React
- React Native
import React from 'react'
import {
createSlot,
transformInputProps,
renderChildren,
isNativePlatform,
getPlatformPrimitive,
} from '@haus-storefront-react/common-utils'
function SearchInput({ children, asChild, ...props }) {
const { isReactNative, isSSR } = isNativePlatform()
const platform = isReactNative || isSSR ? 'native' : 'web'
const InputComp = asChild
? createSlot(platform, true, 'input')
: getPlatformPrimitive('input', platform)
const inputProps = transformInputProps(props, platform)
return (
<InputComp {...inputProps}>
{renderChildren(children, { platform, ...props })}
</InputComp>
)
}
import React from 'react'
import {
createSlot,
getPlatformPrimitive,
transformInputProps,
renderChildren,
isNativePlatform,
} from '@haus-storefront-react/common-utils'
function SearchInput({ children, asChild, ...props }) {
const { isReactNative, isSSR } = isNativePlatform()
const platform = isReactNative || isSSR ? 'native' : 'web'
const InputComp = asChild
? createSlot(platform, true, 'input')
: getPlatformPrimitive('input', platform)
const inputProps = transformInputProps(props, platform)
return (
<InputComp {...inputProps}>
{renderChildren(children, { platform, ...props })}
</InputComp>
)
}
Data Manipulation Pipeline
- React
- React Native
import {
removeTypename,
extractSlug,
insertAndOverwrite,
generateSearchInput,
} from '@haus-storefront-react/common-utils'
function processGraphQLData(data, pathname) {
// Clean GraphQL data
const cleanData = removeTypename(data)
// Extract slug from pathname
const slug = extractSlug(pathname)
// Process array
const newItems = [{ id: 1 }, { id: 2 }]
const updatedArray = insertAndOverwrite(cleanData.items, newItems, 0)
// Generate search input for SSR
const searchInput = generateSearchInput({
term: slug || '',
take: 10,
skip: 0,
})
return { cleanData, slug, updatedArray, searchInput }
}
import {
removeTypename,
extractSlug,
insertAndOverwrite,
generateSearchInput,
} from '@haus-storefront-react/common-utils'
function processGraphQLData(data, pathname) {
// Clean GraphQL data
const cleanData = removeTypename(data)
// Extract slug from pathname
const slug = extractSlug(pathname)
// Process array
const newItems = [{ id: 1 }, { id: 2 }]
const updatedArray = insertAndOverwrite(cleanData.items, newItems, 0)
// Generate search input for SSR
const searchInput = generateSearchInput({
term: slug || '',
take: 10,
skip: 0,
})
return { cleanData, slug, updatedArray, searchInput }
}
Logger with Namespace
- React
- React Native
import { useEffect } from 'react'
import { logger, debugUtils } from '@haus-storefront-react/common-utils'
// Enable debug mode
debugUtils.enable()
function MyComponent() {
useEffect(() => {
logger.group('Component Lifecycle', 'MyComponent')
logger.time('Render Time', 'MyComponent')
logger.log('Component mounted', 'MyComponent')
return () => {
logger.log('Component unmounted', 'MyComponent')
logger.timeEnd('Render Time', 'MyComponent')
logger.groupEnd()
}
}, [])
const handleClick = () => {
logger.info('Button clicked', 'MyComponent')
}
return <button onClick={handleClick}>Click me</button>
}
import { useEffect } from 'react'
import { Button, View } from 'react-native'
import { logger, debugUtils } from '@haus-storefront-react/common-utils'
debugUtils.enable()
function MyComponent() {
useEffect(() => {
logger.group('Component Lifecycle', 'MobileComponent')
logger.time('Render Time', 'MobileComponent')
logger.log('Component mounted', 'MobileComponent')
return () => {
logger.log('Component unmounted', 'MobileComponent')
logger.timeEnd('Render Time', 'MobileComponent')
logger.groupEnd()
}
}, [])
const handlePress = () => {
logger.info('Button pressed', 'MobileComponent')
}
return (
<View>
<Button title='Click me' onPress={handlePress} />
</View>
)
}
Conditional Rendering with Platform Primitives
- React
- React Native
import {
getPlatformPrimitive,
isNativePlatform,
transformImageProps,
} from '@haus-storefront-react/common-utils'
function ResponsiveImage({ src, alt, ...props }) {
const { isReactNative, isSSR } = isNativePlatform()
const platform = isReactNative || isSSR ? 'native' : 'web'
const ImageComponent = getPlatformPrimitive('img', platform)
const imageProps = transformImageProps({ src, alt, ...props }, platform)
return <ImageComponent {...imageProps} />
}
import { View } from 'react-native'
import {
getPlatformPrimitive,
isNativePlatform,
transformImageProps,
} from '@haus-storefront-react/common-utils'
function ResponsiveImage({ src, alt, ...props }) {
const { isReactNative } = isNativePlatform()
const platform = isReactNative ? 'native' : 'web'
const ImageComponent = getPlatformPrimitive('img', platform)
const imageProps = transformImageProps({ src, alt, ...props }, platform)
return (
<View>
<ImageComponent {...imageProps} />
</View>
)
}
Made with ❤️ by Haus Tech Team