import * as React from 'react';
import classNames from 'classnames';
import {
DIRECTION,
JUSTIFY_VALUES,
ALIGNMENT_VALUES,
MARGINS,
GAP_VALUES,
FLEX_VALUES,
} from './FlexConsts';
import {generateResponsiveClassNames} from '../utils/responsive-props';
import type {ResponsivePropType} from '../utils/responsive-props';
type FlexContainerType =
| 'a'
| 'article'
| 'aside'
| 'div'
| 'footer'
| 'form'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'header'
| 'input'
| 'li'
| 'main'
| 'nav'
| 'ol'
| 'p'
| 'pre'
| 'section'
| 'span'
| 'textarea'
| 'ul';
type FlexDirectionType = 'column' | 'column-reverse' | 'row' | 'row-reverse';
type FlexJustifyValuesType =
| 'center'
| 'flex-start'
| 'flex-end'
| 'space-between'
| 'space-around'
| 'space-evenly'
| 'stretch';
type FlexAlignmentValuesType =
| 'center'
| 'flex-start'
| 'flex-end'
| 'baseline'
| 'stretch';
type FlexMarginsType =
| 'none'
| 'xxs'
| 'xs'
| 's'
| 'm'
| 'l'
| 'xl'
| 'xxl'
| 'xxxl'
| 'xxxxl';
type FlexGapValueType =
| 'none'
| 'xxs'
| 'xs'
| 's'
| 'm'
| 'l'
| 'xl'
| 'xxl'
| 'xxxl'
| 'xxxxl';
type FlexFlexValueType =
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 'auto'
| 'initial'
| 'none';
export {
DIRECTION,
JUSTIFY_VALUES,
ALIGNMENT_VALUES,
MARGINS,
GAP_VALUES,
FLEX_VALUES,
};
export type FlexPropsType = {
/**
* Children to be render inside of the Flex.
* @example
* children to be render here
*
*
*/
children: React.ReactNode;
/**
* Html tag used as container
*/
as?: FlexContainerType;
/**
* Additional class names
*/
className?: string;
/**
* component will be rendered on 100% width of a parent
* @example
* component content
*
*/
fullWidth?: ResponsivePropType;
/**
* component will be rendered on 100% height of a parent
* @example
* component content
*
*/
fullHeight?: ResponsivePropType;
/**
* It will set flex-shirnk to 0
* @example
* component content
*
*/
noShrink?: ResponsivePropType;
/**
* Specify flex direction
* @example
* component content
*
* @see direction=column https://styleguide.brainly.com/latest/docs/interactive.html?direction=column#flexbox
* @see direction=column-reverse https://styleguide.brainly.com/latest/docs/interactive.html?direction=column-reverse#flexbox
* @see direction=row https://styleguide.brainly.com/latest/docs/interactive.html?direction=row#flexbox
* @see direction=row-reverse https://styleguide.brainly.com/latest/docs/interactive.html?direction=row-reverse#flexbox
*/
direction?: ResponsivePropType;
/**
* Specify flex justify content
* @example
* component content
*
* @see justifyContent=center https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=center#flexbox
* @see justifyContent=flex-start https://styleguide.brainly.com/latest/docs/interactive.html?ustifyContent=flex-start#flexbox
* @see justifyContent=flex-end https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=flex-end#flexbox
* @see justifyContent=space-between https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=space-between#flexbox
* @see justifyContent=space-around https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=space-around#flexbox
* @see justifyContent=space-evenly https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=space-evenly#flexbox
* @see justifyContent=stretch https://styleguide.brainly.com/latest/docs/interactive.html?justifyContent=stretch#flexbox
*/
justifyContent?: ResponsivePropType;
/**
* Specify flex align content
* @example
* component content
*
* @see alignContent=center https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=center#flexbox
* @see alignContent=flex-start https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=flex-start#flexbox
* @see alignContent=flex-end https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=flex-end#flexbox
* @see alignContent=baseline https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=baseline#flexbox
* @see alignContent=stretch https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=stretch#flexbox
*/
alignContent?: ResponsivePropType;
/**
* Specify flex align items
* @example
* component content
*
* @see alignItems=center https://styleguide.brainly.com/latest/docs/interactive.html?alignItems=center#flexbox
* @see alignItems=flex-start https://styleguide.brainly.com/latest/docs/interactive.html?alignItems=flex-start#flexbox
* @see alignItems=flex-end https://styleguide.brainly.com/latest/docs/interactive.html?alignItems=flex-end#flexbox
* @see alignItems=baseline https://styleguide.brainly.com/latest/docs/interactive.html?alignItems=baseline#flexbox
* @see alignItems=stretch https://styleguide.brainly.com/latest/docs/interactive.html?alignContent=stretch#flexbox
*/
alignItems?: ResponsivePropType;
/**
* Specify flex align self
* @example
* component content
*
* @see alignSelf=center https://styleguide.brainly.com/latest/docs/interactive.html?alignSelf=center#flexbox
* @see alignSelf=flex-start https://styleguide.brainly.com/latest/docs/interactive.html?alignSelf=flex-start#flexbox
* @see alignSelf=flex-end https://styleguide.brainly.com/latest/docs/interactive.html?alignSelf=flex-end#flexbox
* @see alignSelf=baseline https://styleguide.brainly.com/latest/docs/interactive.html?alignSelf=baseline#flexbox
* @see alignSelf=stretch https://styleguide.brainly.com/latest/docs/interactive.html?alignSelf=stretch#flexbox
*/
alignSelf?: ResponsivePropType;
/**
* It will set flex display to inline-flex
* @example
* component content
*
*/
inlineFlex?: ResponsivePropType;
/**
* It will wrap component
* @example
* component content
*
*/
wrap?: ResponsivePropType;
/**
* It will wrap reverse component
* @example
* component content
*
*/
wrapReverse?: ResponsivePropType;
/**
* Specify margin for flex based on spacings: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
margin?: ResponsivePropType;
/**
* Specify margin top for flex based on spacings: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
marginTop?: ResponsivePropType;
/**
* Specify margin right for flex based on spacings: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
marginRight?: ResponsivePropType;
/**
* Specify margin bottom for flex based on spacings: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
marginBottom?: ResponsivePropType;
/**
* Specify margin left for flex based on spacings: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
marginLeft?: ResponsivePropType;
/**
* Specify gap between flex children: none: 0px, xxs: 4px, xs: 8px, s: 16px, m: 24px, l: 40px, xl: 64px, xxl: 104px, xxxl: 168px, xxxxl: 272px
* @example
* component content
*
*/
gap?: ResponsivePropType;
/**
* Specify flex value:
* @example
* component content
*
*/
flex?: ResponsivePropType;
} & Omit<
React.AllHTMLAttributes,
| 'children'
| 'as'
| 'className'
| 'fullWidth'
| 'fullHeight'
| 'noShrink'
| 'direction'
| 'justifyContent'
| 'alignContent'
| 'alignItems'
| 'alignSelf'
| 'inlineFlex'
| 'wrap'
| 'wrapReverse'
| 'margin'
| 'marginTop'
| 'marginRight'
| 'marginBottom'
| 'marginLeft'
| 'gap'
| 'flex'
>;
const Flex = React.forwardRef(
(props: FlexPropsType, ref) => {
const {
as: Container = 'div',
fullWidth,
fullHeight,
noShrink,
inlineFlex,
alignItems,
alignContent,
justifyContent,
wrap,
wrapReverse,
alignSelf,
direction,
margin,
marginTop,
marginBottom,
marginLeft,
marginRight,
gap,
children,
className,
flex,
...otherProps
} = props;
const flexClass = classNames(
'sg-flex',
...generateResponsiveClassNames(
propValue =>
propValue === true ? `sg-flex--full-width` : `sg-flex--auto-width`,
fullWidth
),
...generateResponsiveClassNames(
propValue =>
propValue === true ? `sg-flex--full-height` : `sg-flex--auto-height`,
fullHeight
),
...generateResponsiveClassNames(
propValue =>
propValue === true ? `sg-flex--no-shrink` : `sg-flex--shrink-1`,
noShrink
),
...generateResponsiveClassNames(
propValue => (propValue === true ? `sg-flex--inline` : `sg-flex--flex`),
inlineFlex
),
...generateResponsiveClassNames(direction => {
if (direction === DIRECTION.COLUMN) {
return 'sg-flex--column';
} else if (direction === DIRECTION.COLUMN_REVERSE) {
return 'sg-flex--column-reverse';
} else if (direction === DIRECTION.ROW) {
return 'sg-flex--row';
} else if (direction === DIRECTION.ROW_REVERSE) {
return 'sg-flex--row-reverse';
} else {
return 'sg-flex--row';
}
}, direction),
...generateResponsiveClassNames(
propValue => (propValue === true ? `sg-flex--inline` : `sg-flex--flex`),
inlineFlex
),
...generateResponsiveClassNames(
(propValue: string) => `sg-flex--justify-content-${propValue}`,
justifyContent
),
...generateResponsiveClassNames(
propValue => `sg-flex--align-items-${propValue}`,
alignItems
),
...generateResponsiveClassNames(
propValue => `sg-flex--align-content-${propValue}`,
alignContent
),
...generateResponsiveClassNames(
propValue => `sg-flex--align-self-${propValue}`,
alignSelf
),
...generateResponsiveClassNames(
propValue => (propValue ? 'sg-flex--wrap' : 'sg-flex--nowrap'),
wrap
),
...generateResponsiveClassNames(
propValue => (propValue ? 'sg-flex--wrap-reverse' : 'sg-flex--nowrap'),
wrapReverse
),
...generateResponsiveClassNames(
propValue => `sg-flex--margin-${propValue}`,
margin
),
...generateResponsiveClassNames(
propValue => `sg-flex--margin-top-${propValue}`,
marginTop
),
...generateResponsiveClassNames(
propValue => `sg-flex--margin-right-${propValue}`,
marginRight
),
...generateResponsiveClassNames(
propValue => `sg-flex--margin-bottom-${propValue}`,
marginBottom
),
...generateResponsiveClassNames(
propValue => `sg-flex--margin-left-${propValue}`,
marginLeft
),
...generateResponsiveClassNames(
propValue => `sg-flex--gap-${propValue}`,
gap
),
...generateResponsiveClassNames(
propValue => `sg-flex--flex-${propValue}`,
flex
),
className
);
return (
// @ts-ignore ts migration
{children}
);
}
);
Flex.displayName = 'Flex';
export default Flex;