import { classNames } from '@vkontakte/vkjs'; import { calculateGap, columnGapClassNames, type GapProp, type GapsProp, resolveLayoutProps, rowGapClassNames, } from '../../lib/layouts'; import type { LayoutProps } from '../../lib/layouts/types'; import type { CSSCustomProperties } from '../../types'; import { RootComponent } from '../RootComponent/RootComponent'; import type { RootComponentProps } from '../RootComponent/RootComponent'; import { FlexItem, type FlexItemProps } from './FlexItem/FlexItem'; import styles from './Flex.module.css'; import flexItemStyles from './FlexItem/FlexItem.module.css'; export type { FlexItemProps }; const justifyClassNames = { 'start': styles.justifyStart, 'end': styles.justifyEnd, 'center': styles.justifyCenter, 'space-around': styles.justifySpaceAround, 'space-between': styles.justifySpaceBetween, 'space-evenly': styles.justifySpaceEvenly, }; const alignClassNames = { start: styles.alignStart, end: styles.alignEnd, center: styles.alignCenter, stretch: styles.alignStretch, baseline: styles.alignBaseline, }; const alignSelfClassNames = { start: flexItemStyles.alignSelfStart, end: flexItemStyles.alignSelfEnd, center: flexItemStyles.alignSelfCenter, baseline: flexItemStyles.alignSelfBaseline, stretch: flexItemStyles.alignSelfStretch, }; const displayClassNames = { 'none': styles.displayNone, 'inline-flex': styles.displayInlineFlex, }; type FlexContentProps = | 'start' | 'end' | 'center' | 'space-around' | 'space-between' | 'space-evenly'; export interface FlexProps extends Omit, 'baseClassName'>, LayoutProps { /** * Направление осей, эквивалентно `flex-direction`. */ direction?: 'row' | 'column'; /** * Отступы между элементами. * Значение из списка предопределённых пресетов или число, которое будет приведено к пикселям. * Через массив можно задать отступ между столбцами и строками [row, column], если они отличаются. */ gap?: GapsProp; /** * Отключает перенос контента, эквивалентно `flex-wrap=nowrap`. */ noWrap?: boolean; /** * Выравнивание элементов по вспомогательной оси, эквивалентно `align-items`. */ align?: 'start' | 'end' | 'center' | 'stretch' | 'baseline'; /** * Выравнивание элементов по главной оси, эквивалентно `justify-content`. */ justify?: FlexContentProps; /** * Значение `auto` позволяет задать платформенные отступы вокруг контейнера. */ margin?: 'none' | 'auto'; /** * Для инвертирования направления, эквивалентно `row-reverse` `column-reverse`. */ reverse?: boolean; /** * Для задания выравнивания, отличного от установленного на родителе, эквивалентно `align-self`. */ alignSelf?: 'start' | 'end' | 'center' | 'baseline' | 'stretch'; /** * Возможность задать css-свойство `display`. */ display?: 'none' | 'flex' | 'inline-flex'; } /** * @see https://vkui.io/components/flex */ export const Flex: React.FC & { /** * @deprecated Since 7.11.0. Будет удалено в **VKUI v9**. * Используйте компонент `Flex`. */ Item: typeof FlexItem; } = ({ gap = 0, align, justify, margin = 'none', noWrap = false, direction = 'row', reverse = false, children, alignSelf, display = 'flex', ...restProps }: FlexProps) => { const [rowGap, columnGap] = calculateGap(gap); const resolvedProps = resolveLayoutProps(restProps); return ( {children} ); }; function getGapsPresets(rowGap: GapProp, columnGap: GapProp) { return classNames( typeof rowGap === 'string' && rowGapClassNames[rowGap], typeof columnGap === 'string' && columnGapClassNames[columnGap], ); } function getGapsByUser(rowGap: GapProp, columnGap: GapProp) { const style: CSSCustomProperties = {}; if (typeof rowGap === 'number') { style['--vkui_internal--row_gap'] = `${rowGap}px`; } if (typeof columnGap === 'number') { style['--vkui_internal--column_gap'] = `${columnGap}px`; } return style; } Flex.Item = FlexItem;