feat: enhance description component, update property panel with tabs, and refine docs
This commit is contained in:
@@ -117,5 +117,4 @@
|
||||
}
|
||||
|
||||
.bim-collapse-content-box {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
53
src/components/description/index.css
Normal file
53
src/components/description/index.css
Normal file
@@ -0,0 +1,53 @@
|
||||
.bim-description {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
/* 默认字体大小和颜色 */
|
||||
font-size: var(--bim-desc-font-size, 14px);
|
||||
color: var(--bim-text-color, #333);
|
||||
/* 严格移除容器本身的 padding */
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bim-description-item {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
/* 严格移除 item 的 padding,完全由 label/value padding 控制 */
|
||||
padding: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 边框模式 */
|
||||
.bim-description.is-bordered {
|
||||
border-bottom: none; /* 最后一项会补齐 */
|
||||
}
|
||||
|
||||
.bim-description.is-bordered .bim-description-item {
|
||||
border-bottom: 1px solid var(--bim-border-color, #eee);
|
||||
}
|
||||
|
||||
/* 标签样式 */
|
||||
.bim-description-label {
|
||||
color: var(--bim-desc-label-color, var(--bim-label-color, #666));
|
||||
flex-shrink: 0;
|
||||
/* 默认 padding: 0 4px */
|
||||
padding: var(--bim-desc-label-padding, 4px 4px);
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
}
|
||||
|
||||
/* 边框模式下的标签样式 */
|
||||
.bim-description.is-bordered .bim-description-label {
|
||||
border-right: 1px solid var(--bim-border-color, #eee);
|
||||
}
|
||||
|
||||
/* 内容样式 */
|
||||
.bim-description-value {
|
||||
color: var(--bim-desc-value-color, var(--bim-value-color, #333));
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
/* 默认 padding: 0 4px */
|
||||
padding: var(--bim-desc-value-padding, 4px 4px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
160
src/components/description/index.ts
Normal file
160
src/components/description/index.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
import './index.css';
|
||||
import { DescriptionOptions, DescriptionItem } from './types';
|
||||
import { IBimComponent } from '../../types/component';
|
||||
import { themeManager } from '../../services/theme';
|
||||
import type { ThemeConfig } from '../../themes/types';
|
||||
|
||||
/**
|
||||
* 描述列表组件
|
||||
* 用于展示一组 Key-Value 数据
|
||||
* 注意:本组件为纯展示组件,不处理国际化,请在外部传入处理好的文本。
|
||||
*/
|
||||
export class BimDescription implements IBimComponent {
|
||||
private element: HTMLElement;
|
||||
private options: DescriptionOptions;
|
||||
private unsubscribeTheme: (() => void) | null = null;
|
||||
|
||||
constructor(options: DescriptionOptions) {
|
||||
this.options = {
|
||||
bordered: false,
|
||||
...options
|
||||
};
|
||||
|
||||
this.element = this.createDom();
|
||||
|
||||
const container = typeof this.options.container === 'string'
|
||||
? document.getElementById(this.options.container)
|
||||
: this.options.container;
|
||||
|
||||
if (container) {
|
||||
container.appendChild(this.element);
|
||||
}
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
this.applyCustomStyles();
|
||||
this.renderItems();
|
||||
|
||||
// 订阅主题变更
|
||||
this.unsubscribeTheme = themeManager.subscribe((theme) => {
|
||||
this.setTheme(theme);
|
||||
});
|
||||
|
||||
// 初始应用主题
|
||||
this.setTheme(themeManager.getTheme());
|
||||
}
|
||||
|
||||
private createDom(): HTMLElement {
|
||||
const el = document.createElement('div');
|
||||
el.className = `bim-description ${this.options.className || ''}`;
|
||||
|
||||
if (this.options.bordered) el.classList.add('is-bordered');
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
private applyCustomStyles() {
|
||||
const style = this.element.style;
|
||||
|
||||
// 应用全局字体大小
|
||||
if (this.options.fontSize) {
|
||||
style.setProperty('--bim-desc-font-size', this.options.fontSize);
|
||||
}
|
||||
|
||||
// 应用全局 Label 颜色
|
||||
if (this.options.labelColor) {
|
||||
style.setProperty('--bim-desc-label-color', this.options.labelColor);
|
||||
}
|
||||
|
||||
// 应用全局 Value 颜色
|
||||
if (this.options.valueColor) {
|
||||
style.setProperty('--bim-desc-value-color', this.options.valueColor);
|
||||
}
|
||||
|
||||
// 应用 Padding 配置
|
||||
if (this.options.labelPadding) {
|
||||
style.setProperty('--bim-desc-label-padding', this.options.labelPadding);
|
||||
}
|
||||
|
||||
if (this.options.valuePadding) {
|
||||
style.setProperty('--bim-desc-value-padding', this.options.valuePadding);
|
||||
}
|
||||
}
|
||||
|
||||
private renderItems() {
|
||||
this.element.innerHTML = ''; // 清空现有内容
|
||||
|
||||
this.options.items.forEach(item => {
|
||||
const itemEl = document.createElement('div');
|
||||
itemEl.className = `bim-description-item ${item.className || ''}`;
|
||||
|
||||
// 1. Label
|
||||
const labelEl = document.createElement('div');
|
||||
labelEl.className = 'bim-description-label';
|
||||
|
||||
// 行级颜色覆盖全局颜色
|
||||
if (item.labelColor) {
|
||||
labelEl.style.color = item.labelColor;
|
||||
}
|
||||
|
||||
// 设置固定宽度
|
||||
if (this.options.labelWidth) {
|
||||
labelEl.style.width = this.options.labelWidth;
|
||||
}
|
||||
|
||||
// 直接显示文本
|
||||
// bordered 模式移除冒号,普通模式保留
|
||||
labelEl.textContent = this.options.bordered ? item.label : (item.label + ':');
|
||||
|
||||
// 2. Value
|
||||
const valueEl = document.createElement('div');
|
||||
valueEl.className = 'bim-description-value';
|
||||
|
||||
// 行级颜色覆盖全局颜色
|
||||
if (item.valueColor) {
|
||||
valueEl.style.color = item.valueColor;
|
||||
}
|
||||
|
||||
if (typeof item.value === 'string') {
|
||||
valueEl.innerHTML = item.value;
|
||||
} else {
|
||||
valueEl.appendChild(item.value);
|
||||
}
|
||||
|
||||
itemEl.appendChild(labelEl);
|
||||
itemEl.appendChild(valueEl);
|
||||
this.element.appendChild(itemEl);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态更新数据
|
||||
*/
|
||||
public setItems(items: DescriptionItem[]) {
|
||||
this.options.items = items;
|
||||
this.renderItems();
|
||||
}
|
||||
|
||||
public setTheme(theme: ThemeConfig): void {
|
||||
const style = this.element.style;
|
||||
// 设置基础主题变量 (作为 fallback 或默认值)
|
||||
style.setProperty('--bim-text-color', theme.textPrimary);
|
||||
style.setProperty('--bim-label-color', theme.textSecondary);
|
||||
style.setProperty('--bim-value-color', theme.textPrimary);
|
||||
style.setProperty('--bim-border-color', theme.border);
|
||||
}
|
||||
|
||||
public setLocales(): void {
|
||||
// 本组件不处理国际化
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
if (this.unsubscribeTheme) {
|
||||
this.unsubscribeTheme();
|
||||
this.unsubscribeTheme = null;
|
||||
}
|
||||
this.element.remove();
|
||||
}
|
||||
}
|
||||
58
src/components/description/types.ts
Normal file
58
src/components/description/types.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
/**
|
||||
* 描述列表项配置
|
||||
*/
|
||||
export interface DescriptionItem {
|
||||
/** 标签文本 (直接显示,组件内部不翻译) */
|
||||
label: string;
|
||||
|
||||
/** 内容文本或元素 */
|
||||
value: string | HTMLElement;
|
||||
|
||||
/** 行级自定义标签颜色 */
|
||||
labelColor?: string;
|
||||
|
||||
/** 行级自定义内容颜色 */
|
||||
valueColor?: string;
|
||||
|
||||
/** 自定义类名 */
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 描述列表组件配置
|
||||
*/
|
||||
export interface DescriptionOptions {
|
||||
/** 挂载容器 */
|
||||
container: HTMLElement | string;
|
||||
|
||||
/** 数据项列表 */
|
||||
items: DescriptionItem[];
|
||||
|
||||
/**
|
||||
* 是否显示边框 (默认 false)
|
||||
* 开启后,将显示行间分割线以及 Key-Value 之间的纵向分割线
|
||||
*/
|
||||
bordered?: boolean;
|
||||
|
||||
/** 标签固定宽度 (例如 '80px'),若不设置则自适应 */
|
||||
labelWidth?: string;
|
||||
|
||||
/** 全局标签颜色 */
|
||||
labelColor?: string;
|
||||
|
||||
/** 全局内容颜色 */
|
||||
valueColor?: string;
|
||||
|
||||
/** 全局字体大小 */
|
||||
fontSize?: string;
|
||||
|
||||
/** 标签内边距 (默认 '0 4px') */
|
||||
labelPadding?: string;
|
||||
|
||||
/** 内容内边距 (默认 '0 4px') */
|
||||
valuePadding?: string;
|
||||
|
||||
/** 自定义类名 */
|
||||
className?: string;
|
||||
}
|
||||
@@ -11,8 +11,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 4px 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@@ -21,22 +19,25 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
/* 恢复原样式:上下4px,左右0 */
|
||||
padding: 4px 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border-radius: 0; /* 恢复直角 */
|
||||
background: transparent;
|
||||
color: var(--bim-tab-text, #e6e6e6);
|
||||
cursor: pointer;
|
||||
transition: color 0.2s ease, border-color 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
border-bottom: 2px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
}
|
||||
|
||||
.bim-tab__item:hover:not(.is-disabled):not(.is-active) {
|
||||
.bim-tab__item:hover {
|
||||
color: var(--bim-tab-text, #e6e6e6);
|
||||
border-bottom-color: var(--bim-tab-border, rgba(255, 255, 255, 0.15));
|
||||
background-color: var(--bim-tab-hover-bg, rgba(255, 255, 255, 0.05));
|
||||
border-bottom-color: var(--bim-tab-hover-bg, rgba(255, 255, 255, 0.15));
|
||||
}
|
||||
|
||||
/* Active 状态 */
|
||||
.bim-tab__item.is-active {
|
||||
color: var(--bim-tab-text-active, #4da3ff);
|
||||
border-bottom-color: var(--bim-tab-text-active, #4da3ff);
|
||||
@@ -105,4 +106,3 @@
|
||||
.construct-tab__panel-content .bim-tree {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user