mirror of
https://github.com/NetEase/tango.git
synced 2026-08-28 17:41:30 +08:00
fix: support quick set tid in SettingForm (#151)
* fix: support quick set tid * fix: shape return type of parseDndId
This commit is contained in:
@@ -44,6 +44,7 @@ function SettingFormDemo({ initValues, prototype }: SettingFormDemoProps) {
|
||||
prototype={prototype}
|
||||
showIdentifier={{
|
||||
identifierKey: 'tid',
|
||||
getIdentifier: () => `time${Date.now()}`,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -75,7 +75,7 @@ export function getElementData(
|
||||
const display = getElementCSSDisplay(element);
|
||||
return {
|
||||
id: dnd.id,
|
||||
codeId: dnd.index,
|
||||
codeId: dnd.codeId,
|
||||
name: dnd.component || element.tagName.toLowerCase(),
|
||||
filename: dnd.filename,
|
||||
bounding,
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Box } from 'coral-system';
|
||||
import { SettingForm, FormModel, SettingFormProps } from '@music163/tango-setting-form';
|
||||
import { Panel } from '@music163/tango-ui';
|
||||
import { clone } from '@music163/tango-helpers';
|
||||
import { clone, parseDndId } from '@music163/tango-helpers';
|
||||
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
|
||||
import { registerBuiltinSetters } from './setters';
|
||||
|
||||
@@ -103,6 +103,11 @@ export const SettingPanel = observer((props: SettingPanelProps) => {
|
||||
prototype={prototype}
|
||||
showIdentifier={{
|
||||
identifierKey: 'tid',
|
||||
getIdentifier: () => {
|
||||
// 直接拿当前的虚拟 id 作为 tid
|
||||
const { codeId } = parseDndId(workspace.selectSource.first.id);
|
||||
return codeId;
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -81,8 +81,8 @@ const OutlineTreeNode: React.FC<{ node: ITangoViewNodeData } & ComponentsTreePro
|
||||
const sandboxQuery = useSandboxQuery();
|
||||
const [visible, setVisible] = useState(true);
|
||||
const nodeLabel = (() => {
|
||||
const { index } = parseDndId(node.id);
|
||||
return index;
|
||||
const { codeId } = parseDndId(node.id);
|
||||
return codeId;
|
||||
})();
|
||||
const componentPrototype = workspace.componentPrototypes.get(node.component);
|
||||
const icon = componentPrototype?.icon || 'icon-placeholder';
|
||||
|
||||
@@ -75,9 +75,13 @@ export function parseDndTrackId(str: string) {
|
||||
|
||||
interface DndIdParsedType {
|
||||
/**
|
||||
* 完整的 ID
|
||||
* full id
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* 组件代码中的 id,一般对应组件的 tid 属性
|
||||
*/
|
||||
codeId?: string;
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
@@ -86,19 +90,11 @@ interface DndIdParsedType {
|
||||
* 文件名
|
||||
*/
|
||||
filename?: string;
|
||||
/**
|
||||
* @deprecated 使用 filename 代替
|
||||
*/
|
||||
module?: string;
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
index?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 dnd id
|
||||
* @example Button:123 -> { component: "Button", id: "Button:123" }
|
||||
* @example Button:button123 -> { component: "Button", id: "Button:123" }
|
||||
* @example LocalBlock:Button:123 -> { filename: LocalBlock, component: "Button", id: "Button:123" }
|
||||
* @param str
|
||||
*/
|
||||
@@ -109,19 +105,20 @@ export function parseDndId(str: string): DndIdParsedType {
|
||||
|
||||
const parts = str.split(':');
|
||||
if (parts.length === 2) {
|
||||
// e.g. Button:button123
|
||||
return {
|
||||
component: parts[0],
|
||||
index: parts[1],
|
||||
id: str,
|
||||
component: parts[0],
|
||||
codeId: parts[1],
|
||||
};
|
||||
} else if (parts.length >= 3) {
|
||||
// e.g. LocalBlock:Button:button123
|
||||
const filename = decodeURIComponent(parts[0]);
|
||||
return {
|
||||
module: filename,
|
||||
id: str,
|
||||
filename,
|
||||
component: parts[1],
|
||||
index: parts[2],
|
||||
id: str,
|
||||
codeId: parts[2],
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -58,22 +58,21 @@ describe('string', () => {
|
||||
|
||||
it('parseDndId', () => {
|
||||
expect(parseDndId('123')).toEqual({ id: '123' });
|
||||
expect(parseDndId('Button:123')).toEqual({
|
||||
expect(parseDndId('Button:button123')).toEqual({
|
||||
component: 'Button',
|
||||
id: 'Button:123',
|
||||
index: '123',
|
||||
id: 'Button:button123',
|
||||
codeId: 'button123',
|
||||
});
|
||||
expect(parseDndId('Button.Group:123')).toEqual({
|
||||
expect(parseDndId('Button.Group:buttonGroup123')).toEqual({
|
||||
component: 'Button.Group',
|
||||
id: 'Button.Group:123',
|
||||
index: '123',
|
||||
id: 'Button.Group:buttonGroup123',
|
||||
codeId: 'buttonGroup123',
|
||||
});
|
||||
expect(parseDndId('LocalBlock:Button.Group:123')).toEqual({
|
||||
expect(parseDndId('LocalBlock:Button.Group:buttonGroup123')).toEqual({
|
||||
id: 'LocalBlock:Button.Group:buttonGroup123',
|
||||
filename: 'LocalBlock',
|
||||
module: 'LocalBlock',
|
||||
component: 'Button.Group',
|
||||
id: 'LocalBlock:Button.Group:123',
|
||||
index: '123',
|
||||
codeId: 'buttonGroup123',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -104,7 +104,8 @@ export interface SettingFormProps {
|
||||
showIdentifier?:
|
||||
| false
|
||||
| {
|
||||
identifierKey: string;
|
||||
identifierKey: string; // 唯一标识符属性key
|
||||
getIdentifier?: () => string; // 获取唯一标识符的方法
|
||||
};
|
||||
/**
|
||||
* 是否显示搜索框
|
||||
@@ -222,6 +223,9 @@ export function SettingForm({
|
||||
<SettingFormItem
|
||||
noStyle
|
||||
setter="idSetter"
|
||||
setterProps={{
|
||||
getId: showIdentifier.getIdentifier,
|
||||
}}
|
||||
name={showIdentifier.identifierKey}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Input, InputProps, Tooltip } from 'antd';
|
||||
import { css, Box } from 'coral-system';
|
||||
import { FormItemComponentProps } from '../form-item';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
import { ExclamationCircleOutlined, ThunderboltOutlined } from '@ant-design/icons';
|
||||
import { Action } from '@music163/tango-ui';
|
||||
|
||||
const idInputStyle = css`
|
||||
> .ant-input-borderless {
|
||||
@@ -22,6 +23,7 @@ export function IdSetter({
|
||||
defaultValue,
|
||||
onChange,
|
||||
placeholder = '输入唯一组件ID',
|
||||
getId,
|
||||
...rest
|
||||
}: FormItemComponentProps<string>) {
|
||||
const [value, setValue] = useState(valueProp || defaultValue);
|
||||
@@ -60,6 +62,8 @@ export function IdSetter({
|
||||
},
|
||||
};
|
||||
|
||||
const showQuickIdButton = !value || error; // 没有设置 id 或 id 不合法的时候显示快捷生成按钮
|
||||
|
||||
return (
|
||||
<Box css={idInputStyle}>
|
||||
<Input
|
||||
@@ -67,13 +71,29 @@ export function IdSetter({
|
||||
value={value}
|
||||
{...__props}
|
||||
{...rest}
|
||||
suffix={
|
||||
prefix={
|
||||
error ? (
|
||||
<Tooltip title={error} color="#ff4d4f">
|
||||
<ExclamationCircleOutlined style={{ color: 'red' }} />
|
||||
</Tooltip>
|
||||
) : null
|
||||
}
|
||||
suffix={
|
||||
showQuickIdButton ? (
|
||||
<Action
|
||||
size="small"
|
||||
icon={<ThunderboltOutlined />}
|
||||
tooltip="快捷设置组件ID"
|
||||
onClick={() => {
|
||||
const id = getId?.();
|
||||
if (id) {
|
||||
setValue(id);
|
||||
onChange?.(id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user