Skip to content

Commit

Permalink
add: 指引组件
Browse files Browse the repository at this point in the history
  • Loading branch information
hzm0321 committed Oct 1, 2022
1 parent d4fd89f commit 9dcfead
Show file tree
Hide file tree
Showing 7 changed files with 359 additions and 31 deletions.
122 changes: 97 additions & 25 deletions docs/9.business/9.1.components.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,43 @@ sidebar_position: 9
# 9.1. 公共业务组件

### 9.1.1. 字段钻取组件(`DrillComponent`

#### 简介

钻取组件用于业务对象查找与当前对象关联的字段信息的组件,可以通过参数控制向上还或向下查找关联字段,并且可以通过关系字段继续查找与之关联的字段信息。

#### 参数
| 参数 | 说明 | 类型 | 默认值 |
|----------------|---------------|-----------------------------------------------|-----|
| title | 自定义弹窗标题 || - |
| renderer | 组件自定义渲染 | `JSX` | - |
| onOk | 弹窗关闭回调,自己去写前端回写的逻辑 | `(params) => void;` | - |
| onClear | 弹窗关闭回调 | `() => void;` | - |
| initValue | 后端返回的初始值 | | - |
| isWriteBack | 是否需要回写 | `true` | - |
| curFieldCode | 当前字段的code,用于排除当前字段(不可选)取 businessObjectFieldCode | `string` | - |
| readOnly | 是否只读(默认false) | `false` | - |
| getInitRes | 初始化获取字段信息 | `(res) => void;` | - |
| drillMainKeyType | 是否钻取主键(默认false) | `false` | - |
| drillSet | 是否开始钻取集合 默认不开启钻取单值或对象 | `false` | - |
| drillDownFlag | 控制是否向下钻取 默认是false | `false` | - |
| componentTypeList | 前端自定义钻取参数 拼接到drill接口路径后 | | - |
| getReferenceInfo | 初始化掉解析接口reference-info后的回调 参数为解析接口返回值 | | - |
| selectObjectCheckFlag | 选择对象后,是否需要校验下一个框框 默认不校验可以只选对象保存 | `false` | - |
| onChange | 选中下拉选项的回调 | `(...args: any[]) => any;` | - |

| 参数 | 说明 | 类型 | 默认值 |
|-----------------------|--------------------------------------------------|----------------------------|-----|
| title | 自定义弹窗标题 || - |
| renderer | 组件自定义渲染 | `JSX` | - |
| onOk | 弹窗关闭回调,自己去写前端回写的逻辑 | `(params) => void;` | - |
| onClear | 弹窗关闭回调 | `() => void;` | - |
| initValue | 后端返回的初始值 | | - |
| isWriteBack | 是否需要回写 | `true` | - |
| curFieldCode | 当前字段的code,用于排除当前字段(不可选)取 businessObjectFieldCode | `string` | - |
| readOnly | 是否只读(默认false) | `false` | - |
| getInitRes | 初始化获取字段信息 | `(res) => void;` | - |
| drillMainKeyType | 是否钻取主键(默认false) | `false` | - |
| drillSet | 是否开始钻取集合 默认不开启钻取单值或对象 | `false` | - |
| drillDownFlag | 控制是否向下钻取 默认是false | `false` | - |
| componentTypeList | 前端自定义钻取参数 拼接到drill接口路径后 | | - |
| getReferenceInfo | 初始化掉解析接口reference-info后的回调 参数为解析接口返回值 | | - |
| selectObjectCheckFlag | 选择对象后,是否需要校验下一个框框 默认不校验可以只选对象保存 | `false` | - |
| onChange | 选中下拉选项的回调 | `(...args: any[]) => any;` | - |

#### 使用

```tsx
import React, { useMemo, useState } from 'react';
import { Header, Content } from 'components/Page';
import { Button, DataSet, Form, Output } from 'choerodon-ui/pro';
import { FieldType } from 'choerodon-ui/pro/lib/data-set/enum';
import { DataSetProps } from 'choerodon-ui/pro/lib/data-set/DataSet';
import React, {useMemo, useState} from 'react';
import {Header, Content} from 'components/Page';
import {Button, DataSet, Form, Output} from 'choerodon-ui/pro';
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
import {DataSetProps} from 'choerodon-ui/pro/lib/data-set/DataSet';

import DrillComponent from '@apaas/businessComponents/DrillComponent';
import { ButtonColor } from 'choerodon-ui/pro/lib/button/enum';
import {ButtonColor} from 'choerodon-ui/pro/lib/button/enum';

const demo = () => {

Expand Down Expand Up @@ -112,11 +115,11 @@ export default demo;
```

#### 页面效果

![层层钻取组件](/drillComponent.png)

<maintainer title="此组件维护者" authors={["wy"]}/>


### 9.1.2. 关系透视图组件(`RelationalPivot`

#### 简介
Expand Down Expand Up @@ -192,4 +195,73 @@ Modal.open({

<maintainer title="此组件维护者" authors={["hzm"]}/>

### 9.1.3. 用户指引组件(`Intro`

#### 简介

基于 `intro.js` 封装的用户指引组件,用于引导用户操作。

[官方文档](https://introjs.com/docs/)

#### 基础指引演示

```tsx live
function IntroDemo() {
const [introEnable, setIntroEnable] = useState(false);

const INTRO_ID = {
id1: "id1",
id2: "id2",
}

const introSteps = useMemo(() => {
return [
{
element: `#${INTRO_ID.id1}`,
intro: "这是第一个指引",
},
{
element: `#${INTRO_ID.id2}`,
intro: "这是第二个指引",
},
];
}, []);

const handleIntro = useCallback(() => {
setIntroEnable(true);
},[]);

const onExit = useCallback(() => {
setIntroEnable(false);
},[]);

return <>
<button onClick={handleIntro}>开启指引</button>
<div>
<span id={INTRO_ID.id1}>指引一</span>
<span id={INTRO_ID.id2}>指引二</span>
</div>
<Intro enabled={introEnable} steps={introSteps} onExit={onExit} />
</>
}
```

#### 参数

| 参数 | 说明 | 类型 | 默认值 |
|--------------------|-----------------------------|---------------------------------|---------|
| enabled | 是否启用 | `boolean` | `false` |
| steps | 指引步骤 | `introJs.Step[]` | - |
| options(可选) | 指引配置项 | `introJs.Options` | - |
| initialStep(可选) | 初始化时的所在步骤 | `number` | `0` |
| onExit(可选) | 监听指引退出 | `Function` | - |
| onBeforeExit(可选) | 监听指引退出前,返回 `false` 阻止指引弹窗关闭 | `() => boolean ⎮ void` | - |
| onChange(可选) | 监听每次步骤变化 | `(element: HTMLElement) => any` | - |
| onBeforeChange(可选) | 监听每次步骤变化前 | `(element: HTMLElement) => any` | - |
| onAfterChange(可选) | 监听每次步骤变化后 | `(element: HTMLElement) => any` | - |
| onComplete(可选) | 监听步骤完成后 | `Function` | - |


<maintainer title="此组件维护者" authors={["hzm"]}/>


4 changes: 3 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ const config = {
hashed: true, // For Docs using Chinese, The `language` is recommended to set to:
// ```
language: ["en", "zh"], // ```
},],],
},],
'@docusaurus/theme-live-codeblock'
],

presets: [['@docusaurus/preset-classic', /** @type {import('@docusaurus/preset-classic').Options} */
({
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@ant-design/icons": "^4.7.0",
"@docusaurus/core": "^2.1.0",
"@docusaurus/preset-classic": "^2.1.0",
"@docusaurus/theme-live-codeblock": "^2.1.0",
"@easyops-cn/docusaurus-search-local": "^0.30.2",
"@mdx-js/react": "^1.6.22",
"antd": "^4.22.6",
Expand All @@ -26,6 +27,7 @@
"clsx": "^1.2.1",
"docusaurus-plugin-less": "^2.0.2",
"docusaurus-plugin-sass": "^0.2.2",
"intro.js": "^6.0.0",
"less": "^4.1.3",
"less-loader": "^11.0.0",
"mobx": "4.15.7",
Expand All @@ -40,6 +42,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.1.0",
"@tsconfig/docusaurus": "^1.0.5",
"@types/intro.js": "^5.1.0",
"babel-plugin-import": "^1.13.5",
"typescript": "^4.7.4"
},
Expand Down
93 changes: 93 additions & 0 deletions src/components/Intro/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { forwardRef, useCallback, useEffect, useRef, useImperativeHandle } from 'react';
import introJs from 'intro.js';
import { isEmpty, isNumber, isUndefined } from 'lodash';
import 'intro.js/introjs.css';

import './intro.css';

export interface IntroRefType extends introJs.IntroJs {}

interface Props {
enabled: boolean; // 是否启用
steps: introJs.Step[]; // 步骤
options?: introJs.Options; // 配置
initialStep?: number; // 初始化时的所在步骤
onExit?: Parameters<introJs.IntroJs['onexit']>[0];
onBeforeExit?: Parameters<introJs.IntroJs['onbeforeexit']>[0];
onBeforeChange?: Parameters<introJs.IntroJs['onbeforechange']>[0];
onAfterChange?: Parameters<introJs.IntroJs['onafterchange']>[0];
onChange?: Parameters<introJs.IntroJs['onchange']>[0];
onComplete?: Parameters<introJs.IntroJs['oncomplete']>[0];
}

/**
* 用户指引组件
* @constructor
*/
const Intro = forwardRef<IntroRefType, Props>(( {
enabled,
steps,
options = {},
initialStep,
onExit,
onBeforeExit,
onBeforeChange,
onAfterChange,
onChange,
onComplete,
},
ref) => {
const introJsRef = useRef<introJs.IntroJs>(introJs());

useImperativeHandle(ref, () => introJsRef.current);

useEffect(() => {
if (enabled) {
// 写入配置
configureIntroJs();
// 开始渲染
renderSteps();
} else {
introJsRef.current.exit();
}
}, [enabled, steps, initialStep]);

useEffect(() => {
return () => {
introJsRef.current.exit();
};
}, []);

// 初始化配置
const configureIntroJs = () => {
const defaultOptions: introJs.Options = {
nextLabel: '<span style="display: inline-block">下一步</span>',
prevLabel: '<span style="display: inline-block">上一步</span>',
doneLabel: '<span style="display: inline-block">完成</span>',
buttonClass: 'c7n-pro-btn-wrapper c7n-pro-btn c7n-pro-btn-raised c7n-pro-btn-default',
};

introJsRef.current.setOptions({ ...defaultOptions, ...options, steps });
onExit && introJsRef.current.onexit(onExit);
if (!isUndefined(onBeforeExit)) {
introJsRef.current.onbeforeexit(onBeforeExit);
}
onBeforeChange && introJsRef.current.onbeforechange(onBeforeChange);
onAfterChange && introJsRef.current.onafterchange(onAfterChange);
onChange && introJsRef.current.onchange(onChange);
onComplete && introJsRef.current.oncomplete(onComplete);
};

const renderSteps = useCallback(() => {
if (enabled && !isEmpty(steps)) {
introJsRef.current.start();
}
if (isNumber(initialStep)) {
introJsRef.current.goToStepNumber(initialStep + 1);
}
}, [enabled, steps, initialStep]);

return null;
});

export default Intro;
Empty file added src/components/Intro/intro.css
Empty file.
12 changes: 12 additions & 0 deletions src/theme/ReactLiveScope/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import introJs from "intro.js";

import Intro from '../../components/Intro';
// Add react-live imports you need here
const ReactLiveScope = {
React,
...React,
Intro,
introJs
};
export default ReactLiveScope;
Loading

0 comments on commit 9dcfead

Please sign in to comment.