Compare commits

..

14 Commits

Author SHA1 Message Date
wwsun f2919c1aa0 chore(release): publish
- @music163/tango-designer@1.0.0-alpha.2
 - tango-spec@1.0.2
2023-12-13 15:59:20 +08:00
wwsun 5dd5ab62a8 chore: up 2023-12-13 15:57:54 +08:00
Wells 5e7e285452 fix: update variable tree with help messages and styling & add tangoConfig schema
* fix: update variable tree with help messages and styling

* chore: add spec package

* fix: update schema

* chore: disabled umi https2

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-13 14:03:07 +08:00
wwsun b3a458a914 chore(release): publish
- @music163/tango-context@1.0.0-alpha.1
 - @music163/tango-core@1.0.0-alpha.1
 - @music163/tango-designer@1.0.0-alpha.1
 - @music163/tango-sandbox@1.0.0-alpha.1
 - @music163/tango-setting-form@1.0.0-alpha.1
 - @music163/tango-ui@1.0.0-alpha.1
2023-12-12 11:12:09 +08:00
Wells 1acfa6864b fix: render form item without setter & enhance tools (#76)
* fix: render form item without setter

* fix: update toggle-button style

* fix: update tools

* fix: remove useless code

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-12 11:10:17 +08:00
Wells baf071f130 chore: use umi4 (#75)
Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-08 15:46:51 +08:00
Wells 6b1d55a11f RC (#74)
* chore: up

* chore: update release scripts

* chore: up

* chore: update lerna config

* chore(release): publish

 - @music163/tango-context@1.0.0-alpha.0
 - @music163/tango-core@1.0.0-alpha.0
 - @music163/tango-designer@1.0.0-alpha.0
 - @music163/tango-sandbox@1.0.0-alpha.0
 - @music163/tango-setting-form@1.0.0-alpha.0
 - @music163/tango-ui@1.0.0-alpha.0

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-07 12:40:18 +08:00
Wells a8357f45b8 fix: add showSearch and showGroups to SettingForm & update internal icons (#73)
* fix: add internal setters & fix ui

* feat: add showSearch and showGroups to SettingForm

* fix: update icons

* fix: use antd form

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-07 10:31:19 +08:00
Wells 9db6358588 fix: disable search keymap of InputCode (#72)
Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-06 15:33:47 +08:00
wwsun 5bc2fb2d5a chore: up 2023-12-06 11:33:05 +08:00
wwsun 05a0f8f490 chore(release): publish
- @music163/tango-context@0.2.12
 - @music163/tango-core@0.2.11
 - @music163/tango-designer@0.5.14
 - @music163/tango-sandbox@0.1.16
 - @music163/tango-setting-form@0.2.16
2023-12-04 18:43:14 +08:00
wwsun c884712331 fix: update FileType 2023-12-04 18:38:38 +08:00
wwsun e35ff792a0 chore(release): publish
- @music163/tango-context@0.2.11
 - @music163/tango-core@0.2.10
 - @music163/tango-designer@0.5.13
 - @music163/tango-sandbox@0.1.15
 - @music163/tango-setting-form@0.2.15
2023-12-04 12:54:30 +08:00
Wells 138cbe9b20 fix: add filesFormatter to sandbox & fix update props with imports (#71)
* fix: update types

* fix: add filesFormatter to sandbox

* fix: update node attributes with imports

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
2023-12-04 12:52:10 +08:00
72 changed files with 4667 additions and 2826 deletions
+2
View File
@@ -0,0 +1,2 @@
registry=https://registry.npmmirror.com/
-2
View File
@@ -1,2 +0,0 @@
PORT=6006
HOST=local.netease.com
+9
View File
@@ -0,0 +1,9 @@
/node_modules
/.env.local
/.umirc.local.ts
/config/config.local.ts
/src/.umi
/src/.umi-production
/src/.umi-test
/dist
.swc
@@ -1,33 +1,17 @@
import path from 'path';
import { defineConfig } from 'umi';
const resolvePackageIndex = (relativeEntry: string) =>
path.resolve(__dirname, '../../../packages/', relativeEntry);
path.resolve(__dirname, '../../packages/', relativeEntry);
export default {
export default defineConfig({
routes: [
{
exact: true,
path: '/',
component: 'index',
name: '首页',
},
{ path: '/', component: 'index' },
{ path: '/docs', component: 'docs' },
],
devServer: {
host: 'local.netease.com',
port: 8008,
https: {
key: path.resolve(__dirname, 'local.netease.com-key.pem'),
cert: path.resolve(__dirname, 'local.netease.com.pem'),
},
headers: { 'Origin-Agent-Cluster': '?0' },
},
targets: {
chrome: 79,
firefox: false,
safari: false,
edge: false,
ios: false,
},
npmClient: 'yarn',
mfsu: false,
codeSplitting: false,
alias: {
'@music163/tango-helpers': resolvePackageIndex('helpers/src/index.ts'),
'@music163/tango-core': resolvePackageIndex('core/src/index.ts'),
@@ -44,6 +28,21 @@ export default {
moment: 'moment',
antd: 'antd',
},
headScripts: [
'https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.development.js',
'https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.development.js',
'https://cdn.jsdelivr.net/npm/react-is@18.2.0/umd/react-is.production.min.js',
'https://cdn.jsdelivr.net/npm/moment/min/moment-with-locales.js',
'https://cdn.jsdelivr.net/npm/styled-components@5.3.11/dist/styled-components.js',
'https://cdn.jsdelivr.net/npm/antd@4.24.13/dist/antd-with-locales.min.js',
'https://cdn.jsdelivr.net/npm/prettier@2.6.0/standalone.js',
'https://cdn.jsdelivr.net/npm/prettier@2.6.0/parser-babel.js',
],
https: {
key: path.resolve(__dirname, 'local.netease.com-key.pem'),
cert: path.resolve(__dirname, 'local.netease.com.pem'),
http2: false,
},
chainWebpack: (config: any) => {
// @see https://github.com/graphql/graphql-js/issues/1272#issuecomment-393903706
config.module
@@ -61,4 +60,5 @@ export default {
config.module.rule('js').include.add(resolvePackageIndex('ui/src'));
return config;
},
};
monorepoRedirect: {},
});
-5
View File
@@ -1,5 +0,0 @@
# `playground`
搭建平台演示示例
## 说明
+11 -12
View File
@@ -2,24 +2,23 @@
"name": "playground",
"version": "0.0.0",
"private": true,
"description": "playground of tango-apps",
"license": "MIT",
"author": "wwsun <ww.sun@outlook.com>",
"files": [
"lib"
],
"author": "Wells <ww.sun@outlook.com>",
"scripts": {
"build": "COMPRESS=none umi build",
"start": "umi dev"
"dev": "HOST=local.netease.com PORT=8001 umi dev",
"build": "umi build",
"postinstall": "umi setup",
"setup": "umi setup",
"start": "npm run dev"
},
"dependencies": {
"@ant-design/icons": "^4.8.0",
"@music163/tango-designer": "*",
"@music163/tango-helpers": "*",
"antd": "^4.24.2",
"coral-system": "^1.0.5"
"coral-system": "^1.0.5",
"umi": "^4.0.89"
},
"devDependencies": {
"umi": "^3.5.24"
"@types/react": "^18.0.33",
"@types/react-dom": "^18.0.11",
"typescript": "^5.0.3"
}
}
+10
View File
@@ -0,0 +1,10 @@
import type { IApi } from 'umi';
export default (api: IApi) => {
api.addMiddlewares(() => {
return (req, res, next) => {
res.setHeader('Origin-Agent-Cluster', '?0');
next();
};
});
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

@@ -6,29 +6,30 @@ import { registerSetter } from '@music163/tango-designer';
import type { ComponentPrototypeType } from '@music163/tango-helpers';
import { FooSetter } from '../components';
export * from './mock-files';
export const bootHelperVariables = [
{
key: '$helpers',
title: '工具函数',
children: [
{
title: 'setStoreValue',
title: '设置变量值',
key: '() => tango.setStoreValue("variableName", "variableValue")',
type: 'function',
help: '设置状态值,tango.setStoreValue("variableName", "variableValue")',
},
{
title: 'getStoreValue',
title: '获取变量值',
key: '() => tango.getStoreValue("variableName")',
type: 'function',
help: '获取状态值',
},
{ title: 'openModal', key: '() => tango.openModal("")', type: 'function' },
{ title: 'closeModal', key: '() => tango.closeModal("")', type: 'function' },
{ title: 'navigateTo', key: '() => tango.navigateTo("/")', type: 'function' },
{ title: 'showToast', key: '() => tango.showToast("hello")', type: 'function' },
{ title: 'formatDate', key: '() => tango.formatDate("2022-12-12")', type: 'function' },
{ title: 'formatNumber', key: '() => tango.formatDate(9999)', type: 'function' },
{ title: '打开弹窗', key: '() => tango.openModal("")', type: 'function' },
{ title: '关闭弹窗', key: '() => tango.closeModal("")', type: 'function' },
{ title: '切换路由', key: '() => tango.navigateTo("/")', type: 'function' },
{
title: 'copyToClipboard',
title: '拷贝到剪贴板',
key: '() => tango.copyToClipboard("hello")',
type: 'function',
},
@@ -143,6 +143,8 @@ import {
FormilyForm,
} from "@music163/antd";
import { Space } from '@music163/antd';
import { MyButton } from '../components/button';
class App extends React.Component {
render() {
return (
@@ -151,6 +153,7 @@ class App extends React.Component {
</Section>
<Section>
<Space>
<MyButton />
<Button>button</Button>
<Input />
</Space>
@@ -162,6 +165,16 @@ class App extends React.Component {
export default definePage(App);
`;
const componentsButtonCode = `
import React from 'react';
export function MyButton() {
return <button>my button</button>
}
`;
const componentsPrototypeCode = ``;
const storeApp = `
import { defineStore } from '@music163/tango-boot';
@@ -246,6 +259,8 @@ export const sampleFiles = [
{ filename: '/src/style.css', code: cssCode },
{ filename: '/src/index.js', code: entryCode },
{ filename: '/src/pages/list.js', code: viewHomeCode },
{ filename: '/src/components/button.js', code: componentsButtonCode },
{ filename: '/src/components/prototype.js', code: componentsPrototypeCode },
{ filename: '/src/routes.js', code: routesCode },
{ filename: '/src/stores/index.js', code: storeIndexCode },
{ filename: '/src/stores/app.js', code: storeApp },
@@ -2,4 +2,5 @@
@import '~antd/dist/antd.less'; // 引入官方提供的 less 样式入口文件
@primary-color: #2f54eb;
@border-radius-base: 2px;
@border-radius-base: 2px;
+11
View File
@@ -0,0 +1,11 @@
import React from 'react';
import { Outlet } from 'umi';
import './index.less';
export default function Layout() {
return (
<div>
<Outlet />
</div>
);
}
+9
View File
@@ -0,0 +1,9 @@
const DocsPage = () => {
return (
<div>
<p>This is umi docs.</p>
</div>
);
};
export default DocsPage;
-21
View File
@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tango Playground</title>
</head>
<body>
<div id="root"></div>
<script src="https://cdn.jsdelivr.net/npm/react@16.14.0/umd/react.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@16.14.0/umd/react-dom.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-is@16.13.1/umd/react-is.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment/min/moment-with-locales.js"></script>
<script src="https://cdn.jsdelivr.net/npm/styled-components@5.3.11/dist/styled-components.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.15.6/babel.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prettier@2.6.0/standalone.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prettier@2.6.0/parser-babel.js"></script>
<script src="https://cdn.jsdelivr.net/npm/antd@4.24.13/dist/antd-with-locales.min.js"></script>
</body>
</html>
+2 -3
View File
@@ -15,9 +15,7 @@ import {
themeLight,
} from '@music163/tango-designer';
import { createEngine, Workspace } from '@music163/tango-core';
import { Logo, ProjectDetail, bootHelperVariables } from './share';
import { sampleFiles } from '../mock/project';
import './index.less';
import { Logo, ProjectDetail, bootHelperVariables, sampleFiles } from '../helpers';
import {
ApiOutlined,
AppstoreAddOutlined,
@@ -68,6 +66,7 @@ export default function App() {
<Box px="l">
<Toolbar>
<Toolbar.Item key="routeSwitch" placement="left" />
<Toolbar.Item key="history" placement="left" />
<Toolbar.Item key="preview" placement="left" />
<Toolbar.Item key="modeSwitch" placement="right" />
<Toolbar.Item key="togglePanel" placement="right" />
+1 -1
View File
@@ -1,3 +1,3 @@
{
"extends": "../../tsconfig.json"
"extends": "./src/.umi/tsconfig.json"
}
+1
View File
@@ -0,0 +1 @@
import 'umi/typings';
+2 -2
View File
@@ -16,8 +16,8 @@
"dependencies": {
"@music163/tango-setting-form": "*",
"@music163/tango-ui": "*",
"mobx": "6.9.0",
"mobx-react-lite": "4.0.2"
"mobx": "6.12.0",
"mobx-react-lite": "4.0.5"
},
"devDependencies": {
"@storybook/addon-actions": "^6.5.14",
+14 -131
View File
@@ -1,7 +1,6 @@
import React, { useState } from 'react';
import { EditableVariableTree, FormModel, SettingForm } from '@music163/tango-setting-form';
import { ComponentPrototypeType, getValue } from '@music163/tango-helpers';
import { createServices } from '@music163/request';
import React from 'react';
import { FormModel, SettingForm } from '@music163/tango-setting-form';
import { ComponentPrototypeType } from '@music163/tango-helpers';
import { Box } from 'coral-system';
import { JsonView } from '@music163/tango-ui';
import { toJS } from 'mobx';
@@ -9,51 +8,9 @@ import { observer } from 'mobx-react-lite';
import { Card } from 'antd';
export default {
title: 'SettingForm/ Setters',
title: 'SettingForm',
};
const modelVariables = [
{
title: 'stores',
key: 'stores',
selectable: false,
children: [
{
title: 'app',
key: 'stores.app',
selectable: false,
children: [
{ title: 'app.title', key: 'stores.app.title', raw: '"hello"' },
{ title: 'app.age', key: 'stores.app.age', raw: '20' },
{ title: 'app.detail', key: 'stores.app.detail', raw: '{ foo: "foo" }' },
{ title: 'app.list', key: 'stores.app.list', type: 'function', raw: '() => {}' },
],
},
{
title: 'user',
key: 'stores.user',
selectable: false,
children: [
{ title: 'name', key: 'stores.user.name' },
{ title: 'age', key: 'stores.user.age' },
],
},
],
},
{
title: 'services',
key: 'services',
selectable: false,
children: [
{
title: 'listUsers',
key: 'services.listUsers',
type: 'function',
},
],
},
];
const prototype: ComponentPrototypeType = {
name: 'Test',
exportType: 'namedExport',
@@ -257,47 +214,6 @@ const prototype: ComponentPrototypeType = {
],
};
const deerService = createServices(
{
listMy: {
url: '/my/upload/list',
},
listFav: {
url: '/my/star/list',
},
listPub: {
url: '/list',
},
},
{
baseURL: 'https://febase-openapi.fn.netease.com/deer/api/deer/pic',
withCredentials: false, // 解决跨域时必须非*问题
headers: {
'Febase-Auth': 'dskPVkIRnQ2dEn1DbyxURmUj4rl4BsCh53xFAsJnvVs=',
},
},
);
const context = {
stores: {
app: {
title: 'Sample App',
age: 20,
detail: {
foo: 'foo',
bar: 'bar',
biz: {
x: 'xxx',
},
},
newKey: 'xxx',
},
foo: {
test: 'test string',
},
},
};
/**
* 表单值预览
*/
@@ -310,9 +226,7 @@ export function Basic() {
const model = new FormModel(
{
router: 'www.163.com',
expression: {
foo: 'foo',
},
expression: `{ foo: 'foo' }`,
object: {
name: 'Alice',
},
@@ -324,19 +238,7 @@ export function Basic() {
return (
<Box display="flex">
<SettingForm
model={model}
remoteServices={{
ImageService: deerService as any,
}}
prototype={prototype}
evaluateContext={{
tango: context,
__UNSAFE_TANGO_CURRENT_PAGE_RENDER_RUNTIME__: { routeData: { params: {}, query: {} } },
}}
modelVariables={modelVariables}
expressionVariables={modelVariables}
/>
<SettingForm model={model} prototype={prototype} />
<Box position="relative">
<Card title="表单状态预览" style={{ position: 'sticky', top: 0 }}>
<FormValuePreview model={model} />
@@ -346,6 +248,14 @@ export function Basic() {
);
}
export function Lite() {
return (
<Box width={320} border="solid">
<SettingForm showSearch={false} showGroups={false} prototype={prototype} />
</Box>
);
}
export function NoExpressionSwitch() {
const model = new FormModel({});
return (
@@ -354,30 +264,3 @@ export function NoExpressionSwitch() {
</Box>
);
}
export function Binding() {
const [data, setData] = useState<any>({});
return (
<Box>
<Box as="code" bg="highlight" color="white" fontSize="24px">
selected: {data?.key}
</Box>
<EditableVariableTree
dataSource={modelVariables as any}
getPreviewValue={(node) => {
if (!node || !node.key) {
return;
}
if (node.type === 'function') {
return node.raw;
}
const keyPath = node.key.replaceAll('?', '');
return getValue(context, keyPath);
}}
onSelect={setData}
onAddVariable={console.log}
onSave={console.log}
/>
</Box>
);
}
+57 -12
View File
@@ -1,6 +1,6 @@
import React from 'react';
import { ToggleButton, IconFont } from '@music163/tango-ui';
import { Box, Flex } from 'coral-system';
import { ToggleButton, UndoOutlined, RedoOutlined } from '@music163/tango-ui';
import { Box, Group, Flex } from 'coral-system';
export default {
title: 'UI/ToggleButton',
@@ -9,28 +9,73 @@ export default {
export function Basic() {
return (
<Box>
<Flex gap="l" bg="#efefef" p="l">
<Box display="flex" columnGap="l" p="l">
<ToggleButton>
<IconFont type="icon-undo" />
<UndoOutlined />
</ToggleButton>
<ToggleButton selected>
<IconFont type="icon-redo" />
<RedoOutlined />
</ToggleButton>
<ToggleButton disabled>
<IconFont type="icon-redo" />
<RedoOutlined />
</ToggleButton>
</Box>
<Box display="flex" columnGap="l" p="l">
<ToggleButton type="primary">
<UndoOutlined />
</ToggleButton>
<ToggleButton type="primary" selected>
<RedoOutlined />
</ToggleButton>
<ToggleButton type="primary" disabled>
<RedoOutlined />
</ToggleButton>
</Box>
</Box>
);
}
export function DarkMode() {
return (
<Box>
<Flex gap="l" bg="#222" p="l">
<ToggleButton shape="ghost">
<UndoOutlined />
</ToggleButton>
<ToggleButton shape="ghost" selected>
<RedoOutlined />
</ToggleButton>
<ToggleButton shape="ghost" disabled>
<UndoOutlined />
</ToggleButton>
</Flex>
<Flex gap="l" bg="#222" p="l">
<ToggleButton shape="ghost">
<IconFont type="icon-undo" />
<ToggleButton shape="text">
<UndoOutlined />
</ToggleButton>
<ToggleButton shape="ghost" selected>
<IconFont type="icon-redo" />
<ToggleButton shape="text" selected>
<RedoOutlined />
</ToggleButton>
<ToggleButton shape="ghost" disabled>
<IconFont type="icon-undo" />
<ToggleButton shape="text" disabled>
<RedoOutlined />
</ToggleButton>
</Flex>
</Box>
);
}
export function ButtonGroup() {
return (
<Group attached>
<ToggleButton>
<UndoOutlined />
</ToggleButton>
<ToggleButton selected>
<RedoOutlined />
</ToggleButton>
<ToggleButton disabled>
<RedoOutlined />
</ToggleButton>
</Group>
);
}
-1
View File
@@ -1,6 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "independent",
"packages": ["packages/*"],
"npmClient": "yarn",
+22 -18
View File
@@ -6,7 +6,7 @@
"apps/*"
],
"scripts": {
"start": "yarn workspace playground start",
"start": "yarn workspace playground dev",
"start:docs": "yarn workspace storybook storybook",
"start:site": "yarn workspace website start",
"deploy:site": "yarn workspace website deploy",
@@ -18,18 +18,19 @@
"test:watch": "jest --watch",
"eslint": "eslint packages/**/src/*.{ts,tsx} --cache",
"publish": "lerna publish",
"ver": "lerna version --no-private --conventional-commits",
"release": "yarn eslint && yarn build && yarn run ver && lerna publish from-git",
"ver": "lerna version --no-private",
"release": "yarn eslint && yarn build && lerna version --no-private --conventional-commits && lerna publish from-git",
"release:npm": "yarn eslint && yarn build && yarn run ver && lerna publish from-git",
"release:beta": "yarn eslint && yarn build && yarn run ver && lerna publish from-package --dist-tag beta",
"up": "yarn upgrade-interactive --latest",
"prepare": "husky install"
},
"devDependencies": {
"@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.23.2",
"@commitlint/cli": "^17.5.0",
"@commitlint/config-conventional": "^17.3.0",
"@babel/preset-env": "^7.23.6",
"@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "^7.23.3",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@types/jest": "^29.5.7",
"@types/lodash-es": "^4.17.10",
"@types/lodash.get": "^4.4.8",
@@ -38,13 +39,13 @@
"@types/react": "^18.2.34",
"@types/react-dom": "^18.2.14",
"@types/styled-components": "^5.1.29",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"conventional-changelog-cli": "^2.2.2",
"@typescript-eslint/eslint-plugin": "^6.13.2",
"@typescript-eslint/parser": "^6.13.2",
"conventional-changelog-cli": "^4.1.0",
"copyfiles": "^2.4.1",
"eslint": "^8.52.0",
"eslint": "^8.55.0",
"eslint-config-ali": "^14.0.2",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-react": "^7.33.2",
@@ -53,14 +54,17 @@
"husky": "^8.0.3",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"lerna": "^6.6.1",
"lint-staged": "^14.0.1",
"prettier": "^2.8.7",
"lerna": "^8.0.0",
"lint-staged": "^15.2.0",
"prettier": "^3.1.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"styled-components": "^5.3.6",
"typedoc": "^0.25.3",
"typescript": "^5.2.2"
"typedoc": "^0.25.4",
"typescript": "^5.3.3"
},
"engines": {
"node": ">=18"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-context@0.2.12...@music163/tango-context@1.0.0-alpha.1) (2023-12-12)
**Note:** Version bump only for package @music163/tango-context
## [0.2.12](https://github.com/netease/tango/compare/@music163/tango-context@0.2.11...@music163/tango-context@0.2.12) (2023-12-04)
**Note:** Version bump only for package @music163/tango-context
## [0.2.11](https://github.com/netease/tango/compare/@music163/tango-context@0.2.10...@music163/tango-context@0.2.11) (2023-12-04)
**Note:** Version bump only for package @music163/tango-context
## [0.2.10](https://github.com/netease/tango/compare/@music163/tango-context@0.2.9...@music163/tango-context@0.2.10) (2023-11-30)
**Note:** Version bump only for package @music163/tango-context
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-context",
"version": "0.2.10",
"version": "1.0.0-alpha.1",
"description": "react context for tango-apps",
"keywords": [
"react",
@@ -31,9 +31,9 @@
"react": ">= 16.8"
},
"dependencies": {
"@music163/tango-core": "^0.2.9",
"@music163/tango-core": "^1.0.0-alpha.1",
"@music163/tango-helpers": "^0.1.8",
"mobx-react-lite": "4.0.2"
"mobx-react-lite": "4.0.5"
},
"publishConfig": {
"access": "public",
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-core@0.2.11...@music163/tango-core@1.0.0-alpha.1) (2023-12-12)
**Note:** Version bump only for package @music163/tango-core
## [0.2.11](https://github.com/netease/tango/compare/@music163/tango-core@0.2.10...@music163/tango-core@0.2.11) (2023-12-04)
### Bug Fixes
- update FileType ([c884712](https://github.com/netease/tango/commit/c8847123312bc47ea06575f4e714dfd596893e39))
## [0.2.10](https://github.com/netease/tango/compare/@music163/tango-core@0.2.9...@music163/tango-core@0.2.10) (2023-12-04)
### Bug Fixes
- add filesFormatter to sandbox & fix update props with imports ([#71](https://github.com/netease/tango/issues/71)) ([138cbe9](https://github.com/netease/tango/commit/138cbe9b203b370aff42c1ae8086d69edacf35e9))
## [0.2.9](https://github.com/netease/tango/compare/@music163/tango-core@0.2.8...@music163/tango-core@0.2.9) (2023-11-30)
### Bug Fixes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-core",
"version": "0.2.9",
"version": "1.0.0-alpha.1",
"description": "tango core",
"author": "wwsun <ww.sun@outlook.com>",
"homepage": "",
@@ -24,14 +24,14 @@
"prepublishOnly": "yarn build"
},
"dependencies": {
"@babel/generator": "^7.23.0",
"@babel/parser": "^7.23.0",
"@babel/traverse": "^7.23.2",
"@babel/types": "^7.23.0",
"@babel/generator": "^7.23.5",
"@babel/parser": "^7.23.5",
"@babel/traverse": "^7.23.5",
"@babel/types": "^7.23.5",
"@music163/tango-helpers": "^0.1.8",
"@types/babel__generator": "^7.6.6",
"@types/babel__traverse": "^7.20.3",
"mobx": "6.9.0",
"@types/babel__generator": "^7.6.7",
"@types/babel__traverse": "^7.20.4",
"mobx": "6.12.0",
"path-browserify": "^1.0.1"
},
"peerDependencies": {
+1 -1
View File
@@ -4,5 +4,5 @@ export * from './helpers';
export * from './types';
export { default as generator } from '@babel/generator';
export { default as traverse } from '@babel/types';
export { default as traverse } from '@babel/traverse';
export * from '@babel/parser';
+16 -2
View File
@@ -307,10 +307,24 @@ export class TangoViewModule extends TangoModule implements IViewFile {
updateNodeAttributes(nodeId: string, config: Record<string, any>, relatedImports?: string[]) {
if (relatedImports && relatedImports.length) {
// 导入依赖的组件
relatedImports.forEach((name: string) => {
const newImportData = relatedImports.reduce((prev, name) => {
const proto = this.workspace.getPrototype(name);
const { source, specifiers } = prototype2importDeclarationData(proto, this.filename);
this.addImportSpecifiers(source, specifiers);
const existSpecifiers: IImportSpecifierData[] = prev[source];
if (existSpecifiers) {
// merge specifiers
specifiers.forEach((item) => {
if (!existSpecifiers.find((existItem) => existItem.localName === item.localName)) {
existSpecifiers.push(item);
}
});
} else {
prev[source] = specifiers;
}
return prev;
}, {});
Object.keys(newImportData).forEach((source) => {
this.addImportSpecifiers(source, newImportData[source]);
});
}
this.ast = updateJSXAttributes(this.ast, nodeId, config);
+1 -1
View File
@@ -94,7 +94,7 @@ export class Workspace extends EventTarget implements IWorkspace {
/**
* 本地区块 { [blockName]: filePath }
* FIXME: 修正类型 Record<string, TangoBlockModule>
* TODO: 废弃这个,不再支持
*/
localBlocks: Record<string, string>;
+10 -1
View File
@@ -10,11 +10,20 @@ export enum FileType {
Module = 'module',
StoreEntryModule = 'storeEntryModule',
RouteModule = 'routeModule',
BlockEntryModule = 'blockEntryModule',
ServiceModule = 'serviceModule',
StoreModule = 'storeModule',
// 组件配置文件
ComponentPrototypeModule = 'componentPrototypeModule',
// 组件运行调试入口文件,一般为 `/app.js`
ComponentDemoEntryModule = 'componentDemoEntryModule',
// 区块入口文件 FIXME: 是否移除
BlockEntryModule = 'blockEntryModule',
// jsx 类型视图文件
JsxViewModule = 'jsxViewModule',
// json 类型视图文件
JsonViewModule = 'jsonViewModule',
// 非 js 文件
+23
View File
@@ -3,6 +3,29 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.2](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.0-alpha.1...@music163/tango-designer@1.0.0-alpha.2) (2023-12-13)
### Bug Fixes
- update variable tree with help messages and styling & add tangoConfig schema ([5e7e285](https://github.com/netease/tango/commit/5e7e285452b46888b447991b0e8548b6392acb3a))
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.14...@music163/tango-designer@1.0.0-alpha.1) (2023-12-12)
### Bug Fixes
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
## [0.5.14](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.13...@music163/tango-designer@0.5.14) (2023-12-04)
**Note:** Version bump only for package @music163/tango-designer
## [0.5.13](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.12...@music163/tango-designer@0.5.13) (2023-12-04)
### Bug Fixes
- add filesFormatter to sandbox & fix update props with imports ([#71](https://github.com/netease/tango/issues/71)) ([138cbe9](https://github.com/netease/tango/commit/138cbe9b203b370aff42c1ae8086d69edacf35e9))
## [0.5.12](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.11...@music163/tango-designer@0.5.12) (2023-11-30)
### Bug Fixes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-designer",
"version": "0.5.12",
"version": "1.0.0-alpha.2",
"description": "lowcode designer",
"keywords": [
"react"
@@ -33,12 +33,12 @@
"dependencies": {
"@ant-design/icons": "^4.8.0",
"@music163/request": "^0.1.2",
"@music163/tango-context": "^0.2.10",
"@music163/tango-core": "^0.2.9",
"@music163/tango-context": "^1.0.0-alpha.1",
"@music163/tango-core": "^1.0.0-alpha.1",
"@music163/tango-helpers": "^0.1.8",
"@music163/tango-sandbox": "^0.1.14",
"@music163/tango-setting-form": "^0.2.14",
"@music163/tango-ui": "^0.1.12",
"@music163/tango-sandbox": "^1.0.0-alpha.1",
"@music163/tango-setting-form": "^1.0.0-alpha.1",
"@music163/tango-ui": "^1.0.0-alpha.1",
"antd": "^4.24.2",
"cash-dom": "^8.1.2",
"classnames": "^2.3.2",
@@ -11,6 +11,7 @@ import {
Empty,
Popconfirm,
Tooltip,
Alert,
} from 'antd';
import { Box, Text, css } from 'coral-system';
import {
@@ -166,7 +167,7 @@ export function EditableVariableTree({
height={height}
position="relative"
>
<Box p="l" width="40%" borderRight="solid" borderColor="line.normal">
<Box p="l" width="40%">
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
<Input.Group compact>
<Search
@@ -201,68 +202,75 @@ export function EditableVariableTree({
/>
</Box>
{node ? (
<Panel
title={
{
preview: '变量值预览',
add: '添加变量',
define: '变量定义',
}[mode]
}
extra={
hasPanelSwitch && mode !== 'add' ? (
<Radio.Group
optionType="button"
buttonStyle="solid"
size="small"
value={mode}
onChange={(e) => setMode(e.target.value)}
options={previewOptions}
<Box width="60%" position="sticky" top="0">
{node.help && (
<Alert
type="info"
message={`使用说明:${node.help}`}
closable
style={{ marginBottom: 12 }}
/>
)}
<Panel
shape="solid"
title={
{
preview: '变量值预览',
add: '添加变量',
define: '变量定义',
}[mode]
}
extra={
hasPanelSwitch && mode !== 'add' ? (
<Radio.Group
optionType="button"
buttonStyle="solid"
size="small"
value={mode}
onChange={(e) => setMode(e.target.value)}
options={previewOptions}
/>
) : null
}
bodyProps={{ px: 'm' }}
>
{mode === 'preview' && (
<ValuePreview
value={getPreviewValue(node)}
onSelect={(valuePath) => {
return ['tango', node.key.replaceAll('.', '?.'), valuePath].join('.');
}}
/>
) : null
}
width="60%"
borderRadius="m"
position="sticky"
top="0"
bodyProps={{ px: 'm' }}
>
{mode === 'preview' && (
<ValuePreview
value={getPreviewValue(node)}
onSelect={(valuePath) => {
return ['tango', node.key.replaceAll('.', '?.'), valuePath].join('.');
}}
/>
)}
{mode === 'define' && (
<NodeDefineForm
node={node}
onSave={onSave}
onDelete={(item) => {
const [type, storeName, stateName] = item.key.split('.');
onDeleteVariable(storeName, stateName);
setNode(null);
}}
/>
)}
{mode === 'add' && (
<AddNodeForm
parentNode={node}
onCancel={() => {
setMode(defaultMode);
setNode(null);
}}
onSubmit={(storeName, data) => {
onAddVariable(storeName, data);
setMode(defaultMode);
setNode(null);
}}
/>
)}
</Panel>
)}
{mode === 'define' && (
<NodeDefineForm
node={node}
onSave={onSave}
onDelete={(item) => {
const [type, storeName, stateName] = item.key.split('.');
onDeleteVariable(storeName, stateName);
setNode(null);
}}
/>
)}
{mode === 'add' && (
<AddNodeForm
parentNode={node}
onCancel={() => {
setMode(defaultMode);
setNode(null);
}}
onSubmit={(storeName, data) => {
onAddVariable(storeName, data);
setMode(defaultMode);
setNode(null);
}}
/>
)}
</Panel>
</Box>
) : (
<Panel title="提示" flex="1" position="sticky" top="0">
<Panel shape="solid" title="提示" flex="1" position="sticky" top="0">
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请从左侧列表中选择一个变量" />
</Panel>
)}
@@ -469,11 +477,11 @@ interface NodePreviewProps {
export function ValuePreview({ value, onSelect }: NodePreviewProps) {
if (isNil(value)) {
return <span></span>;
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂时没有可预览的数据" />;
}
if (isFunction(value)) {
return <span></span>;
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂不支持预览函数" />;
}
if (typeof value === 'object') {
@@ -503,7 +511,7 @@ function NodeDefineForm({ node, onSave = noop, onDelete = noop }: NodeDefineProp
const [error, setError] = useState('');
const [editable, { on, off }] = useBoolean();
if (isNil(node.raw)) {
return <Empty description="缺失定义数据" />;
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="缺失定义数据" />;
}
return (
<Box>
+13
View File
@@ -23,6 +23,12 @@ export type SandboxProps = Omit<CodeSandboxProps, 'files' | 'eventHandlers' | 'o
* tangoConfigJson 处理器
*/
configFormatter?: IMergeTangoConfigJsonConfig['formatter'];
/**
* 文件格式化器
* @param files 沙箱文件列表
* @returns 修改后的文件列表
*/
filesFormatter?: (files: CodeSandboxProps['files']) => CodeSandboxProps['files'];
sandboxType?: 'design' | 'preview';
mode?: 'single' | 'combined';
injectScript?: string;
@@ -41,6 +47,7 @@ const LANDING_PAGE_PATH = '/__background_landing_page__';
function useSandbox({
isPreview: isPreviewProp,
configFormatter,
filesFormatter,
onViewChange,
onMessage: onMessageProp,
onLoad: onLoadProp,
@@ -79,7 +86,12 @@ function useSandbox({
prev[filename] = { code };
return prev;
}, {});
files = fixSandboxFiles(files, workspace.entry);
if (filesFormatter) {
// 支持用户对传入的文件进行修改
files = filesFormatter(files);
}
const onMessage = (data: any) => onMessageProp && onMessageProp(data, getSandboxConfig());
const onLoad = () => onLoadProp && onLoadProp(getSandboxConfig());
@@ -413,6 +425,7 @@ function fixSandboxFiles(files: Record<string, { code: string }>, entry = '/src/
`,
};
}
return files;
}
+3 -1
View File
@@ -168,4 +168,6 @@ const setters: IFormItemCreateOptions[] = [
{ name: 'borderSetter', component: BorderSetter },
];
setters.forEach(register);
export function registerBuiltinSetters() {
setters.forEach(register);
}
+3 -1
View File
@@ -4,7 +4,9 @@ import { SettingForm, FormModel, SettingFormProps } from '@music163/tango-settin
import { Panel } from '@music163/tango-ui';
import { clone } from '@music163/tango-helpers';
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
import './setters';
import { registerBuiltinSetters } from './setters';
registerBuiltinSetters();
export interface SettingPanelProps extends SettingFormProps {
title?: React.ReactNode;
@@ -1,9 +1,9 @@
import React, { useState, useEffect, useMemo } from 'react';
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
import { Box, css } from 'coral-system';
import { Button, FormProps, Empty, Space, Dropdown } from 'antd';
import { Button, FormProps, Empty, Space, Dropdown, Form, Select, Input } from 'antd';
import { PlayCircleOutlined } from '@ant-design/icons';
import { Form, InputCode, Panel, JsonView, Search } from '@music163/tango-ui';
import { InputCode, Panel, JsonView, Search } from '@music163/tango-ui';
import {
isNil,
getVariableContent,
@@ -37,15 +37,6 @@ enum ServiceFunctionMethodType {
// DELETE = 'DELETE',
}
/**
* requestType
* headers: Content-Type
*/
enum DataServiceRequestType {
'application/json' = 'json',
'application/x-www-form-urlencoded' = 'x-www-form-urlencoded',
}
/**
* 将 api 路径转换为默认的驼峰方法名
*/
@@ -79,12 +70,6 @@ const httpMethods = Object.keys(ServiceFunctionMethodType).map((key) => ({
value: key,
}));
// requestType 类型
const requestTypes = Object.keys(DataServiceRequestType).map((key) => ({
label: key,
value: DataServiceRequestType[key],
}));
const detailFormStyle = css`
.ant-form-item {
margin-bottom: 12px;
@@ -261,8 +246,8 @@ function ServiceDetailForm({
return (
<Form
form={form}
labelCol={6}
wrapperCol={17}
labelCol={{ span: 6 }}
wrapperCol={{ span: 17 }}
colon={false}
layout="horizontal"
initialValues={initialValues}
@@ -285,12 +270,9 @@ function ServiceDetailForm({
required: true,
},
]}
component="select"
componentProps={{
options: serviceModules,
disabled: disabled || isModifyMode,
}}
/>
>
<Select options={serviceModules} disabled={disabled || isModifyMode} />
</Form.Item>
<Form.Item
label="方法名"
name="name"
@@ -308,11 +290,6 @@ function ServiceDetailForm({
},
},
]}
component="input"
componentProps={{
placeholder: '请输入数据服务调用名称',
disabled: disabled || isModifyMode,
}}
extra={
!disabled &&
!isModifyMode && (
@@ -331,38 +308,15 @@ function ServiceDetailForm({
</Box>
)
}
/>
<Form.Item
label="路径"
name="url"
rules={[{ required: true, type: 'url' }]}
component="input"
componentProps={{
placeholder: '请输入数据服务调用名称',
disabled: disabled || isModifyMode,
}}
/>
<Form.Item
label="方法"
name="method"
component="select"
componentProps={{
options: httpMethods,
placeholder: '请选择 HTTP 请求方法',
disabled,
}}
/>
<Form.Item
label="编码类型"
name="requestType"
tooltip="设置请求头的 Content-Type,若不设置,则默认变为为 JSON"
component="select"
componentProps={{
options: requestTypes,
placeholder: '请求头Content-Type,默认为JSON',
disabled,
}}
/>
>
<Input placeholder="请输入数据服务调用名称" disabled={disabled || isModifyMode} />
</Form.Item>
<Form.Item label="路径" name="url" rules={[{ required: true, type: 'url' }]}>
<Input placeholder="请输入数据服务调用名称" disabled={disabled || isModifyMode} />
</Form.Item>
<Form.Item label="方法" name="method">
<Select options={httpMethods} placeholder="请选择 HTTP 请求方法" disabled={disabled} />
</Form.Item>
<Form.Item
label="格式化响应"
name="formatter"
@@ -1,8 +1,8 @@
import React from 'react';
import { Button, Space } from 'antd';
import { useBoolean } from '@music163/tango-helpers';
import { Panel, Form, IconButton } from '@music163/tango-ui';
import { Button, Space, Form, Input } from 'antd';
import { FileAddOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { useBoolean } from '@music163/tango-helpers';
import { Panel, IconButton } from '@music163/tango-ui';
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
import { EditableVariableTree, EditableVariableTreeProps } from '../components';
@@ -90,9 +90,10 @@ interface AddStoreFormProps {
function AddStoreForm({ existNames = [], onCancel, onSubmit }: AddStoreFormProps) {
return (
<Panel title="添加模型" subTitle="模型可以用来组织一组变量">
<Panel title="添加模型" subTitle="模型可以用来组织一组变量" bodyProps={{ p: 'l' }}>
<Form
autoComplete="off"
colon={false}
onFinish={(values) => {
onSubmit && onSubmit(values);
}}
@@ -112,11 +113,9 @@ function AddStoreForm({ existNames = [], onCancel, onSubmit }: AddStoreFormProps
},
},
]}
component="input"
componentProps={{
placeholder: '请输入模型名称',
}}
/>
>
<Input placeholder="请输入模型名称" />
</Form.Item>
<Form.Item label=" ">
<Space>
<Button onClick={onCancel}></Button>
+3 -3
View File
@@ -1,6 +1,6 @@
import React from 'react';
import { Box } from 'coral-system';
import { ToggleButton, IconFont } from '@music163/tango-ui';
import { ToggleButton, RedoOutlined, UndoOutlined } from '@music163/tango-ui';
import { observer, useWorkspace } from '@music163/tango-context';
export const HistoryTool = observer(() => {
@@ -16,7 +16,7 @@ export const HistoryTool = observer(() => {
workspace.selectSource.clear();
}}
>
<IconFont type="icon-undo" />
<UndoOutlined />
</ToggleButton>
<ToggleButton
shape="ghost"
@@ -27,7 +27,7 @@ export const HistoryTool = observer(() => {
workspace.selectSource.clear();
}}
>
<IconFont type="icon-redo" />
<RedoOutlined />
</ToggleButton>
</Box>
);
@@ -1,8 +1,9 @@
import React from 'react';
import { Group } from 'coral-system';
import { Modal } from 'antd';
import { ToggleButton } from '@music163/tango-ui';
import { ToggleButton, CodeOutlined } from '@music163/tango-ui';
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
import { BorderOutlined } from '@ant-design/icons';
export const ModeSwitchTool = observer(() => {
const workspace = useWorkspace();
@@ -17,7 +18,7 @@ export const ModeSwitchTool = observer(() => {
}}
tooltip="设计视图"
>
<BorderOutlined />
</ToggleButton>
<ToggleButton
shape="ghost"
@@ -36,7 +37,7 @@ export const ModeSwitchTool = observer(() => {
}}
tooltip="源码视图"
>
<CodeOutlined />
</ToggleButton>
</Group>
);
+9 -15
View File
@@ -1,10 +1,10 @@
import React, { useMemo, useState } from 'react';
import { Button, Popconfirm, Modal, ModalProps } from 'antd';
import { Button, Popconfirm, Modal, ModalProps, Form, Input } from 'antd';
import { Box, css, Group, Text } from 'coral-system';
import { FileOutlined, DeleteOutlined, CopyOutlined, SettingOutlined } from '@ant-design/icons';
import { array2object, callAll } from '@music163/tango-helpers';
import { IPageConfigData } from '@music163/tango-core';
import { Form, ToggleButton } from '@music163/tango-ui';
import { ToggleButton } from '@music163/tango-ui';
import { observer, useWorkspace } from '@music163/tango-context';
export const RouteSwitchTool = observer(() => {
@@ -250,17 +250,13 @@ function CopyViewModalForm({
}}
>
<Form
wrapperCol={20}
wrapperCol={{ span: 20 }}
form={form}
initialValues={{ name: current?.name, path: current?.path }}
>
<Form.Item
label="页面标题"
name="name"
required
component="input"
componentProps={{ placeholder: '请输入标题' }}
/>
<Form.Item label="页面标题" name="name" required>
<Input placeholder="请输入标题" />
</Form.Item>
<Form.Item
label="页面路由"
name="path"
@@ -281,11 +277,9 @@ function CopyViewModalForm({
message: '非法的路由地址',
},
]}
component="input"
componentProps={{
placeholder: '输入页面路由',
}}
/>
>
<Input placeholder="请输入页面路由" />
</Form.Item>
</Form>
</Modal>
);
+10 -9
View File
@@ -1,7 +1,13 @@
import React from 'react';
import { observer, useDesigner } from '@music163/tango-context';
import { Box } from 'coral-system';
import { IconFont, ToggleButton } from '@music163/tango-ui';
import {
OpenPanelFilledLeftOutlined,
OpenPanelFilledRightOutlined,
OpenPanelLeftOutlined,
OpenPanelRightOutlined,
ToggleButton,
} from '@music163/tango-ui';
export const TogglePanelTool = observer(() => {
const designer = useDesigner();
@@ -14,20 +20,15 @@ export const TogglePanelTool = observer(() => {
designer.setActiveSidebarPanel(designer.activeSidebarPanel ? '' : 'outline');
}}
>
<IconFont
type={
designer.activeSidebarPanel ? 'icon-open-panel-filled-left' : 'icon-open-panel-left'
}
/>
{designer.activeSidebarPanel ? <OpenPanelFilledLeftOutlined /> : <OpenPanelLeftOutlined />}
</ToggleButton>
<ToggleButton
tooltip="隐藏/显示右侧面板"
shape="ghost"
onClick={() => designer.toggleRightPanel()}
disabled={designer.activeView === 'code'}
>
<IconFont
type={designer.showRightPanel ? 'icon-open-panel-filled-right' : 'icon-open-panel-right'}
/>
{designer.showRightPanel ? <OpenPanelFilledRightOutlined /> : <OpenPanelRightOutlined />}
</ToggleButton>
</Box>
);
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.16...@music163/tango-sandbox@1.0.0-alpha.1) (2023-12-12)
**Note:** Version bump only for package @music163/tango-sandbox
## [0.1.16](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.15...@music163/tango-sandbox@0.1.16) (2023-12-04)
**Note:** Version bump only for package @music163/tango-sandbox
## [0.1.15](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.14...@music163/tango-sandbox@0.1.15) (2023-12-04)
**Note:** Version bump only for package @music163/tango-sandbox
## [0.1.14](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.13...@music163/tango-sandbox@0.1.14) (2023-11-30)
**Note:** Version bump only for package @music163/tango-sandbox
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-sandbox",
"version": "0.1.14",
"version": "1.0.0-alpha.1",
"description": "sandbox of tango apps",
"author": "wwsun <ww.sun@outlook.com>",
"homepage": "",
@@ -29,7 +29,7 @@
},
"dependencies": {
"@ant-design/icons": "^4.8.0",
"@music163/tango-core": "^0.2.9",
"@music163/tango-core": "^1.0.0-alpha.1",
"@music163/tango-helpers": "^0.1.8",
"crypto-js": "^4.1.1",
"lodash.isequal": "4.5.0",
+15
View File
@@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.16...@music163/tango-setting-form@1.0.0-alpha.1) (2023-12-12)
### Bug Fixes
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
## [0.2.16](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.15...@music163/tango-setting-form@0.2.16) (2023-12-04)
**Note:** Version bump only for package @music163/tango-setting-form
## [0.2.15](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.14...@music163/tango-setting-form@0.2.15) (2023-12-04)
**Note:** Version bump only for package @music163/tango-setting-form
## [0.2.14](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.13...@music163/tango-setting-form@0.2.14) (2023-11-30)
**Note:** Version bump only for package @music163/tango-setting-form
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-setting-form",
"version": "0.2.14",
"version": "1.0.0-alpha.1",
"description": "setting form of tango-apps",
"author": "wwsun <ww.sun@outlook.com>",
"homepage": "",
@@ -28,13 +28,13 @@
},
"dependencies": {
"@ant-design/icons": "^4.8.0",
"@music163/tango-core": "^0.2.9",
"@music163/tango-core": "^1.0.0-alpha.1",
"@music163/tango-helpers": "^0.1.8",
"@music163/tango-ui": "^0.1.12",
"@music163/tango-ui": "^1.0.0-alpha.1",
"antd": "^4.24.2",
"coral-system": "^1.0.5",
"mobx": "6.9.0",
"mobx-react-lite": "4.0.2"
"mobx": "6.12.0",
"mobx-react-lite": "4.0.5"
},
"publishConfig": {
"access": "public",
+15 -16
View File
@@ -8,14 +8,15 @@ import {
useBoolean,
} from '@music163/tango-helpers';
import { isWrappedByExpressionContainer } from '@music163/tango-core';
import { IconFont, ToggleButton } from '@music163/tango-ui';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { InputProps, Tooltip } from 'antd';
import { ToggleButton, CodeOutlined } from '@music163/tango-ui';
import { InputProps } from 'antd';
import { useFormModel, useFormVariable } from './context';
import { FormControl } from './form-ui';
import { Box, Text } from 'coral-system';
export interface FormItemProps extends ComponentPropType {
extra?: React.ReactNode;
footer?: React.ReactNode;
}
export interface FormItemComponentProps<T = any> {
@@ -76,6 +77,7 @@ export function createFormItem(options: IFormItemCreateOptions) {
getVisible: getVisibleProp,
getSetterProps: getSetterPropsProp,
extra,
footer,
}: FormItemProps) {
const { disableSwitchExpressionSetter } = useFormVariable();
const model = useFormModel();
@@ -106,7 +108,7 @@ export function createFormItem(options: IFormItemCreateOptions) {
let expProps = {};
// FIXME: 重新考虑这段代码的位置
// FIXME: 重新考虑这段代码的位置,外置这个逻辑
if (['expressionSetter', 'actionSetter', 'eventSetter'].includes(setter) || isVariable) {
expProps = {
modalTitle: title,
@@ -141,7 +143,8 @@ export function createFormItem(options: IFormItemCreateOptions) {
docs={docs}
error={field.error}
extra={
<>
<Box>
{extra}
{!disableVariableSetter ? (
<ToggleButton
borderRadius="s"
@@ -153,12 +156,12 @@ export function createFormItem(options: IFormItemCreateOptions) {
selected={isVariable}
onClick={() => toggleIsVariable()}
>
<IconFont type="icon-brackets-curly" />
<CodeOutlined />
</ToggleButton>
) : null}
{extra}
</>
</Box>
}
footer={footer}
data-setter={setterName}
data-field={name}
>
@@ -187,10 +190,6 @@ export function register(config: IFormItemCreateOptions) {
});
}
const iconStyle = {
color: 'red',
};
export function SettingFormItem(props: FormItemProps) {
const { setter } = props;
const Comp = REGISTERED_FORM_ITEM_MAP[setter];
@@ -199,10 +198,10 @@ export function SettingFormItem(props: FormItemProps) {
return (
<Fallback
{...props}
extra={
<Tooltip title={`${props.name}: invalid setter ${props.setter}`}>
<QuestionCircleOutlined color="red" style={iconStyle} />
</Tooltip>
footer={
<Text color="red" mt="m">
{props.setter} is invalid
</Text>
}
/>
);
+3
View File
@@ -7,6 +7,7 @@ import { isNil, isString } from '@music163/tango-helpers';
export interface FormControlProps extends Omit<FormLabelProps, 'type'> {
visible: boolean;
extra?: React.ReactNode;
footer?: React.ReactNode;
error?: string;
children?: React.ReactNode;
}
@@ -18,6 +19,7 @@ export function FormControl({
tip,
docs,
extra,
footer,
error,
children,
...rest
@@ -29,6 +31,7 @@ export function FormControl({
{extra}
</Box>
<Box>{children}</Box>
{footer}
{!!error && (
<Box mt="m" color="red">
{error}
+36 -23
View File
@@ -83,7 +83,15 @@ export interface SettingFormProps {
*/
prototype?: ComponentPrototypeType;
/**
* 选项分组信息
* 是否显示搜索框
*/
showSearch?: boolean;
/**
* 是否显示分组导航
*/
showGroups?: boolean;
/**
* 选项分组信息,用于对表单项进行分组展示,如未提供,则使用内置的分组信息
*/
groupOptions?: IFormTabsGroupOption[];
/**
@@ -98,6 +106,8 @@ export function SettingForm({
model: modelProp,
defaultValue,
onChange = noop,
showSearch = true,
showGroups = true,
groupOptions = internalGroups,
}: SettingFormProps) {
const [keyword, setKeyword] = useState('');
@@ -107,10 +117,8 @@ export function SettingForm({
const componentPropGroups = useMemo(() => {
return normalizeComponentProps(componentProps);
}, [componentProps]);
const filterProps = useMemo(() => {
if (!keyword) {
return componentPropGroups[tabKey] || [];
}
const computedProps = mapTreeData(componentProps, (node) => {
const { getProp, ...rest } = node;
return {
@@ -118,8 +126,19 @@ export function SettingForm({
...getProp?.(model),
};
});
// 没有进行搜索的情况
if (!keyword) {
if (showGroups) {
return componentPropGroups[tabKey] || [];
} else {
return computedProps;
}
}
// 用户进行搜索的情况
return filterComponentProps(computedProps, keyword);
}, [keyword, componentProps, tabKey, model]);
}, [keyword, componentProps, tabKey, model, showGroups, componentPropGroups]);
const renderProps = useCallback(
(props: ComponentPropType[]) =>
@@ -129,15 +148,7 @@ export function SettingForm({
...rest,
...getProp?.(model),
};
const FormChild = isValidNestProps(childProto.props)
? SettingFormObject
: childProto.setter
? SettingFormItem
: null;
if (!FormChild) {
return null;
}
const FormChild = isValidNestProps(childProto.props) ? SettingFormObject : SettingFormItem;
return <FormChild key={item.name} {...childProto} />;
}),
[model],
@@ -155,15 +166,17 @@ export function SettingForm({
<FormModelProvider value={model}>
<Box className="SettingForm" mb="xl" css={formStyle}>
<Box className="SettingFormHeader" position="sticky" top="0" bg="white" zIndex="2">
<Box className="SettingFormSearch" px="l" py="m">
<Search
placeholder="搜索属性"
onChange={(val) => {
setKeyword(val?.trim());
}}
/>
</Box>
{!keyword && (
{showSearch && (
<Box className="SettingFormSearch" px="l" py="m">
<Search
placeholder="搜索属性"
onChange={(val) => {
setKeyword(val?.trim());
}}
/>
</Box>
)}
{!keyword && showGroups && (
<Box className="SettingFormNav">
<Tabs activeKey={tabKey} onChange={setTabKey}>
{groupOptions.map((group) => (
+6 -1
View File
@@ -1,5 +1,5 @@
import { register } from './form-item';
import { ExpressionSetter } from './setter';
import { ExpressionSetter, TextSetter } from './setter';
// 预注册基础 Setter
register({
@@ -7,6 +7,11 @@ register({
component: ExpressionSetter,
});
register({
name: 'textSetter',
component: TextSetter,
});
export * from './form';
export * from './form-item';
export * from './form-object';
+8 -3
View File
@@ -1,7 +1,12 @@
import React from 'react';
import { Input } from 'antd';
import { InputCode } from '@music163/tango-ui';
import { FormItemComponentProps } from './form-item';
// TODO: 内置基本的 ExpressionSetter,默认全部 fallback 到此 setter
export function ExpressionSetter(props: FormItemComponentProps<string>) {
return <div>exp setter</div>;
export function ExpressionSetter({ value, onChange, ...rest }: FormItemComponentProps<string>) {
return <InputCode onChange={(val) => onChange?.(val)} value={value || ''} {...rest} />;
}
export function TextSetter({ onChange, ...rest }: FormItemComponentProps<string>) {
return <Input onChange={(e) => onChange?.(e.target.value)} {...rest} />;
}
+10
View File
@@ -0,0 +1,10 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 1.0.2 (2023-12-13)
### Bug Fixes
- update variable tree with help messages and styling & add tangoConfig schema ([5e7e285](https://github.com/NetEase/tango/commit/5e7e285452b46888b447991b0e8548b6392acb3a))
+3
View File
@@ -0,0 +1,3 @@
# Tango Config Spec
This is the specification for the Tango Config format.
+27
View File
@@ -0,0 +1,27 @@
{
"name": "tango-spec",
"version": "1.0.2",
"description": "tango config spec",
"keywords": [
"json",
"schema"
],
"author": "wwsun <ww.sww@outlook.com>",
"homepage": "https://github.com/NetEase/tango#readme",
"license": "MIT",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/NetEase/tango.git"
},
"scripts": {
"test": "node ./__tests__/spec.test.js"
},
"bugs": {
"url": "https://github.com/NetEase/tango/issues"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
+118
View File
@@ -0,0 +1,118 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://unpkg.com/tango-spec/tango-config.json",
"title": "JSON Schema of tango.config.json",
"description": "tango.config.json is a configuration file for NetEase Tango apps",
"type": "object",
"properties": {
"packages": {
"type": "object",
"patternProperties": {
"^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "package description"
},
"version": {
"type": "string",
"description": "package version"
},
"library": {
"type": "string",
"description": "package library"
},
"type": {
"type": "string",
"description": "package type",
"enum": ["dependency", "bizDependency", "baseDependency"]
},
"resources": {
"type": "array",
"items": {
"type": "string"
},
"description": "package resources"
},
"designerResources": {
"type": "array",
"items": {
"type": "string"
},
"description": "package designer resources"
}
},
"additionalProperties": false,
"required": ["version", "library"]
}
},
"additionalProperties": false
},
"dataSource": {
"type": "object",
"properties": {
"ox": {
"type": "object",
"description": "music ox data provider",
"properties": {
"key": {
"type": "string",
"description": "dataSource provider name"
},
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"app": {
"type": "string",
"description": "app name"
},
"branch": {
"type": "string",
"description": "branch name"
}
},
"additionalProperties": false,
"required": ["app", "branch"]
}
}
}
}
}
},
"proxy": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "the path of proxy rule"
},
"value": {
"type": "object",
"properties": {
"target": {
"type": "string",
"description": "the target of proxy rule"
},
"changeOrigin": {
"type": "boolean",
"description": "whether change origin of proxy rule"
}
},
"additionalProperties": false,
"required": ["target"]
}
}
},
"externalResources": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": true,
"required": ["packages"]
}
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-ui@0.1.12...@music163/tango-ui@1.0.0-alpha.1) (2023-12-12)
### Bug Fixes
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
- disable search keymap of InputCode ([#72](https://github.com/netease/tango/issues/72)) ([9db6358](https://github.com/netease/tango/commit/9db635858876ee0b9612e4b2ccd996280fc35d3b))
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
## [0.1.12](https://github.com/netease/tango/compare/@music163/tango-ui@0.1.11...@music163/tango-ui@0.1.12) (2023-11-28)
### Bug Fixes
+4 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@music163/tango-ui",
"version": "0.1.12",
"version": "1.0.0-alpha.1",
"description": "ui widgets of tango",
"keywords": [
"react",
@@ -34,14 +34,13 @@
},
"dependencies": {
"@ant-design/icons": "^4.8.0",
"@codemirror/autocomplete": "^6.10.2",
"@codemirror/autocomplete": "^6.11.1",
"@codemirror/lang-javascript": "^6.2.1",
"@codemirror/lint": "^6.4.2",
"@codemirror/search": "^6.5.4",
"@codemirror/search": "^6.5.5",
"@music163/tango-helpers": "^0.1.8",
"@uiw/react-codemirror": "^4.21.20",
"@uiw/react-codemirror": "^4.21.21",
"antd": "^4.24.2",
"antd-easy-form": "^1.1.3",
"coral-system": "^1.0.5",
"eslint-linter-browserify": "^8.51.0",
"react-json-view": "^1.21.3",
+22
View File
@@ -0,0 +1,22 @@
import React from 'react';
import { createIcon } from './create-icon';
const CodeOutlinedSvg = () => (
<svg
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="m31 16-7 7-1.41-1.41 5.58-5.59-5.58-5.59 1.41-1.41z" />
<path d="m1 16 7-7 1.41 1.41-5.58 5.59 5.58 5.59-1.41 1.41z" />
<path
d="m5.91 15h20.17v2h-20.17z"
transform="matrix(.25881905 -.96592583 .96592583 .25881905 -3.6 27.31)"
/>
<path d="m0 0h32v32h-32z" fill="none" transform="matrix(0 -1 1 0 0 32)" />
</svg>
);
export const CodeOutlined = createIcon(CodeOutlinedSvg, 'CodeOutlined');
+13
View File
@@ -0,0 +1,13 @@
import React from 'react';
import Icon from '@ant-design/icons';
import type { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
export function createIcon(component: React.ComponentType<any>, displayName?: string) {
const CustomIcon = (props: Partial<CustomIconComponentProps>) => (
<Icon component={component} {...props} />
);
if (displayName) {
CustomIcon.displayName = displayName;
}
return CustomIcon;
}
+8
View File
@@ -0,0 +1,8 @@
export * from './create-icon';
export * from './code-outlined';
export * from './open-panel-filled-left-outlined';
export * from './open-panel-filled-right-outlined';
export * from './open-panel-left-outlined';
export * from './open-panel-right-outlined';
export * from './undo-outlined';
export * from './redo-outlined';
@@ -0,0 +1,20 @@
import React from 'react';
import { createIcon } from './create-icon';
const OpenPanelFilledLeftOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm0 22h-16v-20h16z" />
<path d="m0 0h32v32h-32z" fill="none" />
</svg>
);
export const OpenPanelFilledLeftOutlined = createIcon(
OpenPanelFilledLeftOutlinedSvg,
'OpenPanelFilledLeftOutlined',
);
@@ -0,0 +1,20 @@
import React from 'react';
import { createIcon } from './create-icon';
const OpenPanelFilledRightOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h16v20h-16z" />
<path d="m0 0h32v32h-32z" fill="none" />
</svg>
);
export const OpenPanelFilledRightOutlined = createIcon(
OpenPanelFilledRightOutlinedSvg,
'OpenPanelFilledRightOutlined',
);
@@ -0,0 +1,17 @@
import React from 'react';
import { createIcon } from './create-icon';
const OpenPanelLeftOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h6v20h-6zm24 20h-16v-20h16z" />
<path d="m0 0h32v32h-32z" fill="none" />
</svg>
);
export const OpenPanelLeftOutlined = createIcon(OpenPanelLeftOutlinedSvg, 'OpenPanelLeftOutlined');
@@ -0,0 +1,20 @@
import React from 'react';
import { createIcon } from './create-icon';
const OpenPanelRightOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h16v20h-16zm24 20h-6v-20h6z" />
<path d="m0 0h32v32h-32z" fill="none" />
</svg>
);
export const OpenPanelRightOutlined = createIcon(
OpenPanelRightOutlinedSvg,
'OpenPanelRightOutlined',
);
+16
View File
@@ -0,0 +1,16 @@
import React from 'react';
import { createIcon } from './create-icon';
const RedoOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m12 10h12.1851l-3.5874-3.5859 1.4023-1.4141 6 6-6 6-1.4023-1.4146 3.5844-3.5854h-12.1821a6 6 0 0 0 0 12h8v2h-8a8 8 0 0 1 0-16z" />
</svg>
);
export const RedoOutlined = createIcon(RedoOutlinedSvg, 'RedoOutlined');
+16
View File
@@ -0,0 +1,16 @@
import React from 'react';
import { createIcon } from './create-icon';
const UndoOutlinedSvg = () => (
<svg
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m20 10h-12.1851l3.5874-3.5859-1.4023-1.4141-6 6 6 6 1.4023-1.4146-3.5844-3.5854h12.1821a6 6 0 0 1 0 12h-8v2h8a8 8 0 0 0 0-16z" />
</svg>
);
export const UndoOutlined = createIcon(UndoOutlinedSvg, 'UndoOutlined');
+1 -1
View File
@@ -1,3 +1,4 @@
export * from './icons';
export * from './action-select';
export * from './code-editor';
export * from './chat-input';
@@ -19,4 +20,3 @@ export * from './tabs';
export * from './select-action';
export * from './copy-clipboard';
export * from './tag-select';
export { Form } from 'antd-easy-form';
+2 -1
View File
@@ -153,12 +153,12 @@ export function InputCode({
autocomplete: buildAutoComplete(autoCompleteContext, options),
});
}, [autoCompleteContext, autoCompleteOptions]);
const { rootStyle, codeSetup } = useInputCode({ shape, status, showLineNumbers, showFoldGutter });
const extensions = [javascript({ jsx: true }), globalJavaScriptCompletions];
if (enableESLint) {
// @ts-ignore
extensions.push(lintGutter(), linter(esLint(new eslint.Linter(), eslintConfig)));
}
const { rootStyle, codeSetup } = useInputCode({ shape, status, showLineNumbers, showFoldGutter });
return (
<Box className="InputCode" display="flex" alignItems="center" overflow="hidden" {...rootStyle}>
@@ -194,6 +194,7 @@ function useInputCode({
codeSetup: {
lineNumbers: showLineNumbers ?? lineNumbers,
foldGutter: showFoldGutter ?? foldGutter,
searchKeymap: false, // 默认关闭搜索快捷键,原因:https://github.com/uiwjs/react-codemirror/issues/280
},
};
}
+5 -5
View File
@@ -64,18 +64,18 @@ const buttonStyle = css`
&.shape-outline {
background-color: #fff;
border: 1px solid #d9d9d9;
border: 1px solid var(--tango-colors-line2);
border-radius: var(--tango-radii-s);
&.disabled {
color: rgba(0, 0, 0, 0.25);
background-color: #f5f5f5;
color: var(--tango-colors-text4);
background-color: var(--tango-colors-fill1);
}
&.selected.type-normal {
color: var(--tango-colors-gray-100);
background-color: var(--tango-colors-gray-30);
border-color: var(--tango-colors-gray-30);
background-color: var(--tango-colors-fill3);
border-color: var(--tango-colors-line2);
}
&.selected.type-primary {
+3795 -2332
View File
File diff suppressed because it is too large Load Diff