@tfdesign/b-end 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/tfds/CHECKLIST.md +5 -0
- package/skills/tfds/COMMON_FAILURES.md +48 -0
- package/skills/tfds/DESIGN_PRINCIPLES.md +5 -0
- package/skills/tfds/GLOBAL_DESIGN_RULES.md +31 -0
- package/skills/tfds/LAYOUT_RULES.md +31 -0
- package/skills/tfds/components.index.json +75 -27
- package/skills/tfds/components.summary.json +13 -13
- package/src/_b_end_runtime/components/Card.jsx +151 -13
- package/src/_b_end_runtime/components/Card.tokens.js +27 -3
- package/src/_b_end_runtime/components/CardPreview.jsx +11 -3
- package/src/_b_end_runtime/components/ChatMessage.jsx +59 -1
- package/src/_b_end_runtime/components/ConversationList.jsx +68 -68
- package/src/_b_end_runtime/components/ConversationList.tokens.js +5 -3
- package/src/_b_end_runtime/components/FullScreenPage.jsx +1 -0
- package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +13 -15
- package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +2 -0
- package/src/_b_end_runtime/components/Modal.jsx +1 -0
- package/src/_b_end_runtime/components/Sheet.jsx +1 -0
- package/src/_b_end_runtime/components/Table.jsx +7 -0
- package/src/_b_end_runtime/components/Tabs.jsx +46 -3
- package/src/_b_end_runtime/components/Tabs.tokens.js +3 -0
- package/src/_b_end_runtime/components/TagBar.jsx +2 -0
- package/src/_b_end_runtime/components/Toast.jsx +1 -0
- package/src/_b_end_runtime/components/Upload.jsx +1 -0
- package/src/_b_end_runtime/components.js +24 -11
- package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +548 -135
- package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +1 -1
- package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +6 -6
- package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +66 -5
- package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +50 -17
- package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +28 -78
- package/src/_b_end_runtime/patterns.js +32 -21
- package/src/_b_end_runtime/preview-registry.jsx +20 -4
- package/src/index.d.ts +4 -2
|
@@ -1065,7 +1065,7 @@ export const COMPONENTS = [
|
|
|
1065
1065
|
name: 'Card',
|
|
1066
1066
|
element: 'article',
|
|
1067
1067
|
category: 'business',
|
|
1068
|
-
description: '业务信息摘要卡片,支持数据卡片、商品卡片、信息卡片1和信息卡片2
|
|
1068
|
+
description: '业务信息摘要卡片,支持数据卡片、商品卡片、信息卡片1和信息卡片2。所有卡片分类统一遵循背景反衬原则:灰色/浅灰/非纯白背景用白底卡,纯白背景用灰底卡。',
|
|
1069
1069
|
componentFile: './components/Card.jsx',
|
|
1070
1070
|
tokensFile: './components/Card.tokens.js',
|
|
1071
1071
|
props: [
|
|
@@ -1114,7 +1114,7 @@ export const COMPONENTS = [
|
|
|
1114
1114
|
'【类型】type=data 为数据卡片;type=product 为商品卡片 / 业务对象卡;type=info 为信息卡片1,用于展示带图标、主副标题和底部辅助信息的业务信息对象;type=info2 为信息卡片2,用于 AI 能力、推荐工具、重点入口等静态信息入口场景。type=animated 仅作为旧版兼容别名,生成新页面时不要使用。',
|
|
1115
1115
|
'【分类决策表】选择 Card 类型时按业务对象优先级判断:1. 如果内容是指标摘要、趋势解读、工具入口、模板入口、脚本/话术/SOP/案例入口,使用 `type="data"`;2. 如果内容是具体商品、订单、门店、素材、工单附件、查询结果等可识别业务对象,使用 `type="product"`;3. 如果内容是智能体、知识库、应用、服务、官方能力等需要表达“身份 + 说明 + 辅助指标”的对象,使用 `type="info"`(信息卡片1);4. 如果内容是 AI 推荐、重点能力、首页推荐、配置向导、单步启动入口,且需要更强入口感,使用 `type="info2"`。当同一内容同时满足多个条件时,优先级为 product(具体对象)> info(身份对象)> info2(推荐入口)> data(摘要入口)。',
|
|
1116
1116
|
'【分类 Bad Case】禁止用 `type="data"` 承载具体商品/订单对象;禁止用 `type="product"` 展示纯指标趋势或工具入口;禁止用 `type="info"` 只做强推荐按钮或首页营销入口;禁止用 `type="info2"` 承载商品/订单/复杂详情或列表型内容。AI 生成页面时,必须先判断内容语义,再选择卡片分类,不要仅根据是否有图标、是否有标签或视觉喜好选择类型。',
|
|
1117
|
-
'【数据卡片适用场景】数据卡片不仅适用于指标摘要、趋势分析、服务能力入口和工具入口,也适用于模板、脚本、案例类内容入口,例如优秀知识模版、优秀案例模版、脚本模版、话术模版、内容生成模版、服务 SOP 模版等。此类内容仍使用数据卡片的摘要入口结构:标题 + 描述 + 可选指标/元信息 + 标签 +
|
|
1117
|
+
'【数据卡片适用场景】数据卡片不仅适用于指标摘要、趋势分析、服务能力入口和工具入口,也适用于模板、脚本、案例类内容入口,例如优秀知识模版、优秀案例模版、脚本模版、话术模版、内容生成模版、服务 SOP 模版等。此类内容仍使用数据卡片的摘要入口结构:标题 + 描述 + 可选指标/元信息 + 标签 + 右侧进入提示箭头;如果需要突出缩略图/封面图或具体商品、订单、附件对象,应改用商品卡片;如果需要强调 AI 能力、智能体、知识库或应用服务身份,应优先使用信息卡片1。',
|
|
1118
1118
|
'【数据卡片结构】上半区固定为标题 + 描述 + 1-3 项指标,下半区为左下角标签 + 右侧单步进入按钮。数据卡片支持可选右侧图标:默认 `dataIconVisible="hidden"` 不显示图标;需要图标时设置 `dataIconVisible="visible"` 并传入 `dataIconName`,标题/描述/指标区域居左,图标容器 48×48px、圆角必须使用 rounded-xl token(16px),仅显示在数据卡片右上角并与文字区域顶部对齐,图标与左侧标题内容区左右间距必须等于数据卡片四周 padding,即 p-5 / 20px。图标样式复用信息卡片1同名容器逻辑:`dataIconStyle="inverse"` 为黑底白 icon(默认),`dataIconStyle="tone"` 为彩色浅底;色系通过 `dataIconTone` 选取。',
|
|
1119
1119
|
'【数据卡片数据项】数据卡片的指标数据通过 `stats` 动态配置,用于按场景展示摘要维度,例如触达用户、会话量、收藏量、转化率、完成率、运行次数、更新时间、异常数量等。数据结构固定为 `{ iconName, value, tooltip? }`,其中 iconName 必须复用 Icon,value 为短数字或短文字,tooltip 用于 hover/focus 展示该数据项的详细说明。最多展示 3 组,超出运行时自动截断;每组样式固定为 14px 图标 + 12px / 400 文案,项间距 20px。Tooltip 只做补充解释,不承载核心操作路径。',
|
|
1120
1120
|
'【信息卡片1结构】信息卡片1支持两种布局:`infoLayout="icon-right"` 为默认布局,即“图标在右”;左侧承载标题/副标题/底部辅助信息,图标整体放在最右侧,状态徽标紧跟主标题右侧。`infoLayout="default"` 即“图标在左”;左侧固定 48px 图标容器,右侧上半区为主标题 + 副标题 + 右上角状态徽标,底部为辅助显示区。信息卡片1图标与标题内容区左右间距必须等于信息卡片1四周 padding,即 p-6 / 24px。信息卡片1适合内容对象、智能体、知识库、应用、服务入口等需要“图标 + 长说明 + 关键辅助信息”的场景。',
|
|
@@ -1131,19 +1131,22 @@ export const COMPONENTS = [
|
|
|
1131
1131
|
'【商品文案】标题最多 1 行,字号统一为 text-base / 16px / 600,优先放用户识别对象所需的名称 / 订单号 / 关键标识;副标题最多 1 行,用于展示数量、价格、规格、订单金额、下单时间、售后进度等辅助信息;不要把长说明、操作指引或多段备注塞入副标题',
|
|
1132
1132
|
'【信息卡片1底部数据项】右下角数据项通过 `infoStats` 动态配置,用于按场景展示该信息对象的关键辅助数据,例如启用量、评分、调用量、响应率、转化率、更新时间、风险数量、操作入口等。数据结构固定为 `{ iconName, value, tooltip? }`,其中 iconName 必须复用 Icon,value 为短数字或短文字,tooltip 用于 hover/focus 展示该数据项的详细说明。最多展示 3 组,超出运行时自动截断;每组样式固定为 14px 图标 + 12px / 400 文案,项间距 20px,必须与底部身份区保持 16px 行高内垂直居中。',
|
|
1133
1133
|
'【信息卡片1文案】默认文案按抖音官方 AI 能力模拟,标题为“抖音 AI 创作助手”,副标题说明短视频脚本、标题推荐、封面文案和热点灵感生成能力。标题建议 1 行,字号统一为 text-base / 16px / 600;副标题建议 2 行内,字号 12px / 400,不要堆叠多段正文。默认底部数据项使用“启用量 / 评分 / 成功率”,并通过 Tooltip 解释每组数据含义;底部整栏所有头像、图标、文字必须保持 16px 行高内垂直居中并对齐到同一行。信息卡片1右下角数据项应优先展示真实数据维度,不默认展示“立即体验”这类操作文案;单步进入操作应使用信息卡片2或页面内独立按钮。',
|
|
1134
|
-
'
|
|
1134
|
+
'【整卡点击(强约束)】所有 Card 分类只要传入 `onAction`(表示存在详情页 / 二级页 / 深入工作页),默认整张卡片区域都必须可点击进入,并支持鼠标点击与 `Enter / Space` 键盘触发;不要把查看交互只缩成右下角一个小箭头热区。数据卡片和信息卡片2可保留右下角圆形箭头作为“进入提示”,但箭头只做辅助热区,点击后与整卡复用同一回调。若卡片内未来存在独立按钮、更多菜单或 Tag 操作,子交互需阻止冒泡,避免误触整卡跳转。',
|
|
1135
|
+
'【onAction 语义】`onAction` 不是“箭头按钮专属回调”,而是 Card 的统一详情跳转能力。data / product / info / info2 四类卡片都可以传 `onAction`;传入后整卡即视为可进入对象,`actionAriaLabel` 同时作为整卡和辅助箭头按钮的无障碍文案。',
|
|
1136
|
+
'【数据卡片适用场景】数据卡片不仅适用于指标摘要、趋势分析、服务能力入口和工具入口,也适用于模板、脚本、案例类内容入口,例如优秀知识模版、优秀案例模版、脚本模版、话术模版、内容生成模版、服务 SOP 模版等。此类内容仍使用数据卡片的摘要入口结构:标题 + 描述 + 可选指标/元信息 + 标签 + 右侧进入提示箭头;如果需要突出缩略图/封面图或具体商品、订单、附件对象,应改用商品卡片;如果需要强调 AI 能力、智能体、知识库或应用服务身份,应优先使用信息卡片1。',
|
|
1137
|
+
'【信息卡片2】info2 不是通用卡片替代品,只用于需要突出推荐、智能能力、配置向导、重点工具入口的静态信息入口。结构为左上图标 + 标题/描述 + 左下角徽标 + 右下角圆形箭头提示入口;默认标题“智能策略生成”、默认图标色系 grey、徽标“AI 推荐”、操作文案“立即体验”。',
|
|
1135
1138
|
'【信息卡片2标签】info2 的 animatedBadge 固定展示在左下角,必须与标题左边界对齐,并与右下角圆形箭头操作按钮保持同一行垂直居中。标签默认一律使用 Tag variant="white" + fontWeight="regular",不跟随 animatedTone,禁止把标签放到右上角。',
|
|
1136
|
-
'【信息卡片2操作】右下角操作入口必须复用数据卡片同款圆形箭头按钮样式和交互:28×28px、圆形、默认透明描边 + text-tertiary 图标,卡片 hover 或按钮 hover 时变为黑色描边与黑色箭头,按下 active:scale-[0.96]。animatedActionText
|
|
1139
|
+
'【信息卡片2操作】右下角操作入口必须复用数据卡片同款圆形箭头按钮样式和交互:28×28px、圆形、默认透明描边 + text-tertiary 图标,卡片 hover 或按钮 hover 时变为黑色描边与黑色箭头,按下 active:scale-[0.96]。animatedActionText 只作为操作语义文案,不直接渲染为文字按钮。只要传了 `onAction`,默认整张 info2 卡片和右下角箭头都能进入同一个详情目标。',
|
|
1137
1140
|
'【信息卡片2视觉】info2 不包含柔光、流动光带或特殊 hover 位移;背景颜色、边框颜色和 hover 投影完全复用普通 Card 的 color=white / grey 规则。animatedTone 只影响左上图标容器色系,不影响卡片背景、边框和底部标签。',
|
|
1138
1141
|
'【信息卡片2图标 Hover】卡片 hover 时,左上图标容器必须自动切换为当前 animatedTone 对应的 hover 背景、纯白 icon、透明描边:brand→brand-500、blue→blue-500、purple→purple-500、green→green-500、orange→orange-500、grey→black。禁止 hover 后继续显示浅底、深色 icon 或描边色。',
|
|
1139
1142
|
'【颜色】color=white 使用 65% 白底 + 白色描边;color=grey 使用 Blue Grey 100 背景 + Blue Grey 300 描边',
|
|
1140
|
-
'【容器映射(强约束)】Card
|
|
1143
|
+
'【容器映射(强约束)】Card 的颜色必须与所处背景做反衬,而且这条规则对所有 Card 分类统一生效:当 Card 所在父容器是“灰底页面/灰底区块/浅灰分区/其他非纯白背景”→ Card 用 `color="white"`;当父容器本身是“纯白底卡片/纯白底面板”→ Card 用 `color="grey"`,用灰底卡片做二级区块分层,避免白底叠白底',
|
|
1141
1144
|
'【配置面板颜色】所有 Card 分类(数据卡片、商品卡片、信息卡片1、信息卡片2)都必须优先展示“颜色”配置项,并提供白底 / 灰底两种选择。平台预览中切换右上角画布底色时,卡片颜色必须按反衬规则自动同步:灰底画布 → 白底卡片,白底画布 → 灰底卡片。',
|
|
1142
|
-
'
|
|
1145
|
+
'【一句话记忆】如果卡片背景环境是灰色、浅灰色或其他非纯白色,就选“白底”分类卡片;如果卡片背景环境是纯白色,就选“灰底”分类卡片。不要让 Card 和父级背景同色相贴。',
|
|
1143
1146
|
'【状态】白底卡默认态使用 65% 白底 + 轻白描边;hover 后补满白底并出现业务卡片专用投影;灰底卡保持灰底与灰描边并保留投影反馈',
|
|
1144
1147
|
'【指标】指标项推荐控制在 3 项以内,图标 14px、文字 12px,项间距 20px',
|
|
1145
1148
|
'【标签】通用 tags 只用于数据卡片,展示在左下角并与右侧操作按钮水平对齐;商品卡片和信息卡片1禁止渲染通用 tags,主标题左侧不得出现“标签”等前缀标签,运行时会隐藏误注入的 white Tag。Card 内所有标签默认必须使用圆角矩形样式 `radius="md"`,不使用全圆胶囊 `radius="full"`;数据卡片、商品状态标签、信息卡片1徽标都遵守该规则。数据卡片不论是否展示图标、也不论 dataIconStyle 为 tone 或 inverse,默认标签都必须统一使用 grey 标签样式。商品状态标签和信息卡片1徽标仅可展示在右上角并与标题水平对齐。信息卡片1徽标与 infoIconStyle 联动:`tone` 时一律 grey,`inverse` 时默认彩色 purple;卡片彩色标签优先使用 purple(紫色)/ teal(青绿色)/ blue(蓝色)/ cyan(青色)/ orange(橙色),避免优先使用 pink、red、yellow 等过强警示或装饰色。商品状态标签复用 green + l + md;不显示图标和关闭按钮,建议使用 2-4 字短标签。',
|
|
1146
|
-
'
|
|
1149
|
+
'【操作】当 `onAction` 存在时,整张 Card 是主进入热区;数据卡片 / 信息卡片2 的右侧圆形箭头只承载同一个进入动作的视觉提示,aria-label 需说明目标;商品卡片和信息卡片1不额外渲染箭头按钮,但仍应支持整卡点击查看。',
|
|
1147
1150
|
'【信息卡片1语义映射】AI / 智能能力推荐使用 magic-wand-01-stroked + pink 或 brand;数据洞察可用 bar-chart / line-chart 类图标 + blue;任务自动化可用 zap / settings 类图标 + orange;安全、审核、风控可用 shield / alert 类图标 + red 或 orange;知识库、文档、客服可用 book / message 类图标 + green 或 blue。色系只表达类别和状态,不用于装饰。',
|
|
1148
1151
|
'【文案长度】数据卡片标题优先控制在 1 行内,描述建议 2 行内;商品卡片标题和副标题均为 1 行截断,避免状态标签被挤压或换行;信息卡片1标题 1 行、副标题 2 行,底部辅助区允许换行但不得撑破卡片宽度。',
|
|
1149
1152
|
],
|
|
@@ -1159,6 +1162,8 @@ export const COMPONENTS = [
|
|
|
1159
1162
|
{ label: '信息卡片1(风控能力)', code: '<Card type="info" infoIconName="shield-01-stroked" infoIconTone="orange" title="内容安全巡检" description="对视频、评论和私信内容进行风险识别,辅助运营及时处理异常内容。" infoMetaBadge="内测中" infoMetaBadgeVariant="orange" infoMetaLabel="郭泽智" infoStats={[{ iconName: "alert-circle-stroked", value: "23 条风险", tooltip: "当前待处理的高风险内容数量" }, { iconName: "check-circle-stroked", value: "98.6%", tooltip: "系统自动识别准确率" }]} />' },
|
|
1160
1163
|
{ label: '信息卡片2', code: '<Card type="info2" title="智能策略生成" description="基于业务目标、历史数据和运营规则,自动生成可执行策略建议。" animatedIconName="magic-wand-01-stroked" animatedBadge="AI 推荐" animatedActionText="立即体验" onAction={() => {}} />' },
|
|
1161
1164
|
{ label: '信息卡片2(报告入口)', code: '<Card type="info2" animatedTone="purple" title="自动生成报告" description="汇总核心指标、异常归因和建议动作,生成可直接复用的业务报告。" animatedBadge="Beta" animatedActionText="开始生成" onAction={() => {}} />' },
|
|
1165
|
+
{ label: '商品卡片整卡点击', code: '<Card type="product" title="订单 202604300018" description="共 3 件 · 实付 ¥268.00 · 退款中" productStatus="退款中" actionAriaLabel="查看订单详情" onAction={() => {}} />' },
|
|
1166
|
+
{ label: '信息卡片1整卡点击', code: '<Card type="info" infoIconName="magic-wand-01-stroked" title="抖音 AI 创作助手" description="抖音官方 AI 创作能力,支持短视频脚本、标题推荐、封面文案和热点灵感生成。" infoMetaBadge="官方能力" actionAriaLabel="查看创作助手详情" onAction={() => {}} />' },
|
|
1162
1167
|
{ label: '自定义标题', code: '<Card title="重点客户满意度追踪" description="汇总近 7 天满意度变化、问题归因和渠道分布,并给出跟进建议。" onAction={() => {}} />' },
|
|
1163
1168
|
{ label: '自定义指标', code: '<Card stats={[{ iconName: "users-01-stroked", value: "860", tooltip: "近 7 天触达用户数" }, { iconName: "message-chat-square-stroked", value: "3,421", tooltip: "近 7 天累计会话量" }, { iconName: "hearts-stroked", value: "95", tooltip: "用户收藏或点赞次数" }]} onAction={() => {}} />' },
|
|
1164
1169
|
{ label: '自定义标签', code: '<Card tags={["客服", "高优先"]} actionAriaLabel="查看客服趋势分析" onAction={() => {}} />' },
|
|
@@ -1172,6 +1177,7 @@ export const COMPONENTS = [
|
|
|
1172
1177
|
{ label: '✅ Good(趋势摘要用数据卡片)', code: '<Card title="近 7 天转化趋势" description="成交转化率 +12%,互动提升 8%" stats={[{ iconName: "trend-up-01-stroked", value: "+12%" }]} tags={["趋势", "经营"]} onAction={() => {}} />' },
|
|
1173
1178
|
{ label: '❌ Bad(用信息卡片1做单步推荐入口)', code: '/* 禁止!推荐入口更强调行动,不需要身份区、头像和多项辅助指标 */\n<Card type="info" title="智能策略生成" description="一键生成可执行策略建议" infoMetaBadge="AI 推荐" />' },
|
|
1174
1179
|
{ label: '✅ Good(推荐入口用信息卡片2)', code: '<Card type="info2" title="智能策略生成" description="基于业务目标、历史数据和运营规则,自动生成可执行策略建议。" animatedBadge="AI 推荐" animatedActionText="立即体验" onAction={() => {}} />' },
|
|
1180
|
+
{ label: '❌ Bad(有详情页却只让小箭头可点)', code: '/* 禁止!传了 onAction 的 Card 默认整卡都应可点,不要在外层再手动禁用主热区或只保留右下角小按钮 */\n<Card type="info2" onAction={() => {}} className="pointer-events-auto" />' },
|
|
1175
1181
|
{ label: '❌ Bad(用信息卡片2承载商品对象)', code: '/* 禁止!商品对象需要图片/状态/关键识别信息,不应用推荐入口卡承载 */\n<Card type="info2" title="海底捞门店通用双人套餐" description="数量 1 · ¥128.00 · 月售 2,361" animatedBadge="已使用" />' },
|
|
1176
1182
|
{ label: '✅ Good(商品对象用商品卡片)', code: '<Card type="product" title="海底捞门店通用双人套餐" description="数量 1 · ¥128.00 · 月售 2,361" productStatus="已使用" />' },
|
|
1177
1183
|
],
|
|
@@ -1302,7 +1308,7 @@ export const COMPONENTS = [
|
|
|
1302
1308
|
name: 'InfoDisplayPanel',
|
|
1303
1309
|
element: 'section',
|
|
1304
1310
|
category: 'business',
|
|
1305
|
-
description: '信息展示面板框架,用于客服工作台、在线 Agent、工单详情右侧信息区等场景;默认以主栏承载全部 tabs
|
|
1311
|
+
description: '信息展示面板框架,用于客服工作台、在线 Agent、工单详情右侧信息区等场景;默认以主栏承载全部 tabs,并按业务动态 tab1 / tab2 / tab3 拆分为 1-3 栏,支持整体宽度与栏间宽度拖拽。',
|
|
1306
1312
|
componentFile: './components/InfoDisplayPanel.jsx',
|
|
1307
1313
|
tokensFile: './components/InfoDisplayPanel.tokens.js',
|
|
1308
1314
|
props: [
|
|
@@ -1344,6 +1350,7 @@ export const COMPONENTS = [
|
|
|
1344
1350
|
'【不适用场景】整页客服工作台外框用 CustomerServiceWorkspaceFrame;左侧会话 / 工单队列用 ConversationList;单个业务摘要用 Card;字段型详情或可批量操作数据用 Form / Table。',
|
|
1345
1351
|
'【结构】外层为一个白色圆角容器,默认使用 `w-full` 撑满父容器可用宽度;内部按“拆分栏数组 + 主栏”组织。每一栏都必须包含 56px 顶部 Tabs 栏和内容区;顶部横线只保留 Header 内 1 条通栏下描边,左右贴满当前栏容器。Tabs 交互、文字、选中态与 3px Brand 指示线必须复用基础 `Tabs variant="line" size="lg"`,禁止手写 tab button 或手写选中线。栏与栏之间用 1px 垂直分隔线,禁止通过 gap 制造分栏空隙。',
|
|
1346
1352
|
'【分栏能力】默认单栏时,全部 tabs 位于主栏;主栏永远在最右侧,拆分出的独立栏固定追加在主栏左侧。每栏右上角始终只有 1 个动作按钮,拆分与合并统一使用 `Button variant="ghost-black" size="md" iconOnly tooltip="拆分/合并"` 显示提示文案。最多支持 3 栏,即 1 个主栏 + 最多 2 个拆分栏。',
|
|
1353
|
+
'【动态 tab1/tab2/tab3 拆分】InfoDisplayPanel 必须按业务实际 tabs 动态决定可见栏数,而不是写死三栏:只有 1 个分类时自动降级为单栏标题 + 内容;有 2 个分类时最多支持 2 栏;有 3 个及以上分类且容器宽度达到三栏门槛时才支持 3 栏。tab 的数量、名称、顺序、内容都必须来自 `panels[].tabs` / `panels[].content` 或 `renderPanelContent`,不要把“托管助手 / 历史工单 / 工单日志”等示例固定写死到所有业务页面。',
|
|
1347
1354
|
'【Tabs来源】Tabs 的数量、名称和顺序必须跟随具体生成页面的业务信息架构动态生成,由 `panels[].tabs` 提供;不要把默认示例 tabs 当作真实业务规则,也不要为了凑满 3 栏强行生成无意义的 tab。',
|
|
1348
1355
|
'【Tab数量与拆分上限】可拆栏数同时受容器宽度和 tab 总数限制:仅 1 个 tab 时不使用 Tabs,运行时自动降级为 `FormTitle variant="card"` 标题展示且不显示拆分按钮;仅 2 个 tab 时最多拆分为 2 栏;大于等于 3 个 tab 且容器宽度达到 602px 时才允许拆分为 3 栏。',
|
|
1349
1356
|
'【拆分规则】点击主栏右上角“拆分”时,只拆出当前选中的主栏 tab;拆分后该 tab 从主栏 tabs 中移除,并以独立栏形式出现在主栏左侧。主栏保留剩余未拆分 tabs,顺序始终保持传入时的原始顺序。',
|
|
@@ -1360,6 +1367,7 @@ export const COMPONENTS = [
|
|
|
1360
1367
|
'【组合关系】InfoDisplayPanel 可作为 CustomerServiceWorkspaceFrame 的 mainPanel 内容;放入主白卡时宽高使用 `size-full` 或父容器约束,外层不要再套一层大白卡。',
|
|
1361
1368
|
'【嵌入客服工作台时的语义】在客服工作台框架模版里,InfoDisplayPanel 不是独立静态侧栏,而是“当前左侧选中会话 / 工单”的辅助信息区。左侧会话列表默认选中项变化时,InfoDisplayPanel 内各 tab 的内容也必须同步切换到该当前对象对应的数据上下文,例如用户信息、历史工单、工单日志、视频信息、沟通记录都应属于同一个当前处理对象。',
|
|
1362
1369
|
'【联动边界】客服工作台里的右侧白卡应被视为一个整体工作区:左侧 IM 对话区负责当前线程,右侧 InfoDisplayPanel 负责同一线程的辅助信息。两者由外层模板统一接收当前对象 id 并同步刷新;InfoDisplayPanel 不应自己脱离左侧上下文单独维持另一份“当前对象”。',
|
|
1370
|
+
'【嵌入客服工作台时的能力保留】当 InfoDisplayPanel 被客服工作台框架使用时,必须保留整体信息栏宽度拖拽、内部栏间拖拽、动态 tab 拆分 / 合并、单 tab 降级、宽度门槛和最小栏宽保护。AI 生成页面不得把 InfoDisplayPanel 替换成静态 Card 列、普通 Tabs 面板或固定宽 div,也不得删除拖拽热区和拆分按钮。',
|
|
1363
1371
|
'【可控状态】业务需要同步 URL / 埋点 / 右侧主区状态时,使用 `activeTabs + onTabChange` 控制每栏当前 tab,并使用 `onSplitChange` 感知当前拆分出来的 tab 列表与实际栏数;`columnCount` / `defaultColumnCount` 仅保留为兼容字段,不再作为主交互入口推荐,默认最大栏数按组件逻辑自动支持到 3 栏。',
|
|
1364
1372
|
],
|
|
1365
1373
|
examples: [
|
|
@@ -1827,6 +1835,7 @@ export const COMPONENTS = [
|
|
|
1827
1835
|
{ name: 'activeIndex', type: 'number', default: 0 },
|
|
1828
1836
|
{ name: 'defaultIndex', type: 'number', default: 0 },
|
|
1829
1837
|
{ name: 'onChange', type: 'function', default: null },
|
|
1838
|
+
{ name: 'overflow', type: 'enum', options: ['auto', 'visible'], default: 'auto' },
|
|
1830
1839
|
],
|
|
1831
1840
|
labels: {
|
|
1832
1841
|
variant: {
|
|
@@ -1842,6 +1851,8 @@ export const COMPONENTS = [
|
|
|
1842
1851
|
'【尺寸默认铁律·最新】所有 4 种 Tabs 变体(line / button / pill / segment)在内容展示区、白卡内、卡片内、表单分段、筛选维度、Playground 面板内切换时,**默认尺寸统一为 `size="sm"`**。AI 生成页面时可以省略 size(组件默认即 SM),或显式写 `size="sm"`;⛔ 禁止在内容区默认写 `size="md"` / `size="lg"`。',
|
|
1843
1852
|
'【尺寸例外】只有 Tabs 位于**整个平台顶部 header / 页面级顶导 / 产品级一级导航**时,才允许根据场景使用 `size="md"` 或 `size="lg"`:例如页面级 Pill Tabs、平台顶部模块切换、顶部导航胶囊。只要 Tabs 在白卡、面板、内容区、表单区、筛选区内,就回到 SM。',
|
|
1844
1853
|
'【分段器 = segment 变体】设计稿「分段器」对应代码 **`variant="segment"`**(灰底轨道 + 白底选中块),与 `Tag` 无关。① **卡片内**小模块、指标维度、白/灰卡内并列区块切换 → **默认优先** `variant="segment" size="sm"`。② **页面主内容区顶部**、整块**布局级**主视图切换(并排等大内容区,如「列表/看板/日历」并列)→ **默认优先** `variant="segment" size="sm"`,除非它是页面级顶部 header 导航。',
|
|
1854
|
+
'【防溢出铁律】Tabs 默认 `overflow="auto"`,根节点内置 `max-w-full min-w-0 overflow-x-auto`,内层按 `w-max` 保持单行内容宽度;当 tab 总宽度超过卡片 / 侧栏 / 面板宽度时,必须在组件内部横向滚动,禁止把父容器、白卡或页面撑宽。AI 生成页面时不要给 Tabs 或父级写 `w-fit`、`min-w-max`、固定大宽度、`overflow-visible` 来强行展示全部 tab。',
|
|
1855
|
+
'【父容器适配】Tabs 所在的横向 flex 区、白卡 header、侧栏卡片、抽屉面板内必须允许收缩:父级建议 `min-w-0 max-w-full overflow-hidden`,标题区与操作区并排时,Tabs 容器放在 `min-w-0 flex-1` 或 `max-w-full` 区域内。禁止让 Tabs 与标题互相挤压导致标题竖排、页面横向滚动或卡片越界。',
|
|
1845
1856
|
'【其它 variant 自判】详情子页签、面板内横向主导航感 → `line`;内容区内强调「块状」分类 → `button`;顶导/浮层/工具条胶囊规格 → `pill`;表单分段、筛选维度、与上两类「分段器优先」场景之外的 2~6 项切换 → 可用 `segment` 或按视觉在 `line`/`button` 间选择。',
|
|
1846
1857
|
'【选型·与 Button】Tabs 的每一项是「切换可见内容」;Button 是「执行操作」。同一组互斥展示若无需下划线/胶囊视觉,且只有 2 个选项,可用 Radio horizontal,但「多面板」仍优先 Tabs',
|
|
1847
1858
|
'【选型·与 Select】2~6 个面板级分区用 Tabs;单个字段在表单里从 10+ 枚举中选一个值 → Select,不要把每个枚举值做成 Tab',
|
|
@@ -1851,9 +1862,9 @@ export const COMPONENTS = [
|
|
|
1851
1862
|
'【内描边】pill 容器的白色描边为内描边(ring-inset / box-shadow inset),不占布局空间,所以容器实际高度 = padding × 2 + 选项高度。若手写胶囊,描边必须用 ring-inset 或 box-shadow inset,不能用 border,否则会撑高 2px',
|
|
1852
1863
|
'【表单/筛选器】segment(分段器)用于表单切换、筛选条件等场景,灰色容器 + 白色选中块',
|
|
1853
1864
|
'【悬浮反馈】button、pill、segment 三种变体的非选中项悬浮均使用语义填充色(fill-default)',
|
|
1854
|
-
'【标签数量】建议 2-6
|
|
1855
|
-
'【文字长度】标签文字推荐 2-4
|
|
1856
|
-
'【无障碍】每个标签使用 role="tab",容器使用 role="tablist",选中态用 aria-selected',
|
|
1865
|
+
'【标签数量】建议 2-6 个标签;2-6 个但容器较窄时保持单行横向滚动,不允许溢出;超过 6 个或标签会动态增长时,优先改用 Select / Filter / 更多菜单,不要继续横排堆满 Tabs。',
|
|
1866
|
+
'【文字长度】标签文字推荐 2-4 个汉字,保持简洁;业务必须展示长标签时保持 `whitespace-nowrap` 并依赖横向滚动,不要逐字换行或压缩字间距。',
|
|
1867
|
+
'【无障碍】每个标签使用 role="tab",容器使用 role="tablist",选中态用 aria-selected;组件支持 ArrowLeft / ArrowRight / Home / End 键盘切换。',
|
|
1857
1868
|
],
|
|
1858
1869
|
examples: [
|
|
1859
1870
|
{ label: '线条型(默认 SM)', code: '<Tabs variant="line" items={[{label:"标签一"},{label:"标签二"},{label:"标签三"}]} />' },
|
|
@@ -1863,6 +1874,7 @@ export const COMPONENTS = [
|
|
|
1863
1874
|
{ label: '分段器', code: '<Tabs variant="segment" items={[{label:"SM"},{label:"MD"},{label:"LG"}]} defaultIndex={1} />' },
|
|
1864
1875
|
{ label: '卡片内分段器(小模块切换,默认 SM)', code: '<Tabs variant="segment" items={[{label:"概览"},{label:"明细"},{label:"日志"}]} />' },
|
|
1865
1876
|
{ label: '主区顶部分段器(布局切换,默认 SM)', code: '<Tabs variant="segment" items={[{label:"列表"},{label:"看板"},{label:"日历"}]} />' },
|
|
1877
|
+
{ label: '窄卡片内自动滚动', code: '<div className="min-w-0 max-w-full overflow-hidden"><Tabs variant="segment" items={[{label:"全部"},{label:"通用"},{label:"社区"},{label:"电商"},{label:"生服"},{label:"直播"}]} /></div>' },
|
|
1866
1878
|
{ label: '内容区显式 SM', code: '<Tabs variant="line" size="sm" items={[{label:"Tab1"},{label:"Tab2"}]} />' },
|
|
1867
1879
|
{ label: '顶部 Header 例外(可用 MD/LG)', code: '<Tabs variant="pill" size="md" items={[{label:"服务策略"},{label:"运行数据"}]} />' },
|
|
1868
1880
|
{ label: '❌ Bad(内容区默认使用 MD)', code: '/* 禁止!Tabs 在白卡/内容区/表单分段/筛选维度内默认必须 SM */\n<Tabs variant="segment" size="md" items={[{label:"概览"},{label:"明细"}]} />' },
|
|
@@ -1871,6 +1883,7 @@ export const COMPONENTS = [
|
|
|
1871
1883
|
{ label: '❌ Bad(手写 div role=tablist)', code: '/* 禁止!手写 Tab 缺 token、缺指示器、键盘交互不全 */\n<div role="tablist"><span className="px-3 border-b-2">列表</span><span className="px-3">看板</span></div>' },
|
|
1872
1884
|
{ label: '✅ Good(user/assistant 切换用 segment)', code: '<Tabs variant="segment" items={[{label:"User"},{label:"Assistant"}]} />' },
|
|
1873
1885
|
{ label: '❌ Bad(用 Tag 当面板切换)', code: '/* 禁止!Tag 是状态/分类标签,不承担面板切换;切换面板必须 Tabs */\n<div className="flex gap-2"><Tag variant="brand">Input</Tag><Tag variant="grey">Output</Tag></div>' },
|
|
1886
|
+
{ label: '❌ Bad(Tabs 撑破窄容器)', code: '/* 禁止!w-fit/min-w-max 会把卡片撑破;保持默认 overflow="auto" 即可 */\n<Tabs className="w-fit min-w-max" variant="segment" items={categoryTabs} />' },
|
|
1874
1887
|
],
|
|
1875
1888
|
keywords: [
|
|
1876
1889
|
'Tabs', 'tabs', '标签页', '页签', '选项卡', '切换器',
|