@patreon/studio
Version:
Patreon Studio Design System
83 lines (82 loc) • 3.74 kB
TypeScript
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 {};