@infinilabs/entity-ui
v0.0.5
Published
Customized Entity components
Readme
@infinilabs/entity-ui 使用说明
Customized Entity components
概述
@infinilabs/entity-ui是一个用于展示“实体信息”的 UI 组件库,当前包含组件:EntityCard:基于antdPopover 的锚定式信息卡片,贴近触发元素显示,支持富信息内容与自动定位。EntityLabel:行内标签型组件,展示实体的基本信息(颜色块、图标、标题、子标题、右侧外链)。EntityUser:用于展示用户信息的行内组件,语法同EntityLabel,更便捷地适配“用户实体”的常见样式。
- 采用命名导出,支持 tree-shaking。
安装
- 组件需要
react与react-dom作为对等依赖(peerDependencies)。
pnpm add @infinilabs/entity-ui导入方式
- 推荐从根入口命名导入:
import { EntityCard, EntityLabel, EntityUser } from '@infinilabs/entity-ui';快速上手
- 行内标签 + 悬浮卡片的常见组合:
import { useState } from 'react';
import { EntityCard, EntityLabel } from '@infinilabs/entity-ui';
export default function Demo() {
const data = {
style: { width: '376px', max_height: '500px', cover_max_height: '172px' },
color: '#027FFE',
icon: 'mail',
title: '示例主题',
subtitle: '示例子标题',
url: 'https://example.com',
cover: 'https://picsum.photos/640/360',
categories: ['示例组织', '示例部门'],
properties: [
{ icon: 'email', value: '[email protected]' },
{ icon: 'datetime', value: '2025-08-21T15:34:25Z', view: 'datetime_with_time_zone' },
{ icon: 'tags', value: ['重要', '待办'], view: 'tags' },
],
details: { table: { rows: [{ columns: [{ label: '备注', value: '请及时处理' }] }] } },
tags: ['工作', '提醒'],
};
return (
<div style={{ position: 'relative', height: '60vh', padding: 24 }}>
<EntityLabel
data={{
type: 'user',
id: 'user-demo',
icon: 'user',
title: '示例用户',
color: '#0f0f0f',
subtitle: '示例部门',
url: 'mailto:[email protected]',
}}
/>
<div style={{ marginTop: 16 }}>
<EntityCard
title=""
triggerType="hover"
hoverOpenDelay={500}
autoPlacement
data={data}
trigger={<button className="entity-card__btn">悬停打开卡片</button>}
/>
</div>
</div>
);
}组件:EntityCard
定位与交互
triggerType?: "click" | "hover"默认"hover"。hoverOpenDelay?: number悬停延迟(毫秒),默认500。closeDelay?: number悬停离开延迟关闭(毫秒),默认200。placement?: "left" | "right" | "top" | "bottom"默认"right"。autoPlacement?: boolean打开前根据视窗与触发表剩余空间自动选方向(优先级right → left → bottom → top)。open?: boolean、onOpenChange?: (open: boolean) => void支持受控模式。trigger?: React.ReactNode自定义触发节点(默认一个Button)。- 弹层容器优先挂载到触发元素(
getPopupContainer={() => triggerRef.current || document.body})。 - 弹层内部移除默认内边距(
overlayInnerStyle={{ padding: 0 }})。
数据结构(
data)style?: { width?: string; height?: string; max_width?: string; max_height?: string; cover_max_height?: string }color?: string、icon?: string、title?: string、subtitle?: string、url?: string、cover?: stringcategories?: string[]面包屑tags?: string[]标签properties?: { icon?: string; value?: any; view?: string; payload?: any }[]details?: { table?: { rows?: { columns?: { label?: string; value?: any; view?: string; payload?: any }[] }[] } }- 图标支持:
- 当
icon为http/httpsURL 时,以<img>加载(尺寸与布局与 lucide 图标保持一致)。 - 其他字符串按 lucide-react 名称解析,内置别名:
user→User,email/mail→Mail,phone→Phone,datetime/date→Calendar,time→Clock,tags→Tag;kebab-case自动转为PascalCase。
- 当
多位置触发示例(测试自动定位)
import { EntityCard } from '@infinilabs/entity-ui';
export default function AutoPlacementDemo({ data }: { data: any }) {
return (
<div style={{ position: 'relative', height: '80vh', padding: 24 }}>
<div style={{ position: 'absolute', top: 12, left: 12 }}>
<EntityCard title="" triggerType="hover" hoverOpenDelay={500} autoPlacement data={data} trigger={<button>左上角</button>} />
</div>
<div style={{ position: 'absolute', top: 12, right: 12 }}>
<EntityCard title="" triggerType="hover" hoverOpenDelay={500} autoPlacement data={data} trigger={<button>右上角</button>} />
</div>
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
<EntityCard title="" triggerType="hover" hoverOpenDelay={500} autoPlacement data={data} trigger={<button>页面中间</button>} />
</div>
<div style={{ position: 'absolute', bottom: 12, left: 12 }}>
<EntityCard title="" triggerType="hover" hoverOpenDelay={500} autoPlacement data={data} trigger={<button>左下角</button>} />
</div>
<div style={{ position: 'absolute', bottom: 12, right: 12 }}>
<EntityCard title="" triggerType="hover" hoverOpenDelay={500} autoPlacement data={data} trigger={<button>右下角</button>} />
</div>
</div>
);
}组件:EntityLabel / EntityUser
- 行内展示实体信息,语法一致,
EntityUser常用于用户场景。 - Props
data?: { type?: string; id?: string; icon?: string; title?: string; color?: string; subtitle?: string; url?: string; style?: { width?: string } }
- 图标支持
data.icon为 URL 时使用<img>;否则按 lucide 名称解析(含别名与kebab→Pascal自动转换)。
- 示例
import { EntityLabel, EntityUser } from '@infinilabs/entity-ui';
export default function LabelDemo() {
return (
<>
<EntityLabel data={{ type: 'user', id: 'user-demo', icon: 'user', title: '示例用户', color: '#0f0f0f', subtitle: '示例部门', url: 'mailto:[email protected]' }} />
<EntityUser data={{ type: 'user', id: 'u_only_icon', icon: 'https://picsum.photos/40?random=12' }} />
</>
);
}尺寸与滚动(EntityCard)
- 使用
data.style.width/height/max_width/max_height控制内容尺寸; - 当内容高度超过
max_height时,内容区域纵向滚动; - 封面最大高度通过
data.style.cover_max_height控制; - 弹层内边距已移除,避免双重间距(
overlayInnerStyle={{ padding: 0 }})。
常见问题
- 无法找到默认导出:使用命名导出
import { EntityCard, EntityLabel, EntityUser } from '@infinilabs/entity-ui'。 - 悬停闪烁或误关闭:确认触发区与弹层是否存在遮挡(
z-index)、指针事件设置是否合理;组件默认将弹层容器绑定到触发元素以减少误判。 - 点击触发:将
triggerType设置为"click"并视需要调整延迟为0。
对等依赖(peerDependencies)建议
- 将
react与react-dom设为对等依赖,并在宿主应用中提供它们,以避免重复打包与版本冲突。
