UNPKG

reflexy

Version:

Flexbox layout react components

166 lines (165 loc) 8.91 kB
import type { ComponentProps, GetComponentProps } from '../types'; type Globals = 'inherit' | 'initial' | 'unset'; type FlexPosition = 'center' | 'flex-end' | 'flex-start'; type ContentDistribution = 'space-around' | 'space-between' | 'space-evenly' | 'stretch'; type JustifyContent = Globals | ContentDistribution | FlexPosition; type AlignItems = Globals | FlexPosition | 'baseline' | 'stretch'; type AlignSelf = AlignItems | 'auto'; type AlignContent = Globals | ContentDistribution | FlexPosition; type FlexBasis = Globals | 'auto' | 'content' | number; type FlexWrap = Globals | 'nowrap' | 'wrap' | 'wrap-reverse'; type Column = number | string | boolean; export interface FlexProps { /** Whether sets `display` to `flex` or not. Default `true`. */ flex?: boolean | undefined; /** Sets `display` to `inline-flex`. */ inline?: boolean | undefined; /** Sets `flow-direction` to `row`. */ row?: boolean | undefined; /** Sets `flow-direction` to `column`. Takes a precedence over `row`. */ column?: boolean | undefined; /** Used with `row` or `col`. Sets `flow-direction` to `column-reverse` or `row-reverse`. */ reverse?: boolean | undefined; /** Sets `flex-wrap` to corresponding value. Also accepts boolean value: `true` equals to `wrap`, `false` equals to `nowrap`. */ wrap?: FlexWrap | boolean | undefined; /** Sets `align-content` to corresponding value. */ alignContent?: AlignContent | undefined; /** Sets `align-items` to corresponding value. */ alignItems?: AlignItems | undefined; /** Sets `align-self` to corresponding value. */ alignSelf?: AlignSelf | undefined; /** Sets `justify-content` to corresponding value. */ justifyContent?: JustifyContent | undefined; /** Sets `justifyContent` and `alignItems` to `center`. `justifyContent` and `alignItems` take a precedence over `center`. */ center?: boolean | undefined; /** Sets `flex-basis` to corresponding value. */ basis?: FlexBasis | undefined; /** Sets `flex-grow` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */ grow?: Column | undefined; /** Sets `flex-shrink` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */ shrink?: Column | undefined; /** Sets `order` to corresponding value. */ order?: number | undefined; /** Stretch by horizontal or sets width in percentage (numbers in range 0.0 to 1.0 inclusive). */ hfill?: boolean | number | undefined; /** Stretch by vertical or sets height in percentage (numbers in range 0.0 to 1.0 inclusive). */ vfill?: boolean | number | undefined; /** Stretch by vertical and horizontal. */ fill?: boolean | undefined; /** * Sets `min-width: 0` and `min-height: 0`. * By default, a flex item cannot be smaller than the size of its content. * The initial setting on flex items is `min-width: auto` and `min-height: auto`. * One way to enable flex items to shrink past their content is to set a flex item to `min-width: 0` or `min-height: 0`. */ shrinkByContent?: boolean | undefined; /** Sets `min-width` to `0`. Takes a precedence over `shrinkByContent`. */ shrinkWidth?: boolean | undefined; /** Sets `min-height` to `0`. Takes a precedence over `shrinkByContent`. */ shrinkHeight?: boolean | undefined; } export type SpaceSize = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'; export type SSpaceSize = `-${SpaceSize}`; export type Space = number | SpaceSize | SSpaceSize; /** `number` treat as number of pixels */ export type SpaceUnit = 'px' | 'em' | 'rem' | 'ex' | 'ch' | 'cm' | 'mm' | 'in' | 'pt' | 'pc' | number; export interface SpaceProps { /** Measure unit of space */ unit?: SpaceUnit | undefined; /** Size of margin */ mSize?: Space | undefined; /** Measure unit of margin */ mUnit?: SpaceUnit | undefined; /** margin */ m?: boolean | Space | undefined; /** margin-top */ mt?: boolean | Space | undefined; /** margin-right */ mr?: boolean | Space | undefined; /** margin-bottom */ mb?: boolean | Space | undefined; /** margin-left */ ml?: boolean | Space | undefined; /** margin by x axis: margin-left & margin-right */ mx?: boolean | Space | undefined; /** margin by y axis: margin-top & margin-bottom */ my?: boolean | Space | undefined; /** Size of padding */ pSize?: Space | undefined; /** Measure unit of padding */ pUnit?: SpaceUnit | undefined; /** padding */ p?: boolean | Space | undefined; /** padding-top */ pt?: boolean | Space | undefined; /** padding-right */ pr?: boolean | Space | undefined; /** padding-bottom */ pb?: boolean | Space | undefined; /** padding-left */ pl?: boolean | Space | undefined; /** padding by x axis: padding-left & padding-right */ px?: boolean | Space | undefined; /** padding by y axis: padding-top & padding-bottom */ py?: boolean | Space | undefined; } export type Overflow = Globals | 'auto' | 'hidden' | 'scroll' | 'visible'; export interface OverflowProps { overflow?: Overflow | undefined; overflowX?: OverflowProps['overflow'] | undefined; overflowY?: OverflowProps['overflow'] | undefined; /** Shortcut for overflow */ scrollable?: Extract<Overflow, 'auto' | 'scroll'> | boolean | undefined; scrollableX?: OverflowProps['scrollable'] | undefined; scrollableY?: OverflowProps['scrollable'] | undefined; } export type FlexOnlyProps = FlexProps & SpaceProps & OverflowProps; export interface Styleable<C = string, S = React.CSSProperties> { className?: C | undefined; style?: S | undefined; } export type ClassNameTransformer<T, R = T> = (calcClassName: string, userClassName?: T) => NonNullable<R>; export type StyleTransformer<T, R = T> = (calcStyle?: React.CSSProperties, userStyle?: T) => R; interface StylesOptions { inferStyleProps?: boolean | { className?: boolean | undefined; style?: boolean | undefined; } | undefined; } export type StylesProps<P extends AnyObject, O extends StylesOptions = { inferStyleProps: true; }, InferClassName extends boolean = O['inferStyleProps'] extends boolean ? O['inferStyleProps'] : NonNullable<Exclude<O['inferStyleProps'], boolean | undefined>['className']>, InferStyle extends boolean = O['inferStyleProps'] extends boolean ? O['inferStyleProps'] : NonNullable<Exclude<O['inferStyleProps'], boolean | undefined>['style']>> = P extends Styleable<infer C, infer S> ? Styleable<InferClassName extends true ? C : string, InferStyle extends true ? S : React.CSSProperties> : Styleable<InferClassName extends true ? unknown : string, InferStyle extends true ? unknown : React.CSSProperties>; type PropsWithStyles<P extends AnyObject, O extends StylesOptions> = StylesProps<P, O> & Omit<P, keyof Styleable>; export type GetStylesTransformers<StyledProps extends Styleable<unknown, unknown>, OriginProps extends AnyObject = StyledProps, Strict extends boolean = false> = Strict extends true ? ([StyledProps['className'], OriginProps['className']] extends [ string | undefined, string | undefined ] ? {} : { classNameTransformer?: ClassNameTransformer<StyledProps['className'], OriginProps['className']> | undefined; }) & ([StyledProps['style'], OriginProps['style']] extends [ React.CSSProperties | undefined, React.CSSProperties | undefined ] ? {} : { styleTransformer?: StyleTransformer<StyledProps['style'], OriginProps['style']> | undefined; }) : { classNameTransformer?: ClassNameTransformer<StyledProps['className'], OriginProps['className']> | undefined; styleTransformer?: StyleTransformer<StyledProps['style'], OriginProps['style']> | undefined; }; type PropsWithStylesTransformers<P extends AnyObject, O extends StylesOptions, Styled extends Styleable<unknown, unknown> = PropsWithStyles<P, O>> = Styled & GetStylesTransformers<Styled, P, true>; interface PropsOptions extends StylesOptions { omitProps?: boolean | undefined; } /** All props or `ref`, `style`, `className`. */ type FilterComponentProps<P extends AnyObject, O extends PropsOptions> = O['omitProps'] extends true ? Pick<P, Extract<keyof P, 'ref' | keyof Styleable>> : P; export type FlexComponentProps<C extends React.ElementType = any, O extends PropsOptions = { omitProps: false; inferStyleProps: false; }> = FlexOnlyProps & PropsWithStyles<FilterComponentProps<ComponentProps<C>, O>, O>; export type FlexAllProps<C extends React.ElementType = any, O extends StylesOptions = { inferStyleProps: false; }> = FlexOnlyProps & PropsWithStylesTransformers<GetComponentProps<C>, O> & { /** * Sets custom react component as a container. * Component must accept className and style through props. */ component?: C | undefined; }; export type DefaultComponentType = 'div'; export {};