diff --git a/apps/storybook/src/setting-form.stories.tsx b/apps/storybook/src/setting-form.stories.tsx
index 8bf783a..48a7b90 100644
--- a/apps/storybook/src/setting-form.stories.tsx
+++ b/apps/storybook/src/setting-form.stories.tsx
@@ -44,6 +44,7 @@ function SettingFormDemo({ initValues, prototype }: SettingFormDemoProps) {
prototype={prototype}
showIdentifier={{
identifierKey: 'tid',
+ getIdentifier: () => `time${Date.now()}`,
}}
/>
diff --git a/packages/designer/src/helpers/dom.ts b/packages/designer/src/helpers/dom.ts
index 029a30c..12f4a04 100644
--- a/packages/designer/src/helpers/dom.ts
+++ b/packages/designer/src/helpers/dom.ts
@@ -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,
diff --git a/packages/designer/src/setting-panel.tsx b/packages/designer/src/setting-panel.tsx
index 95df475..88f9e70 100644
--- a/packages/designer/src/setting-panel.tsx
+++ b/packages/designer/src/setting-panel.tsx
@@ -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}
/>
diff --git a/packages/designer/src/sidebar/outline-panel/components-tree.tsx b/packages/designer/src/sidebar/outline-panel/components-tree.tsx
index d282758..5454c34 100644
--- a/packages/designer/src/sidebar/outline-panel/components-tree.tsx
+++ b/packages/designer/src/sidebar/outline-panel/components-tree.tsx
@@ -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';
diff --git a/packages/helpers/src/helpers/string.ts b/packages/helpers/src/helpers/string.ts
index 91a1cfb..ece586d 100644
--- a/packages/helpers/src/helpers/string.ts
+++ b/packages/helpers/src/helpers/string.ts
@@ -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 {
diff --git a/packages/helpers/tests/helpers.test.ts b/packages/helpers/tests/helpers.test.ts
index 7d44a98..15017b1 100644
--- a/packages/helpers/tests/helpers.test.ts
+++ b/packages/helpers/tests/helpers.test.ts
@@ -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',
});
});
diff --git a/packages/setting-form/src/form.tsx b/packages/setting-form/src/form.tsx
index a4813a4..806d72f 100644
--- a/packages/setting-form/src/form.tsx
+++ b/packages/setting-form/src/form.tsx
@@ -104,7 +104,8 @@ export interface SettingFormProps {
showIdentifier?:
| false
| {
- identifierKey: string;
+ identifierKey: string; // 唯一标识符属性key
+ getIdentifier?: () => string; // 获取唯一标识符的方法
};
/**
* 是否显示搜索框
@@ -222,6 +223,9 @@ export function SettingForm({
}
diff --git a/packages/setting-form/src/setters/id-setter.tsx b/packages/setting-form/src/setters/id-setter.tsx
index 8b86709..4cb9b76 100644
--- a/packages/setting-form/src/setters/id-setter.tsx
+++ b/packages/setting-form/src/setters/id-setter.tsx
@@ -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) {
const [value, setValue] = useState(valueProp || defaultValue);
@@ -60,6 +62,8 @@ export function IdSetter({
},
};
+ const showQuickIdButton = !value || error; // 没有设置 id 或 id 不合法的时候显示快捷生成按钮
+
return (
) : null
}
+ suffix={
+ showQuickIdButton ? (
+ }
+ tooltip="快捷设置组件ID"
+ onClick={() => {
+ const id = getId?.();
+ if (id) {
+ setValue(id);
+ onChange?.(id);
+ }
+ }}
+ />
+ ) : null
+ }
/>
);