mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
add placeholder when drag component to grid
This commit is contained in:
parent
54fbe286ed
commit
454e8b8c43
@ -9,6 +9,7 @@ import {
|
||||
Flex,
|
||||
Box,
|
||||
} from '@chakra-ui/react';
|
||||
import { encodeDragDataTransfer, DROP_EXAMPLE_SIZE_PREFIX } from '@meta-ui/runtime';
|
||||
import { registry } from '../../metaUI';
|
||||
|
||||
export const ComponentList: React.FC = () => {
|
||||
@ -26,6 +27,15 @@ export const ComponentList: React.FC = () => {
|
||||
{Array.from(registry.components.get(version)!.values()).map(c => {
|
||||
const onDragStart = (e: any) => {
|
||||
e.dataTransfer.setData('component', `${c.version}/${c.metadata.name}`);
|
||||
// pass the exampleSize to gridlayout to render placeholder
|
||||
e.dataTransfer.setData(
|
||||
encodeDragDataTransfer(
|
||||
`${DROP_EXAMPLE_SIZE_PREFIX}${JSON.stringify(
|
||||
c.metadata.exampleSize
|
||||
)}`
|
||||
),
|
||||
''
|
||||
);
|
||||
};
|
||||
const cEle = (
|
||||
<Flex
|
||||
|
@ -1,11 +1,17 @@
|
||||
import RGL from 'react-grid-layout';
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
import 'react-grid-layout/css/styles.css';
|
||||
import 'react-resizable/css/styles.css';
|
||||
import { GRID_HEIGHT } from '../../constants';
|
||||
import { DROP_EXAMPLE_SIZE_PREFIX, GRID_HEIGHT } from '../../constants';
|
||||
import { decodeDragDataTransfer } from '../../utils/encodeDragDataTransfer';
|
||||
|
||||
const GridLayout: React.FC<ReactGridLayout.ReactGridLayoutProps> = props => {
|
||||
// hack: add onDropDragOver to ReactGridLayoutProps definition
|
||||
const ReactGridLayout: React.FC<RGL.ReactGridLayoutProps & { onDropDragOver: any }> =
|
||||
RGL as any;
|
||||
|
||||
const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
||||
const { children } = props;
|
||||
const spacing = 10;
|
||||
const { width, ref } = useResizeDetector();
|
||||
@ -19,22 +25,33 @@ const GridLayout: React.FC<ReactGridLayout.ReactGridLayoutProps> = props => {
|
||||
background-position: 0px ${spacing / 2}px;
|
||||
`;
|
||||
|
||||
const onDropDragOver = (e: React.DragEvent) => {
|
||||
// Here we need to get data in dataTransfer
|
||||
// but normally we cannot access dataTransfer in onDragOver, so I use a hack
|
||||
// I use the key of dataTransfer to store data, the key will look like 'exampleSize: [1,4]'
|
||||
// https://stackoverflow.com/questions/28487352/dragndrop-datatransfer-getdata-empty
|
||||
const key = e.dataTransfer.types
|
||||
.map(decodeDragDataTransfer)
|
||||
.find(t => t.startsWith(DROP_EXAMPLE_SIZE_PREFIX));
|
||||
const componentSize = JSON.parse(key?.replace(DROP_EXAMPLE_SIZE_PREFIX, '') || '');
|
||||
return { w: componentSize[0], h: componentSize[1] };
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={ref} css={bgCss}>
|
||||
<RGL
|
||||
<ReactGridLayout
|
||||
cols={12}
|
||||
// isDraggable={!!onDragStop}
|
||||
// isResizable={!!onDragStop}
|
||||
compactType={null}
|
||||
preventCollision={true}
|
||||
rowHeight={GRID_HEIGHT}
|
||||
width={width || 0}
|
||||
margin={[spacing, spacing]}
|
||||
isDroppable={true}
|
||||
onDropDragOver={onDropDragOver}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</RGL>
|
||||
</ReactGridLayout>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -20,7 +20,16 @@ const HStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||
slotsMap,
|
||||
}) => {
|
||||
return (
|
||||
<BaseHStack {...{ direction, wrap, align, justify, spacing }}>
|
||||
<BaseHStack
|
||||
height="full"
|
||||
width="full"
|
||||
padding="4"
|
||||
background="white"
|
||||
border="1px solid"
|
||||
borderColor="gray.200"
|
||||
borderRadius="4"
|
||||
{...{ direction, wrap, align, justify, spacing }}
|
||||
>
|
||||
<Slot slotsMap={slotsMap} slot="content" />
|
||||
</BaseHStack>
|
||||
);
|
||||
|
@ -20,7 +20,16 @@ const VStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||
slotsMap,
|
||||
}) => {
|
||||
return (
|
||||
<BaseVStack {...{ direction, wrap, align, justify, spacing }}>
|
||||
<BaseVStack
|
||||
width="full"
|
||||
height="full"
|
||||
padding="4"
|
||||
background="white"
|
||||
border="1px solid"
|
||||
borderColor="gray.200"
|
||||
borderRadius="4"
|
||||
{...{ direction, wrap, align, justify, spacing }}
|
||||
>
|
||||
<Slot slotsMap={slotsMap} slot="content" />
|
||||
</BaseVStack>
|
||||
);
|
||||
|
@ -2,3 +2,4 @@ export const LIST_ITEM_EXP = '$listItem';
|
||||
export const LIST_ITEM_INDEX_EXP = '$i';
|
||||
export const GRID_HEIGHT = 40;
|
||||
export const DIALOG_CONTAINER_ID = 'meta-ui-dialog-container';
|
||||
export const DROP_EXAMPLE_SIZE_PREFIX = 'exampleSize: ';
|
||||
|
@ -23,5 +23,6 @@ export function initMetaUI() {
|
||||
|
||||
export * from './utils/parseType';
|
||||
export * from './utils/parseTypeBox';
|
||||
export * from './utils/encodeDragDataTransfer';
|
||||
export * from './types/RuntimeSchema';
|
||||
export * from './constants';
|
||||
|
19
packages/runtime/src/utils/encodeDragDataTransfer.ts
Normal file
19
packages/runtime/src/utils/encodeDragDataTransfer.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// https://stackoverflow.com/questions/28487352/dragndrop-datatransfer-getdata-empty
|
||||
const UPPERCASE_PREFIX = '^{';
|
||||
const UPPERCASE_SUFFIX = '}^';
|
||||
|
||||
export function encodeDragDataTransfer(str: string): string {
|
||||
return str.replace(/([A-Z]+)/g, `${UPPERCASE_PREFIX}$1${UPPERCASE_SUFFIX}`);
|
||||
}
|
||||
|
||||
export function decodeDragDataTransfer(str: string): string {
|
||||
const escapeRegExp = (escape: string) => ['', ...escape.split('')].join('\\');
|
||||
|
||||
return str.replace(
|
||||
new RegExp(
|
||||
`${escapeRegExp(UPPERCASE_PREFIX)}(.*?)${escapeRegExp(UPPERCASE_SUFFIX)}`,
|
||||
'g'
|
||||
),
|
||||
(_, p1: string) => p1.toUpperCase()
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user