@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
@@ -1 +1 @@
1
- {"version":3,"file":"useKeyboard.cjs","names":[],"sources":["../../src/composables/useKeyboard.ts"],"sourcesContent":["/**\n * 键盘管理 Composable\n * @module composables/useKeyboard\n */\n\nimport { computed, onBeforeUnmount, reactive, ref, shallowRef, watch } from 'vue'\nimport type { Ref } from 'vue'\nimport {\n createKeyboardManager,\n type KeyboardConfig,\n type KeyboardEventMap,\n type KeyboardOptions,\n type KeyboardState,\n type KeyboardType,\n type KeyDefinition,\n} from '@composy/keyboard-core'\n\n/**\n * useKeyboard 选项\n */\nexport interface UseKeyboardOptions extends KeyboardOptions {\n /**\n * 是否立即显示\n */\n immediate?: boolean\n}\n\n/**\n * useKeyboard 返回值\n */\nexport interface UseKeyboardReturn {\n /**\n * 键盘是否可见\n */\n visible: Ref<boolean>\n\n /**\n * 当前键盘类型\n */\n type: Ref<KeyboardType>\n\n /**\n * 是否大写状态\n */\n isUpperCase: Ref<boolean>\n\n /**\n * 当前输入值\n */\n value: Ref<string>\n\n /**\n * 光标位置\n */\n cursorPosition: Ref<number>\n\n /**\n * 当前布局配置\n */\n layout: Ref<KeyboardConfig | null>\n\n /**\n * 完整状态\n */\n state: KeyboardState\n\n /**\n * 显示键盘\n */\n show: (input?: HTMLInputElement | HTMLTextAreaElement) => void\n\n /**\n * 隐藏键盘\n */\n hide: () => void\n\n /**\n * 切换显示/隐藏\n */\n toggle: (input?: HTMLInputElement | HTMLTextAreaElement) => void\n\n /**\n * 切换键盘类型\n */\n switchType: (type: KeyboardType | string) => void\n\n /**\n * 切换大小写\n */\n toggleShift: () => void\n\n /**\n * 处理按键\n */\n handleKey: (key: KeyDefinition) => void\n\n /**\n * 获取按键显示文本\n */\n getKeyLabel: (key: KeyDefinition) => string\n\n /**\n * 设置值\n */\n setValue: (value: string) => void\n\n /**\n * 追加值(在光标位置插入文本)\n */\n appendValue: (text: string) => void\n\n /**\n * 设置最大长度\n */\n setMaxLength: (maxLength?: number) => void\n\n /**\n * 绑定输入框\n */\n bindInput: (input: HTMLInputElement | HTMLTextAreaElement) => void\n\n /**\n * 解绑输入框\n */\n unbindInput: () => void\n\n /**\n * 事件监听\n */\n on: <K extends keyof KeyboardEventMap>(\n event: K,\n handler: (data: KeyboardEventMap[K]) => void\n ) => () => void\n\n /**\n * 单次事件监听\n */\n once: <K extends keyof KeyboardEventMap>(\n event: K,\n handler: (data: KeyboardEventMap[K]) => void\n ) => () => void\n\n /**\n * 销毁\n */\n destroy: () => void\n}\n\n/**\n * 键盘管理 Composable\n */\nexport function useKeyboard(options: UseKeyboardOptions = {}): UseKeyboardReturn {\n const { immediate = false, ...keyboardOptions } = options\n\n // 创建键盘管理器\n const manager = createKeyboardManager(keyboardOptions)\n\n // 响应式状态\n const visible = ref(false)\n const type = ref<KeyboardType>(keyboardOptions.type ?? 'qwerty')\n const isUpperCase = ref(keyboardOptions.defaultUpperCase ?? false)\n const value = ref(keyboardOptions.value ?? '')\n const cursorPosition = ref(keyboardOptions.value?.length ?? 0)\n const layout = shallowRef<KeyboardConfig | null>(manager.getLayout())\n\n // 完整状态(响应式对象)\n const state = reactive<KeyboardState>({\n visible: false,\n type: keyboardOptions.type ?? 'qwerty',\n isUpperCase: keyboardOptions.defaultUpperCase ?? false,\n value: keyboardOptions.value ?? '',\n cursorPosition: keyboardOptions.value?.length ?? 0,\n maxLength: keyboardOptions.maxLength,\n inputElement: null,\n })\n\n // 同步管理器状态到 Vue 响应式状态\n const syncState = (newState: KeyboardState) => {\n visible.value = newState.visible\n type.value = newState.type\n isUpperCase.value = newState.isUpperCase\n value.value = newState.value\n cursorPosition.value = newState.cursorPosition\n\n Object.assign(state, newState)\n }\n\n // 监听状态变化\n manager.on('stateChange', syncState)\n\n // 监听键盘类型切换,更新布局\n manager.on('switch', () => {\n layout.value = manager.getLayout()\n })\n\n // 立即显示\n if (immediate) {\n manager.show()\n }\n\n // 组件卸载时销毁\n onBeforeUnmount(() => {\n manager.destroy()\n })\n\n return {\n visible,\n type,\n isUpperCase,\n value,\n cursorPosition,\n layout,\n state,\n show: (input?: HTMLInputElement | HTMLTextAreaElement) => manager.show(input),\n hide: () => manager.hide(),\n toggle: (input?: HTMLInputElement | HTMLTextAreaElement) => manager.toggle(input),\n switchType: (t: KeyboardType | string) => manager.switchType(t),\n toggleShift: () => manager.toggleShift(),\n handleKey: (key: KeyDefinition) => manager.handleKey(key),\n getKeyLabel: (key: KeyDefinition) => manager.getKeyLabel(key),\n setValue: (v: string) => manager.setValue(v),\n appendValue: (text: string) => manager.appendValue(text),\n setMaxLength: (maxLength?: number) => manager.setMaxLength(maxLength),\n bindInput: (input: HTMLInputElement | HTMLTextAreaElement) => manager.bindInput(input),\n unbindInput: () => manager.unbindInput(),\n on: (event, handler) => manager.on(event, handler),\n once: (event, handler) => manager.once(event, handler),\n destroy: () => manager.destroy(),\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAuJO,SAAS,YAAY,UAA8B,CAAC,GAAsB;CAC/E,MAAM,EAAE,YAAY,OAAO,GAAG,oBAAoB;CAGlD,MAAM,WAAA,GAAA,uBAAA,sBAAA,CAAgC,eAAe;CAGrD,MAAM,WAAA,GAAA,IAAA,IAAA,CAAc,KAAK;CACzB,MAAM,QAAA,GAAA,IAAA,IAAA,CAAyB,gBAAgB,QAAQ,QAAQ;CAC/D,MAAM,eAAA,GAAA,IAAA,IAAA,CAAkB,gBAAgB,oBAAoB,KAAK;CACjE,MAAM,SAAA,GAAA,IAAA,IAAA,CAAY,gBAAgB,SAAS,EAAE;CAC7C,MAAM,kBAAA,GAAA,IAAA,IAAA,CAAqB,gBAAgB,OAAO,UAAU,CAAC;CAC7D,MAAM,UAAA,GAAA,IAAA,WAAA,CAA2C,QAAQ,UAAU,CAAC;CAGpE,MAAM,SAAA,GAAA,IAAA,SAAA,CAAgC;EACpC,SAAS;EACT,MAAM,gBAAgB,QAAQ;EAC9B,aAAa,gBAAgB,oBAAoB;EACjD,OAAO,gBAAgB,SAAS;EAChC,gBAAgB,gBAAgB,OAAO,UAAU;EACjD,WAAW,gBAAgB;EAC3B,cAAc;CAChB,CAAC;CAGD,MAAM,aAAa,aAA4B;EAC7C,QAAQ,QAAQ,SAAS;EACzB,KAAK,QAAQ,SAAS;EACtB,YAAY,QAAQ,SAAS;EAC7B,MAAM,QAAQ,SAAS;EACvB,eAAe,QAAQ,SAAS;EAEhC,OAAO,OAAO,OAAO,QAAQ;CAC/B;CAGA,QAAQ,GAAG,eAAe,SAAS;CAGnC,QAAQ,GAAG,gBAAgB;EACzB,OAAO,QAAQ,QAAQ,UAAU;CACnC,CAAC;CAGD,IAAI,WACF,QAAQ,KAAK;CAIf,CAAA,GAAA,IAAA,gBAAA,OAAsB;EACpB,QAAQ,QAAQ;CAClB,CAAC;CAED,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO,UAAmD,QAAQ,KAAK,KAAK;EAC5E,YAAY,QAAQ,KAAK;EACzB,SAAS,UAAmD,QAAQ,OAAO,KAAK;EAChF,aAAa,MAA6B,QAAQ,WAAW,CAAC;EAC9D,mBAAmB,QAAQ,YAAY;EACvC,YAAY,QAAuB,QAAQ,UAAU,GAAG;EACxD,cAAc,QAAuB,QAAQ,YAAY,GAAG;EAC5D,WAAW,MAAc,QAAQ,SAAS,CAAC;EAC3C,cAAc,SAAiB,QAAQ,YAAY,IAAI;EACvD,eAAe,cAAuB,QAAQ,aAAa,SAAS;EACpE,YAAY,UAAkD,QAAQ,UAAU,KAAK;EACrF,mBAAmB,QAAQ,YAAY;EACvC,KAAK,OAAO,YAAY,QAAQ,GAAG,OAAO,OAAO;EACjD,OAAO,OAAO,YAAY,QAAQ,KAAK,OAAO,OAAO;EACrD,eAAe,QAAQ,QAAQ;CACjC;AACF"}
1
+ {"version":3,"file":"useKeyboard.cjs","names":[],"sources":["../../src/composables/useKeyboard.ts"],"sourcesContent":["/**\r\n * 键盘管理 Composable\r\n * @module composables/useKeyboard\r\n */\r\n\r\nimport type {\r\n KeyboardConfig,\r\n KeyboardEventMap,\r\n KeyboardOptions,\r\n KeyboardState,\r\n KeyboardType,\r\n KeyDefinition,\r\n} from '@composy/keyboard-core'\r\nimport type { Ref } from 'vue'\r\nimport { createKeyboardManager } from '@composy/keyboard-core'\r\nimport { onBeforeUnmount, reactive, ref, shallowRef } from 'vue'\r\n\r\n/**\r\n * useKeyboard 选项\r\n */\r\nexport interface UseKeyboardOptions extends KeyboardOptions {\r\n /**\r\n * 是否立即显示\r\n */\r\n immediate?: boolean\r\n}\r\n\r\n/**\r\n * useKeyboard 返回值\r\n */\r\nexport interface UseKeyboardReturn {\r\n /**\r\n * 键盘是否可见\r\n */\r\n visible: Ref<boolean>\r\n\r\n /**\r\n * 当前键盘类型\r\n */\r\n type: Ref<KeyboardType>\r\n\r\n /**\r\n * 是否大写状态\r\n */\r\n isUpperCase: Ref<boolean>\r\n\r\n /**\r\n * 当前输入值\r\n */\r\n value: Ref<string>\r\n\r\n /**\r\n * 光标位置\r\n */\r\n cursorPosition: Ref<number>\r\n\r\n /**\r\n * 当前布局配置\r\n */\r\n layout: Ref<KeyboardConfig | null>\r\n\r\n /**\r\n * 完整状态\r\n */\r\n state: KeyboardState\r\n\r\n /**\r\n * 显示键盘\r\n */\r\n show: (input?: HTMLInputElement | HTMLTextAreaElement) => void\r\n\r\n /**\r\n * 隐藏键盘\r\n */\r\n hide: () => void\r\n\r\n /**\r\n * 切换显示/隐藏\r\n */\r\n toggle: (input?: HTMLInputElement | HTMLTextAreaElement) => void\r\n\r\n /**\r\n * 切换键盘类型\r\n */\r\n switchType: (type: KeyboardType | string) => void\r\n\r\n /**\r\n * 切换大小写\r\n */\r\n toggleShift: () => void\r\n\r\n /**\r\n * 处理按键\r\n */\r\n handleKey: (key: KeyDefinition) => void\r\n\r\n /**\r\n * 获取按键显示文本\r\n */\r\n getKeyLabel: (key: KeyDefinition) => string\r\n\r\n /**\r\n * 设置值\r\n */\r\n setValue: (value: string) => void\r\n\r\n /**\r\n * 追加值(在光标位置插入文本)\r\n */\r\n appendValue: (text: string) => void\r\n\r\n /**\r\n * 设置最大长度\r\n */\r\n setMaxLength: (maxLength?: number) => void\r\n\r\n /**\r\n * 绑定输入框\r\n */\r\n bindInput: (input: HTMLInputElement | HTMLTextAreaElement) => void\r\n\r\n /**\r\n * 解绑输入框\r\n */\r\n unbindInput: () => void\r\n\r\n /**\r\n * 事件监听\r\n */\r\n on: <K extends keyof KeyboardEventMap>(\r\n event: K,\r\n handler: (data: KeyboardEventMap[K]) => void\r\n ) => () => void\r\n\r\n /**\r\n * 单次事件监听\r\n */\r\n once: <K extends keyof KeyboardEventMap>(\r\n event: K,\r\n handler: (data: KeyboardEventMap[K]) => void\r\n ) => () => void\r\n\r\n /**\r\n * 销毁\r\n */\r\n destroy: () => void\r\n}\r\n\r\n/**\r\n * 键盘管理 Composable\r\n */\r\nexport function useKeyboard(\r\n options: UseKeyboardOptions = {}\r\n): UseKeyboardReturn {\r\n const { immediate = false, ...keyboardOptions } = options\r\n\r\n // 创建键盘管理器\r\n const manager = createKeyboardManager(keyboardOptions)\r\n const initialState = manager.getState()\r\n\r\n // 响应式状态\r\n const visible = ref(initialState.visible)\r\n const type = ref<KeyboardType>(initialState.type)\r\n const isUpperCase = ref(initialState.isUpperCase)\r\n const value = ref(initialState.value)\r\n const cursorPosition = ref(initialState.cursorPosition)\r\n const layout = shallowRef<KeyboardConfig | null>(manager.getLayout())\r\n\r\n // 完整状态(响应式对象)\r\n const state = reactive<KeyboardState>({\r\n ...initialState,\r\n })\r\n\r\n // 同步管理器状态到 Vue 响应式状态\r\n const syncState = (newState: KeyboardState) => {\r\n visible.value = newState.visible\r\n type.value = newState.type\r\n isUpperCase.value = newState.isUpperCase\r\n value.value = newState.value\r\n cursorPosition.value = newState.cursorPosition\r\n\r\n Object.assign(state, newState)\r\n }\r\n\r\n // 监听状态变化\r\n manager.on('stateChange', syncState)\r\n\r\n // 监听键盘类型切换,更新布局\r\n manager.on('switch', () => {\r\n layout.value = manager.getLayout()\r\n })\r\n\r\n // 立即显示\r\n if (immediate) {\r\n manager.show()\r\n }\r\n\r\n // 组件卸载时销毁\r\n onBeforeUnmount(() => {\r\n manager.destroy()\r\n })\r\n\r\n return {\r\n visible,\r\n type,\r\n isUpperCase,\r\n value,\r\n cursorPosition,\r\n layout,\r\n state,\r\n show: (input?: HTMLInputElement | HTMLTextAreaElement) =>\r\n manager.show(input),\r\n hide: () => manager.hide(),\r\n toggle: (input?: HTMLInputElement | HTMLTextAreaElement) =>\r\n manager.toggle(input),\r\n switchType: (t: KeyboardType | string) => manager.switchType(t),\r\n toggleShift: () => manager.toggleShift(),\r\n handleKey: (key: KeyDefinition) => manager.handleKey(key),\r\n getKeyLabel: (key: KeyDefinition) => manager.getKeyLabel(key),\r\n setValue: (v: string) => manager.setValue(v),\r\n appendValue: (text: string) => manager.appendValue(text),\r\n setMaxLength: (maxLength?: number) => manager.setMaxLength(maxLength),\r\n bindInput: (input: HTMLInputElement | HTMLTextAreaElement) =>\r\n manager.bindInput(input),\r\n unbindInput: () => manager.unbindInput(),\r\n on: (event, handler) => manager.on(event, handler),\r\n once: (event, handler) => manager.once(event, handler),\r\n destroy: () => manager.destroy(),\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;AAuJO,SAAS,YACd,UAA8B,CAAC,GACZ;CACnB,MAAM,EAAE,YAAY,OAAO,GAAG,oBAAoB;CAGlD,MAAM,WAAA,GAAA,uBAAA,sBAAA,CAAgC,eAAe;CACrD,MAAM,eAAe,QAAQ,SAAS;CAGtC,MAAM,WAAA,GAAA,IAAA,IAAA,CAAc,aAAa,OAAO;CACxC,MAAM,QAAA,GAAA,IAAA,IAAA,CAAyB,aAAa,IAAI;CAChD,MAAM,eAAA,GAAA,IAAA,IAAA,CAAkB,aAAa,WAAW;CAChD,MAAM,SAAA,GAAA,IAAA,IAAA,CAAY,aAAa,KAAK;CACpC,MAAM,kBAAA,GAAA,IAAA,IAAA,CAAqB,aAAa,cAAc;CACtD,MAAM,UAAA,GAAA,IAAA,WAAA,CAA2C,QAAQ,UAAU,CAAC;CAGpE,MAAM,SAAA,GAAA,IAAA,SAAA,CAAgC,EACpC,GAAG,aACL,CAAC;CAGD,MAAM,aAAa,aAA4B;EAC7C,QAAQ,QAAQ,SAAS;EACzB,KAAK,QAAQ,SAAS;EACtB,YAAY,QAAQ,SAAS;EAC7B,MAAM,QAAQ,SAAS;EACvB,eAAe,QAAQ,SAAS;EAEhC,OAAO,OAAO,OAAO,QAAQ;CAC/B;CAGA,QAAQ,GAAG,eAAe,SAAS;CAGnC,QAAQ,GAAG,gBAAgB;EACzB,OAAO,QAAQ,QAAQ,UAAU;CACnC,CAAC;CAGD,IAAI,WACF,QAAQ,KAAK;CAIf,CAAA,GAAA,IAAA,gBAAA,OAAsB;EACpB,QAAQ,QAAQ;CAClB,CAAC;CAED,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO,UACL,QAAQ,KAAK,KAAK;EACpB,YAAY,QAAQ,KAAK;EACzB,SAAS,UACP,QAAQ,OAAO,KAAK;EACtB,aAAa,MAA6B,QAAQ,WAAW,CAAC;EAC9D,mBAAmB,QAAQ,YAAY;EACvC,YAAY,QAAuB,QAAQ,UAAU,GAAG;EACxD,cAAc,QAAuB,QAAQ,YAAY,GAAG;EAC5D,WAAW,MAAc,QAAQ,SAAS,CAAC;EAC3C,cAAc,SAAiB,QAAQ,YAAY,IAAI;EACvD,eAAe,cAAuB,QAAQ,aAAa,SAAS;EACpE,YAAY,UACV,QAAQ,UAAU,KAAK;EACzB,mBAAmB,QAAQ,YAAY;EACvC,KAAK,OAAO,YAAY,QAAQ,GAAG,OAAO,OAAO;EACjD,OAAO,OAAO,YAAY,QAAQ,KAAK,OAAO,OAAO;EACrD,eAAe,QAAQ,QAAQ;CACjC;AACF"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * 键盘管理 Composable
3
+ * @module composables/useKeyboard
4
+ */
5
+ import type { KeyboardConfig, KeyboardEventMap, KeyboardOptions, KeyboardState, KeyboardType, KeyDefinition } from '@composy/keyboard-core';
6
+ import type { Ref } from 'vue';
7
+ /**
8
+ * useKeyboard 选项
9
+ */
10
+ export interface UseKeyboardOptions extends KeyboardOptions {
11
+ /**
12
+ * 是否立即显示
13
+ */
14
+ immediate?: boolean;
15
+ }
16
+ /**
17
+ * useKeyboard 返回值
18
+ */
19
+ export interface UseKeyboardReturn {
20
+ /**
21
+ * 键盘是否可见
22
+ */
23
+ visible: Ref<boolean>;
24
+ /**
25
+ * 当前键盘类型
26
+ */
27
+ type: Ref<KeyboardType>;
28
+ /**
29
+ * 是否大写状态
30
+ */
31
+ isUpperCase: Ref<boolean>;
32
+ /**
33
+ * 当前输入值
34
+ */
35
+ value: Ref<string>;
36
+ /**
37
+ * 光标位置
38
+ */
39
+ cursorPosition: Ref<number>;
40
+ /**
41
+ * 当前布局配置
42
+ */
43
+ layout: Ref<KeyboardConfig | null>;
44
+ /**
45
+ * 完整状态
46
+ */
47
+ state: KeyboardState;
48
+ /**
49
+ * 显示键盘
50
+ */
51
+ show: (input?: HTMLInputElement | HTMLTextAreaElement) => void;
52
+ /**
53
+ * 隐藏键盘
54
+ */
55
+ hide: () => void;
56
+ /**
57
+ * 切换显示/隐藏
58
+ */
59
+ toggle: (input?: HTMLInputElement | HTMLTextAreaElement) => void;
60
+ /**
61
+ * 切换键盘类型
62
+ */
63
+ switchType: (type: KeyboardType | string) => void;
64
+ /**
65
+ * 切换大小写
66
+ */
67
+ toggleShift: () => void;
68
+ /**
69
+ * 处理按键
70
+ */
71
+ handleKey: (key: KeyDefinition) => void;
72
+ /**
73
+ * 获取按键显示文本
74
+ */
75
+ getKeyLabel: (key: KeyDefinition) => string;
76
+ /**
77
+ * 设置值
78
+ */
79
+ setValue: (value: string) => void;
80
+ /**
81
+ * 追加值(在光标位置插入文本)
82
+ */
83
+ appendValue: (text: string) => void;
84
+ /**
85
+ * 设置最大长度
86
+ */
87
+ setMaxLength: (maxLength?: number) => void;
88
+ /**
89
+ * 绑定输入框
90
+ */
91
+ bindInput: (input: HTMLInputElement | HTMLTextAreaElement) => void;
92
+ /**
93
+ * 解绑输入框
94
+ */
95
+ unbindInput: () => void;
96
+ /**
97
+ * 事件监听
98
+ */
99
+ on: <K extends keyof KeyboardEventMap>(event: K, handler: (data: KeyboardEventMap[K]) => void) => () => void;
100
+ /**
101
+ * 单次事件监听
102
+ */
103
+ once: <K extends keyof KeyboardEventMap>(event: K, handler: (data: KeyboardEventMap[K]) => void) => () => void;
104
+ /**
105
+ * 销毁
106
+ */
107
+ destroy: () => void;
108
+ }
109
+ /**
110
+ * 键盘管理 Composable
111
+ */
112
+ export declare function useKeyboard(options?: UseKeyboardOptions): UseKeyboardReturn;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboard.d.cts","sourceRoot":"","sources":["../../src/composables/useKeyboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,aAAa,EACd,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAI9B;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAErB;;OAEG;IACH,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,CAAA;IAEvB;;OAEG;IACH,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAEzB;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAElB;;OAEG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAE3B;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IAElC;;OAEG;IACH,KAAK,EAAE,aAAa,CAAA;IAEpB;;OAEG;IACH,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,KAAK,IAAI,CAAA;IAE9D;;OAEG;IACH,IAAI,EAAE,MAAM,IAAI,CAAA;IAEhB;;OAEG;IACH,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,KAAK,IAAI,CAAA;IAEhE;;OAEG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,KAAK,IAAI,CAAA;IAEjD;;OAEG;IACH,WAAW,EAAE,MAAM,IAAI,CAAA;IAEvB;;OAEG;IACH,SAAS,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAA;IAEvC;;OAEG;IACH,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,CAAA;IAE3C;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEjC;;OAEG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAEnC;;OAEG;IACH,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAE1C;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,KAAK,IAAI,CAAA;IAElE;;OAEG;IACH,WAAW,EAAE,MAAM,IAAI,CAAA;IAEvB;;OAEG;IACH,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACnC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,KACzC,MAAM,IAAI,CAAA;IAEf;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACrC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,KACzC,MAAM,IAAI,CAAA;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CA4EnB"}
@@ -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
  * ***********************************
@@ -23,12 +23,28 @@ function useKeyboardPopup(options = {}) {
23
23
  let cleanupClickOutside = null;
24
24
  let cleanupViewportChange = null;
25
25
  let cleanupScroll = null;
26
+ let animationFrame = null;
27
+ let visibilitySession = 0;
28
+ const cleanupOpenResources = () => {
29
+ cleanupClickOutside?.();
30
+ cleanupClickOutside = null;
31
+ cleanupViewportChange?.();
32
+ cleanupViewportChange = null;
33
+ cleanupScroll?.();
34
+ cleanupScroll = null;
35
+ };
36
+ const cancelAnimationFrame = () => {
37
+ if (animationFrame === null || typeof window === "undefined") return;
38
+ window.cancelAnimationFrame(animationFrame);
39
+ animationFrame = null;
40
+ };
26
41
  const updatePosition = () => {
27
- if (!popup.value) return;
28
- const popupRect = popup.value.getBoundingClientRect();
42
+ const popupElement = popup.value;
43
+ if (!popupElement) return;
44
+ const popupRect = popupElement.getBoundingClientRect();
29
45
  const result = positionManager.calculate(target.value, {
30
- width: popupRect.width || 300,
31
- height: popupRect.height || 260
46
+ width: Math.max(0, popupRect.width),
47
+ height: Math.max(0, popupRect.height)
32
48
  });
33
49
  placement.value = result.placement;
34
50
  showMask.value = positionManager.shouldShowMask();
@@ -37,71 +53,72 @@ function useKeyboardPopup(options = {}) {
37
53
  left: "0",
38
54
  right: "0",
39
55
  bottom: "0",
40
- maxHeight: `${result.maxHeight}px`,
56
+ maxHeight: result.maxHeight === void 0 ? void 0 : `${result.maxHeight}px`,
41
57
  zIndex: 1e3
42
58
  };
43
59
  else popupStyles.value = {
44
60
  position: "fixed",
45
61
  left: `${result.position.x}px`,
46
62
  top: `${result.position.y}px`,
47
- maxHeight: result.maxHeight ? `${result.maxHeight}px` : void 0,
48
- maxWidth: result.maxWidth ? `${result.maxWidth}px` : void 0,
63
+ maxHeight: result.maxHeight === void 0 ? void 0 : `${result.maxHeight}px`,
64
+ maxWidth: result.maxWidth === void 0 ? void 0 : `${result.maxWidth}px`,
49
65
  zIndex: 1e3
50
66
  };
51
- if (showMask.value) maskStyles.value = {
67
+ maskStyles.value = showMask.value ? {
52
68
  position: "fixed",
53
- top: "0",
54
- left: "0",
55
- right: "0",
56
- bottom: "0",
57
- backgroundColor: "rgba(0, 0, 0, 0.5)",
69
+ inset: "0",
70
+ backgroundColor: "var(--keyboard-mask-bg)",
58
71
  zIndex: 999
59
- };
72
+ } : {};
60
73
  };
61
74
  const close = () => {
62
- onClose?.();
75
+ if (visible.value) onClose?.();
63
76
  };
64
77
  (0, vue.watch)(visible, (newVisible) => {
65
- if (newVisible) {
66
- isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
67
- requestAnimationFrame(() => {
68
- updatePosition();
69
- if (closeOnClickOutside && popup.value) cleanupClickOutside = (0, _composy_keyboard_core.onClickOutside)(popup.value, (event) => {
70
- if (target.value && target.value.contains(event.target)) return;
71
- close();
72
- });
73
- });
74
- cleanupViewportChange = (0, _composy_keyboard_core.onViewportChange)(() => {
75
- isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
76
- updatePosition();
78
+ visibilitySession += 1;
79
+ const currentSession = visibilitySession;
80
+ cancelAnimationFrame();
81
+ cleanupOpenResources();
82
+ if (!newVisible) {
83
+ isAnimating.value = false;
84
+ showMask.value = false;
85
+ popupStyles.value = {};
86
+ maskStyles.value = {};
87
+ return;
88
+ }
89
+ isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
90
+ isAnimating.value = true;
91
+ if (typeof window !== "undefined") animationFrame = window.requestAnimationFrame(() => {
92
+ animationFrame = null;
93
+ if (!visible.value || currentSession !== visibilitySession) return;
94
+ updatePosition();
95
+ isAnimating.value = false;
96
+ if (closeOnClickOutside && popup.value) cleanupClickOutside = (0, _composy_keyboard_core.onClickOutside)(popup.value, (event) => {
97
+ if (target.value && event.target instanceof Node && target.value.contains(event.target)) return;
98
+ close();
77
99
  });
78
- if (!isMobileDevice.value) {
79
- const handleScroll = () => {
80
- requestAnimationFrame(() => {
81
- updatePosition();
82
- });
83
- };
84
- window.addEventListener("scroll", handleScroll, true);
85
- cleanupScroll = () => {
86
- window.removeEventListener("scroll", handleScroll, true);
87
- };
88
- }
89
- } else {
90
- cleanupClickOutside?.();
91
- cleanupClickOutside = null;
92
- cleanupViewportChange?.();
93
- cleanupViewportChange = null;
94
- cleanupScroll?.();
95
- cleanupScroll = null;
100
+ });
101
+ cleanupViewportChange = (0, _composy_keyboard_core.onViewportChange)(() => {
102
+ if (!visible.value) return;
103
+ isMobileDevice.value = (0, _composy_keyboard_core.isMobile)();
104
+ updatePosition();
105
+ });
106
+ if (!isMobileDevice.value && typeof window !== "undefined") {
107
+ const handleScroll = () => {
108
+ if (!visible.value) return;
109
+ window.requestAnimationFrame(updatePosition);
110
+ };
111
+ window.addEventListener("scroll", handleScroll, true);
112
+ cleanupScroll = () => window.removeEventListener("scroll", handleScroll, true);
96
113
  }
97
114
  }, { immediate: true });
98
115
  (0, vue.watch)(target, () => {
99
116
  if (visible.value) updatePosition();
100
117
  });
101
118
  (0, vue.onBeforeUnmount)(() => {
102
- cleanupClickOutside?.();
103
- cleanupViewportChange?.();
104
- cleanupScroll?.();
119
+ visibilitySession += 1;
120
+ cancelAnimationFrame();
121
+ cleanupOpenResources();
105
122
  });
106
123
  return {
107
124
  popupStyles,
@@ -1 +1 @@
1
- {"version":3,"file":"useKeyboardPopup.cjs","names":[],"sources":["../../src/composables/useKeyboardPopup.ts"],"sourcesContent":["/**\n * 键盘弹出层 Composable\n * @module composables/useKeyboardPopup\n */\n\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport type { CSSProperties, Ref } from 'vue'\nimport {\n createPositionManager,\n isMobile,\n onClickOutside,\n onViewportChange,\n type PopupPlacement,\n type PopupPositionConfig,\n type PopupPositionResult,\n} from '@composy/keyboard-core'\n\n/**\n * useKeyboardPopup 选项\n */\nexport interface UseKeyboardPopupOptions extends PopupPositionConfig {\n /**\n * 是否显示\n */\n visible?: Ref<boolean>\n\n /**\n * 目标元素\n */\n target?: Ref<HTMLElement | null>\n\n /**\n * 弹出层元素\n */\n popup?: Ref<HTMLElement | null>\n\n /**\n * 点击外部关闭\n */\n closeOnClickOutside?: boolean\n\n /**\n * 关闭回调\n */\n onClose?: () => void\n}\n\n/**\n * useKeyboardPopup 返回值\n */\nexport interface UseKeyboardPopupReturn {\n /**\n * 弹出层样式\n */\n popupStyles: Ref<CSSProperties>\n\n /**\n * 遮罩层样式\n */\n maskStyles: Ref<CSSProperties>\n\n /**\n * 当前弹出位置\n */\n placement: Ref<PopupPlacement>\n\n /**\n * 是否移动端\n */\n isMobileDevice: Ref<boolean>\n\n /**\n * 是否显示遮罩\n */\n showMask: Ref<boolean>\n\n /**\n * 是否正在动画中\n */\n isAnimating: Ref<boolean>\n\n /**\n * 更新位置\n */\n updatePosition: () => void\n\n /**\n * 关闭弹出层\n */\n close: () => void\n}\n\n/**\n * 键盘弹出层 Composable\n */\nexport function useKeyboardPopup(options: UseKeyboardPopupOptions = {}): UseKeyboardPopupReturn {\n const {\n visible = ref(false),\n target = ref(null),\n popup = ref(null),\n closeOnClickOutside = true,\n onClose,\n ...positionConfig\n } = options\n\n // 创建位置管理器\n const positionManager = createPositionManager(positionConfig)\n\n // 响应式状态\n const popupStyles = ref<CSSProperties>({})\n const maskStyles = ref<CSSProperties>({})\n const placement = ref<PopupPlacement>('bottom')\n const isMobileDevice = ref(isMobile())\n const showMask = ref(false)\n const isAnimating = ref(false)\n\n // 清理函数\n let cleanupClickOutside: (() => void) | null = null\n let cleanupViewportChange: (() => void) | null = null\n let cleanupScroll: (() => void) | null = null\n\n /**\n * 更新弹出层位置\n */\n const updatePosition = () => {\n if (!popup.value) return\n\n const popupRect = popup.value.getBoundingClientRect()\n const result = positionManager.calculate(target.value, {\n width: popupRect.width || 300,\n height: popupRect.height || 260,\n })\n\n placement.value = result.placement\n showMask.value = positionManager.shouldShowMask()\n\n // 设置弹出层样式\n if (result.placement === 'bottom-sheet') {\n // 移动端底部弹出\n popupStyles.value = {\n position: 'fixed',\n left: '0',\n right: '0',\n bottom: '0',\n maxHeight: `${result.maxHeight}px`,\n zIndex: 1000,\n }\n }\n else {\n // PC 端下拉弹出\n popupStyles.value = {\n position: 'fixed',\n left: `${result.position.x}px`,\n top: `${result.position.y}px`,\n maxHeight: result.maxHeight ? `${result.maxHeight}px` : undefined,\n maxWidth: result.maxWidth ? `${result.maxWidth}px` : undefined,\n zIndex: 1000,\n }\n }\n\n // 设置遮罩层样式\n if (showMask.value) {\n maskStyles.value = {\n position: 'fixed',\n top: '0',\n left: '0',\n right: '0',\n bottom: '0',\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n zIndex: 999,\n }\n }\n }\n\n /**\n * 关闭弹出层\n */\n const close = () => {\n onClose?.()\n }\n\n // 监听 visible 变化\n watch(visible, (newVisible) => {\n if (newVisible) {\n // 显示时\n isMobileDevice.value = isMobile()\n\n // 延迟计算位置(等待 DOM 渲染)\n requestAnimationFrame(() => {\n updatePosition()\n\n // 添加点击外部关闭监听\n if (closeOnClickOutside && popup.value) {\n cleanupClickOutside = onClickOutside(popup.value, (event) => {\n // 检查是否点击在目标元素上\n if (target.value && target.value.contains(event.target as Node)) {\n return\n }\n close()\n })\n }\n })\n\n // 监听视口变化\n cleanupViewportChange = onViewportChange(() => {\n isMobileDevice.value = isMobile()\n updatePosition()\n })\n\n // PC 端监听滚动事件,跟随滚动\n if (!isMobileDevice.value) {\n const handleScroll = () => {\n requestAnimationFrame(() => {\n updatePosition()\n })\n }\n window.addEventListener('scroll', handleScroll, true)\n cleanupScroll = () => {\n window.removeEventListener('scroll', handleScroll, true)\n }\n }\n }\n else {\n // 隐藏时清理\n cleanupClickOutside?.()\n cleanupClickOutside = null\n cleanupViewportChange?.()\n cleanupViewportChange = null\n cleanupScroll?.()\n cleanupScroll = null\n }\n }, { immediate: true })\n\n // 监听目标元素变化\n watch(target, () => {\n if (visible.value) {\n updatePosition()\n }\n })\n\n // 组件卸载时清理\n onBeforeUnmount(() => {\n cleanupClickOutside?.()\n cleanupViewportChange?.()\n cleanupScroll?.()\n })\n\n return {\n popupStyles,\n maskStyles,\n placement,\n isMobileDevice,\n showMask,\n isAnimating,\n updatePosition,\n close,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useKeyboardPopup.cjs","names":[],"sources":["../../src/composables/useKeyboardPopup.ts"],"sourcesContent":["/**\r\n * Keyboard popup composable.\r\n * @module composables/useKeyboardPopup\r\n */\r\n\r\nimport type {\r\n PopupPlacement,\r\n PopupPositionConfig,\r\n} from '@composy/keyboard-core'\r\nimport type { CSSProperties, Ref } from 'vue'\r\nimport {\r\n createPositionManager,\r\n isMobile,\r\n onClickOutside,\r\n onViewportChange,\r\n} from '@composy/keyboard-core'\r\nimport { onBeforeUnmount, ref, watch } from 'vue'\r\n\r\nexport interface UseKeyboardPopupOptions extends PopupPositionConfig {\r\n visible?: Ref<boolean>\r\n target?: Ref<HTMLElement | null>\r\n popup?: Ref<HTMLElement | null>\r\n closeOnClickOutside?: boolean\r\n onClose?: () => void\r\n}\r\n\r\nexport interface UseKeyboardPopupReturn {\r\n popupStyles: Ref<CSSProperties>\r\n maskStyles: Ref<CSSProperties>\r\n placement: Ref<PopupPlacement>\r\n isMobileDevice: Ref<boolean>\r\n showMask: Ref<boolean>\r\n isAnimating: Ref<boolean>\r\n updatePosition: () => void\r\n close: () => void\r\n}\r\n\r\nexport function useKeyboardPopup(\r\n options: UseKeyboardPopupOptions = {}\r\n): UseKeyboardPopupReturn {\r\n const {\r\n visible = ref(false),\r\n target = ref(null),\r\n popup = ref(null),\r\n closeOnClickOutside = true,\r\n onClose,\r\n ...positionConfig\r\n } = options\r\n\r\n const positionManager = createPositionManager(positionConfig)\r\n const popupStyles = ref<CSSProperties>({})\r\n const maskStyles = ref<CSSProperties>({})\r\n const placement = ref<PopupPlacement>('bottom')\r\n const isMobileDevice = ref(isMobile())\r\n const showMask = ref(false)\r\n const isAnimating = ref(false)\r\n\r\n let cleanupClickOutside: (() => void) | null = null\r\n let cleanupViewportChange: (() => void) | null = null\r\n let cleanupScroll: (() => void) | null = null\r\n let animationFrame: number | null = null\r\n let visibilitySession = 0\r\n\r\n const cleanupOpenResources = () => {\r\n cleanupClickOutside?.()\r\n cleanupClickOutside = null\r\n cleanupViewportChange?.()\r\n cleanupViewportChange = null\r\n cleanupScroll?.()\r\n cleanupScroll = null\r\n }\r\n\r\n const cancelAnimationFrame = () => {\r\n if (animationFrame === null || typeof window === 'undefined') return\r\n window.cancelAnimationFrame(animationFrame)\r\n animationFrame = null\r\n }\r\n\r\n const updatePosition = () => {\r\n const popupElement = popup.value\r\n if (!popupElement) return\r\n\r\n const popupRect = popupElement.getBoundingClientRect()\r\n const result = positionManager.calculate(target.value, {\r\n width: Math.max(0, popupRect.width),\r\n height: Math.max(0, popupRect.height),\r\n })\r\n\r\n placement.value = result.placement\r\n showMask.value = positionManager.shouldShowMask()\r\n\r\n if (result.placement === 'bottom-sheet') {\r\n popupStyles.value = {\r\n position: 'fixed',\r\n left: '0',\r\n right: '0',\r\n bottom: '0',\r\n maxHeight:\r\n result.maxHeight === undefined ? undefined : `${result.maxHeight}px`,\r\n zIndex: 1000,\r\n }\r\n } else {\r\n popupStyles.value = {\r\n position: 'fixed',\r\n left: `${result.position.x}px`,\r\n top: `${result.position.y}px`,\r\n maxHeight:\r\n result.maxHeight === undefined ? undefined : `${result.maxHeight}px`,\r\n maxWidth:\r\n result.maxWidth === undefined ? undefined : `${result.maxWidth}px`,\r\n zIndex: 1000,\r\n }\r\n }\r\n\r\n maskStyles.value = showMask.value\r\n ? {\r\n position: 'fixed',\r\n inset: '0',\r\n backgroundColor: 'var(--keyboard-mask-bg)',\r\n zIndex: 999,\r\n }\r\n : {}\r\n }\r\n\r\n const close = () => {\r\n if (visible.value) onClose?.()\r\n }\r\n\r\n watch(\r\n visible,\r\n newVisible => {\r\n visibilitySession += 1\r\n const currentSession = visibilitySession\r\n cancelAnimationFrame()\r\n cleanupOpenResources()\r\n\r\n if (!newVisible) {\r\n isAnimating.value = false\r\n showMask.value = false\r\n popupStyles.value = {}\r\n maskStyles.value = {}\r\n return\r\n }\r\n\r\n isMobileDevice.value = isMobile()\r\n isAnimating.value = true\r\n\r\n if (typeof window !== 'undefined') {\r\n animationFrame = window.requestAnimationFrame(() => {\r\n animationFrame = null\r\n if (!visible.value || currentSession !== visibilitySession) return\r\n\r\n updatePosition()\r\n isAnimating.value = false\r\n if (closeOnClickOutside && popup.value) {\r\n cleanupClickOutside = onClickOutside(popup.value, event => {\r\n if (\r\n target.value &&\r\n event.target instanceof Node &&\r\n target.value.contains(event.target)\r\n )\r\n return\r\n close()\r\n })\r\n }\r\n })\r\n }\r\n\r\n cleanupViewportChange = onViewportChange(() => {\r\n if (!visible.value) return\r\n isMobileDevice.value = isMobile()\r\n updatePosition()\r\n })\r\n\r\n if (!isMobileDevice.value && typeof window !== 'undefined') {\r\n const handleScroll = () => {\r\n if (!visible.value) return\r\n window.requestAnimationFrame(updatePosition)\r\n }\r\n window.addEventListener('scroll', handleScroll, true)\r\n cleanupScroll = () =>\r\n window.removeEventListener('scroll', handleScroll, true)\r\n }\r\n },\r\n { immediate: true }\r\n )\r\n\r\n watch(target, () => {\r\n if (visible.value) updatePosition()\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n visibilitySession += 1\r\n cancelAnimationFrame()\r\n cleanupOpenResources()\r\n })\r\n\r\n return {\r\n popupStyles,\r\n maskStyles,\r\n placement,\r\n isMobileDevice,\r\n showMask,\r\n isAnimating,\r\n updatePosition,\r\n close,\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Keyboard popup composable.
3
+ * @module composables/useKeyboardPopup
4
+ */
5
+ import type { PopupPlacement, PopupPositionConfig } from '@composy/keyboard-core';
6
+ import type { CSSProperties, Ref } from 'vue';
7
+ export interface UseKeyboardPopupOptions extends PopupPositionConfig {
8
+ visible?: Ref<boolean>;
9
+ target?: Ref<HTMLElement | null>;
10
+ popup?: Ref<HTMLElement | null>;
11
+ closeOnClickOutside?: boolean;
12
+ onClose?: () => void;
13
+ }
14
+ export interface UseKeyboardPopupReturn {
15
+ popupStyles: Ref<CSSProperties>;
16
+ maskStyles: Ref<CSSProperties>;
17
+ placement: Ref<PopupPlacement>;
18
+ isMobileDevice: Ref<boolean>;
19
+ showMask: Ref<boolean>;
20
+ isAnimating: Ref<boolean>;
21
+ updatePosition: () => void;
22
+ close: () => void;
23
+ }
24
+ export declare function useKeyboardPopup(options?: UseKeyboardPopupOptions): UseKeyboardPopupReturn;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboardPopup.d.cts","sourceRoot":"","sources":["../../src/composables/useKeyboardPopup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAS7C,MAAM,WAAW,uBAAwB,SAAQ,mBAAmB;IAClE,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,MAAM,CAAC,EAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,CAAA;IAC/B,UAAU,EAAE,GAAG,CAAC,aAAa,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,CAAA;IAC9B,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC5B,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACzB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAwKxB"}
@@ -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
  * ***********************************
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 指令导出
3
+ * @module directives
4
+ */
5
+ export * from './v-keyboard';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/directives/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,cAAc,CAAA"}
@@ -2,14 +2,14 @@
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
  * ***********************************
9
9
  */
10
10
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
11
  //#region src/directives/v-keyboard.ts
12
- const KEYBOARD_ATTR = "__v_keyboard__";
12
+ const directiveStates = /* @__PURE__ */ new WeakMap();
13
13
  const vKeyboard = {
14
14
  mounted(el, binding) {
15
15
  const options = parseBinding(binding);
@@ -20,14 +20,14 @@ const vKeyboard = {
20
20
  };
21
21
  el.addEventListener("focus", handleFocus);
22
22
  el.setAttribute("inputmode", "none");
23
- el[KEYBOARD_ATTR] = { cleanup: () => {
23
+ directiveStates.set(el, { cleanup: () => {
24
24
  el.removeEventListener("focus", handleFocus);
25
25
  el.removeAttribute("inputmode");
26
- } };
26
+ } });
27
27
  },
28
28
  updated(el, binding) {
29
- const oldCleanup = el[KEYBOARD_ATTR]?.cleanup;
30
- if (oldCleanup) oldCleanup();
29
+ directiveStates.get(el)?.cleanup();
30
+ directiveStates.delete(el);
31
31
  const options = parseBinding(binding);
32
32
  if (!options.enabled) return;
33
33
  const handleFocus = () => {
@@ -36,15 +36,14 @@ const vKeyboard = {
36
36
  };
37
37
  el.addEventListener("focus", handleFocus);
38
38
  el.setAttribute("inputmode", "none");
39
- el[KEYBOARD_ATTR] = { cleanup: () => {
39
+ directiveStates.set(el, { cleanup: () => {
40
40
  el.removeEventListener("focus", handleFocus);
41
41
  el.removeAttribute("inputmode");
42
- } };
42
+ } });
43
43
  },
44
44
  unmounted(el) {
45
- const data = el[KEYBOARD_ATTR];
46
- if (data?.cleanup) data.cleanup();
47
- delete el[KEYBOARD_ATTR];
45
+ directiveStates.get(el)?.cleanup();
46
+ directiveStates.delete(el);
48
47
  }
49
48
  };
50
49
  function parseBinding(binding) {
@@ -1 +1 @@
1
- {"version":3,"file":"v-keyboard.cjs","names":[],"sources":["../../src/directives/v-keyboard.ts"],"sourcesContent":["/**\n * v-keyboard 指令\n * 自动在输入框聚焦时打开虚拟键盘\n * @module directives/v-keyboard\n */\n\nimport type { Directive, DirectiveBinding } from 'vue'\n\n/**\n * 指令绑定值\n */\nexport interface VKeyboardBinding {\n /** 键盘类型 */\n type?: string\n /** 是否启用 */\n enabled?: boolean\n /** 打开键盘回调 */\n onOpen?: (el: HTMLInputElement | HTMLTextAreaElement) => void\n /** 关闭键盘回调 */\n onClose?: () => void\n}\n\nconst KEYBOARD_ATTR = '__v_keyboard__'\n\n/**\n * v-keyboard 指令\n *\n * @example\n * ```html\n * <!-- 基础用法 -->\n * <input v-keyboard />\n *\n * <!-- 指定键盘类型 -->\n * <input v-keyboard=\"{ type: 'number' }\" />\n *\n * <!-- 配合回调 -->\n * <input v-keyboard=\"{ type: 'phone', onOpen: handleOpen }\" />\n * ```\n */\nexport const vKeyboard: Directive<HTMLInputElement | HTMLTextAreaElement, VKeyboardBinding | string | boolean> = {\n mounted(el, binding) {\n const options = parseBinding(binding)\n if (!options.enabled) return\n\n const handleFocus = () => {\n // 阻止原生键盘\n el.blur()\n options.onOpen?.(el)\n }\n\n el.addEventListener('focus', handleFocus)\n el.setAttribute('inputmode', 'none')\n\n // 存储清理函数\n ;(el as any)[KEYBOARD_ATTR] = {\n cleanup: () => {\n el.removeEventListener('focus', handleFocus)\n el.removeAttribute('inputmode')\n },\n }\n },\n\n updated(el, binding) {\n const oldCleanup = (el as any)[KEYBOARD_ATTR]?.cleanup\n if (oldCleanup) oldCleanup()\n\n const options = parseBinding(binding)\n if (!options.enabled) return\n\n const handleFocus = () => {\n el.blur()\n options.onOpen?.(el)\n }\n\n el.addEventListener('focus', handleFocus)\n el.setAttribute('inputmode', 'none')\n\n ;(el as any)[KEYBOARD_ATTR] = {\n cleanup: () => {\n el.removeEventListener('focus', handleFocus)\n el.removeAttribute('inputmode')\n },\n }\n },\n\n unmounted(el) {\n const data = (el as any)[KEYBOARD_ATTR]\n if (data?.cleanup) data.cleanup()\n delete (el as any)[KEYBOARD_ATTR]\n },\n}\n\n/**\n * 解析指令绑定值\n */\nfunction parseBinding(binding: DirectiveBinding<VKeyboardBinding | string | boolean>): VKeyboardBinding & { enabled: boolean } {\n const value = binding.value\n\n if (value === false) {\n return { enabled: false }\n }\n\n if (value === true || value === undefined) {\n return { enabled: true }\n }\n\n if (typeof value === 'string') {\n return { enabled: true, type: value }\n }\n\n return {\n enabled: value.enabled !== false,\n ...value,\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,gBAAgB;AAiBf,MAAM,YAAoG;CAC/G,QAAQ,IAAI,SAAS;EACnB,MAAM,UAAU,aAAa,OAAO;EACpC,IAAI,CAAC,QAAQ,SAAS;EAEtB,MAAM,oBAAoB;GAExB,GAAG,KAAK;GACR,QAAQ,SAAS,EAAE;EACrB;EAEA,GAAG,iBAAiB,SAAS,WAAW;EACxC,GAAG,aAAa,aAAa,MAAM;EAGjC,GAAW,iBAAiB,EAC5B,eAAe;GACb,GAAG,oBAAoB,SAAS,WAAW;GAC3C,GAAG,gBAAgB,WAAW;EAChC,EACF;CACF;CAEA,QAAQ,IAAI,SAAS;EACnB,MAAM,aAAc,GAAW,cAAa,EAAG;EAC/C,IAAI,YAAY,WAAW;EAE3B,MAAM,UAAU,aAAa,OAAO;EACpC,IAAI,CAAC,QAAQ,SAAS;EAEtB,MAAM,oBAAoB;GACxB,GAAG,KAAK;GACR,QAAQ,SAAS,EAAE;EACrB;EAEA,GAAG,iBAAiB,SAAS,WAAW;EACxC,GAAG,aAAa,aAAa,MAAM;EAEjC,GAAW,iBAAiB,EAC5B,eAAe;GACb,GAAG,oBAAoB,SAAS,WAAW;GAC3C,GAAG,gBAAgB,WAAW;EAChC,EACF;CACF;CAEA,UAAU,IAAI;EACZ,MAAM,OAAQ,GAAW;EACzB,IAAI,MAAM,SAAS,KAAK,QAAQ;EAChC,OAAQ,GAAW;CACrB;AACF;AAKA,SAAS,aAAa,SAAyG;CAC7H,MAAM,QAAQ,QAAQ;CAEtB,IAAI,UAAU,OACZ,OAAO,EAAE,SAAS,MAAM;CAG1B,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC9B,OAAO,EAAE,SAAS,KAAK;CAGzB,IAAI,OAAO,UAAU,UACnB,OAAO;EAAE,SAAS;EAAM,MAAM;CAAM;CAGtC,OAAO;EACL,SAAS,MAAM,YAAY;EAC3B,GAAG;CACL;AACF"}
1
+ {"version":3,"file":"v-keyboard.cjs","names":[],"sources":["../../src/directives/v-keyboard.ts"],"sourcesContent":["/**\r\n * v-keyboard 指令\r\n * 自动在输入框聚焦时打开虚拟键盘\r\n * @module directives/v-keyboard\r\n */\r\n\r\nimport type { Directive, DirectiveBinding } from 'vue'\r\n\r\n/**\r\n * 指令绑定值\r\n */\r\nexport interface VKeyboardBinding {\r\n /** 键盘类型 */\r\n type?: string\r\n /** 是否启用 */\r\n enabled?: boolean\r\n /** 打开键盘回调 */\r\n onOpen?: (el: HTMLInputElement | HTMLTextAreaElement) => void\r\n /** 关闭键盘回调 */\r\n onClose?: () => void\r\n}\r\n\r\ninterface KeyboardDirectiveState {\r\n cleanup: () => void\r\n}\r\n\r\nconst directiveStates = new WeakMap<HTMLElement, KeyboardDirectiveState>()\r\n\r\n/**\r\n * v-keyboard 指令\r\n *\r\n * @example\r\n * ```html\r\n * <!-- 基础用法 -->\r\n * <input v-keyboard />\r\n *\r\n * <!-- 指定键盘类型 -->\r\n * <input v-keyboard=\"{ type: 'number' }\" />\r\n *\r\n * <!-- 配合回调 -->\r\n * <input v-keyboard=\"{ type: 'phone', onOpen: handleOpen }\" />\r\n * ```\r\n */\r\nexport const vKeyboard: Directive<\r\n HTMLInputElement | HTMLTextAreaElement,\r\n VKeyboardBinding | string | boolean\r\n> = {\r\n mounted(el, binding) {\r\n const options = parseBinding(binding)\r\n if (!options.enabled) return\r\n\r\n const handleFocus = () => {\r\n // 阻止原生键盘\r\n el.blur()\r\n options.onOpen?.(el)\r\n }\r\n\r\n el.addEventListener('focus', handleFocus)\r\n el.setAttribute('inputmode', 'none')\r\n\r\n // 存储清理函数\r\n directiveStates.set(el, {\r\n cleanup: () => {\r\n el.removeEventListener('focus', handleFocus)\r\n el.removeAttribute('inputmode')\r\n },\r\n })\r\n },\r\n\r\n updated(el, binding) {\r\n directiveStates.get(el)?.cleanup()\r\n directiveStates.delete(el)\r\n\r\n const options = parseBinding(binding)\r\n if (!options.enabled) return\r\n\r\n const handleFocus = () => {\r\n el.blur()\r\n options.onOpen?.(el)\r\n }\r\n\r\n el.addEventListener('focus', handleFocus)\r\n el.setAttribute('inputmode', 'none')\r\n\r\n directiveStates.set(el, {\r\n cleanup: () => {\r\n el.removeEventListener('focus', handleFocus)\r\n el.removeAttribute('inputmode')\r\n },\r\n })\r\n },\r\n\r\n unmounted(el) {\r\n directiveStates.get(el)?.cleanup()\r\n directiveStates.delete(el)\r\n },\r\n}\r\n\r\n/**\r\n * 解析指令绑定值\r\n */\r\nfunction parseBinding(\r\n binding: DirectiveBinding<VKeyboardBinding | string | boolean>\r\n): VKeyboardBinding & { enabled: boolean } {\r\n const value = binding.value\r\n\r\n if (value === false) {\r\n return { enabled: false }\r\n }\r\n\r\n if (value === true || value === undefined) {\r\n return { enabled: true }\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return { enabled: true, type: value }\r\n }\r\n\r\n return {\r\n enabled: value.enabled !== false,\r\n ...value,\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;AA0BA,MAAM,kCAAkB,IAAI,QAA6C;AAiBlE,MAAM,YAGT;CACF,QAAQ,IAAI,SAAS;EACnB,MAAM,UAAU,aAAa,OAAO;EACpC,IAAI,CAAC,QAAQ,SAAS;EAEtB,MAAM,oBAAoB;GAExB,GAAG,KAAK;GACR,QAAQ,SAAS,EAAE;EACrB;EAEA,GAAG,iBAAiB,SAAS,WAAW;EACxC,GAAG,aAAa,aAAa,MAAM;EAGnC,gBAAgB,IAAI,IAAI,EACtB,eAAe;GACb,GAAG,oBAAoB,SAAS,WAAW;GAC3C,GAAG,gBAAgB,WAAW;EAChC,EACF,CAAC;CACH;CAEA,QAAQ,IAAI,SAAS;EACnB,gBAAgB,IAAI,EAAE,CAAA,EAAG,QAAQ;EACjC,gBAAgB,OAAO,EAAE;EAEzB,MAAM,UAAU,aAAa,OAAO;EACpC,IAAI,CAAC,QAAQ,SAAS;EAEtB,MAAM,oBAAoB;GACxB,GAAG,KAAK;GACR,QAAQ,SAAS,EAAE;EACrB;EAEA,GAAG,iBAAiB,SAAS,WAAW;EACxC,GAAG,aAAa,aAAa,MAAM;EAEnC,gBAAgB,IAAI,IAAI,EACtB,eAAe;GACb,GAAG,oBAAoB,SAAS,WAAW;GAC3C,GAAG,gBAAgB,WAAW;EAChC,EACF,CAAC;CACH;CAEA,UAAU,IAAI;EACZ,gBAAgB,IAAI,EAAE,CAAA,EAAG,QAAQ;EACjC,gBAAgB,OAAO,EAAE;CAC3B;AACF;AAKA,SAAS,aACP,SACyC;CACzC,MAAM,QAAQ,QAAQ;CAEtB,IAAI,UAAU,OACZ,OAAO,EAAE,SAAS,MAAM;CAG1B,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC9B,OAAO,EAAE,SAAS,KAAK;CAGzB,IAAI,OAAO,UAAU,UACnB,OAAO;EAAE,SAAS;EAAM,MAAM;CAAM;CAGtC,OAAO;EACL,SAAS,MAAM,YAAY;EAC3B,GAAG;CACL;AACF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * v-keyboard 指令
3
+ * 自动在输入框聚焦时打开虚拟键盘
4
+ * @module directives/v-keyboard
5
+ */
6
+ import type { Directive } from 'vue';
7
+ /**
8
+ * 指令绑定值
9
+ */
10
+ export interface VKeyboardBinding {
11
+ /** 键盘类型 */
12
+ type?: string;
13
+ /** 是否启用 */
14
+ enabled?: boolean;
15
+ /** 打开键盘回调 */
16
+ onOpen?: (el: HTMLInputElement | HTMLTextAreaElement) => void;
17
+ /** 关闭键盘回调 */
18
+ onClose?: () => void;
19
+ }
20
+ /**
21
+ * v-keyboard 指令
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <!-- 基础用法 -->
26
+ * <input v-keyboard />
27
+ *
28
+ * <!-- 指定键盘类型 -->
29
+ * <input v-keyboard="{ type: 'number' }" />
30
+ *
31
+ * <!-- 配合回调 -->
32
+ * <input v-keyboard="{ type: 'phone', onOpen: handleOpen }" />
33
+ * ```
34
+ */
35
+ export declare const vKeyboard: Directive<HTMLInputElement | HTMLTextAreaElement, VKeyboardBinding | string | boolean>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v-keyboard.d.cts","sourceRoot":"","sources":["../../src/directives/v-keyboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,KAAK,CAAA;AAEtD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa;IACb,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,gBAAgB,GAAG,mBAAmB,KAAK,IAAI,CAAA;IAC7D,aAAa;IACb,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAQD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,CAC/B,gBAAgB,GAAG,mBAAmB,EACtC,gBAAgB,GAAG,MAAM,GAAG,OAAO,CAmDpC,CAAA"}
package/lib/index.cjs 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,9 +12,9 @@ Object.defineProperties(exports, {
12
12
  [Symbol.toStringTag]: { value: "Module" }
13
13
  });
14
14
  const require_KeyboardKey = require("./components/KeyboardKey.cjs");
15
- const require_VirtualKeyboard = require("./components/VirtualKeyboard.cjs");
16
15
  const require_useKeyboard = require("./composables/useKeyboard.cjs");
17
16
  const require_useKeyboardPopup = require("./composables/useKeyboardPopup.cjs");
17
+ const require_VirtualKeyboard = require("./components/VirtualKeyboard.cjs");
18
18
  const require_KeyboardPopup = require("./components/KeyboardPopup.cjs");
19
19
  const require_LicensePlateKeyboard = require("./components/LicensePlateKeyboard.cjs");
20
20
  const require_v_keyboard = require("./directives/v-keyboard.cjs");
package/lib/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @composy/keyboard-vue\n * LDesign 虚拟键盘 - Vue 3 适配器\n * @packageDocumentation\n */\n\nimport type { App, Plugin } from 'vue'\nimport { KeyboardPopup, VirtualKeyboard, LicensePlateKeyboard } from './components'\nimport { vKeyboard } from './directives/v-keyboard'\n\n// 导出组件\nexport * from './components'\n\n// 导出 Composables\nexport * from './composables'\n\n// 导出插件\nexport * from './plugins'\n\n// 导出指令\nexport * from './directives'\n\n// 从核心包重新导出\nexport {\n // 管理器\n createKeyboardManager,\n createPositionManager,\n createKeyboardRenderer,\n KeyboardManager,\n PositionManager,\n KeyboardRenderer,\n\n // 布局\n getLayout,\n registerLayout,\n registerLayouts,\n hasLayout,\n getAvailableLayouts,\n unregisterLayout,\n qwertyLayout,\n numberLayout,\n integerLayout,\n symbolLayout,\n symbolLayout2,\n licensePlateLayout,\n licensePlateProvinceLayout,\n licensePlateLetterLayout,\n licensePlateAlphanumericLayout,\n PROVINCES,\n PLATE_LETTERS,\n // 场景化键盘\n idcardLayout,\n phoneLayout,\n phoneSimpleLayout,\n amountLayout,\n amountSimpleLayout,\n bankcardLayout,\n verifycodeLayout,\n emailLayout,\n urlLayout,\n searchLayout,\n punctLayout,\n EMAIL_SUFFIXES,\n\n // 工具函数\n EventEmitter,\n isMobile,\n isTouchDevice,\n getDeviceType,\n getViewportInfo,\n vibrate,\n onViewportChange,\n getBoundingRect,\n onClickOutside,\n insertTextAtCursor,\n deleteCharBeforeCursor,\n // 随机键盘\n shuffleArray,\n getRandomNumbers,\n getRandomLetters,\n getRandomAlphanumeric,\n createRandomNumberLayout,\n createRandomPinLayout,\n createRandomLetterLayout,\n createRandomMixedLayout,\n refreshRandomLayout,\n\n // 格式化工具\n formatPhone,\n formatBankCard,\n formatAmount,\n formatIdCard,\n formatLicensePlate,\n formatVerifyCode,\n registerFormatter,\n getFormatter,\n applyFormatter,\n\n // 主题系统\n getTheme,\n registerTheme,\n getAvailableThemes,\n getAllThemes,\n setCurrentTheme,\n getCurrentTheme,\n themeToCSS,\n applyTheme,\n generateThemeStyle,\n mergeTheme,\n createTheme,\n miuiTheme,\n iosTheme,\n materialTheme,\n minimalTheme,\n darkTheme,\n presetThemes,\n defaultTheme,\n} from '@composy/keyboard-core'\n\n// 导出类型\nexport type {\n KeyboardType,\n KeyType,\n KeyDefinition,\n KeyboardRow,\n KeyboardConfig,\n KeyboardState,\n KeyboardEventMap,\n KeyboardOptions,\n DeviceType,\n PopupPlacement,\n Position,\n Size,\n BoundingRect,\n PopupPositionConfig,\n PopupPositionResult,\n ViewportInfo,\n // 主题类型\n ThemeName,\n ThemeColors,\n ThemeSizes,\n ThemeEffects,\n ThemeConfig,\n ThemeCSSVariables,\n // 渲染器类型\n KeyboardRendererOptions,\n // 格式化类型\n FormatterFunction,\n} from '@composy/keyboard-core'\n\n/**\n * 键盘插件配置\n */\nexport interface KeyboardPluginOptions {\n /**\n * 组件前缀\n * @default 'L'\n */\n prefix?: string\n}\n\n/**\n * 原生 Vue 项目键盘插件\n * 用于全局注册键盘组件和指令\n *\n * @example\n * ```typescript\n * import { createApp } from 'vue'\n * import { KeyboardVuePlugin } from '@composy/keyboard-vue'\n *\n * const app = createApp(App)\n * app.use(KeyboardVuePlugin, { prefix: 'L' })\n * ```\n */\nexport const KeyboardVuePlugin: Plugin = {\n install(app: App, options: KeyboardPluginOptions = {}) {\n const prefix = options.prefix ?? 'L'\n\n // 注册组件\n app.component(`${prefix}Keyboard`, VirtualKeyboard)\n app.component(`${prefix}KeyboardPopup`, KeyboardPopup)\n app.component(`${prefix}LicensePlateKeyboard`, LicensePlateKeyboard)\n\n // 注册指令\n app.directive('keyboard', vKeyboard)\n },\n}\n\n/**\n * @deprecated 使用 KeyboardVuePlugin 代替\n */\nexport const KeyboardPlugin = KeyboardVuePlugin\n\n// 默认导出插件\nexport default KeyboardVuePlugin\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8KO,MAAM,oBAA4B,EACvC,QAAQ,KAAU,UAAiC,CAAC,GAAG;CACrD,MAAM,SAAS,QAAQ,UAAU;CAGjC,IAAI,UAAU,GAAG,OAAM,WAAY,wBAAA,OAAe;CAClD,IAAI,UAAU,GAAG,OAAM,gBAAiB,sBAAA,OAAa;CACrD,IAAI,UAAU,GAAG,OAAM,uBAAwB,6BAAA,OAAoB;CAGnE,IAAI,UAAU,YAAY,mBAAA,SAAS;AACrC,EACF;AAKO,MAAM,iBAAiB"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\r\n * @composy/keyboard-vue\r\n * LDesign 虚拟键盘 - Vue 3 适配器\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { App, Plugin } from 'vue'\r\nimport {\r\n KeyboardPopup,\r\n LicensePlateKeyboard,\r\n VirtualKeyboard,\r\n} from './components'\r\nimport { vKeyboard } from './directives/v-keyboard'\r\n\r\n// 导出组件\r\nexport * from './components'\r\n\r\n// 导出 Composables\r\nexport * from './composables'\r\n\r\n// 导出指令\r\nexport * from './directives'\r\n\r\n// 导出插件\r\nexport * from './plugins'\r\n\r\n// 从核心包重新导出\r\nexport {\r\n amountLayout,\r\n amountSimpleLayout,\r\n applyFormatter,\r\n applyTheme,\r\n bankcardLayout,\r\n // 管理器\r\n createKeyboardManager,\r\n createKeyboardRenderer,\r\n createPositionManager,\r\n createRandomLetterLayout,\r\n createRandomMixedLayout,\r\n createRandomNumberLayout,\r\n createRandomPinLayout,\r\n createTheme,\r\n darkTheme,\r\n defaultTheme,\r\n deleteCharBeforeCursor,\r\n EMAIL_SUFFIXES,\r\n emailLayout,\r\n // 工具函数\r\n EventEmitter,\r\n formatAmount,\r\n formatBankCard,\r\n formatIdCard,\r\n formatLicensePlate,\r\n // 格式化工具\r\n formatPhone,\r\n formatVerifyCode,\r\n generateThemeStyle,\r\n getAllThemes,\r\n getAvailableLayouts,\r\n getAvailableThemes,\r\n getBoundingRect,\r\n getCurrentTheme,\r\n getDeviceType,\r\n getFormatter,\r\n // 布局\r\n getLayout,\r\n getRandomAlphanumeric,\r\n getRandomLetters,\r\n getRandomNumbers,\r\n // 主题系统\r\n getTheme,\r\n getViewportInfo,\r\n hasLayout,\r\n // 场景化键盘\r\n idcardLayout,\r\n insertTextAtCursor,\r\n integerLayout,\r\n iosTheme,\r\n isMobile,\r\n isTouchDevice,\r\n KeyboardManager,\r\n KeyboardRenderer,\r\n licensePlateAlphanumericLayout,\r\n licensePlateLayout,\r\n licensePlateLetterLayout,\r\n licensePlateProvinceLayout,\r\n materialTheme,\r\n mergeTheme,\r\n minimalTheme,\r\n miuiTheme,\r\n numberLayout,\r\n onClickOutside,\r\n onViewportChange,\r\n phoneLayout,\r\n phoneSimpleLayout,\r\n PLATE_LETTERS,\r\n PositionManager,\r\n presetThemes,\r\n PROVINCES,\r\n punctLayout,\r\n qwertyLayout,\r\n refreshRandomLayout,\r\n registerFormatter,\r\n registerLayout,\r\n registerLayouts,\r\n registerTheme,\r\n searchLayout,\r\n setCurrentTheme,\r\n // 随机键盘\r\n shuffleArray,\r\n symbolLayout,\r\n symbolLayout2,\r\n themeToCSS,\r\n unregisterLayout,\r\n urlLayout,\r\n verifycodeLayout,\r\n vibrate,\r\n} from '@composy/keyboard-core'\r\n\r\n// 导出类型\r\nexport type {\r\n BoundingRect,\r\n DeviceType,\r\n // 格式化类型\r\n FormatterFunction,\r\n KeyboardConfig,\r\n KeyboardEventMap,\r\n KeyboardOptions,\r\n // 渲染器类型\r\n KeyboardRendererOptions,\r\n KeyboardRow,\r\n KeyboardState,\r\n KeyboardType,\r\n KeyDefinition,\r\n KeyType,\r\n PopupPlacement,\r\n PopupPositionConfig,\r\n PopupPositionResult,\r\n Position,\r\n Size,\r\n ThemeColors,\r\n ThemeConfig,\r\n ThemeCSSVariables,\r\n ThemeEffects,\r\n // 主题类型\r\n ThemeName,\r\n ThemeSizes,\r\n ViewportInfo,\r\n} from '@composy/keyboard-core'\r\n\r\n/**\r\n * 键盘插件配置\r\n */\r\nexport interface KeyboardPluginOptions {\r\n /**\r\n * 组件前缀\r\n * @default 'L'\r\n */\r\n prefix?: string\r\n}\r\n\r\n/**\r\n * 原生 Vue 项目键盘插件\r\n * 用于全局注册键盘组件和指令\r\n *\r\n * @example\r\n * ```typescript\r\n * import { createApp } from 'vue'\r\n * import { KeyboardVuePlugin } from '@composy/keyboard-vue'\r\n *\r\n * const app = createApp(App)\r\n * app.use(KeyboardVuePlugin, { prefix: 'L' })\r\n * ```\r\n */\r\nexport const KeyboardVuePlugin: Plugin = {\r\n install(app: App, options: KeyboardPluginOptions = {}) {\r\n const prefix = options.prefix ?? 'L'\r\n\r\n // 注册组件\r\n app.component(`${prefix}Keyboard`, VirtualKeyboard)\r\n app.component(`${prefix}KeyboardPopup`, KeyboardPopup)\r\n app.component(`${prefix}LicensePlateKeyboard`, LicensePlateKeyboard)\r\n\r\n // 注册指令\r\n app.directive('keyboard', vKeyboard)\r\n },\r\n}\r\n\r\n/**\r\n * @deprecated 使用 KeyboardVuePlugin 代替\r\n */\r\nexport const KeyboardPlugin = KeyboardVuePlugin\r\n\r\n// 默认导出插件\r\nexport default KeyboardVuePlugin\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8KO,MAAM,oBAA4B,EACvC,QAAQ,KAAU,UAAiC,CAAC,GAAG;CACrD,MAAM,SAAS,QAAQ,UAAU;CAGjC,IAAI,UAAU,GAAG,OAAM,WAAY,wBAAA,OAAe;CAClD,IAAI,UAAU,GAAG,OAAM,gBAAiB,sBAAA,OAAa;CACrD,IAAI,UAAU,GAAG,OAAM,uBAAwB,6BAAA,OAAoB;CAGnE,IAAI,UAAU,YAAY,mBAAA,SAAS;AACrC,EACF;AAKO,MAAM,iBAAiB"}