import { css } from 'styled-components';
export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
export type Responsive<T> = Partial<Record<Breakpoint, T>>;
declare const isResponsiveKey: unique symbol;
declare const responsiveValue: unique symbol;
/**
 * An opaque object that wraps a responsive value. we use symbols to make it
 * difficult to access responsive value directly.
 */
export declare class OpaqueResponsive<T> {
    [isResponsiveKey]: symbol;
    [responsiveValue]: Responsive<T>;
    constructor(value: Responsive<T>);
}
/**
 * Either a single value or a responsive object of a certain type
 */
export type ValueOrResponsive<T> = T | Responsive<T>;
/**
 * Creates an opaque object that wraps a responsive value
 */
export declare function wrapResponsive<T>(value?: ValueOrResponsive<T> | OpaqueResponsive<T>): OpaqueResponsive<T>;
/**
 * Unwraps a responsive value from a wrapped responsive object and throws an error
 * if the value is not a OpaqueResponsive object.
 */
export declare function unwrapResponsive<T>(value: OpaqueResponsive<T>): Responsive<T>;
/**
 * Merge multiple responsive values into a single responsive value
 * where the values are merged together
 */
export declare function mergeResponsive<T>(values: Array<OpaqueResponsive<T>>): OpaqueResponsive<T>;
/**
 * Merge multiple responsive values into a unified responsive value
 * with keys that are merged together
 */
export declare function mergeNamedResponsive<T>(values: {
    [K in keyof T]: OpaqueResponsive<T[K]>;
}): OpaqueResponsive<Partial<T>>;
/**
 * Merge multiple responsive values into a single responsive value
 * where the values are merged together with values cascading from
 * smaller breakpoints to larger breakpoints like in CSS media queries
 *
 * For example, if we have the following values:
 * - { xs: 10, sm: 20, md: 30 }
 * - { xs: 5, md: 15, lg: 15 }
 * - { xxl: 30 }
 *
 * we would get the following merged values:
 * - { xs: 5, md: 15, xxl: 30 }
 */
export declare function mergeResponsivePreferringLastValue<T>(values: Array<OpaqueResponsive<T>>): OpaqueResponsive<T>;
/**
 * Map a responsive value to a new value
 */
export declare function mapResponsive<T, R>(values: OpaqueResponsive<T>, mapper: (value: T, breakpoint: Breakpoint) => R): OpaqueResponsive<R>;
/**
 * Reduce multiple responsive values into a single responsive value
 */
export declare function reduceResponsive<T, R>(values: OpaqueResponsive<T>, reducer: (acc: R, value: T, key: Breakpoint) => R, initialValue: R): R;
/**
 * Predicate to check if an opaque object has values
 */
export declare function hasResponsiveValue<T>(value: OpaqueResponsive<T>): boolean;
/**
 * Predicate to check if a value is a responsive object
 */
export declare function isResponsive<T>(value: ValueOrResponsive<T>): boolean;
/**
 * Converts a value or responsive value into a CSS string using the
 * mediaForBreakpoint helper to generate media queries for each breakpoint
 * and the mapValue function to generate the CSS for each value
 */
export declare function cssForResponsive<T>(values: OpaqueResponsive<T>, mapValue: (value: T, key: Breakpoint, object: Responsive<T>) => ReturnType<typeof css> | undefined): ReturnType<typeof css>;
/**
 * Generates CSS for a specific property that can be responsive. A transform function is required
 * when the property value is not a string, otherwise an error will be thrown.
 */
export declare function cssForResponsiveProp<T>(propName: string, propValue: OpaqueResponsive<T>, transform: (value: T) => string): ReturnType<typeof css>;
export declare function cssForResponsiveProp<T extends string>(propName: string, propValue: OpaqueResponsive<T>, transform?: (value: T) => string): ReturnType<typeof css>;
export {};
