Skip to content

展示与反馈组件

@mbjia/components

展示与反馈组件

用于加载、空状态、进度、标签和轻量操作展示。

这些组件主要用于加载、空状态、进度、标签和轻量操作展示。

模块定位

提供业务页面中常见的反馈和展示能力,包括加载、空状态、进度、匹配度、图标、长文本省略和虚拟列表。

LoadingEmptyProgress

接入建议

这类组件大多依赖较少,适合普通业务页面按需使用。复杂列表场景优先考虑 CommonVirtualList。

轻业务依赖按需使用展示优先

组件索引

组件说明
LoadingAntD Spin 封装
CircleLoading圆形 loading
DotLoading点状 loading
RedCircleLoading红色圆形 loading
VeLoadingWhite白色 loading
Empty空状态
ProgressBar普通进度条
SegmentedProgressBar分段进度条
MatchingDegree匹配度标签
VeIcon业务图标
ImageLoad图片加载、错误兜底和默认图封装
HoverIconhover 切换背景图标
EllipsisInMiddleOfText中间省略文本
CommonModal通用弹窗
ModalContainer带 tab、目录和内容区的业务弹窗容器
CommonSegmentedNav分段导航
CommonVirtualList虚拟列表
Actions表格行内操作栏,超出项进入更多菜单
MoreActions三点更多操作菜单
SetNumberMemo编辑器数值输入框
SetSelectAndInput编辑器 Select 封装
InfiniteSliderMemo拖拽式无限数值调节器
InfiniteAndInputNumberMemo无限拖拽和数值输入组合控件
PureTextFont字体选择浮层

效果预览

解析中 68%
匹配度高素材处理中

展示反馈组合

加载、空状态、进度、匹配度和编辑器输入控件通常一起出现在素材处理、AI 分析和视频编辑页面。

Loading

AntD Spin 的轻量封装,用于区域加载态。

tsx
<Loading style={{ minHeight: 120 }} />
字段类型必填默认值说明
styleReact.CSSProperties{}透传到 loading 外层容器。

Empty

空状态组件。默认会优先读取主题配置里的 images.common-empty,没有主题图时才使用入参 img

tsx
<Empty text="暂无素材" img="/empty.png" imageW={134} imageH={134} />
字段类型必填默认值说明
imgstring-兜底空状态图片地址。
textReact.ReactNode-空状态文案。
backgroundColorstring'#fff'图片加载背景色,传给 ImageLoad
imageWnumber134图片宽度。
imageHnumber134图片高度。
customStyleReact.CSSProperties-外层容器样式。
imgStyleReact.CSSProperties-图片容器样式。

ProgressBar

普通进度条。percent 会直接转换为宽度百分比。

tsx
<ProgressBar percent={68} content="处理中 68%" />
字段类型必填默认值说明
contentReact.ReactNode-进度条内部展示内容。
percentnumber-进度百分比,源码中直接用于 width: ${percent}%
customStyleReact.CSSProperties-外层样式。

SegmentedProgressBar

视频时间轴分段进度条,用于展示精彩片段、分析结果和当前播放位置。

tsx
const segments = [
  { id: 's1', start: 2, end: 8, detail: '商品露出清晰', title: '镜头 1' },
]

<SegmentedProgressBar
  segments={segments}
  startTime={0}
  endTime={30}
  currentTime={6}
  isPlaying={false}
  onClick={(time) => seek(time)}
  onPause={pause}
  onPlay={play}
/>

数据结构:

ts
export interface Segment {
  start: number
  end: number
  color?: string
  id: string
  detail: string
  title?: string
}
字段类型必填默认值说明
segmentsSegment[]-分段片段。只渲染与 [startTime, endTime] 有交集的片段。
startTimenumber-当前时间轴起始秒。
endTimenumber-当前时间轴结束秒。
currentTimenumber-当前播放秒。
isPlayingboolean-拖拽结束后是否恢复播放。
onClick(time: number) => void-点击或拖拽时间轴时触发。
onPause() => void-开始拖拽时触发。
onPlay() => void-拖拽结束且 isPlaying 为 true 时触发。
onSegmentClick(segment: Segment) => void-点击片段时触发。
offsetTime{ start: number; end: number }{ start: 0, end: 0 }用于展示偏移后的时间文案。
highLightMomentstring-悬浮提示中的高光时刻文案。

MatchingDegree

ts
interface PropsType {
  score: number
  size?: 'large' | 'small'
  degree?: 'vh' | 'h' | 'm' | 'l'
}

用途:展示素材匹配程度。

字段类型必填默认值说明
scorenumber-匹配分数。未传 degree 时会按分数计算等级。
size'large' | 'small''large'尺寸。
degree'vh' | 'h' | 'm' | 'l'score 计算指定匹配等级。

等级文案:

等级文案默认分数规则
vh匹配度极高score >= 0.6
h匹配度高0.3 <= score < 0.6
m匹配度一般0.2 <= score < 0.3
l匹配度低score < 0.2

EllipsisInMiddleOfText

用于文件名或长文本中间省略,保留尾部关键信息。

tsx
<EllipsisInMiddleOfText text="very-long-file-name.mp4" lastPart=".mp4" />
字段类型必填默认值说明
textstring-完整文本。
lastPartstringtext尾部保留/提示文本。
classNamestring-自定义 class。

ImageLoad

图片加载封装。相比普通 img,它会通过 useImageLoad 处理加载状态、错误兜底、默认图和 OEM 默认图。

tsx
<ImageLoad
  src={asset.coverUrl}
  fallbackSrc={asset.previewUrl}
  backgroundColor="#f5f5f5"
  cover
  shouldDefaultImg
  handleClick={() => preview(asset)}
/>
字段类型必填默认值说明
srcstring-首选图片地址。
dataUrlstring-base64 或 data URL,优先级高于 src
fallbackSrcstring-src 加载失败后的兜底地址。
altstring'加载失败'图片 alt。
errorbooleanfalse外部控制错误态。
onError() => void-图片加载失败时触发。
handleClick() => void-点击外层容器时触发。
backgroundColorstring''loading 或图片背景色。
customStyleReact.CSSProperties{}外层样式。
customImgStyleReact.CSSProperties{ height: '100%' }图片样式。
classNamestring''自定义 class。
coverbooleanfalse是否使用 object-fit: cover
shouldDefaultImgbooleanfalseloading 时是否直接展示默认图。

HoverIcon

hover 时切换背景图的图标容器,适合操作按钮、卡片悬浮操作。

tsx
<HoverIcon
  beforeHover="/icons/edit.svg"
  afterHover="/icons/edit-active.svg"
  w={16}
  h={16}
  pointer
  onClick={() => edit()}
/>
字段类型必填默认值说明
beforeHoverstring-默认背景图。
afterHoverstring-hover 背景图。
wnumber | string-宽度。
hnumber | stringw高度。
pointerboolean-是否展示手型光标。
onClick() => void-点击回调。
styleReact.CSSProperties-自定义样式,会合并到背景图样式上。

CommonSegmentedNav

基于 AntD Segmented 的导航组件,适合切换轻量 tab。

ts
type CommonSegmentedOption = {
  label: ReactNode
  value: string | number
  icon?: ReactNode
  disabled?: boolean
  className?: string
}
字段类型必填默认值说明
optionsCommonSegmentedOption[]三个“导航”默认项分段选项。
crtNavnumber | stringoptions[0].value当前选中项。
onChange(value) => void-切换回调。
classNamestring'segmentedNav'自定义 class。

CommonModal

基于 AntD Modal 的业务通用弹窗。统一了居中、不可点击遮罩关闭、默认宽度和业务 wrap class,并在关闭时通过 onOpenChange 通知外层。

tsx
<CommonModal
  open={open}
  okText="确认"
  cancelText="取消"
  onOk={() => submit()}
  onCancel={() => cancel()}
  onOpenChange={(open, fromFooter) => console.log(open, fromFooter)}
>
  <div>弹窗内容</div>
</CommonModal>
字段类型必填默认值说明
openboolean-是否打开。
cancelTextstring | ReactNode-取消按钮文案。
okTextstring-确认按钮文案。
onCancelFunction-点击 footer 取消按钮时触发。
onOkFunction-点击确认按钮时触发。
classNamestring-业务 class,会拼到 wrapClassName
onOkNotClosebooleanfalse点击确认后是否保持弹窗打开。
onCancelNotCloseboolean-点击 footer 取消后是否保持弹窗打开。
onOpenChangeFunction-所有关闭动作都会触发;第二个参数表示是否来自 footer 区域。
widthnumber | string364弹窗宽度。
zIndexnumber3010弹窗层级。
其他属性ModalProps-透传给 AntD Modal

ModalContainer

带 tab、左侧目录和右侧内容区的业务弹窗容器。ScriptModal 等复杂素材选择弹窗可以复用这个结构。

tsx
<ModalContainer
  open={open}
  zIndex={3000}
  destroyOnClose
  currTab="music"
  tabList={[{ id: 'music', title: '音乐' }]}
  dirList={[{ id: 'default', title: '默认分组', selected: true }]}
  onChangeTab={(tab) => setTab(tab)}
  onChangeGroup={(group) => setGroup(group)}
  onClose={() => setOpen(false)}
>
  <MusicList />
</ModalContainer>

数据结构:

ts
export const ModalType = {
  MUSIC: 'music',
  STICKER: 'sticker',
  CAPTION: 'caption',
  SCRIPT: 'script',
} as const

export type GroupItemType = {
  id: string
  title: string
  selected?: boolean
  children?: GroupItemType[]
}
字段类型必填默认值说明
zIndexnumber-弹窗层级。
openboolean-弹窗是否打开。
destroyOnClosebooleanfalse关闭时是否销毁内容。
currTabstring-当前 tab id。
tabList{ id: string; title: string }[][]顶部 tab 列表。
dirListGroupItemType[][]左侧目录列表。
tabBtnstring''右上角按钮文案。
onChangeTab(tab: string) => void-切换 tab。
onClose() => void-关闭弹窗。
onClickTabBtn() => void空函数点击右上角按钮。
onChangeGroup(group: GroupItemType) => void-切换目录。
childrenReact.ReactNode-右侧内容区。
widthnumber1098弹窗宽度。
contentContainerStyleReact.CSSProperties{}内容区样式。
customDirReact.ReactNode-自定义左侧目录区域,优先级高于 dirList

Actions / MoreActions

表格或列表行内操作组件。Actions 会把前几个操作直接展示,剩余操作交给 MoreActions 三点菜单。

tsx
<Actions
  data={row}
  actions={[
    { label: '编辑', value: 'edit', onClick: ({ data }) => edit(data) },
    { label: '删除', value: 'delete', onClick: ({ data }) => remove(data) },
  ]}
  showItems={[0]}
/>

Actions Props:

字段类型必填默认值说明
actions{ label: string; value: string; onClick: (data: any) => void; disabled?: boolean }[][]操作列表。
showItemsnumber[][0, 1]直接展示的操作下标。
dataany{}当前行数据。点击时会包装成 { data } 传给 action。
disAbleFn(data: any, item: any) => boolean-动态禁用函数。
isLinebooleantrue更多按钮方向样式。

MoreActions Props:

字段类型必填默认值说明
items{ label: string; value: any }[]删除、编辑AntD Dropdown 菜单项。
isLinebooleantrue三点按钮横向或纵向样式。

SetNumberMemo

编辑器数值输入框,基于 AntD InputNumber。支持百分比、角度、秒等格式化显示,并在键盘或步进操作结束后触发 onAfterChange

tsx
<SetNumberMemo
  value={20}
  controlType={103}
  acceptType="number"
  onChange={(value) => setValue(value)}
  onAfterChange={(value) => save(value)}
/>
字段类型必填默认值说明
acceptType'number' | 'text''number'输入值转换方式。
valuenumber | null | undefined | ''-当前值;空值会显示为空输入框。
controlTypenumber | string-控制格式化规则。103/202/302 展示 %deg 展示角度,seconds 展示秒。
numberPernumber | stringcontrolType控制数值精度。
widthnumber | string104输入框宽度。
controlsboolean | object自定义上下图标透传给 InputNumber
onChange(value: number | string | null) => void-输入变化时触发。
onAfterChange(value: number | string | null) => void-键盘抬起或步进操作后触发。

特殊格式:

controlType展示形式说明
106201301圈数 x 角度°源码会拆成两个输入框,最终值按 level1 * 360 + level2 返回。
103202302value%百分比输入。
'deg'value°角度输入。
'seconds'value s秒输入。

SetSelectAndInput

编辑器 Select 封装。组件会把 optionsList 转成 AntD Select.Option,其他属性透传给 Select

tsx
<SetSelectAndInput
  optionsList={['左对齐', '居中', '右对齐']}
  value="居中"
  onChange={(value) => setAlign(value)}
/>
字段类型必填默认值说明
optionsListany[]-下拉选项列表;每一项同时作为 keyvalue 和展示文案。
classNamestring-自定义 class。
其他 Select 属性SelectProps-透传给 AntD Select

InfiniteSliderMemo

拖拽式无限数值调节器。适合编辑器里通过横向拖拽快速调整数值,并在拖拽结束后触发保存。

tsx
<InfiniteSliderMemo
  title="字号"
  value={32}
  min={0}
  max={200}
  onChange={(value) => setFontSize(value)}
  onAfterChange={(value) => saveFontSize(value)}
/>
字段类型必填默认值说明
valuenumber | null0当前值。源码会把 undefined/null 当作 0
titlestring-拖拽控件展示文案。
minnumber-最小值,透传给 react-input-number-editor-more
maxnumber-最大值,透传给 react-input-number-editor-more
controlTypenumber-控制精度。
numberPernumber | stringcontrolType控制拖拽精度。
onChange(value: number) => void-拖拽过程中持续触发。
onAfterChange(value: number) => void-鼠标松开后触发。

InfiniteAndInputNumberMemo

组合 InfiniteSliderMemoSetNumberMemo,同时支持拖拽调节和精确输入。

tsx
<InfiniteAndInputNumberMemo
  title="透明度"
  value={80}
  min={0}
  max={100}
  controlType={103}
  onChange={(value) => setOpacity(value)}
  onAfterChange={(value) => saveOpacity(value)}
/>
字段类型必填默认值说明
structure'vertical' | string水平布局vertical 时垂直排列。
titlestring | ReactNode'值'拖拽控件文案。
valuenumber | nullmin0当前值。
controlType102 | 106 | 103 | string-透传给两个子控件。
onChange(value: number) => void-拖拽或输入变化时触发。
onAfterChange(value: number) => void-操作结束后触发。
其他属性any-透传给 InfiniteSliderMemoSetNumberMemo

PureTextFont

字体选择浮层。支持字体库、团队字体、最近使用、搜索字体、默认字体和按元素定位展示。

tsx
const fontRef = useRef<HTMLDivElement>(null)

<PureTextFont
  ref={fontRef}
  originFontName="默认字体"
  currentFontName={fontName}
  language={{ id: 1 }}
  placementElement={buttonRef.current}
  placement="bottomRight"
  showTeamFont
  onSelectFont={(font) => setFont(font)}
  onCloseTextFont={() => setOpen(false)}
/>
字段类型必填默认值说明
originFontNamestring-素材原始默认字体名。
currentFontNamestring-当前字体名。
language{ id: number }-当前语言。个人字体库会按该语言查询。
showDefaultbooleantrue是否展示默认字体项。
showTeamFontboolean-是否展示团队字体 tab。
placementElementHTMLElement-用于定位的目标元素。
placement'bottomRight' | 'topRight' | 'bottomLeft' | 'topLeft' | 'Right' | 'Left'-浮层位置。
gap[number, number][0, 10]定位偏移。
styleReact.CSSProperties-浮层样式。
onSelectFont(font) => void-选择字体后触发。
onCloseTextFont() => void-点击遮罩关闭浮层。

依赖接口:

接口用途
reqAssetFontList查询字体列表。
reqAssetGetFontRecentUsage查询最近使用字体。
reqAssetSetFontRecentUsage选择字体后记录最近使用。
getDepartmentListY判断是否展示团队字体。

CommonVirtualList

基于 virtua 的虚拟列表,用于长列表性能优化。

MBJIA Tools 文档