@composy/keyboard-vue 0.0.1 → 0.0.2

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 (172) hide show
  1. package/README.md +48 -24
  2. package/dist/index.css +552 -560
  3. package/dist/index.js +228 -192
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.css +1 -1
  6. package/dist/index.min.js +954 -1
  7. package/dist/index.min.js.map +1 -0
  8. package/es/.dts-output-manifest.json +1 -0
  9. package/es/.dts.tsbuildinfo +1 -0
  10. package/es/components/KeyboardKey.js +1 -1
  11. package/es/components/KeyboardKey.js.map +1 -1
  12. package/es/components/KeyboardKey.vue_vue_type_script_setup_true_lang.js +16 -7
  13. package/es/components/KeyboardKey.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/es/components/KeyboardPopup.js +1 -1
  15. package/es/components/KeyboardPopup.js.map +1 -1
  16. package/es/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.js +8 -5
  17. package/es/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/es/components/LicensePlateKeyboard.js +1 -1
  19. package/es/components/LicensePlateKeyboard.js.map +1 -1
  20. package/es/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.js +2 -2
  21. package/es/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/es/components/VirtualKeyboard.js +1 -1
  23. package/es/components/VirtualKeyboard.js.map +1 -1
  24. package/es/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.js +4 -4
  25. package/es/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/es/components/index.d.ts +1 -2
  27. package/es/components/index.d.ts.map +1 -1
  28. package/es/components/index.js +1 -1
  29. package/es/composables/index.d.ts +0 -1
  30. package/es/composables/index.js +1 -1
  31. package/es/composables/useKeyboard.d.ts +1 -2
  32. package/es/composables/useKeyboard.d.ts.map +1 -1
  33. package/es/composables/useKeyboard.js +8 -15
  34. package/es/composables/useKeyboard.js.map +1 -1
  35. package/es/composables/useKeyboardPopup.d.ts +2 -51
  36. package/es/composables/useKeyboardPopup.d.ts.map +1 -1
  37. package/es/composables/useKeyboardPopup.js +66 -49
  38. package/es/composables/useKeyboardPopup.js.map +1 -1
  39. package/es/directives/index.d.ts +0 -1
  40. package/es/directives/index.js +1 -1
  41. package/es/directives/v-keyboard.d.ts +0 -1
  42. package/es/directives/v-keyboard.d.ts.map +1 -1
  43. package/es/directives/v-keyboard.js +10 -11
  44. package/es/directives/v-keyboard.js.map +1 -1
  45. package/es/index.d.ts +3 -4
  46. package/es/index.d.ts.map +1 -1
  47. package/es/index.js +2 -5
  48. package/es/index.js.map +1 -1
  49. package/es/plugins/engine-plugin.d.ts +0 -1
  50. package/es/plugins/engine-plugin.d.ts.map +1 -1
  51. package/es/plugins/engine-plugin.js +19 -4
  52. package/es/plugins/engine-plugin.js.map +1 -1
  53. package/es/plugins/index.d.ts +0 -1
  54. package/es/plugins/index.js +1 -1
  55. package/es/style/css.js +1 -1
  56. package/es/style/index.css +2 -0
  57. package/es/style/index.js +1 -1
  58. package/es/styles/index.css +391 -0
  59. package/es/styles/keyboard.css +252 -0
  60. package/es/styles/themes.css +137 -0
  61. package/esm/components/KeyboardKey.js +17 -0
  62. package/esm/components/KeyboardKey.js.map +1 -0
  63. package/esm/components/KeyboardKey.vue_vue_type_script_setup_true_lang.js +140 -0
  64. package/esm/components/KeyboardKey.vue_vue_type_script_setup_true_lang.js.map +1 -0
  65. package/esm/components/KeyboardPopup.js +17 -0
  66. package/esm/components/KeyboardPopup.js.map +1 -0
  67. package/esm/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.js +167 -0
  68. package/esm/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  69. package/esm/components/LicensePlateKeyboard.js +17 -0
  70. package/esm/components/LicensePlateKeyboard.js.map +1 -0
  71. package/esm/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.js +97 -0
  72. package/esm/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  73. package/esm/components/VirtualKeyboard.js +17 -0
  74. package/esm/components/VirtualKeyboard.js.map +1 -0
  75. package/esm/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.js +127 -0
  76. package/esm/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  77. package/{lib → esm}/components/index.d.ts +1 -1
  78. package/esm/components/index.d.ts.map +1 -0
  79. package/esm/components/index.js +15 -0
  80. package/esm/composables/index.d.ts.map +1 -0
  81. package/esm/composables/index.js +13 -0
  82. package/{lib → esm}/composables/useKeyboard.d.ts +1 -1
  83. package/esm/composables/useKeyboard.d.ts.map +1 -0
  84. package/esm/composables/useKeyboard.js +68 -0
  85. package/esm/composables/useKeyboard.js.map +1 -0
  86. package/esm/composables/useKeyboardPopup.d.ts +25 -0
  87. package/esm/composables/useKeyboardPopup.d.ts.map +1 -0
  88. package/esm/composables/useKeyboardPopup.js +136 -0
  89. package/esm/composables/useKeyboardPopup.js.map +1 -0
  90. package/esm/directives/index.d.ts.map +1 -0
  91. package/esm/directives/index.js +12 -0
  92. package/esm/directives/v-keyboard.d.ts.map +1 -0
  93. package/esm/directives/v-keyboard.js +64 -0
  94. package/esm/directives/v-keyboard.js.map +1 -0
  95. package/esm/index.d.ts +42 -0
  96. package/esm/index.d.ts.map +1 -0
  97. package/esm/index.js +34 -0
  98. package/esm/index.js.map +1 -0
  99. package/esm/plugins/engine-plugin.d.ts.map +1 -0
  100. package/esm/plugins/engine-plugin.js +53 -0
  101. package/esm/plugins/engine-plugin.js.map +1 -0
  102. package/esm/plugins/index.d.ts.map +1 -0
  103. package/esm/plugins/index.js +12 -0
  104. package/esm/style/css.js +1 -0
  105. package/esm/style/index.js +1 -0
  106. package/{es → esm}/style/index.less +1 -1
  107. package/esm/styles/index.less +5 -0
  108. package/esm/styles/keyboard.less +286 -0
  109. package/esm/styles/themes.less +164 -0
  110. package/lib/components/KeyboardKey.cjs +1 -1
  111. package/lib/components/KeyboardKey.cjs.map +1 -1
  112. package/lib/components/KeyboardKey.vue_vue_type_script_setup_true_lang.cjs +16 -7
  113. package/lib/components/KeyboardKey.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  114. package/lib/components/KeyboardPopup.cjs +1 -1
  115. package/lib/components/KeyboardPopup.cjs.map +1 -1
  116. package/lib/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.cjs +8 -5
  117. package/lib/components/KeyboardPopup.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  118. package/lib/components/LicensePlateKeyboard.cjs +1 -1
  119. package/lib/components/LicensePlateKeyboard.cjs.map +1 -1
  120. package/lib/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.cjs +2 -2
  121. package/lib/components/LicensePlateKeyboard.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  122. package/lib/components/VirtualKeyboard.cjs +1 -1
  123. package/lib/components/VirtualKeyboard.cjs.map +1 -1
  124. package/lib/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.cjs +4 -4
  125. package/lib/components/VirtualKeyboard.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  126. package/lib/components/index.cjs +1 -1
  127. package/lib/components/index.d.cts +8 -0
  128. package/lib/components/index.d.cts.map +1 -0
  129. package/lib/composables/index.cjs +1 -1
  130. package/lib/composables/index.d.cts +6 -0
  131. package/lib/composables/index.d.cts.map +1 -0
  132. package/lib/composables/useKeyboard.cjs +8 -15
  133. package/lib/composables/useKeyboard.cjs.map +1 -1
  134. package/lib/composables/useKeyboard.d.cts +112 -0
  135. package/lib/composables/useKeyboard.d.cts.map +1 -0
  136. package/lib/composables/useKeyboardPopup.cjs +66 -49
  137. package/lib/composables/useKeyboardPopup.cjs.map +1 -1
  138. package/lib/composables/useKeyboardPopup.d.cts +24 -0
  139. package/lib/composables/useKeyboardPopup.d.cts.map +1 -0
  140. package/lib/directives/index.cjs +1 -1
  141. package/lib/directives/index.d.cts +5 -0
  142. package/lib/directives/index.d.cts.map +1 -0
  143. package/lib/directives/v-keyboard.cjs +10 -11
  144. package/lib/directives/v-keyboard.cjs.map +1 -1
  145. package/lib/directives/v-keyboard.d.cts +35 -0
  146. package/lib/directives/v-keyboard.d.cts.map +1 -0
  147. package/lib/index.cjs +2 -2
  148. package/lib/index.cjs.map +1 -1
  149. package/lib/index.d.cts +41 -0
  150. package/lib/index.d.cts.map +1 -0
  151. package/lib/plugins/engine-plugin.cjs +19 -3
  152. package/lib/plugins/engine-plugin.cjs.map +1 -1
  153. package/lib/plugins/engine-plugin.d.cts +36 -0
  154. package/lib/plugins/engine-plugin.d.cts.map +1 -0
  155. package/lib/plugins/index.cjs +1 -1
  156. package/lib/plugins/index.d.cts +5 -0
  157. package/lib/plugins/index.d.cts.map +1 -0
  158. package/lib/style/index.css +1 -1
  159. package/lib/styles/index.css +357 -195
  160. package/lib/styles/keyboard.css +92 -186
  161. package/lib/styles/themes.css +102 -178
  162. package/package.json +43 -34
  163. package/es/styles/index.less +0 -267
  164. package/es/styles/keyboard.less +0 -399
  165. package/es/styles/themes.less +0 -233
  166. package/lib/composables/useKeyboardPopup.d.ts +0 -73
  167. package/lib/index.d.ts +0 -42
  168. /package/{lib → esm}/composables/index.d.ts +0 -0
  169. /package/{lib → esm}/directives/index.d.ts +0 -0
  170. /package/{lib → esm}/directives/v-keyboard.d.ts +0 -0
  171. /package/{lib → esm}/plugins/engine-plugin.d.ts +0 -0
  172. /package/{lib → esm}/plugins/index.d.ts +0 -0
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * ***********************************
3
3
  * @composy/keyboard-vue v0.0.1 *
4
4
  * Built with rollup *
5
- * Build time: 2024-08-17 11:42:14 *
5
+ * Build time: 2024-10-12 17:44:16 *
6
6
  * Build mode: production *
7
7
  * Minified: No *
8
8
  * ***********************************
@@ -12,7 +12,7 @@
12
12
  "exports",
13
13
  "vue",
14
14
  "@composy/keyboard-core"
15
- ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LDesignPackagesVue3 = {}, global.Vue, global.ComposyKeyboardCore));
15
+ ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LDesignKeyboardVue = {}, global.Vue, global.ComposyKeyboardCore));
16
16
  })(this, function(exports, vue, _composy_keyboard_core) {
17
17
  Object.defineProperties(exports, {
18
18
  __esModule: { value: true },
@@ -27,6 +27,10 @@
27
27
  };
28
28
  const _hoisted_4$2 = {
29
29
  key: 2,
30
+ class: "keyboard-key__label"
31
+ };
32
+ const _hoisted_5$1 = {
33
+ key: 3,
30
34
  class: "keyboard-key__arrow-inline"
31
35
  };
32
36
  var KeyboardKey_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -58,6 +62,10 @@
58
62
  if (typeof keyLabel === "string") return keyLabel;
59
63
  return props.isUpperCase ? keyLabel.upper : keyLabel.lower;
60
64
  });
65
+ const iconMarkup = (0, vue.computed)(() => {
66
+ const icon = props.keyDef.icon;
67
+ return icon ? (0, _composy_keyboard_core.sanitizeSvgIcon)(icon) : "";
68
+ });
61
69
  const keyWidth = (0, vue.computed)(() => {
62
70
  if (props.useFlex) return;
63
71
  const base = props.baseWidth ?? 36;
@@ -86,7 +94,7 @@
86
94
  event.stopPropagation();
87
95
  if (props.keyDef.disabled) return;
88
96
  if (isOptionsOnly.value) {
89
- emit("showOptions", props.keyDef.options);
97
+ emit("showOptions", props.keyDef.options ?? []);
90
98
  return;
91
99
  }
92
100
  emit("press", props.keyDef);
@@ -95,7 +103,7 @@
95
103
  event.preventDefault();
96
104
  event.stopPropagation();
97
105
  if (props.keyDef.disabled) return;
98
- if (hasOptions.value) emit("showOptions", props.keyDef.options);
106
+ if (hasOptions.value) emit("showOptions", props.keyDef.options ?? []);
99
107
  };
100
108
  return (_ctx, _cache) => {
101
109
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
@@ -116,13 +124,13 @@
116
124
  onTouchstart: (0, vue.withModifiers)(handlePress, ["prevent"])
117
125
  }, [
118
126
  (0, vue.createCommentVNode)(" SVG 图标支持 "),
119
- __props.keyDef.icon ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
127
+ iconMarkup.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
120
128
  key: 0,
121
129
  class: "keyboard-key__icon",
122
- innerHTML: __props.keyDef.icon
123
- }, null, 8, _hoisted_2$2)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$2, (0, vue.toDisplayString)(label.value), 1)),
130
+ innerHTML: iconMarkup.value
131
+ }, null, 8, _hoisted_2$2)) : __props.keyDef.icon ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$2, (0, vue.toDisplayString)(__props.keyDef.icon), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$2, (0, vue.toDisplayString)(label.value), 1)),
124
132
  (0, vue.createCommentVNode)(" 纯选项按钮内嵌下拉箭头 "),
125
- isOptionsOnly.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$2, "▼")) : (0, vue.createCommentVNode)("v-if", true)
133
+ isOptionsOnly.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$1, "▼")) : (0, vue.createCommentVNode)("v-if", true)
126
134
  ], 42, _hoisted_1$2),
127
135
  (0, vue.createCommentVNode)(" 有value又有options的按钮:单独可点击的下拉箭头 "),
128
136
  hasOptions.value && !isOptionsOnly.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
@@ -140,6 +148,182 @@
140
148
  KeyboardKey_vue_vue_type_script_setup_true_lang_default.__file = "src/components/KeyboardKey.vue";
141
149
  var KeyboardKey_default = KeyboardKey_vue_vue_type_script_setup_true_lang_default;
142
150
  //#endregion
151
+ //#region src/composables/useKeyboard.ts
152
+ function useKeyboard(options = {}) {
153
+ const { immediate = false, ...keyboardOptions } = options;
154
+ const manager = (0, _composy_keyboard_core.createKeyboardManager)(keyboardOptions);
155
+ const initialState = manager.getState();
156
+ const visible = (0, vue.ref)(initialState.visible);
157
+ const type = (0, vue.ref)(initialState.type);
158
+ const isUpperCase = (0, vue.ref)(initialState.isUpperCase);
159
+ const value = (0, vue.ref)(initialState.value);
160
+ const cursorPosition = (0, vue.ref)(initialState.cursorPosition);
161
+ const layout = (0, vue.shallowRef)(manager.getLayout());
162
+ const state = (0, vue.reactive)({ ...initialState });
163
+ const syncState = (newState) => {
164
+ visible.value = newState.visible;
165
+ type.value = newState.type;
166
+ isUpperCase.value = newState.isUpperCase;
167
+ value.value = newState.value;
168
+ cursorPosition.value = newState.cursorPosition;
169
+ Object.assign(state, newState);
170
+ };
171
+ manager.on("stateChange", syncState);
172
+ manager.on("switch", () => {
173
+ layout.value = manager.getLayout();
174
+ });
175
+ if (immediate) manager.show();
176
+ (0, vue.onBeforeUnmount)(() => {
177
+ manager.destroy();
178
+ });
179
+ return {
180
+ visible,
181
+ type,
182
+ isUpperCase,
183
+ value,
184
+ cursorPosition,
185
+ layout,
186
+ state,
187
+ show: (input) => manager.show(input),
188
+ hide: () => manager.hide(),
189
+ toggle: (input) => manager.toggle(input),
190
+ switchType: (t) => manager.switchType(t),
191
+ toggleShift: () => manager.toggleShift(),
192
+ handleKey: (key) => manager.handleKey(key),
193
+ getKeyLabel: (key) => manager.getKeyLabel(key),
194
+ setValue: (v) => manager.setValue(v),
195
+ appendValue: (text) => manager.appendValue(text),
196
+ setMaxLength: (maxLength) => manager.setMaxLength(maxLength),
197
+ bindInput: (input) => manager.bindInput(input),
198
+ unbindInput: () => manager.unbindInput(),
199
+ on: (event, handler) => manager.on(event, handler),
200
+ once: (event, handler) => manager.once(event, handler),
201
+ destroy: () => manager.destroy()
202
+ };
203
+ }
204
+ //#endregion
205
+ //#region src/composables/useKeyboardPopup.ts
206
+ function useKeyboardPopup(options = {}) {
207
+ const { visible = (0, vue.ref)(false), target = (0, vue.ref)(null), popup = (0, vue.ref)(null), closeOnClickOutside = true, onClose, ...positionConfig } = options;
208
+ const positionManager = (0, _composy_keyboard_core.createPositionManager)(positionConfig);
209
+ const popupStyles = (0, vue.ref)({});
210
+ const maskStyles = (0, vue.ref)({});
211
+ const placement = (0, vue.ref)("bottom");
212
+ const isMobileDevice = (0, vue.ref)((0, _composy_keyboard_core.isMobile)());
213
+ const showMask = (0, vue.ref)(false);
214
+ const isAnimating = (0, vue.ref)(false);
215
+ let cleanupClickOutside = null;
216
+ let cleanupViewportChange = null;
217
+ let cleanupScroll = null;
218
+ let animationFrame = null;
219
+ let visibilitySession = 0;
220
+ const cleanupOpenResources = () => {
221
+ cleanupClickOutside?.();
222
+ cleanupClickOutside = null;
223
+ cleanupViewportChange?.();
224
+ cleanupViewportChange = null;
225
+ cleanupScroll?.();
226
+ cleanupScroll = null;
227
+ };
228
+ const cancelAnimationFrame = () => {
229
+ if (animationFrame === null || typeof window === "undefined") return;
230
+ window.cancelAnimationFrame(animationFrame);
231
+ animationFrame = null;
232
+ };
233
+ const updatePosition = () => {
234
+ const popupElement = popup.value;
235
+ if (!popupElement) return;
236
+ const popupRect = popupElement.getBoundingClientRect();
237
+ const result = positionManager.calculate(target.value, {
238
+ width: Math.max(0, popupRect.width),
239
+ height: Math.max(0, popupRect.height)
240
+ });
241
+ placement.value = result.placement;
242
+ showMask.value = positionManager.shouldShowMask();
243
+ if (result.placement === "bottom-sheet") popupStyles.value = {
244
+ position: "fixed",
245
+ left: "0",
246
+ right: "0",
247
+ bottom: "0",
248
+ maxHeight: result.maxHeight === void 0 ? void 0 : `${result.maxHeight}px`,
249
+ zIndex: 1e3
250
+ };
251
+ else popupStyles.value = {
252
+ position: "fixed",
253
+ left: `${result.position.x}px`,
254
+ top: `${result.position.y}px`,
255
+ maxHeight: result.maxHeight === void 0 ? void 0 : `${result.maxHeight}px`,
256
+ maxWidth: result.maxWidth === void 0 ? void 0 : `${result.maxWidth}px`,
257
+ zIndex: 1e3
258
+ };
259
+ maskStyles.value = showMask.value ? {
260
+ position: "fixed",
261
+ inset: "0",
262
+ backgroundColor: "var(--keyboard-mask-bg)",
263
+ zIndex: 999
264
+ } : {};
265
+ };
266
+ const close = () => {
267
+ if (visible.value) onClose?.();
268
+ };
269
+ (0, vue.watch)(visible, (newVisible) => {
270
+ visibilitySession += 1;
271
+ const currentSession = visibilitySession;
272
+ cancelAnimationFrame();
273
+ cleanupOpenResources();
274
+ if (!newVisible) {
275
+ isAnimating.value = false;
276
+ showMask.value = false;
277
+ popupStyles.value = {};
278
+ maskStyles.value = {};
279
+ return;
280
+ }
281
+ isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
282
+ isAnimating.value = true;
283
+ if (typeof window !== "undefined") animationFrame = window.requestAnimationFrame(() => {
284
+ animationFrame = null;
285
+ if (!visible.value || currentSession !== visibilitySession) return;
286
+ updatePosition();
287
+ isAnimating.value = false;
288
+ if (closeOnClickOutside && popup.value) cleanupClickOutside = (0, _composy_keyboard_core.onClickOutside)(popup.value, (event) => {
289
+ if (target.value && event.target instanceof Node && target.value.contains(event.target)) return;
290
+ close();
291
+ });
292
+ });
293
+ cleanupViewportChange = (0, _composy_keyboard_core.onViewportChange)(() => {
294
+ if (!visible.value) return;
295
+ isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
296
+ updatePosition();
297
+ });
298
+ if (!isMobileDevice.value && typeof window !== "undefined") {
299
+ const handleScroll = () => {
300
+ if (!visible.value) return;
301
+ window.requestAnimationFrame(updatePosition);
302
+ };
303
+ window.addEventListener("scroll", handleScroll, true);
304
+ cleanupScroll = () => window.removeEventListener("scroll", handleScroll, true);
305
+ }
306
+ }, { immediate: true });
307
+ (0, vue.watch)(target, () => {
308
+ if (visible.value) updatePosition();
309
+ });
310
+ (0, vue.onBeforeUnmount)(() => {
311
+ visibilitySession += 1;
312
+ cancelAnimationFrame();
313
+ cleanupOpenResources();
314
+ });
315
+ return {
316
+ popupStyles,
317
+ maskStyles,
318
+ placement,
319
+ isMobileDevice,
320
+ showMask,
321
+ isAnimating,
322
+ updatePosition,
323
+ close
324
+ };
325
+ }
326
+ //#endregion
143
327
  //#region src/components/VirtualKeyboard.vue?vue&type=script&setup=true&lang.ts
144
328
  const _hoisted_1$1 = { class: "virtual-keyboard" };
145
329
  const _hoisted_2$1 = {
@@ -202,7 +386,7 @@
202
386
  const closeOptionsPanel = () => {
203
387
  showOptionsPanel.value = false;
204
388
  };
205
- const getRowStyle = (rowIndex) => {
389
+ const getRowStyle = () => {
206
390
  return {};
207
391
  };
208
392
  return (_ctx, _cache) => {
@@ -211,7 +395,7 @@
211
395
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
212
396
  key: rowIndex,
213
397
  class: (0, vue.normalizeClass)(["virtual-keyboard__row", row.className]),
214
- style: (0, vue.normalizeStyle)(getRowStyle(rowIndex))
398
+ style: (0, vue.normalizeStyle)(getRowStyle())
215
399
  }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(row.keys, (key) => {
216
400
  return (0, vue.openBlock)(), (0, vue.createBlock)(KeyboardKey_default, {
217
401
  key: key.id,
@@ -228,7 +412,7 @@
228
412
  "use-flex"
229
413
  ]);
230
414
  }), 128))], 6);
231
- }), 128)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$1, " 键盘布局未找到 ")),
415
+ }), 128)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$1, "键盘布局未找到")),
232
416
  (0, vue.createCommentVNode)(" 选项面板 "),
233
417
  (0, vue.createVNode)(vue.Transition, { name: "options-panel" }, {
234
418
  default: (0, vue.withCtx)(() => [showOptionsPanel.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_3$1, [(0, vue.createElementVNode)("div", _hoisted_4$1, [_cache[0] || (_cache[0] = (0, vue.createElementVNode)("span", { class: "keyboard-options-panel__title" }, "选择邮箱后缀", -1)), (0, vue.createElementVNode)("button", {
@@ -256,172 +440,6 @@
256
440
  VirtualKeyboard_vue_vue_type_script_setup_true_lang_default.__file = "src/components/VirtualKeyboard.vue";
257
441
  var VirtualKeyboard_default = VirtualKeyboard_vue_vue_type_script_setup_true_lang_default;
258
442
  //#endregion
259
- //#region src/composables/useKeyboard.ts
260
- function useKeyboard(options = {}) {
261
- const { immediate = false, ...keyboardOptions } = options;
262
- const manager = (0, _composy_keyboard_core.createKeyboardManager)(keyboardOptions);
263
- const visible = (0, vue.ref)(false);
264
- const type = (0, vue.ref)(keyboardOptions.type ?? "qwerty");
265
- const isUpperCase = (0, vue.ref)(keyboardOptions.defaultUpperCase ?? false);
266
- const value = (0, vue.ref)(keyboardOptions.value ?? "");
267
- const cursorPosition = (0, vue.ref)(keyboardOptions.value?.length ?? 0);
268
- const layout = (0, vue.shallowRef)(manager.getLayout());
269
- const state = (0, vue.reactive)({
270
- visible: false,
271
- type: keyboardOptions.type ?? "qwerty",
272
- isUpperCase: keyboardOptions.defaultUpperCase ?? false,
273
- value: keyboardOptions.value ?? "",
274
- cursorPosition: keyboardOptions.value?.length ?? 0,
275
- maxLength: keyboardOptions.maxLength,
276
- inputElement: null
277
- });
278
- const syncState = (newState) => {
279
- visible.value = newState.visible;
280
- type.value = newState.type;
281
- isUpperCase.value = newState.isUpperCase;
282
- value.value = newState.value;
283
- cursorPosition.value = newState.cursorPosition;
284
- Object.assign(state, newState);
285
- };
286
- manager.on("stateChange", syncState);
287
- manager.on("switch", () => {
288
- layout.value = manager.getLayout();
289
- });
290
- if (immediate) manager.show();
291
- (0, vue.onBeforeUnmount)(() => {
292
- manager.destroy();
293
- });
294
- return {
295
- visible,
296
- type,
297
- isUpperCase,
298
- value,
299
- cursorPosition,
300
- layout,
301
- state,
302
- show: (input) => manager.show(input),
303
- hide: () => manager.hide(),
304
- toggle: (input) => manager.toggle(input),
305
- switchType: (t) => manager.switchType(t),
306
- toggleShift: () => manager.toggleShift(),
307
- handleKey: (key) => manager.handleKey(key),
308
- getKeyLabel: (key) => manager.getKeyLabel(key),
309
- setValue: (v) => manager.setValue(v),
310
- appendValue: (text) => manager.appendValue(text),
311
- setMaxLength: (maxLength) => manager.setMaxLength(maxLength),
312
- bindInput: (input) => manager.bindInput(input),
313
- unbindInput: () => manager.unbindInput(),
314
- on: (event, handler) => manager.on(event, handler),
315
- once: (event, handler) => manager.once(event, handler),
316
- destroy: () => manager.destroy()
317
- };
318
- }
319
- //#endregion
320
- //#region src/composables/useKeyboardPopup.ts
321
- function useKeyboardPopup(options = {}) {
322
- const { visible = (0, vue.ref)(false), target = (0, vue.ref)(null), popup = (0, vue.ref)(null), closeOnClickOutside = true, onClose, ...positionConfig } = options;
323
- const positionManager = (0, _composy_keyboard_core.createPositionManager)(positionConfig);
324
- const popupStyles = (0, vue.ref)({});
325
- const maskStyles = (0, vue.ref)({});
326
- const placement = (0, vue.ref)("bottom");
327
- const isMobileDevice = (0, vue.ref)((0, _composy_keyboard_core.isMobile)());
328
- const showMask = (0, vue.ref)(false);
329
- const isAnimating = (0, vue.ref)(false);
330
- let cleanupClickOutside = null;
331
- let cleanupViewportChange = null;
332
- let cleanupScroll = null;
333
- const updatePosition = () => {
334
- if (!popup.value) return;
335
- const popupRect = popup.value.getBoundingClientRect();
336
- const result = positionManager.calculate(target.value, {
337
- width: popupRect.width || 300,
338
- height: popupRect.height || 260
339
- });
340
- placement.value = result.placement;
341
- showMask.value = positionManager.shouldShowMask();
342
- if (result.placement === "bottom-sheet") popupStyles.value = {
343
- position: "fixed",
344
- left: "0",
345
- right: "0",
346
- bottom: "0",
347
- maxHeight: `${result.maxHeight}px`,
348
- zIndex: 1e3
349
- };
350
- else popupStyles.value = {
351
- position: "fixed",
352
- left: `${result.position.x}px`,
353
- top: `${result.position.y}px`,
354
- maxHeight: result.maxHeight ? `${result.maxHeight}px` : void 0,
355
- maxWidth: result.maxWidth ? `${result.maxWidth}px` : void 0,
356
- zIndex: 1e3
357
- };
358
- if (showMask.value) maskStyles.value = {
359
- position: "fixed",
360
- top: "0",
361
- left: "0",
362
- right: "0",
363
- bottom: "0",
364
- backgroundColor: "rgba(0, 0, 0, 0.5)",
365
- zIndex: 999
366
- };
367
- };
368
- const close = () => {
369
- onClose?.();
370
- };
371
- (0, vue.watch)(visible, (newVisible) => {
372
- if (newVisible) {
373
- isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
374
- requestAnimationFrame(() => {
375
- updatePosition();
376
- if (closeOnClickOutside && popup.value) cleanupClickOutside = (0, _composy_keyboard_core.onClickOutside)(popup.value, (event) => {
377
- if (target.value && target.value.contains(event.target)) return;
378
- close();
379
- });
380
- });
381
- cleanupViewportChange = (0, _composy_keyboard_core.onViewportChange)(() => {
382
- isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
383
- updatePosition();
384
- });
385
- if (!isMobileDevice.value) {
386
- const handleScroll = () => {
387
- requestAnimationFrame(() => {
388
- updatePosition();
389
- });
390
- };
391
- window.addEventListener("scroll", handleScroll, true);
392
- cleanupScroll = () => {
393
- window.removeEventListener("scroll", handleScroll, true);
394
- };
395
- }
396
- } else {
397
- cleanupClickOutside?.();
398
- cleanupClickOutside = null;
399
- cleanupViewportChange?.();
400
- cleanupViewportChange = null;
401
- cleanupScroll?.();
402
- cleanupScroll = null;
403
- }
404
- }, { immediate: true });
405
- (0, vue.watch)(target, () => {
406
- if (visible.value) updatePosition();
407
- });
408
- (0, vue.onBeforeUnmount)(() => {
409
- cleanupClickOutside?.();
410
- cleanupViewportChange?.();
411
- cleanupScroll?.();
412
- });
413
- return {
414
- popupStyles,
415
- maskStyles,
416
- placement,
417
- isMobileDevice,
418
- showMask,
419
- isAnimating,
420
- updatePosition,
421
- close
422
- };
423
- }
424
- //#endregion
425
443
  //#region src/components/KeyboardPopup.vue?vue&type=script&setup=true&lang.ts
426
444
  var KeyboardPopup_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
427
445
  __name: "KeyboardPopup",
@@ -481,7 +499,7 @@
481
499
  const keyboard = useKeyboard({
482
500
  type: props.type,
483
501
  value: props.value,
484
- maxLength: props.maxLength || (props.type.startsWith("license-plate") ? 7 : void 0),
502
+ maxLength: props.maxLength ?? (props.type.startsWith("license-plate") ? 7 : void 0),
485
503
  enableVibrate: props.enableVibrate
486
504
  });
487
505
  const { popupStyles, maskStyles, placement, showMask, updatePosition, close: closePopup } = useKeyboardPopup({
@@ -497,6 +515,9 @@
497
515
  keyboard.switchType(newType);
498
516
  if (newType.startsWith("license-plate") && !props.maxLength) keyboard.setMaxLength(7);
499
517
  });
518
+ (0, vue.watch)(() => props.maxLength, (maxLength) => {
519
+ if (maxLength !== void 0) keyboard.setMaxLength(maxLength);
520
+ });
500
521
  (0, vue.watch)(() => props.value, (newValue) => {
501
522
  if (newValue !== keyboard.value.value) keyboard.setValue(newValue);
502
523
  });
@@ -512,7 +533,7 @@
512
533
  updatePosition();
513
534
  });
514
535
  } else keyboard.hide();
515
- });
536
+ }, { immediate: true });
516
537
  keyboard.on("confirm", ({ value }) => {
517
538
  emit("confirm", value);
518
539
  emit("update:modelValue", false);
@@ -527,7 +548,7 @@
527
548
  keyboard.appendValue(valueToAppend);
528
549
  };
529
550
  const handleMaskClick = () => {
530
- if (props.closeOnClickOutside) emit("update:modelValue", false);
551
+ if (props.closeOnClickOutside) closePopup();
531
552
  };
532
553
  const popupClass = (0, vue.computed)(() => {
533
554
  return [
@@ -660,7 +681,7 @@
660
681
  var LicensePlateKeyboard_default = LicensePlateKeyboard_vue_vue_type_script_setup_true_lang_default;
661
682
  //#endregion
662
683
  //#region src/directives/v-keyboard.ts
663
- const KEYBOARD_ATTR = "__v_keyboard__";
684
+ const directiveStates = /* @__PURE__ */ new WeakMap();
664
685
  const vKeyboard = {
665
686
  mounted(el, binding) {
666
687
  const options = parseBinding(binding);
@@ -671,14 +692,14 @@
671
692
  };
672
693
  el.addEventListener("focus", handleFocus);
673
694
  el.setAttribute("inputmode", "none");
674
- el[KEYBOARD_ATTR] = { cleanup: () => {
695
+ directiveStates.set(el, { cleanup: () => {
675
696
  el.removeEventListener("focus", handleFocus);
676
697
  el.removeAttribute("inputmode");
677
- } };
698
+ } });
678
699
  },
679
700
  updated(el, binding) {
680
- const oldCleanup = el[KEYBOARD_ATTR]?.cleanup;
681
- if (oldCleanup) oldCleanup();
701
+ directiveStates.get(el)?.cleanup();
702
+ directiveStates.delete(el);
682
703
  const options = parseBinding(binding);
683
704
  if (!options.enabled) return;
684
705
  const handleFocus = () => {
@@ -687,15 +708,14 @@
687
708
  };
688
709
  el.addEventListener("focus", handleFocus);
689
710
  el.setAttribute("inputmode", "none");
690
- el[KEYBOARD_ATTR] = { cleanup: () => {
711
+ directiveStates.set(el, { cleanup: () => {
691
712
  el.removeEventListener("focus", handleFocus);
692
713
  el.removeAttribute("inputmode");
693
- } };
714
+ } });
694
715
  },
695
716
  unmounted(el) {
696
- const data = el[KEYBOARD_ATTR];
697
- if (data?.cleanup) data.cleanup();
698
- delete el[KEYBOARD_ATTR];
717
+ directiveStates.get(el)?.cleanup();
718
+ directiveStates.delete(el);
699
719
  }
700
720
  };
701
721
  function parseBinding(binding) {
@@ -713,19 +733,35 @@
713
733
  }
714
734
  //#endregion
715
735
  //#region src/plugins/engine-plugin.ts
736
+ function isRecord(value) {
737
+ return typeof value === "object" && value !== null;
738
+ }
739
+ function isVueApp(value) {
740
+ return isRecord(value) && typeof value.component === "function" && typeof value.directive === "function";
741
+ }
742
+ function getEngineContext(value) {
743
+ if (!isRecord(value)) return {};
744
+ const framework = isRecord(value.framework) ? value.framework : void 0;
745
+ const container = isRecord(value.container) ? value.container : void 0;
746
+ return {
747
+ framework: isVueApp(framework?.app) ? { app: framework.app } : void 0,
748
+ container: typeof container?.singleton === "function" ? { singleton: container.singleton } : void 0
749
+ };
750
+ }
716
751
  const KeyboardEnginePlugin = {
717
752
  name: "keyboard",
718
753
  version: "0.1.0",
719
754
  async install(context, options) {
720
755
  const prefix = options?.prefix ?? "L";
721
- const app = context?.framework?.app;
756
+ const engineContext = getEngineContext(context);
757
+ const app = engineContext.framework?.app;
722
758
  if (app) {
723
759
  app.component(`${prefix}Keyboard`, VirtualKeyboard_default);
724
760
  app.component(`${prefix}KeyboardPopup`, KeyboardPopup_default);
725
761
  app.component(`${prefix}LicensePlateKeyboard`, LicensePlateKeyboard_default);
726
762
  app.directive("keyboard", vKeyboard);
727
763
  }
728
- if (context?.container?.singleton) context.container.singleton("keyboard", {
764
+ if (engineContext.container?.singleton) engineContext.container.singleton("keyboard", {
729
765
  name: "keyboard",
730
766
  version: "0.1.0"
731
767
  });