mirror of
https://github.com/didi/KnowStreaming.git
synced 2026-01-04 03:42:08 +08:00
初始化3.0.0版本
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
.card-bar-container{
|
||||
padding:16px 24px;
|
||||
width: 100%;
|
||||
.card-bar-content{
|
||||
height: 88px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { Select, Form, Input, Switch, Radio, DatePicker, Row, Col, Collapse } from 'knowdesign';
|
||||
export interface CardBarProps {
|
||||
cardClumns: any[];
|
||||
}
|
||||
const CardBar = (props: CardBarProps) => {
|
||||
const { cardClumns } = props;
|
||||
const CardClumnsItem: any = (cardItem: any) => {
|
||||
const { cardClumnsItemData } = cardItem;
|
||||
return (
|
||||
<Row>
|
||||
<Row>
|
||||
<col>{cardClumnsItemData.icon}</col>
|
||||
<col>{cardClumnsItemData.title}</col>
|
||||
</Row>
|
||||
<Row>
|
||||
<col>{cardClumnsItemData.lable}</col>
|
||||
</Row>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="card-bar-container">
|
||||
<div className="card-bar-container">
|
||||
<div>
|
||||
<div>左侧</div>
|
||||
<div>
|
||||
<div>title</div>
|
||||
<div>
|
||||
<div>分数</div>
|
||||
<div>详情</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{cardClumns &&
|
||||
cardClumns.length != 0 &&
|
||||
cardClumns.map((index, item) => {
|
||||
return <CardClumnsItem key={index} cardClumnsItemData={item}></CardClumnsItem>;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default CardBar;
|
||||
@@ -0,0 +1,73 @@
|
||||
.list-with-hide-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.container-item {
|
||||
flex-shrink: 0;
|
||||
height: 20px;
|
||||
padding: 4px 6px;
|
||||
border-radius: 5px;
|
||||
margin-right: 4px;
|
||||
background: rgba(33, 37, 41, 0.08);
|
||||
font-size: 12px;
|
||||
color: #495057;
|
||||
text-align: center;
|
||||
line-height: 12px;
|
||||
opacity: 0;
|
||||
&.show {
|
||||
opacity: 1;
|
||||
}
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.expand-item {
|
||||
font-size: 12px;
|
||||
color: #495057;
|
||||
line-height: 12px;
|
||||
opacity: 0;
|
||||
&.show {
|
||||
opacity: 1;
|
||||
}
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.hide {
|
||||
position: absolute;
|
||||
z-index: -10000;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tags-with-hide-popover {
|
||||
.dcloud-popover-inner {
|
||||
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 12px rgba(0, 0, 0, 0.04), 0 6px 10px 0 rgba(0, 0, 0, 0.08);
|
||||
border-radius: 8px;
|
||||
&-content {
|
||||
padding: 10px 8px 4px 8px;
|
||||
}
|
||||
}
|
||||
.dcloud-popover-arrow-content {
|
||||
display: none !important;
|
||||
}
|
||||
.container-item-popover {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
max-width: 560px;
|
||||
.container-item {
|
||||
flex-shrink: 0;
|
||||
height: 20px;
|
||||
padding: 4px 6px;
|
||||
border-radius: 5px;
|
||||
margin-right: 4px;
|
||||
background: rgba(33, 37, 41, 0.08);
|
||||
font-size: 12px;
|
||||
color: #495057;
|
||||
text-align: center;
|
||||
line-height: 12px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { Popover } from 'knowdesign';
|
||||
import { TooltipPlacement } from 'knowdesign/lib/basic/tooltip';
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import './index.less';
|
||||
|
||||
type PropsType = {
|
||||
list: string[];
|
||||
expandTagContent: string | ((tagNum: number) => string);
|
||||
placement?: TooltipPlacement;
|
||||
};
|
||||
|
||||
type TagsState = {
|
||||
list: string[];
|
||||
isHideExpandNode: boolean;
|
||||
endI: number;
|
||||
calculated: boolean;
|
||||
};
|
||||
|
||||
// 获取 DOM 元素横向 margin 值
|
||||
const getNodeMargin = (node: Element) => {
|
||||
const nodeStyle = window.getComputedStyle(node);
|
||||
return [nodeStyle.marginLeft, nodeStyle.marginRight].reduce((pre, cur) => {
|
||||
return pre + Number(cur.slice(0, -2));
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// TODO: 页面宽度变化时重新计算
|
||||
export default (props: PropsType) => {
|
||||
const { list = [], expandTagContent, placement = 'bottomRight' } = props;
|
||||
list.sort();
|
||||
const ref = useRef(null);
|
||||
const [curState, setCurState] = useState<TagsState>({
|
||||
list,
|
||||
isHideExpandNode: true,
|
||||
endI: -1,
|
||||
calculated: false,
|
||||
});
|
||||
const [nextTagsList, setNextTagsList] = useState(list);
|
||||
|
||||
useEffect(() => {
|
||||
const f = () => {
|
||||
// 父盒子信息
|
||||
const box = ref.current;
|
||||
const boxWidth = box.offsetWidth;
|
||||
// 子元素信息
|
||||
const childrenList = Array.from(ref.current.children) as HTMLElement[] as any;
|
||||
const len = childrenList.length;
|
||||
const penultimateNode = childrenList[len - 2];
|
||||
const penultimateNodeOffsetRight = penultimateNode.offsetLeft + penultimateNode.offsetWidth - box.offsetLeft;
|
||||
// 如果内容超出展示区域,隐藏一部分
|
||||
if (penultimateNodeOffsetRight > boxWidth) {
|
||||
const lastNode = childrenList[len - 1];
|
||||
const childrenMarin = getNodeMargin(penultimateNode);
|
||||
let curWidth = lastNode.offsetWidth + getNodeMargin(lastNode);
|
||||
childrenList.some((children: any, i: number) => {
|
||||
// 计算下一个元素的宽度
|
||||
const extraWidth = children.offsetWidth + childrenMarin;
|
||||
// 如果加入下个元素后宽度未超出,则继续
|
||||
if (curWidth + extraWidth < boxWidth) {
|
||||
curWidth += extraWidth;
|
||||
return false;
|
||||
} else {
|
||||
// 否则记录当前索引值 i ,并退出
|
||||
setCurState({ list: nextTagsList, isHideExpandNode: false, endI: i, calculated: true });
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 隐藏 展示全部 对应的 DOM 元素
|
||||
setCurState({ list: nextTagsList, isHideExpandNode: true, endI: -1, calculated: true });
|
||||
}
|
||||
};
|
||||
|
||||
// 在 setTimeout 中执行,保证拿到元素此时已经渲染到页面上,能够拿到正确的数据
|
||||
setTimeout(() => f());
|
||||
}, [nextTagsList]);
|
||||
|
||||
useEffect(() => {
|
||||
// 判断数据是否一致
|
||||
if (list.length !== nextTagsList.length || nextTagsList.some((item, i) => item !== list[i])) {
|
||||
setNextTagsList(list);
|
||||
setCurState({ list, isHideExpandNode: true, endI: -1, calculated: false });
|
||||
}
|
||||
}, [list]);
|
||||
|
||||
return (
|
||||
<div className="list-with-hide-container" ref={ref}>
|
||||
{curState.list.map((item, i) => {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={`container-item ${curState.calculated ? (curState.isHideExpandNode ? 'show' : i >= curState.endI ? 'hide' : 'show') : ''
|
||||
}`}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<Popover
|
||||
placement={placement}
|
||||
overlayClassName="tags-with-hide-popover"
|
||||
content={
|
||||
<div className="container-item-popover">
|
||||
{curState.list.map((id) => (
|
||||
<div key={id} className="container-item">
|
||||
{id}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className={`expand-item ${curState.calculated ? (curState.isHideExpandNode ? 'hide' : 'show') : ''}`}>
|
||||
{typeof expandTagContent === 'string' ? expandTagContent : expandTagContent(curState.list.length)}
|
||||
<DownOutlined />
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
.typical-list-card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px 10px 0 10px;
|
||||
&-container {
|
||||
height: 100%;
|
||||
padding: 16px 24px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.01), 0 3px 6px 3px rgba(0, 0, 0, 0.01), 0 2px 6px 0 rgba(0, 0, 0, 0.03);
|
||||
border-radius: 12px 12px 0 0;
|
||||
.title {
|
||||
margin-bottom: 16px;
|
||||
border: none;
|
||||
font-family: @font-family-bold;
|
||||
font-size: 18px;
|
||||
color: #212529;
|
||||
letter-spacing: 0;
|
||||
text-align: justify;
|
||||
line-height: 20px;
|
||||
}
|
||||
.operate-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import './index.less';
|
||||
|
||||
export default ({ title, children }) => {
|
||||
return (
|
||||
<div className="typical-list-card">
|
||||
<div className="typical-list-card-container">
|
||||
<div className="title">{title}</div>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user