mirror of
https://github.com/NetEase/tango.git
synced 2026-09-01 15:03:03 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 253ceca969 | |||
| a0ed57ff4f | |||
| f83c6bc0f6 | |||
| bb92210594 | |||
| 163ecedff3 | |||
| 22a2e9bdd1 | |||
| 696f82bd26 | |||
| a0484e8f64 |
@@ -56,7 +56,7 @@ const tangoConfigJson = {
|
|||||||
},
|
},
|
||||||
'@music163/antd': {
|
'@music163/antd': {
|
||||||
description: '云音乐低代码中后台应用基础物料',
|
description: '云音乐低代码中后台应用基础物料',
|
||||||
version: '0.2.5',
|
version: '0.2.6',
|
||||||
library: 'TangoAntd',
|
library: 'TangoAntd',
|
||||||
type: 'baseDependency',
|
type: 'baseDependency',
|
||||||
resources: [
|
resources: [
|
||||||
@@ -161,6 +161,8 @@ import {
|
|||||||
} from "@music163/antd";
|
} from "@music163/antd";
|
||||||
import { Space } from "@music163/antd";
|
import { Space } from "@music163/antd";
|
||||||
import { LocalButton } from "../components";
|
import { LocalButton } from "../components";
|
||||||
|
import { OutButton } from "../components";
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@@ -181,6 +183,7 @@ class App extends React.Component {
|
|||||||
<Section tid="section2">
|
<Section tid="section2">
|
||||||
<Space tid="space1">
|
<Space tid="space1">
|
||||||
<LocalButton />
|
<LocalButton />
|
||||||
|
<OutButton />
|
||||||
<Button tid="button1">button</Button>
|
<Button tid="button1">button</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</Section>
|
</Section>
|
||||||
@@ -290,6 +293,14 @@ registerComponentPrototype({
|
|||||||
});
|
});
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const outButtonCode = `
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function OutButton(props) {
|
||||||
|
return <button {...props}>Out button (from other file)</button>
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const componentsInputCode = `
|
const componentsInputCode = `
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { registerComponentPrototype } from '../utils';
|
import { registerComponentPrototype } from '../utils';
|
||||||
@@ -312,6 +323,7 @@ registerComponentPrototype({
|
|||||||
const componentsEntryCode = `
|
const componentsEntryCode = `
|
||||||
export { default as LocalButton } from './button';
|
export { default as LocalButton } from './button';
|
||||||
export { default as LocalInput } from './input';
|
export { default as LocalInput } from './input';
|
||||||
|
export { default as OutButton } from './out-button';
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const storeApp = `
|
const storeApp = `
|
||||||
@@ -412,6 +424,7 @@ export const sampleFiles = [
|
|||||||
{ filename: '/src/pages/list.js', code: viewHomeCode },
|
{ filename: '/src/pages/list.js', code: viewHomeCode },
|
||||||
{ filename: '/src/pages/detail.js', code: emptyPageCode },
|
{ filename: '/src/pages/detail.js', code: emptyPageCode },
|
||||||
{ filename: '/src/components/button.js', code: componentsButtonCode },
|
{ filename: '/src/components/button.js', code: componentsButtonCode },
|
||||||
|
{ filename: '/src/components/out-button.js', code: outButtonCode },
|
||||||
{ filename: '/src/components/input.js', code: componentsInputCode },
|
{ filename: '/src/components/input.js', code: componentsInputCode },
|
||||||
{ filename: '/src/components/index.js', code: componentsEntryCode },
|
{ filename: '/src/components/index.js', code: componentsEntryCode },
|
||||||
{ filename: '/src/routes.js', code: routesCode },
|
{ filename: '/src/routes.js', code: routesCode },
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DragPanel } from '@music163/tango-ui';
|
||||||
|
import { Box, Text } from 'coral-system';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'UI/DragPanel',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Basic() {
|
||||||
|
return (
|
||||||
|
<DragPanel
|
||||||
|
title="弹层标题"
|
||||||
|
extra="右上角内容"
|
||||||
|
width={350}
|
||||||
|
body={<Box p="m">内容</Box>}
|
||||||
|
footer={<Text>底部信息</Text>}
|
||||||
|
>
|
||||||
|
<Button>点击唤起浮层</Button>
|
||||||
|
</DragPanel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FooterCustom() {
|
||||||
|
return (
|
||||||
|
<DragPanel
|
||||||
|
title="弹层标题"
|
||||||
|
extra="右上角内容"
|
||||||
|
width={350}
|
||||||
|
body={<Box p="m">内容</Box>}
|
||||||
|
footer={(close) => (
|
||||||
|
<Box display="flex" justifyContent="space-between">
|
||||||
|
<Text>底部信息</Text>
|
||||||
|
<Button size="small" onClick={() => close()}>
|
||||||
|
点此关闭
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Button>点击唤起浮层</Button>
|
||||||
|
</DragPanel>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,6 +3,24 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.2.3](https://github.com/netease/tango/compare/@music163/tango-designer@1.2.2...@music163/tango-designer@1.2.3) (2024-05-30)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- optimize variable panel scroll ui & onCancel bug ([#166](https://github.com/netease/tango/issues/166)) ([a0ed57f](https://github.com/netease/tango/commit/a0ed57ff4f332bd88749b8b1925bdb29319e4d13))
|
||||||
|
|
||||||
|
## [1.2.2](https://github.com/netease/tango/compare/@music163/tango-designer@1.2.1...@music163/tango-designer@1.2.2) (2024-05-27)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- export usePreviewSandboxQuery & add builtin sandboxQuery ([#163](https://github.com/netease/tango/issues/163)) ([163eced](https://github.com/netease/tango/commit/163ecedff3ed7baee59e200a8cc60dcc63a24e48))
|
||||||
|
|
||||||
|
## [1.2.1](https://github.com/netease/tango/compare/@music163/tango-designer@1.2.0...@music163/tango-designer@1.2.1) (2024-05-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- check local component prototypes ([#160](https://github.com/netease/tango/issues/160)) ([a0484e8](https://github.com/netease/tango/commit/a0484e8f64f20f67c30c25c3d5ce65de549b3e04))
|
||||||
|
|
||||||
# [1.2.0](https://github.com/netease/tango/compare/@music163/tango-designer@1.1.0...@music163/tango-designer@1.2.0) (2024-05-21)
|
# [1.2.0](https://github.com/netease/tango/compare/@music163/tango-designer@1.1.0...@music163/tango-designer@1.2.0) (2024-05-21)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-designer",
|
"name": "@music163/tango-designer",
|
||||||
"version": "1.2.0",
|
"version": "1.2.3",
|
||||||
"description": "lowcode designer",
|
"description": "lowcode designer",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react"
|
"react"
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
"@music163/tango-core": "^1.2.0",
|
"@music163/tango-core": "^1.2.0",
|
||||||
"@music163/tango-helpers": "^1.1.1",
|
"@music163/tango-helpers": "^1.1.1",
|
||||||
"@music163/tango-sandbox": "^1.0.4",
|
"@music163/tango-sandbox": "^1.0.4",
|
||||||
"@music163/tango-setting-form": "^1.2.1",
|
"@music163/tango-setting-form": "^1.2.4",
|
||||||
"@music163/tango-ui": "^1.2.0",
|
"@music163/tango-ui": "^1.2.3",
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"cash-dom": "^8.1.2",
|
"cash-dom": "^8.1.2",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export function VariableTree(props: VariableTreeProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display="flex" columnGap="l" className="VariableTree" css={varTreeStyle} {...rest}>
|
<Box display="flex" columnGap="l" className="VariableTree" css={varTreeStyle} {...rest}>
|
||||||
<Box className="VariableList" width="40%">
|
<Box className="VariableList" width="40%" overflow="auto">
|
||||||
{renderHeaderExtra?.(props, state)}
|
{renderHeaderExtra?.(props, state)}
|
||||||
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
|
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
|
||||||
<Search placeholder="请输入变量名" onChange={(val) => setKeyword(val?.trim())} />
|
<Search placeholder="请输入变量名" onChange={(val) => setKeyword(val?.trim())} />
|
||||||
@@ -203,7 +203,11 @@ export function VariableTree(props: VariableTreeProps) {
|
|||||||
<Box flex="0 0 72px" textAlign="right">
|
<Box flex="0 0 72px" textAlign="right">
|
||||||
{node.showRemoveButton && (
|
{node.showRemoveButton && (
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
|
zIndex={99999}
|
||||||
title={`确认删除吗 ${node.title}?该操作会导致引用此模型的代码报错,请谨慎操作!`}
|
title={`确认删除吗 ${node.title}?该操作会导致引用此模型的代码报错,请谨慎操作!`}
|
||||||
|
onCancel={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
onConfirm={(e) => {
|
onConfirm={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (isStoreVariablePath(node.key)) {
|
if (isStoreVariablePath(node.key)) {
|
||||||
@@ -333,7 +337,14 @@ export function VariableTree(props: VariableTreeProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ValueDefine data={activeNode} onSave={onUpdateStoreVariable} />
|
<ValueDefine
|
||||||
|
data={activeNode}
|
||||||
|
onSave={(variableKey, code) => {
|
||||||
|
onUpdateStoreVariable(variableKey, code);
|
||||||
|
// 更新当前节点 code
|
||||||
|
setActiveNode((pre) => ({ ...pre, raw: code }));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</ValueDetail>
|
</ValueDetail>
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ export function ValueDefine({ data, onSave = noop }: ValueDefineProps) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
off();
|
off();
|
||||||
setError('');
|
setError('');
|
||||||
|
// 重置到原始值
|
||||||
|
setValue(data.raw);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
|
|||||||
@@ -6,10 +6,14 @@ export interface IDesignerContext<S = any> {
|
|||||||
* 沙箱查询实例
|
* 沙箱查询实例
|
||||||
*/
|
*/
|
||||||
sandboxQuery: DndQuery;
|
sandboxQuery: DndQuery;
|
||||||
|
/**
|
||||||
|
* 预览沙箱查询实例
|
||||||
|
*/
|
||||||
|
previewSandboxQuery: DndQuery;
|
||||||
/**
|
/**
|
||||||
* 远程服务
|
* 远程服务
|
||||||
*/
|
*/
|
||||||
remoteServices?: Record<string, S>;
|
remoteServices: Record<string, S>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [DesignerProvider, useDesigner] = createContext<IDesignerContext>({
|
const [DesignerProvider, useDesigner] = createContext<IDesignerContext>({
|
||||||
@@ -19,9 +23,13 @@ const [DesignerProvider, useDesigner] = createContext<IDesignerContext>({
|
|||||||
export { DesignerProvider };
|
export { DesignerProvider };
|
||||||
|
|
||||||
export const useSandboxQuery = () => {
|
export const useSandboxQuery = () => {
|
||||||
return useDesigner()?.sandboxQuery;
|
return useDesigner().sandboxQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePreviewSandboxQuery = () => {
|
||||||
|
return useDesigner().previewSandboxQuery;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRemoteServices = () => {
|
export const useRemoteServices = () => {
|
||||||
return useDesigner()?.remoteServices;
|
return useDesigner().remoteServices;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,8 +5,18 @@ import { TangoEngineProvider, ITangoEngineContext } from '@music163/tango-contex
|
|||||||
import zhCN from 'antd/lib/locale/zh_CN';
|
import zhCN from 'antd/lib/locale/zh_CN';
|
||||||
import { DesignerProvider, IDesignerContext } from './context';
|
import { DesignerProvider, IDesignerContext } from './context';
|
||||||
import defaultTheme from './themes/default';
|
import defaultTheme from './themes/default';
|
||||||
|
import { DndQuery } from './dnd';
|
||||||
|
import { DESIGN_SANDBOX_ID, PREVIEW_SANDBOX_ID } from './helpers';
|
||||||
|
|
||||||
export interface DesignerProps extends IDesignerContext, ITangoEngineContext {
|
const builtinSandboxQuery = new DndQuery({
|
||||||
|
context: `#${DESIGN_SANDBOX_ID}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const builtinPreviewSandboxQuery = new DndQuery({
|
||||||
|
context: `#${PREVIEW_SANDBOX_ID}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export interface DesignerProps extends Partial<IDesignerContext>, ITangoEngineContext {
|
||||||
/**
|
/**
|
||||||
* 主题包
|
* 主题包
|
||||||
*/
|
*/
|
||||||
@@ -20,13 +30,23 @@ export interface DesignerProps extends IDesignerContext, ITangoEngineContext {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function Designer(props: DesignerProps) {
|
export function Designer(props: DesignerProps) {
|
||||||
const { engine, config, theme: themeProp, sandboxQuery, remoteServices = {}, children } = props;
|
const {
|
||||||
|
engine,
|
||||||
|
config,
|
||||||
|
theme: themeProp,
|
||||||
|
sandboxQuery = builtinSandboxQuery,
|
||||||
|
previewSandboxQuery = builtinPreviewSandboxQuery,
|
||||||
|
remoteServices = {},
|
||||||
|
children,
|
||||||
|
} = props;
|
||||||
const theme = useMemo(() => extendTheme(themeProp, defaultTheme), [themeProp]);
|
const theme = useMemo(() => extendTheme(themeProp, defaultTheme), [themeProp]);
|
||||||
return (
|
return (
|
||||||
<SystemProvider theme={theme} prefix="--tango">
|
<SystemProvider theme={theme} prefix="--tango">
|
||||||
<ConfigProvider locale={zhCN}>
|
<ConfigProvider locale={zhCN}>
|
||||||
<TangoEngineProvider value={{ engine, config }}>
|
<TangoEngineProvider value={{ engine, config }}>
|
||||||
<DesignerProvider value={{ sandboxQuery, remoteServices }}>{children}</DesignerProvider>
|
<DesignerProvider value={{ sandboxQuery, previewSandboxQuery, remoteServices }}>
|
||||||
|
{children}
|
||||||
|
</DesignerProvider>
|
||||||
</TangoEngineProvider>
|
</TangoEngineProvider>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</SystemProvider>
|
</SystemProvider>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ export const DRAGGABLE_SELECTOR = `[${SLOT.dnd}]`;
|
|||||||
interface DndQueryOptions {
|
interface DndQueryOptions {
|
||||||
/**
|
/**
|
||||||
* DOM 查询上下文选择器
|
* DOM 查询上下文选择器
|
||||||
* TODO: 是不是可以合并成一个 API
|
|
||||||
*/
|
*/
|
||||||
context?: string;
|
context?: string;
|
||||||
/**
|
/**
|
||||||
@@ -63,6 +62,9 @@ export class DndQuery {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沙箱内的 window 对象
|
||||||
|
*/
|
||||||
get window() {
|
get window() {
|
||||||
if (this.context && 'defaultView' in this.context) {
|
if (this.context && 'defaultView' in this.context) {
|
||||||
return (this.context as unknown as Document).defaultView;
|
return (this.context as unknown as Document).defaultView;
|
||||||
@@ -71,6 +73,9 @@ export class DndQuery {
|
|||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沙箱内的全局滚动偏移
|
||||||
|
*/
|
||||||
get scrollTop() {
|
get scrollTop() {
|
||||||
if (this.context && 'documentElement' in this.context) {
|
if (this.context && 'documentElement' in this.context) {
|
||||||
return (this.context as unknown as Document).documentElement.scrollTop;
|
return (this.context as unknown as Document).documentElement.scrollTop;
|
||||||
|
|||||||
@@ -7,6 +7,20 @@ import {
|
|||||||
parseDndId,
|
parseDndId,
|
||||||
} from '@music163/tango-helpers';
|
} from '@music163/tango-helpers';
|
||||||
|
|
||||||
|
// -----------
|
||||||
|
// CONSTANTS
|
||||||
|
// -----------
|
||||||
|
|
||||||
|
export const DRAG_GHOST_ID = 'dragGhost';
|
||||||
|
|
||||||
|
export const DESIGN_SANDBOX_ID = 'sandbox-container';
|
||||||
|
|
||||||
|
export const PREVIEW_SANDBOX_ID = 'preview-sandbox-container';
|
||||||
|
|
||||||
|
// -----------
|
||||||
|
// DOM Helpers
|
||||||
|
// -----------
|
||||||
|
|
||||||
export function buildQueryBySlotId(id: string) {
|
export function buildQueryBySlotId(id: string) {
|
||||||
return `[${SLOT.dnd}="${id}"]`;
|
return `[${SLOT.dnd}="${id}"]`;
|
||||||
}
|
}
|
||||||
@@ -15,8 +29,6 @@ export function getElement(selector: Selector) {
|
|||||||
return $(selector).get(0);
|
return $(selector).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DRAG_GHOST_ID = 'dragGhost';
|
|
||||||
|
|
||||||
export const getDragGhostElement = () => getElement(`#${DRAG_GHOST_ID}`);
|
export const getDragGhostElement = () => getElement(`#${DRAG_GHOST_ID}`);
|
||||||
|
|
||||||
export function setElementStyle(selector: Selector, style: any) {
|
export function setElementStyle(selector: Selector, style: any) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { useSandboxQuery } from '../context';
|
|||||||
import { DndQuery, useDnd } from '../dnd';
|
import { DndQuery, useDnd } from '../dnd';
|
||||||
import { Navigator } from './navigator';
|
import { Navigator } from './navigator';
|
||||||
import { SelectionToolsProps } from '../simulator/selection';
|
import { SelectionToolsProps } from '../simulator/selection';
|
||||||
|
import { DESIGN_SANDBOX_ID, PREVIEW_SANDBOX_ID } from '../helpers';
|
||||||
|
|
||||||
interface ISandboxEventHandlerConfig {
|
interface ISandboxEventHandlerConfig {
|
||||||
sandboxQuery?: DndQuery;
|
sandboxQuery?: DndQuery;
|
||||||
@@ -62,6 +63,7 @@ function useSandbox({
|
|||||||
const workspace = useWorkspace();
|
const workspace = useWorkspace();
|
||||||
const designer = useDesigner();
|
const designer = useDesigner();
|
||||||
const sandboxQuery = useSandboxQuery();
|
const sandboxQuery = useSandboxQuery();
|
||||||
|
|
||||||
const isPreview = isPreviewProp ?? designer.isPreview;
|
const isPreview = isPreviewProp ?? designer.isPreview;
|
||||||
|
|
||||||
// 组件不一定会立即刷新,因此 isActive 需要实时获取
|
// 组件不一定会立即刷新,因此 isActive 需要实时获取
|
||||||
@@ -140,7 +142,7 @@ const PreviewSandbox = observer(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display={display} width="100%" height="100%">
|
<Box display={display} width="100%" height="100%">
|
||||||
<CodeSandbox ref={ref} iframeId="preview-sandbox-container" {...sandboxProps} {...rest} />
|
<CodeSandbox ref={ref} iframeId={PREVIEW_SANDBOX_ID} {...sandboxProps} {...rest} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -188,7 +190,7 @@ const DesignSandbox = observer(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display={display} width="100%" height="100%">
|
<Box display={display} width="100%" height="100%">
|
||||||
<CodeSandbox ref={ref} {...sandboxProps} {...rest} />
|
<CodeSandbox ref={ref} iframeId={DESIGN_SANDBOX_ID} {...sandboxProps} {...rest} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -289,6 +289,10 @@ const StyledCommonGridItem = styled.div`
|
|||||||
transition: 0.15s ease-in-out;
|
transition: 0.15s ease-in-out;
|
||||||
transition-property: transform;
|
transition-property: transform;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
|
img {
|
||||||
|
width: unset;
|
||||||
|
height: 85%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
@@ -355,6 +359,15 @@ function MaterialGrid({ data }: MaterialProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const icon = data.icon || 'icon-placeholder';
|
const icon = data.icon || 'icon-placeholder';
|
||||||
|
|
||||||
|
const iconNode = icon.startsWith('icon-') ? (
|
||||||
|
<IconFont className="material-icon" type={data.icon || 'icon-placeholder'} />
|
||||||
|
) : (
|
||||||
|
<Box className="material-icon">
|
||||||
|
<img src={icon} alt={data.name} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
if (isLine) {
|
if (isLine) {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -380,11 +393,7 @@ function MaterialGrid({ data }: MaterialProps) {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
>
|
>
|
||||||
{icon.startsWith('icon-') ? (
|
{iconNode}
|
||||||
<IconFont className="material-icon" type={data.icon || 'icon-placeholder'} />
|
|
||||||
) : (
|
|
||||||
<img className="material-icon" src={icon} alt={data.name} />
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box flex={1}>
|
<Box flex={1}>
|
||||||
<Box fontWeight="500" display="flex" justifyContent="space-between">
|
<Box fontWeight="500" display="flex" justifyContent="space-between">
|
||||||
@@ -417,11 +426,7 @@ function MaterialGrid({ data }: MaterialProps) {
|
|||||||
onDragEnd={handleDragEnd}
|
onDragEnd={handleDragEnd}
|
||||||
onClick={handleSelect}
|
onClick={handleSelect}
|
||||||
>
|
>
|
||||||
{icon.startsWith('icon-') ? (
|
{iconNode}
|
||||||
<IconFont className="material-icon" type={data.icon || 'icon-placeholder'} />
|
|
||||||
) : (
|
|
||||||
<img className="material-icon" src={icon} alt={data.name} />
|
|
||||||
)}
|
|
||||||
<Text fontSize="12px" marginTop="4px">
|
<Text fontSize="12px" marginTop="4px">
|
||||||
{data.title ?? data.name}
|
{data.title ?? data.name}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const VariablePanel = observer(
|
|||||||
新建模型
|
新建模型
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
bodyProps={{ p: 'm' }}
|
bodyProps={{ p: 'm', height: '100%' }}
|
||||||
>
|
>
|
||||||
{isAdd ? (
|
{isAdd ? (
|
||||||
<AddStoreForm
|
<AddStoreForm
|
||||||
@@ -42,6 +42,7 @@ export const VariablePanel = observer(
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<VariableTree
|
<VariableTree
|
||||||
|
height="100%"
|
||||||
defaultValueDetailMode="define"
|
defaultValueDetailMode="define"
|
||||||
dataSource={storeVariables}
|
dataSource={storeVariables}
|
||||||
onAddStoreVariable={(storeName, data) => {
|
onAddStoreVariable={(storeName, data) => {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ function SelectionBox({ showActions, actions, data }: SelectionBoxProps) {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<SelectionToolSet>{!isPage && actions}</SelectionToolSet>
|
<SelectionToolSet>{!isPage && actions}</SelectionToolSet>
|
||||||
{prototype.hasChildren !== false && (
|
{isFromCurrentFile && prototype?.hasChildren !== false && (
|
||||||
<ComponentsPopover>
|
<ComponentsPopover>
|
||||||
<Tooltip title="快捷添加子元素">
|
<Tooltip title="快捷添加子元素">
|
||||||
<SelectionHelper icon={<PlusOutlined />} />
|
<SelectionHelper icon={<PlusOutlined />} />
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const PreviewTool = observer(() => {
|
|||||||
designer.setActiveView('design');
|
designer.setActiveView('design');
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
tooltip="预览"
|
tooltip={designer.isPreview ? '切换到设计模式' : '切换到预览模式'}
|
||||||
>
|
>
|
||||||
<EyeOutlined />
|
<EyeOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export function Toolbar({ children }: ToolbarProps) {
|
|||||||
<Group display="flex" alignItems="center" gap="m">
|
<Group display="flex" alignItems="center" gap="m">
|
||||||
{centerTools}
|
{centerTools}
|
||||||
</Group>
|
</Group>
|
||||||
<Group display="flex" alignItems="center" gap="m">
|
<Group display="flex" alignItems="center" justifyContent="flex-end" gap="m">
|
||||||
{rightTools}
|
{rightTools}
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -3,6 +3,18 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.2.4](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.2.3...@music163/tango-setting-form@1.2.4) (2024-05-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
|
## [1.2.3](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.2.2...@music163/tango-setting-form@1.2.3) (2024-05-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
|
## [1.2.2](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.2.1...@music163/tango-setting-form@1.2.2) (2024-05-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
## [1.2.1](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.2.0...@music163/tango-setting-form@1.2.1) (2024-05-21)
|
## [1.2.1](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.2.0...@music163/tango-setting-form@1.2.1) (2024-05-21)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-setting-form",
|
"name": "@music163/tango-setting-form",
|
||||||
"version": "1.2.1",
|
"version": "1.2.4",
|
||||||
"description": "setting form of tango-apps",
|
"description": "setting form of tango-apps",
|
||||||
"author": "wwsun <ww.sun@outlook.com>",
|
"author": "wwsun <ww.sun@outlook.com>",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@music163/tango-core": "^1.2.0",
|
"@music163/tango-core": "^1.2.0",
|
||||||
"@music163/tango-helpers": "^1.1.1",
|
"@music163/tango-helpers": "^1.1.1",
|
||||||
"@music163/tango-ui": "^1.2.0",
|
"@music163/tango-ui": "^1.2.3",
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"coral-system": "^1.0.5",
|
"coral-system": "^1.0.5",
|
||||||
"mobx": "6.12.3",
|
"mobx": "6.12.3",
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.2.3](https://github.com/netease/tango/compare/@music163/tango-ui@1.2.2...@music163/tango-ui@1.2.3) (2024-05-30)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- popover re-click position bug & drag panel drag bug ([#165](https://github.com/netease/tango/issues/165)) ([f83c6bc](https://github.com/netease/tango/commit/f83c6bc0f69820582720512eefedc9ddf5db2975))
|
||||||
|
|
||||||
|
## [1.2.2](https://github.com/netease/tango/compare/@music163/tango-ui@1.2.1...@music163/tango-ui@1.2.2) (2024-05-27)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- export usePreviewSandboxQuery & add builtin sandboxQuery ([#163](https://github.com/netease/tango/issues/163)) ([163eced](https://github.com/netease/tango/commit/163ecedff3ed7baee59e200a8cc60dcc63a24e48))
|
||||||
|
|
||||||
|
## [1.2.1](https://github.com/netease/tango/compare/@music163/tango-ui@1.2.0...@music163/tango-ui@1.2.1) (2024-05-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-ui
|
||||||
|
|
||||||
# [1.2.0](https://github.com/netease/tango/compare/@music163/tango-ui@1.1.0...@music163/tango-ui@1.2.0) (2024-05-21)
|
# [1.2.0](https://github.com/netease/tango/compare/@music163/tango-ui@1.1.0...@music163/tango-ui@1.2.0) (2024-05-21)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-ui",
|
"name": "@music163/tango-ui",
|
||||||
"version": "1.2.0",
|
"version": "1.2.3",
|
||||||
"description": "ui widgets of tango",
|
"description": "ui widgets of tango",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const actionStyle = css`
|
|||||||
border-radius: var(--tango-radii-s);
|
border-radius: var(--tango-radii-s);
|
||||||
color: var(--tango-colors-text2);
|
color: var(--tango-colors-text2);
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--tango-colors-fill2);
|
background-color: var(--tango-colors-fill2);
|
||||||
|
|||||||
@@ -5,6 +5,24 @@ import Draggable from 'react-draggable';
|
|||||||
import { CloseOutlined } from '@ant-design/icons';
|
import { CloseOutlined } from '@ant-design/icons';
|
||||||
import { noop } from '@music163/tango-helpers';
|
import { noop } from '@music163/tango-helpers';
|
||||||
|
|
||||||
|
// Dragging over an iframe stops dragging when moving the mouse too fast #613
|
||||||
|
// https://github.com/react-grid-layout/react-draggable/issues/613
|
||||||
|
const injectStyleToBody = () => {
|
||||||
|
const id = 'react-draggable-transparent-selection';
|
||||||
|
if (document.getElementById(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.id = id;
|
||||||
|
style.innerHTML = `
|
||||||
|
/* Prevent iframes from stealing drag events */
|
||||||
|
.react-draggable-transparent-selection iframe {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
};
|
||||||
|
|
||||||
const CloseIcon = styled(CloseOutlined)`
|
const CloseIcon = styled(CloseOutlined)`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@@ -17,7 +35,7 @@ const CloseIcon = styled(CloseOutlined)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface DragPanelProps extends Omit<PopoverProps, 'overlay'> {
|
interface DragPanelProps extends Omit<PopoverProps, 'overlay' | 'open'> {
|
||||||
// 标题
|
// 标题
|
||||||
title?: React.ReactNode | string;
|
title?: React.ReactNode | string;
|
||||||
// 内容
|
// 内容
|
||||||
@@ -59,7 +77,12 @@ export function DragPanel({
|
|||||||
onOpenChange(innerOpen);
|
onOpenChange(innerOpen);
|
||||||
}}
|
}}
|
||||||
overlay={
|
overlay={
|
||||||
<Draggable handle=".selection-drag-bar">
|
<Draggable
|
||||||
|
handle=".selection-drag-bar"
|
||||||
|
onStart={() => {
|
||||||
|
injectStyleToBody();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
bg="#FFF"
|
bg="#FFF"
|
||||||
borderRadius="m"
|
borderRadius="m"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Box, HTMLCoralProps, css } from 'coral-system';
|
import { Box, HTMLCoralProps } from 'coral-system';
|
||||||
import CodeMirror, { ReactCodeMirrorProps } from '@uiw/react-codemirror';
|
import CodeMirror, { ReactCodeMirrorProps } from '@uiw/react-codemirror';
|
||||||
import { javascript, javascriptLanguage, esLint } from '@codemirror/lang-javascript';
|
import { javascript, javascriptLanguage, esLint } from '@codemirror/lang-javascript';
|
||||||
import { CompletionContext } from '@codemirror/autocomplete';
|
import { CompletionContext } from '@codemirror/autocomplete';
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ export const Popover: React.FC<PopoverProps> = ({
|
|||||||
const handleClick = useCallback(
|
const handleClick = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (visible) {
|
||||||
|
setVisible(false);
|
||||||
|
onOpenChange(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const x = e.clientX;
|
const x = e.clientX;
|
||||||
const y = e.clientY;
|
const y = e.clientY;
|
||||||
setLeft(x);
|
setLeft(x);
|
||||||
@@ -104,7 +109,7 @@ export const Popover: React.FC<PopoverProps> = ({
|
|||||||
setVisible(true);
|
setVisible(true);
|
||||||
onOpenChange(true);
|
onOpenChange(true);
|
||||||
},
|
},
|
||||||
[onOpenChange],
|
[visible, onOpenChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ const buttonStyle = css`
|
|||||||
background-color: var(--tango-colors-custom-toolbarButtonBg, rgba(223, 223, 223, 0.08));
|
background-color: var(--tango-colors-custom-toolbarButtonBg, rgba(223, 223, 223, 0.08));
|
||||||
color: var(--tango-colors-custom-toolbarButtonTextColor, #999);
|
color: var(--tango-colors-custom-toolbarButtonTextColor, #999);
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: var(--tango-radii-m);
|
border-radius: var(--tango-radii-s);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--tango-colors-custom-toolbarButtonTextColorHover, #fff);
|
color: var(--tango-colors-custom-toolbarButtonTextColorHover, #fff);
|
||||||
|
|||||||
Reference in New Issue
Block a user