-
Notifications
You must be signed in to change notification settings - Fork 203
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
396 additions
and
201 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
packages/designer/src/components/components-popover.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import React, { useCallback, useMemo, useState } from 'react'; | ||
import { Box } from 'coral-system'; | ||
import { observer, useDesigner, useWorkspace } from '@music163/tango-context'; | ||
import { IconFont, DragPanel } from '@music163/tango-ui'; | ||
import { ComponentsPanel, ComponentsPanelProps } from '../sidebar'; | ||
import { IComponentPrototype } from '@music163/tango-helpers'; | ||
|
||
interface ComponentsPopoverProps { | ||
// 添加组件位置 | ||
type?: 'inner' | 'before' | 'after'; | ||
// 弹出方式 手动触发/DOM 触发 | ||
isControlled?: boolean; | ||
title?: string; | ||
prototype?: IComponentPrototype; | ||
children?: React.ReactNode; | ||
} | ||
|
||
export const ComponentsPopover = observer( | ||
({ | ||
type = 'inner', | ||
title = '添加组件', | ||
isControlled = false, | ||
prototype, | ||
children, | ||
...popoverProps | ||
}: ComponentsPopoverProps) => { | ||
const [layout, setLayout] = useState<ComponentsPanelProps['layout']>('grid'); | ||
const workspace = useWorkspace(); | ||
const designer = useDesigner(); | ||
|
||
const { addComponentPopoverPosition, showAddComponentPopover } = designer; | ||
const selectedNodeName = workspace.selectSource.selected?.[0]?.codeId ?? '未选中'; | ||
|
||
// 推荐使用的子组件 | ||
const insertedList = useMemo( | ||
() => | ||
Array.isArray(prototype?.childrenName) | ||
? prototype.childrenName | ||
: [prototype.childrenName].filter(Boolean), | ||
[prototype.childrenName], | ||
); | ||
|
||
// 推荐使用的代码片段 | ||
const siblingList = useMemo(() => prototype.siblingNames ?? [], [prototype.siblingNames]); | ||
|
||
const tipsTextMap = useMemo( | ||
() => ({ | ||
before: `点击,在 ${selectedNodeName} 的前方添加节点`, | ||
after: `点击,在 ${selectedNodeName} 的后方添加节点`, | ||
inner: `点击,在 ${selectedNodeName} 内部添加节点`, | ||
}), | ||
[selectedNodeName], | ||
); | ||
|
||
const handleSelect = useCallback( | ||
(name: string) => { | ||
switch (type) { | ||
case 'before': | ||
workspace.insertBeforeSelectedNode(name); | ||
break; | ||
case 'after': | ||
workspace.insertAfterSelectedNode(name); | ||
break; | ||
case 'inner': | ||
workspace.insertToSelectedNode(name); | ||
break; | ||
default: | ||
break; | ||
} | ||
}, | ||
[type, workspace], | ||
); | ||
|
||
const changeLayout = useCallback(() => { | ||
setLayout(layout === 'grid' ? 'line' : 'grid'); | ||
}, [layout]); | ||
|
||
const menuData = useMemo(() => { | ||
const menuList = JSON.parse(JSON.stringify(workspace.menuData)); | ||
const commonList = menuList['common']; | ||
if (siblingList?.length) { | ||
commonList.unshift({ | ||
title: '代码片段', | ||
items: siblingList, | ||
}); | ||
} | ||
|
||
if (insertedList?.length) { | ||
commonList.unshift({ | ||
title: '推荐使用', | ||
items: insertedList, | ||
}); | ||
} | ||
|
||
return menuList; | ||
}, [insertedList, siblingList, workspace.menuData]); | ||
|
||
const innerTypeProps = | ||
// 手动触发 适用于 点击添加组件 | ||
type === 'inner' && isControlled | ||
? { | ||
open: showAddComponentPopover, | ||
onOpenChange: (open: boolean) => designer.toggleAddComponentPopover(open), | ||
left: addComponentPopoverPosition.clientX, | ||
top: addComponentPopoverPosition.clientY, | ||
} | ||
: {}; | ||
|
||
return ( | ||
<DragPanel | ||
{...innerTypeProps} | ||
title={title} | ||
extra={ | ||
<Box fontSize="12px"> | ||
{layout === 'grid' ? ( | ||
<IconFont type="icon-liebiaoitem" onClick={changeLayout} /> | ||
) : ( | ||
<IconFont type="icon-grid1" onClick={changeLayout} /> | ||
)} | ||
</Box> | ||
} | ||
footer={tipsTextMap[type]} | ||
width="330px" | ||
body={ | ||
<ComponentsPanel | ||
isScope | ||
showBizComps={false} | ||
menuData={menuData} | ||
layout={layout} | ||
onItemSelect={handleSelect} | ||
style={{ | ||
maxHeight: '400px', | ||
overflow: 'auto', | ||
}} | ||
/> | ||
} | ||
{...popoverProps} | ||
> | ||
{children} | ||
</DragPanel> | ||
); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.