layplux 1.0.1 → 2.0.1

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 (91) hide show
  1. package/dist/cjs/components/center-view/index.cjs +18 -28
  2. package/dist/cjs/components/corner-glow/index.cjs +11 -28
  3. package/dist/cjs/components/dropdown/index.cjs +136 -130
  4. package/dist/cjs/components/icon/index.cjs +29 -51
  5. package/dist/cjs/components/index.cjs +24 -25
  6. package/dist/cjs/components/panel-view/index.cjs +111 -114
  7. package/dist/cjs/components/popup/index.cjs +166 -151
  8. package/dist/cjs/components/title/index.cjs +34 -47
  9. package/dist/cjs/components/tooltip/index.cjs +70 -61
  10. package/dist/cjs/components/widget/index.cjs +52 -72
  11. package/dist/cjs/index.cjs +13 -40
  12. package/dist/cjs/layout/glass-overlay.cjs +15 -28
  13. package/dist/cjs/layout/layered-manager.cjs +20 -29
  14. package/dist/cjs/layout/layplux.cjs +19 -32
  15. package/dist/cjs/layout/root-pane.cjs +20 -38
  16. package/dist/cjs/layout/skeleton/bottom-area.cjs +26 -43
  17. package/dist/cjs/layout/skeleton/bottom-left-area.cjs +12 -29
  18. package/dist/cjs/layout/skeleton/bottom-right-area.cjs +11 -28
  19. package/dist/cjs/layout/skeleton/center-area.cjs +278 -371
  20. package/dist/cjs/layout/skeleton/index.cjs +7 -24
  21. package/dist/cjs/layout/skeleton/left-bottom-area.cjs +12 -29
  22. package/dist/cjs/layout/skeleton/left-top-area.cjs +12 -29
  23. package/dist/cjs/layout/skeleton/right-bottom-area.cjs +11 -28
  24. package/dist/cjs/layout/skeleton/right-top-area.cjs +11 -28
  25. package/dist/cjs/layout/skeleton/skeleton.cjs +55 -60
  26. package/dist/cjs/layout/skeleton/top-area.cjs +26 -43
  27. package/dist/cjs/locales/en-US.cjs +11 -30
  28. package/dist/cjs/locales/index.cjs +12 -30
  29. package/dist/cjs/locales/zh-CN.cjs +11 -30
  30. package/dist/cjs/managers/area.cjs +12 -25
  31. package/dist/cjs/managers/index.cjs +12 -20
  32. package/dist/cjs/managers/pane.cjs +12 -26
  33. package/dist/cjs/managers/skeleton.cjs +112 -124
  34. package/dist/cjs/managers/theme.cjs +8 -29
  35. package/dist/cjs/managers/widget-container.cjs +31 -31
  36. package/dist/cjs/managers/widget.cjs +63 -50
  37. package/dist/cjs/types/config.cjs +2 -16
  38. package/dist/cjs/types/index.cjs +2 -18
  39. package/dist/cjs/types/locale.cjs +2 -16
  40. package/dist/cjs/utils/event-bus.cjs +53 -49
  41. package/dist/cjs/utils/focus-tracker.cjs +66 -42
  42. package/dist/cjs/utils/index.cjs +23 -31
  43. package/dist/cjs/utils/unique-id.cjs +5 -24
  44. package/dist/cjs/utils/vue.cjs +20 -30
  45. package/dist/esm/components/center-view/index.mjs +15 -7
  46. package/dist/esm/components/corner-glow/index.mjs +8 -7
  47. package/dist/esm/components/dropdown/index.mjs +117 -101
  48. package/dist/esm/components/icon/index.mjs +24 -30
  49. package/dist/esm/components/index.mjs +7 -8
  50. package/dist/esm/components/panel-view/index.mjs +107 -98
  51. package/dist/esm/components/popup/index.mjs +155 -130
  52. package/dist/esm/components/title/index.mjs +29 -24
  53. package/dist/esm/components/tooltip/index.mjs +67 -40
  54. package/dist/esm/components/widget/index.mjs +45 -48
  55. package/dist/esm/index.mjs +4 -10
  56. package/dist/esm/layout/glass-overlay.mjs +12 -7
  57. package/dist/esm/layout/layered-manager.mjs +17 -8
  58. package/dist/esm/layout/layplux.mjs +14 -11
  59. package/dist/esm/layout/root-pane.mjs +16 -16
  60. package/dist/esm/layout/skeleton/bottom-area.mjs +23 -22
  61. package/dist/esm/layout/skeleton/bottom-left-area.mjs +9 -8
  62. package/dist/esm/layout/skeleton/bottom-right-area.mjs +8 -7
  63. package/dist/esm/layout/skeleton/center-area.mjs +251 -333
  64. package/dist/esm/layout/skeleton/index.mjs +1 -4
  65. package/dist/esm/layout/skeleton/left-bottom-area.mjs +9 -8
  66. package/dist/esm/layout/skeleton/left-top-area.mjs +9 -8
  67. package/dist/esm/layout/skeleton/right-bottom-area.mjs +8 -7
  68. package/dist/esm/layout/skeleton/right-top-area.mjs +8 -7
  69. package/dist/esm/layout/skeleton/skeleton.mjs +52 -39
  70. package/dist/esm/layout/skeleton/top-area.mjs +23 -22
  71. package/dist/esm/locales/en-US.mjs +9 -10
  72. package/dist/esm/locales/index.mjs +7 -9
  73. package/dist/esm/locales/zh-CN.mjs +9 -10
  74. package/dist/esm/managers/area.mjs +10 -5
  75. package/dist/esm/managers/index.mjs +3 -3
  76. package/dist/esm/managers/pane.mjs +9 -5
  77. package/dist/esm/managers/skeleton.mjs +97 -95
  78. package/dist/esm/managers/theme.mjs +6 -9
  79. package/dist/esm/managers/widget-container.mjs +28 -10
  80. package/dist/esm/managers/widget.mjs +55 -25
  81. package/dist/esm/types/config.mjs +1 -0
  82. package/dist/esm/types/index.mjs +1 -1
  83. package/dist/esm/types/locale.mjs +1 -0
  84. package/dist/esm/utils/event-bus.mjs +46 -17
  85. package/dist/esm/utils/focus-tracker.mjs +63 -23
  86. package/dist/esm/utils/index.mjs +7 -10
  87. package/dist/esm/utils/unique-id.mjs +3 -4
  88. package/dist/esm/utils/vue.mjs +13 -5
  89. package/dist/types/managers/skeleton.d.ts.map +1 -1
  90. package/dist/umd/index.js +2 -30
  91. package/package.json +18 -14
@@ -1,74 +1,82 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var widget_exports = {};
20
- __export(widget_exports, {
21
- isWidget: () => isWidget,
22
- useWidget: () => useWidget
23
- });
24
- module.exports = __toCommonJS(widget_exports);
25
- var import_vue = require("vue");
26
- var import_utils = require("../utils");
27
- var import_components = require("../components");
28
- var import_pane = require("./pane");
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var pane = require('./pane.cjs');
5
+ var uniqueId = require('../utils/unique-id.cjs');
6
+ var vue$1 = require('../utils/vue.cjs');
7
+ var index = require('../components/widget/index.cjs');
8
+
29
9
  function useWidget(config, container, skeleton) {
30
- const { name, props, type } = config;
31
- const active = (0, import_vue.computed)(() => container?.activeId.value === name);
32
- const focused = (0, import_vue.computed)(() => skeleton?.focusedId.value === name);
33
- const id = (0, import_utils.uniqueId)(type);
34
- const align = props?.align ?? "left";
35
- const pane = (0, import_pane.usePane)();
10
+ const {
11
+ name,
12
+ props,
13
+ type
14
+ } = config;
15
+ const active = vue.computed(() => container?.activeId.value === name);
16
+ const focused = vue.computed(() => skeleton?.focusedId.value === name);
17
+ const id = uniqueId.uniqueId(type);
18
+ const align = props?.align ?? 'left';
19
+ const pane$1 = pane.usePane();
20
+
21
+ // ─── Focusable 注册 ──────────────────────────────────────────────────────
22
+ // range 初始为 () => false,PanelView 挂载后通过 focusable.setRange(el) 注入真实 DOM
36
23
  const focusable = skeleton.focusTracker.create({
37
- range: (e) => {
24
+ range: e => {
38
25
  const target = e.target;
39
26
  if (!target) {
40
27
  return false;
41
28
  }
29
+ // 当点击的是panel时,激活
42
30
  const el = document.getElementById(id);
43
31
  if (el?.contains(target)) {
44
32
  return true;
45
33
  }
46
- if (target.classList.contains("layplux-resize-handle")) {
34
+ // 当class中包含layplux-resize-handle则不失去焦点
35
+ if (target.classList.contains('layplux-resize-handle')) {
47
36
  return true;
48
37
  }
49
38
  return false;
50
39
  },
51
40
  onActive: () => {
52
41
  widget.container?.activate(name);
53
- skeleton.event?.emitGlobal(`widget:${name}:focus`, { widget });
42
+ skeleton.event?.emitGlobal(`widget:${name}:focus`, {
43
+ widget
44
+ });
54
45
  },
55
46
  onBlur: () => {
47
+ // 焦点离开 → 清除 focusedId
56
48
  skeleton.blur();
57
- skeleton.event?.emitGlobal(`widget:${name}:blur`, { widget });
58
- if (pane.viewMode.value === "DockUnpinned" || pane.viewMode.value === "Undock") {
49
+ skeleton.event?.emitGlobal(`widget:${name}:blur`, {
50
+ widget
51
+ });
52
+ // DockUnpinned:失焦自动收起
53
+ if (pane$1.viewMode.value === 'DockUnpinned' || pane$1.viewMode.value === 'Undock') {
59
54
  container?.deactivate();
60
55
  }
61
56
  }
62
57
  });
63
58
  function renderBody() {
64
- const { content, contentProps } = config;
65
- return (0, import_utils.createContent)(content, { ...contentProps, config, event: widget.event });
59
+ const {
60
+ content,
61
+ contentProps
62
+ } = config;
63
+ return vue$1.createContent(content, {
64
+ ...contentProps,
65
+ config,
66
+ event: widget.event
67
+ });
66
68
  }
67
69
  function renderContent() {
68
- return (0, import_vue.h)(import_components.WidgetView, { key: id, widget });
70
+ return vue.h(index.WidgetView, {
71
+ key: id,
72
+ widget
73
+ });
69
74
  }
70
75
  function renderTitle() {
71
- return (0, import_vue.h)(import_components.WidgetTitleView, { key: id, widget });
76
+ return vue.h(index.WidgetTitleView, {
77
+ key: id,
78
+ widget
79
+ });
72
80
  }
73
81
  const widget = {
74
82
  id,
@@ -80,7 +88,7 @@ function useWidget(config, container, skeleton) {
80
88
  active,
81
89
  focused,
82
90
  container,
83
- pane,
91
+ pane: pane$1,
84
92
  focusable,
85
93
  event: skeleton.event,
86
94
  renderBody,
@@ -88,16 +96,21 @@ function useWidget(config, container, skeleton) {
88
96
  renderTitle
89
97
  };
90
98
  props?.onInit?.(widget);
99
+
100
+ // Emit view-mode-changed events
91
101
  if (skeleton?.event) {
92
- (0, import_vue.watch)(
93
- () => pane.viewMode.value,
94
- (mode) => {
95
- skeleton.event.emitGlobal(`widget:${name}:view-mode-changed`, { widget, mode });
96
- }
97
- );
102
+ vue.watch(() => pane$1.viewMode.value, mode => {
103
+ skeleton.event.emitGlobal(`widget:${name}:view-mode-changed`, {
104
+ widget,
105
+ mode
106
+ });
107
+ });
98
108
  }
99
109
  return widget;
100
110
  }
101
111
  function isWidget(obj) {
102
112
  return obj && obj.isWidget;
103
113
  }
114
+
115
+ exports.isWidget = isWidget;
116
+ exports.useWidget = useWidget;
@@ -1,16 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
- var config_exports = {};
16
- module.exports = __toCommonJS(config_exports);
1
+ 'use strict';
2
+
@@ -1,18 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
- var types_exports = {};
17
- module.exports = __toCommonJS(types_exports);
18
- __reExport(types_exports, require("./config"), module.exports);
1
+ 'use strict';
2
+
@@ -1,16 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
- var locale_exports = {};
16
- module.exports = __toCommonJS(locale_exports);
1
+ 'use strict';
2
+
@@ -1,63 +1,59 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var event_bus_exports = {};
30
- __export(event_bus_exports, {
31
- createPluginEventBus: () => createPluginEventBus,
32
- emitSystemEvent: () => emitSystemEvent,
33
- getGlobalEmitter: () => getGlobalEmitter,
34
- onSystemEvent: () => onSystemEvent
35
- });
36
- module.exports = __toCommonJS(event_bus_exports);
37
- var import_eventemitter2 = __toESM(require("eventemitter2"), 1);
38
- const globalEmitter = new import_eventemitter2.default({
1
+ 'use strict';
2
+
3
+ var EventEmitter2 = require('eventemitter2');
4
+
5
+ // =================================================================
6
+ // event-bus.ts 基于 EventEmitter2 的插件事件总线
7
+ //
8
+ // 利用 EventEmitter2 的三个核心特性:
9
+ // 1. wildcard: true 支持 'terminal:*' 订阅整个命名空间
10
+ // 2. delimiter: ':' → 'namespace:event' 格式的原生支持
11
+ // 3. listener.off() → 订阅返回 Listener 对象,无需手动传 handler 引用
12
+ // =================================================================
13
+
14
+
15
+ // ── 全局总线单例(所有插件共享,跨插件通信用)──────────────────────
16
+ //
17
+ // wildcard + delimiter 让命名空间隔离变成原生能力:
18
+ // - 插件 A 订阅 'terminal:*' 可以收到所有 terminal 前缀的事件
19
+ // - 全局订阅 '**' 可以监听所有事件(调试用)
20
+ // - maxListeners 设大一点,避免大量插件时出现警告
21
+
22
+ const globalEmitter = new EventEmitter2({
39
23
  wildcard: true,
40
24
  // 开启通配符
41
- delimiter: ":",
25
+ delimiter: ':',
42
26
  // 命名空间分隔符,与原版 createModuleEventBus 保持一致
43
27
  newListener: false,
44
28
  // 不触发 newListener 事件,减少不必要开销
45
29
  maxListeners: 200,
46
30
  // 对标原版 createModuleEventBus(pluginName, 200) 的容量参数
47
- verboseMemoryLeak: true
48
- // 超出 maxListeners 时打印详细的内存泄漏警告
31
+ verboseMemoryLeak: true // 超出 maxListeners 时打印详细的内存泄漏警告
49
32
  });
33
+ // ── 插件私有事件总线工厂函数 ──────────────────────────────────────
34
+ //
35
+ // 每个插件获得一个独立的 emitter 实例(私有事件不污染全局),
36
+ // 同时持有 globalEmitter 引用用于跨插件通信。
37
+ //
38
+ // 命名规则:
39
+ // ctx.event.emit('data-loaded') → 实际发出 'terminal:data-loaded'(自动加前缀)
40
+ // ctx.event.on('data-loaded', fn) → 订阅 'terminal:data-loaded'
41
+ // ctx.event.onGlobal('layout:*', fn) → 订阅全局总线上所有 layout 事件(wildcard)
42
+ // ctx.event.emitGlobal('layout:ready')→ 向全局总线发出事件,所有插件都能收到
43
+
50
44
  function createPluginEventBus(namespace) {
51
- const privateEmitter = new import_eventemitter2.default({
45
+ // 每个插件自己的私有 emitter(同样开启 wildcard)
46
+ const privateEmitter = new EventEmitter2({
52
47
  wildcard: true,
53
- delimiter: ":",
48
+ delimiter: ':',
54
49
  newListener: false,
55
50
  maxListeners: 200,
56
51
  verboseMemoryLeak: true
57
52
  });
58
- const prefixed = (event) => `${namespace}:${event}`;
53
+ const prefixed = event => `${namespace}:${event}`;
59
54
  return {
60
55
  // ── 私有事件(自动加 namespace 前缀)──────────────────────────
56
+
61
57
  emit(event, payload) {
62
58
  privateEmitter.emit(prefixed(event), payload);
63
59
  },
@@ -67,11 +63,9 @@ function createPluginEventBus(namespace) {
67
63
  * 无需调用方保存 handler 引用。
68
64
  */
69
65
  on(event, handler) {
70
- const listener = privateEmitter.on(
71
- prefixed(event),
72
- handler,
73
- { objectify: true }
74
- // 返回 Listener 对象而非 emitter 本身
66
+ const listener = privateEmitter.on(prefixed(event), handler, {
67
+ objectify: true
68
+ } // 返回 Listener 对象而非 emitter 本身
75
69
  );
76
70
  return () => listener.off();
77
71
  },
@@ -88,6 +82,7 @@ function createPluginEventBus(namespace) {
88
82
  return () => listener.off();
89
83
  },
90
84
  // ── 全局事件(跨插件通信,走 globalEmitter)────────────────────
85
+
91
86
  emitGlobal(event, payload) {
92
87
  globalEmitter.emit(event, payload);
93
88
  },
@@ -131,6 +126,7 @@ function createPluginEventBus(namespace) {
131
126
  });
132
127
  },
133
128
  // ── 清理(插件 destroy 时调用)─────────────────────────────────
129
+
134
130
  /**
135
131
  * 移除该插件私有 emitter 上的所有监听器。
136
132
  * 全局监听器需要单独 offGlobal(插件应在 teardown 中手动清理)。
@@ -140,6 +136,9 @@ function createPluginEventBus(namespace) {
140
136
  }
141
137
  };
142
138
  }
139
+
140
+ // ── 系统级全局事件工具函数(PluginManager 使用)────────────────────
141
+
143
142
  function emitSystemEvent(event, payload) {
144
143
  globalEmitter.emit(event, payload);
145
144
  }
@@ -152,3 +151,8 @@ function onSystemEvent(event, handler) {
152
151
  function getGlobalEmitter() {
153
152
  return globalEmitter;
154
153
  }
154
+
155
+ exports.createPluginEventBus = createPluginEventBus;
156
+ exports.emitSystemEvent = emitSystemEvent;
157
+ exports.getGlobalEmitter = getGlobalEmitter;
158
+ exports.onSystemEvent = onSystemEvent;
@@ -1,81 +1,79 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
- var focus_tracker_exports = {};
22
- __export(focus_tracker_exports, {
23
- FocusTracker: () => FocusTracker,
24
- Focusable: () => Focusable
25
- });
26
- module.exports = __toCommonJS(focus_tracker_exports);
1
+ 'use strict';
2
+
3
+ /**
4
+ * 焦点追踪器 — 维护一个焦点栈,管理 Popup/Dropdown 等弹出层的点击外部关闭、ESC 关闭等行为。
5
+ *
6
+ * 核心概念:
7
+ * - actives 是一个栈(active/unshift),栈顶(first)是当前聚焦的 Focusable
8
+ * - modal Focusable 打开时会阻止非 modal 的上层焦点失焦
9
+ * - mount() document 上监听 click,点击栈顶 Focusable 范围外时触发 blur
10
+ */
27
11
  class FocusTracker {
28
- constructor() {
29
- /** 焦点栈,栈顶为当前聚焦项 */
30
- __publicField(this, "actives", []);
31
- /** modal 弹层注册表,用于检查是否有 modal 正在打开 */
32
- __publicField(this, "modals", []);
33
- }
12
+ /** 焦点栈,栈顶为当前聚焦项 */
13
+ actives = [];
14
+
15
+ /** modal 弹层注册表,用于检查是否有 modal 正在打开 */
16
+ modals = [];
17
+
34
18
  /** 当前焦点栈顶 */
35
19
  get first() {
36
20
  return this.actives[0];
37
21
  }
22
+
38
23
  /** 注册一个 modal 弹层,用于 execSave 等时判断是否跳过 */
39
24
  addModal(checkDown, checkOpen) {
40
- this.modals.push({ checkDown, checkOpen });
25
+ this.modals.push({
26
+ checkDown,
27
+ checkOpen
28
+ });
41
29
  }
30
+
42
31
  /** 是否有 modal 弹层正在打开 */
43
32
  checkModalOpen() {
44
- return this.modals.some((item) => item.checkOpen());
33
+ return this.modals.some(item => item.checkOpen());
45
34
  }
35
+
46
36
  /** 触发保存操作,有 modal 时跳过 */
47
37
  execSave() {
48
38
  if (this.checkModalOpen()) return;
49
39
  if (this.first) this.first.internalTriggerSave();
50
40
  }
41
+
51
42
  /** 触发 ESC — 挂起栈顶并调用其 onEsc */
52
43
  execEsc() {
53
- const { first } = this;
44
+ const {
45
+ first
46
+ } = this;
54
47
  if (first) {
55
48
  this.internalSuspenseItem(first);
56
49
  first.internalTriggerEsc();
57
50
  }
58
51
  }
52
+
59
53
  /**
60
54
  * 挂载全局点击监听
61
55
  * 点击 document 时,如果点击目标不在 first 的 range 内,则挂起 first 并触发 blur
62
56
  * @returns 卸载函数
63
57
  */
64
58
  mount(win) {
65
- const checkDown = (e) => {
66
- const { first } = this;
59
+ const checkDown = e => {
60
+ const {
61
+ first
62
+ } = this;
67
63
  if (first && !first.internalCheckInRange(e)) {
68
64
  this.internalSuspenseItem(first);
69
65
  first.internalTriggerBlur();
70
66
  }
71
67
  };
72
- win.document.addEventListener("click", checkDown, true);
73
- return () => win.document.removeEventListener("click", checkDown, true);
68
+ win.document.addEventListener('click', checkDown, true);
69
+ return () => win.document.removeEventListener('click', checkDown, true);
74
70
  }
71
+
75
72
  /** 创建一个 Focusable 实例并绑定到当前 tracker */
76
73
  create(config) {
77
74
  return new Focusable(this, config);
78
75
  }
76
+
79
77
  /**
80
78
  * 激活一个 Focusable — 将其推到栈顶
81
79
  * 如果栈顶已有其他 Focusable 且新项不是 modal,则先触发旧栈顶的 blur
@@ -89,6 +87,7 @@ class FocusTracker {
89
87
  if (!item.isModal && first) first.internalTriggerBlur();
90
88
  item.internalTriggerActive();
91
89
  }
90
+
92
91
  /**
93
92
  * 挂起一个 Focusable — 将其从栈中移除
94
93
  * 移除后如果还有剩余项,激活新的栈顶
@@ -101,40 +100,60 @@ class FocusTracker {
101
100
  }
102
101
  }
103
102
  }
103
+
104
+ /** Focusable 的创建配置 */
105
+
106
+ /**
107
+ * 可聚焦项 — 代表一个弹出层(Popup/Dropdown 等)的焦点状态
108
+ *
109
+ * 使用方式:
110
+ * 1. tracker.create(config) 创建 Focusable
111
+ * 2. 弹出层打开时调用 focusable.active() 推入栈顶
112
+ * 3. 弹出层关闭时调用 focusable.suspense() 或 purge() 移出栈
113
+ * 4. 需要在组件挂载后调用 setRange() 注入真实 DOM
114
+ */
104
115
  class Focusable {
105
116
  constructor(tracker, config) {
106
117
  this.tracker = tracker;
107
118
  this.config = config;
108
- __publicField(this, "isModal");
109
119
  this.isModal = config.modal ?? false;
110
120
  }
121
+
111
122
  /** 激活当前 Focusable,推入焦点栈顶 */
112
123
  active() {
113
124
  this.tracker.internalActiveItem(this);
114
125
  }
126
+
115
127
  /** 挂起当前 Focusable,从焦点栈移除 */
116
128
  suspense() {
117
129
  this.tracker.internalSuspenseItem(this);
118
130
  }
131
+
119
132
  /** 销毁当前 Focusable(同 suspense,语义化别名) */
120
133
  purge() {
121
134
  this.tracker.internalSuspenseItem(this);
122
135
  }
136
+
123
137
  /** 挂载后把真实 DOM 注入,使 range 的 contains 判断生效 */
124
138
  setRange(range) {
125
139
  this.config.range = range;
126
140
  }
141
+
127
142
  /** 检查点击事件是否在 range 范围内 */
128
143
  internalCheckInRange(e) {
129
- const { range } = this.config;
144
+ const {
145
+ range
146
+ } = this.config;
130
147
  if (!range) return false;
131
- if (typeof range === "function") return range(e);
148
+ if (typeof range === 'function') return range(e);
132
149
  return range.contains(e.target);
133
150
  }
151
+
134
152
  /** 触发失焦回调 */
135
153
  internalTriggerBlur() {
136
154
  this.config.onBlur?.();
137
155
  }
156
+
138
157
  /** 触发保存回调,返回 true 表示已处理 */
139
158
  internalTriggerSave() {
140
159
  if (this.config.onSave) {
@@ -143,12 +162,17 @@ class Focusable {
143
162
  }
144
163
  return false;
145
164
  }
165
+
146
166
  /** 触发 ESC 回调 */
147
167
  internalTriggerEsc() {
148
168
  this.config.onEsc?.();
149
169
  }
170
+
150
171
  /** 触发激活回调 */
151
172
  internalTriggerActive() {
152
173
  this.config.onActive?.();
153
174
  }
154
175
  }
176
+
177
+ exports.FocusTracker = FocusTracker;
178
+ exports.Focusable = Focusable;
@@ -1,31 +1,23 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
- var utils_exports = {};
21
- __export(utils_exports, {
22
- enUS: () => import_locales.enUS,
23
- getBuiltInLocale: () => import_locales.getBuiltInLocale,
24
- zhCN: () => import_locales.zhCN
25
- });
26
- module.exports = __toCommonJS(utils_exports);
27
- __reExport(utils_exports, require("./vue"), module.exports);
28
- __reExport(utils_exports, require("./unique-id"), module.exports);
29
- __reExport(utils_exports, require("./focus-tracker"), module.exports);
30
- __reExport(utils_exports, require("./event-bus"), module.exports);
31
- var import_locales = require("../locales");
1
+ 'use strict';
2
+
3
+ var vue = require('./vue.cjs');
4
+ var uniqueId = require('./unique-id.cjs');
5
+ var focusTracker = require('./focus-tracker.cjs');
6
+ var eventBus = require('./event-bus.cjs');
7
+ var index = require('../locales/index.cjs');
8
+ var enUS = require('../locales/en-US.cjs');
9
+ var zhCN = require('../locales/zh-CN.cjs');
10
+
11
+
12
+
13
+ exports.createContent = vue.createContent;
14
+ exports.uniqueId = uniqueId.uniqueId;
15
+ exports.FocusTracker = focusTracker.FocusTracker;
16
+ exports.Focusable = focusTracker.Focusable;
17
+ exports.createPluginEventBus = eventBus.createPluginEventBus;
18
+ exports.emitSystemEvent = eventBus.emitSystemEvent;
19
+ exports.getGlobalEmitter = eventBus.getGlobalEmitter;
20
+ exports.onSystemEvent = eventBus.onSystemEvent;
21
+ exports.getBuiltInLocale = index.getBuiltInLocale;
22
+ exports.enUS = enUS.enUS;
23
+ exports.zhCN = zhCN.zhCN;