fix: support quick set tid in SettingForm (#151)

* fix: support quick set tid

* fix: shape return type of parseDndId
This commit is contained in:
Wells
2024-05-17 10:53:18 +08:00
committed by GitHub
parent ffaa276b5c
commit 1fc22a4535
8 changed files with 58 additions and 32 deletions
@@ -44,6 +44,7 @@ function SettingFormDemo({ initValues, prototype }: SettingFormDemoProps) {
prototype={prototype}
showIdentifier={{
identifierKey: 'tid',
getIdentifier: () => `time${Date.now()}`,
}}
/>
</Box>
+1 -1
View File
@@ -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,
+6 -1
View File
@@ -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';
+12 -15
View File
@@ -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 {
+9 -10
View File
@@ -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',
});
});
+5 -1
View File
@@ -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>
);