Skip to content

Commit

Permalink
fix: refactor action, formHeader, selectionDropdown (#114)
Browse files Browse the repository at this point in the history
* fix: add new action component

* fix: refactor form header component and add documentation link

* fix: refactor dropdown menu for selected item

* fix: update

* fix: add store variable in modelSetter

* fix: code styles
  • Loading branch information
wwsun authored Mar 18, 2024
1 parent 23c2e2e commit 489118b
Show file tree
Hide file tree
Showing 21 changed files with 388 additions and 131 deletions.
2 changes: 2 additions & 0 deletions apps/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
"mobx-react-lite": "4.0.5"
},
"devDependencies": {
"@ant-design/icons": "^4.8.0",
"@storybook/addon-actions": "^6.5.14",
"@storybook/addon-essentials": "^6.5.14",
"@storybook/addon-links": "^6.5.14",
"@storybook/react": "^6.5.14",
"antd": "^4.24.2",
"babel-plugin-styled-components": "^2.0.7",
"tsconfig-paths-webpack-plugin": "^3.5.2"
}
Expand Down
68 changes: 68 additions & 0 deletions apps/storybook/src/ui/action.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import { Action } from '@music163/tango-ui';
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Space } from 'antd';

export default {
title: 'UI/Action',
component: Action,
};

export const Basic = {
args: {
icon: <PlusOutlined />,
tooltip: '添加服务函数',
},
};

export const Link = {
args: {
icon: <QuestionCircleOutlined />,
tooltip: '查看帮助文档',
href: 'https://music.163.com',
},
};

export const Outline = {
args: {
icon: <PlusOutlined />,
tooltip: '添加服务函数',
shape: 'outline',
},
};

export const Small = {
args: {
size: 'small',
icon: <PlusOutlined />,
tooltip: '添加服务函数',
},
};

export const Disabled = () => {
return (
<Space>
<Action icon={<PlusOutlined />} tooltip="添加服务函数" disabled />
<Action icon={<PlusOutlined />} tooltip="添加服务函数" disabled shape="outline" />
<Action
icon={<QuestionCircleOutlined />}
tooltip="查看帮助文档"
href="https://music.163.com"
disabled
/>
</Space>
);
};

export const List = () => {
return (
<Space>
<Action icon={<PlusOutlined />} tooltip="添加服务函数" />
<Action
icon={<QuestionCircleOutlined />}
tooltip="查看帮助文档"
href="https://music.163.com"
/>
</Space>
);
};
4 changes: 2 additions & 2 deletions apps/storybook/src/ui/input-code.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { IconButton, InputCode } from '@music163/tango-ui';
import { Action, InputCode } from '@music163/tango-ui';
import { BlockOutlined } from '@ant-design/icons';

export default {
Expand All @@ -22,7 +22,7 @@ const context = {
export function Basic() {
return (
<InputCode
suffix={<IconButton icon={<BlockOutlined />} />}
suffix={<Action icon={<BlockOutlined />} size="small" />}
autoCompleteContext={{ tango: context }}
/>
);
Expand Down
8 changes: 4 additions & 4 deletions packages/designer/src/sandbox/navigator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Box, css, Group } from 'coral-system';
import { IconButton, ToggleButton } from '@music163/tango-ui';
import { Action, ToggleButton } from '@music163/tango-ui';
import { observer, useDesigner } from '@music163/tango-context';
import { Input } from 'antd';
import {
Expand Down Expand Up @@ -84,9 +84,9 @@ export class Navigator extends React.Component<NavigatorProps, NavigatorState> {
css={navigatorStyle}
>
<Box>
<IconButton icon={<ArrowLeftOutlined />} onClick={onBack} title="返回" />
<IconButton icon={<ArrowRightOutlined />} onClick={onForward} title="前进" />
<IconButton icon={<ReloadOutlined />} onClick={onRefresh} title="刷新" />
<Action size="small" icon={<ArrowLeftOutlined />} onClick={onBack} title="返回" />
<Action size="small" icon={<ArrowRightOutlined />} onClick={onForward} title="前进" />
<Action size="small" icon={<ReloadOutlined />} onClick={onRefresh} title="刷新" />
</Box>
<Input
className="navigatorInput"
Expand Down
5 changes: 3 additions & 2 deletions packages/designer/src/setters/expression-setter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
IVariableTreeNode,
} from '@music163/tango-helpers';
import { CloseCircleFilled, ExpandAltOutlined } from '@ant-design/icons';
import { IconButton, Panel, InputCode } from '@music163/tango-ui';
import { Panel, InputCode, Action } from '@music163/tango-ui';
import { FormItemComponentProps } from '@music163/tango-setting-form';
import { useWorkspace, useWorkspaceData } from '@music163/tango-context';
import { VariableTree } from '../components';
Expand Down Expand Up @@ -130,10 +130,11 @@ export function ExpressionSetter(props: ExpressionSetterProps) {
}}
/>
)}
<IconButton
<Action
tooltip="打开表达式变量选择面板"
icon={<ExpandAltOutlined />}
onClick={on}
size="small"
/>
</Box>
}
Expand Down
2 changes: 2 additions & 0 deletions packages/designer/src/setters/model-setter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export function ModelSetter({
if (!definedVariables.includes(keyPath)) {
ret.showAddButton = false;
ret.showRemoveButton = false;
} else if (/^stores\.[a-zA-Z0-9]+$/.test(keyPath)) {
ret.showAddButton = true;
}

return ret;
Expand Down
30 changes: 14 additions & 16 deletions packages/designer/src/setting-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const SettingPanel = observer((props: SettingPanelProps) => {
const workspace = useWorkspace();
const designer = useDesigner();

if (!designer.showRightPanel) {
if (!designer.showRightPanel || !workspace.selectSource.isSelected) {
return <Box className="SettingPanel" />;
}

Expand Down Expand Up @@ -93,21 +93,19 @@ export const SettingPanel = observer((props: SettingPanelProps) => {
headerProps={headerProps}
className="SettingPanel"
>
{workspace.selectSource.isSelected ? (
prototype ? (
<SettingForm
key={workspace.selectSource.first.id}
model={formModel}
prototype={prototype}
showIdentifier={{
identifierKey: 'tid',
}}
{...props}
/>
) : (
<Box p="m">没有找到与该组件相关的配置信息</Box>
)
) : null}
{prototype ? (
<SettingForm
key={workspace.selectSource.first.id}
model={formModel}
prototype={prototype}
showIdentifier={{
identifierKey: 'tid',
}}
{...props}
/>
) : (
<Box p="m">没有找到与该组件相关的配置信息</Box>
)}
</Panel>
);
});
140 changes: 110 additions & 30 deletions packages/designer/src/simulator/selection.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';
import styled, { css, keyframes } from 'styled-components';
import { Box, Button, Group, HTMLCoralProps } from 'coral-system';
import { Dropdown, DropdownProps } from 'antd';
import { PlusSquareOutlined, HolderOutlined, InfoCircleOutlined } from '@ant-design/icons';
import { ISelectedItemData, isString, noop } from '@music163/tango-helpers';
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
import { IconButton } from '@music163/tango-ui';
import { Action, IconFont } from '@music163/tango-ui';
import { getDragGhostElement } from '../helpers';
import { getWidget } from '../widgets';

Expand Down Expand Up @@ -58,6 +59,13 @@ const selectionBoxStyle = css`
top: 0;
`;

interface IInsertedData {
name: string;
label: string;
icon: string;
description: string;
}

export interface SelectionBoxProps {
/**
* 是否显示操作按钮
Expand Down Expand Up @@ -90,15 +98,20 @@ function SelectionBox({ showActions, actions, data }: SelectionBoxProps) {
const isPage = prototype?.type === 'page';

// 如果声明了 childrenName,提供快捷子元素创建入口
let insertedList: ISelectedItemData[] = [];
let insertedList: IInsertedData[] = [];
if (prototype?.childrenName) {
const names = Array.isArray(prototype?.childrenName)
? prototype.childrenName
: [prototype.childrenName];
insertedList = names.map((child) => ({
id: child,
name: child,
}));
insertedList = names.map((child) => {
const proto = workspace.componentPrototypes.get(child);
return {
name: child,
label: proto?.title || child,
icon: proto?.icon,
description: proto?.help,
};
});
}

let selectionHelpersAlign: SelectionHelperAlignType = 'top-right';
Expand Down Expand Up @@ -166,41 +179,28 @@ function SelectionBox({ showActions, actions, data }: SelectionBoxProps) {
}}
/>
{!isFromCurrentFile && (
<IconButton
<Action
as="span"
color="white"
tooltip={`该节点来自其他文件(${data.filename})`}
icon={<InfoCircleOutlined />}
size="small"
/>
)}
</>
}
/>
<SelectionToolSet>{!isPage && actions}</SelectionToolSet>
{insertedList.length > 0 && (
<SelectionHelper
icon={<PlusSquareOutlined />}
label={
insertedList.length === 1 ? (
<span
onClick={() => {
workspace.insertToSelectedNode(insertedList[0].name);
}}
>
添加 {insertedList[0].name}
</span>
) : (
<NameSelector
label="添加"
parents={insertedList}
onSelect={(item) => {
workspace.insertToSelectedNode(item.name);
}}
/>
)
}
/>
<InsertedDropdown
options={insertedList}
onSelect={(name) => {
workspace.insertToSelectedNode(name);
}}
>
<SelectionHelper icon={<PlusSquareOutlined />} />
</InsertedDropdown>
)}
<SelectionToolSet>{!isPage && actions}</SelectionToolSet>
</SelectionHelpers>
)}
</Box>
Expand Down Expand Up @@ -370,3 +370,83 @@ const NameSelector = ({ label, parents = [], onSelect = noop }: NameSelectorProp
</NameSelectorWrapper>
);
};

interface InsertedDropdownProps extends DropdownProps {
options?: IInsertedData[];
onSelect?: (name: string) => void;
}

function InsertedDropdown({ options = [], onSelect, ...props }: InsertedDropdownProps) {
return (
<Dropdown
trigger={['click']}
dropdownRender={() => {
return (
<Box
bg="#FFF"
borderRadius="m"
boxShadow="lowDown"
border="solid"
borderColor="line2"
overflow="hidden"
>
<Box px="l" py="m" color="text2">
为当前节点添加子元素
</Box>
<Box>
{options.map((item) => (
<InsertedItem
key={item.name}
label={item.label}
icon={item.icon}
description={item.description}
onClick={() => onSelect?.(item.name)}
/>
))}
</Box>
</Box>
);
}}
{...props}
/>
);
}

const insertedItemStyle = css`
cursor: pointer;
&:hover {
background-color: var(--tango-colors-fill2);
}
`;

function InsertedItem({
label,
icon = 'icon-placeholder',
description,
}: HTMLCoralProps<'div'> & Omit<IInsertedData, 'name'>) {
return (
<Box display="flex" columnGap="m" px="l" py="m" fontSize="12px" css={insertedItemStyle}>
<Box
size="35px"
fontSize="32px"
background="fill1"
border="1px solid"
borderColor="line2"
display="flex"
alignItems="center"
justifyContent="center"
>
{icon.startsWith('icon-') ? (
<IconFont className="material-icon" type={icon} />
) : (
<img src={icon} alt={label} />
)}
</Box>
<Box>
<Box fontWeight="500">{label}</Box>
<Box color="text2">{description}</Box>
</Box>
</Box>
);
}
2 changes: 2 additions & 0 deletions packages/helpers/src/helpers/logger.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable no-console */

export const logger = {
group(title: string, body: string) {
console.groupCollapsed(title);
Expand Down
Loading

0 comments on commit 489118b

Please sign in to comment.