@composy/keyboard-core 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.
- package/README.md +156 -37
- package/dist/index.js +1540 -1395
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2981 -1
- package/dist/index.min.js.map +1 -0
- package/es/.dts-output-manifest.json +1 -0
- package/es/.dts.tsbuildinfo +1 -0
- package/es/icons.d.ts +0 -1
- package/es/icons.js +1 -1
- package/es/icons.js.map +1 -1
- package/es/index.d.ts +3 -4
- package/es/index.js +15 -15
- package/es/layouts/amount.d.ts +0 -1
- package/es/layouts/amount.js +1 -1
- package/es/layouts/amount.js.map +1 -1
- package/es/layouts/bankcard.d.ts +0 -1
- package/es/layouts/bankcard.js +1 -1
- package/es/layouts/bankcard.js.map +1 -1
- package/es/layouts/email.d.ts +0 -1
- package/es/layouts/email.js +1 -1
- package/es/layouts/email.js.map +1 -1
- package/es/layouts/idcard.d.ts +0 -1
- package/es/layouts/idcard.js +1 -1
- package/es/layouts/idcard.js.map +1 -1
- package/es/layouts/index.d.ts +11 -12
- package/es/layouts/index.js +23 -23
- package/es/layouts/index.js.map +1 -1
- package/es/layouts/license-plate.d.ts +0 -1
- package/es/layouts/license-plate.js +1 -1
- package/es/layouts/license-plate.js.map +1 -1
- package/es/layouts/number.d.ts +0 -1
- package/es/layouts/number.js +1 -1
- package/es/layouts/number.js.map +1 -1
- package/es/layouts/phone.d.ts +0 -1
- package/es/layouts/phone.js +1 -1
- package/es/layouts/phone.js.map +1 -1
- package/es/layouts/punct.d.ts +0 -1
- package/es/layouts/punct.js +1 -1
- package/es/layouts/punct.js.map +1 -1
- package/es/layouts/qwerty.d.ts +0 -1
- package/es/layouts/qwerty.js +1 -1
- package/es/layouts/qwerty.js.map +1 -1
- package/es/layouts/search.d.ts +0 -1
- package/es/layouts/search.js +1 -1
- package/es/layouts/search.js.map +1 -1
- package/es/layouts/symbol.d.ts +0 -1
- package/es/layouts/symbol.js +1 -1
- package/es/layouts/symbol.js.map +1 -1
- package/es/layouts/url.d.ts +0 -1
- package/es/layouts/url.js +1 -1
- package/es/layouts/url.js.map +1 -1
- package/es/layouts/verifycode.d.ts +0 -1
- package/es/layouts/verifycode.js +1 -1
- package/es/layouts/verifycode.js.map +1 -1
- package/es/managers/index.d.ts +1 -2
- package/es/managers/index.js +1 -1
- package/es/managers/keyboard-manager.d.ts +2 -1
- package/es/managers/keyboard-manager.js +79 -22
- package/es/managers/keyboard-manager.js.map +1 -1
- package/es/managers/keyboard-renderer.d.ts +3 -2
- package/es/managers/keyboard-renderer.js +81 -39
- package/es/managers/keyboard-renderer.js.map +1 -1
- package/es/managers/position-manager.d.ts +4 -3
- package/es/managers/position-manager.js +42 -21
- package/es/managers/position-manager.js.map +1 -1
- package/es/themes/index.d.ts +1 -2
- package/es/themes/index.js +2 -1
- package/es/themes/index.js.map +1 -1
- package/es/themes/presets.d.ts +0 -1
- package/es/themes/presets.js +1 -1
- package/es/themes/presets.js.map +1 -1
- package/es/themes/types.d.ts +1 -1
- package/es/themes/types.js +1 -1
- package/es/types/index.d.ts +0 -1
- package/es/types/index.js +1 -1
- package/es/types/keyboard.d.ts +0 -1
- package/es/types/keyboard.js +1 -1
- package/es/types/position.d.ts +0 -1
- package/es/types/position.js +1 -1
- package/es/utils/device.d.ts +0 -1
- package/es/utils/device.js +11 -7
- package/es/utils/device.js.map +1 -1
- package/es/utils/dom.d.ts +4 -1
- package/es/utils/dom.js +25 -7
- package/es/utils/dom.js.map +1 -1
- package/es/utils/event-emitter.d.ts +0 -1
- package/es/utils/event-emitter.js +2 -1
- package/es/utils/event-emitter.js.map +1 -1
- package/es/utils/formatters.d.ts +0 -1
- package/es/utils/formatters.js +4 -4
- package/es/utils/formatters.js.map +1 -1
- package/es/utils/index.d.ts +2 -3
- package/es/utils/index.js +5 -5
- package/es/utils/random.d.ts +4 -1
- package/es/utils/random.js +2 -2
- package/es/utils/random.js.map +1 -1
- package/esm/icons.js +1 -1
- package/esm/icons.js.map +1 -1
- package/esm/index.js +15 -15
- package/esm/layouts/amount.js +1 -1
- package/esm/layouts/amount.js.map +1 -1
- package/esm/layouts/bankcard.js +1 -1
- package/esm/layouts/bankcard.js.map +1 -1
- package/esm/layouts/email.js +1 -1
- package/esm/layouts/email.js.map +1 -1
- package/esm/layouts/idcard.js +1 -1
- package/esm/layouts/idcard.js.map +1 -1
- package/esm/layouts/index.js +23 -23
- package/esm/layouts/index.js.map +1 -1
- package/esm/layouts/license-plate.js +1 -1
- package/esm/layouts/license-plate.js.map +1 -1
- package/esm/layouts/number.js +1 -1
- package/esm/layouts/number.js.map +1 -1
- package/esm/layouts/phone.js +1 -1
- package/esm/layouts/phone.js.map +1 -1
- package/esm/layouts/punct.js +1 -1
- package/esm/layouts/punct.js.map +1 -1
- package/esm/layouts/qwerty.js +1 -1
- package/esm/layouts/qwerty.js.map +1 -1
- package/esm/layouts/search.js +1 -1
- package/esm/layouts/search.js.map +1 -1
- package/esm/layouts/symbol.js +1 -1
- package/esm/layouts/symbol.js.map +1 -1
- package/esm/layouts/url.js +1 -1
- package/esm/layouts/url.js.map +1 -1
- package/esm/layouts/verifycode.js +1 -1
- package/esm/layouts/verifycode.js.map +1 -1
- package/esm/managers/index.js +1 -1
- package/esm/managers/keyboard-manager.js +79 -22
- package/esm/managers/keyboard-manager.js.map +1 -1
- package/esm/managers/keyboard-renderer.js +81 -39
- package/esm/managers/keyboard-renderer.js.map +1 -1
- package/esm/managers/position-manager.js +42 -21
- package/esm/managers/position-manager.js.map +1 -1
- package/esm/themes/index.js +2 -1
- package/esm/themes/index.js.map +1 -1
- package/esm/themes/presets.js +1 -1
- package/esm/themes/presets.js.map +1 -1
- package/esm/utils/device.js +11 -7
- package/esm/utils/device.js.map +1 -1
- package/esm/utils/dom.js +25 -7
- package/esm/utils/dom.js.map +1 -1
- package/esm/utils/event-emitter.js +2 -1
- package/esm/utils/event-emitter.js.map +1 -1
- package/esm/utils/formatters.js +4 -4
- package/esm/utils/formatters.js.map +1 -1
- package/esm/utils/random.js +2 -2
- package/esm/utils/random.js.map +1 -1
- package/lib/icons.cjs +1 -1
- package/lib/icons.cjs.map +1 -1
- package/{esm/icons.d.ts → lib/icons.d.cts} +0 -1
- package/lib/index.cjs +14 -13
- package/{esm/index.d.ts → lib/index.d.cts} +3 -4
- package/lib/layouts/amount.cjs +1 -1
- package/lib/layouts/amount.cjs.map +1 -1
- package/{esm/layouts/amount.d.ts → lib/layouts/amount.d.cts} +0 -1
- package/lib/layouts/bankcard.cjs +1 -1
- package/lib/layouts/bankcard.cjs.map +1 -1
- package/{esm/layouts/bankcard.d.ts → lib/layouts/bankcard.d.cts} +0 -1
- package/lib/layouts/email.cjs +1 -1
- package/lib/layouts/email.cjs.map +1 -1
- package/lib/layouts/{email.d.ts → email.d.cts} +0 -1
- package/lib/layouts/idcard.cjs +1 -1
- package/lib/layouts/idcard.cjs.map +1 -1
- package/{esm/layouts/idcard.d.ts → lib/layouts/idcard.d.cts} +0 -1
- package/lib/layouts/index.cjs +23 -23
- package/lib/layouts/index.cjs.map +1 -1
- package/{esm/layouts/index.d.ts → lib/layouts/index.d.cts} +11 -12
- package/lib/layouts/license-plate.cjs +1 -1
- package/lib/layouts/license-plate.cjs.map +1 -1
- package/{esm/layouts/license-plate.d.ts → lib/layouts/license-plate.d.cts} +0 -1
- package/lib/layouts/number.cjs +1 -1
- package/lib/layouts/number.cjs.map +1 -1
- package/{esm/layouts/number.d.ts → lib/layouts/number.d.cts} +0 -1
- package/lib/layouts/phone.cjs +1 -1
- package/lib/layouts/phone.cjs.map +1 -1
- package/lib/layouts/{phone.d.ts → phone.d.cts} +0 -1
- package/lib/layouts/punct.cjs +1 -1
- package/lib/layouts/punct.cjs.map +1 -1
- package/lib/layouts/{punct.d.ts → punct.d.cts} +0 -1
- package/lib/layouts/qwerty.cjs +1 -1
- package/lib/layouts/qwerty.cjs.map +1 -1
- package/{esm/layouts/qwerty.d.ts → lib/layouts/qwerty.d.cts} +0 -1
- package/lib/layouts/search.cjs +1 -1
- package/lib/layouts/search.cjs.map +1 -1
- package/{esm/layouts/search.d.ts → lib/layouts/search.d.cts} +0 -1
- package/lib/layouts/symbol.cjs +1 -1
- package/lib/layouts/symbol.cjs.map +1 -1
- package/{esm/layouts/symbol.d.ts → lib/layouts/symbol.d.cts} +0 -1
- package/lib/layouts/url.cjs +1 -1
- package/lib/layouts/url.cjs.map +1 -1
- package/{esm/layouts/url.d.ts → lib/layouts/url.d.cts} +0 -1
- package/lib/layouts/verifycode.cjs +1 -1
- package/lib/layouts/verifycode.cjs.map +1 -1
- package/lib/layouts/{verifycode.d.ts → verifycode.d.cts} +0 -1
- package/lib/managers/index.cjs +1 -1
- package/lib/managers/{index.d.ts → index.d.cts} +1 -2
- package/lib/managers/keyboard-manager.cjs +79 -22
- package/lib/managers/keyboard-manager.cjs.map +1 -1
- package/lib/managers/{keyboard-manager.d.ts → keyboard-manager.d.cts} +2 -1
- package/lib/managers/keyboard-renderer.cjs +80 -38
- package/lib/managers/keyboard-renderer.cjs.map +1 -1
- package/lib/managers/{keyboard-renderer.d.ts → keyboard-renderer.d.cts} +3 -2
- package/lib/managers/position-manager.cjs +42 -21
- package/lib/managers/position-manager.cjs.map +1 -1
- package/lib/managers/{position-manager.d.ts → position-manager.d.cts} +4 -3
- package/lib/themes/index.cjs +2 -1
- package/lib/themes/index.cjs.map +1 -1
- package/lib/themes/{index.d.ts → index.d.cts} +1 -2
- package/lib/themes/presets.cjs +1 -1
- package/lib/themes/presets.cjs.map +1 -1
- package/lib/themes/{presets.d.ts → presets.d.cts} +0 -1
- package/lib/themes/types.cjs +1 -1
- package/{esm/themes/types.d.ts → lib/themes/types.d.cts} +1 -1
- package/lib/types/index.cjs +1 -1
- package/{esm/types/index.d.ts → lib/types/index.d.cts} +0 -1
- package/lib/types/keyboard.cjs +1 -1
- package/{esm/types/keyboard.d.ts → lib/types/keyboard.d.cts} +0 -1
- package/lib/types/position.cjs +1 -1
- package/lib/types/{position.d.ts → position.d.cts} +0 -1
- package/lib/utils/device.cjs +11 -7
- package/lib/utils/device.cjs.map +1 -1
- package/{esm/utils/device.d.ts → lib/utils/device.d.cts} +0 -1
- package/lib/utils/dom.cjs +25 -6
- package/lib/utils/dom.cjs.map +1 -1
- package/{esm/utils/dom.d.ts → lib/utils/dom.d.cts} +4 -1
- package/lib/utils/event-emitter.cjs +2 -1
- package/lib/utils/event-emitter.cjs.map +1 -1
- package/{esm/utils/event-emitter.d.ts → lib/utils/event-emitter.d.cts} +0 -1
- package/lib/utils/formatters.cjs +4 -4
- package/lib/utils/formatters.cjs.map +1 -1
- package/{esm/utils/formatters.d.ts → lib/utils/formatters.d.cts} +0 -1
- package/lib/utils/index.cjs +4 -3
- package/{esm/utils/index.d.ts → lib/utils/index.d.cts} +2 -3
- package/lib/utils/random.cjs +2 -2
- package/lib/utils/random.cjs.map +1 -1
- package/{esm/utils/random.d.ts → lib/utils/random.d.cts} +4 -1
- package/package.json +28 -14
- package/es/icons.d.ts.map +0 -1
- package/es/index.d.ts.map +0 -1
- package/es/layouts/amount.d.ts.map +0 -1
- package/es/layouts/bankcard.d.ts.map +0 -1
- package/es/layouts/email.d.ts.map +0 -1
- package/es/layouts/idcard.d.ts.map +0 -1
- package/es/layouts/index.d.ts.map +0 -1
- package/es/layouts/license-plate.d.ts.map +0 -1
- package/es/layouts/number.d.ts.map +0 -1
- package/es/layouts/phone.d.ts.map +0 -1
- package/es/layouts/punct.d.ts.map +0 -1
- package/es/layouts/qwerty.d.ts.map +0 -1
- package/es/layouts/search.d.ts.map +0 -1
- package/es/layouts/symbol.d.ts.map +0 -1
- package/es/layouts/url.d.ts.map +0 -1
- package/es/layouts/verifycode.d.ts.map +0 -1
- package/es/managers/index.d.ts.map +0 -1
- package/es/managers/keyboard-manager.d.ts.map +0 -1
- package/es/managers/keyboard-renderer.d.ts.map +0 -1
- package/es/managers/position-manager.d.ts.map +0 -1
- package/es/themes/index.d.ts.map +0 -1
- package/es/themes/presets.d.ts.map +0 -1
- package/es/themes/types.d.ts.map +0 -1
- package/es/types/index.d.ts.map +0 -1
- package/es/types/keyboard.d.ts.map +0 -1
- package/es/types/position.d.ts.map +0 -1
- package/es/utils/device.d.ts.map +0 -1
- package/es/utils/dom.d.ts.map +0 -1
- package/es/utils/event-emitter.d.ts.map +0 -1
- package/es/utils/formatters.d.ts.map +0 -1
- package/es/utils/index.d.ts.map +0 -1
- package/es/utils/random.d.ts.map +0 -1
- package/esm/icons.d.ts.map +0 -1
- package/esm/index.d.ts.map +0 -1
- package/esm/layouts/amount.d.ts.map +0 -1
- package/esm/layouts/bankcard.d.ts.map +0 -1
- package/esm/layouts/email.d.ts +0 -11
- package/esm/layouts/email.d.ts.map +0 -1
- package/esm/layouts/idcard.d.ts.map +0 -1
- package/esm/layouts/index.d.ts.map +0 -1
- package/esm/layouts/license-plate.d.ts.map +0 -1
- package/esm/layouts/number.d.ts.map +0 -1
- package/esm/layouts/phone.d.ts +0 -15
- package/esm/layouts/phone.d.ts.map +0 -1
- package/esm/layouts/punct.d.ts +0 -7
- package/esm/layouts/punct.d.ts.map +0 -1
- package/esm/layouts/qwerty.d.ts.map +0 -1
- package/esm/layouts/search.d.ts.map +0 -1
- package/esm/layouts/symbol.d.ts.map +0 -1
- package/esm/layouts/url.d.ts.map +0 -1
- package/esm/layouts/verifycode.d.ts +0 -15
- package/esm/layouts/verifycode.d.ts.map +0 -1
- package/esm/managers/index.d.ts +0 -8
- package/esm/managers/index.d.ts.map +0 -1
- package/esm/managers/keyboard-manager.d.ts +0 -130
- package/esm/managers/keyboard-manager.d.ts.map +0 -1
- package/esm/managers/keyboard-renderer.d.ts +0 -115
- package/esm/managers/keyboard-renderer.d.ts.map +0 -1
- package/esm/managers/position-manager.d.ts +0 -72
- package/esm/managers/position-manager.d.ts.map +0 -1
- package/esm/themes/index.d.ts +0 -70
- package/esm/themes/index.d.ts.map +0 -1
- package/esm/themes/presets.d.ts +0 -39
- package/esm/themes/presets.d.ts.map +0 -1
- package/esm/themes/types.d.ts.map +0 -1
- package/esm/themes/types.js +0 -10
- package/esm/types/index.d.ts.map +0 -1
- package/esm/types/index.js +0 -10
- package/esm/types/keyboard.d.ts.map +0 -1
- package/esm/types/keyboard.js +0 -10
- package/esm/types/position.d.ts +0 -139
- package/esm/types/position.d.ts.map +0 -1
- package/esm/types/position.js +0 -10
- package/esm/utils/device.d.ts.map +0 -1
- package/esm/utils/dom.d.ts.map +0 -1
- package/esm/utils/event-emitter.d.ts.map +0 -1
- package/esm/utils/formatters.d.ts.map +0 -1
- package/esm/utils/index.d.ts.map +0 -1
- package/esm/utils/index.js +0 -16
- package/esm/utils/random.d.ts.map +0 -1
- package/lib/icons.d.ts +0 -58
- package/lib/index.d.ts +0 -12
- package/lib/layouts/amount.d.ts +0 -14
- package/lib/layouts/bankcard.d.ts +0 -15
- package/lib/layouts/idcard.d.ts +0 -16
- package/lib/layouts/index.d.ts +0 -54
- package/lib/layouts/license-plate.d.ts +0 -35
- package/lib/layouts/number.d.ts +0 -14
- package/lib/layouts/qwerty.d.ts +0 -10
- package/lib/layouts/search.d.ts +0 -7
- package/lib/layouts/symbol.d.ts +0 -14
- package/lib/layouts/url.d.ts +0 -7
- package/lib/themes/types.d.ts +0 -118
- package/lib/types/index.d.ts +0 -7
- package/lib/types/keyboard.d.ts +0 -253
- package/lib/utils/device.d.ts +0 -45
- package/lib/utils/dom.d.ts +0 -69
- package/lib/utils/event-emitter.d.ts +0 -52
- package/lib/utils/formatters.d.ts +0 -51
- package/lib/utils/index.d.ts +0 -10
- package/lib/utils/random.d.ts +0 -71
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol.js","names":[],"sources":["../../src/layouts/symbol.ts"],"sourcesContent":["/**\n * 符号键盘布局\n * @module layouts/symbol\n */\n\nimport type { KeyboardConfig, KeyDefinition } from '../types'\n\n/**\n * 创建符号按键\n */\nfunction createSymbolKey(symbol: string, id?: string): KeyDefinition {\n return {\n id: id || `symbol-${symbol.charCodeAt(0)}`,\n type: 'char',\n label: symbol,\n value: symbol,\n }\n}\n\n/**\n * 符号键盘配置\n */\nexport const symbolLayout: KeyboardConfig = {\n type: 'symbol',\n name: '符号键盘',\n supportShift: false,\n switchable: ['qwerty', 'number'],\n rows: [\n {\n keys: [\n createSymbolKey('1'),\n createSymbolKey('2'),\n createSymbolKey('3'),\n createSymbolKey('4'),\n createSymbolKey('5'),\n createSymbolKey('6'),\n createSymbolKey('7'),\n createSymbolKey('8'),\n createSymbolKey('9'),\n createSymbolKey('0'),\n ],\n },\n {\n keys: [\n createSymbolKey('-'),\n createSymbolKey('/'),\n createSymbolKey(':'),\n createSymbolKey(';'),\n createSymbolKey('('),\n createSymbolKey(')'),\n createSymbolKey('¥', 'yen'),\n createSymbolKey('@'),\n createSymbolKey('\"', 'quote'),\n ],\n },\n {\n keys: [\n {\n id: 'switch-symbol-2',\n type: 'tab',\n label: '#+= ',\n width: 1.5,\n className: 'key-switch',\n data: { targetType: 'symbol-2' },\n },\n createSymbolKey('.'),\n createSymbolKey(','),\n createSymbolKey('?'),\n createSymbolKey('!'),\n createSymbolKey('
|
|
1
|
+
{"version":3,"file":"symbol.js","names":[],"sources":["../../src/layouts/symbol.ts"],"sourcesContent":["/**\r\n * 符号键盘布局\r\n * @module layouts/symbol\r\n */\r\n\r\nimport type { KeyboardConfig, KeyDefinition } from '../types'\r\n\r\n/**\r\n * 创建符号按键\r\n */\r\nfunction createSymbolKey(symbol: string, id?: string): KeyDefinition {\r\n return {\r\n id: id || `symbol-${symbol.charCodeAt(0)}`,\r\n type: 'char',\r\n label: symbol,\r\n value: symbol,\r\n }\r\n}\r\n\r\n/**\r\n * 符号键盘配置\r\n */\r\nexport const symbolLayout: KeyboardConfig = {\r\n type: 'symbol',\r\n name: '符号键盘',\r\n supportShift: false,\r\n switchable: ['qwerty', 'number'],\r\n rows: [\r\n {\r\n keys: [\r\n createSymbolKey('1'),\r\n createSymbolKey('2'),\r\n createSymbolKey('3'),\r\n createSymbolKey('4'),\r\n createSymbolKey('5'),\r\n createSymbolKey('6'),\r\n createSymbolKey('7'),\r\n createSymbolKey('8'),\r\n createSymbolKey('9'),\r\n createSymbolKey('0'),\r\n ],\r\n },\r\n {\r\n keys: [\r\n createSymbolKey('-'),\r\n createSymbolKey('/'),\r\n createSymbolKey(':'),\r\n createSymbolKey(';'),\r\n createSymbolKey('('),\r\n createSymbolKey(')'),\r\n createSymbolKey('¥', 'yen'),\r\n createSymbolKey('@'),\r\n createSymbolKey('\"', 'quote'),\r\n ],\r\n },\r\n {\r\n keys: [\r\n {\r\n id: 'switch-symbol-2',\r\n type: 'tab',\r\n label: '#+= ',\r\n width: 1.5,\r\n className: 'key-switch',\r\n data: { targetType: 'symbol-2' },\r\n },\r\n createSymbolKey('.'),\r\n createSymbolKey(','),\r\n createSymbolKey('?'),\r\n createSymbolKey('!'),\r\n createSymbolKey(\"'\", 'apostrophe'),\r\n {\r\n id: 'backspace',\r\n type: 'backspace',\r\n label: '⌫',\r\n width: 1.5,\r\n className: 'key-backspace',\r\n },\r\n ],\r\n },\r\n {\r\n keys: [\r\n {\r\n id: 'switch-qwerty',\r\n type: 'tab',\r\n label: 'ABC',\r\n width: 1.5,\r\n className: 'key-switch',\r\n data: { targetType: 'qwerty' },\r\n },\r\n {\r\n id: 'switch-number',\r\n type: 'tab',\r\n label: '123',\r\n width: 1.25,\r\n className: 'key-switch',\r\n data: { targetType: 'number' },\r\n },\r\n {\r\n id: 'space',\r\n type: 'space',\r\n label: '空格',\r\n value: ' ',\r\n width: 4,\r\n className: 'key-space',\r\n },\r\n {\r\n id: 'done',\r\n type: 'done',\r\n label: '完成',\r\n width: 2,\r\n className: 'key-done',\r\n },\r\n ],\r\n },\r\n ],\r\n}\r\n\r\n/**\r\n * 符号键盘第二页\r\n */\r\nexport const symbolLayout2: KeyboardConfig = {\r\n type: 'symbol',\r\n name: '符号键盘2',\r\n supportShift: false,\r\n switchable: ['qwerty', 'number'],\r\n rows: [\r\n {\r\n keys: [\r\n createSymbolKey('['),\r\n createSymbolKey(']'),\r\n createSymbolKey('{'),\r\n createSymbolKey('}'),\r\n createSymbolKey('#'),\r\n createSymbolKey('%'),\r\n createSymbolKey('^'),\r\n createSymbolKey('*'),\r\n createSymbolKey('+'),\r\n createSymbolKey('='),\r\n ],\r\n },\r\n {\r\n keys: [\r\n createSymbolKey('_'),\r\n createSymbolKey('\\\\'),\r\n createSymbolKey('|'),\r\n createSymbolKey('~'),\r\n createSymbolKey('<'),\r\n createSymbolKey('>'),\r\n createSymbolKey('€', 'euro'),\r\n createSymbolKey('$'),\r\n createSymbolKey('&'),\r\n ],\r\n },\r\n {\r\n keys: [\r\n {\r\n id: 'switch-symbol-1',\r\n type: 'tab',\r\n label: '123',\r\n width: 1.5,\r\n className: 'key-switch',\r\n data: { targetType: 'symbol' },\r\n },\r\n createSymbolKey('`', 'backtick'),\r\n createSymbolKey('·', 'middle-dot'),\r\n createSymbolKey('…', 'ellipsis'),\r\n createSymbolKey('°', 'degree'),\r\n createSymbolKey('•', 'bullet'),\r\n {\r\n id: 'backspace',\r\n type: 'backspace',\r\n label: '⌫',\r\n width: 1.5,\r\n className: 'key-backspace',\r\n },\r\n ],\r\n },\r\n {\r\n keys: [\r\n {\r\n id: 'switch-qwerty',\r\n type: 'tab',\r\n label: 'ABC',\r\n width: 1.5,\r\n className: 'key-switch',\r\n data: { targetType: 'qwerty' },\r\n },\r\n {\r\n id: 'switch-number',\r\n type: 'tab',\r\n label: '123',\r\n width: 1.25,\r\n className: 'key-switch',\r\n data: { targetType: 'number' },\r\n },\r\n {\r\n id: 'space',\r\n type: 'space',\r\n label: '空格',\r\n value: ' ',\r\n width: 4,\r\n className: 'key-space',\r\n },\r\n {\r\n id: 'done',\r\n type: 'done',\r\n label: '完成',\r\n width: 2,\r\n className: 'key-done',\r\n },\r\n ],\r\n },\r\n ],\r\n}\r\n"],"mappings":"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"}
|
package/esm/layouts/url.js
CHANGED
package/esm/layouts/url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","names":[],"sources":["../../src/layouts/url.ts"],"sourcesContent":["/**\n * URL/链接键盘布局\n * @module layouts/url\n */\n\n// 导入键盘配置和按键定义的类型\nimport type { KeyboardConfig, KeyDefinition } from '../types'\n// 导入删除和Shift图标资源\nimport { ICON_DELETE, ICON_SHIFT } from '../icons'\n\n/**\n * 创建字符按键(支持大小写)\n * @param char - 字符,用于生成大小写标签和值\n * @returns 返回一个按键定义对象\n */\nfunction createCharKey(char: string): KeyDefinition {\n return {\n id: `url-char-${char.toLowerCase()}`,
|
|
1
|
+
{"version":3,"file":"url.js","names":[],"sources":["../../src/layouts/url.ts"],"sourcesContent":["/**\r\n * URL/链接键盘布局\r\n * @module layouts/url\r\n */\r\n\r\n// 导入键盘配置和按键定义的类型\r\nimport type { KeyboardConfig, KeyDefinition } from '../types'\r\n// 导入删除和Shift图标资源\r\nimport { ICON_DELETE, ICON_SHIFT } from '../icons'\r\n\r\n/**\r\n * 创建字符按键(支持大小写)\r\n * @param char - 字符,用于生成大小写标签和值\r\n * @returns 返回一个按键定义对象\r\n */\r\nfunction createCharKey(char: string): KeyDefinition {\r\n return {\r\n id: `url-char-${char.toLowerCase()}`, // 按键唯一标识,格式为 url-char-x\r\n type: 'char', // 按键类型为字符键\r\n label: { lower: char.toLowerCase(), upper: char.toUpperCase() }, // 显示标签:小写/大写\r\n value: { lower: char.toLowerCase(), upper: char.toUpperCase() }, // 输出值:小写/大写\r\n }\r\n}\r\n\r\n/**\r\n * 创建快捷片段按键\r\n * 用于URL键盘中常用的符号和域名后缀\r\n * @param label - 按键显示文本\r\n * @param width - 可选,按键宽度倍数\r\n * @returns 返回一个片段按键定义对象\r\n */\r\nfunction snippet(label: string, width?: number): KeyDefinition {\r\n // 生成唯一 ID:用 label 的字符编码(去除非法字符后拼接)\r\n const idSuffix =\r\n label.replace(/[^a-z0-9]/gi, '') ||\r\n label\r\n .split('')\r\n .map(c => c.charCodeAt(0))\r\n .join('')\r\n return {\r\n id: `url-snippet-${idSuffix}`, // 按键唯一标识,格式为 url-snippet-xxx\r\n type: 'char', // 按键类型为字符键\r\n label, // 显示文本\r\n value: label, // 输出值与显示文本相同\r\n width, // 按键宽度倍数\r\n className: 'key-snippet', // 自定义CSS类名,用于样式控制\r\n }\r\n}\r\n\r\n// 导出URL键盘布局配置\r\nexport const urlLayout: KeyboardConfig = {\r\n type: 'url', // 布局类型标识为 url\r\n name: '网址键盘', // 布局显示名称\r\n supportShift: true, // 支持Shift切换大小写\r\n defaultUpperCase: false, // 默认为小写状态\r\n switchable: ['symbol', 'number'], // 可切换到符号键盘和数字键盘\r\n rows: [\r\n // QWERTY 第一行:q w e r t y u i o p\r\n {\r\n keys: 'qwertyuiop'.split('').map(createCharKey), // 将字符串拆分为字符数组,逐个创建按键\r\n },\r\n // QWERTY 第二行:a s d f g h j k l\r\n {\r\n keys: 'asdfghjkl'.split('').map(createCharKey), // 将字符串拆分为字符数组,逐个创建按键\r\n },\r\n // QWERTY 第三行 + Shift + 退格\r\n {\r\n keys: [\r\n {\r\n id: 'shift', // Shift键标识\r\n type: 'shift', // 按键类型为Shift\r\n icon: ICON_SHIFT, // 使用Shift图标\r\n label: '', // 无文字标签,仅显示图标\r\n width: 1.5, // 宽度为1.5倍\r\n className: 'key-shift', // CSS类名\r\n },\r\n ...'zxcvbnm'.split('').map(createCharKey), // 展开第三行字母 z x c v b n m 的按键定义\r\n {\r\n id: 'backspace', // 退格键标识\r\n type: 'backspace', // 按键类型为退格\r\n icon: ICON_DELETE, // 使用删除图标\r\n label: '', // 无文字标签,仅显示图标\r\n width: 1.5, // 宽度为1.5倍\r\n className: 'key-backspace', // CSS类名\r\n },\r\n ],\r\n },\r\n // 底部行:切换 + 符号 + 域名后缀 + 前往\r\n {\r\n keys: [\r\n {\r\n id: 'switch-number',\r\n type: 'tab',\r\n label: '123',\r\n width: 1.2,\r\n className: 'key-switch',\r\n data: { targetType: 'number' },\r\n }, // 切换到数字键盘\r\n snippet('/', 0.8), // 斜杠快捷键,宽度0.8倍\r\n snippet('.', 0.8), // 点号快捷键,宽度0.8倍\r\n snippet('-', 0.8), // 横杠快捷键,宽度0.8倍\r\n snippet('.com', 1.5), // .com域名后缀快捷键,宽度1.5倍\r\n snippet('.cn', 1.2), // .cn域名后缀快捷键,宽度1.2倍\r\n {\r\n id: 'space',\r\n type: 'space',\r\n label: '',\r\n value: ' ',\r\n width: 1.5,\r\n className: 'key-space',\r\n }, // 空格键,宽度1.5倍\r\n {\r\n id: 'url-go',\r\n type: 'done',\r\n label: '前往',\r\n width: 1.5,\r\n className: 'key-done',\r\n }, // 前往/完成按钮,宽度1.5倍\r\n ],\r\n },\r\n ],\r\n}\r\n"],"mappings":";;;;;;;;;;;AAeA,SAAS,cAAc,MAA6B;CAClD,OAAO;EACL,IAAI,YAAY,KAAK,YAAY;EACjC,MAAM;EACN,OAAO;GAAE,OAAO,KAAK,YAAY;GAAG,OAAO,KAAK,YAAY;EAAE;EAC9D,OAAO;GAAE,OAAO,KAAK,YAAY;GAAG,OAAO,KAAK,YAAY;EAAE;CAChE;AACF;AASA,SAAS,QAAQ,OAAe,OAA+B;CAQ7D,OAAO;EACL,IAAI,eANJ,MAAM,QAAQ,eAAe,EAAE,KAC/B,MACG,MAAM,EAAE,CAAA,CACR,KAAI,MAAK,EAAE,WAAW,CAAC,CAAC,CAAA,CACxB,KAAK,EAAE;EAGV,MAAM;EACN;EACA,OAAO;EACP;EACA,WAAW;CACb;AACF;AAGO,MAAM,YAA4B;CACvC,MAAM;CACN,MAAM;CACN,cAAc;CACd,kBAAkB;CAClB,YAAY,CAAC,UAAU,QAAQ;CAC/B,MAAM;EAEJ,EACE,MAAM,aAAa,MAAM,EAAE,CAAA,CAAE,IAAI,aAAa,EAChD;EAEA,EACE,MAAM,YAAY,MAAM,EAAE,CAAA,CAAE,IAAI,aAAa,EAC/C;EAEA,EACE,MAAM;GACJ;IACE,IAAI;IACJ,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,WAAW;GACb;GACA,GAAG,UAAU,MAAM,EAAE,CAAA,CAAE,IAAI,aAAa;GACxC;IACE,IAAI;IACJ,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,WAAW;GACb;EACF,EACF;EAEA,EACE,MAAM;GACJ;IACE,IAAI;IACJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,WAAW;IACX,MAAM,EAAE,YAAY,SAAS;GAC/B;GACA,QAAQ,KAAK,EAAG;GAChB,QAAQ,KAAK,EAAG;GAChB,QAAQ,KAAK,EAAG;GAChB,QAAQ,QAAQ,GAAG;GACnB,QAAQ,OAAO,GAAG;GAClB;IACE,IAAI;IACJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,WAAW;GACb;GACA;IACE,IAAI;IACJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,WAAW;GACb;EACF,EACF;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifycode.js","names":[],"sources":["../../src/layouts/verifycode.ts"],"sourcesContent":["/**\n * 验证码键盘布局\n * @module layouts/verifycode\n */\n\n// 从类型定义文件中导入 KeyboardConfig(键盘配置)和 KeyDefinition(按键定义)类型\nimport type { KeyboardConfig, KeyDefinition } from '../types'\n// 从图标模块中导入删除键图标和清除键图标\nimport {
|
|
1
|
+
{"version":3,"file":"verifycode.js","names":[],"sources":["../../src/layouts/verifycode.ts"],"sourcesContent":["/**\r\n * 验证码键盘布局\r\n * @module layouts/verifycode\r\n */\r\n\r\n// 从类型定义文件中导入 KeyboardConfig(键盘配置)和 KeyDefinition(按键定义)类型\r\nimport type { KeyboardConfig, KeyDefinition } from '../types'\r\n// 从图标模块中导入删除键图标和清除键图标\r\nimport { ICON_CLEAR, ICON_DELETE } from '../icons'\r\n\r\n/**\r\n * 创建数字按键\r\n * @param num - 数字字符串(如 '0'-'9')\r\n * @returns 返回一个按键定义对象\r\n */\r\nfunction createNumberKey(num: string): KeyDefinition {\r\n return {\r\n id: `verify-${num}`, // 按键唯一标识符,格式为 verify-数字\r\n type: 'char', // 按键类型为字符键\r\n label: num, // 按键上显示的文本\r\n value: num, // 按键按下后输出的值\r\n className: 'key-num', // 按键的 CSS 类名,用于样式定制\r\n }\r\n}\r\n\r\n/**\r\n * 验证码键盘配置 - 4x4布局(与其他数字键盘一致)\r\n * 布局结构:\r\n * 第1行: 1 2 3 [退格]\r\n * 第2行: 4 5 6 [清除]\r\n * 第3行: 7 8 9 [关闭]\r\n * 第4行: [空] 0 [确定(占2格)]\r\n */\r\nexport const verifycodeLayout: KeyboardConfig = {\r\n type: 'verifycode', // 键盘类型标识\r\n name: '验证码键盘', // 键盘的显示名称\r\n supportShift: false, // 不支持 Shift 切换(纯数字键盘无需切换)\r\n rows: [\r\n // 键盘的行数组\r\n // ---- 第1行 ----\r\n {\r\n className: 'numpad-row', // 行的 CSS 类名\r\n keys: [\r\n // 该行包含的按键数组\r\n createNumberKey('1'), // 数字键 1\r\n createNumberKey('2'), // 数字键 2\r\n createNumberKey('3'), // 数字键 3\r\n {\r\n id: 'backspace', // 退格键的唯一标识\r\n type: 'backspace', // 按键类型为退格,删除最后一个字符\r\n icon: ICON_DELETE, // 使用删除图标作为显示内容\r\n label: '', // 无文本标签(由图标替代)\r\n className: 'key-numpad-fn', // 功能键的 CSS 类名\r\n },\r\n ],\r\n },\r\n // ---- 第2行 ----\r\n {\r\n className: 'numpad-row', // 行的 CSS 类名\r\n keys: [\r\n createNumberKey('4'), // 数字键 4\r\n createNumberKey('5'), // 数字键 5\r\n createNumberKey('6'), // 数字键 6\r\n {\r\n id: 'clear', // 清除键的唯一标识\r\n type: 'clear', // 按键类型为清除,清空所有输入\r\n icon: ICON_CLEAR, // 使用清除图标作为显示内容\r\n label: '', // 无文本标签\r\n className: 'key-numpad-fn', // 功能键的 CSS 类名\r\n },\r\n ],\r\n },\r\n // ---- 第3行 ----\r\n {\r\n className: 'numpad-row', // 行的 CSS 类名\r\n keys: [\r\n createNumberKey('7'), // 数字键 7\r\n createNumberKey('8'), // 数字键 8\r\n createNumberKey('9'), // 数字键 9\r\n {\r\n id: 'close', // 关闭键的唯一标识\r\n type: 'close', // 按键类型为关闭,收起键盘\r\n label: '关闭', // 按钮上显示的文本\r\n className: 'key-numpad-fn', // 功能键的 CSS 类名\r\n },\r\n ],\r\n },\r\n // ---- 第4行 ----\r\n {\r\n className: 'numpad-row', // 行的 CSS 类名\r\n keys: [\r\n {\r\n id: 'empty', // 占位空键的唯一标识\r\n type: 'char', // 类型为字符键(但被禁用)\r\n label: '', // 无显示文本\r\n value: '', // 无输出值\r\n disabled: true, // 禁用状态,不可点击\r\n className: 'key-numpad-empty', // 空占位键的 CSS 类名\r\n },\r\n createNumberKey('0'), // 数字键 0\r\n {\r\n id: 'done', // 确定键的唯一标识\r\n type: 'done', // 按键类型为确定,完成输入\r\n label: '确定', // 按钮上显示的文本\r\n width: 2, // 占据 2 个键的宽度\r\n className: 'key-numpad-done', // 确定键的 CSS 类名\r\n },\r\n ],\r\n },\r\n ],\r\n data: {\r\n // 键盘的附加数据\r\n maxLength: 6, // 验证码最大输入长度为 6 位\r\n inputType: 'verifycode', // 输入类型标识,用于外部判断\r\n },\r\n}\r\n"],"mappings":";;;;;;;;;;;AAeA,SAAS,gBAAgB,KAA4B;CACnD,OAAO;EACL,IAAI,UAAU;EACd,MAAM;EACN,OAAO;EACP,OAAO;EACP,WAAW;CACb;AACF;AAUO,MAAM,mBAAmC;CAC9C,MAAM;CACN,MAAM;CACN,cAAc;CACd,MAAM;EAGJ;GACE,WAAW;GACX,MAAM;IAEJ,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB;KACE,IAAI;KACJ,MAAM;KACN,MAAM;KACN,OAAO;KACP,WAAW;IACb;GACF;EACF;EAEA;GACE,WAAW;GACX,MAAM;IACJ,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB;KACE,IAAI;KACJ,MAAM;KACN,MAAM;KACN,OAAO;KACP,WAAW;IACb;GACF;EACF;EAEA;GACE,WAAW;GACX,MAAM;IACJ,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB,gBAAgB,GAAG;IACnB;KACE,IAAI;KACJ,MAAM;KACN,OAAO;KACP,WAAW;IACb;GACF;EACF;EAEA;GACE,WAAW;GACX,MAAM;IACJ;KACE,IAAI;KACJ,MAAM;KACN,OAAO;KACP,OAAO;KACP,UAAU;KACV,WAAW;IACb;IACA,gBAAgB,GAAG;IACnB;KACE,IAAI;KACJ,MAAM;KACN,OAAO;KACP,OAAO;KACP,WAAW;IACb;GACF;EACF;CACF;CACA,MAAM;EAEJ,WAAW;EACX,WAAW;CACb;AACF"}
|
package/esm/managers/index.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* ***********************************
|
|
3
3
|
* @composy/keyboard-core v0.0.1 *
|
|
4
4
|
* Built with rollup *
|
|
5
|
-
* Build time: 2024-
|
|
5
|
+
* Build time: 2024-10-12 17:29:15 *
|
|
6
6
|
* Build mode: production *
|
|
7
7
|
* Minified: No *
|
|
8
8
|
* ***********************************
|
|
9
9
|
*/
|
|
10
10
|
import { getLayout } from "../layouts/index.js";
|
|
11
|
-
import { EventEmitter } from "../utils/event-emitter.js";
|
|
12
11
|
import { isMobile, vibrate } from "../utils/device.js";
|
|
13
12
|
import { deleteCharBeforeCursor, getInputCursorPosition, insertTextAtCursor, setInputCursorPosition } from "../utils/dom.js";
|
|
13
|
+
import { EventEmitter } from "../utils/event-emitter.js";
|
|
14
14
|
//#region src/managers/keyboard-manager.ts
|
|
15
15
|
const DEFAULT_OPTIONS = {
|
|
16
16
|
type: "qwerty",
|
|
@@ -22,14 +22,28 @@ const DEFAULT_OPTIONS = {
|
|
|
22
22
|
enableVibrate: true,
|
|
23
23
|
customLayouts: {}
|
|
24
24
|
};
|
|
25
|
+
function normalizeMaxLength(value) {
|
|
26
|
+
if (value === void 0 || !Number.isFinite(value)) return void 0;
|
|
27
|
+
return Math.max(0, Math.floor(value));
|
|
28
|
+
}
|
|
29
|
+
function clampValue(value, maxLength) {
|
|
30
|
+
return maxLength === void 0 ? value : value.slice(0, maxLength);
|
|
31
|
+
}
|
|
25
32
|
var KeyboardManager = class extends EventEmitter {
|
|
26
33
|
constructor(options = {}) {
|
|
27
34
|
super();
|
|
28
35
|
/** 当前布局配置 */
|
|
29
36
|
this.currentLayout = null;
|
|
37
|
+
this.destroyed = false;
|
|
38
|
+
const maxLength = normalizeMaxLength(options.maxLength);
|
|
30
39
|
this.options = {
|
|
31
40
|
...DEFAULT_OPTIONS,
|
|
32
|
-
...options
|
|
41
|
+
...options,
|
|
42
|
+
maxLength,
|
|
43
|
+
customLayouts: {
|
|
44
|
+
...DEFAULT_OPTIONS.customLayouts,
|
|
45
|
+
...options.customLayouts ?? {}
|
|
46
|
+
}
|
|
33
47
|
};
|
|
34
48
|
if (options.customLayouts) Object.entries(options.customLayouts).forEach(([name, layout]) => {
|
|
35
49
|
this.options.customLayouts[name] = layout;
|
|
@@ -38,8 +52,8 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
38
52
|
visible: false,
|
|
39
53
|
type: this.options.type,
|
|
40
54
|
isUpperCase: this.options.defaultUpperCase,
|
|
41
|
-
value: this.options.value,
|
|
42
|
-
cursorPosition: this.options.value.length,
|
|
55
|
+
value: clampValue(this.options.value, this.options.maxLength),
|
|
56
|
+
cursorPosition: clampValue(this.options.value, this.options.maxLength).length,
|
|
43
57
|
maxLength: this.options.maxLength,
|
|
44
58
|
inputElement: null
|
|
45
59
|
};
|
|
@@ -61,7 +75,10 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
61
75
|
* 获取配置选项
|
|
62
76
|
*/
|
|
63
77
|
getOptions() {
|
|
64
|
-
return {
|
|
78
|
+
return {
|
|
79
|
+
...this.options,
|
|
80
|
+
customLayouts: { ...this.options.customLayouts }
|
|
81
|
+
};
|
|
65
82
|
}
|
|
66
83
|
/**
|
|
67
84
|
* 加载键盘布局
|
|
@@ -81,7 +98,11 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
81
98
|
* 显示键盘
|
|
82
99
|
*/
|
|
83
100
|
show(inputElement) {
|
|
84
|
-
if (this.
|
|
101
|
+
if (this.destroyed) return;
|
|
102
|
+
if (this.state.visible) {
|
|
103
|
+
if (inputElement && this.state.inputElement !== inputElement) this.bindInput(inputElement);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
85
106
|
this.state.visible = true;
|
|
86
107
|
this.state.inputElement = inputElement ?? null;
|
|
87
108
|
if (inputElement) {
|
|
@@ -95,6 +116,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
95
116
|
* 隐藏键盘
|
|
96
117
|
*/
|
|
97
118
|
hide() {
|
|
119
|
+
if (this.destroyed) return;
|
|
98
120
|
if (!this.state.visible) return;
|
|
99
121
|
const prevType = this.state.type;
|
|
100
122
|
this.state.visible = false;
|
|
@@ -106,6 +128,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
106
128
|
* 切换键盘显示/隐藏
|
|
107
129
|
*/
|
|
108
130
|
toggle(inputElement) {
|
|
131
|
+
if (this.destroyed) return;
|
|
109
132
|
if (this.state.visible) this.hide();
|
|
110
133
|
else this.show(inputElement);
|
|
111
134
|
}
|
|
@@ -113,6 +136,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
113
136
|
* 切换键盘类型
|
|
114
137
|
*/
|
|
115
138
|
switchType(type) {
|
|
139
|
+
if (this.destroyed) return;
|
|
116
140
|
if (this.state.type === type) return;
|
|
117
141
|
const fromType = this.state.type;
|
|
118
142
|
if (!this.loadLayout(type)) return;
|
|
@@ -127,6 +151,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
127
151
|
* 切换大小写
|
|
128
152
|
*/
|
|
129
153
|
toggleShift() {
|
|
154
|
+
if (this.destroyed) return;
|
|
130
155
|
if (!this.currentLayout?.supportShift) return;
|
|
131
156
|
this.state.isUpperCase = !this.state.isUpperCase;
|
|
132
157
|
this.emitStateChange();
|
|
@@ -136,6 +161,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
136
161
|
* 设置大小写状态
|
|
137
162
|
*/
|
|
138
163
|
setShift(isUpperCase) {
|
|
164
|
+
if (this.destroyed) return;
|
|
139
165
|
if (!this.currentLayout?.supportShift) return;
|
|
140
166
|
if (this.state.isUpperCase === isUpperCase) return;
|
|
141
167
|
this.state.isUpperCase = isUpperCase;
|
|
@@ -146,6 +172,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
146
172
|
* 处理按键
|
|
147
173
|
*/
|
|
148
174
|
handleKey(key) {
|
|
175
|
+
if (this.destroyed) return;
|
|
149
176
|
if (this.options.enableVibrate && isMobile()) vibrate(10);
|
|
150
177
|
this.emit("keypress", {
|
|
151
178
|
key,
|
|
@@ -191,12 +218,15 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
191
218
|
setInputCursorPosition(input, result.cursorPosition);
|
|
192
219
|
this.state.value = result.value;
|
|
193
220
|
this.state.cursorPosition = result.cursorPosition;
|
|
194
|
-
|
|
221
|
+
this.dispatchInputEvent(input);
|
|
195
222
|
} else {
|
|
196
|
-
if (this.state.maxLength && this.state.value.length >= this.state.maxLength) return;
|
|
197
|
-
const
|
|
223
|
+
if (this.state.maxLength !== void 0 && this.state.value.length >= this.state.maxLength) return;
|
|
224
|
+
const availableLength = this.state.maxLength === void 0 ? keyValue.length : this.state.maxLength - this.state.value.length;
|
|
225
|
+
const valueToInsert = keyValue.slice(0, Math.max(0, availableLength));
|
|
226
|
+
if (!valueToInsert) return;
|
|
227
|
+
const newValue = this.state.value.slice(0, this.state.cursorPosition) + valueToInsert + this.state.value.slice(this.state.cursorPosition);
|
|
198
228
|
this.state.value = newValue;
|
|
199
|
-
this.state.cursorPosition +=
|
|
229
|
+
this.state.cursorPosition += valueToInsert.length;
|
|
200
230
|
}
|
|
201
231
|
this.emitStateChange();
|
|
202
232
|
this.emit("input", {
|
|
@@ -216,7 +246,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
216
246
|
setInputCursorPosition(input, result.cursorPosition);
|
|
217
247
|
this.state.value = result.value;
|
|
218
248
|
this.state.cursorPosition = result.cursorPosition;
|
|
219
|
-
|
|
249
|
+
this.dispatchInputEvent(input);
|
|
220
250
|
this.emitStateChange();
|
|
221
251
|
this.emit("backspace", {
|
|
222
252
|
deletedChar: result.deletedChar,
|
|
@@ -255,7 +285,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
255
285
|
const previousValue = this.state.value;
|
|
256
286
|
if (this.state.inputElement) {
|
|
257
287
|
this.state.inputElement.value = "";
|
|
258
|
-
this.state.inputElement
|
|
288
|
+
this.dispatchInputEvent(this.state.inputElement);
|
|
259
289
|
}
|
|
260
290
|
this.state.value = "";
|
|
261
291
|
this.state.cursorPosition = 0;
|
|
@@ -297,11 +327,14 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
297
327
|
* 设置值
|
|
298
328
|
*/
|
|
299
329
|
setValue(value) {
|
|
300
|
-
this.
|
|
301
|
-
|
|
330
|
+
if (this.destroyed) return;
|
|
331
|
+
const nextValue = clampValue(value, this.state.maxLength);
|
|
332
|
+
this.state.value = nextValue;
|
|
333
|
+
this.state.cursorPosition = nextValue.length;
|
|
302
334
|
if (this.state.inputElement) {
|
|
303
|
-
this.state.inputElement.value =
|
|
304
|
-
setInputCursorPosition(this.state.inputElement,
|
|
335
|
+
this.state.inputElement.value = nextValue;
|
|
336
|
+
setInputCursorPosition(this.state.inputElement, nextValue.length);
|
|
337
|
+
this.dispatchInputEvent(this.state.inputElement);
|
|
305
338
|
}
|
|
306
339
|
this.emitStateChange();
|
|
307
340
|
this.autoSwitchLicensePlate();
|
|
@@ -310,6 +343,7 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
310
343
|
* 追加值(在光标位置插入文本)
|
|
311
344
|
*/
|
|
312
345
|
appendValue(text) {
|
|
346
|
+
if (this.destroyed) return;
|
|
313
347
|
if (!text) return;
|
|
314
348
|
const input = this.state.inputElement;
|
|
315
349
|
if (input) {
|
|
@@ -318,9 +352,10 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
318
352
|
setInputCursorPosition(input, result.cursorPosition);
|
|
319
353
|
this.state.value = result.value;
|
|
320
354
|
this.state.cursorPosition = result.cursorPosition;
|
|
321
|
-
|
|
355
|
+
this.dispatchInputEvent(input);
|
|
322
356
|
} else {
|
|
323
|
-
if (this.state.maxLength
|
|
357
|
+
if (this.state.maxLength !== void 0) text = text.slice(0, Math.max(0, this.state.maxLength - this.state.value.length));
|
|
358
|
+
if (!text) return;
|
|
324
359
|
const newValue = this.state.value.slice(0, this.state.cursorPosition) + text + this.state.value.slice(this.state.cursorPosition);
|
|
325
360
|
this.state.value = newValue;
|
|
326
361
|
this.state.cursorPosition += text.length;
|
|
@@ -331,22 +366,38 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
331
366
|
* 设置最大长度
|
|
332
367
|
*/
|
|
333
368
|
setMaxLength(maxLength) {
|
|
334
|
-
this.
|
|
369
|
+
if (this.destroyed) return;
|
|
370
|
+
const normalizedMaxLength = normalizeMaxLength(maxLength);
|
|
371
|
+
this.state.maxLength = normalizedMaxLength;
|
|
372
|
+
const nextValue = clampValue(this.state.value, normalizedMaxLength);
|
|
373
|
+
const changed = nextValue !== this.state.value;
|
|
374
|
+
this.state.value = nextValue;
|
|
375
|
+
this.state.cursorPosition = Math.min(this.state.cursorPosition, nextValue.length);
|
|
376
|
+
if (this.state.inputElement && this.state.inputElement.value !== nextValue) {
|
|
377
|
+
this.state.inputElement.value = nextValue;
|
|
378
|
+
setInputCursorPosition(this.state.inputElement, this.state.cursorPosition);
|
|
379
|
+
this.dispatchInputEvent(this.state.inputElement);
|
|
380
|
+
}
|
|
335
381
|
this.emitStateChange();
|
|
382
|
+
if (changed) this.autoSwitchLicensePlate();
|
|
336
383
|
}
|
|
337
384
|
/**
|
|
338
385
|
* 绑定输入框
|
|
339
386
|
*/
|
|
340
387
|
bindInput(input) {
|
|
388
|
+
if (this.destroyed) return;
|
|
341
389
|
this.state.inputElement = input;
|
|
342
|
-
|
|
343
|
-
|
|
390
|
+
const nextValue = clampValue(input.value, this.state.maxLength);
|
|
391
|
+
if (input.value !== nextValue) input.value = nextValue;
|
|
392
|
+
this.state.value = nextValue;
|
|
393
|
+
this.state.cursorPosition = Math.min(getInputCursorPosition(input), nextValue.length);
|
|
344
394
|
this.emitStateChange();
|
|
345
395
|
}
|
|
346
396
|
/**
|
|
347
397
|
* 解绑输入框
|
|
348
398
|
*/
|
|
349
399
|
unbindInput() {
|
|
400
|
+
if (this.destroyed) return;
|
|
350
401
|
this.state.inputElement = null;
|
|
351
402
|
this.emitStateChange();
|
|
352
403
|
}
|
|
@@ -356,13 +407,19 @@ var KeyboardManager = class extends EventEmitter {
|
|
|
356
407
|
emitStateChange() {
|
|
357
408
|
this.emit("stateChange", { ...this.state });
|
|
358
409
|
}
|
|
410
|
+
dispatchInputEvent(input) {
|
|
411
|
+
const EventConstructor = input.ownerDocument.defaultView?.Event ?? Event;
|
|
412
|
+
input.dispatchEvent(new EventConstructor("input", { bubbles: true }));
|
|
413
|
+
}
|
|
359
414
|
/**
|
|
360
415
|
* 销毁
|
|
361
416
|
*/
|
|
362
417
|
destroy() {
|
|
418
|
+
if (this.destroyed) return;
|
|
363
419
|
this.hide();
|
|
364
420
|
this.clear();
|
|
365
421
|
this.state.inputElement = null;
|
|
422
|
+
this.destroyed = true;
|
|
366
423
|
}
|
|
367
424
|
};
|
|
368
425
|
function createKeyboardManager(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-manager.js","names":[],"sources":["../../src/managers/keyboard-manager.ts"],"sourcesContent":["/**\n * 键盘管理器\n * @module managers/keyboard-manager\n */\n\nimport type {\n KeyboardConfig,\n KeyboardEventMap,\n KeyboardOptions,\n KeyboardState,\n KeyboardType,\n KeyDefinition,\n} from '../types'\nimport { getLayout } from '../layouts'\nimport { EventEmitter } from '../utils/event-emitter'\nimport { isMobile, vibrate } from '../utils/device'\nimport {\n deleteCharBeforeCursor,\n getInputCursorPosition,\n insertTextAtCursor,\n setInputCursorPosition,\n} from '../utils/dom'\n\n/**\n * 默认键盘选项\n */\nconst DEFAULT_OPTIONS: Required<KeyboardOptions> = {\n type: 'qwerty',\n value: '',\n maxLength: undefined as unknown as number,\n defaultUpperCase: false,\n closeOnClickOutside: true,\n enableSound: false,\n enableVibrate: true,\n customLayouts: {},\n}\n\n/**\n * 键盘管理器类\n * 处理键盘状态管理、输入处理等核心逻辑\n */\nexport class KeyboardManager extends EventEmitter<KeyboardEventMap> {\n /** 配置选项 */\n private options: Required<KeyboardOptions>\n\n /** 当前状态 */\n private state: KeyboardState\n\n /** 当前布局配置 */\n private currentLayout: KeyboardConfig | null = null\n\n constructor(options: KeyboardOptions = {}) {\n super()\n this.options = { ...DEFAULT_OPTIONS, ...options }\n\n // 注册自定义布局\n if (options.customLayouts) {\n Object.entries(options.customLayouts).forEach(([name, layout]) => {\n // 这里不用 registerLayout 以避免覆盖内置布局的警告\n this.options.customLayouts[name] = layout\n })\n }\n\n // 初始化状态\n this.state = {\n visible: false,\n type: this.options.type,\n isUpperCase: this.options.defaultUpperCase,\n value: this.options.value,\n cursorPosition: this.options.value.length,\n maxLength: this.options.maxLength,\n inputElement: null,\n }\n\n // 加载初始布局\n this.loadLayout(this.options.type)\n }\n\n /**\n * 获取当前状态\n */\n getState(): Readonly<KeyboardState> {\n return { ...this.state }\n }\n\n /**\n * 获取当前布局配置\n */\n getLayout(): KeyboardConfig | null {\n return this.currentLayout\n }\n\n /**\n * 获取配置选项\n */\n getOptions(): Readonly<Required<KeyboardOptions>> {\n return { ...this.options }\n }\n\n /**\n * 加载键盘布局\n */\n private loadLayout(type: KeyboardType | string): boolean {\n // 先从自定义布局查找\n let layout = this.options.customLayouts[type]\n\n // 再从内置布局查找\n if (!layout) {\n layout = getLayout(type) as KeyboardConfig\n }\n\n if (!layout) {\n console.error(`[KeyboardManager] Layout \"${type}\" not found`)\n return false\n }\n\n this.currentLayout = layout\n\n // 更新大小写状态\n if (layout.supportShift) {\n this.state.isUpperCase = layout.defaultUpperCase ?? this.options.defaultUpperCase\n }\n\n return true\n }\n\n /**\n * 显示键盘\n */\n show(inputElement?: HTMLInputElement | HTMLTextAreaElement): void {\n if (this.state.visible) return\n\n this.state.visible = true\n this.state.inputElement = inputElement ?? null\n\n // 同步输入框的值\n if (inputElement) {\n this.state.value = inputElement.value\n this.state.cursorPosition = getInputCursorPosition(inputElement)\n }\n\n this.emitStateChange()\n this.emit('show', { type: this.state.type })\n }\n\n /**\n * 隐藏键盘\n */\n hide(): void {\n if (!this.state.visible) return\n\n const prevType = this.state.type\n this.state.visible = false\n this.state.inputElement = null\n\n this.emitStateChange()\n this.emit('hide', { type: prevType })\n }\n\n /**\n * 切换键盘显示/隐藏\n */\n toggle(inputElement?: HTMLInputElement | HTMLTextAreaElement): void {\n if (this.state.visible) {\n this.hide()\n }\n else {\n this.show(inputElement)\n }\n }\n\n /**\n * 切换键盘类型\n */\n switchType(type: KeyboardType | string): void {\n if (this.state.type === type) return\n\n const fromType = this.state.type\n if (!this.loadLayout(type)) return\n\n this.state.type = type as KeyboardType\n\n this.emitStateChange()\n this.emit('switch', { from: fromType, to: type as KeyboardType })\n }\n\n /**\n * 切换大小写\n */\n toggleShift(): void {\n if (!this.currentLayout?.supportShift) return\n\n this.state.isUpperCase = !this.state.isUpperCase\n this.emitStateChange()\n this.emit('shift', { isUpperCase: this.state.isUpperCase })\n }\n\n /**\n * 设置大小写状态\n */\n setShift(isUpperCase: boolean): void {\n if (!this.currentLayout?.supportShift) return\n if (this.state.isUpperCase === isUpperCase) return\n\n this.state.isUpperCase = isUpperCase\n this.emitStateChange()\n this.emit('shift', { isUpperCase })\n }\n\n /**\n * 处理按键\n */\n handleKey(key: KeyDefinition): void {\n // 触发震动反馈\n if (this.options.enableVibrate && isMobile()) {\n vibrate(10)\n }\n\n this.emit('keypress', { key, value: this.state.value })\n\n switch (key.type) {\n case 'char':\n case 'space':\n this.handleCharKey(key)\n break\n case 'backspace':\n this.handleBackspace()\n break\n case 'shift':\n this.toggleShift()\n break\n case 'clear':\n this.handleClear()\n break\n case 'enter':\n case 'done':\n this.handleConfirm()\n break\n case 'close':\n this.hide()\n break\n case 'tab':\n this.handleTab(key)\n break\n case 'custom':\n // 自定义按键,只触发事件\n break\n }\n }\n\n /**\n * 处理字符输入\n */\n private handleCharKey(key: KeyDefinition): void {\n const keyValue = this.getKeyValue(key)\n if (!keyValue) return\n\n const input = this.state.inputElement\n\n if (input) {\n // 如果有绑定输入框,直接操作输入框\n const result = insertTextAtCursor(input, keyValue, this.state.maxLength)\n input.value = result.value\n setInputCursorPosition(input, result.cursorPosition)\n this.state.value = result.value\n this.state.cursorPosition = result.cursorPosition\n\n // 触发原生 input 事件\n input.dispatchEvent(new Event('input', { bubbles: true }))\n }\n else {\n // 没有输入框,直接修改内部值\n if (this.state.maxLength && this.state.value.length >= this.state.maxLength) {\n return\n }\n const newValue = this.state.value.slice(0, this.state.cursorPosition)\n + keyValue\n + this.state.value.slice(this.state.cursorPosition)\n this.state.value = newValue\n this.state.cursorPosition += keyValue.length\n }\n\n this.emitStateChange()\n this.emit('input', { value: this.state.value, key })\n\n // 车牌号智能切换\n this.autoSwitchLicensePlate()\n }\n\n /**\n * 处理退格\n */\n private handleBackspace(): void {\n const input = this.state.inputElement\n\n if (input) {\n const result = deleteCharBeforeCursor(input)\n input.value = result.value\n setInputCursorPosition(input, result.cursorPosition)\n this.state.value = result.value\n this.state.cursorPosition = result.cursorPosition\n\n // 触发原生 input 事件\n input.dispatchEvent(new Event('input', { bubbles: true }))\n\n this.emitStateChange()\n this.emit('backspace', { deletedChar: result.deletedChar, value: this.state.value })\n }\n else {\n if (this.state.cursorPosition === 0) return\n\n const deletedChar = this.state.value.charAt(this.state.cursorPosition - 1)\n this.state.value = this.state.value.slice(0, this.state.cursorPosition - 1)\n + this.state.value.slice(this.state.cursorPosition)\n this.state.cursorPosition--\n\n this.emitStateChange()\n this.emit('backspace', { deletedChar, value: this.state.value })\n }\n\n // 车牌号智能切换\n this.autoSwitchLicensePlate()\n }\n\n /**\n * 车牌号智能切换逻辑\n * 根据当前值长度自动切换键盘布局\n * 只有 2 种布局:省份键盘(第1位)和 字母+数字混合键盘(第2-8位)\n */\n private autoSwitchLicensePlate(): void {\n // 只在车牌键盘类型时生效\n if (!this.state.type.startsWith('license-plate')) return\n\n const len = this.state.value.length\n let targetType: string | null = null\n\n if (len === 0) {\n // 第1位:省份简称\n targetType = 'license-plate-province'\n }\n else {\n // 第2-8位:字母+数字混合键盘\n // (第2位虽然只能输入字母,但显示混合键盘,用户自己知道不能输入数字)\n targetType = 'license-plate-alphanumeric'\n }\n\n // 如果需要切换\n if (targetType && this.state.type !== targetType) {\n this.switchType(targetType)\n }\n }\n\n /**\n * 处理清空\n */\n private handleClear(): void {\n const previousValue = this.state.value\n\n if (this.state.inputElement) {\n this.state.inputElement.value = ''\n this.state.inputElement.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n this.state.value = ''\n this.state.cursorPosition = 0\n\n this.emitStateChange()\n this.emit('clear', { previousValue })\n \n // 车牌号智能切换\n this.autoSwitchLicensePlate()\n }\n\n /**\n * 处理确认\n */\n private handleConfirm(): void {\n this.emit('confirm', { value: this.state.value })\n this.hide()\n }\n\n /**\n * 处理切换键盘\n */\n private handleTab(key: KeyDefinition): void {\n const targetType = key.data?.targetType as KeyboardType | string | undefined\n if (targetType) {\n this.switchType(targetType)\n }\n }\n\n /**\n * 获取按键的实际输出值\n */\n private getKeyValue(key: KeyDefinition): string {\n const value = key.value ?? key.label\n\n if (typeof value === 'string') {\n return value\n }\n\n return this.state.isUpperCase ? value.upper : value.lower\n }\n\n /**\n * 获取按键的显示文本\n */\n getKeyLabel(key: KeyDefinition): string {\n const label = key.label\n\n if (typeof label === 'string') {\n return label\n }\n\n return this.state.isUpperCase ? label.upper : label.lower\n }\n\n /**\n * 设置值\n */\n setValue(value: string): void {\n this.state.value = value\n this.state.cursorPosition = value.length\n\n if (this.state.inputElement) {\n this.state.inputElement.value = value\n setInputCursorPosition(this.state.inputElement, value.length)\n }\n\n this.emitStateChange()\n \n // 车牌号智能切换\n this.autoSwitchLicensePlate()\n }\n\n /**\n * 追加值(在光标位置插入文本)\n */\n appendValue(text: string): void {\n if (!text) return\n\n const input = this.state.inputElement\n\n if (input) {\n const result = insertTextAtCursor(input, text, this.state.maxLength)\n input.value = result.value\n setInputCursorPosition(input, result.cursorPosition)\n this.state.value = result.value\n this.state.cursorPosition = result.cursorPosition\n\n // 触发原生 input 事件\n input.dispatchEvent(new Event('input', { bubbles: true }))\n }\n else {\n if (this.state.maxLength && this.state.value.length + text.length > this.state.maxLength) {\n text = text.slice(0, this.state.maxLength - this.state.value.length)\n }\n const newValue = this.state.value.slice(0, this.state.cursorPosition)\n + text\n + this.state.value.slice(this.state.cursorPosition)\n this.state.value = newValue\n this.state.cursorPosition += text.length\n }\n\n this.emitStateChange()\n }\n\n /**\n * 设置最大长度\n */\n setMaxLength(maxLength?: number): void {\n this.state.maxLength = maxLength\n this.emitStateChange()\n }\n\n /**\n * 绑定输入框\n */\n bindInput(input: HTMLInputElement | HTMLTextAreaElement): void {\n this.state.inputElement = input\n this.state.value = input.value\n this.state.cursorPosition = getInputCursorPosition(input)\n this.emitStateChange()\n }\n\n /**\n * 解绑输入框\n */\n unbindInput(): void {\n this.state.inputElement = null\n this.emitStateChange()\n }\n\n /**\n * 发送状态变化事件\n */\n private emitStateChange(): void {\n this.emit('stateChange', { ...this.state })\n }\n\n /**\n * 销毁\n */\n destroy(): void {\n this.hide()\n this.clear()\n this.state.inputElement = null\n }\n}\n\n/**\n * 创建键盘管理器实例\n */\nexport function createKeyboardManager(options?: KeyboardOptions): KeyboardManager {\n return new KeyboardManager(options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keyboard-manager.js","names":[],"sources":["../../src/managers/keyboard-manager.ts"],"sourcesContent":["/**\r\n * 键盘管理器\r\n * @module managers/keyboard-manager\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 '../types'\r\nimport { getLayout } from '../layouts'\r\nimport { isMobile, vibrate } from '../utils/device'\r\nimport {\r\n deleteCharBeforeCursor,\r\n getInputCursorPosition,\r\n insertTextAtCursor,\r\n setInputCursorPosition,\r\n} from '../utils/dom'\r\nimport { EventEmitter } from '../utils/event-emitter'\r\n\r\n/**\r\n * 默认键盘选项\r\n */\r\nconst DEFAULT_OPTIONS: Required<KeyboardOptions> = {\r\n type: 'qwerty',\r\n value: '',\r\n maxLength: undefined as unknown as number,\r\n defaultUpperCase: false,\r\n closeOnClickOutside: true,\r\n enableSound: false,\r\n enableVibrate: true,\r\n customLayouts: {},\r\n}\r\n\r\nfunction normalizeMaxLength(value: number | undefined): number | undefined {\r\n if (value === undefined || !Number.isFinite(value)) return undefined\r\n return Math.max(0, Math.floor(value))\r\n}\r\n\r\nfunction clampValue(value: string, maxLength: number | undefined): string {\r\n return maxLength === undefined ? value : value.slice(0, maxLength)\r\n}\r\n\r\n/**\r\n * 键盘管理器类\r\n * 处理键盘状态管理、输入处理等核心逻辑\r\n */\r\nexport class KeyboardManager extends EventEmitter<KeyboardEventMap> {\r\n /** 配置选项 */\r\n private options: Required<KeyboardOptions>\r\n\r\n /** 当前状态 */\r\n private state: KeyboardState\r\n\r\n /** 当前布局配置 */\r\n private currentLayout: KeyboardConfig | null = null\r\n\r\n private destroyed = false\r\n\r\n constructor(options: KeyboardOptions = {}) {\r\n super()\r\n const maxLength = normalizeMaxLength(options.maxLength)\r\n this.options = {\r\n ...DEFAULT_OPTIONS,\r\n ...options,\r\n maxLength,\r\n customLayouts: {\r\n ...DEFAULT_OPTIONS.customLayouts,\r\n ...(options.customLayouts ?? {}),\r\n },\r\n }\r\n\r\n // 注册自定义布局\r\n if (options.customLayouts) {\r\n Object.entries(options.customLayouts).forEach(([name, layout]) => {\r\n // 这里不用 registerLayout 以避免覆盖内置布局的警告\r\n this.options.customLayouts[name] = layout\r\n })\r\n }\r\n\r\n // 初始化状态\r\n this.state = {\r\n visible: false,\r\n type: this.options.type,\r\n isUpperCase: this.options.defaultUpperCase,\r\n value: clampValue(this.options.value, this.options.maxLength),\r\n cursorPosition: clampValue(this.options.value, this.options.maxLength)\r\n .length,\r\n maxLength: this.options.maxLength,\r\n inputElement: null,\r\n }\r\n\r\n // 加载初始布局\r\n this.loadLayout(this.options.type)\r\n }\r\n\r\n /**\r\n * 获取当前状态\r\n */\r\n getState(): Readonly<KeyboardState> {\r\n return { ...this.state }\r\n }\r\n\r\n /**\r\n * 获取当前布局配置\r\n */\r\n getLayout(): KeyboardConfig | null {\r\n return this.currentLayout\r\n }\r\n\r\n /**\r\n * 获取配置选项\r\n */\r\n getOptions(): Readonly<Required<KeyboardOptions>> {\r\n return { ...this.options, customLayouts: { ...this.options.customLayouts } }\r\n }\r\n\r\n /**\r\n * 加载键盘布局\r\n */\r\n private loadLayout(type: KeyboardType | string): boolean {\r\n // 先从自定义布局查找\r\n let layout = this.options.customLayouts[type]\r\n\r\n // 再从内置布局查找\r\n if (!layout) {\r\n layout = getLayout(type) as KeyboardConfig\r\n }\r\n\r\n if (!layout) {\r\n console.error(`[KeyboardManager] Layout \"${type}\" not found`)\r\n return false\r\n }\r\n\r\n this.currentLayout = layout\r\n\r\n // 更新大小写状态\r\n if (layout.supportShift) {\r\n this.state.isUpperCase =\r\n layout.defaultUpperCase ?? this.options.defaultUpperCase\r\n }\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 显示键盘\r\n */\r\n show(inputElement?: HTMLInputElement | HTMLTextAreaElement): void {\r\n if (this.destroyed) return\r\n if (this.state.visible) {\r\n if (inputElement && this.state.inputElement !== inputElement) {\r\n this.bindInput(inputElement)\r\n }\r\n return\r\n }\r\n\r\n this.state.visible = true\r\n this.state.inputElement = inputElement ?? null\r\n\r\n // 同步输入框的值\r\n if (inputElement) {\r\n this.state.value = inputElement.value\r\n this.state.cursorPosition = getInputCursorPosition(inputElement)\r\n }\r\n\r\n this.emitStateChange()\r\n this.emit('show', { type: this.state.type })\r\n }\r\n\r\n /**\r\n * 隐藏键盘\r\n */\r\n hide(): void {\r\n if (this.destroyed) return\r\n if (!this.state.visible) return\r\n\r\n const prevType = this.state.type\r\n this.state.visible = false\r\n this.state.inputElement = null\r\n\r\n this.emitStateChange()\r\n this.emit('hide', { type: prevType })\r\n }\r\n\r\n /**\r\n * 切换键盘显示/隐藏\r\n */\r\n toggle(inputElement?: HTMLInputElement | HTMLTextAreaElement): void {\r\n if (this.destroyed) return\r\n if (this.state.visible) {\r\n this.hide()\r\n } else {\r\n this.show(inputElement)\r\n }\r\n }\r\n\r\n /**\r\n * 切换键盘类型\r\n */\r\n switchType(type: KeyboardType | string): void {\r\n if (this.destroyed) return\r\n if (this.state.type === type) return\r\n\r\n const fromType = this.state.type\r\n if (!this.loadLayout(type)) return\r\n\r\n this.state.type = type as KeyboardType\r\n\r\n this.emitStateChange()\r\n this.emit('switch', { from: fromType, to: type as KeyboardType })\r\n }\r\n\r\n /**\r\n * 切换大小写\r\n */\r\n toggleShift(): void {\r\n if (this.destroyed) return\r\n if (!this.currentLayout?.supportShift) return\r\n\r\n this.state.isUpperCase = !this.state.isUpperCase\r\n this.emitStateChange()\r\n this.emit('shift', { isUpperCase: this.state.isUpperCase })\r\n }\r\n\r\n /**\r\n * 设置大小写状态\r\n */\r\n setShift(isUpperCase: boolean): void {\r\n if (this.destroyed) return\r\n if (!this.currentLayout?.supportShift) return\r\n if (this.state.isUpperCase === isUpperCase) return\r\n\r\n this.state.isUpperCase = isUpperCase\r\n this.emitStateChange()\r\n this.emit('shift', { isUpperCase })\r\n }\r\n\r\n /**\r\n * 处理按键\r\n */\r\n handleKey(key: KeyDefinition): void {\r\n if (this.destroyed) return\r\n // 触发震动反馈\r\n if (this.options.enableVibrate && isMobile()) {\r\n vibrate(10)\r\n }\r\n\r\n this.emit('keypress', { key, value: this.state.value })\r\n\r\n switch (key.type) {\r\n case 'char':\r\n case 'space':\r\n this.handleCharKey(key)\r\n break\r\n case 'backspace':\r\n this.handleBackspace()\r\n break\r\n case 'shift':\r\n this.toggleShift()\r\n break\r\n case 'clear':\r\n this.handleClear()\r\n break\r\n case 'enter':\r\n case 'done':\r\n this.handleConfirm()\r\n break\r\n case 'close':\r\n this.hide()\r\n break\r\n case 'tab':\r\n this.handleTab(key)\r\n break\r\n case 'custom':\r\n // 自定义按键,只触发事件\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * 处理字符输入\r\n */\r\n private handleCharKey(key: KeyDefinition): void {\r\n const keyValue = this.getKeyValue(key)\r\n if (!keyValue) return\r\n\r\n const input = this.state.inputElement\r\n\r\n if (input) {\r\n // 如果有绑定输入框,直接操作输入框\r\n const result = insertTextAtCursor(input, keyValue, this.state.maxLength)\r\n input.value = result.value\r\n setInputCursorPosition(input, result.cursorPosition)\r\n this.state.value = result.value\r\n this.state.cursorPosition = result.cursorPosition\r\n\r\n // 触发原生 input 事件\r\n this.dispatchInputEvent(input)\r\n } else {\r\n // 没有输入框,直接修改内部值\r\n if (\r\n this.state.maxLength !== undefined &&\r\n this.state.value.length >= this.state.maxLength\r\n ) {\r\n return\r\n }\r\n const availableLength =\r\n this.state.maxLength === undefined\r\n ? keyValue.length\r\n : this.state.maxLength - this.state.value.length\r\n const valueToInsert = keyValue.slice(0, Math.max(0, availableLength))\r\n if (!valueToInsert) return\r\n const newValue =\r\n this.state.value.slice(0, this.state.cursorPosition) +\r\n valueToInsert +\r\n this.state.value.slice(this.state.cursorPosition)\r\n this.state.value = newValue\r\n this.state.cursorPosition += valueToInsert.length\r\n }\r\n\r\n this.emitStateChange()\r\n this.emit('input', { value: this.state.value, key })\r\n\r\n // 车牌号智能切换\r\n this.autoSwitchLicensePlate()\r\n }\r\n\r\n /**\r\n * 处理退格\r\n */\r\n private handleBackspace(): void {\r\n const input = this.state.inputElement\r\n\r\n if (input) {\r\n const result = deleteCharBeforeCursor(input)\r\n input.value = result.value\r\n setInputCursorPosition(input, result.cursorPosition)\r\n this.state.value = result.value\r\n this.state.cursorPosition = result.cursorPosition\r\n\r\n // 触发原生 input 事件\r\n this.dispatchInputEvent(input)\r\n\r\n this.emitStateChange()\r\n this.emit('backspace', {\r\n deletedChar: result.deletedChar,\r\n value: this.state.value,\r\n })\r\n } else {\r\n if (this.state.cursorPosition === 0) return\r\n\r\n const deletedChar = this.state.value.charAt(this.state.cursorPosition - 1)\r\n this.state.value =\r\n this.state.value.slice(0, this.state.cursorPosition - 1) +\r\n this.state.value.slice(this.state.cursorPosition)\r\n this.state.cursorPosition--\r\n\r\n this.emitStateChange()\r\n this.emit('backspace', { deletedChar, value: this.state.value })\r\n }\r\n\r\n // 车牌号智能切换\r\n this.autoSwitchLicensePlate()\r\n }\r\n\r\n /**\r\n * 车牌号智能切换逻辑\r\n * 根据当前值长度自动切换键盘布局\r\n * 只有 2 种布局:省份键盘(第1位)和 字母+数字混合键盘(第2-8位)\r\n */\r\n private autoSwitchLicensePlate(): void {\r\n // 只在车牌键盘类型时生效\r\n if (!this.state.type.startsWith('license-plate')) return\r\n\r\n const len = this.state.value.length\r\n let targetType: string | null = null\r\n\r\n if (len === 0) {\r\n // 第1位:省份简称\r\n targetType = 'license-plate-province'\r\n } else {\r\n // 第2-8位:字母+数字混合键盘\r\n // (第2位虽然只能输入字母,但显示混合键盘,用户自己知道不能输入数字)\r\n targetType = 'license-plate-alphanumeric'\r\n }\r\n\r\n // 如果需要切换\r\n if (targetType && this.state.type !== targetType) {\r\n this.switchType(targetType)\r\n }\r\n }\r\n\r\n /**\r\n * 处理清空\r\n */\r\n private handleClear(): void {\r\n const previousValue = this.state.value\r\n\r\n if (this.state.inputElement) {\r\n this.state.inputElement.value = ''\r\n this.dispatchInputEvent(this.state.inputElement)\r\n }\r\n\r\n this.state.value = ''\r\n this.state.cursorPosition = 0\r\n\r\n this.emitStateChange()\r\n this.emit('clear', { previousValue })\r\n\r\n // 车牌号智能切换\r\n this.autoSwitchLicensePlate()\r\n }\r\n\r\n /**\r\n * 处理确认\r\n */\r\n private handleConfirm(): void {\r\n this.emit('confirm', { value: this.state.value })\r\n this.hide()\r\n }\r\n\r\n /**\r\n * 处理切换键盘\r\n */\r\n private handleTab(key: KeyDefinition): void {\r\n const targetType = key.data?.targetType as KeyboardType | string | undefined\r\n if (targetType) {\r\n this.switchType(targetType)\r\n }\r\n }\r\n\r\n /**\r\n * 获取按键的实际输出值\r\n */\r\n private getKeyValue(key: KeyDefinition): string {\r\n const value = key.value ?? key.label\r\n\r\n if (typeof value === 'string') {\r\n return value\r\n }\r\n\r\n return this.state.isUpperCase ? value.upper : value.lower\r\n }\r\n\r\n /**\r\n * 获取按键的显示文本\r\n */\r\n getKeyLabel(key: KeyDefinition): string {\r\n const label = key.label\r\n\r\n if (typeof label === 'string') {\r\n return label\r\n }\r\n\r\n return this.state.isUpperCase ? label.upper : label.lower\r\n }\r\n\r\n /**\r\n * 设置值\r\n */\r\n setValue(value: string): void {\r\n if (this.destroyed) return\r\n const nextValue = clampValue(value, this.state.maxLength)\r\n this.state.value = nextValue\r\n this.state.cursorPosition = nextValue.length\r\n\r\n if (this.state.inputElement) {\r\n this.state.inputElement.value = nextValue\r\n setInputCursorPosition(this.state.inputElement, nextValue.length)\r\n this.dispatchInputEvent(this.state.inputElement)\r\n }\r\n\r\n this.emitStateChange()\r\n\r\n // 车牌号智能切换\r\n this.autoSwitchLicensePlate()\r\n }\r\n\r\n /**\r\n * 追加值(在光标位置插入文本)\r\n */\r\n appendValue(text: string): void {\r\n if (this.destroyed) return\r\n if (!text) return\r\n\r\n const input = this.state.inputElement\r\n\r\n if (input) {\r\n const result = insertTextAtCursor(input, text, this.state.maxLength)\r\n input.value = result.value\r\n setInputCursorPosition(input, result.cursorPosition)\r\n this.state.value = result.value\r\n this.state.cursorPosition = result.cursorPosition\r\n\r\n // 触发原生 input 事件\r\n this.dispatchInputEvent(input)\r\n } else {\r\n if (this.state.maxLength !== undefined) {\r\n text = text.slice(\r\n 0,\r\n Math.max(0, this.state.maxLength - this.state.value.length)\r\n )\r\n }\r\n if (!text) return\r\n const newValue =\r\n this.state.value.slice(0, this.state.cursorPosition) +\r\n text +\r\n this.state.value.slice(this.state.cursorPosition)\r\n this.state.value = newValue\r\n this.state.cursorPosition += text.length\r\n }\r\n\r\n this.emitStateChange()\r\n }\r\n\r\n /**\r\n * 设置最大长度\r\n */\r\n setMaxLength(maxLength?: number): void {\r\n if (this.destroyed) return\r\n const normalizedMaxLength = normalizeMaxLength(maxLength)\r\n this.state.maxLength = normalizedMaxLength\r\n const nextValue = clampValue(this.state.value, normalizedMaxLength)\r\n const changed = nextValue !== this.state.value\r\n this.state.value = nextValue\r\n this.state.cursorPosition = Math.min(\r\n this.state.cursorPosition,\r\n nextValue.length\r\n )\r\n if (\r\n this.state.inputElement &&\r\n this.state.inputElement.value !== nextValue\r\n ) {\r\n this.state.inputElement.value = nextValue\r\n setInputCursorPosition(this.state.inputElement, this.state.cursorPosition)\r\n this.dispatchInputEvent(this.state.inputElement)\r\n }\r\n this.emitStateChange()\r\n if (changed) this.autoSwitchLicensePlate()\r\n }\r\n\r\n /**\r\n * 绑定输入框\r\n */\r\n bindInput(input: HTMLInputElement | HTMLTextAreaElement): void {\r\n if (this.destroyed) return\r\n this.state.inputElement = input\r\n const nextValue = clampValue(input.value, this.state.maxLength)\r\n if (input.value !== nextValue) input.value = nextValue\r\n this.state.value = nextValue\r\n this.state.cursorPosition = Math.min(\r\n getInputCursorPosition(input),\r\n nextValue.length\r\n )\r\n this.emitStateChange()\r\n }\r\n\r\n /**\r\n * 解绑输入框\r\n */\r\n unbindInput(): void {\r\n if (this.destroyed) return\r\n this.state.inputElement = null\r\n this.emitStateChange()\r\n }\r\n\r\n /**\r\n * 发送状态变化事件\r\n */\r\n private emitStateChange(): void {\r\n this.emit('stateChange', { ...this.state })\r\n }\r\n\r\n private dispatchInputEvent(\r\n input: HTMLInputElement | HTMLTextAreaElement\r\n ): void {\r\n const EventConstructor = input.ownerDocument.defaultView?.Event ?? Event\r\n input.dispatchEvent(new EventConstructor('input', { bubbles: true }))\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n destroy(): void {\r\n if (this.destroyed) return\r\n this.hide()\r\n this.clear()\r\n this.state.inputElement = null\r\n this.destroyed = true\r\n }\r\n}\r\n\r\n/**\r\n * 创建键盘管理器实例\r\n */\r\nexport function createKeyboardManager(\r\n options?: KeyboardOptions\r\n): KeyboardManager {\r\n return new KeyboardManager(options)\r\n}\r\n"],"mappings":"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"}
|