@done-coding/admin-core 0.31.0 → 0.31.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.
Files changed (80) hide show
  1. package/es/bridge/config-hook.mjs +3 -0
  2. package/es/bridge/index.mjs +6 -0
  3. package/es/bridge/theme/index.mjs +11 -3
  4. package/es/components/app-layout/AppBody.vue.mjs +1 -1
  5. package/es/components/app-layout/AppBody.vue2.mjs +2 -2
  6. package/es/components/app-layout/AppPage.vue.mjs +1 -1
  7. package/es/components/app-layout/AppPage.vue2.mjs +175 -33
  8. package/es/components/app-layout/AppPageNavBar.vue.mjs +7 -0
  9. package/es/components/app-layout/AppPageNavBar.vue2.mjs +148 -0
  10. package/es/components/app-layout/app-page-geometry.mjs +3 -2
  11. package/es/components/app-layout/app-page-slot-surface.mjs +31 -0
  12. package/es/components/app-layout/use-app-page-title-field.mjs +41 -0
  13. package/es/components/data-view/DataGridView.vue.mjs +1 -1
  14. package/es/components/data-view/DataGridView.vue2.mjs +2 -1
  15. package/es/components/data-view/DataListView.vue.mjs +1 -1
  16. package/es/components/data-view/DataListView.vue2.mjs +14 -9
  17. package/es/components/data-view/DataListViewItem.vue.mjs +1 -1
  18. package/es/components/data-view/DataListViewItem.vue2.mjs +3 -1
  19. package/es/components/data-view/InfiniteListView.vue.mjs +1 -1
  20. package/es/components/data-view/InfiniteListView.vue2.mjs +25 -18
  21. package/es/components/data-view/use-grid-layout.mjs +13 -15
  22. package/es/components/display/TabsMain.vue.mjs +3 -1
  23. package/es/components/display/use-badge.mjs +10 -3
  24. package/es/components/form/FormItem.vue.mjs +1 -1
  25. package/es/components/form/FormMain.vue.mjs +1 -1
  26. package/es/components/form/FormMain.vue2.mjs +11 -4
  27. package/es/components/form/FormSearch.vue.mjs +1 -1
  28. package/es/components/form/FormSearch.vue2.mjs +12 -4
  29. package/es/components/form/FormSubmitPanel.vue.mjs +1 -1
  30. package/es/components/form/FormSubmitPanel.vue2.mjs +2 -0
  31. package/es/components/form/use-ai-fill.mjs +7 -1
  32. package/es/components/list-layout/ListLayout.vue.mjs +1 -1
  33. package/es/components/list-layout/ListLayout.vue2.mjs +19 -10
  34. package/es/components/modal/ModalConfirm.vue.mjs +1 -1
  35. package/es/components/modal/ModalConfirm.vue2.mjs +28 -5
  36. package/es/components/table/TableToolbar.vue.mjs +1 -1
  37. package/es/components/table/TableToolbar.vue2.mjs +15 -1
  38. package/es/components/view-layout/ViewLayout.vue.mjs +1 -1
  39. package/es/components/view-layout/ViewLayout.vue2.mjs +22 -29
  40. package/es/components/view-layout/ViewLayoutToolbar.vue.mjs +1 -1
  41. package/es/components/view-layout/ViewLayoutToolbar.vue2.mjs +16 -129
  42. package/es/config/slot-region.mjs +1 -0
  43. package/es/hooks/use-surface.mjs +5 -0
  44. package/es/hooks/use-theme-apply.mjs +18 -0
  45. package/es/index.mjs +4 -1
  46. package/es/store/app.mjs +26 -11
  47. package/es/style.css +230 -172
  48. package/package.json +2 -2
  49. package/src/bridge/docs/README.md +19 -3
  50. package/src/components/app-layout/docs/README-AppBody.md +25 -1
  51. package/src/components/app-layout/docs/README-AppHeader.md +1 -1
  52. package/src/components/app-layout/docs/README-AppPage.md +172 -3
  53. package/src/components/data-view/docs/README-DataListView.md +40 -1
  54. package/src/components/data-view/docs/README-InfiniteListView.md +68 -4
  55. package/src/components/display/docs/README-BadgeMark.md +18 -10
  56. package/src/components/form/docs/README-FormMain.md +26 -0
  57. package/src/components/list-layout/docs/README-ListLayout.md +12 -1
  58. package/src/components/menu/README.md +1 -1
  59. package/src/components/modal/docs/README-ModalConfirm.md +57 -0
  60. package/src/components/view-layout/docs/README-ViewLayout.md +46 -129
  61. package/types/bridge/config-hook.d.ts +5 -2
  62. package/types/bridge/index.d.ts +22 -0
  63. package/types/components/app-layout/AppPage.vue.d.ts +43 -1
  64. package/types/components/app-layout/AppPageNavBar.vue.d.ts +48 -0
  65. package/types/components/app-layout/app-page-geometry.d.ts +27 -2
  66. package/types/components/app-layout/app-page-slot-surface.d.ts +18 -0
  67. package/types/components/app-layout/index.d.ts +1 -0
  68. package/types/components/app-layout/types.d.ts +37 -1
  69. package/types/components/app-layout/use-app-page-title-field.d.ts +49 -0
  70. package/types/components/data-view/DataListViewItem.vue.d.ts +7 -0
  71. package/types/components/data-view/types.d.ts +26 -3
  72. package/types/components/data-view/use-grid-layout.d.ts +31 -6
  73. package/types/components/form/types.d.ts +8 -2
  74. package/types/components/list-layout/ListLayout.vue.d.ts +23 -2
  75. package/types/components/list-layout/types.d.ts +7 -0
  76. package/types/components/view-layout/ViewLayout.vue.d.ts +4 -16
  77. package/types/components/view-layout/ViewLayoutToolbar.vue.d.ts +3 -9
  78. package/types/components/view-layout/types.d.ts +11 -50
  79. package/types/config/slot-region.d.ts +17 -1
  80. package/types/injectInfo.json.d.ts +1 -1
@@ -0,0 +1,49 @@
1
+ import { AppPageTitleField } from './types';
2
+ /**
3
+ * `AppPage` 认领句柄的内部面(消费方**够不着**)。
4
+ *
5
+ * 🔴 键走 `Symbol.for(包名 + 键名)`(规则 8 同法):dev 下 `@done-coding/admin-core`
6
+ * 走 dist、core 内部相对路径走源码,是**两个 module instance** ——
7
+ * 裸 `Symbol()` 会造出两个互不相等的符号,`AppPage` 就认领不到消费方建的句柄,
8
+ * 表现为「标题永远不变」且不报错。
9
+ */
10
+ export declare const APP_PAGE_TITLE_FIELD_CLAIM: unique symbol;
11
+ /** 句柄的内部认领面(仅 `AppPage` 使用,[MUST NOT] 写进对外类型) */
12
+ export interface AppPageTitleFieldClaim {
13
+ /** 认领:装上写回口(`AppPage` 的 title model setter) */
14
+ claimWrite: (write: (title: string | undefined) => void) => void;
15
+ /** 认领:把 navbar 标题位元素喂进句柄(供消费方 Teleport) */
16
+ claimBox: (el: HTMLElement | undefined) => void;
17
+ /** 认领后是否已具备写回能力 */
18
+ isClaimed: () => boolean;
19
+ }
20
+ /** 带内部认领面的句柄(`AppPage` 内部断言用) */
21
+ export type AppPageTitleFieldInternal = AppPageTitleField & {
22
+ [APP_PAGE_TITLE_FIELD_CLAIM]?: AppPageTitleFieldClaim;
23
+ };
24
+ /**
25
+ * 页面标题回写的**能力令牌**(`vq3mzn`)。
26
+ *
27
+ * ```vue
28
+ * const titleField = useAppPageTitleField();
29
+ * <AppPage v-model:title="title" show-nav-bar :title-field="titleField">
30
+ * <ViewLayout :title-field="titleField" />
31
+ * </AppPage>
32
+ * ```
33
+ *
34
+ * 🔴 **令牌性 = 不给就够不着**:同一个句柄同时传给页面与子件,两边才接得上。
35
+ * [MUST NOT] 退回 provide/inject 全局通道 —— 那等于「页面里任何后代都能改标题」,
36
+ * 正是本设计要挡的。
37
+ *
38
+ * 🔴 **单句柄,[MUST NOT] 拆成 `secret` + `remoter` 两个**:接线点由 3 降到 2,
39
+ * 同名同值传两处,令牌性不丢,但不会传串、也不用分「给页面的那半 / 给子件的那半」。
40
+ *
41
+ * 🔴 **[MUST NOT] 加「子件必须是 AppPage 直系子元素」这类 DOM 校验**:本仓已两次付过代价
42
+ * (`useContextDefaults` 读直系父 DOM,消费方在插槽里包一层 `<div>` 就断链且静默)。
43
+ * 令牌管的是「谁能改」,DOM 层数管的是另一件事**且管不准** ——
44
+ * 包一层 div 的人并没有越权,他只是写了个 div。
45
+ *
46
+ * ⚠️ 未被任何 `AppPage` 认领时 `changeTitle` 走 **dev 期点名 warn**,
47
+ * [MUST NOT] 改成静默 no-op:「标题没变」这种失败形态本仓已连修四个。
48
+ */
49
+ export declare const useAppPageTitleField: () => AppPageTitleField;
@@ -15,6 +15,13 @@ type __VLS_Props = {
15
15
  masonry?: boolean;
16
16
  /** 瀑布流跨度(`grid-row-end: span N`);未测到时不写,退 CSS 兜底跨度 */
17
17
  spanRows?: number;
18
+ /**
19
+ * **不成网格时的纵向间距**(px → `margin-bottom`),由 DataListView 下发。
20
+ * 🔴 只在「不成网格 **且** 非末项」时有值:成网格的间距归容器的 grid `gap`
21
+ * (叠上去就是双份);末项的 `margin-bottom` 会与父盒底边折叠、**穿透出去**
22
+ * —— 既不计入 `clientHeight` 又推开后邻(`ViewLayout` 栽过同一条)。
23
+ */
24
+ flowGap?: number;
18
25
  };
19
26
  declare function __VLS_template(): {
20
27
  attrs: Partial<{}>;
@@ -77,6 +77,10 @@ export interface DataListViewProps<T extends Record<string, any>, F extends Reco
77
77
  * item 间距(px)。缺省取间距阶梯的**模块档**(`gap.size × 密度 × 1`,默认 8)——
78
78
  * grid 的 gap 是**卡与卡之间**,正是模块档的定义值。
79
79
  * [MUST NOT] 在消费侧写死像素补偿(改 gap 基数 / 换密度档时会脱钩)。
80
+ *
81
+ * 🔴 **与 {@link gridColumns} 正交**(zc6ptn):不成网格时同样有间距 ——
82
+ * 那条路径走每项的 `margin-bottom`(末项不下发),值与成网格时**同一个**。
83
+ * 要贴合传 `0`。
80
84
  */
81
85
  gap?: number;
82
86
  /**
@@ -181,10 +185,22 @@ export interface InfiniteListViewProps<T extends Record<string, any> = Record<st
181
185
  * **项自己已经成卡**(面与面不叠,p4wrtn)。为真时容器**只撤面色、不撤呼吸与圆角** ——
182
186
  * 呼吸计入高度账(与可用高扣减同源),撤了会连带改 refine 的 reserve。
183
187
  *
184
- * 🔴 判据 [MUST NOT] 收窄成「`card === true`」:`InfiniteListView` 没有 `card`
185
- * (卡由消费方自画),那样写会整条漏掉它。
188
+ * 缺省**跟随 {@link card}**(v0.32.0,j8pwer)。
189
+ * ⚠️ 此前缺省恒 `false`,理由是「本组件没有内置卡壳、core 无从判断」——
190
+ * 卡壳补上之后那个理由消失了;不跟着改就会出现「有卡壳 + 容器仍铺面」的面套面。
186
191
  */
187
192
  itemCard?: boolean;
193
+ /**
194
+ * **内置卡壳**(默认 `true`,j8pwer):面 + 圆角 + 1px 边框 + 内呼吸,全走 token,
195
+ * 落在每项外层的 `.infinite-list-view__row` 上。
196
+ *
197
+ * 🔴 取值与另两条卡片路径(`DataListView` / `DataGridView`)**同源**
198
+ * (共享 `card-shell.less` + 同一个 `cardPad`),[MUST NOT] 另写一套。
199
+ *
200
+ * ⚠️ **可见变更**:自画卡片视觉的消费方会多出一层边框 ⇒ 传 `false` 关掉,
201
+ * [MUST NOT] 在自己的卡上再画一层边框叠上去。
202
+ */
203
+ card?: boolean;
188
204
  /** 传入时容器限高滚动(内部 overflowY: auto);数字 = px,字符串 = CSS 长度(如 "100vh") */
189
205
  maxHeight?: number | string;
190
206
  /** opt-in 触摸下拉刷新(默认关) */
@@ -209,7 +225,14 @@ export interface InfiniteListViewProps<T extends Record<string, any> = Record<st
209
225
  estimateSizeAt?: (index: number) => number;
210
226
  /** 多列时的列间距(px,默认 0);纵向间距走 {@link itemGap} */
211
227
  laneGap?: number;
212
- /** 同列相邻项的纵向间距(px,默认 0)——透传 virtual-core 的 `gap` */
228
+ /**
229
+ * 同列相邻项的**纵向间距**(px)——透传 virtual-core 的 `gap`。
230
+ *
231
+ * 缺省取间距阶梯的**模块档**(`APP_LAYOUT_GAP_CONFIG.size × 密度 × 1`,默认 8),
232
+ * 与 `DataListView` 的 `gap` 同一个解析口(`useDataViewGap`):
233
+ * **间距是列表的固有属性,不是某个形态的附属品**(zc6ptn)⇒ 缺省 [MUST NOT] 是 0。
234
+ * 要贴合显式传 `0`。
235
+ */
213
236
  itemGap?: number;
214
237
  }
215
238
  /** InfiniteListView 实例 */
@@ -1,5 +1,35 @@
1
1
  import { ComputedRef, CSSProperties } from 'vue';
2
2
  import { DataViewGridColumns } from './types';
3
+ /** {@link useDataViewGap} 返回 */
4
+ export interface UseDataViewGapReturn {
5
+ /** 生效间距(px):显式 `gap` > 间距阶梯**模块档** */
6
+ gapValue: ComputedRef<number>;
7
+ /**
8
+ * 内置卡壳的内呼吸(px)= 间距阶梯的**呼吸档**(×1.5,默认 12)。
9
+ * 🔴 [MUST NOT] 改读 `--dc-core-content-gap` —— 那是 huhyx7 明令废掉的第二来源,
10
+ * 与 gap 各随不同轴变动,最松密度档会出现「卡内 20 ≥ 外圈 20 > 卡间 8」的乱序。
11
+ * 与 `hooks/use-surface.ts` 同档同源(数据区自持面的内呼吸也是这一档)。
12
+ */
13
+ cardPad: ComputedRef<number>;
14
+ }
15
+ /**
16
+ * item 间距解析 —— **本族三条路径唯一的口**(zc6ptn)。
17
+ *
18
+ * 🔴 **存在的理由 = 让「同源同值」成为构造保证**:`DataListView`(成网格走 grid `gap`、
19
+ * 不成网格走项的 `margin-bottom`)、`InfiniteListView`(`itemGap` 透传虚拟器)、
20
+ * 瀑布流装箱(跨度里的 gap 分量)三处用的必须是**同一个数**。各写一份
21
+ * `gap ?? gapScaleValue(...)` 看着一样,但改口径时必漏一处 ⇒ 抽成函数。
22
+ *
23
+ * 缺省取**模块档**(×1,默认 8)而非历史写死的 12:`gap` 是**卡与卡之间**,
24
+ * 正是模块档的定义;12 是**呼吸档**(卡片内边距)的值,属档位用错。
25
+ * 归位后同时接上 density 缩放(compact/cozy/comfortable ×0.75/×1/×1.5)。
26
+ *
27
+ * ⚠️ [MUST NOT] 为拿这个值去调 {@link useDataViewGridLayout} —— 那会白挂一份
28
+ * `useBreakpoint`(matchMedia 监听),只为一个永不求值的 `gridTemplateColumns`。
29
+ *
30
+ * @param gap 惰性 getter:显式间距(px);`undefined` = 取模块档
31
+ */
32
+ export declare const useDataViewGap: (gap: () => number | undefined) => UseDataViewGapReturn;
3
33
  /** {@link useDataViewGridLayout} 入参(全部惰性 getter,保持响应式) */
4
34
  export interface UseDataViewGridLayoutOptions {
5
35
  /** 列数配置;`undefined` = 不成网格 */
@@ -15,12 +45,7 @@ export interface UseDataViewGridLayoutReturn {
15
45
  gridTemplateColumns: ComputedRef<string | undefined>;
16
46
  /** 网格容器样式;不成网格时 `undefined`(调用方原样透给 `:style`) */
17
47
  gridStyle: ComputedRef<CSSProperties | undefined>;
18
- /**
19
- * 内置卡壳的内呼吸(px)= 间距阶梯的**呼吸档**(×1.5,默认 12)。
20
- * 🔴 [MUST NOT] 改读 `--dc-core-content-gap` —— 那是 huhyx7 明令废掉的第二来源,
21
- * 与 gap 各随不同轴变动,最松密度档会出现「卡内 20 ≥ 外圈 20 > 卡间 8」的乱序。
22
- * 与 `hooks/use-surface.ts` 同档同源(数据区自持面的内呼吸也是这一档)。
23
- */
48
+ /** 内置卡壳的内呼吸(px)= 间距阶梯的**呼吸档**;转发自 {@link UseDataViewGapReturn.cardPad} */
24
49
  cardPad: ComputedRef<number>;
25
50
  }
26
51
  /**
@@ -81,8 +81,14 @@ SV extends PK extends keyof SO ? SO[PK] : PV = PK extends keyof SO ? SO[PK] : PV
81
81
  /** 表单项label */
82
82
  label: string;
83
83
  /**
84
- * 隐藏 label 且不占位(label-wrap 整体 display:none,表单元素顶满整行)。
85
- * 仅当 label 有值时生效——无 label 时 element-plus 会给 content 加 margin-left 留白,需改用 labelWidth:0。
84
+ * 隐藏 label 且不占位(label 整体 `display:none`,表单元素顶满整行)。
85
+ *
86
+ * ⚠️ 仅当 label 有值时生效——无 label 时 element-plus 会给 content 加 margin-left 留白,
87
+ * 需改用 `labelWidth: 0`。
88
+ *
89
+ * 🔴 **v0.32.0 起对「裸 `FormMain`」(未给 `labelWidth`)同样生效**:此前实现只藏
90
+ * `.el-form-item__label-wrap`,而那层 wrap **EP 只在 `label-width: auto` 时才渲染**
91
+ * ⇒ 裸用时类挂上了、规则匹配不到任何元素,**静默失效**(ncl4rj)。
86
92
  */
87
93
  labelHide?: boolean;
88
94
  /** 提示信息 */
@@ -21,6 +21,7 @@ declare const _default: <T extends Record<string, any>, PO extends Record<string
21
21
  activeData?: T | undefined;
22
22
  } & Partial<Pick<import('../form').FormSearchProps<PO, SO, {}>, "staticQuery">> & {
23
23
  title?: string;
24
+ titleField?: import('../app-layout').AppPageTitleField;
24
25
  formSearchProps?: Partial<Omit<import('../form').FormSearchProps<PO, SO, {}>, "staticQuery" | "compact" | "list">> | undefined;
25
26
  } & Pick<import('../table').TableMainProps<T, import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<PO, SO>> & SQ, ListLayoutInnerInjectInfo<PO, F>>, import('./types').TableMainRequiredKey> & Partial<Pick<import('../table').TableMainProps<T, import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<PO, SO>> & SQ, ListLayoutInnerInjectInfo<PO, F>>, import('./types').TableMainOptionsKey>> & {
26
27
  tableMainProps?: Partial<Omit<import('../table').TableMainProps<T, import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<PO, SO>> & SQ, ListLayoutInnerInjectInfo<PO, F>>, import('./types').TableMainOptionsKey | import('./types').TableMainRewriteKey>> | undefined;
@@ -52,7 +53,17 @@ declare const _default: <T extends Record<string, any>, PO extends Record<string
52
53
  attrs: any;
53
54
  slots: Readonly<{
54
55
  /** 头部插槽(无 scope) */
55
- header?: () => VNode[];
56
+ /**
57
+ * 标题行(插槽 > `title` > 不渲染)。
58
+ * **scope 带 `title`**(v0.32.0 补,与 `ViewLayout` 对齐)——插槽接管后仍拿得到原标题,
59
+ * 「加个徽标 / 副标题」这类小改不必把 `title` 再从外面透一遍。
60
+ *
61
+ * ⚠️ 它是**内容区的标题行**,不是页面 chrome。要页面级 navbar(返回 / ⋮ / tabbar)
62
+ * [MUST] 走 `AppPage` 的 `showNavBar` —— **同名不同物**,[MUST NOT] 拿本槽拼。
63
+ */
64
+ header?: (scope: {
65
+ title?: string;
66
+ }) => VNode[];
56
67
  /** 操作区插槽(无 scope) */
57
68
  operation?: () => VNode[];
58
69
  /** 自定义视图项插槽 */
@@ -62,7 +73,17 @@ declare const _default: <T extends Record<string, any>, PO extends Record<string
62
73
  triggerSearch: (() => void) | undefined;
63
74
  }) => VNode[]) | undefined; }> & {
64
75
  /** 头部插槽(无 scope) */
65
- header?: () => VNode[];
76
+ /**
77
+ * 标题行(插槽 > `title` > 不渲染)。
78
+ * **scope 带 `title`**(v0.32.0 补,与 `ViewLayout` 对齐)——插槽接管后仍拿得到原标题,
79
+ * 「加个徽标 / 副标题」这类小改不必把 `title` 再从外面透一遍。
80
+ *
81
+ * ⚠️ 它是**内容区的标题行**,不是页面 chrome。要页面级 navbar(返回 / ⋮ / tabbar)
82
+ * [MUST] 走 `AppPage` 的 `showNavBar` —— **同名不同物**,[MUST NOT] 拿本槽拼。
83
+ */
84
+ header?: (scope: {
85
+ title?: string;
86
+ }) => VNode[];
66
87
  /** 操作区插槽(无 scope) */
67
88
  operation?: () => VNode[];
68
89
  /** 自定义视图项插槽 */
@@ -1,6 +1,7 @@
1
1
  import { ExtractFormStringifyFromObject, ExtractFormStringifyFromList, FormItemConfigList, FormSearchInstance, FormSearchProps, FormSearchSearchType } from '../form';
2
2
  import { TableApiParams, TableApiResult, TableMainInstance, TableMainProps } from '../table';
3
3
  import { SlotLayoutFlowAsideProps } from '../slot-layout';
4
+ import { AppPageTitleField } from '../app-layout';
4
5
  import { DataGridViewProps, GridColumnsConfig, InfiniteListViewConfig } from '../data-view';
5
6
  export type FormSearchOptionsKey = "staticQuery";
6
7
  export type FormSearchRewriteKey = "list";
@@ -28,6 +29,12 @@ F extends Record<string, any>> = Partial<Pick<FormSearchProps<PO, SO, {}>, FormS
28
29
  * 常见场景传 `title` 即可。与 `ViewLayout.title` 同口径 —— 列表页与详情页头部结构对齐。
29
30
  */
30
31
  title?: string;
32
+ /**
33
+ * 页面标题回写的**能力令牌**(`useAppPageTitleField()` 的产物,v0.32.0)。
34
+ * 传了即把本组件的 {@link title} 推给页面级 navbar(与 `ViewLayout` 同口径)。
35
+ * ⚠️ 同一个句柄**只该给一个**子件:一页一个 navbar、一个标题,给两个就是后写的赢。
36
+ */
37
+ titleField?: AppPageTitleField;
31
38
  formSearchProps?: Partial<Omit<FormSearchProps<PO, SO, {}>, FormSearchOptionsKey | FormSearchRewriteKey | "compact">>;
32
39
  } & Pick<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainRequiredKey> & Partial<Pick<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainOptionsKey>> & {
33
40
  tableMainProps?: Partial<Omit<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainOptionsKey | TableMainOptionsKey | TableMainRewriteKey>>;
@@ -18,6 +18,8 @@ declare const _default: <P extends Record<string, any> = Record<string, any>, R
18
18
  header?: (scope: {
19
19
  data: R | undefined;
20
20
  loading: boolean;
21
+ /** 原 `title` prop 值(v0.32.0 补)——插槽接管后仍拿得到,不必再从外面透一遍 */
22
+ title?: string;
21
23
  }) => VNode[];
22
24
  /**
23
25
  * 底部区插槽;不传即完全不渲染([MUST NOT] 留空盒占 reserve)。
@@ -34,14 +36,6 @@ declare const _default: <P extends Record<string, any> = Record<string, any>, R
34
36
  loading: boolean;
35
37
  fetchSeq: number;
36
38
  }) => VNode[];
37
- /**
38
- * `appBar` 形态右侧「更多」位的内容(默认 `MoreFilled` ⋮)。**仅 `appBar` 开启时渲染**。
39
- *
40
- * ⚠️ 点击绑在**外层 `span`** 上 ⇒ 本槽内容 [MUST] 按「哑内容」设计(图标 / 文字)。
41
- * 塞进带点击的组件(如 `ActionBtn`)时其事件会冒泡到外层、与 `onMore` / 菜单**双触发**;
42
- * 要自己接管点击就别传回调,或在槽内 `@click.stop`。
43
- */
44
- more?: () => VNode[];
45
39
  }> & {
46
40
  default: (scope: ViewLayoutScope<R>) => VNode[];
47
41
  /**
@@ -52,6 +46,8 @@ declare const _default: <P extends Record<string, any> = Record<string, any>, R
52
46
  header?: (scope: {
53
47
  data: R | undefined;
54
48
  loading: boolean;
49
+ /** 原 `title` prop 值(v0.32.0 补)——插槽接管后仍拿得到,不必再从外面透一遍 */
50
+ title?: string;
55
51
  }) => VNode[];
56
52
  /**
57
53
  * 底部区插槽;不传即完全不渲染([MUST NOT] 留空盒占 reserve)。
@@ -68,14 +64,6 @@ declare const _default: <P extends Record<string, any> = Record<string, any>, R
68
64
  loading: boolean;
69
65
  fetchSeq: number;
70
66
  }) => VNode[];
71
- /**
72
- * `appBar` 形态右侧「更多」位的内容(默认 `MoreFilled` ⋮)。**仅 `appBar` 开启时渲染**。
73
- *
74
- * ⚠️ 点击绑在**外层 `span`** 上 ⇒ 本槽内容 [MUST] 按「哑内容」设计(图标 / 文字)。
75
- * 塞进带点击的组件(如 `ActionBtn`)时其事件会冒泡到外层、与 `onMore` / 菜单**双触发**;
76
- * 要自己接管点击就别传回调,或在槽内 `@click.stop`。
77
- */
78
- more?: () => VNode[];
79
67
  };
80
68
  emit: (evt: "update:isAutoRefresh", value: boolean) => void;
81
69
  }>) => import('vue').VNode & {
@@ -1,4 +1,4 @@
1
- import { AppPageListDetailNavigationContext, ViewLayoutButtonConfig, ViewLayoutButtonContext, ViewLayoutMoreOption } from './types';
1
+ import { AppPageListDetailNavigationContext, ViewLayoutButtonConfig, ViewLayoutButtonContext } from './types';
2
2
  type __VLS_Props = {
3
3
  /** v-show 判据(父算好传入:有工具条内容或有标题) */
4
4
  visible: boolean;
@@ -20,19 +20,13 @@ type __VLS_Props = {
20
20
  showRefresh: boolean;
21
21
  /** 横向内边距(左右同值,gap 阶梯派生,父算好传入;[MUST NOT] 在本组件重算) */
22
22
  padXPx: string;
23
- /** 移动端 app bar 形态(四项 gate 的总闸) */
24
- appBar?: boolean;
25
- back?: () => void;
26
- moreOptions?: ViewLayoutMoreOption[];
27
- onMoreSelect?: (item: ViewLayoutMoreOption) => void;
28
- onMore?: () => void;
23
+ /** 同组元素之间的间隔 px 串(呼吸档,父算好传入 —— 真相源在父,[MUST NOT] 在此重算) */
24
+ groupGapPx: string;
29
25
  };
30
26
  declare function __VLS_template(): {
31
27
  attrs: Partial<{}>;
32
28
  slots: {
33
29
  header?(_: {}): any;
34
- more?(_: {}): any;
35
- more?(_: {}): any;
36
30
  };
37
31
  refs: {};
38
32
  rootEl: HTMLDivElement;
@@ -1,5 +1,6 @@
1
1
  import { Ref } from 'vue';
2
2
  import { ActionBtnConfigItem } from '../display';
3
+ import { AppPageTitleField } from '../app-layout';
3
4
  /**
4
5
  * 列表 / 详情同页范式的导航上下文(`APP_PAGE_LIST_DETAIL_CONTEXT` 的值形状)。
5
6
  * 在此重声明一份**结构等价**的类型,是为了让 view-layout 族不反向 import inject 桶
@@ -61,15 +62,6 @@ export type ViewLayoutButtonConfig = ActionBtnConfigItem<ViewLayoutButtonContext
61
62
  /**
62
63
  * ViewLayout 展示布局 props
63
64
  */
64
- /**
65
- * `appBar` 形态下右侧「更多」菜单的一项(规则 9:桶内符号带 `ViewLayout` 命名空间前缀)。
66
- */
67
- export interface ViewLayoutMoreOption {
68
- /** 菜单项展示文案 */
69
- label: string;
70
- /** 菜单项值(业务据它分发;回调入参是**整条配置**而非本值) */
71
- value: string | number;
72
- }
73
65
  export interface ViewLayoutProps<P = Record<string, any>, R = any> {
74
66
  /** 数据拉取函数:params 来自 props.params(未传则收 undefined),每次拉取(激活 / 手动刷新 / 自动刷新)传入 */
75
67
  api: (params?: P) => Promise<R>;
@@ -132,50 +124,19 @@ export interface ViewLayoutProps<P = Record<string, any>, R = any> {
132
124
  /** 右侧额外按钮(置于 AutoRefreshGroup 之前) */
133
125
  rightExtraButtons?: ViewLayoutButtonConfig[];
134
126
  /**
135
- * **移动端 app bar 形态**(默认关,opt-in)。
127
+ * 页面标题回写的**能力令牌**(`useAppPageTitleField()` 的产物,v0.32.0)。
136
128
  *
137
- * 开启后 toolbar 变成移动端 header 的样子:去掉左缘 3px 主色条 · 下边缘加投影 ·
138
- * `min-height: 44px`,并**解锁** {@link back} 与右侧「更多」位。
129
+ * 传了即把**本组件正在渲染的标题**({@link title})推给页面级 navbar
130
+ * 「详情页头部」与「页面 navbar」不必各维护一份标题。
139
131
  *
140
- * 🔴 **四项能力全部由本开关 gate**(甲方 2026-09-19:「左侧的 back、右侧的三个点、
141
- * chrome 最小高度 44、无圆角,**都是通过 props 开启移动端模式才有的**」)——
142
- * 不开启时传了 `back` / `moreOptions` 也**不渲染**,高度不加 44 下限。
143
- * [MUST NOT] 实现成「传了就生效」:那在默认形态下只是多出一个按钮、不报错,
144
- * 是最容易漏掉又最难发现的一类偏差。
132
+ * 🔴 它的价值在**够不着内层组件**的场合:`AppPageListDetailLayout` 里的 `ViewLayout`
133
+ * 是门面内部的,消费方只能经 `viewLayoutProps` 传进来。
145
134
  *
146
- * 🔴 **只由消费方显式开启,[MUST NOT] 自动检测**(甲方:「是**开启**,不是检测是移动端」)。
147
- * [MUST NOT] `matchMedia` / UA / 视口宽 / 容器断点自动切 —— 同一套 core 服务多形态应用,
148
- * 「窄就是移动端」不成立(分栏详情 / 侧栏 / 弹窗里都窄),自动切会让消费方在完全
149
- * 没配置的情况下突然换一套 chrome。
135
+ * ⚠️ **标题要从拉到的 `data` 里派生**时 [MUST NOT] 指望本 prop(它转发的是 `title`)——
136
+ * 那种场合直接在插槽里用 scope `data` 自己调 `titleField.changeTitle(...)`,
137
+ * 令牌本就在消费方手里。
150
138
  *
151
- * ⚠️ 命名避开 `header`:本组件**已有 `#header` 插槽**(标题槽),
152
- * 叫 `headerMode` 会让「header 模式」与「#header 槽」在文档与代码里天天打架。
153
- */
154
- appBar?: boolean;
155
- /**
156
- * 返回回调;给了才渲染左侧返回箭头,**且仅 `appBar` 开启时**。
157
- *
158
- * 箭头的点击热区靠外层 padding 撑到 ≥44×44(移动端触控下限),
159
- * [MUST NOT] 只放大图标本身 —— 那只是看着大、点不准。
160
- */
161
- back?: () => void;
162
- /**
163
- * `appBar` 右侧「更多」菜单项;配了(非空)即点击开 `ElDropdown` 菜单。
164
- * **仅 `appBar` 开启时生效**。
165
- */
166
- moreOptions?: ViewLayoutMoreOption[];
167
- /**
168
- * 选中「更多」菜单项。**入参恒是整条 item 配置**(不是 `value`)。
169
- *
170
- * 仅在**配了** {@link moreOptions} 时可能触发;没配菜单时走 {@link onMore}。
171
- * 🔴 两个回调**各自单义、由配置互斥**,[MUST NOT] 合并成「一个回调 + 可选参数」——
172
- * 消费方**静态就知道**自己配没配菜单,可选参数会强迫他处理一个在他那份配置里
173
- * 根本不可能发生的分支,而文档只能靠脚注补救。需要脚注解释的签名通常是该拆了。
174
- */
175
- onMoreSelect?: (item: ViewLayoutMoreOption) => void;
176
- /**
177
- * **没配** {@link moreOptions} 时,点击「更多」位**直接触发**(不出菜单)。
178
- * 仅 `appBar` 开启时生效;与 {@link onMoreSelect} 由配置互斥。
139
+ * ⚠️ 同一个句柄**只该给一个**子件:一页一个 navbar、一个标题,给两个就是后写的赢。
179
140
  */
180
- onMore?: () => void;
141
+ titleField?: AppPageTitleField;
181
142
  }
@@ -35,7 +35,23 @@ export declare enum SlotRegion {
35
35
  * 否则暗色下 overlay `#1d1e1f` 上盖 `#141414` 会出现「弹窗里凹下去一块」
36
36
  * (亮色两者都是 `#fff`,**看不出来** —— [MUST NOT] 只用亮色截图验收)。
37
37
  */
38
- ModalConfirm_Body = 7
38
+ ModalConfirm_Body = 7,
39
+ /**
40
+ * ModalConfirm **抽屉形态**的正文区(drawer 的默认插槽直系父)。
41
+ *
42
+ * 🔴 **与 {@link ModalConfirm_Body} 是两个档,不是一个档的两种写法**:
43
+ * 抽屉正文自 v0.32.0 起取**底色**(k2vnfp)⇒ 它**不再是一块面**
44
+ * ⇒ 后代 [MUST] 自持面(与 modal 正文那档**正好相反**)。
45
+ *
46
+ * ⚠️ 上面那条标记的语义一直是「**你脚下是一块面**」。抽屉正文改成底之后它就不再是
47
+ * 那个意思了 —— 所以是**换一个标**,[MUST NOT] 把那个标的含义反过来
48
+ * (反过来会把 modal 形态一起改掉,而 modal 正文仍是面、那儿的自动关面是对的)。
49
+ *
50
+ * ⚠️ 它同时还被「**refine 默认开**」那一路消费(`ViewLayout` / `TabsMain`)——
51
+ * 抽屉与弹窗**两档都 provide 有界可用高** ⇒ 那一路 [MUST] 把两个档都列上,
52
+ * 漏一个就是「抽屉里的 ViewLayout 掉回自然流」。
53
+ */
54
+ ModalConfirm_DrawerBody = 8
39
55
  }
40
56
  /**
41
57
  * 读 DOM 槽位数字值并守卫:数字读回是字符串,[MUST] 经本函数 `Number()` 强转 + 枚举值校验;
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  "name": "@done-coding/admin-core",
3
- "version": "0.31.0",
3
+ "version": "0.31.1-alpha.0",
4
4
  "description": "内部前端库"
5
5
  };
6
6