import { useDndMonitor, useDroppable } from '@dnd-kit/core'; import { css } from '@emotion/css'; import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react'; import { uid } from '@formily/shared'; import cls from 'classnames'; import React, { createContext, useContext, useState } from 'react'; import { useSchemaInitializer } from '../../../'; import { DndContext } from '../../common/dnd-context'; const GridRowContext = createContext(null); const GridColContext = createContext(null); const GridContext = createContext({}); const ColDivider = (props) => { const { isOver, setNodeRef } = useDroppable({ id: props.id, data: props.data, }); const droppableStyle = { backgroundColor: isOver ? 'rgba(241, 139, 98, .1)' : undefined, }; return (
); }; const RowDivider = (props) => { const { isOver, setNodeRef } = useDroppable({ id: props.id, data: props.data, }); const droppableStyle = {}; if (isOver) { droppableStyle['backgroundColor'] = 'rgba(241, 139, 98, .1)'; } const [active, setActive] = useState(false); useDndMonitor({ onDragStart(event) { setActive(true); }, onDragMove(event) {}, onDragOver(event) {}, onDragEnd(event) { setActive(false); }, onDragCancel(event) { setActive(false); }, }); return ( ); }; const wrapRowSchema = (schema: Schema) => { const row = new Schema({ type: 'void', name: `row_${uid()}`, 'x-uid': uid(), 'x-component': 'Grid.Row', }); const col = row.addProperty(uid(), { type: 'void', 'x-uid': uid(), 'x-component': 'Grid.Col', }); if (Schema.isSchemaInstance(schema)) { schema.parent = col; } col.addProperty(schema.name, schema); return row; }; const wrapColSchema = (schema: Schema) => { const s = new Schema({ type: 'void', name: `col_${uid()}`, 'x-uid': uid(), 'x-component': 'Grid.Col', }); // parent 更新了,需要重新指定 if (Schema.isSchemaInstance(schema)) { schema.parent = s; } s.addProperty(schema.name, schema); return s; }; const useRowProperties = () => { const fieldSchema = useFieldSchema(); return fieldSchema.reduceProperties((buf, s) => { if (s['x-component'] === 'Grid.Row' && !s['x-hidden']) { buf.push(s); } return buf; }, []); }; const useColProperties = () => { const fieldSchema = useFieldSchema(); return fieldSchema.reduceProperties((buf, s) => { if (s['x-component'] === 'Grid.Col' && !s['x-hidden']) { buf.push(s); } return buf; }, []); }; const DndWrapper = (props) => { if (props.dndContext === false) { return <>{props.children}; } return {props.children}; }; export const useGridContext = () => { return useContext(GridContext); }; export const useGridRowContext = () => { return useContext(GridRowContext); } export const Grid: any = observer((props: any) => { const field = useField(); const fieldSchema = useFieldSchema(); const { render } = useSchemaInitializer(fieldSchema['x-initializer']); const addr = field.address.toString(); const rows = useRowProperties(); return (
{rows.map((schema, index) => { return ( ); })} {render()}
); }); Grid.Row = observer((props) => { const field = useField(); const fieldSchema = useFieldSchema(); const addr = field.address.toString(); const cols = useColProperties(); return (
{cols.map((schema, index) => { return ( ); })}
); }); Grid.Col = observer((props: any) => { const { cols } = useContext(GridRowContext); const w = props.width || 100 / cols.length; const width = `calc(${w}% - 24px - 24px / ${cols.length})`; return (
{props.children}
); });