/** * @file 简化版 Flex 布局,主要用于不熟悉 CSS 的开发者 */ import React from 'react'; import {Renderer, RendererProps} from '../factory'; import {Schema} from '../types'; import {BaseSchema, SchemaCollection} from '../Schema'; /** * Flex 布局 * 文档:https://baidu.gitee.io/amis/docs/components/flex */ export interface FlexSchema extends BaseSchema { /** * 指定为 flex 展示类型 */ type: 'flex'; /** * 水平分布 */ justify?: | 'start' | 'flex-start' | 'center' | 'end' | 'flex-end' | 'space-around' | 'space-between' | 'space-evenly'; /** * 垂直布局 */ alignItems?: | 'stretch' | 'start' | 'flex-start' | 'flex-end' | 'end' | 'center' | 'baseline'; /** * 多行情况下的垂直分布 */ alignContent?: | 'normal' | 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' | 'stretch'; /** * 方向 */ direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse'; /** * 每个 flex 的设置 */ items: SchemaCollection; /** * 自定义样式 */ style?: { [propName: string]: any; }; } export interface FlexProps extends RendererProps, Omit {} export default class Flex extends React.Component { static defaultProps: Partial = { direction: 'row', justify: 'center', alignItems: 'center', alignContent: 'center' }; constructor(props: FlexProps) { super(props); } render() { const { items, direction, justify, alignItems, alignContent, style, render, className } = this.props; const flexStyle = { display: 'flex', flexDirection: direction, justifyContent: justify, alignItems, alignContent, ...style }; return (
{(Array.isArray(items) ? items : items ? [items] : [] ).map((item, key) => render(`flexItem/${key}`, item))}
); } } export interface FlexItemSchema extends BaseSchema { /** * 功能和 wrapper 类似,主要是给 flex 子节点用的 */ type: 'flex-item'; /** * 内容 */ body: SchemaCollection; /** * 自定义样式 */ style?: { [propName: string]: any; }; } export interface FlexItemProps extends RendererProps, Omit { children?: JSX.Element | ((props?: any) => JSX.Element); } export class FlexItem extends React.Component { static propsList: Array = ['body', 'className', 'children']; renderBody(): JSX.Element | null { const {children, body, render} = this.props; return children ? typeof children === 'function' ? (children(this.props) as JSX.Element) : (children as JSX.Element) : body ? (render('body', body) as JSX.Element) : null; } render() { const {className, size, classnames: cx, style} = this.props; return (
{this.renderBody()}
); } } @Renderer({ type: 'flex', name: 'flex' }) export class FlexRenderer extends Flex {} @Renderer({ type: 'flex-item', name: 'flex-item' }) export class FlexItemRenderer extends FlexItem {}