@junerver/vue-touch-ime 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css ADDED
@@ -0,0 +1,2 @@
1
+ .vti-kb{--vti-accent:#3ef2c0;--vti-accent-strong:color-mix(in srgb, var(--vti-accent) 72%, #000);--vti-on-accent:#06241c;--vti-bg:#071418f7;--vti-panel-border:#3ef2c04d;--vti-strip-bg:#040d10d9;--vti-strip-border:#3ef2c038;--vti-key-bg:linear-gradient(180deg, #18383cf2, #0d2226f2);--vti-key-border:#94c0bb47;--vti-key-fg:#d7e2e0;--vti-fn-fg:#9fc3bb;--vti-muted-fg:#5f7d81;--vti-buffer-fg:#8df5cf;--vti-key-h:54px;--vti-key-radius:10px;--vti-font:"Microsoft YaHei", "Noto Sans SC", Arial, sans-serif;z-index:2147483000;pointer-events:none;font-family:var(--vti-font);position:fixed;bottom:0;left:0;right:0}.vti-kb.show{pointer-events:auto}.vti-kb__panel{visibility:hidden;max-width:1120px;padding:10px 12px calc(12px + env(safe-area-inset-bottom,0px));border:1px solid var(--vti-panel-border);background:var(--vti-bg);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;border-bottom:none;border-radius:14px 14px 0 0;margin:0 auto;transition:transform .18s,visibility 0s linear .18s;transform:translateY(100%);box-shadow:0 -14px 36px #0000008c}.vti-kb.show .vti-kb__panel{visibility:visible;transition:transform .18s,visibility;transform:translateY(0)}.vti-kb__strip{border:1px solid var(--vti-strip-border);background:var(--vti-strip-bg);border-radius:9px;align-items:center;gap:10px;min-height:46px;margin-bottom:8px;padding:4px 10px;display:flex}.vti-kb__buffer{min-width:88px;max-width:220px;color:var(--vti-buffer-fg);letter-spacing:.06em;white-space:nowrap;text-overflow:ellipsis;flex:none;font:600 17px Consolas,monospace;overflow:hidden}.vti-kb__cands{scrollbar-width:thin;scrollbar-color:color-mix(in srgb, var(--vti-accent) 30%, transparent) transparent;flex:1;align-items:center;gap:8px;min-width:0;display:flex;overflow-x:auto}.vti-kb__cand{border:1px solid color-mix(in srgb, var(--vti-accent) 35%, transparent);min-width:52px;height:36px;color:var(--vti-key-fg);background:color-mix(in srgb, var(--vti-bg) 85%, var(--vti-accent));cursor:pointer;border-radius:8px;flex:none;padding:0 14px;font-family:inherit;font-size:19px}.vti-kb__cand:active{border-color:var(--vti-accent);color:var(--vti-bg);background:var(--vti-accent)}.vti-kb__hint{color:var(--vti-muted-fg);white-space:nowrap;font-size:13px}.vti-kb__row{gap:8px;margin-bottom:8px;display:flex}.vti-kb__row--last{margin-bottom:0}.vti-kb__row--num{grid-template-columns:repeat(4,1fr);display:grid}.vti-kb__key{min-width:0;height:var(--vti-key-h);border:1px solid var(--vti-key-border);border-radius:var(--vti-key-radius);color:var(--vti-key-fg);background:var(--vti-key-bg);font:600 21px/1 var(--vti-font);cursor:pointer;flex:1;transition:all 80ms}.vti-kb__key:active{border-color:var(--vti-accent);color:var(--vti-bg);background:var(--vti-accent)}.vti-kb__key--fn{color:var(--vti-fn-fg);flex:1.4;font-size:16px}.vti-kb__key--fn.on{border-color:var(--vti-accent);color:var(--vti-accent)}.vti-kb__key--space{color:var(--vti-fn-fg);flex:3.2;font-size:16px}.vti-kb__key--done{border-color:color-mix(in srgb, var(--vti-accent) 55%, transparent);color:var(--vti-on-accent);background:linear-gradient(180deg, var(--vti-accent), var(--vti-accent-strong));flex:1.8;font-size:18px}.vti-kb__key--done:active{background:var(--vti-buffer-fg)}.vti-kb__key--zero{grid-column:span 2}.vti-kb__key--ghost{opacity:.28;cursor:default}
2
+ /*$vite$:1*/
@@ -0,0 +1,50 @@
1
+ /**
2
+ * vue-touch-ime · 会话状态(Vue 组合式 API)。
3
+ *
4
+ * 焦点驱动:SoftKeyboard.vue 挂载后 attach() 注册文档级 focusin/focusout,
5
+ * 页面上任何文本输入框自动接管,无需逐个输入框接线。
6
+ *
7
+ * 关键约束:
8
+ * - 键盘按键必须 preventDefault 保持输入框焦点(见 SoftKeyboard.vue),
9
+ * 否则输入框的 @blur 提交会被提前触发;
10
+ * - 数字类输入(type=number)浏览器值消毒会吃掉 "12." 这类中间态,
11
+ * 草稿串由本模块持有,只把合法值落 DOM;
12
+ * - 「进场即全选」的输入(replaceAll)首键整体替换旧值。
13
+ */
14
+ import { type ComputedRef } from 'vue';
15
+ import { type SoftCandidate, type SoftKbKind, type SoftKbMode } from './ime';
16
+ export type { SoftCandidate, SoftKbKind, SoftKbMode };
17
+ export declare function isSoftInput(el: EventTarget | null): el is HTMLInputElement;
18
+ export interface SoftKeyboardState {
19
+ visible: boolean;
20
+ /** 当前键盘模式:拼音 / 英文 / 数字 */
21
+ mode: SoftKbMode;
22
+ /** 输入限制类型(决定可用键与编辑模型) */
23
+ kind: SoftKbKind;
24
+ /** 拼音缓冲(不进 input,只在候选栏回显) */
25
+ buffer: string;
26
+ /** 数字类草稿(含尾部未落盘的小数点) */
27
+ draft: string;
28
+ /** 首键整体替换(行内编辑进场即全选的输入框) */
29
+ replaceAll: boolean;
30
+ /** 英文模式大写锁定一次 */
31
+ shift: boolean;
32
+ /** 从数字模式返回时的文本模式 */
33
+ prevTextMode: Exclude<SoftKbMode, 'num'>;
34
+ }
35
+ export interface SoftKeyboard {
36
+ state: SoftKeyboardState;
37
+ candidates: ComputedRef<SoftCandidate[]>;
38
+ attach: (root: HTMLElement | null) => void;
39
+ detach: () => void;
40
+ openFor: (el: HTMLInputElement) => void;
41
+ close: (blur?: boolean) => void;
42
+ press: (token: string) => void;
43
+ pickCandidate: (candidate: SoftCandidate) => void;
44
+ getTarget: () => HTMLInputElement | null;
45
+ }
46
+ export declare function createSoftKeyboard(): SoftKeyboard;
47
+ /** 模块级单例(SoftKeyboard.vue 默认实例) */
48
+ export declare const softKeyboard: SoftKeyboard;
49
+ /** 取默认单例;需要独立实例时用 createSoftKeyboard() */
50
+ export declare function useSoftKeyboard(): SoftKeyboard;
package/package.json CHANGED
@@ -1,6 +1,88 @@
1
1
  {
2
2
  "name": "@junerver/vue-touch-ime",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.1.0",
4
+ "description": "Vue 3 触摸屏软键盘(内置中文拼音输入法)- 零接线焦点接管、按输入类型限制(数字/小数/文本)、中英数三模式,适配无物理键盘的触屏工控/车载/自助终端",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./ime": {
16
+ "types": "./dist/ime.d.ts",
17
+ "import": "./dist/ime.js",
18
+ "require": "./dist/ime.cjs"
19
+ },
20
+ "./dict": {
21
+ "types": "./dist/pinyinDict.d.ts",
22
+ "import": "./dist/pinyinDict.js",
23
+ "require": "./dist/pinyinDict.cjs"
24
+ },
25
+ "./style.css": "./dist/style.css"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "sideEffects": [
31
+ "**/*.css"
32
+ ],
33
+ "scripts": {
34
+ "dev": "vite",
35
+ "build": "vite build && npm run build:types",
36
+ "build:types": "vue-tsc --declaration --emitDeclarationOnly --outDir dist -p tsconfig.build.json",
37
+ "test": "vitest run",
38
+ "gen:dict": "python scripts/gen-pinyin-dict.py",
39
+ "prepublishOnly": "npm run build"
40
+ },
41
+ "keywords": [
42
+ "vue",
43
+ "vue3",
44
+ "keyboard",
45
+ "soft-keyboard",
46
+ "touch",
47
+ "touchscreen",
48
+ "ime",
49
+ "pinyin",
50
+ "chinese",
51
+ "软键盘",
52
+ "触摸屏",
53
+ "输入法",
54
+ "拼音",
55
+ "中文输入"
56
+ ],
57
+ "author": "junerver",
58
+ "license": "MIT",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/junerver/vue-touch-ime.git"
62
+ },
63
+ "homepage": "https://github.com/junerver/vue-touch-ime#readme",
64
+ "bugs": {
65
+ "url": "https://github.com/junerver/vue-touch-ime/issues"
66
+ },
67
+ "publishConfig": {
68
+ "access": "public"
69
+ },
70
+ "peerDependencies": {
71
+ "vue": "^3.4.0"
72
+ },
73
+ "devDependencies": {
74
+ "@types/node": "^24.12.3",
75
+ "@vitejs/plugin-vue": "^6.0.6",
76
+ "@vue/test-utils": "^2.4.6",
77
+ "@vue/tsconfig": "^0.9.1",
78
+ "jsdom": "^26.1.0",
79
+ "typescript": "~6.0.2",
80
+ "vite": "^8.0.12",
81
+ "vitest": "^3.2.4",
82
+ "vue": "^3.5.34",
83
+ "vue-tsc": "^3.2.8"
84
+ },
85
+ "engines": {
86
+ "node": ">=18.0.0"
87
+ }
88
+ }