Merge branch 'feat/selectTreev2' into develop
This commit is contained in:
commit
d7a29f51b7
@ -1,12 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { Button } from '@zhst/meta'
|
|
||||||
import { useThrottleFn } from '@zhst/hooks'
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
|
|
||||||
const { run } = useThrottleFn(() => console.log('123'))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button onClick={() => run()} >测试</Button>
|
|
||||||
)
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ import { IRecord } from '../../../WarningRecordCard';
|
|||||||
import { ViewLargerImageModalRef } from '../../../ViewLargerImageModal';
|
import { ViewLargerImageModalRef } from '../../../ViewLargerImageModal';
|
||||||
import WarningRecordCard from '../../../WarningRecordCard';
|
import WarningRecordCard from '../../../WarningRecordCard';
|
||||||
import ViewLargerImageModal from '../../../ViewLargerImageModal';
|
import ViewLargerImageModal from '../../../ViewLargerImageModal';
|
||||||
import { Empty, Space, Spin } from 'antd';
|
import { Empty, Space, Spin } from '@zhst/meta';
|
||||||
import { pxToRem } from '@zhst/func'
|
import { pxToRem } from '@zhst/func'
|
||||||
import { LoadingOutlined } from '@ant-design/icons';
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import VideoPlayerCard from '../../../VideoPlayerCard';
|
import VideoPlayerCard from '../../../VideoPlayerCard';
|
||||||
import { VideoPlayerCardProps } from '../../../VideoPlayerCard';
|
import { VideoPlayerCardProps } from '../../../VideoPlayerCard';
|
||||||
import { Row, Col, Segmented, theme } from 'antd';
|
import { Row, Col, Segmented, theme } from '@zhst/meta';
|
||||||
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
|
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
|
||||||
import { pxToRem } from '@zhst/func'
|
import { pxToRem } from '@zhst/func'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useImperativeHandle, useRef, useState, forwardRef, useContext } from 'react';
|
import React, { useImperativeHandle, useRef, useState, forwardRef, useContext } from 'react';
|
||||||
import { Modal, ModalProps, Space, SpaceProps, theme } from 'antd';
|
import { Modal, ModalProps, Space, SpaceProps, theme } from '@zhst/meta';
|
||||||
import { DownloadOutlined } from '@ant-design/icons';
|
import { DownloadOutlined } from '@ant-design/icons';
|
||||||
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Card, Space, Divider, CardProps, theme } from 'antd';
|
import { Card, Space, Divider, CardProps, theme } from '@zhst/meta';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React, { FC, useState, useContext, ReactNode } from 'react';
|
import React, { FC, useState, useContext, ReactNode } from 'react';
|
||||||
import { ModalFormProps } from '@ant-design/pro-components'
|
import { ModalFormProps } from '@ant-design/pro-components'
|
||||||
import { Input, Dropdown } from 'antd'
|
|
||||||
import {
|
import {
|
||||||
ButtonProps,
|
ButtonProps,
|
||||||
ConfigProvider,
|
ConfigProvider,
|
||||||
|
Input,
|
||||||
|
Dropdown,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Button,
|
Button,
|
||||||
Divider,
|
Divider,
|
||||||
|
@ -21,6 +21,8 @@ export type { ViewLargerImageModalRef, ViewLargerImageModalProps } from './ViewL
|
|||||||
export { default as ViewLargerImageModal, useViewLargerImageModal } from './ViewLargerImageModal'
|
export { default as ViewLargerImageModal, useViewLargerImageModal } from './ViewLargerImageModal'
|
||||||
export type { VideoPlayerCardProps } from './VideoPlayerCard'
|
export type { VideoPlayerCardProps } from './VideoPlayerCard'
|
||||||
export { default as VideoPlayerCard } from './VideoPlayerCard'
|
export { default as VideoPlayerCard } from './VideoPlayerCard'
|
||||||
|
export type { TreePanelProps, TreePanelRefProps } from './treePanel'
|
||||||
|
export { default as TreePanel } from './treePanel'
|
||||||
export { default as RealTimeMonitor } from './RealTimeMonitor'
|
export { default as RealTimeMonitor } from './RealTimeMonitor'
|
||||||
export { default as InfiniteList } from './infiniteList'
|
export { default as InfiniteList } from './infiniteList'
|
||||||
export type { InfiniteListProps, InfiniteListRefProps } from './infiniteList'
|
export type { InfiniteListProps, InfiniteListRefProps } from './infiniteList'
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { forwardRef, ReactNode, useContext, useEffect, useImperativeHandle, useRef } from 'react'
|
import React, { forwardRef, ReactNode, useContext, useEffect, useImperativeHandle, useRef } from 'react'
|
||||||
import { ConfigProvider } from '@zhst/meta';
|
import { ConfigProvider, Spin, SpinProps } from '@zhst/meta';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import InfiniteScroll from 'react-infinite-scroll-component';
|
import InfiniteScroll from 'react-infinite-scroll-component';
|
||||||
import { Spin, SpinProps } from 'antd';
|
|
||||||
import { useSize } from '@zhst/hooks';
|
import { useSize } from '@zhst/hooks';
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { forwardRef, useContext, useImperativeHandle, useRef } from 'react';
|
import React, { forwardRef, useContext, useImperativeHandle, useRef } from 'react';
|
||||||
import { Button, Modal, ModalProps, Select, SelectProps, Space, theme } from 'antd';
|
import { ConfigProvider, CropperImage, Scanner, CropperImageProps, CropperImageRefProps, Button, Modal, ModalProps, Select, SelectProps, Space, theme } from '@zhst/meta'
|
||||||
import { ConfigProvider, CropperImage, Scanner, CropperImageProps, CropperImageRefProps } from '@zhst/meta'
|
|
||||||
import { IconFont } from '@zhst/icon'
|
import { IconFont } from '@zhst/icon'
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TreeDataNode } from 'antd';
|
import { TreeDataNode } from '@zhst/meta';
|
||||||
import BoxTree from './boxTree';
|
import BoxTree from './boxTree';
|
||||||
|
|
||||||
export interface TreeData extends TreeDataNode {
|
export interface TreeData extends TreeDataNode {
|
||||||
|
267
packages/biz/src/treePanel/TreePanel.tsx
Normal file
267
packages/biz/src/treePanel/TreePanel.tsx
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
import React, { FC, useContext, ReactNode } from 'react';
|
||||||
|
import {
|
||||||
|
ConfigProvider,
|
||||||
|
Input,
|
||||||
|
Dropdown,
|
||||||
|
Tooltip,
|
||||||
|
Button,
|
||||||
|
DataNode as TreeDataNode,
|
||||||
|
Tree as BoxTree,
|
||||||
|
TreeProps as BoxTreeProps,
|
||||||
|
TreeProps,
|
||||||
|
InputProps,
|
||||||
|
DropDownProps,
|
||||||
|
SelectProps,
|
||||||
|
Select
|
||||||
|
} from '@zhst/meta';
|
||||||
|
import { IconFont } from '@zhst/icon';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
interface IOption {
|
||||||
|
label: string
|
||||||
|
key: string
|
||||||
|
icon?: string | ReactNode
|
||||||
|
disabled?: boolean;
|
||||||
|
showTooltip?: boolean;
|
||||||
|
onClick?: () => void
|
||||||
|
className?: string;
|
||||||
|
dropdownConfig?: DropDownProps
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITag {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
icon?: ReactNode
|
||||||
|
parentNode?: string
|
||||||
|
children?: ITag[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BoxPanelProps {
|
||||||
|
treeType?: 'directory' | 'normal'
|
||||||
|
searchInputProps?: InputProps
|
||||||
|
showOptions?: boolean
|
||||||
|
showSelectBar?: boolean // 显示搜索框
|
||||||
|
filterSelectProps?: SelectProps
|
||||||
|
onSelect?: SelectProps['onChange']
|
||||||
|
treeProps?: Partial<BoxTreeProps>
|
||||||
|
data: TreeDataNode[]
|
||||||
|
onSearch?: (e: any) => void
|
||||||
|
onItemCheck?: TreeProps['onCheck']
|
||||||
|
onItemSelect?: TreeProps['onSelect']
|
||||||
|
customImport?: ReactNode | string // 自定义搜索栏边上的过滤图标
|
||||||
|
extra?: ReactNode | string // 搜索栏下面的插槽
|
||||||
|
prefixCls?: string
|
||||||
|
showSearchBar?: boolean // 是否显示搜索栏
|
||||||
|
noFilter?: boolean // 是否显示搜索拓展 icon
|
||||||
|
filterList?: IOption[]
|
||||||
|
optionList?: IOption[]
|
||||||
|
showTagPanel?: boolean // 标签插槽
|
||||||
|
tagList?: ITag[] // 标签列表
|
||||||
|
tagExpandAll?: boolean // 展开所有
|
||||||
|
onTagCheck?: (value: string, tag: ITag) => void;
|
||||||
|
checkedTags?: string[]
|
||||||
|
onResetTags?: () => void
|
||||||
|
onTagExpand?: (e: any) => void
|
||||||
|
tagFootRender?: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
const { DirectoryTree } = BoxTree
|
||||||
|
|
||||||
|
const BoxPanel: FC<BoxPanelProps> = (props) => {
|
||||||
|
const {
|
||||||
|
treeType = 'directory',
|
||||||
|
searchInputProps,
|
||||||
|
showOptions = true,
|
||||||
|
showSelectBar,
|
||||||
|
filterSelectProps,
|
||||||
|
extra,
|
||||||
|
noFilter,
|
||||||
|
data = [],
|
||||||
|
treeProps,
|
||||||
|
onSelect,
|
||||||
|
onSearch,
|
||||||
|
onItemCheck,
|
||||||
|
onItemSelect,
|
||||||
|
showSearchBar = true,
|
||||||
|
optionList = [],
|
||||||
|
filterList = [],
|
||||||
|
showTagPanel,
|
||||||
|
tagList,
|
||||||
|
tagExpandAll,
|
||||||
|
onTagExpand,
|
||||||
|
checkedTags = [],
|
||||||
|
onTagCheck,
|
||||||
|
onResetTags,
|
||||||
|
tagFootRender,
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
customImport: customFilter
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('biz-tree-panel', customizePrefixCls);
|
||||||
|
const CurrentTree = treeType === 'directory' ? DirectoryTree : BoxTree
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化拓展 filter
|
||||||
|
* @param _list
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const initFilter = (_list?: BoxPanelProps['filterList']) => {
|
||||||
|
const WithDropdown = (dom: ReactNode, isShow?: boolean, _config?: DropDownProps) => {
|
||||||
|
if (!isShow) {
|
||||||
|
return dom
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown placement="bottomLeft" arrow {..._config}>
|
||||||
|
{dom}
|
||||||
|
</Dropdown>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return _list?.map(item => (
|
||||||
|
<Tooltip
|
||||||
|
title={item.label}
|
||||||
|
open={item.showTooltip}
|
||||||
|
>
|
||||||
|
{WithDropdown(
|
||||||
|
<Button className={classNames(componentName + '-search-btns-btn')} type="text" onClick={item.onClick} icon={item.icon} />,
|
||||||
|
item.type === 'dropdown',
|
||||||
|
item.dropdownConfig
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化拓展 filter
|
||||||
|
* @param _list
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const initOptions = (_list?: BoxPanelProps['optionList']) => {
|
||||||
|
return _list?.map((item, idx) => (
|
||||||
|
<>
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
<div key={idx} className={classNames(componentName + '-btns-btn')}>
|
||||||
|
{item.icon}
|
||||||
|
<span className={classNames(componentName + '-btns-btn-label', item.className)}>{item.label}</span>
|
||||||
|
</div>
|
||||||
|
{idx % 2 !== 0 && (<br/>)}
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化标签面板
|
||||||
|
* @param _tagList
|
||||||
|
* @param sort 是否分类
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const initTagPanel = (_tagList: BoxPanelProps['tagList'], sort?: boolean) => {
|
||||||
|
// 正常标签渲染
|
||||||
|
const commonTag = (_tagProps: ITag) => (
|
||||||
|
<span
|
||||||
|
className={classNames(
|
||||||
|
componentName + '-tags-tag_common',
|
||||||
|
{[componentName + '-tags-tag_checked']: checkedTags.includes(_tagProps.value)}
|
||||||
|
)}
|
||||||
|
key={_tagProps.value}
|
||||||
|
onClick={() => onTagCheck?.(_tagProps.value, _tagProps)}
|
||||||
|
>{_tagProps.label}</span>
|
||||||
|
)
|
||||||
|
// 包装父级标签
|
||||||
|
const _withFather = (tag: ITag) => (
|
||||||
|
<div key={tag.value}>
|
||||||
|
<span className={classNames(componentName + '-tags-tag')}>{tag.label}</span>
|
||||||
|
{tag.children?.map?.(_tag => commonTag(_tag))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
return _tagList?.map(tag => {
|
||||||
|
if (tag.children?.length && sort) {
|
||||||
|
return _withFather(tag)
|
||||||
|
} else {
|
||||||
|
return commonTag(tag)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={componentName}>
|
||||||
|
{/* 搜索栏 */}
|
||||||
|
{showSearchBar && (
|
||||||
|
<div className={classNames(componentName + '-search')}>
|
||||||
|
<Input
|
||||||
|
className={classNames(componentName + '-search-input')}
|
||||||
|
onChange={(e) => onSearch?.(e)}
|
||||||
|
placeholder='请输入盒子名称'
|
||||||
|
{...searchInputProps}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* 搜索栏 */}
|
||||||
|
{showSelectBar && (
|
||||||
|
<div className={classNames(componentName + '-search')}>
|
||||||
|
<Select
|
||||||
|
className={classNames(componentName + '-search-input')}
|
||||||
|
onChange={onSelect}
|
||||||
|
{...filterSelectProps}
|
||||||
|
/>
|
||||||
|
{customFilter || (!noFilter && (
|
||||||
|
<div
|
||||||
|
className={classNames(componentName + '-search-btns')}
|
||||||
|
>
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
{initFilter(filterList)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showTagPanel && (
|
||||||
|
<div className={classNames(componentName + '-tags')}>
|
||||||
|
<div className={classNames(componentName + '-tags-title')}>
|
||||||
|
标签
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
componentName + '-tags-tag_option',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{tagExpandAll && (
|
||||||
|
<span
|
||||||
|
className={classNames(componentName + '-tags-tag_option-btn')}
|
||||||
|
onClick={onResetTags}
|
||||||
|
>重置</span>
|
||||||
|
)}
|
||||||
|
<span
|
||||||
|
className={classNames(componentName + '-tags-tag_option-btn')}
|
||||||
|
onClick={onTagExpand}
|
||||||
|
>{tagExpandAll ? '收起' : '更多'}<IconFont icon={tagExpandAll ? 'icon-shangjiantou' : 'icon-xiajiantou'} /></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{initTagPanel(tagList, tagExpandAll)}
|
||||||
|
{tagFootRender}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* 默认操作按钮 */}
|
||||||
|
{showOptions && (
|
||||||
|
<div className={classNames(componentName + '-btns')}>
|
||||||
|
{initOptions(optionList)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{extra}
|
||||||
|
<CurrentTree
|
||||||
|
className={classNames(componentName + '-tree')}
|
||||||
|
treeData={data}
|
||||||
|
showIcon={false}
|
||||||
|
blockNode
|
||||||
|
onSelect={onItemSelect}
|
||||||
|
onCheck={onItemCheck}
|
||||||
|
{...treeProps}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BoxPanel
|
0
packages/biz/src/treePanel/constants.ts
Normal file
0
packages/biz/src/treePanel/constants.ts
Normal file
135
packages/biz/src/treePanel/demo/basic.tsx
Normal file
135
packages/biz/src/treePanel/demo/basic.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import React, { useState, useRef } from 'react';
|
||||||
|
import { TreePanel } from '@zhst/biz';
|
||||||
|
import { Badge, Checkbox } from '@zhst/meta'
|
||||||
|
import { treeData, boxDataSource } from './mock'
|
||||||
|
import { ImportOutlined, FolderAddOutlined, CloseCircleOutlined, FilterOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
const demo = () => {
|
||||||
|
const [checkedTags, setCheckedTags] = useState<string[]>([]);
|
||||||
|
const [tagExpandAll, setTagExpandAll] = useState(false);
|
||||||
|
const [showTagPanel, setShowTagPanel] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '12px', width: '240px', border: '1px solid #09f' }}>
|
||||||
|
<TreePanel
|
||||||
|
data={boxDataSource}
|
||||||
|
showTagPanel={showTagPanel}
|
||||||
|
tagExpandAll={tagExpandAll}
|
||||||
|
showSelectBar
|
||||||
|
onTagCheck={(value) => setCheckedTags(pre => {
|
||||||
|
if (pre.includes(value)) {
|
||||||
|
return pre.filter(item => item !== value)
|
||||||
|
} else {
|
||||||
|
return [...pre, value]
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
onResetTags={() => setCheckedTags([])}
|
||||||
|
checkedTags={checkedTags}
|
||||||
|
filterList={[
|
||||||
|
{
|
||||||
|
label: '过滤',
|
||||||
|
key: 'multi',
|
||||||
|
icon: <FilterOutlined />,
|
||||||
|
type: 'dropdown',
|
||||||
|
showTooltip: false,
|
||||||
|
dropdownConfig: {
|
||||||
|
menu: {
|
||||||
|
// 自定义返回项
|
||||||
|
_internalRenderMenuItem: (originNode, menuItemProps, stateProps) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{originNode}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
selectable: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: <p style={{ margin: '0', textAlign: 'center' }} >全部</p>,
|
||||||
|
key: 'all',
|
||||||
|
onClick: () => console.log('多选1')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Badge status="success" />,
|
||||||
|
label: '多选1',
|
||||||
|
key: 'multi1',
|
||||||
|
onClick: () => console.log('多选1')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '多选2',
|
||||||
|
icon: <Badge status='error' />,
|
||||||
|
key: 'multi2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
extra={(
|
||||||
|
<div>
|
||||||
|
<span><Checkbox>全选</Checkbox></span>
|
||||||
|
<a style={{ float: 'right', color: '#09f' }} >批量操作</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
optionList={[
|
||||||
|
{
|
||||||
|
label: '导入盒子',
|
||||||
|
key: 'import',
|
||||||
|
icon: <ImportOutlined />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '新建组',
|
||||||
|
key: 'add',
|
||||||
|
icon: <FolderAddOutlined />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
key: 'del',
|
||||||
|
icon: <CloseCircleOutlined />,
|
||||||
|
props: {
|
||||||
|
danger: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
tagList={[
|
||||||
|
{
|
||||||
|
label: '标签组1',
|
||||||
|
value: '1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: '标签1-1',
|
||||||
|
value: '1-1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '标签1-2',
|
||||||
|
value: '1-2',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '标签组2',
|
||||||
|
value: '2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: '标签2-1',
|
||||||
|
value: '2-1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '标签2-2',
|
||||||
|
value: '2-2',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
onTagExpand={() => {
|
||||||
|
setTagExpandAll(pre => !pre)
|
||||||
|
setCheckedTags([])
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default demo;
|
54
packages/biz/src/treePanel/demo/mock.tsx
Normal file
54
packages/biz/src/treePanel/demo/mock.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { TreeData } from "@zhst/biz";
|
||||||
|
|
||||||
|
export const boxDataSource: TreeData[] = [
|
||||||
|
{
|
||||||
|
title: '全部盒子',
|
||||||
|
key: '0-0',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: '盒子组1',
|
||||||
|
key: '0-0-0',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: '摄像头1',
|
||||||
|
key: '0-0-0-0',
|
||||||
|
isCamera: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '摄像头2',
|
||||||
|
key: '0-0-0-1',
|
||||||
|
isCamera: true
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '盒子组2',
|
||||||
|
key: '0-0-1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: '摄像头4',
|
||||||
|
key: '0-0-1-0',
|
||||||
|
isCamera: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
export const treeData: TreeData[] = [
|
||||||
|
{ key: '0-1-0', title: '分组0-1-0', isLeaf: true, checkable: false },
|
||||||
|
{ key: '0-1-1', title: '分组0-1-1', isLeaf: true, checkable: false },
|
||||||
|
{ key: '0-1-2', title: '分组0-1-2', isLeaf: true, checkable: false },
|
||||||
|
{
|
||||||
|
key: '0-1-3',
|
||||||
|
title: '分组0-1-3',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-1-3-1', title: '分组0-1-3-1', isLeaf: true, isCamera: true },
|
||||||
|
{ key: '0-1-3-2', title: '分组0-1-3-2', isLeaf: true, isCamera: true },
|
||||||
|
{ key: '0-1-3-3', title: '分组0-1-3-3', isLeaf: true, isCamera: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
0
packages/biz/src/treePanel/demo/no
Normal file
0
packages/biz/src/treePanel/demo/no
Normal file
129
packages/biz/src/treePanel/index.less
Normal file
129
packages/biz/src/treePanel/index.less
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
.zhst-biz-tree-panel {
|
||||||
|
&-search {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btns {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btns {
|
||||||
|
&-btn {
|
||||||
|
margin-right: 16px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: .3s ease all;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
&-label {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-common {
|
||||||
|
flex: 1;
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-import {
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tags {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #595959;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tag {
|
||||||
|
margin-right: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #595959;
|
||||||
|
font-size: 14px;
|
||||||
|
transition:.3s ease all;
|
||||||
|
|
||||||
|
&_common {
|
||||||
|
margin-top: 6px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #191919;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
transition: .3s ease all;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: content-box;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #09f;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_checked {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #09f;
|
||||||
|
}
|
||||||
|
|
||||||
|
&_fz12 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&_option {
|
||||||
|
float: right;
|
||||||
|
&-btn {
|
||||||
|
margin-left: 12px;
|
||||||
|
color: #09f;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .3s ease all;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_absolute {
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
}
|
81
packages/biz/src/treePanel/index.md
Normal file
81
packages/biz/src/treePanel/index.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
category: Components
|
||||||
|
title: TreePanel 树面板
|
||||||
|
toc: content
|
||||||
|
demo:
|
||||||
|
cols: 2
|
||||||
|
group:
|
||||||
|
title: 数据展示
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 代码演示
|
||||||
|
|
||||||
|
<code src="./demo/basic.tsx">基本用法</code>
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| treeType | 树的类型 | 'directory' 'normal' | directory | --- |
|
||||||
|
| searchInputProps | antd-inputProps | --- | --- | --- |
|
||||||
|
| showOptions | --- | boolean | --- | --- |
|
||||||
|
| treeProps | --- | antd-treeProps | --- | --- |
|
||||||
|
| data | --- | TreeDataNode[] | [] | --- |
|
||||||
|
| onSearch | --- | (e: any) => void | - | --- |
|
||||||
|
| onItemCheck | --- | TreeProps['onCheck'] | - | --- |
|
||||||
|
| onItemSelect | --- | TreeProps['onSelect'] | - | --- |
|
||||||
|
| customImport | 自定义搜索栏边上的过滤图标 | ReactNode 、string | - | --- |
|
||||||
|
| extra | 数组件上方插槽 | ReactNode 、string | --- | --- |
|
||||||
|
| prefixCls | class前缀,用于覆盖class | string | --- | --- |
|
||||||
|
| showSelectBar | 显示搜索框 | boolean | false | --- |
|
||||||
|
| filterSelectProps | 搜索框 | antd-SelectProps | - | --- |
|
||||||
|
| showSearchBar | 显示搜索框 | boolean | false | --- |
|
||||||
|
| noFilter | 是否显示搜索拓展 | boolean | false | --- |
|
||||||
|
| filterList | 过滤插槽列表 | IOption[] | [] | --- |
|
||||||
|
| optionList | 操作按钮列表 | IOption[] | [] | --- |
|
||||||
|
| showTagPanel | 显示标签插槽 | boolean | false | --- |
|
||||||
|
| tagList | 标签列表 | ITag[] | [] | --- |
|
||||||
|
| onSelect | 搜索选中事件 | SelectProps['onChange'] | - | --- |
|
||||||
|
| tagExpandAll | 标签展开状态 | boolean | false | --- |
|
||||||
|
| onTagCheck | 标签点击事件 | (value: string, tag: ITag) => void; | false | --- |
|
||||||
|
| checkedTags | 标签选中状态 | string[] | [] | --- |
|
||||||
|
| onResetTags | 重置标签事件 | () => void | - | --- |
|
||||||
|
| onTagExpand | 标签展开事件 | (e: any) => void | - | --- |
|
||||||
|
| tagFootRender | 标签展开状态 | ReactNode, string | false | --- |
|
||||||
|
|
||||||
|
### IOption
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface IOption {
|
||||||
|
label: string
|
||||||
|
key: string
|
||||||
|
icon?: string | ReactNode
|
||||||
|
disabled?: boolean;
|
||||||
|
showTooltip?: boolean;
|
||||||
|
onClick?: () => void
|
||||||
|
className?: string;
|
||||||
|
dropdownConfig?: DropDownProps
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ITag
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface ITag {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
icon?: ReactNode
|
||||||
|
parentNode?: string
|
||||||
|
children?: ITag[]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 组件设计
|
||||||
|
|
||||||
|
该组件包含以下功能:
|
||||||
|
|
||||||
|
1. 顶部按钮支持
|
||||||
|
2. 输入框单行展示
|
||||||
|
3. 选择框和筛选框同一行
|
||||||
|
4. 按钮列表
|
7
packages/biz/src/treePanel/index.tsx
Normal file
7
packages/biz/src/treePanel/index.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiangzhixiong on 2024/06/04
|
||||||
|
*/
|
||||||
|
import TreePanel from './TreePanel'
|
||||||
|
export type { TreePanelProps, TreePanelRefProps } from './TreePanel'
|
||||||
|
|
||||||
|
export default TreePanel
|
@ -1,6 +1,5 @@
|
|||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
import { Button, ConfigProvider, theme, Flex, InputProps, TabsProps, Tabs, ButtonProps, Tree, TreeProps, DataNode as TreeDataNode } from '@zhst/meta'
|
import { Button, Input, ConfigProvider, theme, Flex, InputProps, TabsProps, Tabs, ButtonProps, Tree, TreeProps, DataNode as TreeDataNode } from '@zhst/meta'
|
||||||
import { Input } from 'antd'
|
|
||||||
import { IconFont } from '@zhst/icon'
|
import { IconFont } from '@zhst/icon'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import React, { FC, useState } from 'react';
|
||||||
import { Modal, ModalProps, Radio, RadioGroupProps, Select, SelectProps, TransferProps, TreeDataNode, TreeProps } from 'antd';
|
import { Modal, ModalProps, Radio, RadioGroupProps, Select, SelectProps, TransferProps, TreeDataNode, TreeProps } from '@zhst/meta';
|
||||||
import TreeTransfer from '../treeTransfer';
|
import TreeTransfer from '../treeTransfer';
|
||||||
import { TreeTransferProps } from '../treeTransfer'
|
import { TreeTransferProps } from '../treeTransfer'
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ export type {
|
|||||||
DirectoryTreeExpandAction,
|
DirectoryTreeExpandAction,
|
||||||
DirectoryTreeProps
|
DirectoryTreeProps
|
||||||
} from './tree';
|
} from './tree';
|
||||||
|
export { default as Spin } from './spin'
|
||||||
|
export type { SpinProps, SpinSize, SpinType } from './spin'
|
||||||
export { default as message } from './message'
|
export { default as message } from './message'
|
||||||
export { default as Button } from './button'
|
export { default as Button } from './button'
|
||||||
export type { ArgsProps } from './message'
|
export type { ArgsProps } from './message'
|
||||||
|
@ -26,8 +26,8 @@ const seedToken: SeedToken = {
|
|||||||
colorWarning: '#FAAD14',
|
colorWarning: '#FAAD14',
|
||||||
colorError: '#FF4D4F',
|
colorError: '#FF4D4F',
|
||||||
colorInfo: '#0099FF',
|
colorInfo: '#0099FF',
|
||||||
colorLink: '',
|
colorLink: '#0099FF',
|
||||||
colorTextBase: '',
|
colorTextBase: '#191919',
|
||||||
|
|
||||||
colorBgBase: '',
|
colorBgBase: '',
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ const seedToken: SeedToken = {
|
|||||||
sizePopupArrow: 16,
|
sizePopupArrow: 16,
|
||||||
|
|
||||||
// Control Base
|
// Control Base
|
||||||
controlHeight: 32,
|
controlHeight: 36,
|
||||||
|
|
||||||
// zIndex
|
// zIndex
|
||||||
zIndexBase: 0,
|
zIndexBase: 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user