@done-coding/admin-core 0.10.0 → 0.10.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 (46) hide show
  1. package/es/bridge/config-hook.mjs +32 -26
  2. package/es/bridge/index.mjs +129 -83
  3. package/es/bridge/theme/index.mjs +103 -0
  4. package/es/bridge/theme/persist.mjs +14 -0
  5. package/es/bridge/theme/system-dark.mjs +11 -0
  6. package/es/components/app-layout/AppAside.vue.mjs +7 -0
  7. package/es/components/app-layout/AppAside.vue2.mjs +22 -0
  8. package/es/components/app-layout/AppFooter.vue.mjs +2 -2
  9. package/es/components/app-layout/AppHeader.vue.mjs +2 -2
  10. package/es/components/app-layout/AppHeader.vue2.mjs +35 -41
  11. package/es/components/app-layout/AppLayout.vue.mjs +2 -2
  12. package/es/components/app-layout/AppLayout.vue2.mjs +106 -88
  13. package/es/components/app-layout/AppShell.vue.mjs +60 -0
  14. package/es/components/app-layout/AppShell.vue2.mjs +4 -0
  15. package/es/components/app-layout/AppSidebar.vue.mjs +2 -2
  16. package/es/components/app-layout/AppSidebar.vue2.mjs +44 -47
  17. package/es/components/app-layout/AppTheme.vue.mjs +2 -2
  18. package/es/components/app-layout/AppTheme.vue2.mjs +55 -25
  19. package/es/components/app-layout/viewport.mjs +5 -0
  20. package/es/components/form/FormItemNestForm.vue.mjs +1 -1
  21. package/es/components/form/FormItemNestFormList.vue.mjs +1 -1
  22. package/es/components/form/FormSearch.vue.mjs +2 -2
  23. package/es/components/form/FormSearch.vue2.mjs +1 -1
  24. package/es/hooks/use-admin-theme-apply.mjs +16 -15
  25. package/es/hooks/use-admin-viewport-apply.mjs +29 -17
  26. package/es/index.mjs +182 -175
  27. package/es/store/app.mjs +133 -77
  28. package/es/style.css +1 -1
  29. package/package.json +2 -2
  30. package/types/bridge/config-hook.d.ts +10 -2
  31. package/types/bridge/index.d.ts +105 -5
  32. package/types/bridge/theme/index.d.ts +10 -0
  33. package/types/bridge/theme/persist.d.ts +23 -0
  34. package/types/bridge/theme/system-dark.d.ts +14 -0
  35. package/types/bridge/theme/types.d.ts +258 -0
  36. package/types/components/app-layout/AppAside.vue.d.ts +21 -0
  37. package/types/components/app-layout/AppLayout.vue.d.ts +2 -7
  38. package/types/components/app-layout/AppShell.vue.d.ts +27 -0
  39. package/types/components/app-layout/index.d.ts +4 -1
  40. package/types/components/app-layout/types.d.ts +117 -1
  41. package/types/components/app-layout/viewport.d.ts +30 -0
  42. package/types/hooks/use-admin-viewport-apply.d.ts +6 -1
  43. package/types/store/app.d.ts +24 -83
  44. package/types/types/route.d.ts +2 -0
  45. package/es/bridge/theme.mjs +0 -65
  46. package/types/bridge/theme.d.ts +0 -85
@@ -0,0 +1,258 @@
1
+ import { Component, DeepReadonly, Ref } from 'vue';
2
+ import { AppThemeConfig, AppLayoutHeaderConfig, AppLayoutFooterConfig, AppLayoutSidebarConfig, AppLayoutAsideConfig, AppLayoutBreadcrumbConfig, AppLayoutBodyConfig, AppLayoutViewportConfig, AppLayoutGapConfig, StorageLike } from '../index';
3
+ import { UpdatableConfigKey, UpdatableConfigMap } from '../config-hook';
4
+ /**
5
+ * bridge 主题模块**类型面**(从 `bridge/theme.ts` 升级目录拆出,CLAUDE.md 规则 12)。
6
+ *
7
+ * 纯类型 / 接口定义,无运行时逻辑——工厂在 `./index.ts`、持久化在 `./persist.ts`、
8
+ * 系统明暗探测在 `./system-dark.ts`。本文件显式 `import type { Component, DeepReadonly,
9
+ * Ref } from "vue"`(规则 9.0:lib build 下 vite-plugin-dts 不靠 auto-import)。
10
+ */
11
+ /**
12
+ * 主题 preset 的 layout 维度(焊缝契约 ④,P1 冻结,跨域共享)。
13
+ *
14
+ * layout 归属为 theme preset 的一个维度(一个 preset = 一个人格 = 色 + 局一体),
15
+ * 单入口 `setStyle` 切换。本结构纯数据可 JSON(除 `shell` 为运行时组件引用)。
16
+ *
17
+ * **灌值语义 = 基线复位 + 叠加**:bridge init 时快照六组布局 config 为基线;每次
18
+ * `setStyle` 先把六组 config 复位到基线、再叠加当前 preset 的 layout partial
19
+ * (`bridge.update` 单字段一级浅合并)。无跨 preset 残留、幂等。不带 layout 的老
20
+ * preset → 仅复位到 init 基线,零改动可用。
21
+ */
22
+ export interface AdminThemePresetLayout {
23
+ /** header 配置 partial(如 `{height}`),叠加到基线 `APP_LAYOUT_HEADER_CONFIG` */
24
+ header?: Partial<AppLayoutHeaderConfig>;
25
+ /** footer 配置 partial(如 `{height}`) */
26
+ footer?: Partial<AppLayoutFooterConfig>;
27
+ /** sidebar 配置 partial(如 `{width, collapseWidth}`) */
28
+ sidebar?: Partial<AppLayoutSidebarConfig>;
29
+ /** aside 右侧补充区配置 partial(如 `{width}`;P1' additive,带布局变更 preset 可配) */
30
+ aside?: Partial<AppLayoutAsideConfig>;
31
+ /** breadcrumb 配置 partial(如 `{height}`) */
32
+ breadcrumb?: Partial<AppLayoutBreadcrumbConfig>;
33
+ /** body 配置 partial(如 `{shimPadding}`) */
34
+ body?: Partial<AppLayoutBodyConfig>;
35
+ /** viewport 边框配置 partial(四边 padding;套框 / 拆框) */
36
+ viewport?: Partial<AppLayoutViewportConfig>;
37
+ /** 模块间距配置 partial(内缝 gap;分离式人格设 `{ size }` 让模块间露底色条带) */
38
+ gap?: Partial<AppLayoutGapConfig>;
39
+ /**
40
+ * 编排组件(布局形态)。缺省 → AppLayout 回退内置默认 AppShell(经典布局)。
41
+ * 运行时引用(不持久化);setStyle 切走 / 老 preset 无 shell → 回退内置。
42
+ * [MUST] markRaw(theme hook add 时自动 markRaw 兜底,防 reactive proxy 化)。
43
+ */
44
+ shell?: Component;
45
+ /**
46
+ * 数据分流意图(AppLayout 读取执行):提取 1 级路由模块到 header。
47
+ * 缺省 / undefined → 复位到 init 默认(false)。
48
+ */
49
+ extractLevel1ToHeader?: boolean;
50
+ }
51
+ /**
52
+ * 配置化通用描述(**跨配置块对齐标准**:theme preset / form / table / panel 等配置项复用)。
53
+ *
54
+ * 一个描述对象,含正反两面——供人 + web agent 选型:
55
+ * - `suitable`(正向):什么场景**宜选**。
56
+ * - `unsuitable`(反向):什么场景**不宜选**——对 agent,知道何时不该选与该选同等重要。
57
+ *
58
+ * 定位:高配置化体系 ≈ 运行期 schema(类 zod),本描述是 agent 选型 + 排除入口;结构化
59
+ * traits(如 `layout.extractLevel1ToHeader`)机器可读、本符补散文语义。两面均可选。
60
+ * 注:展示名 `label` 是 entry 各自的独立字段,不并入本描述对象。
61
+ */
62
+ export interface AdminConfigDescription {
63
+ /** 正向:什么应用 / 场景宜选(如「沉浸式工作台、需上下文面板的应用」)。 */
64
+ suitable?: string;
65
+ /** 反向:什么场景不宜选(agent 排除用,如「表单密集型后台、窄屏移动端」)。 */
66
+ unsuitable?: string;
67
+ }
68
+ /**
69
+ * 主题生命周期钩子上下文(core 注入,仅一个纯值 `id`)。
70
+ *
71
+ * 只携带 `id`(本钩子针对哪套主题)——供「被多个 preset 复用的同一钩子函数」区分自己
72
+ * 正服务于哪套主题(如打 `<style data-admin-theme="<id>">` 标签)。
73
+ *
74
+ * [MUST NOT] 挂 `document` / DOM 引用(钩子要操作 DOM 直接用全局 `document`,代传 element
75
+ * 易致内存泄漏)。**亦不传 `isDark`**:主题的 `<style>` [SHOULD] 一次注入含 `:root{}`(亮)
76
+ * + `:root.dark{}`(暗) 双态、明暗由 `<html>.dark` 类名切换自适配(同 core `useAdminThemeApply`
77
+ * 范式)——无需按明暗"细化按需加载",`setMode` 也因此不触发钩子(传 isDark 反诱导单态注入 →
78
+ * 切明暗即坏,与"setMode 不触发"自相矛盾)。
79
+ */
80
+ export interface AdminThemeLifecycleContext {
81
+ /** 本钩子针对的主题 id(风格 name)。 */
82
+ id: string;
83
+ }
84
+ /**
85
+ * 主题生命周期钩子(挂 {@link AdminThemeEntry};plugin `AdminThemePreset` 超集透传)。
86
+ *
87
+ * core 在 `setStyle` 切换时 **try-catch** 调用,让每套主题自管 DOM 副作用——典型:
88
+ * 激活时往 `document.head` 注入本主题专属 `<style data-admin-theme="<id>">`、切走前移除,
89
+ * 既支持复杂样式(@keyframes / 伪元素 / media)又守资产隔离(只当前主题 style 在 head)。
90
+ *
91
+ * 触发规则:仅 `setStyle`(风格切换)触发,`setMode`(明暗切换)**不触发**——主题注入的
92
+ * style [SHOULD] 含 `:root.dark` 双态由 `.dark` 自适配。钩子抛错仅 warn 吞掉,[MUST NOT]
93
+ * 阻断切换、[MUST NOT] 殃及他主题(守资产隔离)。
94
+ */
95
+ export interface AdminThemeLifecycleHooks {
96
+ /**
97
+ * 主题**激活后**调用(config / layout 已应用、`themeStyle` 已置新值)。
98
+ * 典型:往全局 `document.head` 注入本主题专属 `<style data-admin-theme="<id>">`。
99
+ */
100
+ onActivate?: (ctx: AdminThemeLifecycleContext) => void;
101
+ /**
102
+ * 主题**切走前**调用(即将切到别的风格 / 移除当前主题时回退 default 之前)。
103
+ * 典型:移除 onActivate 注入的 `<style data-admin-theme="<id>">`,归还干净 head。
104
+ *
105
+ * 钩子 [SHOULD] **幂等**:移除前先检测目标 `<style>` 是否仍在(`querySelector` 命中再
106
+ * removeChild),多次 / 重复清理才稳。core 侧已只在「切走 / 移除**当前**主题」时触发一次
107
+ * (非当前主题移除不重复触发),但作者自身幂等是更稳的兜底。
108
+ */
109
+ onDeactivate?: (ctx: AdminThemeLifecycleContext) => void;
110
+ }
111
+ /**
112
+ * 主题注册项(`bridge.theme.add` 第 2 参)——core 侧主题「preset」结构。
113
+ *
114
+ * core 不依赖 plugin,故自定义此最小注册形;plugin-theme 的 `AdminThemePreset`
115
+ * (含 id/label/description/config)是其结构超集,可整坨直接透传:
116
+ * `bridge.theme.add(preset.id, preset)`(多出的 id 作 excess 字段被忽略,label/description 纳入)。
117
+ *
118
+ * 继承 {@link AdminThemeLifecycleHooks}:可选 `onActivate` / `onDeactivate` 生命周期钩子。
119
+ */
120
+ export interface AdminThemeEntry extends AdminThemeLifecycleHooks {
121
+ /**
122
+ * 风格色值(light/dark 两套 `AppThemeColor`)。
123
+ *
124
+ * 内部做浅快照(`{light:{...},dark:{...}}`)——与调用方对象解耦,且与 bridge
125
+ * 响应式 APP_THEME_CONFIG 的 proxy target 解耦(避免切走后反写注册值)。
126
+ */
127
+ config: AppThemeConfig;
128
+ /** 展示名(供 `AppTheme.vue` 下拉显示,如中文「柔光悬浮」);缺省回退注册 name 自身。 */
129
+ label?: string;
130
+ /**
131
+ * 描述(自然语言,供人 / web agent 理解选型):分「适合 / 不适合」两面。
132
+ *
133
+ * 定位:高配置化体系 ≈ 运行期 schema(类 zod),`description` 是 agent「选型 + 排除」
134
+ * 的语义入口;结构化 traits(`layout.extractLevel1ToHeader` 等)机器可读、本字段补散文语义。
135
+ * 缺省 undefined。见 {@link AdminConfigDescription}。
136
+ */
137
+ description?: AdminConfigDescription;
138
+ /**
139
+ * 布局维度(焊缝契约 ④);缺省 → 切到该 preset 仅复位布局基线(不套框、内置 shell、经典分流)。
140
+ * 见 {@link AdminThemePresetLayout}。
141
+ */
142
+ layout?: AdminThemePresetLayout;
143
+ }
144
+ /**
145
+ * 主题明暗模式三态:亮 / 暗 / 跟随系统。
146
+ * - `light` / `dark`:固定明暗。
147
+ * - `system`:跟随 `prefers-color-scheme`(系统切换实时响应)。
148
+ * 派生 `themeIsDark` = `mode==='system' ? 系统偏暗 : mode==='dark'`。
149
+ */
150
+ export type AdminThemeMode = "light" | "dark" | "system";
151
+ /** 主题模块对外能力。 */
152
+ export interface AdminThemeModule {
153
+ /**
154
+ * 注册/覆盖一个风格(插件 install 经 `bridge.theme.add` 调;同名覆盖)。
155
+ *
156
+ * 第 2 参收 {@link AdminThemeEntry}(`{config,label?}`);config 内部浅快照解耦。
157
+ * 若新注册 name 命中持久化恢复的目标风格(init 时尚未注册),自动 `setStyle(name)`。
158
+ */
159
+ add: (name: string, preset: AdminThemeEntry) => void;
160
+ /** 注销一个风格(`'default'` 不可注销;注销当前风格则回退 `'default'`)。 */
161
+ remove: (name: string) => void;
162
+ /** 切换风格(未注册回退 `'default'`):同步 APP_THEME_CONFIG + 持久化。 */
163
+ setStyle: (name: string) => void;
164
+ /**
165
+ * 切换明暗模式三态(亮/暗/跟随系统)+ 持久化。`system` 态下 `themeIsDark` 跟随系统偏好。
166
+ */
167
+ setMode: (mode: AdminThemeMode) => void;
168
+ /**
169
+ * 切换暗色(向后兼容二态 API):`true`→`setMode('dark')`、`false`→`setMode('light')`。
170
+ * 新代码 [SHOULD] 用 {@link AdminThemeModule.setMode}(支持 `system` 第三态)。
171
+ */
172
+ setDark: (isDark: boolean) => void;
173
+ /** 响应式风格名列表(只读,供 `AppTheme.vue` 下拉;`length>1` 才显示选择)。 */
174
+ list: DeepReadonly<Ref<string[]>>;
175
+ /** 取风格展示名(`add` 注册的 label;缺省回退 name 自身)。 */
176
+ labelOf: (name: string) => string;
177
+ /** 取风格描述(`add` 注册的 description,含 suitable/unsuitable 两面;未设回退 undefined)。 */
178
+ descriptionOf: (name: string) => AdminConfigDescription | undefined;
179
+ }
180
+ /**
181
+ * 当前生效 preset 的 layout 运行时维度(AppLayout 直读,响应式)。
182
+ *
183
+ * 尺寸 / 套框等纯数据维度经 setStyle 灌进 bridge 响应式 config(基线复位 + 叠加),
184
+ * 故不在本结构重复——本结构仅暴露**非 config 的运行时维度**:编排组件 + 分流意图。
185
+ */
186
+ export interface BridgeThemeLayoutState {
187
+ /**
188
+ * 当前 preset 的编排组件(缺省 undefined → AppLayout 回退内置默认 AppShell)。
189
+ * markRaw 后存储(防 proxy 化)。
190
+ */
191
+ shell?: Component;
192
+ /** 当前 preset 的分流意图(提取 1 级路由到 header);缺省复位 false。 */
193
+ extractLevel1ToHeader: boolean;
194
+ }
195
+ /** 主题 hook 对外契约:模块 + 顶层响应式只读真相源。 */
196
+ export interface BridgeThemeHook {
197
+ /** 主题模块(add/remove/setStyle/setDark/list) */
198
+ theme: AdminThemeModule;
199
+ /** 当前风格名(响应式只读;切换真相源,appStore / AppTheme.vue 读此) */
200
+ themeStyle: DeepReadonly<Ref<string>>;
201
+ /**
202
+ * 明暗模式三态真相源(响应式只读;亮/暗/跟随系统)。`themeIsDark` 由本 mode + 系统偏好派生。
203
+ */
204
+ themeMode: DeepReadonly<Ref<AdminThemeMode>>;
205
+ /** 是否暗色(响应式只读 **派生**;= mode==='system'?系统偏暗:mode==='dark'。挂值 composable toggle .dark 读此) */
206
+ themeIsDark: DeepReadonly<Ref<boolean>>;
207
+ /**
208
+ * 当前 preset 的 layout 运行时维度(响应式只读;AppLayout 直读 shell + 分流意图)。
209
+ * 尺寸 / 套框纯数据维度经 setStyle 灌 bridge config,不在此重复。
210
+ */
211
+ themeLayout: DeepReadonly<Ref<BridgeThemeLayoutState>>;
212
+ }
213
+ /**
214
+ * 六组布局 config 的 init 基线快照(`setStyle` 复位 + 叠加用)。
215
+ *
216
+ * = bridge init 传入的六组布局 config 浅快照(不含 theme)。setStyle 切到任一 preset
217
+ * 前先把六组 config 复位到本基线、再叠加 preset.layout partial(幂等、无残留)。
218
+ */
219
+ export interface BridgeThemeLayoutBaseline {
220
+ /** header 配置基线 */
221
+ header: AppLayoutHeaderConfig;
222
+ /** footer 配置基线 */
223
+ footer: AppLayoutFooterConfig;
224
+ /** sidebar 配置基线 */
225
+ sidebar: AppLayoutSidebarConfig;
226
+ /** aside 右侧补充区配置基线(P1' additive) */
227
+ aside: AppLayoutAsideConfig;
228
+ /** breadcrumb 配置基线 */
229
+ breadcrumb: AppLayoutBreadcrumbConfig;
230
+ /** body 配置基线 */
231
+ body: AppLayoutBodyConfig;
232
+ /** viewport 边框配置基线(已合并核内默认四边 0) */
233
+ viewport: AppLayoutViewportConfig;
234
+ /** 模块间距配置基线(内缝 gap;已合并核内默认 size 0) */
235
+ gap: AppLayoutGapConfig;
236
+ }
237
+ /** `createBridgeThemeHook` 入参。 */
238
+ export interface BridgeThemeInit {
239
+ /** init 默认风格 config(= bridge init 传入的 APP_THEME_CONFIG);core 自动 add 为 `'default'` */
240
+ initConfig: AppThemeConfig;
241
+ /**
242
+ * 注入的 config 更新器(= configHook.update 全量 key)。
243
+ *
244
+ * setStyle 经此把当前风格 config 灌进 APP_THEME_CONFIG(整体替换 light/dark),
245
+ * 并把六组布局 config 基线复位 + 叠加 preset.layout partial。复用既有 update
246
+ * 通道,[MUST NOT] 另持一份主题 / 布局响应式。
247
+ */
248
+ update: <K extends UpdatableConfigKey>(key: K, partial: Partial<UpdatableConfigMap[K]>) => void;
249
+ /**
250
+ * 六组布局 config init 基线(setStyle 复位 + 叠加用)。
251
+ * 缺省(向后兼容 / 测试)→ 不做布局复位,setStyle 仅切色 + 应用 preset.layout partial。
252
+ */
253
+ layoutBaseline?: BridgeThemeLayoutBaseline;
254
+ /** 注入的命名空间 storage(= bridge.getStorage());持久化 `{themeStyle,themeIsDark}` */
255
+ storage: StorageLike;
256
+ /** 持久化 key(命名空间已由 storage 加前缀);缺省 `"admin-core-theme"` */
257
+ storageKey?: string;
258
+ }
@@ -0,0 +1,21 @@
1
+ type __VLS_Props = {
2
+ /** 显隐(= showAside,路由 meta.layout.aside 基线);false 不渲染 */
3
+ show: boolean;
4
+ };
5
+ declare function __VLS_template(): {
6
+ attrs: Partial<{}>;
7
+ slots: {
8
+ default?(_: {}): any;
9
+ };
10
+ refs: {};
11
+ rootEl: any;
12
+ };
13
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
14
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
16
+ export default _default;
17
+ type __VLS_WithTemplateSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -1,4 +1,4 @@
1
- import { AppLayoutAppStoreSlice, AppLayoutUserStoreSlice, AppLayoutBridgeSlice } from './types';
1
+ import { AppShellContentAnchor, AppLayoutAppStoreSlice, AppLayoutUserStoreSlice, AppLayoutBridgeSlice } from './types';
2
2
  import { WatermarkProps } from 'element-plus';
3
3
  type __VLS_Props = {
4
4
  /**
@@ -21,12 +21,7 @@ type __VLS_Props = {
21
21
  };
22
22
  declare function __VLS_template(): {
23
23
  attrs: Partial<{}>;
24
- slots: {
25
- 'sidebar-top'?(_: {}): any;
26
- 'sidebar-bottom'?(_: {}): any;
27
- 'header-left'?(_: {}): any;
28
- 'header-right'?(_: {}): any;
29
- };
24
+ slots: Partial<Record<NonNullable<AppShellContentAnchor>, (_: {}) => any>>;
30
25
  refs: {};
31
26
  rootEl: HTMLDivElement;
32
27
  };
@@ -0,0 +1,27 @@
1
+ import { AppShellProps } from './types';
2
+ declare function __VLS_template(): {
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ default?(_: {
6
+ Footer: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
7
+ }): any;
8
+ aside?(_: {}): any;
9
+ brand?(_: {}): any;
10
+ themeSwitcher?(_: {
11
+ Default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
12
+ }): any;
13
+ userEntry?(_: {}): any;
14
+ settings?(_: {}): any;
15
+ };
16
+ refs: {};
17
+ rootEl: any;
18
+ };
19
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
20
+ declare const __VLS_component: import('vue').DefineComponent<AppShellProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<AppShellProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
22
+ export default _default;
23
+ type __VLS_WithTemplateSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };
@@ -1,9 +1,12 @@
1
1
  import { default as AppLayout } from './AppLayout.vue';
2
2
  import { default as AppHeader } from './AppHeader.vue';
3
3
  import { default as AppSidebar } from './AppSidebar.vue';
4
+ import { default as AppAside } from './AppAside.vue';
4
5
  import { default as AppBody } from './AppBody.vue';
5
6
  import { default as AppBreadcrumb } from './AppBreadcrumb.vue';
6
7
  import { default as AppFooter } from './AppFooter.vue';
7
8
  import { default as AppPage } from './AppPage.vue';
8
- export { AppLayout, AppHeader, AppSidebar, AppBody, AppBreadcrumb, AppFooter, AppPage, };
9
+ import { default as AppTheme } from './AppTheme.vue';
10
+ export { AppLayout, AppHeader, AppSidebar, AppAside, AppBody, AppBreadcrumb, AppFooter, AppPage, AppTheme, };
9
11
  export * from './types';
12
+ export * from './viewport';
@@ -1,5 +1,7 @@
1
+ import { Component, VNode } from 'vue';
1
2
  import { createAppStore, createUserStore } from '../../store';
2
3
  import { AdminBridge } from '../../bridge';
4
+ import { RouteMetaResolveRaw } from '../../types';
3
5
  /**
4
6
  * AppLayout 族 app store 消费契约(props/inject 切面)。
5
7
  *
@@ -39,4 +41,118 @@ export type AppLayoutUserStoreSlice<UserInfo = Record<string, any>> = ReturnType
39
41
  * (getRoutes / generateRouteMetaRawTree)。loginApi / refreshToken 等 auth
40
42
  * 面不通过本 slice 暴露(业务侧通过 appAdminBridge 直读)。
41
43
  */
42
- export type AppLayoutBridgeSlice = Pick<AdminBridge, "APP_BASE_INFO" | "APP_ENV_INFO" | "APP_CACHE_CONFIG" | "APP_LAYOUT_HEADER_CONFIG" | "APP_LAYOUT_FOOTER_CONFIG" | "APP_LAYOUT_SIDEBAR_CONFIG" | "APP_LAYOUT_BREADCRUMB_CONFIG" | "APP_LAYOUT_BODY_CONFIG" | "APP_LAYOUT_VIEWPORT_CONFIG" | "APP_LAYOUT_CONFIG" | "APP_ROUTER_META_DEFAULT_CONFIG" | "APP_ROUTER_CONFIG" | "APP_ROUTER_PATHS_CONFIG" | "APP_THEME_CONFIG" | "theme" | "themeStyle" | "themeIsDark" | "themeColors" | "getRoutes" | "generateRouteMetaRawTree">;
44
+ export type AppLayoutBridgeSlice = Pick<AdminBridge, "APP_BASE_INFO" | "APP_ENV_INFO" | "APP_CACHE_CONFIG" | "APP_LAYOUT_HEADER_CONFIG" | "APP_LAYOUT_FOOTER_CONFIG" | "APP_LAYOUT_SIDEBAR_CONFIG" | "APP_LAYOUT_BREADCRUMB_CONFIG" | "APP_LAYOUT_BODY_CONFIG" | "APP_LAYOUT_VIEWPORT_CONFIG" | "APP_LAYOUT_GAP_CONFIG" | "APP_LAYOUT_CONFIG" | "APP_ROUTER_META_DEFAULT_CONFIG" | "APP_ROUTER_CONFIG" | "APP_ROUTER_PATHS_CONFIG" | "APP_THEME_CONFIG" | "theme" | "themeStyle" | "themeMode" | "themeIsDark" | "themeLayout" | "themeColors" | "getRoutes" | "generateRouteMetaRawTree">;
45
+ /**
46
+ * 内容锚 slot 名集(焊缝契约 ③,纯功能语义;P1' 去布局化重做)。
47
+ *
48
+ * 业务 slot 为**内容锚**(描述「是什么功能」非「放哪」)——同一份业务原料,落位权归
49
+ * AppShell:不同 AppShell 把同一内容锚渲染到不同区域 = 不同布局人格。AppLayout 用
50
+ * `v-for` 整组动态透传给 AppShell([MUST NOT] 在 AppLayout 写死任一内容锚落位)。
51
+ *
52
+ * - `brand`:品牌 / logo / 应用名入口
53
+ * - `userEntry`:用户下拉 / 登录按钮 / 用户态入口
54
+ * - `settings`:设置 / 配置入口
55
+ * - `themeSwitcher`:主题(风格 + 亮暗)切换器(scope 传内置 AppTheme 默认内容)
56
+ * - `aside`(P4 加):右侧补充区内容中转锚 → 喂进 `AppAside` 默认 slot。
57
+ * **与 sidebar 同构:全局单实例 + 应用层切入**——App.vue 填一次 `#aside`(同
58
+ * `#brand` / `#userEntry` 范式),`showAside=true`(路由 `meta.layout.aside` 派生)
59
+ * 的页面都显示这同一份;宽度 / 位置 / 容器归主题(`preset.layout.aside.width` +
60
+ * AppAside 积木)。per-page 内容随页变化 = **业务页面开发自决**(如自往 `#aside` 塞
61
+ * `<RouterView name="aside" />`),**不属本布局体系范围**,core 不建 per-route 投递机制。
62
+ *
63
+ * 去 `nav*` 位置锚:菜单走数据流(`menuFlatList`),渲染成何种导航由 AppShell 自由
64
+ * (复用导出积木 `MenuTree` / `AppSidebar` 或自 DIY)。
65
+ * 内置默认 AppShell 的落位映射(1:1 镜像经典布局)见 `AppShell.vue` 注释。
66
+ */
67
+ export type AppShellContentAnchor = "brand" | "userEntry" | "settings" | "themeSwitcher" | "aside";
68
+ /**
69
+ * AppShell 扁平注入面 props(焊缝契约 ①-props)。
70
+ *
71
+ * 原分喂 AppHeader / AppSidebar 的 props **扁平合并为一份**,三处零件由 AppShell
72
+ * 内部自行分发。样式 / themeColors / 折叠态 / changeSidebarCollapseStatus 走
73
+ * **inject**(`APP_LAYOUT_APP_STORE_KEY` / `APP_LAYOUT_BRIDGE_KEY`,AppLayout 已 provide),
74
+ * 不进 props——AppShell setup 内自取(同内置 AppHeader/AppSidebar 既有范式)。
75
+ */
76
+ export interface AppShellProps {
77
+ /** 完整菜单树(经权限 / menuShow 过滤、排序) */
78
+ menus: RouteMetaResolveRaw[];
79
+ /** 扁平菜单列表(喂 AppBody / 子零件高度链 + 路由匹配) */
80
+ menuFlatList: RouteMetaResolveRaw[];
81
+ /** sidebar 区菜单(分流后) */
82
+ sidebarMenus: RouteMetaResolveRaw[];
83
+ /** header 区菜单(分流后;extractLevel1ToHeader=true 时为 1 级模块) */
84
+ headerMenus: RouteMetaResolveRaw[];
85
+ /** 当前聚焦菜单 */
86
+ activeMenu?: RouteMetaResolveRaw;
87
+ /** 当前聚焦模块菜单(header 模块高亮) */
88
+ activeModuleMenu?: RouteMetaResolveRaw;
89
+ /**
90
+ * 是否展示 header(路由 meta.layout 基线意图)。AppShell 自解读:决定喂给哪个区域的
91
+ * `show`(内置默认 shell 喂 AppHeader)。
92
+ */
93
+ showHeader: boolean;
94
+ /**
95
+ * 是否展示 sidebar(路由 meta.layout 基线意图)。语义同 `showHeader`——
96
+ * 内置默认 shell 喂 AppSidebar 的 `show`。
97
+ */
98
+ showSidebar: boolean;
99
+ /**
100
+ * 是否展示右侧 aside 补充区(路由 meta.layout 基线意图,additive,默认 false)。
101
+ * 内置经典 shell 不渲染 aside(经典无右栏);自定义 shell 据此渲染右侧区。
102
+ */
103
+ showAside: boolean;
104
+ /**
105
+ * sidebar 层级是否高于 header(透传内置 AppSidebar.aboveHeader)。
106
+ * 默认 false;自定义 shell 可忽略。
107
+ */
108
+ sidebarAboveHeader: boolean;
109
+ }
110
+ /**
111
+ * AppShell emits(焊缝契约 ①-emits)。
112
+ *
113
+ * 当前空——作为统一预留通道。后续 AppShell 需向 AppLayout 反向通知(如布局态变更)
114
+ * 时在此扩展,[MUST NOT] 自造平行回调 props。
115
+ */
116
+ export interface AppShellEmits {
117
+ }
118
+ /**
119
+ * AppShell 默认 scoped slot 作用域参数(焊缝契约 ①-slots,default slot)。
120
+ *
121
+ * AppShell 在「主体该出现的位置」吐出本作用域 → AppLayout 接住后:
122
+ * 用 `Footer` 组件引用组装进 `AppBody #footer`,并把 AppBody(持有 menuFlatList、
123
+ * 守高度链)塞回该默认 slot 位置。这绕过「父传子 slot 是父作用域 vnode、子无法
124
+ * 反向注入子 slot」的 Vue 约束(footer 走「AppShell 吐组件引用 → AppLayout 组装」)。
125
+ */
126
+ export interface AppShellDefaultSlotScope {
127
+ /**
128
+ * AppShell 选定的 footer 组件引用(默认 = `componentFallBack.AppFooter`;
129
+ * 自定义 shell 可吐自定义 footer)。AppLayout 用 `<component :is="Footer" />`
130
+ * 渲染进 `AppBody #footer`。
131
+ */
132
+ Footer: Component;
133
+ }
134
+ /**
135
+ * 功能锚 scoped slot 作用域参数(焊缝契约 ①-slots,内容锚 scope)。
136
+ *
137
+ * AppShell 经各功能锚 slot 的 scope 传「内置默认内容组件引用」给布局,布局可用可无视:
138
+ * - `themeSwitcher` 锚 `Default` = 内置 `AppTheme`(保证主题切换功能以某形式可达;布局
139
+ * 无视默认内容时须自供等效切换 UI,否则违约——见声明驱动测试纪律)。
140
+ * - `brand` / `userEntry` / `settings` / `aside` 锚 `Default` = `undefined`(不预设未遇到的需求,随时可扩)。
141
+ */
142
+ export interface AppShellAnchorScope {
143
+ /** 该功能锚的内置默认内容组件引用(仅 themeSwitcher 提供,markRaw);其余 undefined */
144
+ Default?: Component;
145
+ }
146
+ /**
147
+ * AppShell slots 契约(焊缝契约 ①-slots 全集)。
148
+ *
149
+ * - `default`:作用域 = {@link AppShellDefaultSlotScope},AppLayout 在此塞 AppBody(持高度链)。
150
+ * - 各内容锚({@link AppShellContentAnchor}):scoped slot(scope = {@link AppShellAnchorScope}),
151
+ * AppLayout `v-for` 整组转发业务侧填的同名 slot;AppShell 自行决定每个内容锚落到哪个区域。
152
+ */
153
+ export type AppShellSlots = {
154
+ /** 默认 slot:AppLayout 在此塞 AppBody(scoped,拿 Footer 组件引用组装 #footer) */
155
+ default: (scope: AppShellDefaultSlotScope) => VNode[];
156
+ } & {
157
+ [K in AppShellContentAnchor]?: (scope: AppShellAnchorScope) => VNode[];
158
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * viewport 镂空 SVG 装饰边框基础设施常量(焊缝契约 ⑤,P1 冻结)。
3
+ *
4
+ * 把 viewport 那圈留白(`APP_LAYOUT_VIEWPORT_CONFIG` 四边 padding 让出的边距)
5
+ * 从消极留白变积极画布:AppShell 可 teleport 一个铺满视口的大 SVG 到 body、
6
+ * 镂空出内容区,在边框圈里画渐变 / 动画 / 填充色。
7
+ *
8
+ * - **叠加非替代**:现有 `useAdminViewportApply` 的 padding 留白机制保留;SVG 只在
9
+ * 让出的那圈里画装饰。镂空矩形尺寸 = AppShell 经 inject 读 `APP_LAYOUT_VIEWPORT_CONFIG`
10
+ * 四边算(响应式)。
11
+ * - **teleport + pointer-events:none**:teleport 到 body(避开层叠上下文 / overflow
12
+ * 裁切),`pointer-events: none` 绝不挡交互。
13
+ *
14
+ * z-index 双档(core 导出常量,AppShell / 主题资产按需选档):
15
+ * 业务自造 z-index 字面量会与 el 弹窗(2000 起动态自增)打架——故 core 冻结两档安全值。
16
+ */
17
+ /**
18
+ * viewport 装饰 z-index——**弹窗下档**(默认,绝对安全)。
19
+ *
20
+ * `800 < 2000`(el 弹窗 base z-index)→ 装饰永远在弹窗下,绝不盖住 dialog / message。
21
+ * 大多数边框装饰用此档(装饰是背景氛围,不该盖业务弹窗)。
22
+ */
23
+ export declare const ADMIN_CORE_VIEWPORT_DECOR_ZINDEX_BELOW = 800;
24
+ /**
25
+ * viewport 装饰 z-index——**弹窗上档**(盖住弹窗,慎用)。
26
+ *
27
+ * el z-index 自 2000 动态自增(每开一层 +N),`10000` 实践绝对安全盖住弹窗档。
28
+ * 仅当装饰需覆盖弹窗(如全屏切换动画遮罩 / 边框需压住一切)时用此档。
29
+ */
30
+ export declare const ADMIN_CORE_VIEWPORT_DECOR_ZINDEX_ABOVE = 10000;
@@ -1,9 +1,14 @@
1
1
  import { DeepReadonly } from 'vue';
2
- import { AppLayoutViewportConfig } from '../bridge';
2
+ import { AppLayoutViewportConfig, AppLayoutGapConfig } from '../bridge';
3
3
  /** `useAdminViewportApply` 入参。 */
4
4
  export interface UseAdminViewportApplyOptions {
5
5
  /** viewport 边框配置响应式获取器(= `bridge.APP_LAYOUT_VIEWPORT_CONFIG`) */
6
6
  getViewportConfig: () => AppLayoutViewportConfig | DeepReadonly<AppLayoutViewportConfig>;
7
+ /**
8
+ * 模块间距 gap 配置响应式获取器(= `bridge.APP_LAYOUT_GAP_CONFIG`,可选)。
9
+ * 传入则额外注入 `--admin-core-gap`;不传则不注入该 var(向后兼容)。
10
+ */
11
+ getGapConfig?: () => AppLayoutGapConfig | DeepReadonly<AppLayoutGapConfig>;
7
12
  /** 注入 document(测试 / SSR);缺省 `globalThis.document`,不存在时静默跳过 */
8
13
  document?: Document;
9
14
  }