@zh-keyboard/vue
Version:
基于Vue的中文虚拟键盘组件
1,005 lines (1,004 loc) • 39 kB
JavaScript
import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, defineComponent as c, getCurrentInstance as l, getCurrentScope as u, mergeModels as d, nextTick as f, normalizeClass as p, normalizeStyle as m, onBeforeUnmount as h, onMounted as g, onScopeDispose as _, onUnmounted as v, openBlock as y, ref as b, renderList as x, shallowRef as S, toDisplayString as C, toValue as w, unref as T, useModel as E, vShow as D, watch as O, watchEffect as k, withDirectives as A, withModifiers as j } from "vue";
import { CanvasDrawer as M, calculateKeyboardPosition as N, createKeyRepeater as P, delToInputElement as F, getHandwritingRecognizer as I, getKeyboardConfig as L, getPinyinEngine as R, isInputElement as z, writeToInputElement as ee } from "@zh-keyboard/core";
export * from "@zh-keyboard/core";
//#region ../../node_modules/.pnpm/@vueuse+shared@13.1.0_vue@3.5.13_typescript@5.8.3_/node_modules/@vueuse/shared/index.mjs
function B(e) {
return u() ? (_(e), !0) : !1;
}
var V = typeof window < "u" && typeof document < "u";
typeof WorkerGlobalScope < "u" && globalThis instanceof WorkerGlobalScope;
var te = (e) => e != null, H = Object.prototype.toString, ne = (e) => H.call(e) === "[object Object]", U = () => {};
function re(e, t) {
function n(...n) {
return new Promise((r, i) => {
Promise.resolve(e(() => t.apply(this, n), {
fn: t,
thisArg: this,
args: n
})).then(r).catch(i);
});
}
return n;
}
function ie(e, t = {}) {
let n, r, i = U, a = (e) => {
clearTimeout(e), i(), i = U;
}, o;
return (s) => {
let c = w(e), l = w(t.maxWait);
return n && a(n), c <= 0 || l !== void 0 && l <= 0 ? (r &&= (a(r), null), Promise.resolve(s())) : new Promise((e, u) => {
i = t.rejectOnCancel ? u : e, o = s, l && !r && (r = setTimeout(() => {
n && a(n), r = null, e(o());
}, l)), n = setTimeout(() => {
r && a(r), r = null, e(s());
}, c);
});
};
}
function W(e) {
return Array.isArray(e) ? e : [e];
}
function ae(e) {
return e || l();
}
function oe(e, t = 200, n = {}) {
return re(ie(t, n), e);
}
function se(e, t = !0, n) {
ae(n) ? g(e, n) : t ? e() : f(e);
}
function ce(e, t, n) {
return O(e, t, {
...n,
immediate: !0
});
}
//#endregion
//#region ../../node_modules/.pnpm/@vueuse+core@13.1.0_vue@3.5.13_typescript@5.8.3_/node_modules/@vueuse/core/index.mjs
var G = V ? window : void 0;
V && window.document, V && window.navigator, V && window.location;
function K(e) {
let t = w(e);
return t?.$el ?? t;
}
function q(...e) {
let n = [], r = () => {
n.forEach((e) => e()), n.length = 0;
}, i = (e, t, n, r) => (e.addEventListener(t, n, r), () => e.removeEventListener(t, n, r)), a = t(() => {
let t = W(w(e[0])).filter((e) => e != null);
return t.every((e) => typeof e != "string") ? t : void 0;
}), o = ce(() => [
a.value?.map((e) => K(e)) ?? [G].filter((e) => e != null),
W(w(a.value ? e[1] : e[0])),
W(T(a.value ? e[2] : e[1])),
w(a.value ? e[3] : e[2])
], ([e, t, a, o]) => {
if (r(), !e?.length || !t?.length || !a?.length) return;
let s = ne(o) ? { ...o } : o;
n.push(...e.flatMap((e) => t.flatMap((t) => a.map((n) => i(e, t, n, s)))));
}, { flush: "post" });
return B(r), () => {
o(), r();
};
}
function le() {
let e = S(!1), t = l();
return t && g(() => {
e.value = !0;
}, t), e;
}
function J(e) {
let n = le();
return t(() => (n.value, !!e()));
}
function ue(e, n, r = {}) {
let { window: i = G, ...a } = r, o, s = J(() => i && "MutationObserver" in i), c = () => {
o &&= (o.disconnect(), void 0);
}, l = t(() => {
let t = W(w(e)).map(K).filter(te);
return new Set(t);
}), u = O(() => l.value, (e) => {
c(), s.value && e.size && (o = new MutationObserver(n), e.forEach((e) => o.observe(e, a)));
}, {
immediate: !0,
flush: "post"
}), d = () => o?.takeRecords(), f = () => {
u(), c();
};
return B(f), {
isSupported: s,
stop: f,
takeRecords: d
};
}
function de(e, t, n = {}) {
let { window: r = G, document: i = r?.document, flush: a = "sync" } = n;
if (!r || !i) return U;
let o, s = (e) => {
o?.(), o = e;
}, c = k(() => {
let n = K(e);
if (n) {
let { stop: e } = ue(i, (e) => {
e.map((e) => [...e.removedNodes]).flat().some((e) => e === n || e.contains(n)) && t(e);
}, {
window: r,
childList: !0,
subtree: !0
});
s(e);
}
}, { flush: a }), l = () => {
c(), s();
};
return B(l), l;
}
function fe(e = {}) {
let { window: t = G, deep: n = !0, triggerOnRemoval: r = !1 } = e, i = e.document ?? t?.document, a = () => {
let e = i?.activeElement;
if (n) for (; e?.shadowRoot;) e = e?.shadowRoot?.activeElement;
return e;
}, o = S(), s = () => {
o.value = a();
};
if (t) {
let e = {
capture: !0,
passive: !0
};
q(t, "blur", (e) => {
e.relatedTarget === null && s();
}, e), q(t, "focus", s, e);
}
return r && de(o, s, { document: i }), s(), o;
}
function pe(e, n, r = {}) {
let { window: i = G, ...a } = r, o, s = J(() => i && "ResizeObserver" in i), c = () => {
o &&= (o.disconnect(), void 0);
}, l = O(t(() => {
let t = w(e);
return Array.isArray(t) ? t.map((e) => K(e)) : [K(t)];
}), (e) => {
if (c(), s.value && i) {
o = new ResizeObserver(n);
for (let t of e) t && o.observe(t, a);
}
}, {
immediate: !0,
flush: "post"
}), u = () => {
c(), l();
};
return B(u), {
isSupported: s,
stop: u
};
}
function Y(e, n = {
width: 0,
height: 0
}, r = {}) {
let { window: i = G, box: a = "content-box" } = r, o = t(() => (K(e)?.namespaceURI)?.includes("svg")), s = S(n.width), c = S(n.height), { stop: l } = pe(e, ([t]) => {
let n = a === "border-box" ? t.borderBoxSize : a === "content-box" ? t.contentBoxSize : t.devicePixelContentBoxSize;
if (i && o.value) {
let t = K(e);
if (t) {
let e = t.getBoundingClientRect();
s.value = e.width, c.value = e.height;
}
} else if (n) {
let e = W(n);
s.value = e.reduce((e, { inlineSize: t }) => e + t, 0), c.value = e.reduce((e, { blockSize: t }) => e + t, 0);
} else s.value = t.contentRect.width, c.value = t.contentRect.height;
}, r);
se(() => {
let t = K(e);
t && (s.value = "offsetWidth" in t ? t.offsetWidth : n.width, c.value = "offsetHeight" in t ? t.offsetHeight : n.height);
});
let u = O(() => K(e), (e) => {
s.value = e ? n.width : 0, c.value = e ? n.height : 0;
});
function d() {
l(), u();
}
return {
width: s,
height: c,
stop: d
};
}
//#endregion
//#region src/utils/useHandwritingRecognizer.ts
function me(e = !1) {
let t = b(!1), n = b(0);
async function r() {
let e = I();
if (e) try {
t.value = await e.initialize({ onProgress: (e) => {
n.value = e;
} });
} catch (e) {
console.error("初始化手写识别服务失败:", e), t.value = !1;
}
else console.warn("未注册手写识别服务"), t.value = !1;
}
async function i() {
let e = I();
if (e && t.value) try {
await e.close(), t.value = !1;
} catch (e) {
console.error("关闭手写识别服务失败:", e);
}
}
return g(() => {
e && r();
}), v(() => {
i();
}), {
recognizerInitialized: t,
recognizerProgress: n
};
}
//#endregion
//#region src/assets/icons/keyboard-backspace.svg
var he = "data:image/svg+xml,%3csvg%20t='1777011781316'%20class='icon'%20viewBox='0%200%201439%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='5887'%20width='200'%20height='200'%3e%3cpath%20d='M1283.03672%200.000187H465.243153a158.045778%20158.045778%200%200%200-122.329921%2057.680486L24.083875%20440.475014c-0.622227%200.68445-1.182232%201.431123-1.742237%202.177796A115.672087%20115.672087%200%200%200%200.003672%20511.906728a118.658779%20118.658779%200%200%200%2026.818004%2074.667297l316.713783%20380.492099a158.232446%20158.232446%200%200%200%20121.707694%2056.933814H1283.03672a156.303541%20156.303541%200%200%200%20156.05465-156.116873V156.054837A156.241318%20156.241318%200%200%200%201283.03672%200.000187z%20m-257.477728%20689.863598a47.538179%2047.538179%200%200%201-33.600284%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-13.937896L847.72638%20579.293963l-110.569822%20110.569822a47.911515%2047.911515%200%200%201-33.724729%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-81.325131l110.383154-110.569822-110.569822-110.569822a47.662624%2047.662624%200%200%201%200-67.387235%2047.600402%2047.600402%200%200%201%2067.325012%200l110.632045%20110.632045%20110.569822-110.632045A47.625291%2047.625291%200%200%201%201025.434546%20401.336906l-110.383153%20110.569822%20110.569821%20110.569822a47.662624%2047.662624%200%200%201-0.062222%2067.387235z'%20fill='%232C2C2C'%20p-id='5888'%3e%3c/path%3e%3c/svg%3e", ge = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M19,7V11H5.83L9.41,7.41L8,6L2,12L8,18L9.41,16.58L5.83,13H21V7H19Z'%20/%3e%3c/svg%3e";
//#endregion
//#region src/hooks/useKeyRepeater.ts
function X() {
let e = P();
function t(t, n) {
t.preventDefault(), t.currentTarget?.setPointerCapture?.(t.pointerId), e.start(n);
}
function n() {
e.stop();
}
return h(() => {
e.stop();
}), {
startRepeat: t,
stopRepeat: n
};
}
//#endregion
//#region src/components/CandidateList.vue?vue&type=script&setup=true&lang.ts
var _e = { class: "zhk-candidate-list" }, ve = ["onClick"], Z = /* @__PURE__ */ c({
__name: "CandidateList",
props: { candidates: {} },
emits: ["select"],
setup(t, { emit: n }) {
let r = n;
function a(e) {
r("select", e);
}
return (t, n) => (y(), i("div", _e, [(y(!0), i(e, null, x(t.candidates, (e, t) => (y(), i("button", {
key: `candidate-${t}`,
class: "zhk-candidate-list__item",
onClick: (e) => a(t)
}, C(e), 9, ve))), 128))]));
}
}), ye = { class: "handwriting-input" }, be = { class: "handwriting-content" }, xe = { class: "handwriting-buttons" }, Se = { class: "handwriting-canvas-container" }, Ce = {
key: 0,
class: "handwriting-loading"
}, we = { class: "progress-bar" }, Te = { class: "progress-text" }, Ee = { class: "handwriting-buttons" }, De = /* @__PURE__ */ c({
__name: "HandwritingInput",
props: {
recognizerInitialized: { type: Boolean },
recognizerProgress: {}
},
emits: ["key", "exit"],
setup(e, { emit: t }) {
let n = e, r = t, o = b(null), c = null, l = b(!1), { width: u, height: d } = Y(o);
function p() {
c && c.clearCanvas();
}
function h() {
o.value && (c && c.destroy(), o.value.width = u.value, o.value.height = d.value, c = new M(o.value, { onDrawEnd: S }));
}
let g = b([]), { startRepeat: _, stopRepeat: x } = X();
async function S() {
if (!c || c.getStrokeData().length === 0 || l.value) return;
let e = I();
if (e) {
l.value = !0;
try {
let t = [...c.getStrokeData()];
g.value = await e.recognize(t);
} catch (e) {
console.error("识别笔迹失败:", e);
} finally {
l.value = !1;
}
} else console.warn("手写识别服务不可用");
}
v(() => {
c && c.destroy();
}), k(() => {
o.value && (u.value || d.value) && n.recognizerInitialized && f(() => {
h();
});
});
function w(e) {
let t = g.value[e];
t && (r("key", { key: t }), g.value = [], p());
}
return (e, t) => (y(), i("div", ye, [s(Z, {
candidates: g.value,
onSelect: w
}, null, 8, ["candidates"]), a("div", be, [
a("div", xe, [
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[0] ||= (e) => T(_)(e, () => r("key", { key: "。" })),
onPointerup: t[1] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[2] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[3] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[4] ||= j(() => {}, ["prevent"])
}, " 。 ", 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[5] ||= (e) => T(_)(e, () => r("key", { key: "?" })),
onPointerup: t[6] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[7] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[8] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[9] ||= j(() => {}, ["prevent"])
}, " ? ", 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[10] ||= (e) => T(_)(e, () => r("key", { key: "!" })),
onPointerup: t[11] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[12] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[13] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[14] ||= j(() => {}, ["prevent"])
}, " ! ", 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[15] ||= (e) => T(_)(e, () => r("key", { key: "、" })),
onPointerup: t[16] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[17] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[18] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[19] ||= j(() => {}, ["prevent"])
}, " 、 ", 32)
]),
a("div", Se, [e.recognizerInitialized ? (y(), i("canvas", {
key: 1,
ref_key: "canvasRef",
ref: o,
class: "handwriting-canvas"
}, null, 512)) : (y(), i("div", Ce, [
t[37] ||= a("div", { class: "loading-text" }, " 正在加载手写识别... ", -1),
a("div", we, [a("div", {
class: "progress-fill",
style: m({ width: `${e.recognizerProgress * 100}%` })
}, null, 4)]),
a("div", Te, C(Math.round(e.recognizerProgress * 100)) + "% ", 1)
]))]),
a("div", Ee, [
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[20] ||= (e) => T(_)(e, () => r("key", {
key: "delete",
isControl: !0
})),
onPointerup: t[21] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[22] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[23] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[24] ||= j(() => {}, ["prevent"])
}, t[38] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20t='1777011781316'%20class='icon'%20viewBox='0%200%201439%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='5887'%20width='200'%20height='200'%3e%3cpath%20d='M1283.03672%200.000187H465.243153a158.045778%20158.045778%200%200%200-122.329921%2057.680486L24.083875%20440.475014c-0.622227%200.68445-1.182232%201.431123-1.742237%202.177796A115.672087%20115.672087%200%200%200%200.003672%20511.906728a118.658779%20118.658779%200%200%200%2026.818004%2074.667297l316.713783%20380.492099a158.232446%20158.232446%200%200%200%20121.707694%2056.933814H1283.03672a156.303541%20156.303541%200%200%200%20156.05465-156.116873V156.054837A156.241318%20156.241318%200%200%200%201283.03672%200.000187z%20m-257.477728%20689.863598a47.538179%2047.538179%200%200%201-33.600284%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-13.937896L847.72638%20579.293963l-110.569822%20110.569822a47.911515%2047.911515%200%200%201-33.724729%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-81.325131l110.383154-110.569822-110.569822-110.569822a47.662624%2047.662624%200%200%201%200-67.387235%2047.600402%2047.600402%200%200%201%2067.325012%200l110.632045%20110.632045%20110.569822-110.632045A47.625291%2047.625291%200%200%201%201025.434546%20401.336906l-110.383153%20110.569822%20110.569821%20110.569822a47.662624%2047.662624%200%200%201-0.062222%2067.387235z'%20fill='%232C2C2C'%20p-id='5888'%3e%3c/path%3e%3c/svg%3e",
alt: "删除"
}, null, -1)], 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onClick: t[25] ||= (e) => r("exit"),
onContextmenu: t[26] ||= j(() => {}, ["prevent"])
}, " 拼音 ", 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[27] ||= (e) => T(_)(e, () => r("key", { key: "," })),
onPointerup: t[28] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[29] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[30] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[31] ||= j(() => {}, ["prevent"])
}, " , ", 32),
a("button", {
class: "handwriting-btn handwriting-btn--function",
onPointerdown: t[32] ||= (e) => T(_)(e, () => r("key", {
key: "enter",
isControl: !0
})),
onPointerup: t[33] ||= (...e) => T(x) && T(x)(...e),
onPointerleave: t[34] ||= (...e) => T(x) && T(x)(...e),
onPointercancel: t[35] ||= (...e) => T(x) && T(x)(...e),
onContextmenu: t[36] ||= j(() => {}, ["prevent"])
}, t[39] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M19,7V11H5.83L9.41,7.41L8,6L2,12L8,18L9.41,16.58L5.83,13H21V7H19Z'%20/%3e%3c/svg%3e",
alt: "回车"
}, null, -1)], 32)
])
])]));
}
}), Oe = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M6,18H18V16H6M12,8.41L16.59,13L18,11.58L12,5.58L6,11.58L7.41,13L12,8.41Z'%20/%3e%3c/svg%3e", ke = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M3%2015H5V19H19V15H21V19C21%2020.1%2020.1%2021%2019%2021H5C3.9%2021%203%2020.1%203%2019V15Z'%20/%3e%3c/svg%3e", Ae = { class: "zhk-selection" }, je = { class: "zhk-selection__list" }, Me = ["onClick"], Ne = /* @__PURE__ */ c({
__name: "CandidateSelection",
props: { candidates: {} },
emits: ["select", "close"],
setup(t, { emit: n }) {
let r = n;
function o(e) {
r("select", e);
}
function s() {
r("close");
}
function c(e) {
let t = Array.from(e).length;
return t >= 2 && t <= 3 ? 2 : t >= 4 ? 3 : 1;
}
return (t, n) => (y(), i("div", Ae, [a("div", je, [(y(!0), i(e, null, x(t.candidates, (e, t) => (y(), i("div", {
key: t,
class: p(["zhk-selection__text", [`zhk-selection__text--span-${c(e)}`]]),
onClick: (e) => o(t)
}, C(e), 11, Me))), 128))]), a("div", { class: "zhk-selection__func" }, [a("button", {
class: "zhk-selection__func-btn",
onClick: s
}, " 返回 ")])]));
}
}), Pe = { class: "zhk-candidate" }, Fe = {
key: 0,
class: "zhk-candidate__container zhk-candidate__container--loading"
}, Ie = { class: "zhk-candidate__container" }, Le = {
key: 0,
class: "zhk-candidate__pinyin"
}, Re = { class: "zhk-candidate__bottom-container" }, ze = /* @__PURE__ */ c({
__name: "CandidateBar",
props: {
modelValue: { required: !0 },
modelModifiers: {}
},
emits: /* @__PURE__ */ d(["key", "input"], ["update:modelValue"]),
setup(o, { expose: s, emit: c }) {
let l = c, u = E(o, "modelValue"), d = null, f = b(!0), p = b(null), m = t(() => p.value?.candidates.map((e) => e.text) ?? []), h = b(!1);
g(async () => {
if (d = R(), !d) throw Error("未找到拼音引擎实例,请确保已正确注册引擎");
f.value = !0;
try {
await d.whenReady?.();
} catch (e) {
console.error("拼音引擎就绪失败:", e);
}
f.value = !1, u.value && (p.value = await d.processInput(u.value));
}), v(() => {
d?.syncData?.(), d?.processInput("").catch(() => {}), d = null;
}), O(u, async (e) => {
let t = d;
if (!(!t || f.value)) {
if (e === "") {
t.processInput("").catch(() => {}), p.value = null;
return;
}
p.value = await t.processInput(e);
}
});
async function _(e) {
if (!d) return;
let t = await d.pickCandidate(e);
p.value = t, t.preeditBody || (l("input", t.committed || ""), u.value = "", p.value = null, h.value = !1);
}
s({ handleSelection: _ });
let x = t(() => {
let e = p.value;
return e ? e.preeditHead + e.preeditBody : "";
});
return (t, o) => (y(), i("div", Pe, [f.value ? (y(), i("div", Fe, o[2] ||= [a("span", { class: "zhk-candidate__loading-text" }, "加载拼音引擎中…", -1)])) : (y(), i(e, { key: 1 }, [a("div", Ie, [x.value ? (y(), i("div", Le, C(x.value), 1)) : r("", !0), a("div", Re, [m.value.length > 0 ? (y(), n(Z, {
key: 0,
candidates: m.value,
onSelect: _
}, null, 8, ["candidates"])) : r("", !0), m.value.length > 0 ? (y(), i("button", {
key: 1,
class: "zhk-candidate__more",
onClick: o[0] ||= (e) => h.value = !0
}, o[3] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z'%20/%3e%3c/svg%3e",
alt: "更多"
}, null, -1)])) : r("", !0)])]), h.value ? (y(), n(Ne, {
key: 0,
candidates: m.value,
onSelect: _,
onClose: o[1] ||= (e) => h.value = !1
}, null, 8, ["candidates"])) : r("", !0)], 64))]));
}
}), Be = { class: "zhk-base" }, Ve = { class: "zhk-base__row" }, He = ["onPointerdown"], Ue = ["disabled"], We = {
key: 1,
src: Oe,
class: "zhk-base__key-icon",
alt: "Shift"
}, Ge = ["onPointerdown"], Ke = { class: "zhk-base__row" }, qe = { class: "zhk-base__toggle-main" }, Je = { class: "zhk-base__toggle-sub" }, Ye = /* @__PURE__ */ c({
__name: "KeyboardBase",
props: /* @__PURE__ */ d({ enableHandwriting: { type: Boolean } }, {
modelValue: { default: "en" },
modelModifiers: {}
}),
emits: /* @__PURE__ */ d(["key"], ["update:modelValue"]),
setup(s, { emit: c }) {
let l = s, u = c, d = E(s, "modelValue"), f = t(() => d.value === "en_cap"), m = t(() => d.value === "zh"), h = t(() => m.value ? !0 : f.value);
function g(e, t = !1) {
u("key", {
key: e,
isControl: t
});
}
function _() {
m.value ? d.value = "hand" : d.value = f.value ? "en" : "en_cap";
}
function v() {
d.value = "num";
}
function S() {
d.value = "symbol";
}
let w = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0"
], D = [
[
"q",
"w",
"e",
"r",
"t",
"y",
"u",
"i",
"o",
"p"
],
[
"a",
"s",
"d",
"f",
"g",
"h",
"j",
"k",
"l"
],
[
"z",
"x",
"c",
"v",
"b",
"n",
"m"
]
], O = b(""), k = b(null), { startRepeat: A, stopRepeat: M } = X();
function N() {
if (d.value === "zh" && O.value) {
O.value = O.value.slice(0, -1);
return;
}
g("delete", !0);
}
function P() {
if (d.value === "zh" && O.value) {
k.value?.handleSelection(0);
return;
}
g(" ");
}
function F() {
if (d.value === "zh" && O.value) {
g(O.value), O.value = "";
return;
}
g("enter", !0);
}
function I(e) {
if (d.value === "zh") {
O.value += e;
return;
}
g(f.value ? e.toUpperCase() : e);
}
function L() {
d.value = d.value === "zh" ? "en" : "zh";
}
let R = t(() => l.enableHandwriting ? "手写" : "-"), z = t(() => !l.enableHandwriting);
return (t, s) => (y(), i("div", Be, [
a("div", Ve, [d.value === "zh" ? (y(), n(ze, {
key: 0,
ref_key: "candidateBarRef",
ref: k,
modelValue: O.value,
"onUpdate:modelValue": s[0] ||= (e) => O.value = e,
onInput: s[1] ||= (e) => g(e, !1)
}, null, 8, ["modelValue"])) : (y(), i(e, { key: 1 }, x(w, (e, t) => a("button", {
key: `number-${t}`,
class: "zhk-base__key zhk-base__key--letter",
onPointerdown: (t) => T(A)(t, () => I(e)),
onPointerup: s[2] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[3] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[4] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[5] ||= j(() => {}, ["prevent"])
}, C(e), 41, He)), 64))]),
(y(), i(e, null, x(D, (t, n) => a("div", {
key: `row-${n}`,
class: "zhk-base__row"
}, [
n === 2 ? (y(), i("button", {
key: 0,
class: p(["zhk-base__key zhk-base__key--function zhk-base__key--shift", {
"zhk-base__key--active": !m.value && f.value,
"zhk-base__key--disabled": m.value && z.value
}]),
disabled: m.value && z.value,
onClick: _,
onContextmenu: s[6] ||= j(() => {}, ["prevent"])
}, [m.value ? (y(), i(e, { key: 0 }, [o(C(R.value), 1)], 64)) : (y(), i("img", We))], 42, Ue)) : r("", !0),
(y(!0), i(e, null, x(t, (e, t) => (y(), i("button", {
key: `key-${n}-${t}`,
class: "zhk-base__key zhk-base__key--letter",
onPointerdown: (t) => T(A)(t, () => I(e)),
onPointerup: s[7] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[8] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[9] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[10] ||= j(() => {}, ["prevent"])
}, C(h.value ? e.toUpperCase() : e), 41, Ge))), 128)),
n === 2 ? (y(), i("button", {
key: 1,
class: "zhk-base__key zhk-base__key--function zhk-base__key--delete",
onPointerdown: s[11] ||= (e) => T(A)(e, () => N()),
onPointerup: s[12] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[13] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[14] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[15] ||= j(() => {}, ["prevent"])
}, s[39] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20t='1777011781316'%20class='icon'%20viewBox='0%200%201439%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='5887'%20width='200'%20height='200'%3e%3cpath%20d='M1283.03672%200.000187H465.243153a158.045778%20158.045778%200%200%200-122.329921%2057.680486L24.083875%20440.475014c-0.622227%200.68445-1.182232%201.431123-1.742237%202.177796A115.672087%20115.672087%200%200%200%200.003672%20511.906728a118.658779%20118.658779%200%200%200%2026.818004%2074.667297l316.713783%20380.492099a158.232446%20158.232446%200%200%200%20121.707694%2056.933814H1283.03672a156.303541%20156.303541%200%200%200%20156.05465-156.116873V156.054837A156.241318%20156.241318%200%200%200%201283.03672%200.000187z%20m-257.477728%20689.863598a47.538179%2047.538179%200%200%201-33.600284%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-13.937896L847.72638%20579.293963l-110.569822%20110.569822a47.911515%2047.911515%200%200%201-33.724729%2013.937896%2047.662624%2047.662624%200%200%201-33.662506-81.325131l110.383154-110.569822-110.569822-110.569822a47.662624%2047.662624%200%200%201%200-67.387235%2047.600402%2047.600402%200%200%201%2067.325012%200l110.632045%20110.632045%20110.569822-110.632045A47.625291%2047.625291%200%200%201%201025.434546%20401.336906l-110.383153%20110.569822%20110.569821%20110.569822a47.662624%2047.662624%200%200%201-0.062222%2067.387235z'%20fill='%232C2C2C'%20p-id='5888'%3e%3c/path%3e%3c/svg%3e",
class: "zhk-base__key-icon",
alt: "Delete"
}, null, -1)], 32)) : r("", !0)
])), 64)),
a("div", Ke, [
a("button", {
class: "zhk-base__key zhk-base__key--function",
onClick: S,
onContextmenu: s[16] ||= j(() => {}, ["prevent"])
}, " 符 ", 32),
a("button", {
class: "zhk-base__key zhk-base__key--function",
onClick: v,
onContextmenu: s[17] ||= j(() => {}, ["prevent"])
}, " 123 ", 32),
a("button", {
class: "zhk-base__key",
onPointerdown: s[18] ||= (e) => T(A)(e, () => g(",")),
onPointerup: s[19] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[20] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[21] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[22] ||= j(() => {}, ["prevent"])
}, " , ", 32),
a("button", {
class: "zhk-base__key zhk-base__key--space",
onPointerdown: s[23] ||= (e) => T(A)(e, () => P()),
onPointerup: s[24] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[25] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[26] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[27] ||= j(() => {}, ["prevent"])
}, s[40] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M3%2015H5V19H19V15H21V19C21%2020.1%2020.1%2021%2019%2021H5C3.9%2021%203%2020.1%203%2019V15Z'%20/%3e%3c/svg%3e",
class: "zhk-base__key-icon",
alt: "Space"
}, null, -1)], 32),
a("button", {
class: "zhk-base__key",
onPointerdown: s[28] ||= (e) => T(A)(e, () => g("。")),
onPointerup: s[29] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[30] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[31] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[32] ||= j(() => {}, ["prevent"])
}, " 。 ", 32),
a("button", {
class: "zhk-base__key zhk-base__key--function",
onClick: L,
onContextmenu: s[33] ||= j(() => {}, ["prevent"])
}, [a("span", qe, C(d.value === "zh" ? "中" : "英"), 1), a("span", Je, "/" + C(d.value === "zh" ? "英" : "中"), 1)], 32),
a("button", {
class: "zhk-base__key zhk-base__key--function",
onPointerdown: s[34] ||= (e) => T(A)(e, () => F()),
onPointerup: s[35] ||= (...e) => T(M) && T(M)(...e),
onPointerleave: s[36] ||= (...e) => T(M) && T(M)(...e),
onPointercancel: s[37] ||= (...e) => T(M) && T(M)(...e),
onContextmenu: s[38] ||= j(() => {}, ["prevent"])
}, s[41] ||= [a("img", {
src: "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M19,7V11H5.83L9.41,7.41L8,6L2,12L8,18L9.41,16.58L5.83,13H21V7H19Z'%20/%3e%3c/svg%3e",
class: "zhk-base__key-icon",
alt: "Enter"
}, null, -1)], 32)
])
]));
}
}), Xe = { class: "num-keyboard" }, Ze = { class: "num-keyboard__container" }, Qe = { class: "num-keyboard__left" }, $e = { class: "num-keyboard__rows" }, et = ["onClick", "onPointerdown"], tt = {
key: 1,
src: ke,
class: "zhk-base__key-icon",
alt: "Space"
}, nt = { class: "num-keyboard__right" }, rt = ["onPointerdown"], it = ["src", "alt"], at = { key: 1 }, ot = /* @__PURE__ */ c({
__name: "NumericKeyboard",
props: { keyboardRows: { default: () => L().numKeys || [
[
"1",
"2",
"3"
],
[
"4",
"5",
"6"
],
[
"7",
"8",
"9"
],
[
"back",
"0",
"space"
]
] } },
emits: ["key", "exit"],
setup(t, { emit: n }) {
let r = n, s = [
{
key: "delete",
icon: he,
text: "",
alt: "Delete"
},
{
key: ".",
icon: "",
text: ".",
alt: "."
},
{
key: "@",
icon: "",
text: "@",
alt: "@"
},
{
key: "enter",
icon: ge,
text: "",
alt: "Enter"
}
];
function c(e) {
r("key", { key: e });
}
function l(e, t = !0) {
r("key", {
key: e,
isControl: t
});
}
function u() {
r("exit");
}
let { startRepeat: d, stopRepeat: f } = X();
function m(e, t) {
e === "back" || (e === "space" && (e = " "), e === "delete" || e === "enter" ? d(t, () => l(e)) : d(t, () => c(e)));
}
return (t, n) => (y(), i("div", Xe, [a("div", Ze, [a("div", Qe, [a("div", $e, [(y(!0), i(e, null, x(t.keyboardRows, (t, r) => (y(), i("div", {
key: `row-${r}`,
class: "num-keyboard__row"
}, [(y(!0), i(e, null, x(t, (t, a) => (y(), i("button", {
key: `key-${r}-${a}`,
class: p(["num-keyboard__key", {
"num-keyboard__key--back": t === "back",
"num-keyboard__key--space": t === "space"
}]),
onClick: (e) => t === "back" && u(),
onPointerdown: (e) => m(t, e),
onPointerup: n[0] ||= (...e) => T(f) && T(f)(...e),
onPointerleave: n[1] ||= (...e) => T(f) && T(f)(...e),
onPointercancel: n[2] ||= (...e) => T(f) && T(f)(...e),
onContextmenu: n[3] ||= j(() => {}, ["prevent"])
}, [t === "back" ? (y(), i(e, { key: 0 }, [o(" 返回 ")], 64)) : t === "space" ? (y(), i("img", tt)) : (y(), i(e, { key: 2 }, [o(C(t), 1)], 64))], 42, et))), 128))]))), 128))])]), a("div", nt, [(y(), i(e, null, x(s, (e, t) => a("button", {
key: `func-${t}`,
class: "num-keyboard__key num-keyboard__key--function",
onPointerdown: (t) => m(e.key, t),
onPointerup: n[4] ||= (...e) => T(f) && T(f)(...e),
onPointerleave: n[5] ||= (...e) => T(f) && T(f)(...e),
onPointercancel: n[6] ||= (...e) => T(f) && T(f)(...e),
onContextmenu: n[7] ||= j(() => {}, ["prevent"])
}, [e.icon ? (y(), i("img", {
key: 0,
src: e.icon,
class: "num-keyboard__key-icon",
alt: e.alt
}, null, 8, it)) : (y(), i("span", at, C(e.text), 1))], 40, rt)), 64))])])]));
}
}), st = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M18,20V10H6V20H18M18,8A2,2%200%200,1%2020,10V20A2,2%200%200,1%2018,22H6C4.89,22%204,21.1%204,20V10A2,2%200%200,1%206,8H15V6A3,3%200%200,0%2012,3A3,3%200%200,0%209,6H7A5,5%200%200,1%2012,1A5,5%200%200,1%2017,6V8H18M12,17A2,2%200%200,1%2010,15A2,2%200%200,1%2012,13A2,2%200%200,1%2014,15A2,2%200%200,1%2012,17Z'%20/%3e%3c/svg%3e", ct = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3e%3cpath%20d='M12,17C10.89,17%2010,16.1%2010,15C10,13.89%2010.89,13%2012,13A2,2%200%200,1%2014,15A2,2%200%200,1%2012,17M18,20V10H6V20H18M18,8A2,2%200%200,1%2020,10V20A2,2%200%200,1%2018,22H6C4.89,22%204,21.1%204,20V10C4,8.89%204.89,8%206,8H7V6A5,5%200%200,1%2012,1A5,5%200%200,1%2017,6V8H18M12,3A3,3%200%200,0%209,6V8H15V6A3,3%200%200,0%2012,3Z'%20/%3e%3c/svg%3e", lt = { class: "symbol-keyboard" }, ut = { class: "symbol-keyboard__content" }, dt = { class: "symbol-keyboard__functions" }, ft = { class: "symbol-keyboard__lang-selector" }, pt = { class: "symbol-keyboard__control-group" }, Q = ["src"], mt = ["src"], ht = { class: "symbol-keyboard__symbols-container" }, gt = { class: "symbol-keyboard__symbols-grid" }, _t = ["onClick", "onPointerdown"], vt = "!@#$%^&*(){}[]<>/\\|:;\"',.?+-=_~`€£¥₹©®™°", yt = "!@#¥%…&*(){}[]<>/\|:;"',。?+-=_~·€£¥₹©®™°", bt = /* @__PURE__ */ c({
__name: "SymbolKeyboard",
emits: ["key", "exit"],
setup(n, { emit: r }) {
let o = r, s = b("en"), c = t(() => s.value === "zh" ? yt : vt), l = b(!1), { startRepeat: u, stopRepeat: d } = X();
function f(e, t) {
l.value && u(t, () => m(e));
}
function m(e) {
o("key", { key: e }), l.value || o("exit");
}
function h() {
o("exit");
}
function g(e) {
s.value = e;
}
function _() {
l.value = !l.value;
}
return (t, n) => (y(), i("div", lt, [a("div", ut, [a("div", dt, [a("div", ft, [a("button", {
class: p(["symbol-keyboard__lang-btn", { "symbol-keyboard__lang-btn--active": s.value === "zh" }]),
onClick: n[0] ||= (e) => g("zh"),
onContextmenu: n[1] ||= j(() => {}, ["prevent"])
}, " 中文 ", 34), a("button", {
class: p(["symbol-keyboard__lang-btn", { "symbol-keyboard__lang-btn--active": s.value === "en" }]),
onClick: n[2] ||= (e) => g("en"),
onContextmenu: n[3] ||= j(() => {}, ["prevent"])
}, " 英文 ", 34)]), a("div", pt, [a("button", {
class: p(["symbol-keyboard__key symbol-keyboard__key--function symbol-keyboard__key--lock", { "symbol-keyboard__key--locked": l.value }]),
onClick: _,
onContextmenu: n[4] ||= j(() => {}, ["prevent"])
}, [l.value ? (y(), i("img", {
key: 1,
src: T(ct),
alt: "Lock closed"
}, null, 8, mt)) : (y(), i("img", {
key: 0,
src: T(st),
alt: "Lock open"
}, null, 8, Q))], 34), a("button", {
class: "symbol-keyboard__key symbol-keyboard__key--function symbol-keyboard__key--back",
onClick: h,
onContextmenu: n[5] ||= j(() => {}, ["prevent"])
}, " 返回 ", 32)])]), a("div", ht, [a("div", gt, [(y(!0), i(e, null, x(c.value, (e, t) => (y(), i("button", {
key: `key-${t}`,
class: "symbol-keyboard__key",
onClick: (t) => !l.value && m(e),
onPointerdown: (t) => f(e, t),
onPointerup: n[6] ||= (...e) => T(d) && T(d)(...e),
onPointerleave: n[7] ||= (...e) => T(d) && T(d)(...e),
onPointercancel: n[8] ||= (...e) => T(d) && T(d)(...e),
onContextmenu: n[9] ||= j(() => {}, ["prevent"])
}, C(e), 41, _t))), 128))])])])]));
}
}), xt = {
key: 0,
class: "zhk__disabled-overlay"
}, $ = /* @__PURE__ */ c({
__name: "ZhKeyboard",
props: {
defaultMode: {
type: String,
default: () => L().defaultMode ?? "en"
},
enableHandwriting: {
type: Boolean,
default: () => L().enableHandwriting ?? !1
},
position: {
type: String,
default: () => L().position ?? "static"
},
floatMarginTop: {
type: Number,
default: () => L().floatMarginTop ?? 0
},
disableWhenNoFocus: {
type: Boolean,
default: () => L().disableWhenNoFocus ?? !0
},
numKeys: { type: Array || void 0 },
requireInputmode: {
type: Boolean,
default: () => L().requireInputmode ?? !1
}
},
emits: ["key"],
setup(o, { emit: s }) {
let c = o, l = s, u = b(c.defaultMode), d = b(c.defaultMode), f = b([]), h = b(!1), g = b(null), _ = b(null), { recognizerInitialized: v, recognizerProgress: x } = me(c.enableHandwriting);
O(u, (e, t) => {
e !== t && (d.value = t);
});
let S = fe(), C = t(() => S.value && z(S.value) ? S.value : null), w = t(() => c.position === "static" ? !0 : !(!S.value || !z(S.value) || c.requireInputmode && !S.value.dataset.inputmode)), { height: E } = Y(_);
k(() => {
if (C.value) {
let e = C.value.dataset.inputmode;
e && (u.value = e);
}
});
let M = t(() => c.disableWhenNoFocus === !1 ? !1 : !C.value);
function P() {
E.value && (g.value = N(C.value, _.value, c.position, c.floatMarginTop));
}
k(P);
let I = oe(P, 100);
q(window, "scroll", I, { passive: !0 }), q(window, "resize", I, { passive: !0 });
function L(e) {
if (e.isControl) {
switch (e.key) {
case "delete":
F(C.value);
break;
case "more":
h.value = !0;
break;
default: break;
}
return;
} else R(e.key);
l("key", e);
}
function R(e) {
ee(C.value, e);
}
function B() {
u.value === "hand" ? d.value = "zh" : ["num", "symbol"].includes(d.value) && (d.value = c.defaultMode), u.value = d.value;
}
function V(e) {
f.value = e;
}
return (t, s) => A((y(), i("div", {
ref_key: "keyboardRef",
ref: _,
class: p(["zhk", {
"zhk--floating": o.position === "float",
"zhk--bottom": o.position === "bottom",
"zhk--disabled": M.value
}]),
style: m({
"--keyboard-height": `${T(E)}px`,
...g.value
}),
onMousedown: s[1] ||= j(() => {}, ["prevent"])
}, [M.value || !w.value || !T(E) ? (y(), i("div", xt, s[2] ||= [a("span", null, "请选择输入框以启用键盘", -1)])) : (y(), i(e, { key: 1 }, [u.value === "hand" ? (y(), n(De, {
key: 0,
"recognizer-initialized": T(v),
"recognizer-progress": T(x),
onKey: L,
onExit: B,
onRecognize: V
}, null, 8, ["recognizer-initialized", "recognizer-progress"])) : u.value === "num" ? (y(), n(ot, {
key: 1,
"keyboard-rows": o.numKeys,
onKey: L,
onExit: B
}, null, 8, ["keyboard-rows"])) : u.value === "symbol" ? (y(), n(bt, {
key: 2,
onKey: L,
onExit: B
})) : u.value === "en" || u.value === "en_cap" || u.value === "zh" ? (y(), n(Ye, {
key: 3,
modelValue: u.value,
"onUpdate:modelValue": s[0] ||= (e) => u.value = e,
"enable-handwriting": o.enableHandwriting,
onKey: L
}, null, 8, ["modelValue", "enable-handwriting"])) : r("", !0)], 64))], 38)), [[D, w.value]]);
}
}), St = { install: (e) => {
e.component("ZhKeyboard", $);
} };
//#endregion
export { $ as ZhKeyboard, St as default };
//# sourceMappingURL=zh-keyboard-vue.js.map