✨ ui: Add CSS ellipsis + Tooltip for SelectableButtonGroup; keep Tag intact
- Truncate long labels via pure CSS and always show full text in a Tooltip - Ensure the right-side Tag is never truncated and remains fully visible - Simplify implementation: remove overflow detection and ResizeObserver - Use minimal markup with sbg-button/sbg-inner/sbg-label to enable shrinking - Add global rules to allow `.semi-button-content` to shrink and ellipsize Files: - web/src/components/common/ui/SelectableButtonGroup.jsx - web/src/index.css No API changes; visuals improved and code complexity reduced.
This commit is contained in:
@@ -17,10 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
For commercial licensing, please contact support@quantumnous.com
|
For commercial licensing, please contact support@quantumnous.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useRef } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
||||||
import { useMinimumLoadingTime } from '../../../hooks/common/useMinimumLoadingTime';
|
import { useMinimumLoadingTime } from '../../../hooks/common/useMinimumLoadingTime';
|
||||||
import { Divider, Button, Tag, Row, Col, Collapsible, Checkbox, Skeleton } from '@douyinfe/semi-ui';
|
import { Divider, Button, Tag, Row, Col, Collapsible, Checkbox, Skeleton, Tooltip } from '@douyinfe/semi-ui';
|
||||||
import { IconChevronDown, IconChevronUp } from '@douyinfe/semi-icons';
|
import { IconChevronDown, IconChevronUp } from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,8 +57,6 @@ const SelectableButtonGroup = ({
|
|||||||
const needCollapse = collapsible && items.length > perRow * maxVisibleRows;
|
const needCollapse = collapsible && items.length > perRow * maxVisibleRows;
|
||||||
const showSkeleton = useMinimumLoadingTime(loading);
|
const showSkeleton = useMinimumLoadingTime(loading);
|
||||||
|
|
||||||
const contentRef = useRef(null);
|
|
||||||
|
|
||||||
const maskStyle = isOpen
|
const maskStyle = isOpen
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
@@ -131,7 +129,7 @@ const SelectableButtonGroup = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const contentElement = showSkeleton ? renderSkeletonButtons() : (
|
const contentElement = showSkeleton ? renderSkeletonButtons() : (
|
||||||
<Row gutter={[8, 8]} style={{ lineHeight: '32px', ...style }} ref={contentRef}>
|
<Row gutter={[8, 8]} style={{ lineHeight: '32px', ...style }}>
|
||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
const isDisabled = item.disabled || (typeof item.tagCount === 'number' && item.tagCount === 0);
|
const isDisabled = item.disabled || (typeof item.tagCount === 'number' && item.tagCount === 0);
|
||||||
const isActive = Array.isArray(activeValue)
|
const isActive = Array.isArray(activeValue)
|
||||||
@@ -152,6 +150,7 @@ const SelectableButtonGroup = ({
|
|||||||
theme={isActive ? 'light' : 'outline'}
|
theme={isActive ? 'light' : 'outline'}
|
||||||
type={isActive ? 'primary' : 'tertiary'}
|
type={isActive ? 'primary' : 'tertiary'}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
|
className="sbg-button"
|
||||||
icon={
|
icon={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={isActive}
|
checked={isActive}
|
||||||
@@ -162,19 +161,15 @@ const SelectableButtonGroup = ({
|
|||||||
}
|
}
|
||||||
style={{ width: '100%', cursor: 'default' }}
|
style={{ width: '100%', cursor: 'default' }}
|
||||||
>
|
>
|
||||||
{item.icon && (
|
<div className="sbg-content">
|
||||||
<span style={{ marginRight: 4 }}>{item.icon}</span>
|
{item.icon && (<span className="sbg-icon">{item.icon}</span>)}
|
||||||
)}
|
<Tooltip content={item.label}>
|
||||||
<span style={{ marginRight: item.tagCount !== undefined ? 4 : 0 }}>{item.label}</span>
|
<span className="sbg-ellipsis">{item.label}</span>
|
||||||
{item.tagCount !== undefined && (
|
</Tooltip>
|
||||||
<Tag
|
{item.tagCount !== undefined && (
|
||||||
color='white'
|
<Tag className="sbg-tag" color='white' shape="circle" size="small">{item.tagCount}</Tag>
|
||||||
shape="circle"
|
)}
|
||||||
size="small"
|
</div>
|
||||||
>
|
|
||||||
{item.tagCount}
|
|
||||||
</Tag>
|
|
||||||
)}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
@@ -192,20 +187,19 @@ const SelectableButtonGroup = ({
|
|||||||
onClick={() => onChange(item.value)}
|
onClick={() => onChange(item.value)}
|
||||||
theme={isActive ? 'light' : 'outline'}
|
theme={isActive ? 'light' : 'outline'}
|
||||||
type={isActive ? 'primary' : 'tertiary'}
|
type={isActive ? 'primary' : 'tertiary'}
|
||||||
icon={item.icon}
|
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
|
className="sbg-button"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
>
|
>
|
||||||
<span style={{ marginRight: item.tagCount !== undefined ? 4 : 0 }}>{item.label}</span>
|
<div className="sbg-content">
|
||||||
{item.tagCount !== undefined && (
|
{item.icon && (<span className="sbg-icon">{item.icon}</span>)}
|
||||||
<Tag
|
<Tooltip content={item.label}>
|
||||||
color='white'
|
<span className="sbg-ellipsis">{item.label}</span>
|
||||||
shape="circle"
|
</Tooltip>
|
||||||
size="small"
|
{item.tagCount !== undefined && (
|
||||||
>
|
<Tag className="sbg-tag" color='white' shape="circle" size="small">{item.tagCount}</Tag>
|
||||||
{item.tagCount}
|
)}
|
||||||
</Tag>
|
</div>
|
||||||
)}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -289,6 +289,27 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ==================== 组件特定样式 ==================== */
|
/* ==================== 组件特定样式 ==================== */
|
||||||
|
/* SelectableButtonGroup */
|
||||||
|
.sbg-button .semi-button-content {
|
||||||
|
min-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbg-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbg-ellipsis {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tabs组件样式 */
|
/* Tabs组件样式 */
|
||||||
.semi-tabs-content {
|
.semi-tabs-content {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user