@tfdesign/b-end 1.0.15 → 1.0.16
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tfdesign/b-end",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "TFDS B-end React components + Tailwind v4 theme.css; self-contained npm install (no monorepo clone required).",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"bin": {
|
|
33
|
-
"tfds-setup": "
|
|
33
|
+
"tfds-setup": "scripts/setup.mjs"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"prepack": "node ../../scripts/generate-tfds-b-end-bundle.mjs && node ../../scripts/generate-tfds-b-end-types.mjs",
|
|
@@ -46,7 +46,7 @@ TFDS 是**桌面优先**的 B 端工具产品,响应式策略和 C 端不同
|
|
|
46
46
|
| `1280 × 768` | 筛选栏、Tabs、按钮组、表格工具条不溢出;底部操作 / 输入区可达 |
|
|
47
47
|
| `1024 × 768` | 次要侧栏允许折叠 / 收窄 / 内滚;主内容仍可完成核心任务 |
|
|
48
48
|
|
|
49
|
-
⛔ **禁止**通过浏览器缩放、隐藏关键控件或让 body 横向滚动来掩盖布局问题。
|
|
49
|
+
⛔ **禁止**通过浏览器缩放、隐藏关键控件或让 body 横向滚动来掩盖布局问题。
|
|
50
50
|
✅ 横向超宽内容只能在对应组件 / 面板内部滚动,例如 Table、代码区、Tabs viewport、InfoDisplayPanel 栏内内容。
|
|
51
51
|
|
|
52
52
|
---
|
|
@@ -335,7 +335,7 @@ prompt editor / prompt workspace / runtime / run result /
|
|
|
335
335
|
|
|
336
336
|
### 1.5.5 AI 入口页(ChatHomePagePattern)背景与白卡边界(强约束)
|
|
337
337
|
|
|
338
|
-
AI 入口页的核心是「**从 0 发起任务**」:用户第一步是输入一句需求 / 搜索助手 / 从模板开始。它的视觉应该是**浅灰大背景承载整页氛围**,并在灰底上直接组织 Hero、筛选行与卡片网格。
|
|
338
|
+
AI 入口页的核心是「**从 0 发起任务**」:用户第一步是输入一句需求 / 搜索助手 / 从模板开始。它的视觉应该是**浅灰大背景承载整页氛围**,并在灰底上直接组织 Hero、筛选行与卡片网格。
|
|
339
339
|
⚠️ 这里最常见的误用是:为了“看起来更像后台”,在右侧内容区外又包了一整张白色大卡片容器,导致页面层级变成“灰底 → 大白卡 → 卡片”,整体像嵌套面板,入口页气质被破坏。
|
|
340
340
|
|
|
341
341
|
- ✅ **正确**:灰底为主,白卡只出现在**推荐卡片本身**(`<Card color="white" />`)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"system": "b-end",
|
|
3
3
|
"skill": "tfds",
|
|
4
|
-
"generatedAt": "2026-05-
|
|
4
|
+
"generatedAt": "2026-05-13T13:51:39.617Z",
|
|
5
5
|
"purpose": "轻量组件与页面模板目录。AI 先读本文件做选型;确定命中组件后,再到 components.index.json 按 id 读取 props / rules / examples。",
|
|
6
6
|
"counts": {
|
|
7
7
|
"total": 47,
|
|
@@ -135,16 +135,16 @@ const TABLE_SHELL = [
|
|
|
135
135
|
].join(' ');
|
|
136
136
|
|
|
137
137
|
const TABLE = 'flex w-full min-w-0 flex-1 min-h-0 flex-col';
|
|
138
|
-
const TABLE_VIEWPORT = 'flex flex-col flex-1 min-h-0 w-full overflow-
|
|
138
|
+
const TABLE_VIEWPORT = 'flex flex-col flex-1 min-h-0 w-full overflow-auto';
|
|
139
139
|
const TABLE_CONTENT = 'flex w-full flex-1 min-h-0 flex-col';
|
|
140
|
-
const TABLE_BODY = 'flex-1 min-h-0 w-full
|
|
140
|
+
const TABLE_BODY = 'flex-1 min-h-0 w-full';
|
|
141
141
|
|
|
142
142
|
/* ── 表头 / 单元格 ──
|
|
143
143
|
* Table 自身不带任何背景色,行/单元格全部透明,由外部容器决定底色。
|
|
144
144
|
* sticky 表头与固定列因此在滚动时会与内容色一致;如业务需要遮挡,
|
|
145
145
|
* 请在外层容器设置背景色(白卡 / 灰底 page 等)。
|
|
146
146
|
*/
|
|
147
|
-
const HEADER_ROW = 'grid w-full min-w-0';
|
|
147
|
+
const HEADER_ROW = 'sticky top-0 z-40 grid w-full min-w-0 bg-surface';
|
|
148
148
|
const BODY_ROW = 'grid w-full min-w-0';
|
|
149
149
|
|
|
150
150
|
const HEADER_CELL = [
|
|
@@ -226,6 +226,7 @@ const PAGE_ELLIPSIS = 'inline-flex size-8 items-center justify-center text-sm fo
|
|
|
226
226
|
|
|
227
227
|
/* ── 空态 ── */
|
|
228
228
|
const EMPTY_CELL = 'px-4 py-10 text-center text-sm font-normal leading-5 text-foreground-muted';
|
|
229
|
+
const PINNED_SURFACE_BACKGROUND = 'var(--color-surface, #FFFFFF)';
|
|
229
230
|
|
|
230
231
|
/* ── 卡片型表单 ── */
|
|
231
232
|
const CARD_FORM_BODY = 'flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto';
|
|
@@ -318,6 +319,34 @@ function getColumnTemplateMinWidth(columns) {
|
|
|
318
319
|
return columns.reduce((sum, column) => sum + resolveColumnMetrics(column).minWidth, 0);
|
|
319
320
|
}
|
|
320
321
|
|
|
322
|
+
function getPinnedColumnStates(columns, fixedColumnsMode) {
|
|
323
|
+
const states = columns.map(() => null);
|
|
324
|
+
|
|
325
|
+
if (!columns.length || fixedColumnsMode === 'none') {
|
|
326
|
+
return states;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const lastColumnIndex = columns.length - 1;
|
|
330
|
+
|
|
331
|
+
if (isFirstColumnFixed(fixedColumnsMode)) {
|
|
332
|
+
states[0] = {
|
|
333
|
+
side: 'left',
|
|
334
|
+
offset: 0,
|
|
335
|
+
edge: 'right',
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (isLastColumnFixed(fixedColumnsMode) && lastColumnIndex > 0) {
|
|
340
|
+
states[lastColumnIndex] = {
|
|
341
|
+
side: 'right',
|
|
342
|
+
offset: 0,
|
|
343
|
+
edge: 'left',
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return states;
|
|
348
|
+
}
|
|
349
|
+
|
|
321
350
|
function buildCellClass(baseClass, sizeKey, extraClass = '') {
|
|
322
351
|
return [
|
|
323
352
|
baseClass,
|
|
@@ -327,11 +356,9 @@ function buildCellClass(baseClass, sizeKey, extraClass = '') {
|
|
|
327
356
|
}
|
|
328
357
|
|
|
329
358
|
function getPinnedCellStyle({
|
|
330
|
-
columnIndex,
|
|
331
|
-
columnsLength,
|
|
332
359
|
align,
|
|
333
360
|
minHeight,
|
|
334
|
-
|
|
361
|
+
pinnedState,
|
|
335
362
|
isHeader = false,
|
|
336
363
|
}) {
|
|
337
364
|
const style = {
|
|
@@ -339,24 +366,28 @@ function getPinnedCellStyle({
|
|
|
339
366
|
textAlign: align || 'left',
|
|
340
367
|
};
|
|
341
368
|
|
|
342
|
-
|
|
343
|
-
const fixLast = isLastColumnFixed(fixedColumnsMode) && columnIndex === columnsLength - 1;
|
|
344
|
-
|
|
345
|
-
if (!fixFirst && !fixLast) {
|
|
369
|
+
if (!pinnedState) {
|
|
346
370
|
return style;
|
|
347
371
|
}
|
|
348
372
|
|
|
349
373
|
style.position = 'sticky';
|
|
350
|
-
style.background =
|
|
351
|
-
style.
|
|
374
|
+
style.background = PINNED_SURFACE_BACKGROUND;
|
|
375
|
+
style.backgroundClip = 'padding-box';
|
|
376
|
+
style.zIndex = isHeader ? 50 : 30;
|
|
377
|
+
|
|
378
|
+
if (pinnedState.side === 'left') {
|
|
379
|
+
style.left = `${pinnedState.offset}px`;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (pinnedState.side === 'right') {
|
|
383
|
+
style.right = `${pinnedState.offset}px`;
|
|
384
|
+
}
|
|
352
385
|
|
|
353
|
-
if (
|
|
354
|
-
style.left = 0;
|
|
386
|
+
if (pinnedState.edge === 'right') {
|
|
355
387
|
style.boxShadow = '2px 0 0 rgba(45, 66, 107, 0.06)';
|
|
356
388
|
}
|
|
357
389
|
|
|
358
|
-
if (
|
|
359
|
-
style.right = 0;
|
|
390
|
+
if (pinnedState.edge === 'left') {
|
|
360
391
|
style.boxShadow = '-2px 0 0 rgba(45, 66, 107, 0.06)';
|
|
361
392
|
}
|
|
362
393
|
|
|
@@ -1107,6 +1138,10 @@ export default function Table({
|
|
|
1107
1138
|
: [pageSize];
|
|
1108
1139
|
const columnTemplate = useMemo(() => buildColumnGridTemplate(columns), [columns]);
|
|
1109
1140
|
const columnTemplateMinWidth = useMemo(() => getColumnTemplateMinWidth(columns), [columns]);
|
|
1141
|
+
const pinnedColumnStates = useMemo(
|
|
1142
|
+
() => getPinnedColumnStates(columns, fixedColumnsMode),
|
|
1143
|
+
[columns, fixedColumnsMode],
|
|
1144
|
+
);
|
|
1110
1145
|
const selectValue = Number.isNaN(Number(pageSize)) ? pageSize : Number(pageSize);
|
|
1111
1146
|
const selectOptions = useMemo(() => {
|
|
1112
1147
|
const normalized = Array.from(new Set([...pageSizeOptions, pageSize]));
|
|
@@ -1269,7 +1304,7 @@ export default function Table({
|
|
|
1269
1304
|
<div className={TABLE} role="grid" aria-rowcount={visibleDataSource.length + 1} aria-colcount={columns.length}>
|
|
1270
1305
|
<div className={HEADER_ROW} role="row" style={{ gridTemplateColumns: columnTemplate }}>
|
|
1271
1306
|
{columns.map((column, columnIndex) => (
|
|
1272
|
-
|
|
1307
|
+
<div
|
|
1273
1308
|
key={column.key || column.dataIndex || column.title}
|
|
1274
1309
|
className={[
|
|
1275
1310
|
HEADER_CELL,
|
|
@@ -1277,11 +1312,9 @@ export default function Table({
|
|
|
1277
1312
|
].join(' ')}
|
|
1278
1313
|
role="columnheader"
|
|
1279
1314
|
style={getPinnedCellStyle({
|
|
1280
|
-
columnIndex,
|
|
1281
|
-
columnsLength: columns.length,
|
|
1282
1315
|
align: column.align,
|
|
1283
1316
|
minHeight: HEADER_MIN_HEIGHT[normalizeCellSize(column.cellSize)] || HEADER_MIN_HEIGHT.default,
|
|
1284
|
-
|
|
1317
|
+
pinnedState: pinnedColumnStates[columnIndex],
|
|
1285
1318
|
isHeader: true,
|
|
1286
1319
|
})}
|
|
1287
1320
|
>
|
|
@@ -1317,11 +1350,9 @@ export default function Table({
|
|
|
1317
1350
|
)}
|
|
1318
1351
|
role="gridcell"
|
|
1319
1352
|
style={getPinnedCellStyle({
|
|
1320
|
-
columnIndex,
|
|
1321
|
-
columnsLength: columns.length,
|
|
1322
1353
|
align: column.align,
|
|
1323
1354
|
minHeight: getTypeMinHeight(normalizeColumnType(column.type), normalizeCellSize(column.cellSize)),
|
|
1324
|
-
|
|
1355
|
+
pinnedState: pinnedColumnStates[columnIndex],
|
|
1325
1356
|
})}
|
|
1326
1357
|
>
|
|
1327
1358
|
<div className="w-full min-w-0">
|