# UI plugin development
2.9.0+# Initialization the plugin
You can quickly create a UI plugin via create-umi:
# npx create-umi --type=plugin
$ yarn create umi --type=plugin
In the final step, whether or not you have Y
in the Umi UI` option, you have created a umi plugin with UI interaction.
After initializing the UI plugin, the directory structure is as follows:
- root
- src // server-side code
- index.js // plugin entry
- ui
- index.js // client UI entry
- package.json // plugin dependencies and other information
- example // UI test directory
In the plugin directory, install dependencies.
# npm install
$ yarn install
# Development plugin
As with the normal plugin, after installing the dependencies, execute the following command:
# npm run build && npm run start
$ yarn build && yarn start
At this point, you can see that UmiUI is up.
The example
project is the test project. Click on the entry and you will see the UI plugin on the left menu.
ui/index.js
is responsible for the display of the UI plugin. You can use the Umi UI Client API, development plugin.
WARNING
Umi UI uses antd 4.x for development and external for antd.
Please refer to antd 4.x documentation when developing plugin UI.
import { Button } from 'antd';
export default (api) => {
const { callRemote } = api;
function PluginPanel() {
return (
<div style={{ padding: 20 }}>
<Button
type="primary"
onClick={async () => {
const { data } = await callRemote({
type: 'org..umi-dev.test',
});
alert(data);
}}
>Test</Button>
</div>
);
}
api.addPanel({
title: 'umi-dev',
path: '/umi-dev',
icon: 'home',
component: PluginPanel,
});
}
# Manage the plugin dependencies
The npm package module used in the UI is placed in devDependencies
in package.json
to prevent users from installing unnecessary dependencies.
Because of the umd compilation performed by the UI plugin package, the dependent modules are compiled into the umd file.
E.g:
// ui/index.js
// antd 4.x Icon
import { PlusOutlined } from '@ant-design/icons';
import classnames from 'classnames';
import styles from './index.module.less'
export default (api) => {
function PluginPanel() {
const wrapperCls = classnames(styles.bar, styles.foo);
return (
<div className={wrapperCls}>
<PlusOutlined />
</div>
);
}
api.addPanel({
title: 'umi-dev',
path: '/umi-dev',
icon: 'home',
component: PluginPanel,
});
}
package.json
Because Umi UI does external for
react
,react-dom
,antd
libraries, when developing plugin packages, inpeerDependencies
Packages are not built intoumd
, reducing the extra repetitive dependencies of the plugin.
{
"peerDependencies": {
"antd": "4.x",
"react": "16.8.6",
"react-dom": "16.8.6",
"umi": "2.x || ^2.9.0-0"
},
"dependencies": {
- "classnames": "^2.2.6",
- "@ant-design/icons": "^4.0.0-alpha.11"
},
"devDependencies": {
+ "classnames": "^2.2.6",
+ "@ant-design/icons": "^4.0.0-alpha.11"
}
}
# Internationalization
Umi UI supports plug-in internationalization, and provides Chinese(zh-CN) and English(en-US) languages. The language is switched through the bottom right corner menu.
Make the plugin using api.addLocales() and api.intl.* Have internationalization capabilities.
Register the internationalization fields:
// ui/index.js
import React from 'react';
export default (api) => {
// or
// import zh from './your-locale/zh.js'
// import en from './your-locale/en.js'
// { 'zh-CN': zh, 'en-US': en }
api.addLocales({
'zh-CN': {
'org.sorrycc.react.name': '陈成',
},
'en-US': {
'org.sorrycc.react.name': 'chencheng',
},
});
};
Using internationalization fields, api.intl.* provides a range of tool methods to choose from:
import React from 'react';
export default (api) => {
api.addLocales({
'zh-CN': {
'org.sorrycc.react.name': '陈成',
},
'en-US': {
'org.sorrycc.react.name': 'chencheng',
},
});
// Usage api reference https://github.com/formatjs/react-intl/blob/1c7b6f87d5cc49e6ef3f5133cacf8b066df53bde/docs/API.md
const {
FormattedMessage,
formatMessage,
} = api.intl;
const Component = (
<div>
<p>{formatMessage({ id: 'org.sorrycc.react.name' })}</p>
<FormattedMessage id="org.sorrycc.react.name" />
{/* api.intl alias `api.intl.formatMessage`: */ }
<p>{intl({ id: 'org.sorrycc.react.name' })}</p>
</div>
)
api.addPanel({
title: '插件模板',
path: '/plugin-bar',
icon: 'environment',
component: Component,
});
};
The result is as follows:
# Extended assets
Add assets using api.modifyBlockUIResources
:
// src/index.(js|ts)
api.modifyBlockUIResources((memo) => {
return [{
id: 'bigfish-techui-block',
name: 'TechUI',
blockType: 'block',
resourceType: 'custom',
icon: 'https://img.alicdn.com/tfs/TB1CpakmGL7gK0jSZFBXXXZZpXa-64-64.png',
description: '蚂蚁金融科技 UI 精选区块。',
getData: () => ({
success: true,
data: [
{
// git 地址
url: 'https://github.com/ant-design/ant-design-blocks/tree/master/form-register',
name: 'form-注册新用户',
description: '用户填写必须的信息以注册新用户。',
img: 'https://raw.githubusercontent.com/ant-design/ant-design-blocks/master/form-register/snapshot.png',
tags: [
'表单',
],
previewUrl: 'https://ant.design/components/form-cn/#components-form-demo-register',
}
]
}),
}, {
id: 'bigfish-techui-template',
name: 'TechUI',
blockType: 'template',
resourceType: 'custom',
icon: 'https://img.alicdn.com/tfs/TB1CpakmGL7gK0jSZFBXXXZZpXa-64-64.png',
description: '蚂蚁金融科技 UI 精选模板。',
getData: () => {
// same as block
return getBigfishBlock({
market: 'techui',
type: 'TEMPLATE',
}, true);
},
}, ...memo];
});
// socket api
api.onUISocket(async () => {
});
// add ui umd file
api.addUIPlugin(require.resolve('../ui/dist/index.umd.js'));
# Custom Block Slots
The UmiUIFlag
component exported from umi
can be used as a placeholder when the block is inserted. After the block is added, UmiUIFlag
will be automatically deleted.
import React from 'react';
import { UmiUIFlag } from 'umi';
import { Button } from 'antd';
export default () => (
<div>Hello
<div>
<p>World</p>
<UmiUIFlag />
<p>
aaaaa
<div>
<UmiUIFlag inline />Hello Inline<UmiUIFlag inline />
</div>
</p>
</div>
<Button type="primary">World</Button>
</div>
);
# Use Umi UI theme
Umi UI provides a set of antd theme variables that third-party component libraries can use to develop plug-ins in non-Umi UI runtime environments.
# Usage
Install the umi-ui-theme
theme pack, now only the dark
dark theme is available.
// .umirc.js
import { dark, light } from 'umi-ui-theme';
{
theme: dark
}
Introduced in the less file, you can use the less variable inside.
// dark
@import "~@umi-ui-theme/dark.less";
// light
@import "~@umi-ui-theme/light.less";