@done-coding/admin-core 0.27.1-alpha.0 → 0.28.1-alpha.0
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/es/bridge/badge.mjs +0 -1
- package/es/bridge/route.mjs +4 -1
- package/es/components/app-layout/AppHeader.vue.mjs +1 -1
- package/es/components/app-layout/AppHeader.vue2.mjs +2 -2
- package/es/components/app-layout/AppPage.vue.mjs +1 -1
- package/es/components/app-layout/AppPage.vue2.mjs +7 -7
- package/es/components/app-layout/app-page-geometry.mjs +2 -2
- package/es/components/display/BadgeMark.vue.mjs +1 -1
- package/es/components/display/BadgeMark.vue2.mjs +25 -15
- package/es/components/display/TabsHeader.vue.mjs +1 -1
- package/es/components/display/TabsHeader.vue2.mjs +1 -1
- package/es/components/display/TabsMain.vue.mjs +1 -1
- package/es/components/display/use-badge-mask.mjs +2 -3
- package/es/components/display/use-badge.mjs +36 -39
- package/es/components/form/FormMain.vue.mjs +1 -1
- package/es/components/form/FormSearch.vue.mjs +1 -1
- package/es/components/menu/MenuItemSub.vue.mjs +2 -2
- package/es/components/menu/MenuTree.vue.mjs +3 -3
- package/es/components/view-layout/ViewLayout.vue.mjs +1 -1
- package/es/components/view-layout/ViewLayout.vue2.mjs +1 -1
- package/es/config/badge-attr.mjs +6 -0
- package/es/hooks/use-theme-apply.mjs +48 -0
- package/es/index.mjs +3 -0
- package/es/style.css +97 -78
- package/es/utils/dom.mjs +12 -2
- package/package.json +2 -2
- package/src/bridge/docs/README.md +27 -2
- package/src/components/app-layout/docs/README-AppPage.md +1 -1
- package/src/components/display/docs/README-BadgeMark.md +24 -1
- package/src/components/page-layout/docs/README-AppPageListDetailLayout.md +1 -1
- package/src/components/view-layout/docs/README-ViewLayout.md +8 -2
- package/types/bridge/badge.d.ts +44 -7
- package/types/components/app-layout/app-page-geometry.d.ts +9 -2
- package/types/components/display/BadgeMark.vue.d.ts +5 -2
- package/types/components/display/use-badge.d.ts +40 -7
- package/types/config/badge-attr.d.ts +26 -0
- package/types/config/index.d.ts +1 -0
- package/types/hooks/menus-dispatch.d.ts +1 -0
- package/types/injectInfo.json.d.ts +1 -1
- package/types/types/route.d.ts +8 -0
- package/types/utils/dom.d.ts +10 -4
package/es/style.css
CHANGED
|
@@ -66,34 +66,35 @@
|
|
|
66
66
|
justify-content: flex-end;
|
|
67
67
|
gap: 8px;
|
|
68
68
|
}
|
|
69
|
-
.badge-mark[data-v-
|
|
69
|
+
.badge-mark[data-v-18853ddc] .el-badge__content.is-fixed {
|
|
70
70
|
right: 0;
|
|
71
71
|
transform: translateY(-50%) translateX(calc(100% + 2px));
|
|
72
72
|
}
|
|
73
|
-
.badge-mark_middle[data-v-
|
|
73
|
+
.badge-mark_middle[data-v-18853ddc] .el-badge__content.is-fixed {
|
|
74
74
|
top: 50%;
|
|
75
75
|
}
|
|
76
|
-
.badge-mark[data-v-
|
|
76
|
+
.badge-mark[data-v-18853ddc] .badge-mark__icon {
|
|
77
77
|
display: block;
|
|
78
78
|
font-size: 1em;
|
|
79
79
|
line-height: 1;
|
|
80
80
|
}
|
|
81
|
-
.app-page[data-v-
|
|
82
|
-
--dc-page-content-viewport-top: var(--
|
|
83
|
-
--dc-page-content-viewport-bottom: var(--
|
|
84
|
-
--dc-page-content-viewport-left: var(--
|
|
85
|
-
--dc-page-content-viewport-right: var(--
|
|
86
|
-
--dc-page-content-viewport-width: var(--
|
|
87
|
-
--dc-page-content-viewport-height: var(--
|
|
81
|
+
.app-page[data-v-facaf577] {
|
|
82
|
+
--dc-page-content-viewport-top: var(--v14c1dc69);
|
|
83
|
+
--dc-page-content-viewport-bottom: var(--v6d1cb697);
|
|
84
|
+
--dc-page-content-viewport-left: var(--f914311a);
|
|
85
|
+
--dc-page-content-viewport-right: var(--v28c52fa0);
|
|
86
|
+
--dc-page-content-viewport-width: var(--v2838584c);
|
|
87
|
+
--dc-page-content-viewport-height: var(--v76c7ad93);
|
|
88
88
|
}
|
|
89
|
-
.app-page-shim[data-v-
|
|
89
|
+
.app-page-shim[data-v-facaf577] {
|
|
90
90
|
display: flow-root;
|
|
91
|
-
--app-viewport-max-height: var(--
|
|
91
|
+
--app-viewport-max-height: var(--v9258c294);
|
|
92
92
|
}
|
|
93
|
-
.app-page-slot-shim[data-v-
|
|
93
|
+
.app-page-slot-shim[data-v-facaf577] {
|
|
94
94
|
box-sizing: border-box;
|
|
95
95
|
width: 100%;
|
|
96
96
|
height: 100%;
|
|
97
|
+
border-radius: var(--dc-core-radius, var(--el-border-radius-base));
|
|
97
98
|
}
|
|
98
99
|
[data-v-64f355fe] .auto-refresh-label {
|
|
99
100
|
display: flex;
|
|
@@ -130,7 +131,7 @@ to {
|
|
|
130
131
|
text-align: center;
|
|
131
132
|
font-variant-numeric: tabular-nums;
|
|
132
133
|
}
|
|
133
|
-
.view-layout-header[data-v-
|
|
134
|
+
.view-layout-header[data-v-e7dc3f12] {
|
|
134
135
|
flex: 0 1 auto;
|
|
135
136
|
min-width: 0;
|
|
136
137
|
overflow: hidden;
|
|
@@ -141,38 +142,47 @@ to {
|
|
|
141
142
|
white-space: nowrap;
|
|
142
143
|
text-overflow: ellipsis;
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
-
box-shadow: inset 0 -1px 0 0 var(--el-border-color-extra-light), inset 0 -6px 6px -6px var(--el-border-color-extra-light);
|
|
146
|
-
}
|
|
147
|
-
.view-layout[data-v-0507f728] {
|
|
145
|
+
.view-layout[data-v-e7dc3f12] {
|
|
148
146
|
display: flex;
|
|
149
147
|
flex-direction: column;
|
|
150
148
|
}
|
|
151
|
-
.view-layout-toolbar[data-v-
|
|
149
|
+
.view-layout-toolbar[data-v-e7dc3f12] {
|
|
152
150
|
display: flex;
|
|
153
151
|
justify-content: space-between;
|
|
154
152
|
align-items: center;
|
|
155
|
-
padding
|
|
153
|
+
padding: 0 8px 8px;
|
|
154
|
+
position: relative;
|
|
156
155
|
gap: 20px;
|
|
157
|
-
|
|
156
|
+
background: color-mix(in srgb, var(--dc-core-surface, var(--el-bg-color)) 50%, var(--dc-core-ground, var(--el-bg-color-page)));
|
|
157
|
+
border-radius: 0;
|
|
158
158
|
}
|
|
159
|
-
.view-layout-
|
|
160
|
-
|
|
159
|
+
.view-layout-toolbar[data-v-e7dc3f12]::before {
|
|
160
|
+
content: "";
|
|
161
|
+
position: absolute;
|
|
162
|
+
top: 0;
|
|
163
|
+
bottom: 0;
|
|
164
|
+
left: 0;
|
|
165
|
+
width: 3px;
|
|
166
|
+
border-radius: 3px;
|
|
167
|
+
background: var(--dc-core-primary-color, var(--el-color-primary));
|
|
168
|
+
}
|
|
169
|
+
.view-layout-toolbar__left[data-v-e7dc3f12],
|
|
170
|
+
.view-layout-toolbar__right[data-v-e7dc3f12] {
|
|
161
171
|
display: flex;
|
|
162
172
|
align-items: center;
|
|
163
173
|
gap: 10px;
|
|
164
174
|
}
|
|
165
|
-
.view-layout-toolbar__left[data-v-
|
|
166
|
-
.view-layout-toolbar__right[data-v-
|
|
175
|
+
.view-layout-toolbar__left[data-v-e7dc3f12] > *,
|
|
176
|
+
.view-layout-toolbar__right[data-v-e7dc3f12] > * {
|
|
167
177
|
flex: none;
|
|
168
178
|
}
|
|
169
|
-
.view-layout-toolbar__left .view-layout-header[data-v-
|
|
179
|
+
.view-layout-toolbar__left .view-layout-header[data-v-e7dc3f12] {
|
|
170
180
|
flex: 1 1 auto;
|
|
171
181
|
}
|
|
172
|
-
.view-layout-toolbar__right[data-v-
|
|
182
|
+
.view-layout-toolbar__right[data-v-e7dc3f12] {
|
|
173
183
|
flex: none;
|
|
174
184
|
}
|
|
175
|
-
.view-layout-content[data-v-
|
|
185
|
+
.view-layout-content[data-v-e7dc3f12] {
|
|
176
186
|
overflow: auto;
|
|
177
187
|
}
|
|
178
188
|
.dc-app-page-detail__title[data-v-4426d26a] {
|
|
@@ -232,33 +242,33 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
232
242
|
opacity: 0.3;
|
|
233
243
|
}
|
|
234
244
|
}
|
|
235
|
-
[data-v-
|
|
236
|
-
margin-bottom: 18px;
|
|
245
|
+
[data-v-ba043bbe] .el-row > .el-col > .el-form-item {
|
|
246
|
+
margin-bottom: var(--dc-core-form-item-gap, 18px);
|
|
237
247
|
}
|
|
238
|
-
[data-v-
|
|
248
|
+
[data-v-ba043bbe] .el-row > .el-col > .el-form-item.dc-form-item-collapsed,[data-v-ba043bbe] .el-row > .el-col:has(> .el-form-item.dc-form-item-collapsed) {
|
|
239
249
|
display: none;
|
|
240
250
|
}
|
|
241
|
-
[data-v-
|
|
251
|
+
[data-v-ba043bbe] .el-row > .el-col > .el-form-item.dc-form-item-pseudo {
|
|
242
252
|
margin-bottom: 8px;
|
|
243
253
|
}
|
|
244
|
-
.dc-form-main[data-v-
|
|
254
|
+
.dc-form-main[data-v-ba043bbe] {
|
|
245
255
|
position: relative;
|
|
246
256
|
}
|
|
247
|
-
.dc-form-main .form-ai-fill-anchor[data-v-
|
|
257
|
+
.dc-form-main .form-ai-fill-anchor[data-v-ba043bbe] {
|
|
248
258
|
opacity: 0.45;
|
|
249
259
|
transition: opacity var(--dc-core-motion-duration, 0.2s) ease;
|
|
250
260
|
}
|
|
251
|
-
.dc-form-main:hover .form-ai-fill-anchor[data-v-
|
|
252
|
-
.dc-form-main:focus-within .form-ai-fill-anchor[data-v-
|
|
253
|
-
.dc-form-main .form-ai-fill-anchor[data-v-
|
|
254
|
-
.dc-form-main .form-ai-fill-anchor[data-v-
|
|
261
|
+
.dc-form-main:hover .form-ai-fill-anchor[data-v-ba043bbe],
|
|
262
|
+
.dc-form-main:focus-within .form-ai-fill-anchor[data-v-ba043bbe],
|
|
263
|
+
.dc-form-main .form-ai-fill-anchor[data-v-ba043bbe]:hover,
|
|
264
|
+
.dc-form-main .form-ai-fill-anchor[data-v-ba043bbe]:focus-within {
|
|
255
265
|
opacity: 1;
|
|
256
266
|
}
|
|
257
|
-
[data-v-
|
|
258
|
-
animation: dc-form-ai-filled-flash-
|
|
267
|
+
[data-v-ba043bbe] .el-col.dc-form-item-ai-filled > .el-form-item {
|
|
268
|
+
animation: dc-form-ai-filled-flash-ba043bbe 1.6s ease-out;
|
|
259
269
|
border-radius: 4px;
|
|
260
270
|
}
|
|
261
|
-
@keyframes dc-form-ai-filled-flash-
|
|
271
|
+
@keyframes dc-form-ai-filled-flash-ba043bbe {
|
|
262
272
|
0% {
|
|
263
273
|
background-color: var(--dc-core-primary-color-light-8, var(--el-color-primary-light-8));
|
|
264
274
|
}
|
|
@@ -385,16 +395,23 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
385
395
|
.panel-main-item-col:not(:last-of-type) .panel-main-item-col-wrap_card[data-v-e74d05c3] {
|
|
386
396
|
margin-bottom: var(--v0799966c);
|
|
387
397
|
}
|
|
388
|
-
.form-
|
|
398
|
+
.form-search[data-v-e52f9711] {
|
|
399
|
+
display: flow-root;
|
|
400
|
+
}
|
|
401
|
+
.form-search_show[data-v-e52f9711] {
|
|
389
402
|
margin-bottom: 10px;
|
|
390
403
|
}
|
|
391
|
-
.form-search
|
|
404
|
+
.form-search[data-v-e52f9711] > .el-form {
|
|
405
|
+
margin-bottom: calc(-1 * var(--dc-core-form-item-gap, 18px));
|
|
406
|
+
}
|
|
407
|
+
.form-search .btn-box[data-v-e52f9711] {
|
|
392
408
|
display: flex;
|
|
393
409
|
align-items: center;
|
|
394
410
|
gap: 8px;
|
|
395
411
|
justify-content: flex-end;
|
|
412
|
+
margin-bottom: var(--dc-core-form-item-gap, 18px);
|
|
396
413
|
}
|
|
397
|
-
.form-search .btn-box-expand-icon[data-v-
|
|
414
|
+
.form-search .btn-box-expand-icon[data-v-e52f9711] {
|
|
398
415
|
margin-right: 2px;
|
|
399
416
|
}
|
|
400
417
|
.form-verify-image[data-v-7a70397e] .el-input__suffix-inner * {
|
|
@@ -417,11 +434,13 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
417
434
|
height: 100%;
|
|
418
435
|
background-color: #f4f4f4;
|
|
419
436
|
}
|
|
420
|
-
.tabs-main-bar[data-v-
|
|
437
|
+
.tabs-main-bar[data-v-2fbdd074] {
|
|
421
438
|
position: relative;
|
|
422
439
|
display: flex;
|
|
423
440
|
align-items: center;
|
|
424
441
|
/* ============ Level —— 只控字号 ============ */
|
|
442
|
+
/* 卡片变体的内缩距离:**同心圆角公式 R₂ = R₁ + D 的那个 D**。
|
|
443
|
+
容器 padding 与外圆角 [MUST] 共用它,[MUST NOT] 两处各写一个数(改一处就不同心了)。 */
|
|
425
444
|
/* ============ Variant: card —— 分段块(segmented / pill) ============
|
|
426
445
|
容器一条**面色底**,选中项一块**浅色圆角块** + 主色字。对比来自「块」本身,
|
|
427
446
|
不依赖与下方 content 的连通 —— 故在「各模块成面 + gap 露底」的布局里同样成立。
|
|
@@ -435,77 +454,77 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
435
454
|
/* ============ Variant: indicator-compact —— 紧凑 1px 下划线 ============ */
|
|
436
455
|
/* ============ Variant: plain —— 无装饰(active 加粗 + primary 字色) ============ */
|
|
437
456
|
}
|
|
438
|
-
.tabs-main-bar-item[data-v-
|
|
457
|
+
.tabs-main-bar-item[data-v-2fbdd074] {
|
|
439
458
|
border: none;
|
|
440
459
|
background: transparent;
|
|
441
460
|
cursor: pointer;
|
|
442
461
|
color: var(--el-text-color-regular);
|
|
443
462
|
transition: background 0.2s, color 0.2s, box-shadow 0.2s;
|
|
444
463
|
}
|
|
445
|
-
.tabs-main-bar-indicator[data-v-
|
|
464
|
+
.tabs-main-bar-indicator[data-v-2fbdd074] {
|
|
446
465
|
position: absolute;
|
|
447
466
|
left: 0;
|
|
448
467
|
background: var(--dc-core-primary-color);
|
|
449
468
|
transition: transform 0.2s, width 0.2s;
|
|
450
469
|
}
|
|
451
|
-
.tabs-main-bar--l1 .tabs-main-bar-item[data-v-
|
|
470
|
+
.tabs-main-bar--l1 .tabs-main-bar-item[data-v-2fbdd074] {
|
|
452
471
|
font-size: 16px;
|
|
453
472
|
}
|
|
454
|
-
.tabs-main-bar--l2 .tabs-main-bar-item[data-v-
|
|
473
|
+
.tabs-main-bar--l2 .tabs-main-bar-item[data-v-2fbdd074] {
|
|
455
474
|
font-size: 14px;
|
|
456
475
|
}
|
|
457
|
-
.tabs-main-bar--l3 .tabs-main-bar-item[data-v-
|
|
476
|
+
.tabs-main-bar--l3 .tabs-main-bar-item[data-v-2fbdd074] {
|
|
458
477
|
font-size: 12px;
|
|
459
478
|
}
|
|
460
|
-
.tabs-main-bar--l4 .tabs-main-bar-item[data-v-
|
|
479
|
+
.tabs-main-bar--l4 .tabs-main-bar-item[data-v-2fbdd074] {
|
|
461
480
|
font-size: 12px;
|
|
462
481
|
}
|
|
463
|
-
.tabs-main-bar--variant-card[data-v-
|
|
482
|
+
.tabs-main-bar--variant-card[data-v-2fbdd074] {
|
|
464
483
|
gap: 2px;
|
|
465
484
|
align-items: stretch;
|
|
466
|
-
padding:
|
|
485
|
+
padding: 8px 8px 0;
|
|
467
486
|
background: var(--el-bg-color);
|
|
468
|
-
border-radius: var(--dc-core-radius, var(--el-border-radius-base)) var(--dc-core-radius, var(--el-border-radius-base)) 0 0;
|
|
487
|
+
border-radius: calc(var(--dc-core-radius, var(--el-border-radius-base)) + 8px) calc(var(--dc-core-radius, var(--el-border-radius-base)) + 8px) 0 0;
|
|
469
488
|
}
|
|
470
|
-
.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-
|
|
489
|
+
.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-2fbdd074] {
|
|
471
490
|
display: flex;
|
|
472
491
|
align-items: center;
|
|
473
492
|
padding: 6px 16px;
|
|
474
493
|
line-height: 1.4;
|
|
475
494
|
border-radius: var(--dc-core-radius, var(--el-border-radius-base)) var(--dc-core-radius, var(--el-border-radius-base)) 0 0;
|
|
476
495
|
}
|
|
477
|
-
.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-
|
|
496
|
+
.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-2fbdd074]:hover:not(.tabs-main-bar-item_active) {
|
|
478
497
|
color: var(--dc-core-primary-color);
|
|
479
498
|
}
|
|
480
|
-
.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-
|
|
499
|
+
.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-2fbdd074] {
|
|
481
500
|
color: var(--dc-core-primary-color);
|
|
482
501
|
font-weight: 500;
|
|
483
|
-
background: var(--
|
|
502
|
+
background: var(--v0fab19c0);
|
|
484
503
|
}
|
|
485
|
-
.tabs-main-bar--variant-indicator .tabs-main-bar-item[data-v-
|
|
504
|
+
.tabs-main-bar--variant-indicator .tabs-main-bar-item[data-v-2fbdd074] {
|
|
486
505
|
padding: 8px 16px;
|
|
487
506
|
}
|
|
488
|
-
.tabs-main-bar--variant-indicator .tabs-main-bar-item_active[data-v-
|
|
507
|
+
.tabs-main-bar--variant-indicator .tabs-main-bar-item_active[data-v-2fbdd074] {
|
|
489
508
|
color: var(--dc-core-primary-color);
|
|
490
509
|
}
|
|
491
|
-
.tabs-main-bar--variant-indicator .tabs-main-bar-indicator[data-v-
|
|
510
|
+
.tabs-main-bar--variant-indicator .tabs-main-bar-indicator[data-v-2fbdd074] {
|
|
492
511
|
bottom: 0;
|
|
493
512
|
height: 2px;
|
|
494
513
|
}
|
|
495
|
-
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item[data-v-
|
|
514
|
+
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item[data-v-2fbdd074] {
|
|
496
515
|
padding: 6px 10px;
|
|
497
516
|
}
|
|
498
|
-
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item_active[data-v-
|
|
517
|
+
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item_active[data-v-2fbdd074] {
|
|
499
518
|
color: var(--dc-core-primary-color);
|
|
500
519
|
}
|
|
501
|
-
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-indicator[data-v-
|
|
520
|
+
.tabs-main-bar--variant-indicator-compact .tabs-main-bar-indicator[data-v-2fbdd074] {
|
|
502
521
|
bottom: 0;
|
|
503
522
|
height: 1px;
|
|
504
523
|
}
|
|
505
|
-
.tabs-main-bar--variant-plain .tabs-main-bar-item[data-v-
|
|
524
|
+
.tabs-main-bar--variant-plain .tabs-main-bar-item[data-v-2fbdd074] {
|
|
506
525
|
padding: 4px 8px;
|
|
507
526
|
}
|
|
508
|
-
.tabs-main-bar--variant-plain .tabs-main-bar-item_active[data-v-
|
|
527
|
+
.tabs-main-bar--variant-plain .tabs-main-bar-item_active[data-v-2fbdd074] {
|
|
509
528
|
color: var(--dc-core-primary-color);
|
|
510
529
|
font-weight: 600;
|
|
511
530
|
}
|
|
@@ -631,7 +650,7 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
631
650
|
height: 100%;
|
|
632
651
|
padding: 0 20px;
|
|
633
652
|
}
|
|
634
|
-
.app-header[data-v-
|
|
653
|
+
.app-header[data-v-fe33f01b] {
|
|
635
654
|
transition-duration: 0.3s;
|
|
636
655
|
transition-property: height;
|
|
637
656
|
transition-timing-function: linear;
|
|
@@ -639,13 +658,13 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
639
658
|
box-shadow: var(--dc-core-shadow, var(--el-box-shadow));
|
|
640
659
|
z-index: 1;
|
|
641
660
|
}
|
|
642
|
-
.app-header-module[data-v-
|
|
661
|
+
.app-header-module[data-v-fe33f01b] {
|
|
643
662
|
display: flex;
|
|
644
663
|
flex: 1;
|
|
645
664
|
height: 100%;
|
|
646
665
|
overflow-x: auto;
|
|
647
666
|
}
|
|
648
|
-
.app-header-module-item[data-v-
|
|
667
|
+
.app-header-module-item[data-v-fe33f01b] {
|
|
649
668
|
display: flex;
|
|
650
669
|
justify-content: center;
|
|
651
670
|
align-items: center;
|
|
@@ -653,24 +672,24 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
653
672
|
white-space: nowrap;
|
|
654
673
|
height: 100%;
|
|
655
674
|
}
|
|
656
|
-
.app-header-module-item[data-v-
|
|
657
|
-
.app-header-module-item_active[data-v-
|
|
658
|
-
color: var(--
|
|
675
|
+
.app-header-module-item[data-v-fe33f01b]:hover,
|
|
676
|
+
.app-header-module-item_active[data-v-fe33f01b] {
|
|
677
|
+
color: var(--v5a41bfe6);
|
|
659
678
|
}
|
|
660
|
-
.app-header-module-item_active[data-v-
|
|
679
|
+
.app-header-module-item_active[data-v-fe33f01b] {
|
|
661
680
|
position: relative;
|
|
662
681
|
}
|
|
663
|
-
.app-header-module-item_active[data-v-
|
|
682
|
+
.app-header-module-item_active[data-v-fe33f01b]::before {
|
|
664
683
|
content: "";
|
|
665
684
|
position: absolute;
|
|
666
685
|
left: 50%;
|
|
667
686
|
top: 0;
|
|
668
687
|
width: 100%;
|
|
669
688
|
height: 3px;
|
|
670
|
-
background-color: var(--
|
|
689
|
+
background-color: var(--v5a41bfe6);
|
|
671
690
|
transform: translateX(-50%);
|
|
672
691
|
}
|
|
673
|
-
.app-header-shim[data-v-
|
|
692
|
+
.app-header-shim[data-v-fe33f01b] {
|
|
674
693
|
width: 100%;
|
|
675
694
|
height: 100%;
|
|
676
695
|
display: flex;
|
|
@@ -680,10 +699,10 @@ html.dark .view-layout-toolbar[data-v-0507f728] {
|
|
|
680
699
|
font-size: 18px;
|
|
681
700
|
font-weight: bold;
|
|
682
701
|
}
|
|
683
|
-
.app-header-module-item__icon[data-v-
|
|
702
|
+
.app-header-module-item__icon[data-v-fe33f01b] {
|
|
684
703
|
margin-right: 8px;
|
|
685
704
|
}
|
|
686
|
-
.app-header-right[data-v-
|
|
705
|
+
.app-header-right[data-v-fe33f01b] {
|
|
687
706
|
padding-left: 80px;
|
|
688
707
|
display: flex;
|
|
689
708
|
align-items: center;
|
package/es/utils/dom.mjs
CHANGED
|
@@ -20,10 +20,20 @@ function domClosestStickyScrollport(el) {
|
|
|
20
20
|
}
|
|
21
21
|
return void 0;
|
|
22
22
|
}
|
|
23
|
+
function domPreferredScrollBehavior() {
|
|
24
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
25
|
+
return "smooth";
|
|
26
|
+
}
|
|
27
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth";
|
|
28
|
+
}
|
|
23
29
|
function domScrollIntoViewport(target, options = {}) {
|
|
24
30
|
if (!target || typeof target.scrollIntoView !== "function") return;
|
|
25
|
-
const {
|
|
26
|
-
target.scrollIntoView({
|
|
31
|
+
const { block = "nearest", inline = "nearest" } = options;
|
|
32
|
+
target.scrollIntoView({
|
|
33
|
+
behavior: options.behavior ?? domPreferredScrollBehavior(),
|
|
34
|
+
block,
|
|
35
|
+
inline
|
|
36
|
+
});
|
|
27
37
|
}
|
|
28
38
|
export {
|
|
29
39
|
domClosestScrollableAncestor,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@done-coding/admin-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1-alpha.0",
|
|
4
4
|
"description": "内部前端库",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "es/index.mjs",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@tanstack/vue-virtual": "^3.13.35"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "89cee2eb458d349b9a6f2f1acb6088f811cd5e8d"
|
|
87
87
|
}
|
|
@@ -86,18 +86,26 @@ type BadgeEntry = {
|
|
|
86
86
|
expireAt?: number;
|
|
87
87
|
/** 面向 agent / AI 对话的语义描述(core 不消费,纯透传;自由文本) */
|
|
88
88
|
description?: string;
|
|
89
|
+
/** 本条标的版本号(core 不消费,纯透传);消费方据它做「版本化的已读记录」 */
|
|
90
|
+
version?: string | number;
|
|
89
91
|
} & (
|
|
90
92
|
| { kind: "count"; value: number; max?: number } // 数字角标
|
|
91
93
|
| { kind: "new" } // 新上线
|
|
92
94
|
| { kind: "updated" } // 更新
|
|
93
95
|
| { kind: "beta" } // 内测:能用,不稳定
|
|
94
|
-
| { kind: "wip" } //
|
|
96
|
+
| { kind: "wip" } // 开发中:仅提示,**不拦点击**
|
|
95
97
|
| { kind: "custom"; text: string; type?: BadgeProps["type"] }
|
|
98
|
+
| { kind: "anchor" } // 伪标:不渲染角标,只留 DOM 挂点供引导定位
|
|
96
99
|
);
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
内置五档的文案与语义色由 core 统一定,保证跨 app 一致;`custom` 只在内置档不够用时用。
|
|
100
103
|
|
|
104
|
+
**`version` 的用处**:消费方(如 `forge-plugin-guide`)把已读记录的 key 取成 `key@version`
|
|
105
|
+
⇒ **功能有实质更新时改一下版本号,引导 / 提示就对所有人重新出现一次**;不改则关过的人不再被打扰。
|
|
106
|
+
不填时退化为裸 `key`。与 `expireAt`(时效)、`bizKey`(业务标识)三者正交,
|
|
107
|
+
[MUST NOT] 拿它做灰度 / 权限判断。
|
|
108
|
+
|
|
101
109
|
`custom.type` 取 element-plus 的语义色档(`primary` / `success` / `warning` / `danger` / `info`),随主题亮暗自适配。[MUST NOT] 传色值字面量——规则 14,写死色切主题不响应。
|
|
102
110
|
|
|
103
111
|
### API
|
|
@@ -124,10 +132,27 @@ type BadgeEntry = {
|
|
|
124
132
|
|
|
125
133
|
| 消费点 | key 取值 |
|
|
126
134
|
| --- | --- |
|
|
127
|
-
| 菜单项(AppSidebar 菜单树 / AppHeader 模块条) | **路由 `path
|
|
135
|
+
| 菜单项(AppSidebar 菜单树 / AppHeader 模块条) | **路由 `name` 优先、`path` 兜底**(两者都查,先命中先用),无需另配 |
|
|
128
136
|
| `ActionBtn` | 显式 `badgeKey`(按钮没有 path) |
|
|
129
137
|
| `TabsMain` 的 tab 标题(tab-bar / tile 卡片 / tile 角落 nav 三处同步) | `TabsMainItem.badgeKey`。[MUST NOT] 复用 `item.key`——那是**局部唯一**(v-model 值 + 槽名),跨页会串标 |
|
|
130
138
|
|
|
139
|
+
#### 菜单侧为什么 `name` 优先
|
|
140
|
+
|
|
141
|
+
看标的**数据来源**:有 `expireAt` 的静态标(随版本写死的 NEW)在前端代码里写,用什么 key 都行;
|
|
142
|
+
而**无 `expireAt` 的动态标(待办数 / 未开通)由服务端下发、app 轮询 `setAll`** —— 那才是主场景,
|
|
143
|
+
而**服务端不该知道前端的 URL 结构**。`path` 是展示层产物:加一层路由前缀、把模块挪一级、
|
|
144
|
+
路径国际化,服务端那张 key 表就整体失效,且**静默失效**(标不显示而已,不报错、不告警)。
|
|
145
|
+
`name` 是路由的逻辑标识,正是为这种跨层引用存在。
|
|
146
|
+
|
|
147
|
+
`path` [MUST NOT] 拿掉:`name` 在 vue-router 里是**可选的**,没配 name 的路由拿不到 key
|
|
148
|
+
就直接挂不上标;留 path 兜底也让本能力天然 additive —— 现有以 path 注册的一行都不用动。
|
|
149
|
+
|
|
150
|
+
key 空间不会串:`name` 惯例是 camelCase、`path` 必带 `/`。
|
|
151
|
+
[MUST NOT] 为此引入「带前缀区分类型」之类的 key 编码 —— 那是给零概率问题上税。
|
|
152
|
+
|
|
153
|
+
⚠️ vue-router 的 `RouteRecordName = string | symbol`,**symbol 不能当 key**;
|
|
154
|
+
`bridge.getRoutes()` 的解析期已过滤(`typeof name === "string" ? name : undefined`)。
|
|
155
|
+
|
|
131
156
|
### `description`:让这张表可被 agent 读
|
|
132
157
|
|
|
133
158
|
`description` 是 **core 完全不消费**的纯透传字段,供应用层做「本期上了什么功能」这类 AI 对话时,让模型知道某个 key 指向什么、怎么用、什么时候还不该用。
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
| `contentCentered` | `boolean` | `false` | 默认 slot 内容限宽居中(超宽屏适配);同步收窄对后代公布的内容几何(见下) |
|
|
63
63
|
| `contentMaxWidth` | `number` | `1200` | 限宽值(px),仅 `contentCentered` 开启时生效 |
|
|
64
64
|
| `gap` | `number` | `8` | 间距基数 px(缺省读 bridge `APP_LAYOUT_GAP_CONFIG.size`)。**槽 ↔ 内容**与**槽 ↔ 槽**都取由它派生的「外圈档」(`基数 × 2`,随密度缩放),两处同式同源 |
|
|
65
|
-
| `topBg` / `bottomBg` / `leftBg` / `rightBg` | `string` | `var(--el-bg-color)`(面色) | 各槽 shim 背景;传 `"transparent"`
|
|
65
|
+
| `topBg` / `bottomBg` / `leftBg` / `rightBg` | `string` | `var(--el-bg-color)`(面色) | 各槽 shim 背景;传 `"transparent"` 可关。**shim 自带圆角**(`--dc-core-radius`,随主题;无 bg 的槽透明、圆角无视觉影响) |
|
|
66
66
|
|
|
67
67
|
> **五个背景 prop 的契约(分两组,判据是「块」还是「容器」)**
|
|
68
68
|
>
|
|
@@ -108,8 +108,31 @@ bridge.badge.set("/order/list", { kind: "new" });
|
|
|
108
108
|
| `new` | 新 | `success` 绿 | 新功能上线是**正面资讯**(Atlassian success 档即覆盖 "added")。[MUST NOT] 复用红——会与 `count` 撞色,扫视时分不清「有新东西」和「有待办」 |
|
|
109
109
|
| `updated` | 更新 | `primary` 主色 | 中性被动通知,不喧宾夺主 |
|
|
110
110
|
| `beta` | 内测 | `warning` 橙 | 能用但**不稳定需谨慎**,正是 warning 语义 |
|
|
111
|
-
| `wip` | 开发 | `info` 灰 |
|
|
111
|
+
| `wip` | 开发 | `info` 灰 | 尚不完善,中性、不引导点击。**仅提示,不拦点击** |
|
|
112
112
|
| `custom` | 自定 | 缺省 `primary` | 内置档不够用时才用;`type` 只收语义档 |
|
|
113
|
+
| `anchor` | —— | —— | **伪标 / 纯锚点**:不渲染角标,只留 DOM 挂点供引导等消费方定位 |
|
|
114
|
+
|
|
115
|
+
### `anchor`:只要挂点、不要角标
|
|
116
|
+
|
|
117
|
+
想给某个菜单项 / 按钮做新手引导,但它本身没有「新 / 更新」之类的标要显示时用它。
|
|
118
|
+
[MUST NOT] 为此硬挂一个 `new` —— 那会在界面上多出一个用户看不懂的角标。
|
|
119
|
+
|
|
120
|
+
🔴 实现上走 `ElBadge` 的 `hidden`(藏角标、留挂点),**[MUST NOT] 改成「不渲染」**:
|
|
121
|
+
本组件是 `v-if="resolved"`,不渲染会连 `data-dc-badge-key` 一起没掉,
|
|
122
|
+
消费方反而**定位不到**,与这档的用途正好相反。
|
|
123
|
+
|
|
124
|
+
## 遮挡:只有 `locked` 一档拦点击
|
|
125
|
+
|
|
126
|
+
挂 `locked` 的宿主会被**铺一层透明遮罩吃掉点击**,同时打 `tabindex="-1"` +
|
|
127
|
+
`aria-disabled="true"`(移出 Tab 序列,但读屏仍能读到该项并报告为不可用 ——
|
|
128
|
+
「未开通」是要让用户知道存在且可申请的功能,不是要藏起来)。
|
|
129
|
+
|
|
130
|
+
**其余全部 kind 照常可点**,含 `wip`:**开发中 ≠ 不可达** —— 半成品页面让人点进去看是
|
|
131
|
+
正常预期,而未开通是**权限边界**,才必须拦。
|
|
132
|
+
|
|
133
|
+
点击被拦时走 `entry.onTrigger`;未配则出默认提示「请联系平台开通功能」。
|
|
134
|
+
⚠️ `onTrigger` 只在**拦得住**时才有触发点 ⇒ 给 `wip` 配它不会被调用。
|
|
135
|
+
要拦某项就改挂 `locked`,[MUST NOT] 指望用 `onTrigger` 把可点档变成不可点。
|
|
113
136
|
|
|
114
137
|
## 反模式 / 注意
|
|
115
138
|
|
|
@@ -103,7 +103,7 @@ watch(isOutOfSync, (v) => v && refreshList());
|
|
|
103
103
|
| `autoActiveFirst` | `boolean` | 跟随形态 | 列表出数后自动激活第一条。**split 默认 `true`**(宽屏右半屏不该空着)、**sheet 默认 `false`**(窄屏自动弹抽屉是打扰)。⚠️ 详情若有副作用(如「打开即标记已读」)[MUST] 显式关掉 |
|
|
104
104
|
| `queryKey` | `string` | 无 | 传了才把 `activeId` 同步进 URL query(**`replace` 不 `push`**)。复原仍走不变式校验 |
|
|
105
105
|
| `detailApi` | `(params?: { id }) => Promise<R>` | 无 | 传了则内置 `ViewLayout`(零配置拿到内置导航 + `refreshToken` 接线);不传则 `#detail` 原样渲染、门面零请求 |
|
|
106
|
-
| `detailTitle` | `string \| ((detailData, record) => string)` | 无 | 详情区标题。字符串固定 / 函数按数据算:`detailData` = 详情接口数据(**未传 `detailApi` 时恒 `undefined`**)、`record` = 当前项的列表 item(「详情即列表数据」形态靠它出标题)。⚠️
|
|
106
|
+
| `detailTitle` | `string \| ((detailData, record) => string)` | 无 | 详情区标题。字符串固定 / 函数按数据算:`detailData` = 详情接口数据(**未传 `detailApi` 时恒 `undefined`**)、`record` = 当前项的列表 item(「详情即列表数据」形态靠它出标题)。⚠️ **两形态落点不同**(v0.28.0 ⓤⓤ②:标题一律归「最外层容器的标题位」):split 档渲染在**详情区顶部**;sheet 档渲染进**弹层自己的 header**(不再重复出现在正文里)。由此 sheet 档的函数形态**只拿得到 `record`、`detailData` 恒 `undefined`**(详情数据在 `ViewLayout` 内部,弹层壳那层拿不到)——需要详情数据驱动的标题,[MUST] 改在 `#detail` 内自绘。不传则不渲染,业务照旧可在 `#detail` 自绘 |
|
|
107
107
|
| `viewLayoutProps` | `Omit<ViewLayoutProps, "api" \| "params" \| "refreshToken">` | 无 | 透传给内置 `ViewLayout` 的 props——**详情侧的业务操作按钮走这里**:`{ leftExtraButtons: [...] }` 落到 ViewLayout 工具条左侧、与右侧刷新按钮组同一行(`rightExtraButtons` 则置于 `AutoRefreshGroup` 之前)。🔴 `api` / `params` / `refreshToken` 三键被 `Omit`:它们分别由 `detailApi` / `{ id: activeId }` / `activeId` 占位,是「详情跟着当前项走」这条不变式的载体,放开任一个都能让主干**静默失效**(页面看着正常,详情停在上一条)。**未传 `detailApi` 时无内置 ViewLayout,本项无落点** |
|
|
108
108
|
| `sheetLayerType` | `"drawer" \| "modal"` | `"drawer"` | sheet 形态的弹层承载:抽屉 / 居中弹窗。透传 `ModalConfirm.layerType` |
|
|
109
109
|
| `sheetSize` | `string \| number` | `"70%"` | sheet 弹层尺寸(透传 `ModalConfirm.width`):drawer 下是抽屉尺寸、modal 下是弹窗宽度 |
|
|
@@ -75,8 +75,14 @@
|
|
|
75
75
|
「内容的第一行」而非「容器的标题位」——位置与 `ListLayout` 对不齐,主题也无从定向。
|
|
76
76
|
`AppPageDetail` 原先即如此,已归位(见 migrations)。
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
标题本身只给字号 / 字重,[MUST NOT] 自带背景与描边 —— 它坐在 toolbar 这条**分区条**里,
|
|
79
|
+
底色由条统一给。
|
|
80
|
+
|
|
81
|
+
**toolbar 是「条」(bar) 不是「卡」(card)**(甲方 2026-09-16 定性):底色取「面与底的中点」
|
|
82
|
+
(`color-mix(in srgb, --dc-core-surface 50%, --dc-core-ground)`,亮暗自动跟随),
|
|
83
|
+
但守三条纪律 —— **贴边**(零左右呼吸,否则按钮与下方内容区左边界错位,而内容区的面由
|
|
84
|
+
消费方自持、padding 不受本组件控制)· **通栏**(零圆角)· **不加高**(只留既有的 8px 下呼吸)。
|
|
85
|
+
此前「工具条成卡」被否的根因不是「有面」,而是面顺带塞进 12px 内呼吸把 32px 的条撑到 56px。
|
|
80
86
|
|
|
81
87
|
## API
|
|
82
88
|
> ⚠️ API 以 types.ts 与组件源码为真相源;与文档冲突时以源码为准。
|
package/types/bridge/badge.d.ts
CHANGED
|
@@ -53,12 +53,12 @@ export type BadgeEntry = {
|
|
|
53
53
|
/**
|
|
54
54
|
* 被遮挡的标被触发时的回调(点宿主 / 点角标都算触发)。
|
|
55
55
|
*
|
|
56
|
-
* **[MUST] 只有 `
|
|
57
|
-
* 其余 kind
|
|
58
|
-
*
|
|
56
|
+
* **[MUST] 只有 `locked` 一档会调用它**——只有这一档会遮挡宿主交互,
|
|
57
|
+
* 其余 kind(含 `wip`)是纯展示、宿主照常可点,没有"被拦下的那次点击"可供回调。
|
|
58
|
+
* 字段放在共享段(而非收窄进 `locked`)是甲方口径:所有 kind 都可配、非必传。
|
|
59
59
|
*
|
|
60
|
-
* 缺省时由 core 出默认提示(`locked`
|
|
61
|
-
*
|
|
60
|
+
* 缺省时由 core 出默认提示(`locked` →「请联系平台开通功能」)。
|
|
61
|
+
* 要改文案就自己配本回调去弹,core [MUST NOT] 再开覆盖字段。
|
|
62
62
|
*/
|
|
63
63
|
onTrigger?: (entry: BadgeEntry) => void;
|
|
64
64
|
/**
|
|
@@ -72,6 +72,23 @@ export type BadgeEntry = {
|
|
|
72
72
|
* 聚合与数据来源全在 app(同本文件开头的分工)。
|
|
73
73
|
*/
|
|
74
74
|
bizKey?: string;
|
|
75
|
+
/**
|
|
76
|
+
* 本条标的版本号——**core 不消费、纯透传**,供消费方做「版本化的已读记录」。
|
|
77
|
+
*
|
|
78
|
+
* 典型用法(`forge-plugin-guide`):引导弹窗被用户关掉后记一条「看过了」,
|
|
79
|
+
* 进度 key 取 **`key@version`**;不填版本时退化为裸 `key`。
|
|
80
|
+
* ⇒ **功能有实质更新时改一下版本号,引导就会对所有人重新出现一次**,
|
|
81
|
+
* 而不改版本则关过的人永远不再被打扰。
|
|
82
|
+
*
|
|
83
|
+
* [MUST NOT] 拿它做灰度 / 权限判断——它只是「这条标的第几版」,
|
|
84
|
+
* 与 {@link BadgeEntry.expireAt}(时效)、{@link BadgeEntry.bizKey}(业务标识)三者正交。
|
|
85
|
+
*
|
|
86
|
+
* 收 `number` 是刻意的:后端常直接发数字版本,强制消费方转字符串是无谓摩擦;
|
|
87
|
+
* 拼 key 时统一走模板串,`1` 与 `"1"` 拼出同一个 key、无歧义。
|
|
88
|
+
*
|
|
89
|
+
* @example { kind: "new", description: "批量导出…", version: 2 }
|
|
90
|
+
*/
|
|
91
|
+
version?: string | number;
|
|
75
92
|
} & ({
|
|
76
93
|
/** 数字角标 */
|
|
77
94
|
kind: "count";
|
|
@@ -91,6 +108,20 @@ export type BadgeEntry = {
|
|
|
91
108
|
kind: "deprecated";
|
|
92
109
|
} | {
|
|
93
110
|
kind: "locked";
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* **伪标 / 纯锚点**:不渲染任何角标,只在 DOM 上留一个带 key 的挂点,
|
|
114
|
+
* 供 `forge-plugin-guide` 这类消费方**定位**到这个宿主。
|
|
115
|
+
*
|
|
116
|
+
* 用途:想给某个菜单项 / 按钮做新手引导,但它本身**没有**「新 / 更新」之类的标要显示。
|
|
117
|
+
* [MUST NOT] 为此硬挂一个 `new` 标——那会在界面上多出一个用户看不懂的角标。
|
|
118
|
+
*
|
|
119
|
+
* 🔴 它**不进自动串**:guide 的 `badgeKinds` 默认只收资讯档(`new` / `updated`),
|
|
120
|
+
* 本档要由**显式 `steps`** 用 `badgeKey` 引用才会成为一步 —— 这正是它的定位,
|
|
121
|
+
* 「我只提供锚点,跑不跑、什么时候跑由编排决定」。
|
|
122
|
+
*/
|
|
123
|
+
| {
|
|
124
|
+
kind: "anchor";
|
|
94
125
|
} | {
|
|
95
126
|
/** 自定义标:内置五档不够用时才用 */
|
|
96
127
|
kind: "custom";
|
|
@@ -104,8 +135,14 @@ export type BadgeEntry = {
|
|
|
104
135
|
});
|
|
105
136
|
/** 内置标(非 count / custom)的 kind 联合——文案与语义色由 core 统一定,保证跨 app 一致 */
|
|
106
137
|
export type BadgeBuiltinKind = "new" | "updated" | "beta" | "wip" | "deprecated" | "locked";
|
|
107
|
-
/**
|
|
108
|
-
|
|
138
|
+
/**
|
|
139
|
+
* 会遮挡宿主交互的 kind——[MUST] 与 `use-badge-mask` 的判据同源,[MUST NOT] 两处各写一份。
|
|
140
|
+
*
|
|
141
|
+
* 🔴 **只有 `locked` 一档**(甲方 2026-09-16:「我期望只有未开通才点不进去」):
|
|
142
|
+
* `wip`「开发中」**不拦** —— 开发中 ≠ 不可达,半成品页面让人点进去看是正常预期;
|
|
143
|
+
* 未开通是**权限边界**,才必须拦。要拦某项就改挂 `locked`。
|
|
144
|
+
*/
|
|
145
|
+
export declare const BADGE_MASK_KINDS: readonly ["locked"];
|
|
109
146
|
/** bridge 徽标 hook 工厂入参 */
|
|
110
147
|
export interface BridgeBadgeInit {
|
|
111
148
|
/** 初始标记表(如随版本发布的静态 NEW 标);缺省空表 */
|
|
@@ -82,7 +82,14 @@ export declare function computeAppPageSlotStyles(rect: AppPageRectInset, slotSiz
|
|
|
82
82
|
* - **朝内容侧**:间隔改由**默认槽**让出(见 {@link appPageSlotInset}),
|
|
83
83
|
* 槽这边 [MUST] 归零,否则两边各让一份 = 双份。
|
|
84
84
|
*
|
|
85
|
-
* 保留本函数而非删掉挂点:槽内层 shim 仍是布局盒(`left/right`
|
|
86
|
-
*
|
|
85
|
+
* 保留本函数而非删掉挂点:槽内层 shim 仍是布局盒(`left/right` 靠它填满竖轨)。
|
|
86
|
+
*
|
|
87
|
+
* 🔴 **2026-09-16 起改为四边 `8px`**(甲方定):槽拿到自己的背景色与圆角之后,它已经是
|
|
88
|
+
* 一个**有形的块**而非纯占位轨 —— 内容贴着块边缘(还会被圆角切角)不成样子,故给块内呼吸。
|
|
89
|
+
*
|
|
90
|
+
* ⚠️ 这**不构成上文的「双份」**:让位量取槽的**实测尺寸**(`clientWidth/Height` 含 padding),
|
|
91
|
+
* 槽变胖多少默认内容就多让多少 ⇒「槽边缘 ↔ 默认内容」恒为一个外圈档不变,新增的 8px 落在
|
|
92
|
+
* **槽内**(槽边缘 ↔ 槽内内容)。上文「朝内容侧 [MUST] 归零」针对的是旧式做法 ——
|
|
93
|
+
* 那时槽无背景、padding 直接充当间隔,才会与让位叠成双份。
|
|
87
94
|
*/
|
|
88
95
|
export declare function computeAppPageSlotShimStyles(): AppPageSlotStyles;
|