fix: 完善大图 buttonList

This commit is contained in:
YuanHongbo 2024-04-20 15:36:36 +08:00
parent 4230353aea
commit a3aefaf499
5 changed files with 142 additions and 104 deletions

View File

@ -1,54 +1,83 @@
import React, {useState ,useMemo ,ReactNode} from 'react';
import React, { useState, useMemo, ReactNode, useRef, useEffect } from 'react';
import { Button, Col, Dropdown, Row } from 'antd';
import { Gutter } from 'antd/es/grid/row';
import './index.less';
import { Button, Col, Dropdown, Row } from 'antd/es';
import { Gutter } from '../grid/row';
type ButtonItem = {
export interface IButtonItem {
key: string;
text: ReactNode;
onClick: () => void;
children?: Array<ButtonItem>;
children?: Array<Omit<IButtonItem, 'weight'>>;
// 用于排序
weight: number;
weight: number;
icon?: ReactNode
className?: string;
isCenter?: boolean;
};
type Props = {
buttons: Array<ButtonItem>
customButton?: ButtonItem;
export interface IButtonItemWithoutWeight extends Omit<IButtonItem, 'weight'> { }
export interface ButtonListProps {
buttons: Array<IButtonItem>
gutter?: Gutter;
};
const componentName = 'zhst-button-list';
const ButtonList: React.FC<Props> = (Props) => {
const { buttons, customButton ,gutter} = Props
const ButtonList: React.FC<ButtonListProps> = (Props) => {
const { buttons, gutter } = Props
const [activeKey, setActiveKey] = useState<string | null>(null);
const buttonListRef = useRef<HTMLDivElement>(null);
const [buttonListWrapMarginLeft, setButtonListWrapMarginLeft] = useState(0)
const centerButtonRef = useRef<HTMLDivElement>(null);
const sortedButtons = useMemo(() => {
let buttonList=[...buttons]
if (customButton) {
buttonList = [...buttons,customButton]
}
let buttonList = [...buttons]
return buttonList.sort((a, b) => a.weight - b.weight);
}, [buttons, customButton]);
const handleButtonClick = (key: string, item: ButtonItem) => {
return buttonList?.sort((a, b) => a.weight - b.weight);
}, [buttons]);
const handleButtonClick = (key: string, item: IButtonItem) => {
setActiveKey(activeKey === key ? null : key);
if (!item.children ) {
if (!item.children) {
item.onClick();
}
};
useEffect(() => {
// 如果获取不到 需要居中的
if (!centerButtonRef) return
// 获取 buttonList 宽度
const buttonListWidth: number = buttonListRef.current?.offsetWidth as number;
// 获取 centerButton 宽度
const centerButtonWidth: number = centerButtonRef.current?.offsetWidth as number
// 获取 buttonList 相对视口左偏移量
const buttonListOffset: number = buttonListRef.current?.offsetLeft as number
// 获取 buttonList 中心点 距视口左边距离
const buttonListCenterOffset = buttonListOffset + buttonListWidth / 2
// 获取 centerButton 中心点 相对视口左偏移量
const centerButtonOffset: number = centerButtonRef.current?.offsetLeft as number + centerButtonWidth / 2
/*
centerButton
buttonList - centerButton
buttonListWrap marginLeft
*/
// 这里为什么要 * 2 由于 justify-content: center; marginLeft 需要 * 2才是 正确的值 具体原因 还在研究
const buttonListWrapMarginLeft = (buttonListCenterOffset - centerButtonOffset) * 2
setButtonListWrapMarginLeft(buttonListWrapMarginLeft)
}, [])
return (
<div className={componentName}>
<Row gutter={gutter}>
{sortedButtons.map((item) => (
<Col key={item.key} >
<div className={componentName} ref={buttonListRef}>
<Row gutter={gutter} className={`${componentName}-list-wrap`} style={{ marginLeft: buttonListWrapMarginLeft }} >
{sortedButtons?.map((item) => (
<Col key={item.key} ref={item?.isCenter ? centerButtonRef : undefined} >
{item.children ? (
<Dropdown
menu={{
@ -59,15 +88,20 @@ const ButtonList: React.FC<Props> = (Props) => {
})),
}}
open={activeKey === item.key}
onOpenChange={(visible:boolean) => {
onOpenChange={(visible: boolean) => {
if (!visible) setActiveKey(null);
}}
trigger={['click']}
>
<Button type="text" icon={item.icon} onClick={() => handleButtonClick(item.key, item)}>{item.text}</Button>
<Button type="text" icon={item.icon} onClick={() => handleButtonClick(item.key, item)}>{item.text}</Button>
</Dropdown>
) : (
<Button type="text" icon={item.icon} onClick={() => handleButtonClick(item.key, item)}>{item.text}</Button>
<Button type="text"
icon={item.icon}
onClick={() => handleButtonClick(item.key, item)}
>
{item.text}
</Button>
)}
</Col>
))}

View File

@ -0,0 +1,69 @@
import React, { useState, useMemo } from 'react';
import { Space } from 'antd'
import { DownloadOutlined } from '@ant-design/icons';
import { ButtonList } from '@zhst/meta'
import { ButtonListProps } from '../ButtonList';
import "./index.less"
export default () => {
const [isPlay, setIsPlay] = useState(true);
const props: ButtonListProps = useMemo(() => {
return {
buttons: [
{
key: 'button1',
text: '一级按钮1',
onClick: () => console.log('一级按钮1被点击'),
children: [
{ key: 'subButton1-1', text: '二级按钮1-1', onClick: () => console.log('二级按钮1-1被点击'), icon: <DownloadOutlined /> },
{ key: 'subButton1-2', text: '二级按钮1-2', onClick: () => console.log('二级按钮1-2被点击') },
],
weight: 1,
// icon:<DownloadOutlined />,
},
{
key: 'button2',
text: '一级按钮2',
onClick: () => console.log('一级按钮2被点击'),
weight: 2,
},
{
key: '播放',
text: isPlay ? '播放按钮' : '图片按钮',
onClick: () => { setIsPlay(!isPlay) },
weight: 3,
isCenter: true
},
{
key: 'button3',
text: '一级按钮3',
onClick: () => console.log('一级按钮3被点击'),
weight: 3,
},
{
key: 'button4',
text: '一级按钮4',
onClick: () => console.log('一级按钮4被点击'),
weight: 4,
// isCenter: true
},
{
key: 'button5',
text: '一级按钮5',
onClick: () => console.log('一级按钮5被点击'),
children: [
{ key: 'subButton5-1', text: '二级按钮5-1', onClick: () => console.log('二级按钮5-1被点击') },
],
weight: 5,
},
],
}
}, [isPlay])
return (
<Space size={[8, 16]} direction="vertical">
<ButtonList {...props} />
</Space>
)
}

View File

@ -0,0 +1,5 @@
#buttonlist-demo-base {
.dumi-default-previewer-demo>div {
width: 100%;
}
}

View File

@ -1,10 +1,11 @@
.zhst-button-list {
width: 100%;
display: flex;
justify-content: center;
.ant-btn-text:hover{
background: none !important;
background: none !important ;
color: #247fdb !important;
}
}

View File

@ -7,78 +7,7 @@ title: ButtonList 按钮列表组件
# ButtonList 按钮列表组件
```jsx
import React, { useState, useRef ,useMemo} from 'react';
import { Button, Space } from 'antd'
import { DownloadOutlined } from '@ant-design/icons';
import { ButtonList } from '@zhst/meta'
export default () => {
const [isPlay,setIsPlay] = useState(true);
const props = useMemo(() => {
return {
buttons: [
{
key: 'button1',
text: '一级按钮1',
onClick: () => console.log('一级按钮1被点击'),
children: [
{ key: 'subButton1-1', text: '二级按钮1-1', onClick: () => console.log('二级按钮1-1被点击') , icon:<DownloadOutlined /> },
{ key: 'subButton1-2', text: '二级按钮1-2', onClick: () => console.log('二级按钮1-2被点击') },
],
weight: 1,
// icon:<DownloadOutlined />,
},
{
key: 'button2',
text: '一级按钮2',
onClick: () => console.log('一级按钮2被点击'),
children: null,
weight: 2,
},
{
key: 'button3',
text: '一级按钮3',
onClick: () => console.log('一级按钮3被点击'),
children: null,
weight: 3,
},
{
key: 'button4',
text: '一级按钮4',
onClick: () => console.log('一级按钮4被点击'),
weight: 4,
},
{
key: 'button5',
text: '一级按钮5' ,
onClick: () => console.log('一级按钮5被点击'),
children: [
{ key: 'subButton5-1', text: '二级按钮5-1', onClick: () => console.log('二级按钮5-1被点击') },
],
weight: 5,
},
],
customButton:
{
key: '播放',
text: isPlay ? '播放按钮' : '图片按钮',
onClick: () => {setIsPlay(!isPlay)},
weight: 3.5,
}
}},[isPlay])
return (
<Space size={[8, 16]} direction="vertical">
<ButtonList {...props}/>
</Space>
)
}
```
<code src="./demo/base.tsx"></code>
## API