Skip to Content
文档前端开发其它组件通用组件

common — 通用 UI 小组件

不感知模型的纯视觉组件。可在任意处直接使用——页面、布局、对话框、视图组件。入参是基础数据(字符串、数字、回调);均不涉及 modelNameMetaModelFilterCondition

要了解 common/ 在五层分工中的位置,见 索引

文件导出类别
pagination-bar.tsxPaginationBar分页
empty-state.tsxEmptyState空态 / 加载
loading-skeleton.tsxLoadingSkeleton空态 / 加载
full-screen-loading.tsxFullScreenLoading(默认导出)空态 / 加载
status-badge.tsxStatusBadge状态 / 标识
user-avatar.tsxUserAvatar状态 / 标识
timeline.tsxTimeline展示
check-list.tsxCheckList展示
date-picker.tsxDatePicker输入
datetime-picker.tsxDateTimePicker输入
time-picker.tsxTimePicker输入
time-column-panel.tsxTimeColumnPanel输入(构建块)
time-utils.tsresolveTimeConfig、类型工具
option-select.tsxOptionSelect输入
density-switcher.tsxDensitySwitcher应用控件

导入示例:import { PaginationBar } from "@/components/common/pagination-bar";


分页

PaginationBar

独立分页行(翻页按钮 + 每页条数下拉 + 记录数)。供 ModelTable / ModelCard 工具栏使用,也可用于自定义列表。

<PaginationBar pageNumber={page} totalPages={totalPages} pageSize={pageSize} totalCount={totalCount} selectedCount={selectedIds.length} onPageChange={setPage} onPageSizeChange={setPageSize} />
属性类型必填默认值说明
pageNumbernumber-当前页码(从 1 起)
totalPagesnumber-总页数(展示时下限夹紧为 ≥ 1)
pageSizenumber-当前每页行数
onPageChange(n: number) => void-传入从 1 起的新页码
onPageSizeChange(n: number) => void-新的每页条数
totalCountnumber-显示为 Total N records;省略则不显示汇总
selectedCountnumber0大于 0 时追加显示 · Selected N
availablePageSizesnumber[][10,20,50,100]下拉可选每页条数
classNamestring-

空态 / 加载

EmptyState

居中的「无数据 / 无结果」占位。未传 icon 时默认使用数据库图标。

<EmptyState title="暂无部署" description="请选择环境后查看部署。" action={<Button>开始使用</Button>} /> // 紧凑变体——用于卡片/面板内的行内空态 <EmptyState compact title="暂无条目" />
属性类型必填默认值说明
titlestring-主文案
descriptionstring-辅助说明(最大宽度 max-w-sm
iconReactNode<Database>自定义图标
actionReactNode-文案下方的按钮或链接
compactbooleanfalse更小的内边距与字号,用于行内
classNamestring-

LoadingSkeleton

预置整页骨架(输入行 + 主体 + 分页底栏占位)。用于即将渲染 Model* 视图但数据尚未加载完成的页面。

if (isLoading) return <LoadingSkeleton />;

无 props。

FullScreenLoading

带转圈的模态全屏遮罩。默认导出。用于阻塞整个应用的操作。

import FullScreenLoading from "@/components/common/full-screen-loading"; {isSaving && <FullScreenLoading />}

无 props。


状态 / 标识

StatusBadge

基于 class-variance-authority 变体的彩色胶囊徽标。不解析状态含义——由调用方选择 variant

<StatusBadge variant="success">生效中</StatusBadge> <StatusBadge variant="warning">待处理</StatusBadge> <StatusBadge variant="error">失败</StatusBadge> <StatusBadge variant="info">草稿</StatusBadge> <StatusBadge variant="neutral">已归档</StatusBadge>
属性类型必填默认值说明
variant"success" | "warning" | "error" | "info" | "neutral""neutral"配色主题
classNamestring-与变体类名合并
…HTMLSpanAttributes---透传给底层 <span>

UserAvatar

圆形头像。photoUrl 能加载则显示图片,否则退回 User 图标。photoUrl 的域名无需加入 next.config.jsremotePatterns(使用原生 <img>)。

<UserAvatar photoUrl={user.avatarUrl} /> <UserAvatar /> {/* 退回图标 */} <UserAvatar className="h-12 w-12" /> {/* 自定义尺寸 */}
属性类型必填默认值说明
photoUrlstring-头像 URL;加载失败自动退回默认
classNamestringh-(--ds-h-xl) w-(--ds-h-xl)用 Tailwind 类覆盖尺寸

展示

Timeline

竖向事件时间线,中间有连接线。首条事件高亮;后续事件以弱化颜色渲染。

<Timeline events={[ { idField: "evt-1", timeField: "2026-04-30 09:30", userField: "Alice Lee", actionField: "submitted the request", detailsField: "Reason: vacation", }, { idField: "evt-2", timeField: "2026-04-30 10:15", userField: "Bob Manager", actionField: "approved the request", }, ]} />
属性类型必填默认值说明
eventsTimelineEvent[]-空列表不渲染
classNamestring-

TimelineEvent 结构(每个字段已是格式化后的展示值):

字段类型说明
idFieldstring用作 React key;通常为事件记录 id
timeFieldstring预先格式化的时间戳文案
userFieldstring操作者名称
actionFieldstring动词短语,例如 "approved the request"
detailsFieldstring?可选第二行

CheckList

竖向清单。已勾选显示绿色勾 + 删除线;未勾选显示空心圆。

<CheckList items={[ { idField: "1", labelField: "提交表单", statusField: true }, { idField: "2", labelField: "等待审批", statusField: false, descriptionField: "经理审批中" }, ]} />
属性类型必填默认值说明
itemsCheckListItem[]-空列表不渲染
classNamestring-

CheckListItem 结构:

字段类型说明
idFieldstringReact key
labelFieldstring条目标签
statusFieldbooleantrue = 已勾选(删除线、绿色);false = 未勾选
descriptionFieldstring?可选第二行

输入

三种选择器(DatePicker / DateTimePicker / TimePicker)形态一致:字符串入、字符串出。触发器上的文案可用 displayFormat 设为另一种展示格式(例如 12 小时制或与区域相关的格式),但机器值始终使用规范机器格式,下游链路(表单值、FilterCondition、后端约定)无需了解展示模式。

triggerWrapper 可供表单适配器注入 <FormControl>{button}</FormControl>,使 react-hook-form 的无障碍挂钩(id / aria-describedby / aria-invalid)作用于触发按钮。独立调用方省略该项时,按钮即作为触发器。

DatePicker

纯日历日期选择。

<DatePicker value={value} onChange={setValue} /> <DatePicker value={value} onChange={setValue} dateFormat="yyyy-MM" />
属性类型必填默认值说明
valuestring-dateFormat 下的日期字符串;"" 表示未选
onChange(next: string) => void-新值;清空时为 ""
dateFormatstringconfigs.dateTimeFormats.dateyyyy-MM-dd机器格式。可传 "yyyy-MM" / "MM-dd" 等部分日期选择器
displayFormatstring= dateFormat触发器标签格式
disabledbooleanfalse
placeholderstring"Pick a date"
classNamestring-作用于触发按钮
triggerWrapper(button) => ReactElement-表单适配器用 <FormControl> 包裹
triggerStyleCSSProperties-触发按钮行内样式

DateTimePicker

日历与 24 小时时刻列并排。页脚提供清除 / 现在 / 应用。

<DateTimePicker value={value} onChange={setValue} /> <DateTimePicker value={value} onChange={setValue} defaultTime="23:59:59" />

机器格式固定为 yyyy-MM-dd HH:mm:ss(与 configs.dateTimeFormats.dateTime 一致)。

属性类型必填默认值说明
valuestring-yyyy-MM-dd HH:mm:ss"" 表示未选
onChange(next: string) => void-
displayFormatstringconfigs.dateTimeFormats.dateTime触发器标签格式。可传如 "yyyy-MM-dd hh:mm:ss a" 表示 12 小时制
defaultTimestring"00:00:00"用户选日期但值尚无时间时填充的时刻。范围筛选端点可传 "23:59:59"
disabledbooleanfalse
placeholderstring"Pick date & time"
classNamestring-
triggerWrapper(button) => ReactElement-
triggerStyleCSSProperties-

TimePicker

仅时间(无日历)。在浮层内渲染 TimeColumnPanel

<TimePicker value={value} onChange={setValue} timeFormat="HH:mm:ss" /> <TimePicker value={value} onChange={setValue} timeFormat="HH:mm" config={resolveTimeConfig({ min: "08:00", max: "18:00", minuteStep: 15 }, "HH:mm")} />
属性类型必填默认值说明
valuestring-timeFormat 下的 24 小时字符串;"" 表示未选
onChange(next: string) => void-
timeFormat"HH:mm" | "HH:mm:ss"-机器格式;面板列始终以 24 小时渲染
displayFormatstring= timeFormatdate-fns 格式的触发标签(例如 "hh:mm:ss a" 表示 12 小时制)
configResolvedTimeConfigresolveTimeConfig(undefined, timeFormat)边界 / 快捷选项
disabledbooleanfalse
placeholderstring"Pick time"
classNamestring-
triggerWrapper(button) => ReactElement-
triggerStyleCSSProperties-

TimeColumnPanel

可滚动的小时 / 分 /(秒)列面板,供 TimePickerDateTimePicker 使用。仅在需将列嵌入自定义布局时直接使用。页脚「清除 / 现在 / 应用」是否出现取决于 onClear / onApply / config.clearable / config.showQuickPick

resolveTimeConfig

解析 TimePicker / TimeColumnPanel 配置的纯函数(不含组件逻辑)。接收 Partial<TimePickerConfig>TimeFormat,返回已解析边界、校验步长并将 defaultTime 对齐到步长网格的 ResolvedTimeConfig

import { resolveTimeConfig } from "@/components/common/time-utils"; const config = resolveTimeConfig( { min: "08:00", max: "18:00", minuteStep: 15, quickOptions: ["09:00", "12:00"] }, "HH:mm", );

TimePickerConfig 结构:

字段类型说明
min / maxstring含边界的上下界,格式为 timeFormat
minuteStep / secondStepnumber取值之一为 [1,2,3,4,5,6,10,12,15,20,30,60](60 的因数);60 表示仅允许 00;非法值将告警并退回 1
defaultTimestring首次打开时预填;自动向上对齐到步长网格
quickOptionsstring[]列上方的快捷按钮;超出范围或不在网格上的项自动禁用
clearableboolean页脚是否显示清除(默认 true
showQuickPickboolean页脚是否显示「现在」(默认 true

OptionSelect

绑定选项集(服务端枚举)的独立下拉。内部处理加载 / 错误态。

<OptionSelect optionSetCode="DocumentStatus" value={status} onChange={setStatus} filters={[["disabled", "=", false]]} // 可选:客户端过滤 placeholder="请选择状态" />
属性类型必填默认值说明
optionSetCodestring-服务端选项集标识
valuestring | number-当前选中的 itemCode
onChange(value: string | undefined) => void-新的 itemCode(清空时为 undefined
placeholderstring"Please select..."
disabledbooleanfalse
readOnlybooleanfalse视觉上不可交互,保持正常对比度
filtersFilterCondition-对拉取到的选项做客户端过滤
classNamestring-

加载中 → 渲染 Skeleton。出错 → 渲染禁用下拉,文案 "Failed to load options"


应用控件

DensitySwitcher

通过 @/providers/density-provideruseDensity() 切换紧凑 / 舒适密度。用在应用 Header 中。除 className 外无其他 props。

<DensitySwitcher />
属性类型必填默认值说明
classNamestring-

新增 common 组件的准则

当且仅当全部满足时,组件应放在 common/

  • 只接收朴素数据(无 modelName / MetaModel / FilterCondition 等 props)
  • 不依赖 Model* 视图容器(如 SidePanelContainerProvider 等)
  • 可在非 Model* 宿主中使用(对话框、布局、自定义页面)
最后更新于