<commit_before>import React, { useMemo } from 'react';
import isHasRef from '../isHasRef';
import sharedDefaults from '../sharedDefaults';
import { defaultClassNameTransformer, defaultStyleTransformer } from './utils';
import props2className from './props2className';
import props2style from './props2style';

type Globals = 'inherit' | 'initial' | 'unset';

type FlexPosition = 'center' | 'flex-end' | 'flex-start';

type ContentDistribution = 'space-around' | 'space-between' | 'space-evenly' | 'stretch';

export type JustifyContent = Globals | ContentDistribution | FlexPosition;

export type AlignItems = Globals | FlexPosition | 'baseline' | 'stretch';

export type AlignSelf = AlignItems | 'auto';

export type AlignContent = Globals | ContentDistribution | FlexPosition;

export type FlexBasis = Globals | 'auto' | 'content' | number;

export type FlexWrap = Globals | 'nowrap' | 'wrap' | 'wrap-reverse';

export type Column = number | string | boolean;

export interface FlexProps {
  /** Whether sets `display` to `flex` or not. Default `true`. */
  flex?: boolean;
  /** Sets `display` to `inline-flex`. */
  inline?: boolean;
  /** Sets `flow-direction` to `row`. */
  row?: boolean;
  /** Sets `flow-direction` to `column`. Takes a precedence over `row`. */
  column?: boolean;
  /** Used with `row` or `col`. Sets `flow-direction` to `column-reverse` or `row-reverse`. */
  reverse?: boolean;
  /** Sets `flex-wrap` to corresponding value. Also accepts boolean value: `true` equals to `wrap`, `false` equals to `nowrap`. */
  wrap?: FlexWrap | boolean;
  /** Sets `align-content` to corresponding value. */
  alignContent?: AlignContent;
  /** Sets `align-items` to corresponding value. */
  alignItems?: AlignItems;
  /** Sets `align-self` to corresponding value. */
  alignSelf?: AlignSelf;
  /** Sets `justify-content` to corresponding value. */
  justifyContent?: JustifyContent;
  /** Sets `justifyContent` and `alignItems` to `center`. `justifyContent` and `alignItems` take a precedence over `center`. */
  center?: boolean;
  /** Sets `flex-basis` to corresponding value. */
  basis?: FlexBasis;
  /** Sets `flex-grow` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */
  grow?: Column;
  /** Sets `flex-shrink` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */
  shrink?: Column;
  /** Sets `order` to corresponding value. */
  order?: number;
  /** Stretch by horizontal or sets width in percentage (numbers in range 0.0 to 1.0 inclusive). */
  hfill?: boolean | number;
  /** Stretch by vertical or sets height in percentage (numbers in range 0.0 to 1.0 inclusive). */
  vfill?: boolean | number;
  /** Stretch by vertical and horizontal. */
  fill?: boolean;
  /**
   * 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;
  /** Sets `min-width` to `0`. Takes a precedence over `shrinkByContent`. */
  shrinkWidth?: boolean;
  /** Sets `min-height` to `0`. Takes a precedence over `shrinkByContent`. */
  shrinkHeight?: boolean;
}

export type SpaceSize = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl';

export type SpaceUnit =
  | 'px'
  | 'em'
  | 'rem'
  | 'ex'
  | 'ch'
  | '%'
  | 'vw'
  | 'vh'
  | 'cm'
  | 'mm'
  | 'in'
  | 'pt'
  | 'pc'
  | number;

export interface SpaceProps {
  /** Measure unit of space */
  unit?: SpaceUnit;
  /** Size of margin */
  mSize?: SpaceSize | number;
  /** Measure unit of margin */
  mUnit?: SpaceUnit;
  /** margin */
  m?: boolean | number | SpaceSize;
  /** margin-top */
  mt?: boolean | number | SpaceSize;
  /** margin-right */
  mr?: boolean | number | SpaceSize;
  /** margin-bottom */
  mb?: boolean | number | SpaceSize;
  /** margin-left */
  ml?: boolean | number | SpaceSize;
  /** margin by x axis: margin-left & margin-right */
  mx?: boolean | number | SpaceSize;
  /** margin by y axis: margin-top & margin-bottom */
  my?: boolean | number | SpaceSize;
  /** Size of padding */
  pSize?: SpaceSize | number;
  /** Measure unit of padding */
  pUnit?: SpaceUnit;
  /** padding */
  p?: boolean | number | SpaceSize;
  /** padding-top */
  pt?: boolean | number | SpaceSize;
  /** padding-right */
  pr?: boolean | number | SpaceSize;
  /** padding-bottom */
  pb?: boolean | number | SpaceSize;
  /** padding-left */
  pl?: boolean | number | SpaceSize;
  /** padding by x axis: padding-left & padding-right */
  px?: boolean | number | SpaceSize;
  /** padding by y axis: padding-top & padding-bottom */
  py?: boolean | number | SpaceSize;
}

export type Overflow = Globals | 'auto' | 'hidden' | 'scroll' | 'visible';

export interface OverflowProps {
  overflow?: Overflow;
  overflowX?: OverflowProps['overflow'];
  overflowY?: OverflowProps['overflow'];
  /** Shortcut for overflow */
  scrollable?: Extract<Overflow, 'auto' | 'scroll'> | boolean;
  scrollableX?: OverflowProps['scrollable'];
  scrollableY?: OverflowProps['scrollable'];
}

export interface Styleable<C = string, S = React.CSSProperties> {
  className?: C;
  style?: S;
}

export type ClassNameTransformer<T, R = T> = (
  calcClassName: string,
  userClassName?: T
) => NonNullable<R>;

export type StyleTransformer<T, R = T> = (calcStyle?: React.CSSProperties, userStyle?: T) => R;

export interface Transformable<C = string, S = React.CSSProperties, CR = C, SR = S> {
  classNameTransformer?: ClassNameTransformer<C, CR>;
  styleTransformer?: StyleTransformer<S, SR>;
}

type AnyObject = Record<string, any>;

export type StylesProps<
  P extends AnyObject,
  DefaultStyles extends boolean = false
> = DefaultStyles extends true
  ? Styleable
  : P extends Styleable<infer C, infer S>
  ? Styleable<C, S>
  : Styleable<unknown, unknown>;

export type StylesTransformersProps<
  P extends { [P: string]: any },
  DefaultStyles extends boolean = false
> = DefaultStyles extends true
  ? Transformable<string, React.CSSProperties, P['className'], P['style']>
  : Transformable<P['className'], P['style']>;

type PropsWithComponentRef<P extends AnyObject> = P extends { ref?: any }
  ? P & { componentRef?: P['ref'] }
  : P;

// Since TS 3.7.3
// Use `Omit` (as copy of object type) to make TweakableComponentProps as object
// and to avoid `Rest types may only be created from object types.ts(2700)` error in Flex props.
export type TweakableComponentProps<C extends React.ElementType> = {
  /**
   * Sets custom react component as a container.
   * Component must accept className and style through props. */
  component?: C;
} & Omit<
  undefined extends C
    ? Record<never, never>
    : PropsWithComponentRef<React.ComponentPropsWithRef<C>>,
  'ref'
>;

// Since TS 3.7.3
// Use `div` instead of `React.ElementType<JSX.IntrinsicElements['div']>` to avoid
// `Type instantiation is excessively deep and possibly infinite.` error.
export type DefaultComponentType = 'div';

type PropsWithStyles<P extends AnyObject, DefaultStyles extends boolean> = P &
  StylesProps<P, DefaultStyles>;

type PropsWithStylesTransformers<
  P extends AnyObject,
  DefaultStyles extends boolean
> = PropsWithStyles<P, DefaultStyles> & StylesTransformersProps<P, DefaultStyles>;

type GetComponentRefProp<P extends AnyObject> = P extends { componentRef?: any }
  ? Pick<P, 'componentRef'>
  : P;

export type FlexComponentProps<
  C extends React.ElementType = any,
  DefaultStyles extends boolean = undefined extends C ? true : false,
  OmitComponentProps extends boolean = false
> = FlexProps &
  SpaceProps &
  OverflowProps &
  PropsWithStyles<
    OmitComponentProps extends true
      ? GetComponentRefProp<TweakableComponentProps<C>>
      : Omit<TweakableComponentProps<C>, 'component'>,
    DefaultStyles<commit_msg>Exclude component prop from component props<commit_after>import React, { useMemo } from 'react';
import isHasRef from '../isHasRef';
import sharedDefaults from '../sharedDefaults';
import { defaultClassNameTransformer, defaultStyleTransformer } from './utils';
import props2className from './props2className';
import props2style from './props2style';

type Globals = 'inherit' | 'initial' | 'unset';

type FlexPosition = 'center' | 'flex-end' | 'flex-start';

type ContentDistribution = 'space-around' | 'space-between' | 'space-evenly' | 'stretch';

export type JustifyContent = Globals | ContentDistribution | FlexPosition;

export type AlignItems = Globals | FlexPosition | 'baseline' | 'stretch';

export type AlignSelf = AlignItems | 'auto';

export type AlignContent = Globals | ContentDistribution | FlexPosition;

export type FlexBasis = Globals | 'auto' | 'content' | number;

export type FlexWrap = Globals | 'nowrap' | 'wrap' | 'wrap-reverse';

export type Column = number | string | boolean;

export interface FlexProps {
  /** Whether sets `display` to `flex` or not. Default `true`. */
  flex?: boolean;
  /** Sets `display` to `inline-flex`. */
  inline?: boolean;
  /** Sets `flow-direction` to `row`. */
  row?: boolean;
  /** Sets `flow-direction` to `column`. Takes a precedence over `row`. */
  column?: boolean;
  /** Used with `row` or `col`. Sets `flow-direction` to `column-reverse` or `row-reverse`. */
  reverse?: boolean;
  /** Sets `flex-wrap` to corresponding value. Also accepts boolean value: `true` equals to `wrap`, `false` equals to `nowrap`. */
  wrap?: FlexWrap | boolean;
  /** Sets `align-content` to corresponding value. */
  alignContent?: AlignContent;
  /** Sets `align-items` to corresponding value. */
  alignItems?: AlignItems;
  /** Sets `align-self` to corresponding value. */
  alignSelf?: AlignSelf;
  /** Sets `justify-content` to corresponding value. */
  justifyContent?: JustifyContent;
  /** Sets `justifyContent` and `alignItems` to `center`. `justifyContent` and `alignItems` take a precedence over `center`. */
  center?: boolean;
  /** Sets `flex-basis` to corresponding value. */
  basis?: FlexBasis;
  /** Sets `flex-grow` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */
  grow?: Column;
  /** Sets `flex-shrink` to corresponding value. Also accepts boolean value: `true` equals to `1`, `false` equals to `0`. */
  shrink?: Column;
  /** Sets `order` to corresponding value. */
  order?: number;
  /** Stretch by horizontal or sets width in percentage (numbers in range 0.0 to 1.0 inclusive). */
  hfill?: boolean | number;
  /** Stretch by vertical or sets height in percentage (numbers in range 0.0 to 1.0 inclusive). */
  vfill?: boolean | number;
  /** Stretch by vertical and horizontal. */
  fill?: boolean;
  /**
   * 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;
  /** Sets `min-width` to `0`. Takes a precedence over `shrinkByContent`. */
  shrinkWidth?: boolean;
  /** Sets `min-height` to `0`. Takes a precedence over `shrinkByContent`. */
  shrinkHeight?: boolean;
}

export type SpaceSize = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl';

export type SpaceUnit =
  | 'px'
  | 'em'
  | 'rem'
  | 'ex'
  | 'ch'
  | '%'
  | 'vw'
  | 'vh'
  | 'cm'
  | 'mm'
  | 'in'
  | 'pt'
  | 'pc'
  | number;

export interface SpaceProps {
  /** Measure unit of space */
  unit?: SpaceUnit;
  /** Size of margin */
  mSize?: SpaceSize | number;
  /** Measure unit of margin */
  mUnit?: SpaceUnit;
  /** margin */
  m?: boolean | number | SpaceSize;
  /** margin-top */
  mt?: boolean | number | SpaceSize;
  /** margin-right */
  mr?: boolean | number | SpaceSize;
  /** margin-bottom */
  mb?: boolean | number | SpaceSize;
  /** margin-left */
  ml?: boolean | number | SpaceSize;
  /** margin by x axis: margin-left & margin-right */
  mx?: boolean | number | SpaceSize;
  /** margin by y axis: margin-top & margin-bottom */
  my?: boolean | number | SpaceSize;
  /** Size of padding */
  pSize?: SpaceSize | number;
  /** Measure unit of padding */
  pUnit?: SpaceUnit;
  /** padding */
  p?: boolean | number | SpaceSize;
  /** padding-top */
  pt?: boolean | number | SpaceSize;
  /** padding-right */
  pr?: boolean | number | SpaceSize;
  /** padding-bottom */
  pb?: boolean | number | SpaceSize;
  /** padding-left */
  pl?: boolean | number | SpaceSize;
  /** padding by x axis: padding-left & padding-right */
  px?: boolean | number | SpaceSize;
  /** padding by y axis: padding-top & padding-bottom */
  py?: boolean | number | SpaceSize;
}

export type Overflow = Globals | 'auto' | 'hidden' | 'scroll' | 'visible';

export interface OverflowProps {
  overflow?: Overflow;
  overflowX?: OverflowProps['overflow'];
  overflowY?: OverflowProps['overflow'];
  /** Shortcut for overflow */
  scrollable?: Extract<Overflow, 'auto' | 'scroll'> | boolean;
  scrollableX?: OverflowProps['scrollable'];
  scrollableY?: OverflowProps['scrollable'];
}

export interface Styleable<C = string, S = React.CSSProperties> {
  className?: C;
  style?: S;
}

export type ClassNameTransformer<T, R = T> = (
  calcClassName: string,
  userClassName?: T
) => NonNullable<R>;

export type StyleTransformer<T, R = T> = (calcStyle?: React.CSSProperties, userStyle?: T) => R;

export interface Transformable<C = string, S = React.CSSProperties, CR = C, SR = S> {
  classNameTransformer?: ClassNameTransformer<C, CR>;
  styleTransformer?: StyleTransformer<S, SR>;
}

type AnyObject = Record<string, any>;

export type StylesProps<
  P extends AnyObject,
  DefaultStyles extends boolean = false
> = DefaultStyles extends true
  ? Styleable
  : P extends Styleable<infer C, infer S>
  ? Styleable<C, S>
  : Styleable<unknown, unknown>;

export type StylesTransformersProps<
  P extends { [P: string]: any },
  DefaultStyles extends boolean = false
> = DefaultStyles extends true
  ? Transformable<string, React.CSSProperties, P['className'], P['style']>
  : Transformable<P['className'], P['style']>;

type PropsWithComponentRef<P extends AnyObject> = P extends { ref?: any }
  ? P & { componentRef?: P['ref'] }
  : P;

// Since TS 3.7.3
// Use `Omit` (as copy of object type) to make TweakableComponentProps as object
// and to avoid `Rest types may only be created from object types.ts(2700)` error in Flex props.
export type TweakableComponentProps<C extends React.ElementType> = {
  /**
   * Sets custom react component as a container.
   * Component must accept className and style through props. */
  component?: C;
} & Omit<
  undefined extends C
    ? Record<never, never>
    : PropsWithComponentRef<React.ComponentPropsWithRef<C>>,
  'ref' | 'component' /* if `C` is Flexed component and already contains `component` prop */
>;

// Since TS 3.7.3
// Use `div` instead of `React.ElementType<JSX.IntrinsicElements['div']>` to avoid
// `Type instantiation is excessively deep and possibly infinite.` error.
export type DefaultComponentType = 'div';

type PropsWithStyles<P extends AnyObject, DefaultStyles extends boolean> = P &
  StylesProps<P, DefaultStyles>;

type PropsWithStylesTransformers<
  P extends AnyObject,
  DefaultStyles extends boolean
> = PropsWithStyles<P, DefaultStyles> & StylesTransformersProps<P, DefaultStyles>;

type GetComponentRefProp<P extends AnyObject> = P extends { componentRef?: any }
  ? Pick<P, 'componentRef'>
  : P;

export type FlexComponentProps<
  C extends React.ElementType = any,
  DefaultStyles extends boolean = undefined extends C ? true : false,
  OmitComponentProps extends boolean = false
> = FlexProps &
  SpaceProps &
  OverflowProps &
  PropsWithStyles<
    OmitComponentProps extends true
      ? GetComponentRefProp<TweakableComponentProps<C>>
      : Omit<TweakableComponentProps<C>, 'component'>,
    DefaultStyles
{'fraction_non_alphanumeric': 0.14000623635796694, 'fraction_numerical': 0.003991269098846274, 'mean_word_length': 3.8800973828362753, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7441159', 'n_tokens_mistral': 4969, 'n_tokens_neox': 4881, 'n_words': 1627}