Update from Vibe Studio

This commit is contained in:
Vibe Studio
2026-01-16 02:20:32 +00:00
parent a4605e311a
commit 71de1506ca
28603 changed files with 2179459 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
/// <reference types="react" />
import type { ProHelpDataSource } from './HelpProvide';
/**
* 异步加载内容的面板组件
* @param item 指向当前面板的 ProHelpDataSource
*/
export declare const AsyncContentPanel: React.FC<{
item: ProHelpDataSource<any>['children'][number];
onInit?: (ref: HTMLDivElement) => void;
}>;

View File

@@ -0,0 +1,60 @@
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import { Spin } from 'antd';
import { useContext, useEffect, useState } from 'react';
import { ProHelpProvide } from "./HelpProvide";
import { RenderContentPanel } from "./RenderContentPanel";
/**
* 异步加载内容的面板组件
* @param item 指向当前面板的 ProHelpDataSource
*/
import { jsx as _jsx } from "react/jsx-runtime";
export var AsyncContentPanel = function AsyncContentPanel(_ref) {
var item = _ref.item,
_onInit = _ref.onInit;
var _useContext = useContext(ProHelpProvide),
onLoadContext = _useContext.onLoadContext; // 获取上下文中的 onLoadContext
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
loading = _useState2[0],
setLoading = _useState2[1]; // 加载状态
var _useState3 = useState(),
_useState4 = _slicedToArray(_useState3, 2),
content = _useState4[0],
setContent = _useState4[1]; // 内容数据
useEffect(function () {
if (!item.key) return; // 如果没有key则返回
setLoading(true); // 开始加载
onLoadContext === null || onLoadContext === void 0 || onLoadContext(item.key, item).then(function (res) {
// 调用加载方法
setLoading(false); // 加载完成
setContent(res); // 设置内容数据
});
}, [item.key]);
// 如果没有key则返回null
if (!item.key) return null;
// 如果正在加载并且有key则显示加载中的状态
if (loading && item.key) {
return /*#__PURE__*/_jsx("div", {
style: {
display: 'flex',
justifyContent: 'center',
width: '100%',
boxSizing: 'border-box',
padding: 24
},
children: /*#__PURE__*/_jsx(Spin, {})
}, item.key);
}
// 加载完成后,渲染内容面板
return /*#__PURE__*/_jsx(RenderContentPanel, {
onInit: function onInit(ref) {
_onInit === null || _onInit === void 0 || _onInit(ref);
},
dataSourceChildren: content
});
};

View File

@@ -0,0 +1,156 @@
import type { ImageProps } from 'antd';
import type { AnchorHTMLAttributes } from 'react';
import React from 'react';
/**
* ProHelp 数据源子项内容类型。
* 该类型定义了多种数据源子项内容类型,例如 h1、h2、link、text、image等。
* 其中link 和 inlineLink 属性都是链接类型的数据源子项内容,不同的是 inlineLink 是内联链接,而 link 是块级链接。
*
* @typedef {object} ProHelpDataSourceContentType
* @property {string} h1 标题1类型的数据源子项内容。
* @property {string} h2 标题2类型的数据源子项内容。
* @property {{ children: string } & React.AnchorHTMLAttributes<HTMLAnchorElement>} link 链接类型的数据源子项内容。
* @property {{ children: string } & React.AnchorHTMLAttributes<HTMLAnchorElement>} inlineLink 内联链接类型的数据源子项内容。
* @property {string} text 文本类型的数据源子项内容。
* @property {ImageProps} image 图片类型的数据源子项内容。
*/
type ProHelpDataSourceContentType = {
/**
* h1 标题1类型的数据源子项内容。
*/
h1: string;
/**
* h2 标题1类型的数据源子项内容。
*/
h2: string;
/**
* link 链接类型的数据源子项内容。
*/
link: {
children: string;
} & AnchorHTMLAttributes<HTMLAnchorElement>;
/**
* 行内链接类型的数据源子项内容。
*/
inlineLink: {
children: string;
} & AnchorHTMLAttributes<HTMLAnchorElement>;
/**
* navigation 类型链接,或切换菜单
*/
navigationSwitch: {
selectKey: string;
children: string;
};
/**
* text 文本类型的数据源子项内容。
*/
text: string;
/**
* image 图片类型的数据源子项内容。
*/
image: ImageProps;
/**
* markdown 类型的渲染,支持 基本的 markdown 语法
* 会包在一个叫 inner-html 为 markdown 的 div 中
*/
html: {
className: string;
children: string;
};
};
/**
* ProHelp 数据源子项内容类型的类型,可能的取值为 "h1"、"h2"、"link"、"inlineLink"、"text" 和 "image"。
* @typedef {'h1' | 'h2' | 'link' | 'inlineLink' | 'text' | 'image'} ProHelpDataSourceChildrenType
*/
type ProHelpDataSourceChildrenType = Extract<keyof ProHelpDataSourceContentType, any>;
/**
* ProHelp 数据源子项内容属性类型。
* @template ValueType 数据源项值的类型,默认为 'text'。
* 该类型定义了一个名为 children 的对象属性,根据 valueType 属性的值来确定该属性对象的具体类型,
* 如果 valueType 的类型是 ProHelpDataSourceChildrenType
* 则使用 ProHelpDataSourceContentType 中 ProHelpDataSourceChildrenType 所对应的属性类型;
* 否则,使用 ProHelpDataSourceContentType 中 ValueType 所对应的属性类型。
*/
type ProHelpDataSourceContentProps<ValueTypeMap, ValueType> = ValueType extends ProHelpDataSourceChildrenType ? ProHelpDataSourceContentType[ValueType] : ValueType extends keyof ValueTypeMap ? ValueTypeMap[ValueType] : ProHelpDataSourceContentType[ProHelpDataSourceChildrenType];
/**
* ProHelp 数据源子项类型。
* @template ValueTypeMap 数据源项值的类型,默认为 'text'。
* @property {(ValueType | ProHelpDataSourceChildrenType)} valueType 数据源子项值的类型,可以为指定的类型,也可以是自定义类型。
* @property {ProHelpDataSourceContentProps<ValueType>} children 包含数据源子项内容的对象。
*/
export type ProHelpDataSourceChildren<ValueTypeMap = {
text: string;
}> = {
/**
* 包含数据源子项内容的对象。
* @template ValueType 数据源项值的类型,默认为 'text'。
*/
valueType: ValueTypeMap extends Map<infer ValueType, any> ? ValueType : keyof ValueTypeMap | ProHelpDataSourceChildrenType;
/**
* 数据源子项值的类型。
* @typedef {(ValueTypeMap | ProHelpDataSourceChildrenType)} ProHelpDataSourceChildrenType
*/
children: ProHelpDataSourceContentProps<ValueTypeMap, keyof ValueTypeMap | ProHelpDataSourceChildrenType>;
};
/**
* ProHelp 数据源类型。
* @template ValueType 数据源项值的类型,默认为 'text'。
* @property {string} key 数据源项的唯一标识。
* @property {string} title 数据源项的标题。
* @property children 包含子项的数组,每个子项包含一个唯一标识,标题以及子子项数组。
*/
export type ProHelpDataSource<ValueType = 'text'> = {
/**
* key 数据源项的唯一标识
*/
key: string;
/**
* title 数据源项的标题。
*/
title: string;
/**
* 在一页内加载所有的 children 内容
*/
infiniteScrollFull?: boolean;
/**
* children 包含子项的数组,每个子项包含一个唯一标识,标题以及子子项数组。
*/
children: {
key: string;
title: string;
/**
* 是否远程加载children
*/
asyncLoad?: boolean;
children?: ProHelpDataSourceChildren<ValueType>[];
}[];
};
/**
* 这段代码定义了一个名为 ProHelpProvide 的 React 上下文对象,并且指定了该上下文对象的初始值为 { dataSource: [] }。
* 这个上下文对象中包含了一个名为 dataSource 的属性,该属性的值是一个数组,类型为 ProHelpDataSource<any>[]。
* 该上下文对象通常用于在 React 组件树中共享数据,即可以通过在组件中使用 ProHelpProvide.Provider 包裹一组组件,
* 将 dataSource 和 valueTypeMap 数据源传递给这些组件,这些组件即可从上下文中获取 dataSource 数据源,实现数据的共享和传递。
*/
export declare const ProHelpProvide: React.Context<{
/**
* 帮助文档的数据源,包含一组帮助文档数据,每个数据包含标题和内容等信息。
*/
dataSource: ProHelpDataSource<any>[];
/**
* 帮助组件的子组件,用于渲染自定义的帮助内容。
* 是一个键值对结构的集合,其中:
* 键key为字符串类型
* 值value为一个函数类型该函数接受两个参数一个名为 item 的 ProHelpDataSourceChildren 类型的对象,表示一个 ProHelp 数据源子项的子项;
* 一个名为 index 的数字类型参数,表示该子项在父级子项数组中的索引。
* 该函数返回一个 ReactNode 类型的元素,用于表示该 ProHelp 数据源子项子项应该渲染的 UI 元素。
* 这个 Map 的作用是将 ProHelp 数据源子项子项的 valueType 属性与对应的渲染函数进行映射,从而实现在渲染 ProHelp 数据源时动态地选择渲染方法。
* 在实际使用时,我们可以通过判断子项的 valueType 属性,从 valueTypeMap 中取出对应的渲染函数,再将该子项和渲染函数作为参数传入 renderDataSourceItem 函数中即可。
*/
valueTypeMap: Map<string, (item: ProHelpDataSourceChildren<any>, index: number) => React.ReactNode>;
/**
* 加载数据源的函数,如果把数据源设置为 async load就可以使用这个功能。
*/
onLoadContext?: ((key: React.Key, context: ProHelpDataSource<any>['children'][number]) => Promise<ProHelpDataSourceChildren<any>[]>) | undefined;
}>;
export {};

View File

@@ -0,0 +1,55 @@
import React from 'react';
/**
* ProHelp 数据源子项内容类型。
* 该类型定义了多种数据源子项内容类型,例如 h1、h2、link、text、image等。
* 其中link 和 inlineLink 属性都是链接类型的数据源子项内容,不同的是 inlineLink 是内联链接,而 link 是块级链接。
*
* @typedef {object} ProHelpDataSourceContentType
* @property {string} h1 标题1类型的数据源子项内容。
* @property {string} h2 标题2类型的数据源子项内容。
* @property {{ children: string } & React.AnchorHTMLAttributes<HTMLAnchorElement>} link 链接类型的数据源子项内容。
* @property {{ children: string } & React.AnchorHTMLAttributes<HTMLAnchorElement>} inlineLink 内联链接类型的数据源子项内容。
* @property {string} text 文本类型的数据源子项内容。
* @property {ImageProps} image 图片类型的数据源子项内容。
*/
/**
* ProHelp 数据源子项内容类型的类型,可能的取值为 "h1"、"h2"、"link"、"inlineLink"、"text" 和 "image"。
* @typedef {'h1' | 'h2' | 'link' | 'inlineLink' | 'text' | 'image'} ProHelpDataSourceChildrenType
*/
/**
* ProHelp 数据源子项内容属性类型。
* @template ValueType 数据源项值的类型,默认为 'text'。
* 该类型定义了一个名为 children 的对象属性,根据 valueType 属性的值来确定该属性对象的具体类型,
* 如果 valueType 的类型是 ProHelpDataSourceChildrenType
* 则使用 ProHelpDataSourceContentType 中 ProHelpDataSourceChildrenType 所对应的属性类型;
* 否则,使用 ProHelpDataSourceContentType 中 ValueType 所对应的属性类型。
*/
/**
* ProHelp 数据源子项类型。
* @template ValueTypeMap 数据源项值的类型,默认为 'text'。
* @property {(ValueType | ProHelpDataSourceChildrenType)} valueType 数据源子项值的类型,可以为指定的类型,也可以是自定义类型。
* @property {ProHelpDataSourceContentProps<ValueType>} children 包含数据源子项内容的对象。
*/
/**
* ProHelp 数据源类型。
* @template ValueType 数据源项值的类型,默认为 'text'。
* @property {string} key 数据源项的唯一标识。
* @property {string} title 数据源项的标题。
* @property children 包含子项的数组,每个子项包含一个唯一标识,标题以及子子项数组。
*/
/**
* 这段代码定义了一个名为 ProHelpProvide 的 React 上下文对象,并且指定了该上下文对象的初始值为 { dataSource: [] }。
* 这个上下文对象中包含了一个名为 dataSource 的属性,该属性的值是一个数组,类型为 ProHelpDataSource<any>[]。
* 该上下文对象通常用于在 React 组件树中共享数据,即可以通过在组件中使用 ProHelpProvide.Provider 包裹一组组件,
* 将 dataSource 和 valueTypeMap 数据源传递给这些组件,这些组件即可从上下文中获取 dataSource 数据源,实现数据的共享和传递。
*/
export var ProHelpProvide = /*#__PURE__*/React.createContext({
dataSource: [],
valueTypeMap: new Map()
});

View File

@@ -0,0 +1,18 @@
import React from 'react';
import type { ProHelpDataSource } from './HelpProvide';
export type ProHelpContentPanelProps = {
/**
* 控制当前选中的帮助文档
*/
selectedKey: React.Key;
className?: string;
parentItem?: ProHelpDataSource<any>;
onScroll?: (key?: string) => void;
};
/**
* 控制具体的帮助文档显示组件
* selectedKey 来展示对应的内容。它会根据不同的item.valueType值来展示不同的内容包括标题、图片、超链接等。
* @param ProHelpContentPanelProps
* @returns
*/
export declare const ProHelpContentPanel: React.FC<ProHelpContentPanelProps>;

View File

@@ -0,0 +1,155 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import { ProProvider } from '@ant-design/pro-provider';
import { useDebounceFn } from '@ant-design/pro-utils';
import classNames from 'classnames';
import React, { useContext, useEffect, useMemo, useRef } from 'react';
import { AsyncContentPanel } from "./AsyncContentPanel";
import { ProHelpProvide } from "./HelpProvide";
import { RenderContentPanel } from "./RenderContentPanel";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* 控制具体的帮助文档显示组件
* selectedKey 来展示对应的内容。它会根据不同的item.valueType值来展示不同的内容包括标题、图片、超链接等。
* @param ProHelpContentPanelProps
* @returns
*/
export var ProHelpContentPanel = function ProHelpContentPanel(_ref) {
var className = _ref.className,
parentItem = _ref.parentItem,
selectedKey = _ref.selectedKey,
onScroll = _ref.onScroll;
var _useContext = useContext(ProHelpProvide),
dataSource = _useContext.dataSource;
var _useContext2 = useContext(ProProvider),
hashId = _useContext2.hashId;
// 记录每个面板的滚动高度
var scrollHeightMap = useRef(new Map());
var divRef = useRef(null);
useEffect(function () {
if (!selectedKey || !(parentItem !== null && parentItem !== void 0 && parentItem.infiniteScrollFull)) return;
var div = scrollHeightMap.current.get(selectedKey);
if (div !== null && div !== void 0 && div.offsetTop && divRef.current) {
if (Math.abs(divRef.current.scrollTop - (div === null || div === void 0 ? void 0 : div.offsetTop) + 40) > (div === null || div === void 0 ? void 0 : div.clientHeight)) {
divRef.current.scrollTop = (div === null || div === void 0 ? void 0 : div.offsetTop) - 40;
}
}
}, [selectedKey]);
/**
* debounce防抖处理滚动事件并根据滚动位置来实现找到当前列表的 key
*/
var onScrollEvent = useDebounceFn( /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(e) {
var dom, list;
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
dom = e === null || e === void 0 ? void 0 : e.target; // 根据滚动位置来找到当前列表的 key
list = Array.from(scrollHeightMap.current.entries()).find(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 2),
value = _ref4[1];
if ((dom === null || dom === void 0 ? void 0 : dom.scrollTop) < value.offsetTop) {
return true;
}
return false;
});
if (list) {
_context.next = 4;
break;
}
return _context.abrupt("return");
case 4:
// 如果获取的 key 和当前 key 不同丢弃掉
if (list.at(0) !== selectedKey) {
// 如果不同,则触发 onScroll 事件
onScroll === null || onScroll === void 0 || onScroll(list.at(0));
}
case 5:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x) {
return _ref2.apply(this, arguments);
};
}(), 200);
/**
* 当 parentItem 组件中的 infiniteScrollFull 属性变化时
* 如果该属性为真值,则开始监听滚动事件;
* 如果为假值,则停止监听滚动事件并取消防抖处理。
* 在监听滚动事件时,可以实现分页(瀑布流)效果。同时,该代码还会根据 selectedKey 的变化来触发跳转
*/
useEffect(function () {
var _divRef$current;
if (!(parentItem !== null && parentItem !== void 0 && parentItem.infiniteScrollFull)) return;
onScrollEvent.cancel();
(_divRef$current = divRef.current) === null || _divRef$current === void 0 || _divRef$current.addEventListener('scroll', onScrollEvent.run, false);
return function () {
var _divRef$current2;
onScrollEvent.cancel();
(_divRef$current2 = divRef.current) === null || _divRef$current2 === void 0 || _divRef$current2.removeEventListener('scroll', onScrollEvent.run, false);
};
}, [parentItem === null || parentItem === void 0 ? void 0 : parentItem.infiniteScrollFull, selectedKey]);
/**
* 生成一个 Map 能根据 key 找到所有的 index
*/
var dataSourceMap = useMemo(function () {
var map = new Map();
dataSource.forEach(function (page) {
page.children.forEach(function (item) {
map.set(item.key || item.title, _objectSpread(_objectSpread({}, item), {}, {
parentKey: page.key
}));
});
});
return map;
}, [dataSource]);
var renderItem = function renderItem(item) {
if (item !== null && item !== void 0 && item.asyncLoad) {
return /*#__PURE__*/_jsx("div", {
className: classNames(className, hashId),
id: item.title,
children: /*#__PURE__*/_jsx(AsyncContentPanel, {
item: item,
onInit: function onInit(ref) {
if (!scrollHeightMap.current) return;
scrollHeightMap.current.set(item.key, ref);
}
}, item === null || item === void 0 ? void 0 : item.key)
});
}
return /*#__PURE__*/_jsx("div", {
className: classNames(className, hashId),
id: item.title,
children: /*#__PURE__*/_jsx(RenderContentPanel, {
onInit: function onInit(ref) {
if (!scrollHeightMap.current) return;
scrollHeightMap.current.set(item.key, ref);
},
dataSourceChildren: (item === null || item === void 0 ? void 0 : item.children) || []
})
});
};
if (parentItem && parentItem.infiniteScrollFull) {
var _parentItem$children;
return /*#__PURE__*/_jsx("div", {
ref: divRef,
className: classNames("".concat(className, "-infinite-scroll"), hashId),
style: {
overflow: 'auto'
},
children: (_parentItem$children = parentItem.children) === null || _parentItem$children === void 0 ? void 0 : _parentItem$children.map(function (item) {
return /*#__PURE__*/_jsx(React.Fragment, {
children: renderItem(item)
}, item.key);
})
});
}
return renderItem(dataSourceMap.get(selectedKey));
};

View File

@@ -0,0 +1,15 @@
/// <reference types="react" />
import type { DrawerProps } from 'antd';
import type { ProHelpPanelProps } from './ProHelpPanel';
export type ProHelpDrawerProps = {
/**
* Ant Design Drawer 组件的 Props可以传递一些选项如位置、大小、关闭方式等等。
*/
drawerProps: DrawerProps;
} & Omit<ProHelpPanelProps, 'onClose'>;
/**
* 渲染一个抽屉,其中显示了一个 ProHelpPanel。
* @param drawerProps 要传递给 Drawer 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export declare const ProHelpDrawer: React.FC<ProHelpDrawerProps>;

View File

@@ -0,0 +1,51 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["drawerProps"];
import { Drawer } from 'antd';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import { ProHelpPanel } from "./ProHelpPanel";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* 渲染一个抽屉,其中显示了一个 ProHelpPanel。
* @param drawerProps 要传递给 Drawer 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export var ProHelpDrawer = function ProHelpDrawer(_ref) {
var drawerProps = _ref.drawerProps,
props = _objectWithoutProperties(_ref, _excluded);
var _useMergedState = useMergedState(false, {
value: drawerProps.open,
onChange: drawerProps.afterOpenChange
}),
_useMergedState2 = _slicedToArray(_useMergedState, 2),
drawerOpen = _useMergedState2[0],
setDrawerOpen = _useMergedState2[1];
return /*#__PURE__*/_jsx(Drawer, _objectSpread(_objectSpread({
width: 720,
closeIcon: null,
styles: {
header: {
display: 'none'
},
body: {
padding: 0
}
},
maskClosable: true
}, drawerProps), {}, {
open: drawerOpen,
onClose: function onClose() {
return setDrawerOpen(false);
},
afterOpenChange: function afterOpenChange(open) {
setDrawerOpen(open);
},
children: /*#__PURE__*/_jsx(ProHelpPanel, _objectSpread(_objectSpread({}, props), {}, {
onClose: function onClose() {
return setDrawerOpen(false);
},
bordered: false
}))
}));
};

View File

@@ -0,0 +1,15 @@
/// <reference types="react" />
import type { ModalProps } from 'antd';
import type { ProHelpPanelProps } from './ProHelpPanel';
export type ProHelpModalProps = {
/**
* Ant Design Modal 组件的 props可以传递一些选项如位置、大小、关闭方式等等。
*/
modalProps?: ModalProps;
} & Omit<ProHelpPanelProps, 'onClose'>;
/**
* 渲染一个模态对话框,其中显示了一个 ProHelpPanel。
* @param modalProps 要传递给 Modal 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export declare const ProHelpModal: React.FC<ProHelpModalProps>;

View File

@@ -0,0 +1,48 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["modalProps"];
import { Modal } from 'antd';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import { ProHelpPanel } from "./ProHelpPanel";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* 渲染一个模态对话框,其中显示了一个 ProHelpPanel。
* @param modalProps 要传递给 Modal 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export var ProHelpModal = function ProHelpModal(_ref) {
var modalProps = _ref.modalProps,
props = _objectWithoutProperties(_ref, _excluded);
var _useMergedState = useMergedState(false, {
value: modalProps === null || modalProps === void 0 ? void 0 : modalProps.open,
onChange: modalProps === null || modalProps === void 0 ? void 0 : modalProps.afterClose
}),
_useMergedState2 = _slicedToArray(_useMergedState, 2),
modalOpen = _useMergedState2[0],
setModalOpen = _useMergedState2[1];
return /*#__PURE__*/_jsx(Modal, _objectSpread(_objectSpread({
onCancel: function onCancel() {
setModalOpen(false);
},
styles: {
body: {
margin: -24
}
},
centered: true,
closable: false,
footer: null,
width: 720,
open: modalOpen,
maskClosable: true
}, modalProps), {}, {
children: /*#__PURE__*/_jsx(ProHelpPanel, _objectSpread(_objectSpread({
height: 648
}, props), {}, {
onClose: function onClose() {
return setModalOpen(false);
}
}))
}));
};

View File

@@ -0,0 +1,69 @@
import React from 'react';
export declare const SelectKeyProvide: React.Context<{
selectedKey: string | undefined;
setSelectedKey: (key: string | undefined) => void;
}>;
export type ProHelpPanelProps = {
/**
* 帮助面板的标题
*/
title?: string;
/**
* 帮助面板首次打开时的默认选中文档的键名
*/
defaultSelectedKey?: string;
/**
* 当前选中的帮助文档的键名。如果提供了这个 prop那么该组件将是一个受控组件其状态将由父组件管理。如果未提供那么该组件将是一个非受控组件其状态将在组件内部管理。
*/
selectedKey?: string;
/**
* 当选中的文档键名发生变化时调用的回调函数。新的键名将作为参数传递给该函数。
*/
onSelectedKeyChange?: (key: string | undefined) => void;
/**
*控制左侧面板是否能够打开
*/
showLeftPanel?: boolean;
/**
* 当左侧面板打开状态发生变化时调用的回调函数。新的打开状态将作为参数传递给该函数。
*/
onShowLeftPanelChange?: (show: boolean) => void;
/**
* 是否显示边框
*/
bordered?: boolean;
/**
* 当帮助面板关闭时调用的回调函数。
*/
onClose?: () => void;
/**
* 帮助面板的高度,可以是数字或字符串类型。
*/
height?: number | string;
/**
* 帮助面板的页脚
*/
footer?: React.ReactNode;
/**
* 在一页内加载所有的 children 内容
*/
infiniteScrollFull?: boolean;
/**
* 自定义渲染 extra 部分的内容
*
* @param {React.ReactNode} collapsePannelAction - 折叠收起的左侧按钮
* @param {React.ReactNode} helpSelectAction - 默认的帮助筛选按钮
* @param {React.ReactNode} closeAction - 关闭操作按钮
* @returns {React.ReactNode} - 返回自定义渲染的 extra 操作按钮
*
*/
extraRender?: (collapsePannelAction: React.ReactNode, helpSelectAction: React.ReactNode, closeAction: React.ReactNode) => React.ReactNode;
};
/**
* ProHelpPanel 组件是一个帮助中心面板组件,具有可折叠的左侧菜单和右侧帮助内容区域。
* 左侧菜单显示了帮助文档的目录结构,右侧帮助内容区域显示了用户选中的帮助文档内容。
* 在左侧菜单中,用户可以通过点击目录来选择并显示相应的文档内容。
* @param param0
* @returns
*/
export declare const ProHelpPanel: React.FC<ProHelpPanelProps>;

View File

@@ -0,0 +1,215 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["title", "bordered", "onClose", "footer", "height", "extraRender"];
import { CloseOutlined, ProfileOutlined } from '@ant-design/icons';
import { ProProvider, isNeedOpenHash } from '@ant-design/pro-provider';
import { coverToNewToken } from '@ant-design/pro-utils';
import { Card, ConfigProvider, Menu } from 'antd';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import React, { useContext, useMemo, useState } from 'react';
import { ProHelpProvide } from "./HelpProvide";
import { ProHelpContentPanel } from "./ProHelpContentPanel";
import { ProHelpSelect } from "./Search";
import { useStyle } from "./style";
import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export var SelectKeyProvide = /*#__PURE__*/React.createContext({
selectedKey: undefined,
setSelectedKey: function setSelectedKey() {}
});
/**
* ProHelpPanel 组件是一个帮助中心面板组件,具有可折叠的左侧菜单和右侧帮助内容区域。
* 左侧菜单显示了帮助文档的目录结构,右侧帮助内容区域显示了用户选中的帮助文档内容。
* 在左侧菜单中,用户可以通过点击目录来选择并显示相应的文档内容。
* @param param0
* @returns
*/
export var ProHelpPanel = function ProHelpPanel(_ref) {
var _token$layout, _token$layout2, _token$layout3, _token$layout4, _token$layout5;
var _ref$title = _ref.title,
title = _ref$title === void 0 ? '帮助中心' : _ref$title,
_ref$bordered = _ref.bordered,
bordered = _ref$bordered === void 0 ? true : _ref$bordered,
onClose = _ref.onClose,
footer = _ref.footer,
height = _ref.height,
extraRender = _ref.extraRender,
props = _objectWithoutProperties(_ref, _excluded);
var _useContext = useContext(ConfigProvider.ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var className = getPrefixCls('pro-help');
var _useStyle = useStyle(className),
wrapSSR = _useStyle.wrapSSR,
hashId = _useStyle.hashId;
var _useContext2 = useContext(ProHelpProvide),
dataSource = _useContext2.dataSource;
var _useMergedState = useMergedState(undefined, {
defaultValue: props.defaultSelectedKey,
value: props.selectedKey,
onChange: props.onSelectedKeyChange
}),
_useMergedState2 = _slicedToArray(_useMergedState, 2),
selectedKey = _useMergedState2[0],
setSelectedKey = _useMergedState2[1];
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
openKey = _useState2[0],
setOpenKey = _useState2[1];
var _useContext3 = useContext(ProProvider),
token = _useContext3.token;
var _useMergedState3 = useMergedState(true, {
value: props.showLeftPanel,
onChange: props.onShowLeftPanelChange
}),
_useMergedState4 = _slicedToArray(_useMergedState3, 2),
showLeftPanel = _useMergedState4[0],
setShowLeftPanel = _useMergedState4[1];
var dataSourceKeyMap = useMemo(function () {
var map = new Map();
dataSource.forEach(function (page) {
var _page$children;
map.set(page.key, page);
(_page$children = page.children) === null || _page$children === void 0 || _page$children.forEach(function (item) {
map.set(item.key || item.title, _objectSpread({
parentKey: page.key
}, item));
});
});
return map;
}, [dataSource]);
var parentKey = useMemo(function () {
var _dataSourceKeyMap$get;
return (_dataSourceKeyMap$get = dataSourceKeyMap.get(selectedKey)) === null || _dataSourceKeyMap$get === void 0 ? void 0 : _dataSourceKeyMap$get.parentKey;
}, [dataSourceKeyMap, selectedKey]);
var defaultExtraActions = {
collapsePanelAction: /*#__PURE__*/_jsx("div", {
className: "".concat(className, "-actions-item ").concat(hashId).trim(),
children: /*#__PURE__*/_jsx(ProfileOutlined, {
title: "collapse panel",
onClick: function onClick() {
setShowLeftPanel(!showLeftPanel);
}
})
}),
helpSelectAction: /*#__PURE__*/_jsx(ProHelpSelect, {
iconClassName: "".concat(className, "-actions-item"),
className: "".concat(hashId, " ").concat(className, "-actions-input"),
value: selectedKey,
onChange: function onChange(value, item) {
setSelectedKey(value);
setOpenKey(item === null || item === void 0 ? void 0 : item.dataItemKey);
}
}),
closeAction: /*#__PURE__*/_jsx("div", {
className: "".concat(className, "-actions-item ").concat(hashId).trim(),
children: /*#__PURE__*/_jsx(CloseOutlined, {
title: "close panel",
onClick: function onClick() {
onClose === null || onClose === void 0 || onClose();
}
})
})
};
var extraDomList = function extraDomList() {
return /*#__PURE__*/_jsx("div", {
className: "".concat(className, "-actions ").concat(hashId).trim(),
children: extraRender ? extraRender(defaultExtraActions.collapsePanelAction, defaultExtraActions.helpSelectAction, defaultExtraActions.closeAction) : /*#__PURE__*/_jsxs(_Fragment, {
children: [defaultExtraActions.collapsePanelAction, defaultExtraActions.helpSelectAction, onClose ? defaultExtraActions.closeAction : null]
})
});
};
return wrapSSR( /*#__PURE__*/_jsx(SelectKeyProvide.Provider, {
value: {
selectedKey: selectedKey,
setSelectedKey: setSelectedKey
},
children: /*#__PURE__*/_jsxs(Card, {
bordered: bordered,
title: title,
bodyStyle: {
display: 'flex',
padding: 0,
margin: 0,
height: '100%',
width: '100%'
},
size: "small",
extra: extraDomList(),
children: [showLeftPanel ? /*#__PURE__*/_jsx("div", {
className: "".concat(hashId, " ").concat(className, "-left-panel "),
style: {
height: height
},
children: /*#__PURE__*/_jsx(ConfigProvider, {
theme: {
hashed: isNeedOpenHash(),
token: {
lineHeight: 1.2,
fontSize: 12,
controlHeightLG: 26
},
components: {
Menu: coverToNewToken({
radiusItem: token.borderRadius,
colorActiveBarWidth: 0,
colorActiveBarBorderSize: 0,
colorItemBgSelected: ((_token$layout = token.layout) === null || _token$layout === void 0 || (_token$layout = _token$layout.sider) === null || _token$layout === void 0 ? void 0 : _token$layout.colorBgMenuItemSelected) || 'rgba(0, 0, 0, 0.04)',
colorItemBgActive: ((_token$layout2 = token.layout) === null || _token$layout2 === void 0 || (_token$layout2 = _token$layout2.sider) === null || _token$layout2 === void 0 ? void 0 : _token$layout2.colorBgMenuItemHover) || 'rgba(0, 0, 0, 0.04)',
colorItemText: ((_token$layout3 = token.layout) === null || _token$layout3 === void 0 || (_token$layout3 = _token$layout3.sider) === null || _token$layout3 === void 0 ? void 0 : _token$layout3.colorTextMenu) || 'rgba(0, 0, 0, 0.65)',
colorItemTextHover: ((_token$layout4 = token.layout) === null || _token$layout4 === void 0 || (_token$layout4 = _token$layout4.sider) === null || _token$layout4 === void 0 ? void 0 : _token$layout4.colorTextMenuActive) || 'rgba(0, 0, 0, 0.85)',
colorItemTextSelected: ((_token$layout5 = token.layout) === null || _token$layout5 === void 0 || (_token$layout5 = _token$layout5.sider) === null || _token$layout5 === void 0 ? void 0 : _token$layout5.colorTextMenuSelected) || 'rgba(0, 0, 0, 1)',
colorItemBg: 'transparent',
colorSubItemBg: 'transparent',
popupBg: token === null || token === void 0 ? void 0 : token.colorBgElevated,
darkPopupBg: token === null || token === void 0 ? void 0 : token.colorBgElevated
})
}
},
children: /*#__PURE__*/_jsx(Menu, {
className: "".concat(hashId, " ").concat(className, "-left-panel-menu"),
openKeys: [parentKey, openKey],
onOpenChange: function onOpenChange(keys) {
setOpenKey(keys.at(-1) || '');
},
selectedKeys: selectedKey ? [selectedKey] : [],
onSelect: function onSelect(_ref2) {
var selectedKeys = _ref2.selectedKeys;
setSelectedKey(selectedKeys.at(-1) || '');
},
mode: "inline",
items: dataSource.map(function (item) {
return {
key: item.key,
label: item.title,
children: item.children.map(function (child) {
return {
key: child.key,
label: child.title
};
})
};
})
})
})
}) : null, /*#__PURE__*/_jsxs("div", {
className: "".concat(hashId, " ").concat(className, "-content-panel"),
style: {
height: height
},
children: [selectedKey ? /*#__PURE__*/_jsx(ProHelpContentPanel, {
parentItem: dataSourceKeyMap.get(parentKey),
className: "".concat(className, "-content-render"),
selectedKey: selectedKey,
onScroll: function onScroll(key) {
return setSelectedKey(key);
}
}) : null, footer ? /*#__PURE__*/_jsx("div", {
className: "".concat(hashId, " ").concat(className, "-footer"),
children: footer
}) : null]
})]
})
}));
};

View File

@@ -0,0 +1,32 @@
import type { PopoverProps } from 'antd';
import React from 'react';
export type ProHelpPopoverProps = Omit<PopoverProps, 'content'> & {
/**
* 悬浮提示文字的 CSS 类名
*/
textClassName?: string;
/**
* Popover 内容的 content 的 CSS 类名
*/
popoverContextClassName?: string;
/**
* 悬浮提示文字的 CSS 样式对象
*/
textStyle?: React.CSSProperties;
/**
* 当前选中的帮助文档的 key 值
*/
selectedKey: string;
/**
* 可选的悬浮提示 Popover 组件的 Props用于自定义悬浮提示的样式和行为。
* 该属性可以传递 Ant Design Popover 组件的 props如位置、大小、触发方式等等
* @see 注意content 属性已经被从 PopoverProps 中删除,因为这个属性由 ProHelpPopover 内部控制。
*/
popoverProps?: PopoverProps;
};
/**
* 渲染一个弹出式提示框其中显示了一个ProHelpContentPanel展示帮助文案的详情
* @param popoverProps 要传递给 Drawer 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export declare const ProHelpPopover: React.FC<ProHelpPopoverProps>;

View File

@@ -0,0 +1,40 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import { ProProvider } from '@ant-design/pro-provider';
import { ConfigProvider, Popover } from 'antd';
import classNames from 'classnames';
import React, { useContext } from 'react';
import { ProHelpContentPanel } from "./ProHelpContentPanel";
import { useStyle } from "./style";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* 渲染一个弹出式提示框其中显示了一个ProHelpContentPanel展示帮助文案的详情
* @param popoverProps 要传递给 Drawer 组件的属性。
* @param props 要传递给 ProHelpPanel 组件的属性。
*/
export var ProHelpPopover = function ProHelpPopover(props) {
var _useContext = useContext(ConfigProvider.ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var className = getPrefixCls('pro-help');
var _useContext2 = useContext(ProProvider),
hashId = _useContext2.hashId;
var _useStyle = useStyle(className),
wrapSSR = _useStyle.wrapSSR;
return wrapSSR( /*#__PURE__*/_jsx(Popover, _objectSpread(_objectSpread({
styles: {
body: {
padding: 0
}
},
content: /*#__PURE__*/_jsx("div", {
className: classNames("".concat(className, "-popover-content"), hashId, props.popoverContextClassName),
children: /*#__PURE__*/_jsx(ProHelpContentPanel, {
selectedKey: props.selectedKey
})
})
}, props.popoverProps), {}, {
children: /*#__PURE__*/_jsx("span", {
className: classNames("".concat(className, "-popover-text"), hashId, props.textClassName),
children: props.children
})
})));
};

View File

@@ -0,0 +1,6 @@
import React from 'react';
import type { ProHelpDataSourceChildren } from './HelpProvide';
export declare const RenderContentPanel: React.FC<{
dataSourceChildren: ProHelpDataSourceChildren<any>[];
onInit?: (ref: HTMLDivElement) => void;
}>;

View File

@@ -0,0 +1,111 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import { Image, Typography } from 'antd';
import React, { useContext, useEffect, useRef } from 'react';
import { ProHelpProvide } from "./HelpProvide";
import { SelectKeyProvide } from "./ProHelpPanel";
// HTML渲染组件接收一个字符串形式的html作为props
// 可选接收className作为组件的样式类名
import { jsx as _jsx } from "react/jsx-runtime";
var HTMLRender = function HTMLRender(props) {
var ref = useRef(null);
// 当html发生变化时将其渲染到ref.current的innerHTML中
useEffect(function () {
if (ref.current) ref.current.innerHTML = props.children;
}, [props.children]);
// 返回一个div元素作为容器并传递ref和className作为props
return /*#__PURE__*/_jsx("div", {
ref: ref,
className: props.className || 'inner-html'
});
};
var NavigationSwitch = function NavigationSwitch(props) {
var context = useContext(SelectKeyProvide);
return /*#__PURE__*/_jsx(Typography.Text, {
children: /*#__PURE__*/_jsx("a", {
"data-testid": "navigation-switch",
onClick: function onClick() {
context.setSelectedKey(props.selectKey);
},
children: props.children
})
});
};
export var RenderContentPanel = function RenderContentPanel(_ref) {
var dataSourceChildren = _ref.dataSourceChildren,
onInit = _ref.onInit;
var _useContext = useContext(ProHelpProvide),
valueTypeMap = _useContext.valueTypeMap;
var divRef = useRef(null);
useEffect(function () {
onInit === null || onInit === void 0 || onInit(divRef.current);
}, [dataSourceChildren]);
/**
* itemRender 的定义
* @param {ProHelpDataSourceChildren} item
* @param {number} index
* @return {*}
*/
var itemRender = function itemRender(item, index) {
// 自定义的渲染,优先级最高
if (valueTypeMap.has(item.valueType)) {
var _valueTypeMap$get;
return /*#__PURE__*/_jsx(React.Fragment, {
children: (_valueTypeMap$get = valueTypeMap.get(item.valueType)) === null || _valueTypeMap$get === void 0 ? void 0 : _valueTypeMap$get(item, index)
}, index);
}
if (item.valueType === 'html') {
return /*#__PURE__*/_jsx(HTMLRender, _objectSpread({}, item.children), index);
}
if (item.valueType === 'h1') {
return /*#__PURE__*/_jsx(Typography.Title, {
style: {
marginTop: 0
},
level: 3,
children: item.children
}, index);
}
if (item.valueType === 'h2') {
return /*#__PURE__*/_jsx(Typography.Title, {
style: {
marginTop: 20
},
level: 5,
children: item.children
}, index);
}
if (item.valueType === 'image') {
return /*#__PURE__*/_jsx("div", {
style: {
marginBlock: 12
},
children: /*#__PURE__*/_jsx(Image, _objectSpread({}, item.children))
}, index);
}
if (item.valueType === 'inlineLink') {
return /*#__PURE__*/_jsx(Typography.Text, {
children: /*#__PURE__*/_jsx("a", _objectSpread({}, item.children))
}, index);
}
if (item.valueType === 'link') {
return /*#__PURE__*/_jsx("div", {
children: /*#__PURE__*/_jsx(Typography.Text, {
children: /*#__PURE__*/_jsx("a", _objectSpread({}, item.children))
}, index)
}, index);
}
if (item.valueType === 'navigationSwitch') {
return /*#__PURE__*/_jsx(NavigationSwitch, _objectSpread({}, item.children), index);
}
return /*#__PURE__*/_jsx(Typography.Text, {
children: item.children
}, index);
};
return /*#__PURE__*/_jsx("div", {
ref: divRef,
children: dataSourceChildren === null || dataSourceChildren === void 0 ? void 0 : dataSourceChildren.map(itemRender)
});
};

View File

@@ -0,0 +1,20 @@
import type { SelectProps } from 'antd';
import React from 'react';
/**
* 在一段文本中高亮显示指定的关键词,将文本和匹配项分别处理并放入数组中,最终返回包含高亮文本的组件。
* 在组件中使用了正则表达式来匹配关键词。
* 在渲染文本时使用了React.createElement来创建元素。
*/
export declare const Highlight: React.FC<{
/**
* 要高亮的文本
*/
label: string;
/**
* 高亮的关键词数组
*/
words: string[];
}>;
export declare const ProHelpSelect: React.FC<Omit<SelectProps, 'onSearch' | 'optionFilterProp' | 'options' | 'filterOption'> & {
iconClassName?: string;
}>;

View File

@@ -0,0 +1,156 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
var _excluded = ["iconClassName"];
import { SearchOutlined } from '@ant-design/icons';
import { ProProvider, useStyle } from '@ant-design/pro-provider';
import { compatibleBorder, useDebounceFn } from '@ant-design/pro-utils';
import { ConfigProvider, Select } from 'antd';
import classNames from 'classnames';
import React, { useContext, useState } from 'react';
import { ProHelpProvide } from "./HelpProvide";
/**
* 在一段文本中高亮显示指定的关键词,将文本和匹配项分别处理并放入数组中,最终返回包含高亮文本的组件。
* 在组件中使用了正则表达式来匹配关键词。
* 在渲染文本时使用了React.createElement来创建元素。
*/
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export var Highlight = function Highlight(_ref) {
var label = _ref.label,
words = _ref.words;
var _useContext = useContext(ConfigProvider.ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var lightCls = getPrefixCls('pro-help-search-list-item-content-light');
var optionCls = getPrefixCls('pro-help-search-list-item-content');
// css
var _useStyle = useStyle('Highlight', function (token) {
return _defineProperty(_defineProperty({}, ".".concat(lightCls), {
color: token.colorPrimary
}), ".".concat(optionCls), {
flex: 'auto',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
});
}),
wrapSSR = _useStyle.wrapSSR;
if (words.length === 0) return /*#__PURE__*/_jsx(_Fragment, {
children: label
});
// 创建正则表达式匹配关键词
var matchKeywordsRE = new RegExp(words.map(function (word) {
return word.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}).join('|'), 'gi');
var matchText = label;
var elements = [];
// 遍历匹配的文本将匹配项和非匹配项分别处理并放入elements数组中
while (matchText.length) {
var match = matchKeywordsRE.exec(matchText);
if (!match) {
elements.push(matchText);
break;
}
var start = match.index;
var matchLength = match[0].length + start;
elements.push(matchText.slice(0, start), /*#__PURE__*/React.createElement('span', {
className: lightCls
}, matchText.slice(start, matchLength)));
matchText = matchText.slice(matchLength);
}
return wrapSSR( /*#__PURE__*/React.createElement.apply(React, ['div', {
title: label,
className: optionCls
}].concat(elements)));
};
export var ProHelpSelect = function ProHelpSelect(_ref3) {
var iconClassName = _ref3.iconClassName,
props = _objectWithoutProperties(_ref3, _excluded);
var _useContext2 = useContext(ProHelpProvide),
dataSource = _useContext2.dataSource;
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
keyWord = _useState2[0],
setKeyWork = _useState2[1];
var _useContext3 = useContext(ProProvider),
hashId = _useContext3.hashId;
var debounceSetKeyWork = useDebounceFn( /*#__PURE__*/function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(key) {
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
return _context.abrupt("return", setKeyWork(key));
case 1:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x) {
return _ref4.apply(this, arguments);
};
}(), 20);
var _useState3 = useState(false),
_useState4 = _slicedToArray(_useState3, 2),
open = _useState4[0],
setOpen = _useState4[1];
return /*#__PURE__*/_jsxs(_Fragment, {
children: [!open ? /*#__PURE__*/_jsx("div", {
className: classNames(iconClassName, hashId),
children: /*#__PURE__*/_jsx(SearchOutlined, {
title: "search panel",
onClick: function onClick() {
setOpen(true);
}
})
}) : null, open ? /*#__PURE__*/_jsx(Select, _objectSpread(_objectSpread(_objectSpread({
placeholder: "please input search text",
showSearch: true
}, compatibleBorder(false)), {}, {
onBlur: function onBlur() {
setOpen(false);
},
size: "small"
}, props), {}, {
onSearch: function onSearch(value) {
debounceSetKeyWork.cancel();
debounceSetKeyWork.run(value);
},
filterOption: function filterOption(input, option) {
var _option$title;
return ((_option$title = option === null || option === void 0 ? void 0 : option.title) !== null && _option$title !== void 0 ? _option$title : '').toLowerCase().includes(input.toLowerCase());
},
popupMatchSelectWidth: false,
options: dataSource.map(function (item) {
var _item$children;
return {
label: /*#__PURE__*/_jsx(Highlight, {
label: item.title,
words: [keyWord].filter(Boolean)
}),
title: item.title,
value: item.key,
options: (_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.map(function (sunItem) {
return {
label: /*#__PURE__*/_jsx(Highlight, {
label: sunItem.title,
words: [keyWord].filter(Boolean)
}),
title: sunItem.title,
value: sunItem.key,
dataItemKey: item.key
};
})
};
})
})) : null]
});
};

View File

@@ -0,0 +1,49 @@
import React from 'react';
import type { ProHelpDataSource, ProHelpDataSourceChildren } from './HelpProvide';
import { ProHelpProvide } from './HelpProvide';
import { ProHelpSelect } from './Search';
export * from './ProHelpContentPanel';
export * from './ProHelpDrawer';
export * from './ProHelpModal';
export * from './ProHelpPanel';
export * from './ProHelpPopover';
export * from './RenderContentPanel';
export { ProHelpProvide, ProHelpSelect };
export type { ProHelpDataSource, ProHelpDataSourceChildren };
export type ProHelpProps<ValueType> = {
/**
* 帮助文档的数据源,包含一组帮助文档数据,每个数据包含标题和内容等信息。
*/
dataSource: ProHelpDataSource<ValueType>[];
/**
* 帮助组件的子组件,用于渲染自定义的帮助内容。
* 是一个键值对结构的集合,其中:
* 键key为字符串类型
* 值value为一个函数类型该函数接受两个参数一个名为 item 的 ProHelpDataSourceChildren 类型的对象,表示一个 ProHelp 数据源子项的子项;
* 一个名为 index 的数字类型参数,表示该子项在父级子项数组中的索引。
* 该函数返回一个 ReactNode 类型的元素,用于表示该 ProHelp 数据源子项子项应该渲染的 UI 元素。
* 这个 Map 的作用是将 ProHelp 数据源子项子项的 valueType 属性与对应的渲染函数进行映射,从而实现在渲染 ProHelp 数据源时动态地选择渲染方法。
* 在实际使用时,我们可以通过判断子项的 valueType 属性,从 valueTypeMap 中取出对应的渲染函数,再将该子项和渲染函数作为参数传入 renderDataSourceItem 函数中即可。
*/
valueTypeMap?: Map<string, (item: ProHelpDataSourceChildren<ValueType>, index: number) => React.ReactNode>;
/**
* 帮助组件的子组件,用于渲染自定义的帮助内容。
*/
children?: React.ReactNode;
/**
* 加载数据源的函数,如果把数据源设置为 async load就可以使用这个功能。
*/
onLoadContext?: (key: React.Key, context: ProHelpDataSource<ValueType>['children'][number]) => Promise<ProHelpDataSourceChildren<ValueType>[]>;
};
export type ProHelpContentPanelProps = {
/**
* 控制当前选中的帮助文档
*/
selectedKey: React.Key;
className?: string;
parentItem?: ProHelpDataSource<any>;
onScroll?: (key?: string) => void;
};
export declare const ProHelp: <ValueTypeMap = {
text: any;
}>({ dataSource, valueTypeMap, onLoadContext, ...props }: ProHelpProps<ValueTypeMap>) => import("react/jsx-runtime").JSX.Element;

View File

@@ -0,0 +1,28 @@
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["dataSource", "valueTypeMap", "onLoadContext"];
import React from 'react';
import { ProHelpProvide } from "./HelpProvide";
import { ProHelpSelect } from "./Search";
import { jsx as _jsx } from "react/jsx-runtime";
export * from "./ProHelpContentPanel";
export * from "./ProHelpDrawer";
export * from "./ProHelpModal";
export * from "./ProHelpPanel";
export * from "./ProHelpPopover";
export * from "./RenderContentPanel";
export { ProHelpProvide, ProHelpSelect };
export var ProHelp = function ProHelp(_ref) {
var dataSource = _ref.dataSource,
_ref$valueTypeMap = _ref.valueTypeMap,
valueTypeMap = _ref$valueTypeMap === void 0 ? new Map() : _ref$valueTypeMap,
onLoadContext = _ref.onLoadContext,
props = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/_jsx(ProHelpProvide.Provider, {
value: {
onLoadContext: onLoadContext,
dataSource: dataSource,
valueTypeMap: valueTypeMap
},
children: props.children
});
};

View File

@@ -0,0 +1,11 @@
/// <reference types="react" />
import { Keyframes } from '@ant-design/cssinjs';
import type { ProAliasToken } from '@ant-design/pro-provider';
export interface ProHelpToken extends ProAliasToken {
componentCls: string;
}
export declare const actionsInputAnimal: Keyframes;
export declare function useStyle(prefixCls: string): {
wrapSSR: (node: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>) => import("react").JSX.Element;
hashId: string;
};

View File

@@ -0,0 +1,100 @@
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { Keyframes } from '@ant-design/cssinjs';
import { useStyle as useAntdStyle } from '@ant-design/pro-provider';
export var actionsInputAnimal = new Keyframes('actionsInputAnimal', {
'0%': {
width: '0px'
},
'30%': {
width: '20px'
},
'100%': {
width: '120px'
}
});
var genProHelpStyle = function genProHelpStyle(token) {
return _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(token.componentCls, "-popover-text"), {
color: token.colorPrimary,
cursor: 'pointer',
boxSizing: 'border-box'
}), "".concat(token.componentCls, "-popover-content"), {
maxWidth: 300,
height: '600px',
maxHeight: 'calc(100vh - 200px)',
overflow: 'auto',
paddingInline: 20,
paddingBlockStart: 24,
paddingBlockEnd: 32,
boxSizing: 'border-box'
}), "".concat(token.componentCls, "-left-panel"), {
overflow: 'auto',
boxSizing: 'border-box',
borderInlineEnd: "".concat(token === null || token === void 0 ? void 0 : token.lineWidth, "px solid ").concat(token === null || token === void 0 ? void 0 : token.colorBorderSecondary),
minHeight: '648px',
minWidth: 190,
maxWidth: 190,
'&-menu': {
width: 190,
boxSizing: 'border-box',
minWidth: 190,
height: 'calc(100% - 40px)',
marginBlock: 20
}
}), "".concat(token.componentCls, "-content-panel"), {
minWidth: '200px',
overflow: 'auto',
flex: 1,
display: 'flex',
flexDirection: 'column',
boxSizing: 'border-box',
minHeight: '648px',
img: {
width: '100%'
}
}), "".concat(token.componentCls, "-content-render"), {
paddingBlock: 20,
paddingInline: 24,
flex: 1
}), "".concat(token.componentCls, "-content-footer"), {
padding: 8
}), "".concat(token.componentCls, "-actions"), {
display: 'flex',
boxSizing: 'border-box',
gap: token.marginSM,
'&-item': {
display: 'flex',
boxSizing: 'border-box',
alignItems: 'center',
justifyItems: 'center',
padding: 4,
height: 24,
minWidth: 24,
cursor: 'pointer',
borderRadius: token.borderRadius,
'&:hover': {
backgroundColor: token.colorBgTextHover
}
},
'&-input': {
margin: 0,
maxWidth: 120,
padding: 0,
width: '120px',
boxSizing: 'border-box',
borderRadius: token.borderRadius,
backgroundColor: token.colorBgTextHover,
animationName: actionsInputAnimal,
animationDuration: '0.1s',
animationTimingFunction: 'linear'
}
});
};
export function useStyle(prefixCls) {
return useAntdStyle('ProHelp', function (token) {
var ProLayoutHeaderToken = _objectSpread(_objectSpread({}, token), {}, {
componentCls: ".".concat(prefixCls)
});
return [genProHelpStyle(ProLayoutHeaderToken)];
});
}