@done-coding/admin-core 0.27.0 → 0.27.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 (134) hide show
  1. package/es/bridge/index.mjs +11 -3
  2. package/es/components/app-layout/AppBody.vue.mjs +1 -1
  3. package/es/components/app-layout/AppBody.vue2.mjs +14 -5
  4. package/es/components/app-layout/AppHeader.vue.mjs +1 -1
  5. package/es/components/app-layout/AppHeader.vue2.mjs +7 -5
  6. package/es/components/app-layout/AppLayout.vue.mjs +1 -1
  7. package/es/components/app-layout/AppLayout.vue2.mjs +2 -1
  8. package/es/components/app-layout/AppPage.vue.mjs +1 -1
  9. package/es/components/app-layout/AppPage.vue2.mjs +35 -32
  10. package/es/components/app-layout/app-page-geometry.mjs +16 -16
  11. package/es/components/app-layout/app-page-recommended.mjs +10 -0
  12. package/es/components/data-view/DataGridView.vue.mjs +1 -1
  13. package/es/components/data-view/DataGridView.vue2.mjs +29 -17
  14. package/es/components/data-view/DataListView.vue.mjs +1 -1
  15. package/es/components/data-view/DataListView.vue2.mjs +10 -0
  16. package/es/components/data-view/InfiniteListView.vue.mjs +1 -1
  17. package/es/components/data-view/InfiniteListView.vue2.mjs +9 -3
  18. package/es/components/data-view/use-active-scroll.mjs +15 -0
  19. package/es/components/display/DragFloat.vue.mjs +7 -0
  20. package/es/components/display/DragFloat.vue2.mjs +109 -0
  21. package/es/components/display/TabsHeader.vue.mjs +1 -1
  22. package/es/components/display/TabsHeader.vue2.mjs +9 -10
  23. package/es/components/display/TabsMain.vue.mjs +22 -7
  24. package/es/components/display/tabs-variant.mjs +14 -0
  25. package/es/components/form/FormDivider.vue.mjs +7 -0
  26. package/es/components/form/FormDivider.vue2.mjs +14 -0
  27. package/es/components/form/FormGroupTitle.vue.mjs +7 -0
  28. package/es/components/form/FormGroupTitle.vue2.mjs +59 -0
  29. package/es/components/form/FormItemNestForm.vue.mjs +1 -1
  30. package/es/components/form/FormItemNestFormList.vue.mjs +1 -1
  31. package/es/components/form/FormMain.vue.mjs +1 -1
  32. package/es/components/form/FormMain.vue2.mjs +69 -9
  33. package/es/components/form/FormSearch.vue.mjs +1 -1
  34. package/es/components/form/FormSearch.vue2.mjs +15 -3
  35. package/es/components/form/FormSubmitPanel.vue.mjs +1 -1
  36. package/es/components/form/FormSubmitPanel.vue2.mjs +14 -1
  37. package/es/components/form/ai-schema.mjs +139 -0
  38. package/es/components/form/group.mjs +81 -0
  39. package/es/components/form/use-ai-fill.mjs +71 -0
  40. package/es/components/form/utils.mjs +15 -4
  41. package/es/components/list-layout/ListLayout.vue.mjs +1 -1
  42. package/es/components/list-layout/ListLayout.vue2.mjs +103 -62
  43. package/es/components/modal/ImagePreviewTrigger.vue.mjs +5 -1
  44. package/es/components/modal/ModalConfirm.vue.mjs +1 -1
  45. package/es/components/modal/ModalConfirm.vue2.mjs +8 -5
  46. package/es/components/modal/VideoPreviewTrigger.vue.mjs +1 -1
  47. package/es/components/modal/VideoPreviewTrigger.vue2.mjs +2 -1
  48. package/es/components/page-layout/AppPageDetail.vue.mjs +1 -1
  49. package/es/components/page-layout/AppPageDetail.vue2.mjs +17 -13
  50. package/es/components/page-layout/AppPageListDetailLayout.vue.mjs +7 -4
  51. package/es/components/page-layout/AppPageListDetailSheet.vue.mjs +12 -4
  52. package/es/components/page-layout/AppPageListDetailSplit.vue.mjs +1 -1
  53. package/es/components/page-layout/AppPageListDetailSplit.vue2.mjs +10 -3
  54. package/es/components/table/TableMain.vue.mjs +1 -1
  55. package/es/components/table/TableMain.vue2.mjs +45 -25
  56. package/es/components/view-layout/ViewLayout.vue.mjs +1 -1
  57. package/es/components/view-layout/ViewLayout.vue2.mjs +46 -15
  58. package/es/config/slot-region.mjs +1 -0
  59. package/es/hooks/use-active-record.mjs +5 -1
  60. package/es/hooks/use-surface.mjs +27 -0
  61. package/es/hooks/use-theme-apply.mjs +52 -18
  62. package/es/index.mjs +81 -59
  63. package/es/inject/key.mjs +4 -0
  64. package/es/store/app.mjs +51 -17
  65. package/es/style.css +361 -184
  66. package/es/utils/dom.mjs +7 -1
  67. package/es/utils/gap-scale.mjs +25 -0
  68. package/es/utils/theme-scale.mjs +27 -0
  69. package/package.json +2 -2
  70. package/src/bridge/docs/README.md +30 -0
  71. package/src/components/app-layout/docs/README-AppBody.md +21 -0
  72. package/src/components/app-layout/docs/README-AppPage.md +20 -3
  73. package/src/components/data-view/docs/README-DataGridView.md +15 -0
  74. package/src/components/data-view/docs/README-DataListView.md +13 -0
  75. package/src/components/data-view/docs/README-InfiniteListView.md +15 -0
  76. package/src/components/display/README.md +1 -0
  77. package/src/components/display/docs/README-DragFloat.md +68 -0
  78. package/src/components/form/README.md +4 -2
  79. package/src/components/form/docs/README-FormItemNestForm.md +5 -3
  80. package/src/components/form/docs/README-FormItemNestFormList.md +7 -1
  81. package/src/components/form/docs/README-FormMain.md +102 -1
  82. package/src/components/form/docs/README-FormSearch.md +5 -0
  83. package/src/components/list-layout/docs/README-ListLayout.md +61 -1
  84. package/src/components/modal/docs/README-ImagePreviewTrigger.md +2 -0
  85. package/src/components/modal/docs/README-VideoPreviewTrigger.md +4 -1
  86. package/src/components/page-layout/docs/README-AppPageDetail.md +11 -1
  87. package/src/components/page-layout/docs/README-AppPageListDetailLayout.md +64 -6
  88. package/src/components/table/docs/README-TableMain.md +22 -0
  89. package/src/components/view-layout/docs/README-ViewLayout.md +27 -2
  90. package/src/hooks/docs/README.md +30 -1
  91. package/types/bridge/index.d.ts +69 -10
  92. package/types/components/app-layout/AppPage.vue.d.ts +15 -7
  93. package/types/components/app-layout/app-page-geometry.d.ts +19 -10
  94. package/types/components/app-layout/app-page-recommended.d.ts +12 -0
  95. package/types/components/app-layout/index.d.ts +1 -0
  96. package/types/components/data-view/types.d.ts +18 -0
  97. package/types/components/data-view/use-active-scroll.d.ts +30 -0
  98. package/types/components/display/BadgeMark.vue.d.ts +2 -2
  99. package/types/components/display/DragFloat.vue.d.ts +35 -0
  100. package/types/components/display/TabsHeader.vue.d.ts +7 -0
  101. package/types/components/display/index.d.ts +8 -1
  102. package/types/components/display/tabs-variant.d.ts +17 -0
  103. package/types/components/display/types.d.ts +6 -0
  104. package/types/components/form/FormDivider.vue.d.ts +2 -0
  105. package/types/components/form/FormGroupTitle.vue.d.ts +22 -0
  106. package/types/components/form/FormItemNestForm.vue.d.ts +2 -0
  107. package/types/components/form/ai-schema.d.ts +24 -0
  108. package/types/components/form/group.d.ts +36 -0
  109. package/types/components/form/index.d.ts +2 -0
  110. package/types/components/form/types.d.ts +94 -3
  111. package/types/components/form/use-ai-fill.d.ts +59 -0
  112. package/types/components/form/utils.d.ts +19 -0
  113. package/types/components/list-layout/ListLayout.vue.d.ts +3 -0
  114. package/types/components/list-layout/types.d.ts +28 -0
  115. package/types/components/modal/ModalConfirm.vue.d.ts +1 -1
  116. package/types/components/modal/VideoPreviewTrigger.vue.d.ts +1 -1
  117. package/types/components/page-layout/AppPageDetail.vue.d.ts +2 -2
  118. package/types/components/page-layout/AppPageListDetailLayout.vue.d.ts +3 -7
  119. package/types/components/page-layout/AppPageListDetailSheet.vue.d.ts +4 -8
  120. package/types/components/page-layout/AppPageListDetailSplit.vue.d.ts +4 -8
  121. package/types/components/page-layout/types.d.ts +42 -0
  122. package/types/components/panel/PanelItemNestForm.vue.d.ts +2 -0
  123. package/types/components/table/types.d.ts +9 -0
  124. package/types/components/view-layout/ViewLayout.vue.d.ts +18 -0
  125. package/types/components/view-layout/types.d.ts +15 -0
  126. package/types/config/slot-region.d.ts +10 -1
  127. package/types/hooks/use-surface.d.ts +34 -0
  128. package/types/inject/key.d.ts +10 -0
  129. package/types/injectInfo.json.d.ts +1 -1
  130. package/types/store/app.d.ts +3 -0
  131. package/types/utils/dom.d.ts +31 -0
  132. package/types/utils/gap-scale.d.ts +46 -0
  133. package/types/utils/index.d.ts +1 -0
  134. package/types/utils/theme-scale.d.ts +33 -0
@@ -20,6 +20,7 @@ declare const _default: <T extends Record<string, any>, PO extends Record<string
20
20
  activeId?: ActiveRecordKey | undefined;
21
21
  activeData?: T | undefined;
22
22
  } & Partial<Pick<import('../form').FormSearchProps<PO, SO, {}>, "staticQuery">> & {
23
+ title?: string;
23
24
  formSearchProps?: Partial<Omit<import('../form').FormSearchProps<PO, SO, {}>, "staticQuery" | "compact" | "list">> | undefined;
24
25
  } & 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>> & {
25
26
  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;
@@ -30,6 +31,8 @@ declare const _default: <T extends Record<string, any>, PO extends Record<string
30
31
  injectInfo?: F | undefined;
31
32
  beforeSearch?: ((data: import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<PO, SO>>, type: FormSearchSearchType) => import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<PO, SO>>) | undefined;
32
33
  clearTableFilterOnReset?: boolean;
34
+ gap?: number;
35
+ moduleBg?: boolean | string;
33
36
  initialSearch?: boolean;
34
37
  separateSearch?: boolean;
35
38
  separateSearchConfig?: Pick<import('../slot-layout').SlotLayoutFlowAsideProps, "type" | "gap" | "asideWidth">;
@@ -21,6 +21,13 @@ SO extends Record<string, any>,
21
21
  SQ extends Record<string, any>,
22
22
  /** 期望注入到表格列插槽上的额外内容 */
23
23
  F extends Record<string, any>> = Partial<Pick<FormSearchProps<PO, SO, {}>, FormSearchOptionsKey>> & {
24
+ /**
25
+ * 标题(默认渲染进 `header` 槽位)。
26
+ *
27
+ * 优先级:**`#header` 插槽 > `title` > 不渲染**。插槽是逃生口(复杂头部自行接管),
28
+ * 常见场景传 `title` 即可。与 `ViewLayout.title` 同口径 —— 列表页与详情页头部结构对齐。
29
+ */
30
+ title?: string;
24
31
  formSearchProps?: Partial<Omit<FormSearchProps<PO, SO, {}>, FormSearchOptionsKey | FormSearchRewriteKey | "compact">>;
25
32
  } & Pick<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainRequiredKey> & Partial<Pick<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainOptionsKey>> & {
26
33
  tableMainProps?: Partial<Omit<TableMainProps<T, ExtractFormStringifyFromObject<PO, SO> & SQ, ListLayoutInnerInjectInfo<PO, F>>, TableMainOptionsKey | TableMainOptionsKey | TableMainRewriteKey>>;
@@ -35,6 +42,27 @@ F extends Record<string, any>> = Partial<Pick<FormSearchProps<PO, SO, {}>, FormS
35
42
  beforeSearch?: (data: ExtractFormStringifyFromObject<PO, SO>, type: FormSearchSearchType) => ExtractFormStringifyFromObject<PO, SO>;
36
43
  /** 在点击搜索重置按钮时,是否同时调用清空表格表头过滤 */
37
44
  clearTableFilterOnReset?: boolean;
45
+ /**
46
+ * 模块间距(header / 搜索区 / 操作区各自的**下**间距,px)。
47
+ *
48
+ * 缺省跟随布局 gap 体系 —— 取 `bridge.APP_LAYOUT_GAP_CONFIG.size`(核内默认 8),
49
+ * 改布局 gap 时列表内部间距同步跟随;脱离 `AppLayout` 挂载(取不到 bridge)退 8。
50
+ * 只有该页要与全局不一样时才显式传。
51
+ *
52
+ * 数据区(表格 / 网格)是最后一块,**不带下间距**(下方没有兄弟模块要隔开)。
53
+ */
54
+ gap?: number;
55
+ /**
56
+ * @deprecated `akw76r` 起废弃 —— **三块 chrome 默认成面已覆盖它的用途**,无需再开。
57
+ *
58
+ * 它是**全开关**:一开就给搜索区 / 操作区 / **数据区**四块全上色 + 描边 + 圆角,
59
+ * 与本体系「辅助小块成面、**数据区恒透**」的分配直接冲突(数据区是主内容区,
60
+ * 给它上色会让「哪块是辅助、哪块是正文」的视觉层级塌掉)。
61
+ *
62
+ * 仍可用、行为不变(零 breaking),但 [MUST NOT] 用于新代码;移除走后续 breaking 窗口。
63
+ * 要改 chrome 三块的面色 → 改**主题的 `bodyColor`**(面由它直挂 `--el-bg-color`)。
64
+ */
65
+ moduleBg?: boolean | string;
38
66
  /**
39
67
  * 挂载后是否立即触发初始化查询(默认 true 查)。
40
68
  * - false:进入页面不自动拉数——表格空态显示「欢迎触发查询」(TableMain 经 hasRequested
@@ -93,8 +93,8 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
93
93
  "onUpdate:show"?: ((value: boolean) => any) | undefined;
94
94
  }>, {
95
95
  reverse: boolean;
96
+ type: "" | "default" | "text" | "primary" | "success" | "warning" | "info" | "danger";
96
97
  width: number | string;
97
- type: "" | "text" | "default" | "primary" | "success" | "warning" | "info" | "danger";
98
98
  direction: "rtl" | "ltr" | "ttb" | "btt";
99
99
  showClose: boolean;
100
100
  cancelText: string | (() => VNode);
@@ -23,7 +23,7 @@ declare function __VLS_template(): {
23
23
  attrs: Partial<{}>;
24
24
  slots: {
25
25
  default?(_: {
26
- open: () => void;
26
+ open: (event?: Event) => void;
27
27
  }): any;
28
28
  placeholder?(_: {}): any;
29
29
  error?(_: {}): any;
@@ -1,12 +1,12 @@
1
1
  import { ActiveRecordKey } from '../../hooks/use-active-record';
2
- import { AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailProps } from './types';
2
+ import { AppPageListDetailCtx, AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailProps } from './types';
3
3
  declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, never> & {
5
5
  /**
6
6
  * 完整详情上下文(含序列导航句柄)。**门面内嵌时下发**;
7
7
  * 独立使用时不传,改用下方 `id` / `record`。
8
8
  */
9
- ctx?: Omit<AppPageListDetailDetailScope<T, R>, "data" | "loading">;
9
+ ctx?: AppPageListDetailCtx<T, R>;
10
10
  /** 独立使用时的当前项键(`ctx` 未传时生效;与 `ctx` 都无 → 落空态) */
11
11
  id?: ActiveRecordKey;
12
12
  /** 独立使用时的当前项数据(`ctx` 未传时生效),供 `detailTitle` / `#detail` 消费 */
@@ -1,5 +1,5 @@
1
1
  import { ActiveRecordKey } from '../../hooks/use-active-record';
2
- import { AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListProps, AppPageListDetailProps } from './types';
2
+ import { AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListScope, AppPageListDetailProps } from './types';
3
3
  declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
5
5
  readonly "onUpdate:activeId"?: ((value: ActiveRecordKey | undefined) => any) | undefined;
@@ -11,18 +11,14 @@ declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: No
11
11
  expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
12
12
  attrs: any;
13
13
  slots: Readonly<{
14
- list?: (scope: {
15
- listProps: AppPageListDetailListProps<T>;
16
- }) => unknown;
14
+ list?: (scope: AppPageListDetailListScope<T>) => unknown;
17
15
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
18
16
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
19
17
  top?: () => unknown;
20
18
  bottom?: () => unknown;
21
19
  right?: () => unknown;
22
20
  }> & {
23
- list?: (scope: {
24
- listProps: AppPageListDetailListProps<T>;
25
- }) => unknown;
21
+ list?: (scope: AppPageListDetailListScope<T>) => unknown;
26
22
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
27
23
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
28
24
  top?: () => unknown;
@@ -1,10 +1,10 @@
1
- import { AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListProps, AppPageListDetailProps } from './types';
1
+ import { AppPageListDetailCtx, AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListProps, AppPageListDetailListScope, AppPageListDetailProps } from './types';
2
2
  declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
3
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
4
4
  readonly onClose?: (() => any) | undefined;
5
5
  } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onClose"> & {
6
6
  listProps: AppPageListDetailListProps<T>;
7
- ctx: Omit<AppPageListDetailDetailScope<T, R>, "data" | "loading">;
7
+ ctx: AppPageListDetailCtx<T, R>;
8
8
  listEmpty: boolean;
9
9
  sheetLayerType: "drawer" | "modal";
10
10
  sheetSize: string | number;
@@ -17,18 +17,14 @@ declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: No
17
17
  expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
18
18
  attrs: any;
19
19
  slots: Readonly<{
20
- list?: (scope: {
21
- listProps: AppPageListDetailListProps<T>;
22
- }) => unknown;
20
+ list?: (scope: Omit<AppPageListDetailListScope<T>, "resolvedMode">) => unknown;
23
21
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
24
22
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
25
23
  top?: () => unknown;
26
24
  bottom?: () => unknown;
27
25
  right?: () => unknown;
28
26
  }> & {
29
- list?: (scope: {
30
- listProps: AppPageListDetailListProps<T>;
31
- }) => unknown;
27
+ list?: (scope: Omit<AppPageListDetailListScope<T>, "resolvedMode">) => unknown;
32
28
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
33
29
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
34
30
  top?: () => unknown;
@@ -1,8 +1,8 @@
1
- import { AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListProps, AppPageListDetailProps } from './types';
1
+ import { AppPageListDetailCtx, AppPageListDetailDetailScope, AppPageListDetailEmptyScope, AppPageListDetailListProps, AppPageListDetailListScope, AppPageListDetailProps } from './types';
2
2
  declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
3
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, never> & {
4
4
  listProps: AppPageListDetailListProps<T>;
5
- ctx: Omit<AppPageListDetailDetailScope<T, R>, "data" | "loading">;
5
+ ctx: AppPageListDetailCtx<T, R>;
6
6
  listEmpty: boolean;
7
7
  listWidth: string;
8
8
  /**
@@ -20,18 +20,14 @@ declare const _default: <T extends Record<string, any>, R = any>(__VLS_props: No
20
20
  expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
21
21
  attrs: any;
22
22
  slots: Readonly<{
23
- list?: (scope: {
24
- listProps: AppPageListDetailListProps<T>;
25
- }) => unknown;
23
+ list?: (scope: Omit<AppPageListDetailListScope<T>, "resolvedMode">) => unknown;
26
24
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
27
25
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
28
26
  top?: () => unknown;
29
27
  bottom?: () => unknown;
30
28
  right?: () => unknown;
31
29
  }> & {
32
- list?: (scope: {
33
- listProps: AppPageListDetailListProps<T>;
34
- }) => unknown;
30
+ list?: (scope: Omit<AppPageListDetailListScope<T>, "resolvedMode">) => unknown;
35
31
  detail?: (scope: AppPageListDetailDetailScope<T, R>) => unknown;
36
32
  empty?: (scope: AppPageListDetailEmptyScope) => unknown;
37
33
  top?: () => unknown;
@@ -1,8 +1,17 @@
1
+ import { AppPageListLayoutRecommended } from '../app-layout';
1
2
  import { ViewLayoutProps } from '../view-layout';
2
3
  import { ActiveRecordKey } from '../../hooks/use-active-record';
3
4
  import { NoInferType } from '../../types';
4
5
  /** 形态:`auto` 按视口宽定档(默认)|`split` 强制宽屏并排|`sheet` 强制窄屏抽屉 */
5
6
  export type AppPageListDetailMode = "auto" | "split" | "sheet";
7
+ /**
8
+ * **实际**档位(`mode` 入参解析后的结果)——`auto` 档下才有悬念,强制档恒等于入参。
9
+ *
10
+ * 与入参 `mode` 刻意不同名:`mode` 回答「我要什么」,本值回答「现在是什么」。
11
+ * 三个插槽 scope 都以 `resolvedMode` 下发,消费方 [MUST NOT] 自己再判一次视口宽
12
+ * (与门面的 `splitAt` 形成两个事实源,调用方改阈值时静默不一致)。
13
+ */
14
+ export type AppPageListDetailResolvedMode = "split" | "sheet";
6
15
  /**
7
16
  * `#list` 插槽 scope 携带的「列表接线包」——业务 [MUST] 整体 `v-bind` 到列表组件上:
8
17
  *
@@ -43,11 +52,44 @@ export interface AppPageListDetailDetailScope<T = any, R = any> {
43
52
  data: R | undefined;
44
53
  /** 详情接口拉取中(未传 `detailApi` 时恒为 false) */
45
54
  loading: boolean;
55
+ /**
56
+ * 详情接口**成功**拉取次数(未传 `detailApi` 时恒 0)。详情里的懒加载下游块 `watch` 它即可
57
+ * 选择性重拉,无需把下游数据一起聚进 `detailApi`(那会把没打开的 tab 也拉了)。
58
+ *
59
+ * 🔴 失败不递增。[MUST NOT] 用 `loading` 的 `true→false` 代替,也 [MUST NOT] watch `data` 的对象身份。
60
+ */
61
+ fetchSeq: number;
62
+ /**
63
+ * 当前**实际**档位。**仅门面下发**;`AppPageDetail` 独立成页时为 `undefined`(无形态概念)。
64
+ */
65
+ resolvedMode?: AppPageListDetailResolvedMode;
66
+ }
67
+ /**
68
+ * 门面下发给形态件 / 详情区的上下文 = 详情 scope 去掉「由详情容器现场补齐」的三键
69
+ * (`data` / `loading` / `fetchSeq` 来自内置 `ViewLayout` 的插槽作用域,setup 里取不到)
70
+ * 与「由门面自己补的」`resolvedMode`。
71
+ */
72
+ export type AppPageListDetailCtx<T = any, R = any> = Omit<AppPageListDetailDetailScope<T, R>, "data" | "loading" | "fetchSeq" | "resolvedMode">;
73
+ /**
74
+ * `#list` 插槽 scope。
75
+ *
76
+ * `listLayoutRecommended` 是 `AppPage#left` 的窄栏推荐配置(split 档才有值)——它与
77
+ * `useContextDefaults` 的窄栏上下文默认**同源**(`APP_PAGE_LIST_LAYOUT_RECOMMENDED`),
78
+ * 是消费方在 `#list` 里包了包裹层、隐式上下文断链时的显式出路。
79
+ */
80
+ export interface AppPageListDetailListScope<T = any> {
81
+ listProps: AppPageListDetailListProps<T>;
82
+ /** 窄栏推荐配置;**sheet 档为 `undefined`**(列表在默认槽,不是窄栏) */
83
+ listLayoutRecommended: AppPageListLayoutRecommended | undefined;
84
+ /** 当前**实际**档位 */
85
+ resolvedMode: AppPageListDetailResolvedMode;
46
86
  }
47
87
  /** `#empty` 插槽 scope */
48
88
  export interface AppPageListDetailEmptyScope {
49
89
  /** true = 列表本身无数据;false = 有数据但未选中。两种空态文案不同,由业务分流 */
50
90
  listEmpty: boolean;
91
+ /** 当前**实际**档位(仅门面下发;`AppPageDetail` 独立成页时 `undefined`) */
92
+ resolvedMode?: AppPageListDetailResolvedMode;
51
93
  }
52
94
  /**
53
95
  * 透传给内置 `ViewLayout` 的 props(`detailApi` 传了才有内置 ViewLayout,不传则本项无落点)。
@@ -30,6 +30,8 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
30
30
  generate: () => Record<string, any>;
31
31
  parse: (stringifyData: import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>) => Record<string, any>;
32
32
  stringify: () => import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>;
33
+ getAiSchema: () => Promise<import('../form').FormAiSchema>;
34
+ setValues: (partial: Partial<Record<string, any>>) => void;
33
35
  } | null;
34
36
  }, any>;
35
37
  export default _default;
@@ -191,6 +191,15 @@ T extends Record<string, any>,
191
191
  SQ extends Record<string, any>,
192
192
  /** 期望注入到表格列插槽上的额外内容 */
193
193
  F extends Record<string, any>> {
194
+ /**
195
+ * 自持面(默认 `true`):面色 + 内呼吸 + 圆角,单独用也观感一致。
196
+ *
197
+ * 🔴 开启时自身 padding **计入数据区可用高**——样式与高度账在同一组件内闭环,
198
+ * [MUST NOT] 退回「外层经 `:deep()` 刷面、内层算高」(两边各管一半必漏)。
199
+ * 置于 `ModalConfirm` 正文时经上下文自动取 `false`(那儿已是一块面,
200
+ * 暗色下二次成面会凹);显式传值恒优先。
201
+ */
202
+ surface?: boolean;
194
203
  /** 展示分页器 */
195
204
  showPager?: boolean;
196
205
  /**
@@ -10,8 +10,26 @@ declare const _default: <P extends Record<string, any> = Record<string, any>, R
10
10
  attrs: any;
11
11
  slots: Readonly<{
12
12
  default: (scope: ViewLayoutScope<R>) => VNode[];
13
+ /**
14
+ * 标题行插槽;传了即接管,`title` prop 不再渲染。
15
+ * 带 `data` / `loading` scope —— 标题常要跟着详情数据走(如 `{{ data?.name }}`),
16
+ * 而 `data` 在 setup 里取不到(它是本组件拉取的结果),故 [MUST] 由插槽 scope 下发。
17
+ */
18
+ header?: (scope: {
19
+ data: R | undefined;
20
+ loading: boolean;
21
+ }) => VNode[];
13
22
  }> & {
14
23
  default: (scope: ViewLayoutScope<R>) => VNode[];
24
+ /**
25
+ * 标题行插槽;传了即接管,`title` prop 不再渲染。
26
+ * 带 `data` / `loading` scope —— 标题常要跟着详情数据走(如 `{{ data?.name }}`),
27
+ * 而 `data` 在 setup 里取不到(它是本组件拉取的结果),故 [MUST] 由插槽 scope 下发。
28
+ */
29
+ header?: (scope: {
30
+ data: R | undefined;
31
+ loading: boolean;
32
+ }) => VNode[];
15
33
  };
16
34
  emit: (evt: "update:isAutoRefresh", value: boolean) => void;
17
35
  }>) => import('vue').VNode & {
@@ -26,6 +26,13 @@ export interface ViewLayoutScope<R = any> {
26
26
  refresh: () => Promise<void>;
27
27
  /** 内容区可用高度(refine 时 = 视口高 − toolbar reserve,超高内滚的 max-height 预算);自然流 undefined */
28
28
  viewportHeight: number | undefined;
29
+ /**
30
+ * **成功**拉取计数(单调递增,首拉成功即 1)。供下游懒加载块判「详情整体刷新了、我该重拉」。
31
+ *
32
+ * 🔴 失败**不**递增——故 [MUST NOT] 用 `loading` 的 `true→false` 代替(失败也会落回 false,
33
+ * 下游会基于旧数据白拉一次);也 [MUST NOT] watch `data` 的对象身份(「每次新引用」从不是承诺)。
34
+ */
35
+ fetchSeq: number;
29
36
  }
30
37
  /**
31
38
  * ViewLayout toolbar 按钮渲染上下文(对齐 TableToolbar 惯例,但只含展示布局句柄——不含表格能力)
@@ -84,6 +91,14 @@ export interface ViewLayoutProps<P = Record<string, any>, R = any> {
84
91
  showAutoRefresh?: boolean;
85
92
  /** 是否显示手动刷新按钮(默认 true) */
86
93
  showRefresh?: boolean;
94
+ /**
95
+ * 标题(渲染进 `#header` 行,位于操作条之上——与 `ListLayout` 的 header 槽结构对齐)。
96
+ *
97
+ * 优先级:**`#header` 插槽 > `title` > 不渲染**。插槽是逃生口,常见场景传 `title` 即可。
98
+ * 🔴 [MUST NOT] 把标题塞进内容插槽自画 —— 那样它成了「内容的第一行」而非
99
+ * 「容器的标题位」,主题 persona 也无从定向(`AppPageDetail` 原先即如此,已归位)。
100
+ */
101
+ title?: string;
87
102
  /**
88
103
  * 是否显示内置「上一条 / 下一条」导航(默认 true)。
89
104
  * ⚠️ **真正的显隐判据是可选 inject 探测**:只有置于 `AppPageListDetailLayout` 内
@@ -26,7 +26,16 @@ export declare enum SlotRegion {
26
26
  /** AppPage left 槽(侧向悬浮区) */
27
27
  AppPage_Left = 5,
28
28
  /** TabsMain 页签内容(tab item) */
29
- TabsMain_Item = 6
29
+ TabsMain_Item = 6,
30
+ /**
31
+ * ModalConfirm 正文区(弹窗 / 抽屉的默认插槽直系父)。
32
+ *
33
+ * 用途:告诉后代「**你已经站在一块面上了**」—— 弹窗正文的底是
34
+ * `--el-bg-color-overlay`(抬升面),后代 [MUST NOT] 再刷一层面色,
35
+ * 否则暗色下 overlay `#1d1e1f` 上盖 `#141414` 会出现「弹窗里凹下去一块」
36
+ * (亮色两者都是 `#fff`,**看不出来** —— [MUST NOT] 只用亮色截图验收)。
37
+ */
38
+ ModalConfirm_Body = 7
30
39
  }
31
40
  /**
32
41
  * 读 DOM 槽位数字值并守卫:数字读回是字符串,[MUST] 经本函数 `Number()` 强转 + 枚举值校验;
@@ -0,0 +1,34 @@
1
+ import { ComputedRef } from 'vue';
2
+ /** {@link useSurface} 返回值 */
3
+ export interface UseSurfaceReturn {
4
+ /** 最终是否成面(显式 prop > 上下文推导 > 默认 true) */
5
+ surfaceActive: ComputedRef<boolean>;
6
+ /** 卡内呼吸数值(px);关面时 0。样式与高度账**共用此一处** */
7
+ surfacePad: ComputedRef<number>;
8
+ /** 呼吸的 px 串(供 scoped CSS `v-bind`),与 {@link UseSurfaceReturn.surfacePad} 同源 */
9
+ surfacePadCss: ComputedRef<string>;
10
+ }
11
+ /**
12
+ * 数据区组件的「自持面」——面色 + 内呼吸 + 圆角由组件**自己**持有。
13
+ *
14
+ * 🔴 **存在的理由 = 让样式与高度账在同一个组件内闭环**:内呼吸既用于渲染,
15
+ * 又要从数据区可用高里扣掉。此前 padding 由 `ListLayout` 经 `:deep()` 从外面刷、
16
+ * 可用高在 `TableMain` 里算,两个组件各管一半 ⇒ 每页恒漏一个 padding
17
+ * (甲方 2026-09-15 报障)。**[MUST NOT] 退回「外层刷面、内层算高」。**
18
+ *
19
+ * 用法:消费组件 [MUST] 把 `surfacePad` 计入自己的可用高扣减,
20
+ * 并把 `surfacePadCss` 经 `v-bind` 喂给 padding —— 两者同源,[MUST NOT] 各写各的。
21
+ *
22
+ * 弹窗正文(`SlotRegion.ModalConfirm_Body`)已经是一块面,经既有
23
+ * `useContextDefaults` + `data-dc-slot` 自动关闭,[MUST NOT] 新造 inject key。
24
+ * ⚠️ 只读**直系父** DOM:弹窗正文里隔了容器(如包着 `ListLayout`)就推导不到,
25
+ * 此时由使用方显式传 `surface={false}`。[MUST NOT] 改成向上遍历——那会让
26
+ * 「直系父」这条简单规则失效。
27
+ *
28
+ * 内部件:仅供 table / data-view 族复用,[MUST NOT] 桶导出进公共 API 面。
29
+ *
30
+ * @param getProps 惰性 getter,读 `props` 保持响应式(含可选 `surface`)
31
+ */
32
+ export declare const useSurface: <P extends {
33
+ surface?: boolean;
34
+ }>(getProps: () => P) => UseSurfaceReturn;
@@ -174,6 +174,16 @@ export declare const APP_LAYOUT_BRIDGE_KEY: InjectionKey<AppLayoutBridgeSlice>;
174
174
  * Symbol.for 保证跨包/跨 chunk/跨 ESM 实例唯一(同 APP_LAYOUT_BRIDGE_KEY,规则 8)。
175
175
  */
176
176
  export declare const CORE_BRIDGE_KEY: InjectionKey<CoreBridge>;
177
+ /**
178
+ * FormMain 本轮校验的**错误字段 key 列表** inject key。
179
+ *
180
+ * 用途:折叠分组(`swiftFormItemGroup`)的标题组件据此判断「错误是否落在本组」,
181
+ * 命中则**自动展开 + 滚动到错误项** —— 折叠 ≠ 隐藏,折叠区照常校验,
182
+ * 但 [MUST NOT] 让使用者面对「看不见错在哪、却提交不了」。
183
+ *
184
+ * 由 `FormMain` provide(每次 `validate()` 结算时写入,成功写空数组)。
185
+ */
186
+ export declare const FORM_VALIDATE_ERROR_KEYS: InjectionKey<Readonly<Ref<string[]>>>;
177
187
  /**
178
188
  * 嵌套子 FormMain exposeMap inject key(配置化嵌套联结组件 Nest 三件套挂载)。
179
189
  * ---
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  "name": "@done-coding/admin-core",
3
- "version": "0.27.0",
3
+ "version": "0.27.1-alpha.0",
4
4
  "description": "内部前端库"
5
5
  };
6
6
 
@@ -51,6 +51,7 @@ export declare function createAppStore<UserInfo = unknown, LoginParams = unknown
51
51
  readonly blur?: string | undefined;
52
52
  readonly focusRing?: string | undefined;
53
53
  readonly surface?: string | undefined;
54
+ readonly ground?: string | undefined;
54
55
  }>;
55
56
  showHeader: import('vue').ComputedRef<boolean>;
56
57
  showFooter: import('vue').ComputedRef<boolean>;
@@ -111,6 +112,7 @@ export declare function createAppStore<UserInfo = unknown, LoginParams = unknown
111
112
  readonly blur?: string | undefined;
112
113
  readonly focusRing?: string | undefined;
113
114
  readonly surface?: string | undefined;
115
+ readonly ground?: string | undefined;
114
116
  }>;
115
117
  showHeader: import('vue').ComputedRef<boolean>;
116
118
  showFooter: import('vue').ComputedRef<boolean>;
@@ -171,6 +173,7 @@ export declare function createAppStore<UserInfo = unknown, LoginParams = unknown
171
173
  readonly blur?: string | undefined;
172
174
  readonly focusRing?: string | undefined;
173
175
  readonly surface?: string | undefined;
176
+ readonly ground?: string | undefined;
174
177
  }>;
175
178
  showHeader: import('vue').ComputedRef<boolean>;
176
179
  showFooter: import('vue').ComputedRef<boolean>;
@@ -22,3 +22,34 @@ export declare function domClosestScrollableAncestor(el: HTMLElement | null | un
22
22
  * 而 CSS 仍以该容器为 scrollport → 粘住顶距错位(弹窗内实测踩坑)。
23
23
  */
24
24
  export declare function domClosestStickyScrollport(el: HTMLElement | null | undefined): HTMLElement | undefined;
25
+ /** {@link domScrollIntoViewport} 选项 */
26
+ export interface DomScrollIntoViewportOptions {
27
+ /**
28
+ * 滚动行为。**默认 `"auto"`(瞬时)**,[MUST NOT] 改默认为 `"smooth"`。
29
+ *
30
+ * 本仓踩过:`TabsTile` 自研 smooth 滚动被 **v-model 回流重渲染打断**
31
+ * (watcher 里异步读 y 恒 0,真机复现),最终弃用改走 `ElAnchor`。
32
+ * 「列表项聚焦跟随」属跟随而非导航,瞬时定位反而稳;要动效由调用方显式传。
33
+ */
34
+ behavior?: ScrollBehavior;
35
+ /** 纵向对齐,默认 `"nearest"`(见函数注释) */
36
+ block?: ScrollLogicalPosition;
37
+ /** 横向对齐,默认 `"nearest"` */
38
+ inline?: ScrollLogicalPosition;
39
+ }
40
+ /**
41
+ * 把目标元素滚进**最近的滚动视口**(薄封装 `Element.scrollIntoView`)。
42
+ *
43
+ * 🔴 **默认 `block/inline: "nearest"`**,这是本函数存在的理由:
44
+ * - 原生默认 `"start"` 会「**越级滚动**」—— 子元素调用却把整个 `body` 滚了
45
+ * (本仓 `AppHeader` 曾是裸 `scrollIntoView({behavior:"smooth"})`,即此写法);
46
+ * - `"nearest"` 同时意味着**已在视口内则零动作**,天生具备
47
+ * `scrollIntoViewIfNeeded`(非标准 API)的语义,无需引库。
48
+ *
49
+ * `target` 允许 `null | undefined`(调用方常从 ref / `querySelector` 取),静默返回。
50
+ * SSR / 无 DOM 环境同样静默。
51
+ *
52
+ * [MUST NOT] 为此引 `scroll-into-view-if-needed`(~3KB):它的价值在多层嵌套容器 +
53
+ * 自定义边距,当前用不到;本函数 API 形状与之对齐,真需要时可平替。
54
+ */
55
+ export declare function domScrollIntoViewport(target: Element | null | undefined, options?: DomScrollIntoViewportOptions): void;
@@ -0,0 +1,46 @@
1
+ import { CoreThemeDensity } from '../bridge';
2
+ /**
3
+ * 间距阶梯:**一个基数派生四档**(huhyx7)。
4
+ *
5
+ * 基数 = `bridge.APP_LAYOUT_GAP_CONFIG.size`(默认 8)。四档按**语义**取倍率,
6
+ * [MUST NOT] 处处取同值 —— 全等会让「页面级分隔」与「卡内分段」一样重、层级读不出来。
7
+ *
8
+ * ```
9
+ * 外圈 ×2 内容 ↔ chrome / viewport 边 / 悬浮插槽 ↔ 默认内容
10
+ * 呼吸 ×1.5 卡片内边距
11
+ * 模块 ×1 chrome 模块彼此、卡 ↔ 卡
12
+ * 分段 ×0.5 同一张卡内的段与段
13
+ * ```
14
+ *
15
+ * 🔴 **倍率是实现细节不是配置项**:[MUST NOT] 为此新开 `innerGap` / `outerGap` 之类的
16
+ * bridge 字段 —— 那会退回多旋钮,而单旋钮正是本阶梯的全部价值。
17
+ *
18
+ * 基数取 8 的依据:4px 基准网格 ×2 —— Material 8dp grid / AntD 8 的倍数 /
19
+ * Tailwind `spacing-2` 同档,且**它已在用**,基线不动。
20
+ */
21
+ export declare const GAP_SCALE_RUNG: {
22
+ /** 外圈:内容 ↔ chrome、内容 ↔ viewport 边、悬浮插槽 ↔ 默认内容 */
23
+ readonly outer: 2;
24
+ /** 卡片内边距(呼吸) */
25
+ readonly breath: 1.5;
26
+ /** 模块 / 卡之间 */
27
+ readonly module: 1;
28
+ /** 同一张卡内的分段 */
29
+ readonly section: 0.5;
30
+ };
31
+ /** 间距档位名 */
32
+ export type GapScaleRung = keyof typeof GAP_SCALE_RUNG;
33
+ /**
34
+ * 按密度档缩放间距基数(四舍五入到整 px —— 半像素会让相邻块出现 1px 缝隙差)。
35
+ *
36
+ * 默认 `cozy` ⇒ 原样返回。非法 / 缺省密度档退 `cozy`(不崩、不静默变形)。
37
+ */
38
+ export declare const gapScaleBase: (size: number, density?: CoreThemeDensity) => number;
39
+ /**
40
+ * 取某一档的间距值(px 数值)。
41
+ *
42
+ * @param size 基数(`APP_LAYOUT_GAP_CONFIG.size`)
43
+ * @param rung 档位
44
+ * @param density 密度档(缺省 `cozy`)
45
+ */
46
+ export declare const gapScaleValue: (size: number, rung: GapScaleRung, density?: CoreThemeDensity) => number;
@@ -4,3 +4,4 @@ export * from './dom';
4
4
  export * from './router';
5
5
  export * from './export';
6
6
  export * from './theme-scale';
7
+ export * from './gap-scale';
@@ -34,6 +34,29 @@ export declare const themeScaleMix: (c1: string, c2: string, w1: number) => stri
34
34
  * 非 hex 入参(`var(...)` / `rgba(...)`)→ 原样返回(不崩、不强转)。
35
35
  */
36
36
  export declare const themeScaleToRgba: (hex: string, alpha: number) => string;
37
+ /**
38
+ * 布局底(page 档)派生:bodyColor(面)向黑压一步,混黑权重
39
+ * `k = min(0.5, 18/maxCh)`——最亮通道恒降 ≈18(暗色 `#141414` 命中 REL 上限 0.5
40
+ * 恰为 EP 暗 page `#0a0a0a`;亮色 `#fff` 得 `#ededed`,比 EP/AntD 的 `#f5f5f5` 深一档,
41
+ * 见 {@link PAGE_STEP_CH} 的取值理由)。
42
+ * 公式与明暗无关(对当前模式的 bodyColor 直接适用)。
43
+ * 非 hex(var/rgba/渐变)→ 原样返回(调用方按原值直用,行为不变)。
44
+ *
45
+ * ⚠️ **两个已知退化点**(实际色差 `Δ = min(0.5×maxCh, 18)`):
46
+ * - `maxCh` 太小(近黑)→ Δ 塌向 0(`#000` 得 Δ=0、底 = 面)⇒ 由 {@link themeScaleIsNearBlack}
47
+ * 判出后翻转基准兜底(见 use-theme-apply `buildElevationDecls`);
48
+ * - 非 hex → 原样返回、底 = 面。
49
+ *
50
+ * 两者的**正解都是显式给 `AppThemeColor.ground`**,翻转只是没给时的兜底。
51
+ */
52
+ export declare const themeScalePageColor: (bodyColor: string) => string;
53
+ /**
54
+ * 抬升面(overlay 档)派生:暗色 = bodyColor(面)向白提一步,混白权重
55
+ * `k = min(0.5, 10/(255-maxCh))`——最亮通道恒升 ≈10(`#141414→#1e1e1e`,
56
+ * ≈ EP 暗 overlay `#1d1e1f`);亮色 = bodyColor 原值(EP 亮 overlay 即 `#fff`=面,
57
+ * 亮色层级靠投影/蒙层表达,不再提亮)。非 hex → 原样返回。
58
+ */
59
+ export declare const themeScaleSurfaceColor: (bodyColor: string, mode: ThemeScaleMode) => string;
37
60
  /**
38
61
  * 按 EP 算法 + 模式感知派生一个语义色的 7 档色阶。
39
62
  *
@@ -43,3 +66,13 @@ export declare const themeScaleToRgba: (hex: string, alpha: number) => string;
43
66
  * `base` 非 hex 时各档兜底返回 `base` 原值(保持可挂载、不崩)。
44
67
  */
45
68
  export declare const themeScaleDerive: (base: string, mode: ThemeScaleMode) => ThemeColorScale;
69
+ /**
70
+ * 近黑判定:`bodyColor` 是否已暗到「压不动」,需要翻转基准(底取原值、面向白提)。
71
+ *
72
+ * 🔴 **判据用「余量」不用「亮 / 暗」**:后者要外部告知 `isDark`(本 util 拿不到、
73
+ * 强行传参会把一个纯函数变成要看模式的函数),且会在「深灰但不算暗色」的主题上判错
74
+ * ——余量是从色值本身就能算出来的,不依赖任何外部状态。
75
+ *
76
+ * 非 hex → `false`(判不了就不翻;那种情况的正解是显式给 `ground`)。
77
+ */
78
+ export declare const themeScaleIsNearBlack: (bodyColor: string) => boolean;